# 接受支付宝付款

用 Stripe API 和 Checkout 接受支付宝付款，这是中国人广泛使用的一种数字钱包

# 直接收款 API


Alipay 是一种[单次使用](https://docs.stripe.com/payments/payment-methods.md#usage)的支付方式，客户需要[验证](https://docs.stripe.com/payments/payment-methods.md#customer-actions)他们的付款。客户在您的网站或应用程序中被跳转到 Alipay 页面，授权付款，然后返回您的网站或应用，然后在这里收到付款成功或失败的[即时通知](https://docs.stripe.com/payments/payment-methods.md#payment-notification)。

## 设置 Stripe [服务器端]

首先，您需要有 Stripe 账户。[立即注册](https://dashboard.stripe.com/register)。

用我们的官方库从您的应用程序访问 Stripe API：

#### Ruby

```bash
# Available as a gem
sudo gem install stripe
```

```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```

## 创建 PaymentIntent [服务器端]

[PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) 是一个对象，代表您向客户收款的意图，并跟踪支付流程的生命周期。在您的服务器上创建一个 `PaymentIntent`，并指定要收取的金额和[支持的货币](https://docs.stripe.com/payments/alipay.md#supported-currencies)。Stripe 会基于交易金额、货币和支付流程等因素，自动决定符合条件的支付方式。

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "automatic_payment_methods[enabled]=true" \
  -d amount=1099 \
  -d currency=hkd
```

### 检索客户端私钥

PaymentIntent 包含一个*客户端密钥* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer))，供客户端用于安全地完成支付流程。您可以使用不同的方法将客户端密钥传递给客户端。

#### 单页应用

Retrieve the client secret from an endpoint on your server, using the browser’s `fetch` function. This approach is best if your client side is a single-page application, particularly one built with a modern front-end framework like React. Create the server endpoint that serves the client secret:

#### Ruby

```ruby
get '/secret' do
  intent = # ... Create or retrieve the PaymentIntent
  {client_secret: intent.client_secret}.to_json
end
```

然后在客户端用 JavaScript 获取客户端私钥：

```javascript
(async () => {
  const response = await fetch('/secret');
  const {client_secret: clientSecret} = await response.json();
  // Render the form using the clientSecret
})();
```

#### 服务端呈现

从服务器将客户端私钥传递到客户端。如果在将静态内容发送到浏览器之前，您的应用程序会在服务器上生成静态内容，则此种方法最有效。

在您的结账表单中添加 [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)。在您的服务器代码中，从 PaymentIntent 检索客户端密钥：

#### Ruby

```erb
<form id="payment-form" data-secret="<%= @intent.client_secret %>">
  <button id="submit">Submit</button>
</form>
```

```ruby
get '/checkout' do
  @intent = # ... Fetch or create the PaymentIntent
  erb :checkout
end
```

## 重定向到支付宝钱包 [客户端]

客户通过 Alipay 点击支付时，用 Stripe.js 向 Stripe 提交付款。[Stripe.js](https://docs.stripe.com/payments/elements.md) 是构建支付流程的基础 JavaScript 库。它会自动处理一些复杂操作，例如下面的重定向，使您能够将集成扩展到其他支付方式。在您的结账页面包含 Stripe.js 脚本，方法是将它添加到您的 HTML 文件的 `head` 部分。

```html
<head>
  <title>Checkout</title>
  <script src="https://js.stripe.com/endive/stripe.js"></script>
</head>
```

用下面的 JavaScript 在您的结账页面创建一个 Stripe.js 实例。

```javascript
// 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('<<YOUR_PUBLISHABLE_KEY>>');
```

使用 `PaymentIntent` 的[客户端私钥](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)并调用 `stripe.confirmAlipayPayment`来处理 支付宝重定向。添加一个 `return_url`，确定在客户完成付款后让 Stripe 将他们重定向到哪里。

```javascript
const form = document.getElementById('payment-form');

form.addEventListener('submit', async function(event) {
  event.preventDefault();

  // Set the clientSecret of the PaymentIntent
  const { error } = await stripe.confirmAlipayPayment(clientSecret, {
    // Return URL where the customer should be redirected after the authorization
    return_url: `${window.location.href}`,
  });

  if (error) {
    // Inform the customer that there was an error.
    const errorElement = document.getElementById('error-message');
    errorElement.textContent = error.message;
  }
});
```

`return_url` 对应于您网站上显示付款结果的一个页面。通过对 `PaymentIntent` 进行[状态验证](https://docs.stripe.com/payments/payment-intents/verifying-status.md#checking-status)，您可以确定要显示的内容。要验证状态，Stripe 到 `return_url` 的重定向会包含以下 URL 查询参数。您还可以将自己的查询参数附加到 `return_url`。它们会贯穿整个重定向过程。

| 参数                             | 描述                                                                                                                     |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `payment_intent`               | `PaymentIntent` 的唯一标识符。                                                                                                |
| `payment_intent_client_secret` | `PaymentIntent` 对象的[客户端私钥](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret)。 |

## Optional: 手动处理重定向 [服务器端]

处理重定向的最好方式是使用包含 `confirmAlipayPayment` 的 Stripe.js。若要手动重定向客户：

1. 提供客户完成付款后将其重定向到的 URL。

```curl
curl https://api.stripe.com/v1/payment_intents/{{PAYMENTINTENT_ID}}/confirm \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "payment_method={{PAYMENTMETHOD_ID}}" \
  --data-urlencode "return_url=https://shop.example.com/crtA6B28E1"
```

1. 确认 `PaymentIntent` 的状态是 `requires_action`。`next_action` 的类型将是 `alipay_handle_redirect`。

```json
"next_action": {
  "type": "alipay_handle_redirect",
  "alipay_handle_redirect": {
    "url": "https://hooks.stripe.com/...",
    "return_url": "https://example.com/checkout/complete"
  }
}
```

1. 将客户重定向到 `next_action` 属性中提供的 URL。

客户完成付款后，会被跳转到 `return_url` 目的地。其中会包含 `payment_intent` 和 `payment_intent_client_secret` URL 查询参数，而且您可以通过您自己的查询参数来传递，如上所述。

## Optional: 处理付款后事件

付款完成时，Stripe 会发送一个 [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) 事件。使用管理平台、自定义 *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) 或一个合作伙伴方案来接收这些事件并运行操作，例如，向客户发送订单确认邮件、在数据库中记录订单，或启动配送流程。

侦听这些事件，而不是等待客户端的回调。在客户端上，客户可以在执行回调之前关闭浏览器窗口或退出应用程序，而且恶意客户端可以操纵响应。将集成设置为侦听异步事件还有助于您在未来接受更多支付方式。了解[所有受支持的支付方式之间的差异](https://stripe.com/payments/payment-methods-guide)。

### 接收事件并启动公司操作

在接收和处理公司操作方面有几个选项。

#### 手动

用 Stripe 管理平台查看您的所有 Stripe 付款，发送邮件收据，处理提现或重试失败的付款。

- [在管理平台内查看测试付款](https://dashboard.stripe.com/test/payments)

#### 自定义代码

构建一个 Webhook 处理程序，侦听事件并构建自定义同步付款流程。用 Stripe CLI 在本地测试并调试您的 Webhook 集成。

- [构建自定义 Webhook](https://docs.stripe.com/events/set-up-events.md#create-event-handler)

#### 预构建应用

通过集成合作伙伴应用程序处理常见业务事件，例如[自动化](https://stripe.partners/?f_category=automation)或[营销和销售](https://stripe.partners/?f_category=marketing-and-sales)。

## 支持的货币

Your account must have a bank account for one of the following currencies. You can create Alipay payments in the currencies that map to your country. The default local currency for Alipay is `cny` and customers also see their purchase amount in `cny`.

| 货币    | 国家/地区                                                                                                                                        |
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `cny` | 任何国家                                                                                                                                         |
| `aud` | 澳大利亚                                                                                                                                         |
| `cad` | 加拿大                                                                                                                                          |
| `chf` | 瑞士                                                                                                                                           |
| `eur` | 奥地利、比利时、保加利亚、克罗地亚、塞浦路斯、捷克共和国、丹麦、爱沙尼亚、芬兰、法国、德国、希腊、爱尔兰、意大利、拉脱维亚、列支敦士登、立陶宛、卢森堡、马耳他、荷兰、挪威、葡萄牙、罗马尼亚、斯洛伐克、斯洛文尼亚、西班牙、瑞典、瑞士                          |
| `gbp` | 直布罗陀、英国                                                                                                                                      |
| `hkd` | 香港                                                                                                                                           |
| `jpy` | 日本                                                                                                                                           |
| `myr` | 马来西亚                                                                                                                                         |
| `nzd` | 新西兰                                                                                                                                          |
| `sgd` | 新加坡                                                                                                                                          |
| `usd` | 奥地利、比利时、保加利亚、加拿大、克罗地亚、塞浦路斯、捷克共和国、丹麦、爱沙尼亚、芬兰、法国、德国、直布罗陀、希腊、中国香港、匈牙利、爱尔兰、意大利、拉脱维亚、列支敦士登、立陶宛、卢森堡、马耳他、荷兰、挪威、葡萄牙、罗马尼亚、新加坡、斯洛伐克、斯洛文尼亚、西班牙、瑞典、英国、美国 |

