> This page is for Afterpay Online Developer, version Chinese.
> For other versions, use one of these documentation indexes:
> - Main (default): https://developers.afterpay.com/afterpay-online-developer/main/llms.txt
> - v1: https://developers.afterpay.com/afterpay-online-developer/v-1/llms.txt
> - Chinese: https://developers.afterpay.com/afterpay-online-developer/chinese/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.afterpay.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.afterpay.com/_mcp/server.

# 在您的网站上添加 Cash App Pay

Cash App Pay 是一种快速简便的*即时支付*方式。目前仅在美国可用。

客户可以通过两种方式使用 Cash App Pay 向您付款：

* 使用二维码从桌面设备购物

* 通过点击(tapping）从移动设备购物

以下是这两种支付流程的总结：

#### 使用二维码从桌面设备购物

1. 客户在结账时从桌面设备选择 Cash App Pay 作为支付方式。

2. 客户用移动设备摄像头或 Cash App 的二维码扫描器扫描桌面屏幕上显示的二维码。

3. 客户按照移动设备上的提示完成交易。

#### 通过点击从移动设备购物

1. 客户在结账时从移动设备点击 Cash App Pay 选择它作为支付方式。

2. 客户被重定向到 Cash App，在那里可以按照提示完成交易。

> **注意**
>
> Cash App Pay 是一种**即时支付**方式。客户使用 Cash App Pay 在购买时一次性支付商品和服务。
>
> Cash App Afterpay 是一种**延后支付**方式。客户使用 Cash App Afterpay 分几次免息支付商品和服务。

## 前端显示

如果您同时支持 Cash App Pay 和 Cash App Afterpay，您的结账和支付页面的前端显示会略有变化。

在结账或其他支付界面上，Cash App Pay 作为单独的支付选项与 Cash App Afterpay 并列显示。Cash App Pay 不在 Cash App Afterpay 选项内，而是与其并列显示。拥有 Cash App 账户的客户可以使用其 Cash App 余额作为支付来源进行分期付款。

## 可用地区

您需要了解 Cash App Pay 及其相关产品的可用地区：

* Cash App Pay 仅在美国可用

* Cash App Pay on file 仅在美国可用

## 详细信息

Cash App Pay on file 有单独的页面：

* [Cash App Pay on file](/afterpay-online-developer/chinese/cash-app-pay-on-file)

## 使用现有 Cash App Afterpay API 集成 Cash App 支付

> **声明**
>
> 要在您网站的前端成功启动 Cash App Pay 屏幕流程，您必须使用与[启动 Cash App Afterpay 屏幕流程](https://developers.cash.app/docs/merchant/online-api/adding-afterpay-to-your-site/standard-checkout)相同的 JS 脚本。
>
> 例如，`<script onload="initAfterPay()" src="https://portal.sandbox.afterpay.com/afterpay.js" async defer></script>`

Cash App Pay 支付集成需要使用 Cash App Afterpay 结账流程的[标准 API](https://developers.cash.app/docs/merchant/online-api/adding-afterpay-to-your-site/standard-checkout)，且使用您现有的 Cash App Afterpay 凭证。Cash App Afterpay 后端会处理与 Cash App Pay 的交易。实施流程如下：

1. 调用[创建结账 API](https://developers.cash.app/docs/merchant/reference/checkouts/operations/create-a-v-2-checkout)，添加参数 `isCashAppPay: true` 以创建订单令牌。

2. 将令牌与[标准结账](https://developers.cash.app/docs/merchant/online-api/adding-afterpay-to-your-site/standard-checkout)流程结合使用，但调用 `AfterPay.initializeForCashAppPay` 而不是 Afterpay，如下面的代码示例所示：

   ```js
   function initAfterPay() {

       var cashAppPayOptions = {
           button: {
               size: 'small', // "medium" | "small"
               width: 'full', // "full" | "static"
               theme: 'dark', // "dark" | "light"
               shape: 'round' // "round" | "semiround"
           },
           onComplete: function(event) {
               const {
                   status,
                   cashtag
               } = event.data;
           },
           /* Optional event listeners for merchants to track customer behavior and listen for transaction events in the lifecycle */
           eventListeners: {
               "CUSTOMER_INTERACTION": ({
                   isMobile
               }) => {
                   console.log(`CUSTOMER_INTERACTION`)
                   if (isMobile) {
                       // captureMobileMetrics()
                   } else {
                       // captureDesktopMetrics()
                   };
               },
               "CUSTOMER_REQUEST_DECLINED": () => {
                   console.log(`CUSTOMER_REQUEST_DECLINED`)
               },
               "CUSTOMER_REQUEST_APPROVED": () => {
                   console.log(`CUSTOMER_REQUEST_APPROVED`)
               },
               "CUSTOMER_REQUEST_FAILED": () => {
                   console.log(`CUSTOMER_REQUEST_FAILED`)
               }
           }
       }
       AfterPay.initializeForCashAppPay({
           countryCode: "US",
           token: "ORDER_TOKEN_PLACEHOLDER",
           cashAppPayOptions
       });
   }
   ```

3. 在您想要渲染 Cash App Pay 按钮的位置添加 `id="cash-app-pay"` 的 div。

4. 点击按钮后，客户会看到二维码（在桌面端）。

   ![Cash App Pay 二维码](/_fern-img/3028cb6db3527b5cf9a8ef02b6e2c4b981316d3d7319c369d9596697ff341234.webp)

5. 如果客户确认订单，将返回订单令牌、客户的 Cashtag 和 SUCCESS 状态。如果客户取消订单，将返回订单令牌和 CANCELLED 状态。我们建议您在审核或确认页面上向客户显示 Cashtag。以下是event object的示例：

```JavaScript
event: {
    "data": {
        "status": "SUCCESS",
        "cashtag": "$CASHTAG_PLACEHOLDER",
        "orderToken": "ORDER_TOKEN_PLACEHOLDER",
    }
}
```

> **Cashtag 的显示基于沙盒或正式环境**
>
> * **沙盒环境：** Cash App Afterpay 沙盒始终返回 Cashtag：`$CASHTAG_C_TOKEN`。
>
> * **生产环境：** 在生产环境中，返回每个客户的实际 Cashtag。

6. 根据您用于 Cash App Afterpay 的[支付流程](https://developers.cash.app/docs/merchant/api-development/api-calls-payment-flows)，按照相同的流程完成订单。调用[授权](https://developers.cash.app/docs/merchant/reference/payments/operations/create-a-v-2-payment-auth)或[直接捕获](https://developers.cash.app/docs/merchant/reference/payments/operations/create-a-v-2-payment-capture-1)。完成授权或直接捕获 API 后，您将从 Cash App Afterpay 收到 APPROVED 或 DECLINED 状态。

## 移动设备端(手机)跳转

在移动端，客户不会看到二维码，而是被重定向到 Cash App。当客户同意后，他们会被返回到创建结账调用中 `redirectConfirmUrl` 指定的 URL。这可以是渲染 Cash App Pay 按钮的同一页面，例如 merchant.com/checkout，或一个新页面，例如 `merchant.com/review`

> **可以向 redirectConfirmURL 添加查询参数：**
>
> 如果您想确定页面是否因从 Cash App 重定向而加载，可以向 redirectConfirmURL 添加查询参数。例如 merchant.com/checkout?cashapppay=true
>
> **redirectCancelURL 不被 Cash App Pay 使用：** 在移动端，对于已批准和已拒绝的流程，客户始终被重定向到 redirectConfirmUrl。

`redirectConfirmUrl` 指向的页面应在页面加载时初始化 afterpay.js 并定义以下 `onComplete` 回调：

```JavaScript
function onPageLoad () {
    var cashAppPayListenerOptions = { 
        onComplete: function(event) {
          const { status, cashtag, orderToken} = event.data;
        },
        /* Optional event listeners for merchants to track customer behavior and listen for transaction events in the lifecycle */
           eventListeners: {
                "CUSTOMER_INTERACTION": ({ isMobile }) => {
                    console.log(`CUSTOMER_INTERACTION`)
                    if (isMobile) {
                        // captureMobileMetrics()
                    } else {
                        // captureDesktopMetrics()
                    };
                },
                "CUSTOMER_REQUEST_DECLINED": () => {
                    console.log(`CUSTOMER_REQUEST_DECLINED`)
                },
                 "CUSTOMER_REQUEST_APPROVED": () => {
                    console.log(`CUSTOMER_REQUEST_APPROVED`)
                },
                "CUSTOMER_REQUEST_FAILED": () => {
                    console.log(`CUSTOMER_REQUEST_FAILED`)
                }
            }
      }

    AfterPay.initializeCashAppPayListeners({countryCode: "US", cashAppPayListenerOptions});
}
```

## 为新的结账请求重启 Cash App Pay

> **Note**
>
> 要实施此功能,您必须使用 高级渲染。

### 结账完成后

成功结账后，客户可能会访问另一个页面，然后返回结账页面下单而不刷新页面。或者在另一种情况下，您可能希望在客户完成结账后立即提供追加销售(upsell)。

当您需要使用 Cash App Pay 接受新订单时，可以调用 `AfterPay.restartCashAppPay`。

```js
AfterPay.restartCashAppPay()
AfterPay.renderCashAppPayButton()
```

重启后，AfterPay.js "忘记"所有先前的授权和之前收取的金额。它还会移除所有 Cash App Pay UI（例如，Cash App Pay 按钮、二维码模态框或已批准的 Cashtag）。

我们建议在单页应用中，每当客户离开结账页面时都调用 `AfterPay.restartCashAppPay`。在离开每个页面时重启时，如果客户返回结账页面，您的初始化流程将正常工作。客户永远不会看到之前客户请求的二维码。

### 结账完成前

在某些情况下，必须在成功结账之前重新渲染和重新初始化支付按钮。例如，如果客户选择 Cash App Pay，切换到其他支付方式，然后重新选择 Cash App Pay。

当客户重新选择 Cash App Pay 时，调用 `AfterPay.renderCashAppPayButton` 重新渲染按钮。然后通过调用 `AfterPay.restartCashAppPay` 重启 Cash App Pay。

```js
AfterPay.restartCashAppPay()
AfterPay.renderCashAppPayButton()
```

由于原始结账令牌未使用，您可以将该令牌与 `AfterPay.initializeForCashAppPay(...)` 一起使用。

## 使用 Cash App 退款

Cash App Pay 购买和退款流程遵循标准的 Cash App Afterpay 支付退款和取消流程。

但是，如果在退款 Cash App Pay 订单时出现错误，在Payload中将提供额外信息。请参见下面的示例代码：

**示例代码**

```
{
"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
}
```

> **Info**
>
> 您可以在[此处](https://developers.cash.app/docs/api/technical-documentation/api-fundamentals/errors/error-code-reference#payment-processing-errors)找到完整的 Cash App Pay 错误代码列表。

## 与 Cash App 结算

所有支付解决方案由 Cash App Afterpay 处理。您的结算信息会区分 Cash App Afterpay 和 Cash App 。

## 在二维码扫描信息中添加您的Logo

在 Cash App Pay 结账期间显示的二维码弹窗中添加您公司或组织的Logo。您决定使用此Logo，将其 URL 发送给我们，我们将其放在二维码旁边。请参见下图示例：

![qr-code-afterpay-resized.png](/_fern-img/8aa0a64ce9f324ba2aa9c5954e451d285e8fd742cc396194c208938ad3296833.webp)

操作步骤：

1. 使用您Logo的URL。合适的Logo必须：

* 尺寸至少为 256 x 256 像素

* 文件大小不超过 2MB

* 为正方形Logo，因为其他形状会变形

* 在Logo图像周围留有间距/填充，以确保显示时Logo的任何部分都不会被裁剪

* 格式为 .png、.jpg 或 .jpeg

2. 联系您的 Cash App Afterpay 销售联系人或 Cash App Afterpay 集成联系人，并向他们发送Logo URL。

3. 我们（Cash App Afterpay）将确保您的Logo出现在 Cash App Pay 二维码旁边。

品牌Logo对于 Cash App Pay 的运行不是必需的，但这样的联合品牌展示可以增强结账时的客户体验。如果您想要展示logo的话，这部分需要通过认证测试才能上线。

## 高级渲染控制

作为普通渲染，我们提供一个完全托管且带有品牌的 UI，其中包括 Cash App Pay 按钮。

在某些情况下，您可能需要高级控制。例如，您可能希望在交易继续之前验证客户在结账期间提供的信息。调用 `AfterPay.renderCashAppPayButton` 时，通过 `onBegin` 回调返回一个开始方法，供您在准备就绪时调用。

### 创建您的自定义按钮

您有两个选择 - 使用 JavaScript 创建自定义按钮，或直接使用 HTML。

**JavaScript**

```JavaScript
function createCustomButton() {
  // Create custom button
  const cashAppPayCustomButton = document.createElement('button');
  cashAppPayCustomButton.classList.add('btn', 'cash-app-pay-custom-button');
  cashAppPayCustomButton.textContent = "Continue with";

  // Attach cash app pay logo to button
  const cashAppPayLogo = document.createElement('cash-app-pay-logo');
  cashAppPayCustomButton.appendChild(cashAppPayLogo);
  document.getElementById('cash-app-pay').after(cashAppPayCustomButton);
}
```

**HTML**

```HTML
<button class="btn cash-app-pay-custom-button">
  Continue with<cash-app-pay-logo></cash-app-pay-logo>
</button>
```

`<cash-app-pay-logo>` 元素渲染 Cash App Pay Logo。您可以在"选择支付方式页面"上使用此Logo，或用它增强您的结账按钮。

### 在准备就绪时初始化授权流程

您可能希望在结账体验中使用特定按钮以保持支付方式之间的一致性。当管理选项为 `false` 时，您也可以将按钮选项设置为 `false`。这会阻止渲染 Cash App Pay 按钮。您现在可以提供自己的按钮并管理授权流程。

```JavaScript
// Attach event listener to custom button described in previous section
function addEventListenerToCashAppPayButton(func) {
  const customButton = document.querySelector('.cash-app-pay-custom-button')
  customButton.addEventListener('click', func);
}

// Initialize CashAppPay flow
// This can be used standalone or within the onBegin callback from renderCashAppPayButton
function initializeForCashAppPay(token) {
  var cashAppPayOptions = {
    onComplete: function(event) {
      console.log(`onComplete: ${JSON.stringify(event.data, null, 4)}`);
      var { cashtag } = event.data;
      document.querySelector('.cash-app-pay-custom-button').setAttribute('hidden', true); // hide button
      var cashAppPayCustomer = document.querySelector('cash-app-pay-customer');
      cashAppPayCustomer.setAttribute('cashtag', cashtag);
      cashAppPayCustomer.removeAttribute('hidden'); // show cashtag
    },
    /* Optional event listeners */
    eventListeners: {
      "CUSTOMER_INTERACTION": ({ isMobile }) => {
        console.log(`CUSTOMER_INTERACTION is on Mobile: ${isMobile}`)
      },
      "CUSTOMER_REQUEST_DECLINED": () => {
        console.log(`CUSTOMER_REQUEST_DECLINED`)
      },
      "CUSTOMER_REQUEST_APPROVED": () => {
        console.log(`CUSTOMER_REQUEST_APPROVED`)
      },
      "CUSTOMER_REQUEST_FAILED": () => {
        console.log(`CUSTOMER_REQUEST_FAILED`)
      },
      "CUSTOMER_DISMISSED": () => {
        console.log(`CUSTOMER_DISMISSED`)
      }
    }
  }

  AfterPay.initializeForCashAppPay({
    countryCode: "US",
    token,
    cashAppPayOptions
  });
}

// Load PayKit and render CashAppPayButton without making any additional API calls. Token from createCheckout is not required.
function renderCashAppPayButton() {
  var cashAppPayButtonOptions = {
    button: false, // button set to false prevents rendering of Cash App Pay button, allowing use of custom button
    manage: false, // when manage option is false, a begin function will be returned for merchant to call when ready
    onBegin: function({ begin }) {
      addEventListenerToCashAppPayButton(async (event) => {
        event.preventDefault();
        const token = await createCheckout(true);
        initializeForCashAppPay(token);
        begin();
      });
    },
  }
  //This allows you to render the button without a token
  AfterPay.renderCashAppPayButton({
    countryCode: "US",
    cashAppPayButtonOptions
  });
}
```

## 故障排除

### CSP - 内容安全策略

如果您想使用 Cash App Pay 并有 CSP（内容安全策略），请确保 CSP 将 paykit 的 `pay.css` 文件列入白名单。

此白名单必须同样适用于 Cash App Pay 的生产和沙盒版本。