# Accept an Affirm payment Learn how to accept Affirm, a buy now and pay later payment method. > This guide helps you integrate Affirm in your online checkout flow. For in-person payments with Stripe Terminal, visit [Additional payment methods](https://docs.stripe.com/terminal/payments/additional-payment-methods.md). # Checkout Affirm is a [single use](https://docs.stripe.com/payments/payment-methods.md#usage), [immediate notification](https://docs.stripe.com/payments/payment-methods.md#payment-notification) payment method that requires customers to [authenticate](https://docs.stripe.com/payments/payment-methods.md#customer-actions) their payment. Customers are redirected to the Affirm site, where they agree to the terms of an installment plan. When the customer accepts the terms, funds are guaranteed and transferred to your Stripe account. The customer repays Affirm directly over time. > Before you start the integration, make sure your account is eligible for Affirm by navigating to your [Payment methods settings](https://dashboard.stripe.com/settings/payment_methods). ## Determine compatibility **Customer Geography**: Canada, US **Supported currencies**: `cad, usd` **Presentment currencies**: `cad, usd` **Payment mode**: Yes **Setup mode**: No **Subscription mode**: No A Checkout Session must satisfy all of the following conditions to support Affirm payments: - You can only use one-time line items. Affirm doesn’t support recurring *subscription* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) plans. - Express all *Prices* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) in your domestic currency. ## Accept a payment > This guide builds on the foundational [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?ui=stripe-hosted) Checkout integration. ### Enable Affirm as a payment method When creating a new [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md), you need to: 1. [Enable Affirm](https://dashboard.stripe.com/settings/payment_methods) in your Dashboard. Stripe automatically displays Affirm to eligible customers using [dynamic payment methods](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). If you currently specify `payment_method_types`, see the [migration guide](https://docs.stripe.com/payments/dashboard-payment-methods.md). 2. Make sure all your `line_items` use your domestic currency and the total amount doesn’t exceed Affirm’s [transaction amount limits](https://docs.stripe.com/payments/affirm.md#payment-options). 3. Optionally, specify which countries Checkout allows for shipping locations through `shipping_address_collection[allowed_countries]`. #### Stripe-hosted page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -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]=5000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "shipping_address_collection[allowed_countries][0]=CA" \ -d "shipping_address_collection[allowed_countries][1]=US" \ --data-urlencode "success_url=https://example.com/success" ``` #### Full embedded page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -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]=5000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "return_url=https://example.com/return" \ -d "shipping_address_collection[allowed_countries][0]=CA" \ -d "shipping_address_collection[allowed_countries][1]=US" \ -d ui_mode=embedded_page ``` If you don’t want to collect shipping addresses with Checkout, you can also provide the shipping address using `payment_intent_data[shipping]`. Doing so helps with loan acceptance rates. #### Stripe-hosted page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -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]=5000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_intent_data[shipping][name]=Jenny Rosen" \ -d "payment_intent_data[shipping][address][line1]=1234 Main Street" \ -d "payment_intent_data[shipping][address][city]=San Francisco" \ -d "payment_intent_data[shipping][address][state]=CA" \ -d "payment_intent_data[shipping][address][country]=US" \ -d "payment_intent_data[shipping][address][postal_code]=94111" \ --data-urlencode "success_url=https://example.com/success" ``` #### Full embedded page ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -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]=5000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "return_url=https://example.com/return" \ -d "payment_intent_data[shipping][name]=Jenny Rosen" \ -d "payment_intent_data[shipping][address][line1]=1234 Main Street" \ -d "payment_intent_data[shipping][address][city]=San Francisco" \ -d "payment_intent_data[shipping][address][state]=CA" \ -d "payment_intent_data[shipping][address][country]=US" \ -d "payment_intent_data[shipping][address][postal_code]=94111" \ -d ui_mode=embedded_page ``` ### Fulfill your orders [Use a method such as webhooks](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks) to handle order *fulfillment* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected), instead of relying on your customer to return to the payment status page. The following events are sent when the payment status changes: | Event Name | Description | Next steps | | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | The customer successfully authorized the payment by submitting the Checkout form. | Wait for the payment to succeed or fail. | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) | The customer’s payment succeeded. The `PaymentIntent` transitions to `succeeded`. | Fulfill the goods or services that the customer purchased. | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) | The customer’s payment was declined, or failed for some other reason. The `PaymentIntent` returns to the `requires_payment_method` status. | Email the customer to request that they place a new order. | Learn more about [fulfilling orders](https://docs.stripe.com/checkout/fulfillment.md). ## Test your integration When testing your Checkout integration, select Affirm as the payment method and click the **Pay** button. Test your Affirm integration with your test API keys by viewing the redirect page. You can test a successful payment by authenticating the payment on the redirect page. The PaymentIntent transitions from `requires_action` to `succeeded`. To test authentication failure, use your test API keys and view the redirect page. On the redirect page, close the Affirm modal window and verify that payment failed. The PaymentIntent transitions from `requires_action` to `requires_payment_method`. When redirected to the Affirm sandbox, Affirm may ask for the last four digits of your SSN. Affirm suggests using `'0000'` or `'5678'`. For [manual capture](https://docs.stripe.com/payments/affirm/accept-a-payment.md#manual-capture) PaymentIntents in testmode, the uncaptured PaymentIntent auto-expires 10 minutes after successful authorization. ## Failed payments Affirm takes into account multiple factors when deciding to accept or decline a transaction (for example, the length of time buyer has used Affirm, the outstanding amount the customer has to repay, and the value of the current order). Always present additional payment options such as `card` in your checkout flow, as Affirm payments have a higher rate of decline than many payment methods. In these cases, the [PaymentMethod](https://docs.stripe.com/api/payment_methods/object.md) is detached and the [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) object’s status automatically transitions to `requires_payment_method`. Other than a payment being declined, for an Affirm [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) with a status of `requires_action`, customers need to complete the payment within 12 hours after you redirect them to the Affirm site. If the customer takes no action within 12 hours, the [PaymentMethod](https://docs.stripe.com/api/payment_methods/object.md) is detached and the [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) object’s status automatically transitions to `requires_payment_method`. In these cases, inform your customer to try again with a different payment option presented in your checkout flow. ## Error codes These are the common error codes and corresponding recommended actions: | Error code | Recommended action | | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent_payment_attempt_failed` | A generic failure indicating the Affirm checkout failed. Additional information might be available in the charge outcome reason. | | `payment_method_provider_decline` | Affirm declined the customer’s payment. As a next step, the customer needs to contact Affirm for more information. | | `payment_intent_payment_attempt_expired` | The customer never completed the payment on Affirm’s checkout page, and the payment session has expired. Stripe automatically expires PaymentIntents that aren’t successfully authorized 12 hours after initial checkout creation. | | `payment_method_not_available` | Affirm experienced a service related error and is unable to complete the request. Retry at a later time. | | `amount_too_small` | Enter an amount within Affirm’s [default transactions limits](https://docs.stripe.com/payments/affirm.md#payment-options). | | `amount_too_large` | Enter an amount within Affirm’s [default transactions limits](https://docs.stripe.com/payments/affirm.md#payment-options). | Some errors might have additional insight included in the charge outcome reason: | Outcome Reason | What this means | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `generic_decline` | The default outcome reason for a payment error. This usually indicates that the partner declined the payment (for example, because of insufficient funds), the bank issuer declined the charge, the transaction included a high-risk purchase, or a similar reason. Stripe might not always receive a decline reason for these cases. | | `affirm_checkout_canceled` | Either the customer has explicitly canceled the Affirm checkout or Affirm has rejected the customer’s loan eligibility. Stripe can’t distinguish the difference between these two types of events. |