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.
Caution
The content of this section refers to a Legacy product. You should use the Accept a payment guide for the most recent integration path instead. While Stripe still supports this product, this support might end if the product is deprecated.
Stripe users can use the Payment Intents API – a single integration path for creating payments using any supported method – to accept Afterpay payments from customers in the following countries:
- Australia
- Canada
- New Zealand
- United Kingdom
- United States
Afterpay is a single use, immediate notification payment method that requires customers to authenticate their payment. Customers are redirected to the Afterpay site, where they agree to the terms of an instalment plan. When the customer accepts the terms, funds are guaranteed and transferred to your Stripe account. The customer repays Afterpay directly over time.
Note
Before you start the integration, make sure your account is eligible for Afterpay by navigating to your Payment methods settings.
Set up StripeServer-sideClient-side
Server-side
This integration requires endpoints on your server that talk to the Stripe API. Use our official libraries for access to the Stripe API from your server:
Client-side
The React Native SDK is open source and fully documented. Internally, it uses the native iOS and Android SDKs. To install Stripe’s React Native SDK, run one of the following commands in your project’s directory (depending on which package manager you use):
Next, install some other necessary dependencies:
- For iOS, navigate to the ios directory and run
pod install
to ensure that you also install the required native dependencies. - For Android, there are no more dependencies to install.
Note
We recommend following the official TypeScript guide to add TypeScript support.
Stripe initialisation
To initialise Stripe in your React Native app, either wrap your payment screen with the StripeProvider
component, or use the initStripe
initialisation method. Only the API publishable key in publishableKey
is required. The following example shows how to initialise Stripe using the StripeProvider
component.
import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( <StripeProvider publishableKey={publishableKey} merchantIdentifier="merchant.identifier" // required for Apple Pay urlScheme="your-url-scheme" // required for 3D Secure and bank redirects > {/* Your app code here */} </StripeProvider> ); }
Create a PaymentIntentServer-sideClient-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_
to the list of payment method types for your PaymentIntent
.
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.
const fetchPaymentIntentClientSecret = async () => { const response = await fetch(`${API_URL}/create-payment-intent`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ currency: 'usd', payment_method_types: ['afterpay_clearpay'], }), }); const {clientSecret, error} = await response.json(); return {clientSecret, error}; };
Collect payment method detailsClient-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
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
export default function AfterpayClearpayPaymentScreen() { const [email, setEmail] = useState(''); const handlePayPress = async () => { const billingDetails: PaymentMethodCreateParams.BillingDetails = { email, phone: '+48888000888', addressCity: 'Houston', addressCountry: 'US', addressLine1: '1459 Circle Drive', addressLine2: 'Texas', addressPostalCode: '77063', name: 'Jenny Rosen', }; // Shipping details are optional but recommended to pass in. const shippingDetails: PaymentMethodCreateParams.ShippingDetails = { addressLine1: '1459 Circle Drive', addressCountry: 'US', addressPostalCode: '77063', name: 'Jenny Rosen', }; // ... }; return ( <Screen> <TextInput placeholder="E-mail" onChange={(value) => setEmail(value.nativeEvent.text)} /> </Screen> ); }
Submit the payment to StripeClient-side
Retrieve the client secret from the PaymentIntent you created and call confirmPayment
. You should still handle the client secret carefully because it can complete the charge. Don’t log it, embed it in URLs, or expose it to anyone but the customer.
export default function AfterpayClearpayPaymentScreen() { const [email, setEmail] = useState(''); const handlePayPress = async () => { // ... const {error, paymentIntent} = await confirmPayment(clientSecret, { paymentMethodType: 'AfterpayClearpay', paymentMethodData: { billingDetails, // Shipping details are optional but recommended to pass in. shippingDetails, }, }); if (error) { Alert.alert(`Error code: ${error.code}`, error.message); } else if (paymentIntent) { Alert.alert( 'Success', `The payment was confirmed successfully! currency: ${paymentIntent.currency}`, ); } }; return <Screen>{/* ... */}</Screen>; }
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_
.
For an Afterpay PaymentIntent with a status of requires_
, 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_
.
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_ | A generic failure indicating the Afterpay checkout failed. This can also be a decline which does not appear as a decline error code. |
payment_ | Afterpay declined the customer’s payment. As a next step, the customer needs to contact Afterpay for more information. |
payment_ | The 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 authorised 3 hours after initial checkout creation. |
payment_ | Afterpay experienced a service related error and is unable to complete the request. Retry at a later time. |
amount_ | Enter an amount within Afterpay’s default transactions limits for the country. |
amount_ | Enter an amount within Afterpay’s default transactions limits for the country. |