Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer tools
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment methods
Add payment methods
    Overview
    Payment method integration options
    Manage default payment methods in the Dashboard
    Payment method types
    Cards
    Pay with Stripe balance
    Crypto
    Bank debits
    Bank redirects
    Bank transfers
    Credit transfers (Sources)
    Buy now, pay later
      Affirm
      Afterpay / Clearpay
        Accept a payment
        Site messaging
      Alma
      Billie
      Capchase Pay
      Klarna
      Kriya
      Mondu
      Payment on Invoice
      Scalapay
      SeQura
      Sunbit
      Zip
    Real-time payments
    Vouchers
    Wallets
    Enable local payment methods by country
    Custom payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
Other Stripe products
Financial Connections
Crypto
Climate
HomePaymentsAdd payment methodsBuy now, pay laterAfterpay / Clearpay

Accept an Afterpay or Clearpay payment

Learn how to accept Afterpay (also known as Clearpay in the UK), a payment method in the US, CA, UK, AU, and NZ.

Copy page

Accepting Afterpay in your app consists of displaying a webview for a customer to authenticate their payment. The customer then returns to your app, and you can immediately confirm whether the payment succeeded or failed.

Note

Before you start the integration, make sure your account is eligible for Afterpay by navigating to your Payment methods settings.

Set up Stripe
Server-side
Client-side

First, you need a Stripe account. Register now.

Server-side

This integration requires endpoints on your server that talk to the Stripe API. Use the official libraries for access to the Stripe API from your server:

Command Line
Ruby
# Available as a gem sudo gem install stripe
Gemfile
Ruby
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

Client-side

The Stripe Android SDK is open source and fully documented.

To install the SDK, add stripe-android to the dependencies block of your app/build.gradle file:

build.gradle.kts
Kotlin
plugins { id("com.android.application") } android { ... } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:21.17.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:21.17.0") }

Note

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.

Configure the SDK with your Stripe publishable key so that it can make requests to the Stripe API, such as in your Application subclass:

Kotlin
import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext,
"pk_test_TYooMQauvdEDq54NiTphI7jx"
) } }

Note

Use your test keys while you test and develop, and your live mode keys when you publish your app.

Stripe samples also use OkHttp and GSON to make HTTP requests to a server.

Create a PaymentIntent
Server-side
Client-side

A PaymentIntent is an object that represents your intent to collect payment from a customer and tracks the lifecycle of the payment process through each stage.

Server-side

First, create a PaymentIntent on your server and specify the amount to collect and the currency. If you already have an integration using the Payment Intents API, add afterpay_clearpay to the list of payment method types for your PaymentIntent.

Command Line
curl
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "amount"=1099 \ -d "currency"="usd" \ -d "payment_method_types[]"="afterpay_clearpay"

Additional payment method options

You can specify an optional reference parameter in the payment method options for your PaymentIntent that sets an internal order identifier for the payment. Although this isn’t typically visible to either the business or the consumer, Afterpay’s internal support team can access it during manual support requests. The identifier is limited to 128 characters and may contain only letters, digits, underscores, backslashes, and dashes.

Command Line
curl
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "amount"=1099 \ -d "currency"="usd" \ -d "payment_method_types[]"="afterpay_clearpay" \ -d "payment_method_options[afterpay_clearpay][reference]"="order_123"

Client-side

Included in the returned PaymentIntent is a client secret, which the client side can use to securely complete the payment process instead of passing the entire PaymentIntent object. On the client, request a PaymentIntent from your server and store its client secret.

Kotlin
class AfterpayPaymentActivity: AppCompatActivity() { private lateinit var paymentIntentClientSecret: String override fun onCreate(savedInstanceState: Bundle?) { // ... startCheckout() } private fun startCheckout() { // Request a PaymentIntent from your server and store its client secret } }

Collect payment method details
Client-side

Afterpay requires billing details to be present for the payment to succeed. In your app, collect the required billing details from the customer:

  • Full name (first and last)
  • Email address
  • Full billing address

Create a PaymentMethodCreateParams with these details.

Additionally, while shipping details aren’t required they can help improve authentication rates. To collect shipping details, collect the following from the customer:

  • Full name
  • Full shipping address

Create a ConfirmPaymentIntentParams.Shipping with these details.

Kotlin
val billingDetails = PaymentMethod.BillingDetails( name = "Jenny Rosen", email = "jenny@rosen.com", address = Address.Builder() .setLine1("1234 Market St") .setCity("San Francisco") .setState("CA") .setCountry("US") .setPostalCode("94111") .build() ) val paymentMethodCreateParams = PaymentMethodCreateParams.createAfterpayClearpay(billingDetails) // Shipping details are optional but recommended to pass in. val shippingDetails = ConfirmPaymentIntentParams.Shipping( name = "Jenny Rosen", address = Address.Builder() .setLine1("1234 Market St") .setCity("San Francisco") .setState("CA") .setCountry("US") .setPostalCode("94111") .build() )

Submit the payment to Stripe
Client-side

Retrieve the client secret from the PaymentIntent you created in step 2 and call the PaymentLauncher confirm method. This presents a webview where the customer can complete the payment on their bank’s website or app. Afterwards, onActivityResult is called with the result of the payment.

Kotlin
class AfterpayPaymentActivity : AppCompatActivity() { // ... private lateinit var paymentIntentClientSecret: String private val paymentLauncher: PaymentLauncher by lazy { val paymentConfiguration = PaymentConfiguration.getInstance(applicationContext) PaymentLauncher.Companion.create( this, paymentConfiguration.publishableKey, paymentConfiguration.stripeAccountId, ::onPaymentResult ) } private fun startCheckout() { // ... // Shipping details are optional but recommended to pass in. val confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams( paymentMethodCreateParams = paymentMethodCreateParams, clientSecret = paymentIntentClientSecret, shipping = shippingDetails ) paymentLauncher.confirm(confirmParams) } private fun onPaymentResult(paymentResult: PaymentResult) { when (paymentResult) { is PaymentResult.Completed -> { // show success UI } is PaymentResult.Canceled -> { // handle cancel flow } is PaymentResult.Failed -> { // handle failures // (for example, the customer may need to choose a new payment // method) } } } }

OptionalAdd line items to the PaymentIntent

OptionalSeparate authorization and capture

OptionalHandle post-payment events

OptionalTest Afterpay integration

Failed payments

Afterpay takes into account multiple factors when deciding to accept or decline a transaction (for example, length of time buyer has been using Afterpay, outstanding amount customer has to repay, value of the current order).

You should always present additional payment options such as card in your checkout flow, as Afterpay payments have a higher rate of decline than many payment methods. In these cases, the PaymentMethod is detached and the PaymentIntent object’s status automatically transitions to requires_payment_method.

For an Afterpay PaymentIntent with a status of requires_action, customers need to complete the payment within 3 hours after you redirect them to the Afterpay site (this doesn’t apply to declined payments). If they take no action within 3 hours, the PaymentMethod detaches and the object status for the PaymentIntent 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 codeRecommended action
payment_intent_payment_attempt_failedA generic failure indicating the Afterpay checkout failed. This can also be a decline which does not appear as a decline error code.
payment_method_provider_declineAfterpay declined the customer’s payment. As a next step, the customer needs to contact Afterpay for more information.
payment_intent_payment_attempt_expiredThe customer never completed the payment on Afterpay’s checkout page, and the payment session has expired. Stripe automatically expires Payment Intents that are not successfully authorized 3 hours after initial checkout creation.
payment_method_not_availableAfterpay experienced a service related error and is unable to complete the request. Retry at a later time.
amount_too_smallEnter an amount within Afterpay’s default transactions limits for the country.
amount_too_largeEnter an amount within Afterpay’s default transactions limits for the country.
Was this page helpful?
YesNo
Need help? Contact Support.
Join our early access program.
Check out our changelog.
Questions? Contact Sales.
LLM? Read llms.txt.
Powered by Markdoc