Adding Cash App Pay to Your Site

Cash App Pay is a fast and simple pay now payment method for your customers. Currently it is only available in the USA.

There are two ways customers can pay you with Cash App Pay:

These two payment flows are summarized below:

Shopping from a Desktop Device with a QR Code

  1. From their desktop device, the customer selects Cash App Pay as the payment method during checkout.

  2. The customer holds their mobile device camera or Cash App’s QR scanner over the QR code that appears on the desktop screen to scan the QR code.

  3. The customer follows the prompts on their mobile device to complete the transaction.

Shopping from a Mobile Device by Tapping

  1. From their mobile device, the customer taps Cash App Pay to select it as the payment method during checkout.

  2. The customer is redirected to Cash App, where they can follow the prompts to complete the transaction.

Remember that Cash App Pay is a pay now payment method. Customers use Cash App Pay to pay for goods and services in a single payment at the time of purchase.

Cash App Afterpay is a pay later payment method. Customers use Cash App Afterpay to pay for goods and services in several interest-free payments.

Appearance

If you implement Cash App Pay with Cash App Afterpay, expect the appearance of your checkout and payment pages to change slightly.

On checkout or other payment screens, Cash App Pay appears as a separate payment option alongside Cash App Afterpay. Cash App Pay is not within Cash App Afterpay, but provided alongside it. Customers with Cash App accounts can use their Cash App balance as a payment source to pay in installments.

Availability

It is important you are aware of Cash App Pay availability along with its related products:

  • Cash App Pay is only available in the USA

  • Cash App Pay on file is only available in the USA

Detailed Information

The following sections are on this page:

Cash App Pay on file has a page of its own:

Integrating Cash App Payments Using the Existing Cash App Afterpay API

Disclaimer

To successfully launch the Cash App Pay screenflow on your website’s front-end, you must use the exact same JS script employed for launching the Cash App Afterpay screenflow.

For example, <script onload="initAfterPay()" src="https://portal.sandbox.afterpay.com/afterpay.js" async defer></script>

Accepting Cash App Pay payments uses the standard API for the Cash App Afterpay checkout process, with your existing Cash App Afterpay credentials. The Cash App Afterpay backend handles the transaction with Cash App Pay. The implementation process is as follows:

  1. Call the Create Checkout API with the addition of the following parameter isCashAppPay: true to create an order token.

  2. Use the token in combination with the Standard Checkout flow, but call AfterPay.initializeForCashAppPay instead of Afterpay. like in the code sample below:

    1function initAfterPay() {
    2
    3 var cashAppPayOptions = {
    4 button: {
    5 size: 'small', // "medium" | "small"
    6 width: 'full', // "full" | "static"
    7 theme: 'dark', // "dark" | "light"
    8 shape: 'round' // "round" | "semiround"
    9 },
    10 onComplete: function(event) {
    11 const {
    12 status,
    13 cashtag
    14 } = event.data;
    15 },
    16 /* Optional event listeners for merchants to track customer behavior and listen for transaction events in the lifecycle */
    17 eventListeners: {
    18 "CUSTOMER_INTERACTION": ({
    19 isMobile
    20 }) => {
    21 console.log(`CUSTOMER_INTERACTION`)
    22 if (isMobile) {
    23 // captureMobileMetrics()
    24 } else {
    25 // captureDesktopMetrics()
    26 };
    27 },
    28 "CUSTOMER_REQUEST_DECLINED": () => {
    29 console.log(`CUSTOMER_REQUEST_DECLINED`)
    30 },
    31 "CUSTOMER_REQUEST_APPROVED": () => {
    32 console.log(`CUSTOMER_REQUEST_APPROVED`)
    33 },
    34 "CUSTOMER_REQUEST_FAILED": () => {
    35 console.log(`CUSTOMER_REQUEST_FAILED`)
    36 }
    37 }
    38 }
    39 AfterPay.initializeForCashAppPay({
    40 countryCode: "US",
    41 token: "ORDER_TOKEN_PLACEHOLDER",
    42 cashAppPayOptions
    43 });
    44}
  3. Add a div with id="cash-app-pay" where you want the Cash App Pay button to be rendered.

  4. On clicking the button the customer is shown a QR code (on desktop).

    Cash App Pay QR Code

  5. If the customer confirms the order, an Order Token, the customer’s Cashtag, and a SUCCESS status is returned. If the customer cancels the order, the Order Token and CANCELLED status are returned. We recommend that you display the Cashtag to the customer on the review or confirmation page. This is an example event object:

1event: {
2 "data": {
3 "status": "SUCCESS",
4 "cashtag": "$CASHTAG_PLACEHOLDER",
5 "orderToken": "ORDER_TOKEN_PLACEHOLDER",
6 }
7}
Cashtags are returned based on the environment
  • Sandbox: The Cash App Afterpay Sandbox always returns the Cashtag: $CASHTAG_C_TOKEN.
  • Production: In production, each customer’s actual Cashtag is returned.
  1. Depending on the payment flows you use for Cash App Afterpay, you follow the same process to complete an order. Either call Auth or Direct Capture. You receive an APPROVED or DECLINED status from Cash App Afterpay once the Auth or Direct Capture API has been completed.

Mobile Redirection

On Mobile, instead of a QR code, the customer is redirected to the Cash App. When the customer approves, they are returned to the URL specified in the redirectConfirmUrl in the Create Checkout call. This can be the same page where the Cash App Pay button is rendered e.g. merchant.com/checkout, or a new page for example, merchant.com/review

Query Params can be added to the redirectConfirmURL

If you want to determine if the page is loading as a result of redirect from the Cash App, you can add a query param to your redirectConfirmURL. e.g. merchant.com/checkout?cashapppay=true

The redirectCancelURL is not used by Cash App Pay

On mobile, the customer is always redirected to the redirectConfirmUrl for approved and declined flows.

The page the redirectConfirmUrl points to should initialize afterpay.js and define the below onComplete callback on page load:

1function onPageLoad () {
2 var cashAppPayListenerOptions = {
3 onComplete: function(event) {
4 const { status, cashtag, orderToken} = event.data;
5 },
6 /* Optional event listeners for merchants to track customer behavior and listen for transaction events in the lifecycle */
7 eventListeners: {
8 "CUSTOMER_INTERACTION": ({ isMobile }) => {
9 console.log(`CUSTOMER_INTERACTION`)
10 if (isMobile) {
11 // captureMobileMetrics()
12 } else {
13 // captureDesktopMetrics()
14 };
15 },
16 "CUSTOMER_REQUEST_DECLINED": () => {
17 console.log(`CUSTOMER_REQUEST_DECLINED`)
18 },
19 "CUSTOMER_REQUEST_APPROVED": () => {
20 console.log(`CUSTOMER_REQUEST_APPROVED`)
21 },
22 "CUSTOMER_REQUEST_FAILED": () => {
23 console.log(`CUSTOMER_REQUEST_FAILED`)
24 }
25 }
26 }
27
28 AfterPay.initializeCashAppPayListeners({countryCode: "US", cashAppPayListenerOptions});
29}

Restarting Cash App Pay for a New Checkout Request

To implement this functionality, you must be using advanced rendering.

After checkout completion

After a successful checkout, the customer may visit another page, and then return to the checkout page to place an order without refreshing the page. Or in another scenario, you may want to provide an upsell immediately after the customer completes the checkout.

When you need to take a new order with Cash App Pay, you can call AfterPay.restartCashAppPay.

1AfterPay.restartCashAppPay()
2AfterPay.renderCashAppPayButton()

When restarted, AfterPay.js “forgets” all previous authorizations and previously charged amounts. It also removes all Cash App Pay UI (for example, the Cash App Pay button, QR code modal, or approved Cashtag).

We recommend that in a single page app, you call AfterPay.restartCashAppPay whenever the customer leaves the checkout page. When restarting at the exit of each page, if a customer comes back to the checkout page, your initialization flow works as normal. The customer never sees the QR code for a previous customer request.

Before checkout completion

In some cases, the payment button must be re-rendered and re-initialized without a successful checkout. For example, if a customer selects Cash App Pay, switches to a different payment method, and then re-selects Cash App Pay.

When a customer re-selects Cash App Pay, call AfterPay.renderCashAppPayButton to re-render the button. Next, restart Cash App Pay by calling AfterPay.restartCashAppPay.

1AfterPay.restartCashAppPay()
2AfterPay.renderCashAppPayButton()

Since the original checkout token is unused, you can use that token with AfterPay.initializeForCashAppPay(...).

Payment Refunds with Cash App

Cash App Pay purchase and refund flows follow the standard Cash App Afterpay payment refund and void processes.

However, if there is an error when refunding a Cash App pay order, additional information will be supplied in the payload. See the example code below to see this in action.

Example Code

{
"errorCode": "declined",
"errorId": "ERROR_ID_PLACEHOLDER",
"message": "Cash App declined refund request (permanent decline): PAYMENT_PROCESSING_ERROR REFUND_DECLINED_OTHER Refund could not be created.",
"httpStatusCode": 422
}

You can find a complete list of Cash App Pay error codes here.

Settlement with Cash App

All payment resolution is handled by Cash App Afterpay. Your settlement information differentiates between Cash App Afterpay and Cash App sales.

Add Your Logo to the QR Code Scanner

Add your company or organization’s logo to the QR code pop-up that appears during Cash App Pay checkout. You host this logo, send us its URL and we place it next to the QR code. See an example in the picture below:

qr-code-afterpay-resized.png

To do this:

  1. Host your logo with its own URL. An appropriate logo must be:
  • At least 256 x 256 pixels in size

  • No larger than a 2MB file size

  • A square logo, because other shapes get distorted.

  • Produced with spacing/padding around the logo image, so that no part of the logo is cut-off when it is displayed

  • In a format of either .png, .jpg, or .jpeg

  1. Contact your Cash App Afterpay sales contact or Cash App Afterpay merchant services representative and send them the logo URL.

  2. We (Cash App Afterpay) will ensure your logo appears next to the Cash App Pay QR code.

A brand logo is not necessary for Cash App Pay to work, although the co-branding enhances the customer experience at checkout. Your brand logo is required to pass certification testing.

Advanced Rendering Control

As standard, we provide a fully managed and branded UI that includes a Cash App Pay button.

In some situations you may want advanced controls. For example, you may want to validate information a customer has given during checkout before the transaction continues. When AfterPay.renderCashAppPayButton is called, a begin method is returned through the onBegin callback for you to call when you’re ready.

Create Your Custom Button

You have two choices - to use JavaScript to create the custom button, or to use HTML direct.

JavaScript

1function createCustomButton() {
2 // Create custom button
3 const cashAppPayCustomButton = document.createElement('button');
4 cashAppPayCustomButton.classList.add('btn', 'cash-app-pay-custom-button');
5 cashAppPayCustomButton.textContent = "Continue with";
6
7 // Attach cash app pay logo to button
8 const cashAppPayLogo = document.createElement('cash-app-pay-logo');
9 cashAppPayCustomButton.appendChild(cashAppPayLogo);
10 document.getElementById('cash-app-pay').after(cashAppPayCustomButton);
11}

HTML

1<button class="btn cash-app-pay-custom-button">
2 Continue with<cash-app-pay-logo></cash-app-pay-logo>
3</button>

The <cash-app-pay-logo> element renders a Cash App Pay logo. You can use this logo on your “choose a payment method page,” or to enhance your checkout button.

Initialize the Authorization Flow when Ready

You may want to use a specific button in your checkout experience for consistency across payment methods. When the manage option is false, you can also set the button option to false. This stops a Cash App Pay button from being rendered. You can now provide your own button and manage the authorization flow.

1// Attach event listener to the custom button described in the previous section
2function addEventListenerToCashAppPayButton(func) {
3 const customButton = document.querySelector('.cash-app-pay-custom-button')
4 customButton.addEventListener('click', func);
5}
6
7// Initialize the CashAppPay flow
8// This can be by itself or within the onBegin callback from renderCashAppPayButton
9function initializeForCashAppPay(token) {
10 var cashAppPayOptions = {
11 onComplete: function(event) {
12 console.log(`onComplete: ${JSON.stringify(event.data, null, 4)}`);
13 var { cashtag } = event.data;
14 document.querySelector('.cash-app-pay-custom-button').setAttribute('hidden', true); // hide the button
15 var cashAppPayCustomer = document.querySelector('cash-app-pay-customer');
16 cashAppPayCustomer.setAttribute('cashtag', cashtag);
17 cashAppPayCustomer.removeAttribute('hidden'); // show the cashtag
18 },
19 /* Optional event listeners */
20 eventListeners: {
21 "CUSTOMER_INTERACTION": ({ isMobile }) => {
22 console.log(`CUSTOMER_INTERACTION is on Mobile: ${isMobile}`)
23 },
24 "CUSTOMER_REQUEST_DECLINED": () => {
25 console.log(`CUSTOMER_REQUEST_DECLINED`)
26 },
27 "CUSTOMER_REQUEST_APPROVED": () => {
28 console.log(`CUSTOMER_REQUEST_APPROVED`)
29 },
30 "CUSTOMER_REQUEST_FAILED": () => {
31 console.log(`CUSTOMER_REQUEST_FAILED`)
32 },
33 "CUSTOMER_DISMISSED": () => {
34 console.log(`CUSTOMER_DISMISSED`)
35 }
36 }
37 }
38
39 AfterPay.initializeForCashAppPay({
40 countryCode: "US",
41 token,
42 cashAppPayOptions
43 });
44}
45
46// Load PayKit and render the CashAppPayButton without making any additional API calls. Token from createCheckout is not required.
47function renderCashAppPayButton() {
48 var cashAppPayButtonOptions = {
49 button: false, // button set to false prevents a Cash App Pay button from being rendered so you can use your own custom button
50 manage: false, // when the manage option is false, a begin function will be returned for merchant to call when they're ready
51 onBegin: function({ begin }) {
52 addEventListenerToCashAppPayButton(async (event) => {
53 event.preventDefault();
54 const token = await createCheckout(true);
55 initializeForCashAppPay(token);
56 begin();
57 });
58 },
59 }
60 //This allows you to render the button without a token
61 AfterPay.renderCashAppPayButton({
62 countryCode: "US",
63 cashAppPayButtonOptions
64 });
65}

Troubleshooting

CSP - Content Security Policy

If you want to use Cash App Pay and have a CSP (Content Security Policy), please ensure that the CSP whitelists paykit’s pay.css file.

This whitelisting must apply equally to both the production and sandbox versions of Cash App Pay.