# Medusa Payments

> Implement Medusa v2 payment processing — payment module, provider abstraction, payment sessions, authorization/capture/refund lifecycle, and Stripe/PayPal integration. Use when adding payment providers.

- Skill: `orcaqubits/medusa-payments` (Agent Skill)
- Install (CLI): `npx skillmds@latest add orcaqubits/medusa-payments`
- Raw SKILL.md: https://api.skillmd.com/api/skills/orcaqubits/medusa-payments/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: OrcaQubits (https://skillmd.com/u/orcaqubits)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/orcaqubits/medusa-payments

---


# Medusa v2 Payment Processing

## Before writing code

**Fetch live docs**:
1. Web-search `site:docs.medusajs.com payment module` for payment data model and service methods
2. Web-search `site:docs.medusajs.com payment provider` for the provider abstraction layer
3. Web-search `site:docs.medusajs.com stripe payment` for Stripe integration setup
4. Fetch `https://docs.medusajs.com/resources/references/payment` and review the `IPaymentModuleService` interface
5. Web-search `medusajs v2 AbstractPaymentProvider 2026` for latest provider interface

## Payment Module Architecture

### Entity Relationships

| Entity | Contains | Key Fields |
|--------|----------|------------|
| **PaymentCollection** | Sessions, Payments | status, amount, currency_code |
| **PaymentSession** | Provider data | provider_id, status, amount, data (JSON) |
| **Payment** | Captures, Refunds | provider_id, amount, captured_at |

### Module Links

```
Cart Module ──link──> Payment Module (payment collection)
Order Module ──link──> Payment Module (payment collection)
Region Module ──link──> Payment Module (available providers)
```

> **Fetch live docs** for exact link definitions and how payment collections bridge carts and orders.

## Payment Lifecycle

### PaymentSession Statuses

| Status | Meaning |
|--------|---------|
| `pending` | Session initialized, awaiting customer action |
| `requires_more` | Additional steps needed (e.g., 3DS) |
| `authorized` | Payment authorized, funds reserved |
| `canceled` | Payment voided/canceled |
| `error` | Payment failed |

### Payment Statuses

After authorization, a **Payment** entity is created from the session:

| Status | Meaning |
|--------|---------|
| `captured` | Funds captured to merchant |
| `partially_refunded` | Partial refund issued |
| `refunded` | Full refund issued |

## Payment Provider Abstraction

All payment providers extend `AbstractPaymentProvider`:

```ts
// Skeleton: custom payment provider
// Fetch live docs for AbstractPaymentProvider interface
class MyPaymentProvider extends AbstractPaymentProvider {
  // Implement: initiatePayment, authorizePayment,
  // capturePayment, refundPayment, cancelPayment
  // Fetch live docs for exact method signatures
}
```

### Key Provider Methods

| Method | Purpose |
|--------|---------|
| `initiatePayment` | Create payment session with provider |
| `authorizePayment` | Authorize payment (reserve funds) |
| `capturePayment` | Capture authorized payment |
| `refundPayment` | Refund captured payment |
| `cancelPayment` | Cancel/void payment |
| `deletePayment` | Clean up provider-side session |
| `getPaymentStatus` | Query current status from provider |
| `updatePayment` | Update an existing payment session |
| `retrievePayment` | Retrieve payment data from provider |
| `getWebhookActionAndData` | Parse incoming webhook events |

> **Fetch live docs** for the full method list — the provider interface has additional methods beyond those listed above (e.g., `createAccountHolder`, `listPaymentMethods`, `savePaymentMethod`). Always verify the current `AbstractPaymentProvider` interface.

## Stripe Integration

| Configuration | Description |
|---------------|-------------|
| `apiKey` | Stripe secret key |
| `webhookSecret` | Stripe webhook signing secret |
| `capture` | Auto-capture or manual (`true`/`false`) |

### Stripe Webhook Events

| Event | Medusa Action |
|-------|---------------|
| `payment_intent.succeeded` | Mark session authorized/captured |
| `payment_intent.payment_failed` | Mark session errored |
| `charge.refunded` | Mark refund completed |

> **Fetch live docs** for Stripe provider configuration options and webhook endpoint setup.

## PayPal Integration

| Configuration | Description |
|---------------|-------------|
| `clientId` | PayPal client ID |
| `clientSecret` | PayPal client secret |
| `sandbox` | Use sandbox environment (`true`/`false`) |

> **Fetch live docs** for PayPal provider options, redirect handling, and webhook configuration.

## Payment Workflows

| Workflow | Purpose |
|----------|---------|
| `createPaymentCollectionForCartWorkflow` | Create collection linked to cart |
| `initializePaymentSessionWorkflow` | Start session with specific provider |
| `authorizePaymentSessionWorkflow` | Authorize a pending session |
| `capturePaymentWorkflow` | Capture an authorized payment |
| `refundPaymentWorkflow` | Refund a captured payment |
| `cancelPaymentWorkflow` | Cancel/void a payment |

### Key Service Methods

| Operation | Method |
|-----------|--------|
| Create collection | `paymentModuleService.createPaymentCollections()` |
| Create session | `paymentModuleService.createPaymentSession()` |
| Authorize session | `paymentModuleService.authorizePaymentSession()` |
| Capture payment | `paymentModuleService.capturePayment()` |
| Refund payment | `paymentModuleService.refundPayment()` |

> **Fetch live docs** for workflow input shapes and provider-specific data requirements.

## Admin API Routes

| Route Pattern | Method | Purpose |
|---------------|--------|---------|
| `/admin/payments` | GET | List payments |
| `/admin/payments/:id` | GET | Retrieve payment |
| `/admin/payments/:id/capture` | POST | Capture payment |
| `/admin/payments/:id/refund` | POST | Refund payment |

## Best Practices

### Provider Implementation
- Always extend `AbstractPaymentProvider` — do not implement from scratch
- Store provider-specific data in the session `data` field (not in metadata)
- Handle `requires_more` status for providers with multi-step flows (3DS, redirect)
- Implement idempotent operations — captures and refunds may be retried

### Webhook Handling
- Validate webhook signatures before processing events
- Use idempotency keys to prevent duplicate payment processing
- Log all webhook events for audit trails and debugging
- Handle out-of-order webhook delivery gracefully

### Security
- Never store raw API keys in code — use environment variables
- Never expose payment session secrets to the client
- Use HTTPS-only webhook endpoints
- Implement amount validation — verify captured amount matches the order total

### Testing
- Use provider sandbox/test modes during development
- Test the full lifecycle: initiate -> authorize -> capture -> refund
- Test error scenarios: declined cards, insufficient funds, network timeouts

Fetch the Medusa v2 payment module documentation and provider interface references for exact method signatures, webhook configuration, and provider registration patterns before implementing.

