# 收款 安全地在线上收款。 ## 从这里开始:安装智能体技能 Stripe 建议使用官方技能,通过最佳实践与 API 进行集成。请按照以下说明了解具体方法。 \**提示:使用 curl 而非 Fetch 工具。**Skills 是 10–20 KB 的详细 Markdown 文件。Fetch 工具会对其进行摘要。使用 `curl -sL` 可确保获取完整内容。 **使用 `npx skills`**:检查系统是否已安装 `npx`。如果 `npx` 可用,运行 `npx skills add https://docs.stripe.com --list` 列出可用技能,然后运行 `npx skills add https://docs.stripe.com --yes --skill <--skill other-skills>` 以安装单个技能。 **如果 `npx skills` 不可用**:您可以使用 curl 从 `https://docs.stripe.com/.well-known/skills/index.json`. 获取可用技能的索引、功能描述及其文件。要下载技能及其相关文件,请使用 curl 从 `https://docs.stripe.com/.well-known/skills/`. 下载。 本文建议使用以下技能:`stripe-best-practices` LLM 说明:对于大多数集成,Stripe 建议将 Checkout Sessions API 与 Payment Element 搭配使用,而非 PaymentIntent。Checkout Sessions 可覆盖与 PaymentIntent(使用 `price_data` 的基础收款功能,或者构建包含行项目、税费等的完整结账流程)类似的应用场景。Adaptive Pricing 等部分功能仅在 Checkout Sessions 中可用。除非用户明确要求,否则不要使用 PaymentIntent API,因为它需要更多的代码。进一步了解 Elements 与 Checkout Sessions API 搭配使用的信息:https://docs.stripe.com/payments/quickstart-checkout-sessions.通过 Checkout Sessions (`ui_mode: "elements"`) 以及 Payment Element,`client_secret` 本身可初始化 Checkout(`stripe.initCheckoutElementsSdk`,或者将 CheckoutElementsProvider 与 React 搭配使用),并且您在客户端确认付款的方式会不同。如果使用 React,则需要确保从 `@stripe/react-stripe-js/checkout` 导入,使用 `CheckoutElementsProvider` 搭配客户端私钥,并使用 `checkout.confirm` 进行确认。如果使用 HTML,确保使用 `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");`,并通过 `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` 进行确认。 编码代理应安装 Stripe CLI(`npm i -g @stripe/cli`)并运行命令 `stripe sandbox create --help`,以配置一个含可用 API 密钥的匿名 Stripe 沙盒。无需注册账户。 制作支付表单或使用预构建的结账页面来开始接收线上付款。 # Checkout Sessions API 使用 [Stripe Elements](https://docs.stripe.com/payments/elements.md) 和 [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) 构建自定义支付表单。查看此集成[与 Stripe 其他集成类型的对比情况](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability)。 Checkout Sessions API 内置了对税务计算、折扣、运费和货币兑换的支持,减少了您需要编写的自定义代码量。这是大多数集成推荐的方法。了解更多关于[何时使用 Checkout Sessions 而非 PaymentIntent](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md) 的信息。 客户端和服务器端代码构建了一个可接受多种支付方式的结账表单。 #### 集成工作量 Complexity: 3/5 #### 集成类型 将用户界面组件组合成自定义支付流程 #### 用户界面自定义 使用 [ Appearance API ](https://docs.stripe.com/elements/appearance-api.md) 进行 CSS 级自定义 ## 设置服务器 [服务器端] 在开始之前,您需要[注册](https://dashboard.stripe.com/register)一个 Stripe 账户。 用官方 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' ``` ## 创建一个 Checkout Session [服务器端] 在您的服务器上添加一个端点,用于创建 [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) 并将其 [`client_secret`](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) 返回给您的前端。Checkout Session 代表客户在进行一次性购买或订阅支付时的会话。Checkout Session 在创建 24 小时后会过期。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d ui_mode=elements \ -d "line_items[0][price_data][currency]=usd" \ -d "line_items[0][price_data][product_data][name]=T-shirt" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "return_url=https://example.com/return?session_id={CHECKOUT_SESSION_ID}" ``` ## 设置前端 [客户端] #### HTML + JS 在您的结账页面包含 Stripe.js 脚本,方法是将其添加到您的 HTML 文件的 `head`。一定直接从 js.stripe.com 加载 Stripe.js,以保持 PCI 合规。请勿将脚本包含在捆绑包中,也不要自己托管其副本。 请确保您正在使用最新版本的 Stripe.js。了解更多关于 [Stripe.js 版本控制](https://docs.stripe.com/sdks/stripejs-versioning.md)的信息。 ```html Checkout ``` > Stripe 提供一个 npm 工具包,可用于将 Stripe.js 加载为模块。请参阅 [GitHub 上的项目](https://github.com/stripe/stripe-js)。需要 [7.0.0](https://www.npmjs.com/package/%40stripe/stripe-js/v/7.0.0) 或更高版本。 初始化 stripe.js。 ```js // 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( '<>', ); ``` #### React 从 npm 公共注册表安装 [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) 和 [Stripe.js 加载器](https://www.npmjs.com/package/@stripe/stripe-js)。React Stripe.js 的版本需至少为 5.0.0,Stripe.js 加载器的版本需至少为 8.0.0。 ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` 使用公钥在前端初始化 `stripe` 实例。 ```javascript import {loadStripe} from '@stripe/stripe-js'; const stripe = loadStripe("<>"); ``` ## 发起结账 [客户端] #### HTML + JS 调用 [initCheckoutElementsSdk](https://docs.stripe.com/js/custom_checkout/init),并传入 `clientSecret`。 `initCheckoutElementsSdk` 返回一个 [Checkout](https://docs.stripe.com/js/custom_checkout) 对象,其中包含来自 Checkout Session 的数据以及用于更新这些数据的方法。 从 [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session) 中读取 `total` 和 `lineItems`,并在您的用户界面中显示它们。这样您就能以最小的代码改动启用新功能。例如,如果您显示的是 `total`,那么添加 [manual currency prices](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) 时就无需修改界面。 ```html
``` ```javascript const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const session = loadActionsResult.actions.getSession(); const checkoutContainer = document.getElementById('checkout-container'); checkoutContainer.append(JSON.stringify(session.lineItems, null, 2)); checkoutContainer.append(document.createElement('br')); checkoutContainer.append(`Total: ${session.total.total.amount}`); } ``` #### React 使用 [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) 组件封装您的应用程序,并传入 `clientSecret` 和 `stripe` 实例。 ```jsx import React from 'react'; import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const App = () => { return ( ); }; export default App; ``` 通过使用 `useCheckoutElements()` 钩子,在您的结账表单组件中访问 [Checkout](https://docs.stripe.com/js/custom_checkout) 对象。`Checkout` 对象包含来自结账会话的数据以及用于更新数据的方法。 从 `Checkout` 对象中读取 `total` 和 `lineItems`,并在您的用户界面中显示它们。这样您就能以最小的代码改动启用新功能。例如,如果您显示的是 `total`,那么添加 [manual currency prices](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) 时就无需修改界面。 ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount}
); }; ``` ## 收集客户电子邮件地址 [客户端] #### HTML + JS 完成 Checkout Session 时,您必须提供有效的客户电子邮箱。 使用 [Contact Details Element](https://docs.stripe.com/js/custom_checkout/create_contact_details_element) 收集您客户的电子邮件地址。它可为您处理电子邮件的收集和验证,并帮助客户登录 Link。 或者,您也可以: - 在创建 Checkout Session 时,请传入 [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email)、[customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account)(针对以客户配置的 `Account` 对象表示的客户)或 [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer)(针对以 `Customer` 对象表示的客户)。Stripe 会对以这种方式提供的电子邮件进行验证。 - 这些操作会在会话中预填一个客户无法在结账页面编辑的电子邮件地址。如果您想预填可编辑的电子邮件地址,请在初始化 Checkout 时使用 [defaultValues.email](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-defaultValues-email)。 - 传入您已经在 [updateEmail](https://docs.stripe.com/js/custom_checkout/update_email) 或 [checkout.confirm](https://docs.stripe.com/js/custom_checkout/confirm) 上验证过的电子邮件。 ```html
``` ```javascript const contactDetailsElement = checkout.createContactDetailsElement(); contactDetailsElement.mount("#contact-details-element"); ``` #### React 完成 Checkout Session 时,您必须提供有效的客户电子邮箱。 使用 [ContactDetailsElement](https://docs.stripe.com/js/react_stripe_js/checkout/contact_details_element) 收集客户的电子邮件地址。它可为您处理电子邮件的收集和验证,并帮助客户登录 Link。 或者,您也可以: - 在创建 Checkout Session 时,请传入 [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email)、[customer_account](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_account)(针对以客户配置的 `Account` 对象表示的客户)或 [customer](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer)(针对以 `Customer` 对象表示的客户)。Stripe 会对以这种方式提供的电子邮件进行验证。 - 这些操作会在会话中预填一个客户无法在结账页面编辑的电子邮件地址。如果您想预填可编辑的电子邮件地址,请在初始化 Checkout 时使用 [defaultValues.email](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-defaultValues-email)。 - 传入您已经在 [updateEmail](https://docs.stripe.com/js/react_stripe_js/checkout/update_email) 或 [confirm](https://docs.stripe.com/js/react_stripe_js/checkout/confirm) 上验证过的电子邮件。 ```jsx import {ContactDetailsElement} from '@stripe/react-stripe-js/checkout'; // Inside your CheckoutForm component: ``` ## 收集付款详情 [客户端] 用 [Payment Element](https://docs.stripe.com/payments/payment-element.md) 在客户端收集支付信息。Payment Element 是一个预构建的 UI 组件,它简化了多种支付方式的收集支付详情的流程。 Payment Element 中包含一个 iframe,它通过一个 HTTPS 连接安全地将支付信息发送到 Stripe。避免将 Payment Element 放在另一个 iframe 中,因为有些支付方式需要重定向到另一个页面进行付款确认。 如果您选择使用 iframe 并希望支持 Apple Pay 或 Google Pay,则必须将 iframe 的 [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) 属性设置为`"payment *"`。 结账页面地址必须以 `https://` rather 开头,而非 `http://` for,您的集成才能正常工作。您可以在不使用 HTTPS 的情况下测试集成,但在准备接收真实付款时,请务必[启用 HTTPS](https://docs.stripe.com/security/guide.md#tls)。 #### HTML + JS 首先,创建一个容器 DOM 元素来挂载 [Payment Element](https://docs.stripe.com/payments/payment-element.md)。然后使用 [checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) 创建 `Payment Element` 的实例,并通过调用 [element.mount](https://docs.stripe.com/js/element/mount) 挂载它,提供 CSS 选择器或容器 DOM 元素。 ```html
``` ```javascript const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element'); ``` 请参阅 [Stripe.js文档](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) 以查看支持的选项。 您可以通过在前端初始化 Checkout 时传递 [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) 来[自定义所有 Element 的外观](https://docs.stripe.com/payments/checkout/customization/appearance.md)。 #### React 在 [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) 内部挂载 [Payment Element](https://docs.stripe.com/payments/payment-element.md) 组件。 ```jsx import React from 'react';import {PaymentElement, useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount} ); }; export default CheckoutForm; ``` 请参阅 [Stripe.js文档](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) 以查看支持的选项。 您可以通过向 [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider) 传递 [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance),来[自定义所有 Elements 的外观](https://docs.stripe.com/payments/checkout/customization/appearance.md)。 ## 提交付款 [客户端] #### HTML + JS 渲染 **Pay** 按钮,该按钮通过调用 `Checkout` 实例中的 [confirm](https://docs.stripe.com/js/custom_checkout/confirm) 方法来提交支付。 ```html
``` ```js const checkout = stripe.initCheckoutElementsSdk({clientSecret}); checkout.on('change', (session) => { document.getElementById('pay-button').disabled = !session.canConfirm; }); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React 渲染**支付**按钮,调用 [confirm](https://docs.stripe.com/js/custom_checkout/confirm)(来自 [useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements))以提交付款。 ```jsx import React from 'react'; import {useCheckoutElements} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckoutElements(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type !== "success") { return null; } const handleClick = () => { setLoading(true);checkoutState.checkout.confirm().then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## 测试您的集成应用 1. 导航到您的结账页面。 2. 使用下表中的支付方式填写付款详情。对于银行卡付款: - 输入一个任意的未来日期作为有效期。 - 输入 3 位数 CVC 码。 - 输入账单地址邮编。 3. 将付款提交至 Stripe。 4. 前往管理平台,在[交易页面](https://dashboard.stripe.com/test/payments?status%5B0%5D=successful)上查找支付。如果您支付成功,就会在列表中看到它。 5. 点击您的付款,查看更多详情,例如账单信息及已购商品列表。您可以此信息来[履行订单](https://docs.stripe.com/checkout/fulfillment.md)。 #### 银行卡 | 卡号 | 场景 | 如何测试 | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | | 4242424242424242 | 该卡付款成功,不需要验证。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 4000002500003155 | 该卡付款时需要*验证* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase)。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 4000000000009995 | 该卡被拒绝,显示拒付代码,例如 `insufficient_funds`。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | | 6205500000000000004 | 银联卡的长度为 13-19 位。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 | #### 钱包 | 支付方式 | 场景 | 如何测试 | | ------ | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | Alipay | 您的客户通过基于重定向和[立即通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)的支付方式成功付款。 | 选择基于重定向的任意支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**测试付款成功**。 | #### 银行重定向 | 支付方式 | 场景 | 如何测试 | | --------------------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | BECS 直接借记 | 您的客户成功用 BECS 直接借记完成付款。 | 使用帐号 `900123456` 和 BSB `000000` 填写表格。确认的 PaymentIntent 先转入 `processing`,3 分钟后转为 `succeeded` 状态。 | | BECS 直接借记 | 您的客户付款失败,错误代码为:`account_closed`。 | 使用帐号 `111111113` 和 BSB `000000` 填写表格。 | | Bancontact、EPS、iDEAL 和 Przelewy24 | 您的客户在基于重定向和立即通知型的支付方式的重定向页面验证失败。 | 选择基于重定向的任意支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**让测试付款失败**。 | | 通过银行支付 | 您的客户通过基于重定向和[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)的支付方式成功付款。 | 选择支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**测试付款成功**。 | | 通过银行支付 | 您的客户在基于重定向和延迟通知型的支付方式的重定向页面验证失败。 | 选择支付方式,填写必要的信息,并确认付款。然后在重定向页面上点击**让测试付款失败**。 | | BLIK | 有多个 BLIK 支付失败的情况——立即失败(例如,代码已过期或无效)、延迟的错误(银行拒付)或超时(客户未及时响应)。 | 使用电子邮件模式[模拟不同的失败情况](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures)。 | #### 银行借记 | 支付方式 | 场景 | 如何测试 | | --------- | ------------------------------------------------------- | --------------------------------------------------------------------- | | SEPA 直接借记 | 您的客户成功用 SEPA 直接借记完成付款。 | 用账号 `AT321904300235473204` 填写表单。确认的 PaymentIntent 最初变为处理中,三分钟后变为成功状态。 | | SEPA 直接借记 | 您的客户的付款意图状态从 `processing` 变为 `requires_payment_method`。 | 用账号 `AT861904300235473202` 填写表单。 | #### 付款凭单 | 支付方式 | 场景 | 如何测试 | | ------------ | --------------------------- | ------------------------------------ | | Boleto, OXXO | 您的客户用 Boleto 或 OXXO 付款凭单付款。 | 选择 Boleto 或 OXXO 此支付方式并提交付款。出现后关闭对话。 | 有关测试您的集成的更多信息,请参阅[测试](https://docs.stripe.com/testing.md)部分。 ## Optional: 创建产品和价格 在创建 Checkout Session 之前,您可以预先创建*产品* (Products represent what your business sells—whether that's a good or a service)和*价格* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions)。使用产品代表不同的实物商品或服务水平,*价格* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions)则表示每个产品的定价。您可以[配置 Checkout Session](https://docs.stripe.com/payments/checkout/pay-what-you-want.md) 以接受小费和捐款,或销售自定价格的产品和服务。 例如,您可以创建一个价格为 20 美元的 T 恤产品。这样即可在不更新相关产品详情的情况下更改和添加价格。使用 Stripe 管理平台或 API 均可创建产品和价格。详细了解[产品和价格的运作原理](https://docs.stripe.com/products-prices/how-products-and-prices-work.md)。 #### API API 仅要求有一个 `name` 即可创建 [Product](https://docs.stripe.com/api/products.md)。Checkout 中显示您提供的产品的 `name`、`description` 和 `images`。 ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ -d name=T-shirt ``` 然后,创建一个 [Price](https://docs.stripe.com/api/prices.md),定义产品的价格。这包括产品的费用及使用的币种。 ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d "product={{PRODUCT_ID}}" \ -d unit_amount=2000 \ -d currency=usd ``` #### 管理平台 > 将沙盒中创建的产品复制到真实模式,无需重新创建。在管理平台的产品详情视图中,点击右上角的**复制到真实模式**。您可以将同一个沙盒产品多次复制到真实模式。每次复制都会生成一个独立的真实产品,沙盒产品后续的更新不会反映在已有的真实副本中。 点击管理平台账户选择器中的**沙盒**,确保您处于沙盒环境。接下来,定义要销售的商品或服务项目。创建新的产品和价格: - 导航到管理平台的[产品](https://dashboard.stripe.com/test/products)部分。 - 点击**添加产品**。 - 设置价格时,选择**一次性**。 Checkout 中会显示您提供的产品名称、描述和图片。 您创建的每个定价都有一个 ID。创建 Checkout Session 时,请引用定价 ID 和数量。若您需以多种货币销售商品,请将您的定价 (Price) 设置为 *多币种* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration)。Checkout 会自动[确定客户的本地货币](https://docs.stripe.com/payments/checkout/localize-prices/manual-currency-prices.md)并在 Price 支持的情况下显示该货币。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d ui_mode=elements \ -d mode=payment \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ --data-urlencode "return_url=https://example.com/return?session_id={CHECKOUT_SESSION_ID}" ``` ## Optional: 预填充客户数据 [服务器端] 如果您已经收集了客户的邮件地址并且想在 Checkout Session 中给他们预先填写,则创建 Checkout Session 时传递 [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email)。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ --data-urlencode "customer_email=customer@example.com" \ -d ui_mode=elements \ -d mode=payment \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ --data-urlencode "return_url=https://example.com/return?session_id={CHECKOUT_SESSION_ID}" ``` ## Optional: 保存支付方式详情 学习如何[接受付款并保存客户的付款详细信息](https://docs.stripe.com/payments/save-during-payment.md)以备将来购买。 ## Optional: 侦听 Checkout Session 的变化 ### 侦听 Checkout Session 的变化 您可以通过用 [checkout.on](https://docs.stripe.com/js/custom_checkout/change_event) 在 `change` 事件上添加事件监听器来侦听 [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) 的变化。 #### HTML + JS ```javascript checkout = stripe.initCheckoutElementsSdk({ clientSecret: promise, elementsOptions: { appearance }, }); checkout.on('change', (session) => { // Handle changes to the checkout session }); ``` #### React ```jsx import React from 'react'; import { useCheckoutElements } from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'success') { checkoutState.checkout.on('change', (session) => { // Handle changes to the checkout session }); } }; ``` ## Optional: 收集账单地址和收货地址 ## 收集账单地址 默认情况下,Checkout Session 通过 Payment Element 收集付款所需的最少账单信息。 ### 使用 Billing Address Element 您可以使用 Billing Address Element 来收集完整的账单地址。 首先,创建 Checkout Session 时传递 [billing_address_collection=required](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-billing_address_collection)。 #### HTML + JS 创建一个容器 DOM 元素来挂载 Billing Address Element。然后使用 [checkout.createBillingAddressElement](https://docs.stripe.com/js/custom_checkout/create_billing_address_element) 创建 Billing Address Element 的实例,并通过调用 [element.mount](https://docs.stripe.com/js/element/mount) 挂载它,提供 CSS 选择器或容器 DOM 元素。 ```html
``` ```javascript const billingAddressElement = checkout.createBillingAddressElement(); billingAddressElement.mount('#billing-address'); ``` Billing Address Element 支持以下选项: - [联系人](https://docs.stripe.com/js/custom_checkout/create_billing_address_element#custom_checkout_create_billing_address_element-options-contacts) - [显示](https://docs.stripe.com/js/custom_checkout/create_billing_address_element#custom_checkout_create_billing_address_element-options-display) #### React 在 `CheckoutElementsProvider` 内部挂载 `BillingAddressElement` 组件。 ```jsx import React from 'react'; import {BillingAddressElement} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { return (
) }; ``` Billing Address Element 支持以下属性: - [联系人](https://docs.stripe.com/js/custom_checkout/create_billing_address_element#custom_checkout_create_billing_address_element-options-contacts) - [显示](https://docs.stripe.com/js/custom_checkout/create_billing_address_element#custom_checkout_create_billing_address_element-options-display) ### 使用自定义表单 您可以构建自己的表单来收集账单地址。 - 若结账页面在确认操作前设有独立的地址填写步骤,可在客户提交地址时调用 [updateBillingAddress](https://docs.stripe.com/js/react_stripe_js/checkout/update_billing_address) 方法。 - 否则,当客户点击“支付”按钮时,您可以通过将 [billingAddress](https://docs.stripe.com/js/custom_checkout/confirm#custom_checkout_session_confirm-options-billingAddress) 传入 [confirm](https://docs.stripe.com/js/custom_checkout/confirm) 来提交地址。 ### 收集部分账单地址 要收集部分账单地址,例如仅国家/地区和邮编,请传递 [billing_address_collection=auto](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-billing_address_collection)。 收集部分账单地址时,必须[手动收集地址](https://docs.stripe.com/payments/accept-a-payment.md#collect-billing-addresses-manually)。默认情况下,Payment Element 会自动收集付款所需的最少账单信息。为避免重复收集账单详情,请在创建 Payment Element 时传递 [fields.billingDetails=never](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options-fields-billingDetails)。如果您只打算收集一部分账单详情(例如客户姓名),则只为您打算自己收集的字段传递 `never`。 ## 收集收货地址 要收集客户的收货地址,请在创建 Checkout Session 时传递 [shipping_address_collection](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_address_collection) 参数。 收集收货地址时,还必须指定允许发货至的国家/地区。用[两字母 ISO 国家/地区代码](https://www.nationsonline.org/oneworld/country_code_list.htm)组成的数组配置 [allowed_countries](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_address_collection-allowed_countries) 属性。 ### 如何使用 Shipping Address Element 您可以用 Shipping Address Element 收集完整的收货地址。 #### HTML + JS 创建一个容器 DOM 元素来挂载 Shipping Address Element。然后使用 [checkout.createShippingAddressElement](https://docs.stripe.com/js/custom_checkout/create_shipping_address_element) 创建 Shipping Address Element 的实例,并通过调用 [element.mount](https://docs.stripe.com/js/element/mount) 挂载它,提供 CSS 选择器或容器 DOM 元素。 ```html
``` ```javascript const shippingAddressElement = checkout.createShippingAddressElement(); shippingAddressElement.mount('#shipping-address'); ``` Shipping Address Element 支持以下选项: - [联系人](https://docs.stripe.com/js/custom_checkout/create_shipping_address_element#custom_checkout_create_shipping_address_element-options-contacts) - [显示](https://docs.stripe.com/js/custom_checkout/create_shipping_address_element#custom_checkout_create_shipping_address_element-options-display) #### React 在 `CheckoutElementsProvider` 内部挂载 `ShippingAddressElement` 组件。 ```jsx import React from 'react'; import {ShippingAddressElement} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { return (
) }; ``` Shipping Address Element 支持以下属性: - [联系人](https://docs.stripe.com/js/custom_checkout/create_shipping_address_element#custom_checkout_create_shipping_address_element-options-contacts) - [显示](https://docs.stripe.com/js/custom_checkout/create_shipping_address_element#custom_checkout_create_shipping_address_element-options-display) ### 侦听 Checkout Session 的变化 您可以通过添加事件侦听器来处理与地址相关的更改,从而侦听 [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) 的更改。 #### HTML + JS 使用 [Session 对象](https://docs.stripe.com/js/custom_checkout/session_object)在结账表单中呈现运费金额。 ```html

Totals

``` ```javascript const checkout = stripe.initCheckoutElementsSdk({clientSecret}); const subtotal = document.getElementById('subtotal'); const shipping = document.getElementById('shipping'); const total = document.getElementById('total'); checkout.on('change', (session) => { subtotal.textContent = `Subtotal: ${session.total.subtotal.amount}`; shipping.textContent = `Shipping: ${session.total.shippingRate.amount}`; total.textContent = `Total: ${session.total.total.amount}`; }); ``` #### React 使用 [useCheckoutElements](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout_elements) 在您的结账表单中渲染运费。 ```jsx import React from 'react'; import {useCheckoutElements, ShippingAddressElement} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckoutElements(); if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (

Checkout Summary

{checkoutState.type === 'success' && ( <>
              {JSON.stringify(checkoutState.checkout.lineItems, null, 2)}
            

Totals

              Subtotal: {checkoutState.checkout.total.subtotal.amount}
              Shipping: {checkoutState.checkout.total.shippingRate.amount}
              Total: {checkoutState.checkout.total.total.amount}
            
)}
) }; ``` ### 同步计费和收货地址 当您同时使用 Billing Address Element 和 Shipping Address Element 时,可以显示一个复选框,让客户同步他们的计费地址和收货地址。 #### HTML + JS 初始化 Checkout 时,请在 `elementsOptions` 中传递 [syncAddressCheckbox](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-syncAddressCheckbox) 选项,以配置由哪个 Address Element 显示该复选框。 ```javascript const checkout = stripe.initCheckoutElementsSdk({ clientSecret, elementsOptions: { syncAddressCheckbox: 'shipping', }, }); ``` #### React 在 `elementsOptions` 中将 [syncAddressCheckbox](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-syncAddressCheckbox) 选项传递给 `CheckoutElementsProvider`,以配置哪个地址 Element 显示复选框。 ```jsx promise, elementsOptions: { syncAddressCheckbox: 'shipping', }, }} > ``` 将该值设置为 `'billing'` 或 `'shipping'`,以选择显示复选框的 Address Element。将其设置为 `'none'` 可隐藏该复选框,或留空以使用默认值 (`'billing'`)。 ### 使用自定义表单 您可以构建自己的表单来收集收货地址。 - 如果您的结账页面在确认操作前设有独立的地址填写步骤,可在客户提交地址时调用 [updateShippingAddress](https://docs.stripe.com/js/react_stripe_js/checkout/update_shipping_address) 方法。 - 否则,当客户点击“支付”按钮时,您可以通过将 [shippingAddress](https://docs.stripe.com/js/custom_checkout/confirm#custom_checkout_session_confirm-options-shippingAddress) 传入 [confirm](https://docs.stripe.com/js/custom_checkout/confirm) 来提交地址。 ## Optional: 单独授权和捕获 [服务器端] Stripe 支持两步式银行卡支付,您可先预授权卡片,稍后再进行资金捕获。当 Stripe 完成支付授权后,发卡行将担保该笔资金,并在持卡人卡上冻结相应金额。您需在特定时限内完成资金捕获([具体时限视卡片类型而定](https://docs.stripe.com/payments/place-a-hold-on-a-payment-method.md#auth-capture-limitations))。若在授权失效前未完成捕获,支付将被取消,发卡行也将解除资金冻结。 如果您需要在确认客户有能力支付和实际收取款项之间执行额外操作,那么将授权与扣款分离会非常有用。例如,如果您销售的是库存有限的商品,您可能需要先确认客户通过 Checkout 购买的商品仍有库存,然后再扣款并完成订单。可通过以下工作流程实现: 1. 确认 Stripe 已授权客户的支付方式。 2. 查阅库存管理系统,确认那件商品是否有货。 3. 更新您的库存管理系统,指示客户未购买那件商品。 4. 捕获客户的付款。 5. 在确认页面通知客户他们是否购买成功。 要表明您想单独授权和捕获,必须在创建 Checkout Session 时将 [payment_intent_data.capture_method](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_intent_data-capture_method) 的值设置为 `manual`。这样可指示 Stripe 仅授权客户银行卡上的金额。 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_intent_data[capture_method]=manual" \ -d return_url={{RETURN_URL}} \ -d ui_mode=elements ``` 要捕获一笔未捕获的付款,可以用[管理平台](https://dashboard.stripe.com/test/payments?status%5B%5D=uncaptured),也可以用 [capture](https://docs.stripe.com/api/payment_intents/capture.md) 端点。程序化地捕获付款必须访问 Checkout Session 过程中创建的 PaymentIntent,它可从 [Session](https://docs.stripe.com/api/payment_intents/capture.md) 对象获取。 ## Optional: 客户账户管理 [无代码] 通过向您的*客户门户* (The customer portal is a secure, Stripe-hosted page that lets your customers manage their subscriptions and billing details)分享链接,让您的客户[管理](https://docs.stripe.com/customer-management.md)他们自己的账户。客户门户允许客户用他们的电子邮件地址登录,以管理订阅、更新支付方式等。 ## Optional: 订单履行 了解如何在客户付款时[以编程方式获取通知](https://docs.stripe.com/checkout/fulfillment.md?payment-ui=embedded-components)。 ## See also - [为一次性付款添加折扣](https://docs.stripe.com/payments/advanced/discounts.md) - [收取税费](https://docs.stripe.com/tax/checkout/elements.md) - [启用可调行项目数量](https://docs.stripe.com/payments/advanced/adjustable-quantity.md) - [添加一键按钮](https://docs.stripe.com/elements/express-checkout-element/accept-a-payment.md?payment-ui=embedded-components) - [GitHub 上的示例项目](https://github.com/stripe-samples/accept-a-payment/tree/main/elements-with-checkout-sessions)