Cash App Pay payments
Add support for Cash App Pay to your integration.
We recommend that you implement the custom payment flow integration. The custom payment flow allows you to add Cash App Pay and other payment methods to your integration with the least amount of effort. Accepting Cash App Pay using a Direct API integration consists of:
- Creating a PaymentIntent object to track a payment.
- Submitting the payment to Stripe for processing.
- Authenticating the payment (through a mobile application redirect or QR code).
- Handling post-payment events to redirect the customer after an order succeeds or fails.
Set up StripeServer-side
First, you need a Stripe account. Register now.
Use our official libraries for access to the Stripe API from your application:
Create a PaymentIntentServer-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.
To create a PaymentIntent
on your server:
- Specify the amount to collect and the currency.
- Add
cashapp
to the list of payment method types for yourPaymentIntent
. Make sure Cash App Pay is enabled in the Dashboard.
Retrieve the client secret
The PaymentIntent includes a client secret that the client side uses to securely complete the payment process. You can use different approaches to pass the client secret to the client side.
Submit the payment to Stripe and authenticate transactions client-side
In this step, you’ll complete Cash App Pay payments on the client with Stripe.js. To authenticate a transaction, you must redirect the customer to Cash App.
Include the Stripe.js script on your checkout page by adding it to the head
of your HTML file.
<head> <title>Checkout</title> <script src="https://js.stripe.com/basil/stripe.js"></script> </head>
Create an instance of Stripe.js with the following JavaScript on your checkout page:
// Set your publishable key. Remember to change this to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe(
);'pk_test_TYooMQauvdEDq54NiTphI7jx'
Use stripe.
to confirm the PaymentIntent on the client side.
const form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); // Pass the clientSecret obtained from the server in step 2 as the first argument stripe.confirmCashappPayment( clientSecret, { payment_method: { type: 'cashapp', }, return_url: 'https://www.example.com/checkout/done', }, ); });
Caution
confirmCashappPayment
only redirects mobile browsers to your return_
, it doesn’t redirect desktop browsers. You can manually redirect customers using desktop browsers to your return URL after the returned promise resolves.
Customers can authenticate Cash App Pay transactions with mobile or desktop apps. The client the customer is using determines the authentication method after calling confirmCashappPayment
.
OptionalHandle redirect and authentication manually
We recommend using Stripe.js to handle redirects and authentication with confirmCashappPayment
. However, you can also handle redirects and authentication manually on your server.
Specify handleActions: false
in the confirmCashappPayment
call.
const form = document.getElementById('payment-form'); form.addEventListener('submit', function(event) { event.preventDefault(); // Set the clientSecret here you got in Step 2 stripe.confirmCashappPayment( clientSecret, { payment_method_data: { type: 'cashapp', }, return_url: 'https://www.example.com/checkout/done', }, { handleActions: false }, ).then((result) => { if (result.error) { // Display error to your customer. } else if (result.paymentIntent.status === "requires_action") { const nextAction = result.paymentIntent.next_action.cashapp_handle_redirect_or_display_qr_code; const expiresAt = nextAction.qr_code.expires_at; if (IS_MOBILE) { // This URL redirects the customer to Cash App to approve or decline the payment. const mobileAuthUrl = nextAction.mobile_auth_url; } else if (IS_DESKTOP) { // Render the QR code and display it to the customer using the below image source. const imageUrlSvg = nextAction.qr_code.image_url_svg; const imageUrlPng = nextAction.qr_code.image_url_png; } } }); });
OptionalSeparate authorization and capture
You can separate authorization and capture to create a charge now, but capture funds later. Stripe cancels the PaymentIntent and sends a payment_intent.canceled event if the payment isn’t captured during the 7-day window.
If you know that you can’t capture the payment, we recommend canceling the PaymentIntent instead of waiting for the 7-day window to elapse.
1. Tell Stripe to authorize only
To indicate that you want separate authorization and capture, set capture_method to manual
when creating the PaymentIntent. This parameter instructs Stripe to only authorize the amount on the customer’s Cash App Pay account.
2. Capture the funds
After the authorization succeeds, the PaymentIntent status transitions to requires_
. To capture the authorized funds, make a PaymentIntent capture request.
The total authorized amount is captured by default. You can also specify amount_
which can be less or equal to the total.
Optional Cancel the authorization
If you need to cancel an authorization, you can cancel the PaymentIntent.
OptionalHandle post-payment events
Stripe sends a payment_intent.succeeded event when the payment completes. Use the Dashboard, a custom webhook, or a partner solution to receive these events 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, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events also helps you accept more payment methods in the future. Learn about the differences between all supported payment methods.
Handle events manually in the Dashboard
Use the Dashboard to View your test payments in the Dashboard, send email receipts, handle payouts, or retry failed payments.
Build a custom webhook
Build a custom webhook handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI.
Integrate a prebuilt app
Handle common business events, such as automation or marketing and sales, by integrating a partner application.
Failed payments 
Cash App Pay uses multiple data points to decide when to decline a transaction (for example, their AI model detected high consumer fraud risk for the transaction, or the consumer has revoked your permission to charge them in Cash App).
In these cases, the PaymentMethod is detached and the PaymentIntent object’s status automatically transitions to requires_
.
Other than a payment being declined, for a Cash App Pay PaymentIntent with a status of requires_
, customers must complete the payment within 10 minutes after they’re redirected to Cash App. If no action is taken after 10 minutes, the PaymentMethod is detached and the PaymentIntent object’s status automatically transitions to requires_
.
When this happens, the Payment Element renders error messages and instructs your customer to retry using a different payment method.
Error codes 
The following table details common error codes and recommended actions:
Error Code | Recommended Action |
---|---|
payment_ | Enter the appropriate currency. Cash App Pay only supports usd . |
missing_ | Check the error message for more information about the required parameter. |
payment_ | This code can appear in the last_payment_error.code field of a PaymentIntent. Check the error message for a detailed failure reason and suggestion on error handling. |
payment_ | Provide a return_ when confirming a PaymentIntent with Cash App Pay. |