> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/medusajs/medusa/llms.txt
> Use this file to discover all available pages before exploring further.

# Payment Module

> Learn about the Payment Module and how to manage payment collections, payment sessions, captures, and refunds in Medusa.

## Overview

The Payment Module manages all payment-related operations including payment collection creation, payment session handling, payment capture, and refunds. It provides a provider-agnostic interface that works with various payment providers like Stripe, PayPal, and others.

**Key Features:**

* Payment collection management
* Payment session handling (authorize, capture)
* Multi-provider support (Stripe, PayPal, etc.)
* Payment capture and refund processing
* Webhook handling for async payments
* Account holder management
* Payment method tracking

## When to Use

Use the Payment Module when you need to:

* Process customer payments during checkout
* Authorize payments before capturing
* Capture authorized payments
* Process full or partial refunds
* Handle payment provider webhooks
* Store customer payment methods
* Track payment transactions
* Support multiple payment providers

## Data Models

### PaymentCollection

Groups payment sessions for a cart or order.

<ResponseField name="id" type="string" required>
  Unique payment collection identifier
</ResponseField>

<ResponseField name="currency_code" type="string" required>
  Three-letter ISO currency code
</ResponseField>

<ResponseField name="amount" type="BigNumber" required>
  Total amount to be paid
</ResponseField>

<ResponseField name="authorized_amount" type="BigNumber">
  Amount currently authorized
</ResponseField>

<ResponseField name="captured_amount" type="BigNumber">
  Amount successfully captured
</ResponseField>

<ResponseField name="refunded_amount" type="BigNumber">
  Amount refunded to customer
</ResponseField>

<ResponseField name="status" type="PaymentCollectionStatus" required>
  Status: `not_paid`, `awaiting`, `authorized`, `partially_authorized`, `canceled`
</ResponseField>

<ResponseField name="payment_sessions" type="PaymentSession[]">
  Payment sessions in this collection
</ResponseField>

<ResponseField name="payments" type="Payment[]">
  Completed payments
</ResponseField>

<ResponseField name="region_id" type="string">
  Associated region ID
</ResponseField>

### PaymentSession

Represents an active payment attempt.

<ResponseField name="id" type="string" required>
  Unique payment session identifier
</ResponseField>

<ResponseField name="payment_collection_id" type="string" required>
  ID of the parent payment collection
</ResponseField>

<ResponseField name="provider_id" type="string" required>
  Payment provider identifier (e.g., "stripe", "paypal")
</ResponseField>

<ResponseField name="currency_code" type="string" required>
  Three-letter ISO currency code
</ResponseField>

<ResponseField name="amount" type="BigNumber" required>
  Payment amount
</ResponseField>

<ResponseField name="status" type="PaymentSessionStatus" required>
  Status: `pending`, `authorized`, `error`, `canceled`
</ResponseField>

<ResponseField name="authorized_at" type="DateTime">
  When payment was authorized
</ResponseField>

<ResponseField name="data" type="object">
  Provider-specific data (e.g., Stripe payment intent)
</ResponseField>

<ResponseField name="context" type="object">
  Additional context data
</ResponseField>

### Payment

Represents a completed payment.

<ResponseField name="id" type="string" required>
  Unique payment identifier
</ResponseField>

<ResponseField name="payment_collection_id" type="string" required>
  ID of the payment collection
</ResponseField>

<ResponseField name="payment_session_id" type="string">
  ID of the originating payment session
</ResponseField>

<ResponseField name="provider_id" type="string" required>
  Payment provider identifier
</ResponseField>

<ResponseField name="currency_code" type="string" required>
  Three-letter ISO currency code
</ResponseField>

<ResponseField name="amount" type="BigNumber" required>
  Payment amount
</ResponseField>

<ResponseField name="captured_at" type="DateTime">
  When payment was captured
</ResponseField>

<ResponseField name="captures" type="Capture[]">
  Payment captures
</ResponseField>

<ResponseField name="refunds" type="Refund[]">
  Payment refunds
</ResponseField>

### Capture

Represents a payment capture (full or partial).

<ResponseField name="id" type="string" required>
  Unique capture identifier
</ResponseField>

<ResponseField name="payment_id" type="string" required>
  ID of the payment being captured
</ResponseField>

<ResponseField name="amount" type="BigNumber" required>
  Captured amount
</ResponseField>

<ResponseField name="created_by" type="string">
  User ID who initiated the capture
</ResponseField>

### Refund

Represents a payment refund.

<ResponseField name="id" type="string" required>
  Unique refund identifier
</ResponseField>

<ResponseField name="payment_id" type="string" required>
  ID of the payment being refunded
</ResponseField>

<ResponseField name="amount" type="BigNumber" required>
  Refund amount
</ResponseField>

<ResponseField name="reason_id" type="string">
  ID of the refund reason
</ResponseField>

<ResponseField name="note" type="string">
  Refund note or explanation
</ResponseField>

<ResponseField name="created_by" type="string">
  User ID who initiated the refund
</ResponseField>

### AccountHolder

Stores customer payment account information.

<ResponseField name="id" type="string" required>
  Unique account holder identifier
</ResponseField>

<ResponseField name="email" type="string">
  Account holder email
</ResponseField>

<ResponseField name="customer_id" type="string">
  Associated customer ID
</ResponseField>

<ResponseField name="provider_id" type="string" required>
  Payment provider identifier
</ResponseField>

<ResponseField name="provider_account_id" type="string">
  Provider-specific account ID
</ResponseField>

## Service Interface

The Payment Module service is available at `@medusajs/medusa/payment`.

### Create Payment Collection

Create a payment collection for a cart or order.

<CodeGroup>
  ```typescript Example theme={null}
  import { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
  import { IPaymentModuleService } from "@medusajs/framework/types"
  import { Modules } from "@medusajs/framework/utils"

  export async function POST(
    req: MedusaRequest,
    res: MedusaResponse
  ) {
    const paymentModuleService: IPaymentModuleService = req.scope.resolve(
      Modules.PAYMENT
    )

    const paymentCollection = await paymentModuleService.createPaymentCollections({
      region_id: "reg_us",
      currency_code: "usd",
      amount: 5000,
    })

    res.json({ payment_collection: paymentCollection })
  }
  ```
</CodeGroup>

<ParamField path="data" type="CreatePaymentCollectionDTO" required>
  Payment collection data

  <ParamField path="currency_code" type="string" required>
    Three-letter ISO currency code
  </ParamField>

  <ParamField path="amount" type="number" required>
    Total amount to collect
  </ParamField>

  <ParamField path="region_id" type="string">
    ID of the associated region
  </ParamField>
</ParamField>

<ResponseField name="paymentCollection" type="PaymentCollectionDTO">
  The created payment collection
</ResponseField>

### Create Payment Session

Initiate a payment session with a provider.

<CodeGroup>
  ```typescript Example theme={null}
  const paymentSession = await paymentModuleService.createPaymentSession(
    "paycol_123",
    {
      provider_id: "stripe",
      currency_code: "usd",
      amount: 5000,
      data: {
        // Provider-specific data
      },
      context: {
        customer_id: "cus_123",
        email: "customer@example.com",
      },
    }
  )
  ```
</CodeGroup>

<ParamField path="paymentCollectionId" type="string" required>
  ID of the payment collection
</ParamField>

<ParamField path="data" type="CreatePaymentSessionDTO" required>
  Payment session data

  <ParamField path="provider_id" type="string" required>
    Payment provider ID (e.g., "stripe", "paypal")
  </ParamField>

  <ParamField path="currency_code" type="string" required>
    Currency code
  </ParamField>

  <ParamField path="amount" type="number" required>
    Payment amount
  </ParamField>

  <ParamField path="data" type="object">
    Provider-specific initialization data
  </ParamField>

  <ParamField path="context" type="object">
    Additional context (customer info, etc.)
  </ParamField>
</ParamField>

<ResponseField name="paymentSession" type="PaymentSessionDTO">
  The created payment session
</ResponseField>

### Authorize Payment Session

Authorize a payment (reserve funds).

<CodeGroup>
  ```typescript Example theme={null}
  const payment = await paymentModuleService.authorizePaymentSession(
    "paysess_123",
    {
      // Provider-specific authorization data
    }
  )
  ```
</CodeGroup>

<ParamField path="paymentSessionId" type="string" required>
  ID of the payment session to authorize
</ParamField>

<ParamField path="context" type="object">
  Provider-specific authorization context
</ParamField>

<ResponseField name="payment" type="PaymentDTO">
  The authorized payment
</ResponseField>

### Capture Payment

Capture an authorized payment.

<CodeGroup>
  ```typescript Example theme={null}
  const capture = await paymentModuleService.capturePayment({
    payment_id: "pay_123",
    amount: 5000,
    created_by: "user_admin",
  })
  ```

  ```typescript Partial Capture theme={null}
  const capture = await paymentModuleService.capturePayment({
    payment_id: "pay_123",
    amount: 3000, // Partial capture
    created_by: "user_admin",
  })
  ```
</CodeGroup>

<ParamField path="data" type="CreateCaptureDTO" required>
  Capture data

  <ParamField path="payment_id" type="string" required>
    ID of the payment to capture
  </ParamField>

  <ParamField path="amount" type="number">
    Amount to capture (defaults to full payment amount)
  </ParamField>

  <ParamField path="created_by" type="string">
    User ID initiating the capture
  </ParamField>
</ParamField>

<ResponseField name="capture" type="CaptureDTO">
  The created capture
</ResponseField>

### Refund Payment

Refund a captured payment.

<CodeGroup>
  ```typescript Example theme={null}
  const refund = await paymentModuleService.refundPayment({
    payment_id: "pay_123",
    amount: 5000,
    reason_id: "reason_defective",
    note: "Product was damaged",
    created_by: "user_admin",
  })
  ```

  ```typescript Partial Refund theme={null}
  const refund = await paymentModuleService.refundPayment({
    payment_id: "pay_123",
    amount: 2000, // Partial refund
    created_by: "user_admin",
  })
  ```
</CodeGroup>

<ParamField path="data" type="CreateRefundDTO" required>
  Refund data

  <ParamField path="payment_id" type="string" required>
    ID of the payment to refund
  </ParamField>

  <ParamField path="amount" type="number">
    Amount to refund (defaults to full payment amount)
  </ParamField>

  <ParamField path="reason_id" type="string">
    ID of the refund reason
  </ParamField>

  <ParamField path="note" type="string">
    Refund note or explanation
  </ParamField>

  <ParamField path="created_by" type="string">
    User ID initiating the refund
  </ParamField>
</ParamField>

<ResponseField name="refund" type="RefundDTO">
  The created refund
</ResponseField>

### Handle Provider Webhook

Process payment provider webhooks.

<CodeGroup>
  ```typescript Example theme={null}
  const result = await paymentModuleService.processWebhook({
    provider: "stripe",
    payload: req.body,
    rawData: rawBody,
    headers: req.headers,
  })

  if (result.action === "authorized") {
    // Handle authorization
  } else if (result.action === "captured") {
    // Handle capture
  }
  ```
</CodeGroup>

<ParamField path="data" type="ProviderWebhookPayload" required>
  Webhook data

  <ParamField path="provider" type="string" required>
    Payment provider ID
  </ParamField>

  <ParamField path="payload" type="object" required>
    Webhook payload from provider
  </ParamField>

  <ParamField path="rawData" type="string | Buffer">
    Raw webhook body (for signature verification)
  </ParamField>

  <ParamField path="headers" type="object">
    Webhook request headers
  </ParamField>
</ParamField>

<ResponseField name="result" type="WebhookActionResult">
  Webhook processing result with action type
</ResponseField>

### Create Account Holder

Store customer payment account information.

<CodeGroup>
  ```typescript Example theme={null}
  const accountHolder = await paymentModuleService.createAccountHolder({
    email: "customer@example.com",
    customer_id: "cus_123",
    provider_id: "stripe",
    provider_account_id: "cus_stripe123",
  })
  ```
</CodeGroup>

### List Payment Providers

Retrieve available payment providers.

<CodeGroup>
  ```typescript Example theme={null}
  const providers = await paymentModuleService.listPaymentProviders()
  ```
</CodeGroup>

## Integration Examples

### With Cart Module

Create payment collection for cart checkout.

<CodeGroup>
  ```typescript Example theme={null}
  import { Modules } from "@medusajs/framework/utils"

  const cartModule = container.resolve(Modules.CART)
  const paymentModule = container.resolve(Modules.PAYMENT)

  // Retrieve cart with totals
  const cart = await cartModule.retrieveCart("cart_123", {
    select: ["total", "currency_code"],
  })

  // Create payment collection
  const paymentCollection = await paymentModule.createPaymentCollections({
    currency_code: cart.currency_code,
    amount: cart.total,
  })

  // Create payment session
  const paymentSession = await paymentModule.createPaymentSession(
    paymentCollection.id,
    {
      provider_id: "stripe",
      currency_code: cart.currency_code,
      amount: cart.total,
      context: {
        customer_id: cart.customer_id,
        email: cart.email,
      },
    }
  )
  ```
</CodeGroup>

### With Order Module

Track order payments.

<CodeGroup>
  ```typescript Example theme={null}
  import { Modules } from "@medusajs/framework/utils"

  const orderModule = container.resolve(Modules.ORDER)
  const paymentModule = container.resolve(Modules.PAYMENT)

  // Authorize payment
  const payment = await paymentModule.authorizePaymentSession("paysess_123")

  // Create order if payment successful
  if (payment.captured_at) {
    const order = await orderModule.createOrders({
      // ... order data
    })
    
    // Link payment to order via workflows
  }
  ```
</CodeGroup>

### With Region Module

Region-based payment provider availability.

<CodeGroup>
  ```typescript Example theme={null}
  import { Modules } from "@medusajs/framework/utils"

  const regionModule = container.resolve(Modules.REGION)

  // Retrieve region with payment providers
  const region = await regionModule.retrieveRegion("reg_us", {
    relations: ["payment_providers"],
  })

  // Get available payment providers for region
  const availableProviders = region.payment_providers
  ```
</CodeGroup>

## Payment Providers

Medusa supports multiple payment providers through a provider pattern:

### Stripe

<CodeGroup>
  ```typescript Install theme={null}
  npm install @medusajs/medusa-payment-stripe
  ```

  ```typescript Configure theme={null}
  // medusa-config.js
  module.exports = {
    modules: [
      {
        resolve: "@medusajs/medusa-payment-stripe",
        options: {
          api_key: process.env.STRIPE_API_KEY,
        },
      },
    ],
  }
  ```
</CodeGroup>

### PayPal

<CodeGroup>
  ```typescript Install theme={null}
  npm install medusa-payment-paypal
  ```

  ```typescript Configure theme={null}
  // medusa-config.js
  module.exports = {
    modules: [
      {
        resolve: "medusa-payment-paypal",
        options: {
          client_id: process.env.PAYPAL_CLIENT_ID,
          client_secret: process.env.PAYPAL_CLIENT_SECRET,
          sandbox: process.env.NODE_ENV !== "production",
        },
      },
    ],
  }
  ```
</CodeGroup>

## Best Practices

1. **Authorization vs Capture**: Use two-step authorization and capture for orders that require fulfillment before charging. Authorize during checkout, capture upon shipment.

2. **Currency Precision**: The module automatically rounds amounts to currency-specific precision using `Intl.NumberFormat`.

3. **Partial Operations**: Support partial captures and refunds by specifying amounts less than the total payment amount.

4. **Webhook Security**: Always verify webhook signatures using the raw request body. Providers include signature verification in their SDKs.

5. **Error Handling**: Payment sessions can fail due to insufficient funds, declined cards, etc. Handle `PaymentSessionStatus.ERROR` appropriately.

6. **Idempotency**: Payment operations should be idempotent to prevent duplicate charges during retries.

## Related Modules

* [Cart Module](/modules/cart) - Create payment collections for carts
* [Order Module](/modules/order) - Link payments to orders
* [Region Module](/modules/region) - Configure region payment providers
* [Customer Module](/modules/customer) - Store customer payment methods
