# Enable merchants on your platform to accept payments directly

Facilitate direct payments to businesses on your SaaS platform from their own customers.

Allow your merchant-configured connected account to accept direct charge payments using a Stripe-hosted Checkout page that reflects their branding.

## Create a Checkout Session [Client-side] [Server-side]

Add a checkout button to your website that calls a server-side endpoint to create a Checkout Session.

```html
<html>
  <head>
    <title>Checkout</title>
  </head>
  <body>
    <form action="/create-checkout-session" method="POST">
      <button type="submit">Checkout</button>
    </form>
  </body>
</html>
```

On your server, [create a Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) that renders the payment form to your customer, including purchase details such as line items, the order amount, and currency. Redirect your customer to the [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) returned in the response.

```curl
curl https://api.stripe.com/v1/checkout/sessions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -H "Stripe-Account: {{CONNECTEDACCOUNT_ID}}" \
  -d "line_items[0][price_data][currency]=usd" \
  -d "line_items[0][price_data][product_data][name]=T-shirt" \
  -d "line_items[0][price_data][unit_amount]=1000" \
  -d "line_items[0][quantity]=1" \
  -d "payment_intent_data[application_fee_amount]=123" \
  -d mode=payment \
  --data-urlencode "success_url=https://example.com/success?session_id={CHECKOUT_SESSION_ID}"
```

| Parameter | Description |
| --- | --- |
| `line_items` | Renders up to 100 purchase items in the Stripe-hosted checkout page. |
| `payment_intent_data[application_fee_amount]` | Specifies the amount your platform deducts from the transaction as an application fee. This amount transfers to your platform balance after the payment completes. See [collect fees](https://docs.stripe.com/connect/saas/tasks/app-fees.md) for more information. |
| `success_url` | Where Stripe redirects the customer following payment completion. Stripe updates the URL with the `{CHECKOUT_SESSION_ID}` generated from this request. You can [customize redirect behavior with a Stripe-hosted page](https://docs.stripe.com/payments/checkout/custom-success-page.md) to:
- Retrieve the Checkout Session and inspect its status to decide what to show your customer.
- Append your own query parameters, which persist through the redirect process. |
| `Stripe-Account` | A header that identifies your connected account as the transaction merchant of record. Checkout uses the connected account’s [branding](https://docs.stripe.com/connect/saas/tasks/accept-payment.md#branding) instead of your platform’s. |

Charges that you create directly on the connected account are reported only on that account. These charges aren’t shown in your platform’s Dashboard or exports. Direct charges are included in reports and Sigma for connected accounts that your platform controls. You can always retrieve this information using the Stripe API.

## Handle post-payment events [Server-side]

Stripe sends a [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) event when the payment completes. [Use a webhook to receive these events](https://docs.stripe.com/webhooks/quickstart.md) and run actions, like sending an order confirmation email to your customer, logging the sale in a database, or starting a shipping workflow.

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes. Some payment methods also take 2-14 days for payment confirmation. Setting up your integration to listen for asynchronous events enables you to accept multiple [payment methods](https://stripe.com/payments/payment-methods-guide) with a single integration.

Stripe recommends handling all of the following events when collecting payments with Checkout:

| Event | Description | Next steps |
| --- | --- | --- |
| [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | The customer has successfully authorized the payment by submitting the Checkout form. | Wait for the payment to succeed or fail. |
| [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | The customer’s payment succeeded. | Fulfill the purchased goods or services. |
| [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | The payment was declined, or failed for some other reason. | Contact the customer through email and request that they place a new order. |

These events all include the [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) object. After the payment succeeds, the underlying *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) [status](https://docs.stripe.com/payments/paymentintents/lifecycle.md) changes from `processing` to `succeeded` or a failure status.

## Test the integration

#### Cards

| Card number | Scenario | How to test |
| --- | --- | --- |
| 4242424242424242 | The card payment succeeds and doesn’t require authentication. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. |
| 4000002500003155 | The card payment requires *authentication* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. |
| 4000000000009995 | The card is declined with a decline code like `insufficient_funds`. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. |
| 6205500000000000004 | The UnionPay card has a variable length of 13-19 digits. | Fill out the credit card form using the credit card number with any expiration, CVC, and postal code. |

#### Wallets

| Payment method | Scenario | How to test |
| --- | --- | --- |
| Alipay | Your customer successfully pays with a redirect-based and [immediate notification](https://docs.stripe.com/payments/payment-methods.md#payment-notification) payment method. | Choose any redirect-based payment method, fill out the required details, and confirm the payment. Then click **Complete test payment** on the redirect page. |

#### Bank redirects

| Payment method | Scenario | How to test |
| --- | --- | --- |
| BECS Direct Debit | Your customer successfully pays with BECS Direct Debit. | Fill out the form using the account number `900123456` and BSB `000000`. The confirmed PaymentIntent initially transitions to `processing`, then transitions to the `succeeded` status 3 minutes later. |
| BECS Direct Debit | Your customer’s payment fails with an `account_closed` error code. | Fill out the form using the account number `111111113` and BSB `000000`. |
| Bancontact, EPS, iDEAL, and Przelewy24 | Your customer fails to authenticate on the redirect page for a redirect-based and immediate notification payment method. | Choose any redirect-based payment method, fill out the required details, and confirm the payment. Then click **Fail test payment** on the redirect page. |
| Pay by Bank | Your customer successfully pays with a redirect-based and [delayed notification](https://docs.stripe.com/payments/payment-methods.md#payment-notification) payment method. | Choose the payment method, fill out the required details, and confirm the payment. Then click **Complete test payment** on the redirect page. |
| Pay by Bank | Your customer fails to authenticate on the redirect page for a redirect-based and delayed notification payment method. | Choose the payment method, fill out the required details, and confirm the payment. Then click **Fail test payment** on the redirect page. |
| BLIK | BLIK payments fail in a variety of ways—immediate failures (for example, the code is expired or invalid), delayed errors (the bank declines) or timeouts (the customer didn’t respond in time). | Use email patterns to [simulate the different failures.](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) |

#### Bank debits

| Payment method | Scenario | How to test |
| --- | --- | --- |
| SEPA Direct Debit | Your customer successfully pays with SEPA Direct Debit. | Fill out the form using the account number `AT321904300235473204`. The confirmed PaymentIntent initially transitions to processing, then transitions to the succeeded status three minutes later. |
| SEPA Direct Debit | Your customer’s payment intent status transitions from `processing` to `requires_payment_method`. | Fill out the form using the account number `AT861904300235473202`. |

#### Vouchers

| Payment method | Scenario | How to test |
| --- | --- | --- |
| Boleto, OXXO | Your customer pays with a Boleto or OXXO voucher. | Select Boleto or OXXO as the payment method and submit the payment. Close the dialog after it appears. |

See [Testing](https://docs.stripe.com/testing.md) for additional information to test your integration.

## Next steps

- If your monetization strategy includes charging a per-transaction fee, learn how to [collect application fees](https://docs.stripe.com/connect/saas/tasks/app-fees.md) from each payment.
- If you plan to charge a subscription fee for using your platform, learn how to use Billing to [charge a service fee](https://docs.stripe.com/connect/saas/tasks/service-fee.md).
- Learn how to [manage payment methods for your connected accounts](https://docs.stripe.com/connect/manage-payment-methods.md).
