# 迁移您的基础银行卡集成

迁移到一个可处理银行的银行卡验证要求的集成。

如果您遵循了[不进行银行验证的银行卡付款](https://docs.stripe.com/payments/without-card-authentication.md)指南，那么您创建的付款在银行要求客户验证付款时会被拒绝。

如果您开始看到大量失败的付款，如下面管理平台中这样的付款或 API 中显示有错误代码 `requires_action_not_handled` 的付款，则请升级您的基本集成，以处理而非拒绝这些付款。
![管理平台显示一笔付款失败，注明该银行要求对这笔付款进行验证。](https://b.stripecdn.com/docs-statics-srv/assets/failed-payment-dashboard.9e22ec31f3c7063665911e26e389c5dc.png)

使用本指南，了解如何升级您通过上一指南构建的集成，以添加服务器和客户端代码，通过显示一个模态提示客户验证付款。

> 前往 GitHub 查看该集成的[完整示例](https://github.com/stripe-samples/accept-a-payment/tree/master/custom-payment-flow)。

## 检查付款是否需要验证 [服务器端]

对您的服务器创建 PaymentIntent 的端点进行两项更改：

1. **删除** [error_on_requires_action](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-error_on_requires_action) 参数，不再对需要验证的付款作失败处理。此时，PaymentIntent 状态会变为 `requires_action`。
1. **添加** `confirmation_method` 参数，以表示您要在处理完验证请求后在服务器上再次明确（手动）确认付款。

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d amount=1099 \
  -d currency=usd \
  -d payment_method_types[]=card \
  -d confirm=true \-d payment_method="{{PAYMENT_METHOD_ID}}" \
  -d confirmation_method=manual
```

然后更新您的“生成响应”函数，使其处理 `requires_action` 状态，而不非显示错误：

#### curl

```bash
# If the request succeeds, check the
# PaymentIntent's `status` and handle
# its `next_action`.
```

## 让客户验证 [客户端]

然后，如果客户需要验证，则更新客户端代码，通知 Stripe 显示模态。

当 PaymentIntent 状态为 `requires_action` 时，使用 [stripe.handleCardAction](https://docs.stripe.com/js.md#stripe-handle-card-action)。如果成功，则 PaymentIntent 状态变为 `requires_confirmation`，这时需要在您的服务器再次确认 PaymentIntent 来完成付款。

```javascript
const handleServerResponse = async (responseJson) => {
  if (responseJson.error) {
    // Show error from server on payment form} else if (responseJson.requiresAction) {
    // Use Stripe.js to handle the required card action
    const { error: errorAction, paymentIntent } =
      await stripe.handleCardAction(responseJson.clientSecret);

    if (errorAction) {
      // Show error from Stripe.js in payment form
    } else {
      // The card action has been handled
      // The PaymentIntent can be confirmed again on the server
      const serverResponse = await fetch('/pay', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ payment_intent_id: paymentIntent.id })
      });
      handleServerResponse(await serverResponse.json());
    }
  } else {
    // Show success message
  }
}
```

## 再次确认 PaymentIntent [服务器端]

使用您之前设置的同一端点，再次*确认* (Confirming an intent indicates that the customer intends to use the current or provided payment method. Upon confirmation, the intent attempts to initiate the portions of the flow that have real-world side effects) PaymentIntent，以完成支付并履行订单。如果一小时内未再次确认，支付尝试将失败并返回 `requires_payment_method` 状态。

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/confirm \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST"
```

## 测试集成

在沙盒环境中使用我们的测试卡片，以验证您的集成是否已正确更新。Stripe 会在沙盒环境的模态框中显示一个伪造的认证页面，让您能够模拟成功或失败的认证尝试。在真实模式下，银行将控制模态框内显示的用户界面。

| 卡号               | 描述                                                |
| ---------------- | ------------------------------------------------- |
| 4242424242424242 | 成功并且立即处理付款。                                       |
| 4000000000009995 | 始终会失败，显示拒付码 `insufficient_funds`。                 |
| 4000002500003155 | 要求验证，此集成中会失败，显示拒付代码 `authentication_not_handled`。 |
