Medusa v2 Payment Processing
Before writing code
Fetch live docs:
- Web-search
site:docs.medusajs.com payment module for payment data model and service methods
- Web-search
site:docs.medusajs.com payment provider for the provider abstraction layer
- Web-search
site:docs.medusajs.com stripe payment for Stripe integration setup
- Fetch
https://docs.medusajs.com/resources/references/payment and review the IPaymentModuleService interface
- 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:
// 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.
1---2name: medusa-payments3description: Implement Medusa v2 payment processing — payment module, provider abstraction, payment sessions, authorization/capture/refund lifecycle, and Stripe/PayPal integration. Use when adding payment providers.4---56# Medusa v2 Payment Processing78## Before writing code910**Fetch live docs**:111. Web-search `site:docs.medusajs.com payment module` for payment data model and service methods122. Web-search `site:docs.medusajs.com payment provider` for the provider abstraction layer133. Web-search `site:docs.medusajs.com stripe payment` for Stripe integration setup144. Fetch `https://docs.medusajs.com/resources/references/payment` and review the `IPaymentModuleService` interface155. Web-search `medusajs v2 AbstractPaymentProvider 2026` for latest provider interface1617## Payment Module Architecture1819### Entity Relationships2021| Entity | Contains | Key Fields |22|--------|----------|------------|23| **PaymentCollection** | Sessions, Payments | status, amount, currency_code |24| **PaymentSession** | Provider data | provider_id, status, amount, data (JSON) |25| **Payment** | Captures, Refunds | provider_id, amount, captured_at |2627### Module Links2829```30Cart Module ──link──> Payment Module (payment collection)31Order Module ──link──> Payment Module (payment collection)32Region Module ──link──> Payment Module (available providers)33```3435> **Fetch live docs** for exact link definitions and how payment collections bridge carts and orders.3637## Payment Lifecycle3839### PaymentSession Statuses4041| Status | Meaning |42|--------|---------|43| `pending` | Session initialized, awaiting customer action |44| `requires_more` | Additional steps needed (e.g., 3DS) |45| `authorized` | Payment authorized, funds reserved |46| `canceled` | Payment voided/canceled |47| `error` | Payment failed |4849### Payment Statuses5051After authorization, a **Payment** entity is created from the session:5253| Status | Meaning |54|--------|---------|55| `captured` | Funds captured to merchant |56| `partially_refunded` | Partial refund issued |57| `refunded` | Full refund issued |5859## Payment Provider Abstraction6061All payment providers extend `AbstractPaymentProvider`:6263```ts64// Skeleton: custom payment provider65// Fetch live docs for AbstractPaymentProvider interface66class MyPaymentProvider extends AbstractPaymentProvider {67 // Implement: initiatePayment, authorizePayment,68 // capturePayment, refundPayment, cancelPayment69 // Fetch live docs for exact method signatures70}71```7273### Key Provider Methods7475| Method | Purpose |76|--------|---------|77| `initiatePayment` | Create payment session with provider |78| `authorizePayment` | Authorize payment (reserve funds) |79| `capturePayment` | Capture authorized payment |80| `refundPayment` | Refund captured payment |81| `cancelPayment` | Cancel/void payment |82| `deletePayment` | Clean up provider-side session |83| `getPaymentStatus` | Query current status from provider |84| `updatePayment` | Update an existing payment session |85| `retrievePayment` | Retrieve payment data from provider |86| `getWebhookActionAndData` | Parse incoming webhook events |8788> **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.8990## Stripe Integration9192| Configuration | Description |93|---------------|-------------|94| `apiKey` | Stripe secret key |95| `webhookSecret` | Stripe webhook signing secret |96| `capture` | Auto-capture or manual (`true`/`false`) |9798### Stripe Webhook Events99100| Event | Medusa Action |101|-------|---------------|102| `payment_intent.succeeded` | Mark session authorized/captured |103| `payment_intent.payment_failed` | Mark session errored |104| `charge.refunded` | Mark refund completed |105106> **Fetch live docs** for Stripe provider configuration options and webhook endpoint setup.107108## PayPal Integration109110| Configuration | Description |111|---------------|-------------|112| `clientId` | PayPal client ID |113| `clientSecret` | PayPal client secret |114| `sandbox` | Use sandbox environment (`true`/`false`) |115116> **Fetch live docs** for PayPal provider options, redirect handling, and webhook configuration.117118## Payment Workflows119120| Workflow | Purpose |121|----------|---------|122| `createPaymentCollectionForCartWorkflow` | Create collection linked to cart |123| `initializePaymentSessionWorkflow` | Start session with specific provider |124| `authorizePaymentSessionWorkflow` | Authorize a pending session |125| `capturePaymentWorkflow` | Capture an authorized payment |126| `refundPaymentWorkflow` | Refund a captured payment |127| `cancelPaymentWorkflow` | Cancel/void a payment |128129### Key Service Methods130131| Operation | Method |132|-----------|--------|133| Create collection | `paymentModuleService.createPaymentCollections()` |134| Create session | `paymentModuleService.createPaymentSession()` |135| Authorize session | `paymentModuleService.authorizePaymentSession()` |136| Capture payment | `paymentModuleService.capturePayment()` |137| Refund payment | `paymentModuleService.refundPayment()` |138139> **Fetch live docs** for workflow input shapes and provider-specific data requirements.140141## Admin API Routes142143| Route Pattern | Method | Purpose |144|---------------|--------|---------|145| `/admin/payments` | GET | List payments |146| `/admin/payments/:id` | GET | Retrieve payment |147| `/admin/payments/:id/capture` | POST | Capture payment |148| `/admin/payments/:id/refund` | POST | Refund payment |149150## Best Practices151152### Provider Implementation153- Always extend `AbstractPaymentProvider` — do not implement from scratch154- Store provider-specific data in the session `data` field (not in metadata)155- Handle `requires_more` status for providers with multi-step flows (3DS, redirect)156- Implement idempotent operations — captures and refunds may be retried157158### Webhook Handling159- Validate webhook signatures before processing events160- Use idempotency keys to prevent duplicate payment processing161- Log all webhook events for audit trails and debugging162- Handle out-of-order webhook delivery gracefully163164### Security165- Never store raw API keys in code — use environment variables166- Never expose payment session secrets to the client167- Use HTTPS-only webhook endpoints168- Implement amount validation — verify captured amount matches the order total169170### Testing171- Use provider sandbox/test modes during development172- Test the full lifecycle: initiate -> authorize -> capture -> refund173- Test error scenarios: declined cards, insufficient funds, network timeouts174175Fetch the Medusa v2 payment module documentation and provider interface references for exact method signatures, webhook configuration, and provider registration patterns before implementing.