# [Deprecated] 基于 Charges API 的银行卡付款

了解如何用 Stripe 的旧版 API 对银行卡执行扣款、保存及验证操作。

The content on this page is deprecated and is superseded by:

- [Accept a payment](https://docs.stripe.com/payments/accept-a-payment.md)
- [Build a payments page](https://docs.stripe.com/payments/checkout.md)
- [The Payment Intents API](https://docs.stripe.com/payments/payment-intents.md)

> #### Deprecated
> 
> 我们已经弃用了使用 Charges API 创建银行卡支付的功能，并计划移除对该 API 的支持。请改用 [Checkout](https://docs.stripe.com/payments/checkout.md) 或 [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md)。新集成将无法使用 Charges API 创建支付。
> 
> Charges API 不支持以下功能，信用卡合规对其中很多都有要求：
> 
> - 印度的企业
> - [银行的银行卡验证要求](https://docs.stripe.com/payments/cards/overview.md)
> - [强客户认证](https://docs.stripe.com/strong-customer-authentication.md)

If you use the Charges API, your access to newer Stripe features is limited. To get the latest features, [migrate to the Payment Intents API](https://docs.stripe.com/payments/payment-intents/migration.md).

## 付款流程

In most cases, the Payment Intents API offers more flexibility and integration options.

| Charges API | Payment Intents API |
| --- | --- |
| 1. 用 Elements 在浏览器上收集客户的支付信息。
2. 通过 Stripe.js 令牌化支付信息。
3. 执行请求，将令牌发送到服务器。
4. 用令牌以期望的金额和货币在您的服务器上创建收款。
5. 在付款成功后履行客户的订单。 | 1. 以期望的金额和货币在您的服务器上创建 PaymentIntent。
2. 将 PaymentIntent 的客户端私钥发送到客户端。
3. 用 Elements 在浏览器上收集客户的支付信息。
4. 用 Stripe.js 或移动 SDK 处理 [3DS 验证](https://docs.stripe.com/payments/3d-secure/authentication-flow.md#three-ds-radar)，并在客户端完成付款。
5. 用 Webhooks 在付款成功后履行客户的订单。 |

## 退款

要通过 API 退款，请创建一个[退款](https://docs.stripe.com/api.md#create_refund)，并提供要退还的收款的 ID。

```curl
curl https://api.stripe.com/v1/refunds \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d charge={{CHARGE_ID}}
```

要退还某笔付款的一部分，提供一个 `amount` 参数，以美分作为整数（或收款币种的最小货币单位）。

```curl
curl https://api.stripe.com/v1/refunds \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d charge={{CHARGE_ID}} \
  -d amount=1000
```

## Apple Pay

您的客户批准付款时，您的应用会收到一个 [PKPayment](https://developer.apple.com/documentation/passkit/pkpayment) 实例，其中包含他们通过实施 [PKPaymentAuthorizationViewControllerDelegate](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationviewcontrollerdelegate) 方式而加密的银行卡详情。

1. 使用 [createTokenWithPayment](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPAPIClient.html#/c:@CM@StripePayments@StripeCore@objc\(cs\)STPAPIClient\(im\)createTokenWithPayment:completion:)SDK 方法将 `PKPayment` 变成一个 Stripe `Token`
2. 使用此`Token`创建交易。

#### Swift

```swift
extension CheckoutViewController: PKPaymentAuthorizationViewControllerDelegate {

    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler: @escaping (PKPaymentAuthorizationResult) -> Void) {
        // Convert the PKPayment into a Token
        STPAPIClient.shared.createToken(withPayment: payment) { token, error in
              guard let token = token else {
                  // Handle the error
                  return
              }
            let tokenID = token.tokenId
            // Send the token identifier to your server to create a Charge...
            // If the server responds successfully, set self.paymentSucceeded to YES
        }
    }

    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
        // Dismiss payment authorization view controller
        dismiss(animated: true, completion: {
            if (self.paymentSucceeded) {
                // Show a receipt page...
            } else {
                // Present error to customer...
            }
        })
    }
}
```

## 动态账单描述符

默认情况下，每当您向客户银行卡扣款时，您 Stripe 账户的[对账单描述符](https://docs.stripe.com/get-started/account/set-up.md#public-business-information)都会显示在客户的对账单上。此外，您还可以通过收款对象中的 `statement_descriptor` 参数，在每笔扣款请求中动态设置对账单描述符。

#### curl

```bash
curl https://api.stripe.com/v1/charges \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=999 \
  -d "currency"="usd" \
  -d "description"="Example charge" \
  -d "source"="tok_visa" \
  -d "statement_descriptor"="Custom descriptor"
```

对账单描述符最多为 22 个字符，不能使用 `<`、`>`、`'`、`"` 或 `*` 这些特殊字符，且不能只包含数字。

动态设置信用卡和借记卡收款的对账单描述符时，动态部分会附加到结算商家的对账单描述符（用 `*` 和空格分割）。例如，有一家 FreeCookies 公司，其对账单描述符中包含购买的甜点的种类，则可能是 `FREECOOKIES* SUGAR`。

`*` 和空格算在这 22 个字符限制内，Stripe 自动为动态对账单描述符分配 10 个字符。这意味着，如果结算商家的描述符大于 10 个字符，则会被缩短（假设动态对账单描述符也大于 10 个字符的话）。如果动态对账单描述符也大于 10 个字符，则两个描述符都会缩短为 10 个字符。

如果您在字符限制方面有问题，可以在 Stripe 管理平台内设置一个[简短描述符](https://dashboard.stripe.com/settings/public)，缩短结算商家的描述符。这样可以为动态对账单描述符留出更多空间。简短描述符：

- 使用动态描述符时替换结算商家的对账单描述符。
- 可以介于 2 到 10 个字符之间。

> 如果您账户的对账单描述符超过 10 个字符，则在管理平台设置一个[简短描述符](https://dashboard.stripe.com/settings/public)或使用 `statement_descriptor_prefix`。这样可防止您的对账单描述符被意外缩短。

如果您不确定组合之后的对账单描述符具体是什么样子，可以在 [Stripe 管理平台](https://dashboard.stripe.com/settings/public)查看。

## 在元数据内存储信息

If using the [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md), only retrieve and update the `metadata` and `description` fields on the Payment Intent object. If using both the Payment Intent and Charge objects, you’re not guaranteed to see consistent values for these fields.

Stripe 支持向您的常见请求（例如处理收款）中添加[元数据](https://docs.stripe.com/api.md#metadata)。元数据不会向客户显示，也不会构成我们的欺诈预防系统拒绝或阻止收款的依据。

通过元数据，您可以向 Stripe 活动关联其他信息（对您自身有意义）。您包含的任何元数据都可以在管理平台内查看（例如，查看单笔收款的页数时），并且可用于常见的报告和导出结果中。举例来说，可以将您店铺的订单 ID 绑定到用来收取该订单付款的那笔收款。这样做的话，您、您的会计或您的财务团队都能很方便地核对 Stripe 内的收款与您系统内的订单。

如果您使用的是 *Radar* (Stripe Radar helps detect and block fraud by using machine learning. It's built into Stripe and requires no additional setup to get started)，请考虑将任何额外的客户信息和订单信息作为元数据传递。通过这样做，您就可以编写 [使用元数据属性的 Radar 规则](https://docs.stripe.com/radar/rules/reference.md#metadata-attributes)，并在管理平台中获得更多关于支付的信息，从而加快您的审核流程。

#### curl

```bash
curl https://api.stripe.com/v1/charges \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=999 \
  -d "currency"="usd" \
  -d "description"="Example charge" \
  -d "source"="tok_visa" \
  -d "metadata[order_id]"=6735
```

> 不要以元数据形式或在收款的 `description` 参数中存储任何敏感信息（个人身份信息、银行卡详情等）。

## 拒付

如要让您的集成自动响应付款失败的情况，可以通过两种方式访问扣款的 `outcome`。

- 付款失败时返回[处理 API 错误](https://docs.stripe.com/api.md#error_handling)。如果是阻止的付款和发卡行拒绝的付款，错误中会包含扣款 ID，可以用此 ID 来[检索](https://docs.stripe.com/api.md#retrieve_charge)该笔扣款。
- 用 [webhooks](https://docs.stripe.com/webhooks.md) 监测状态更新。例如，付款不成功时会触发 `charge.failed` 事件。
