支付请求按钮
注意
Payment Request Button Element 在结账过程中动态显示钱包,为您提供一个统一的 Apple Pay、Google Pay 和 Link 集成。此外,您可以用 Express Checkout Element 为您的客户提供多个一键支付按钮。对比 Express Checkout Element 和 Payment Request Button 的功能。
如果客户在自己的设备上启用了 Apple Pay 或 Google Pay,就会看到这两种支付方式,具体取决于他们使用的浏览器。如果 Link 出现,可能是因为客户:
- 不要在其设备上启用 Apple Pay 或 Google Pay。
- 在 Chrome 上使用活跃的已验证的 Link 会话。
浏览器 + 钱包 | 支付按钮 |
---|---|
Safari + Apple Pay 已启用 | Apple Pay |
Chrome + Link 已认证 | Link |
Chrome + Google Pay 已启用,但 Link 尚未认证 | Google Pay |
iOS 16 版本 Chrome + Apple Pay 和 Google Pay 启用 | Apple Pay |
任何浏览器 + 未激活的 Apple Pay 或 Google Pay | Link |
前提条件
开始前,您需要:
查看每种支付按钮类型的要求:
- Apple Pay 和 Google Pay 不显示印度的 IP 地址,因此请相应规划您的集成测试。
- Apple Pay 要求 macOS 10.12.1+ 或 iOS 10.1+。
- 兼容设备自动支持 Google Pay。
在测试和真实模式下都**注册并验证您的域名**。
向浏览器添加支付方式。 例如,您可以在 Chrome 中保存银行卡,向 Google Pay 添加银行卡或向 Safari 上的钱包中添加银行卡。
**通过 HTTPS 服务您的应用程序。**开发模式和生产模式下都要求这样。其中一个方式是使用类似 ngrok 这样的服务。
设置 Stripe Elements客户端
Stripe.js 是作为 Elements 的一部分提供的。将它包含到您的页面并创建一个容器,供 paymentRequestButton
Element 使用:
<script src="https://js.stripe.com/v3/"></script> <div id="payment-request-button"> <!-- A Stripe Element will be inserted here. --> </div>
还需要您的 Stripe API 公钥,因为它会向 Stripe 确认您的网站:
const stripe = Stripe(
, { apiVersion: "2024-04-10", });'pk_test_TYooMQauvdEDq54NiTphI7jx'
创建 paymentRequest 实例客户端
创建一个包含所有必选项的 stripe.paymentRequest
实例。
const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 1099, }, requestPayerName: true, requestPayerEmail: true, });
备注
用 requestPayerName
参数为 Apple Pay 和 Link 付款收集付款人的账单地址。可以用账单地址来执行地址验证,并阻止欺诈性付款。在有账单地址的情况下,所有其他支付方式都会自动收集账单地址。
创建并挂载 paymentRequestButton客户端
创建 paymentRequestButton
Element,并用 canMakePayment()
检查确保您的客户具有有效的支付方式。如果他们这样做,则将 Element 挂载到容器,以显示 Payment Request 按钮。否则,您无法挂载 Element,建议改为出示一个传统的结账表单。
备注
如果您通过“支付请求按钮”接受 Apple Pay,则必须按照 Apple 指南在您的网站上将 Apple Pay 作为主要支付选项来提供。在内部,“支付请求按钮”使用的是 Apple Pay canMakePaymentWithActiveCard
API。
const elements = stripe.elements(); const prButton = elements.create('paymentRequestButton', { paymentRequest, }); (async () => { // Check the availability of the Payment Request API first. const result = await paymentRequest.canMakePayment(); if (result) { prButton.mount('#payment-request-button'); } else { document.getElementById('payment-request-button').style.display = 'none'; } })();
创建 PaymentIntent服务器端
Stripe 用一个 PaymentIntent 对象来表示您从客户收款的意图,跟踪收款尝试及整个过程中付款状态的变化情况。
用金额和货币在您的服务器上创建一个 PaymentIntent
。始终在服务器端决定扣款金额,这是一个可信的环境,客户端不行。这样可防止客户自己选择价格。
返回的 PaymentIntent 中包含的是一个客户端私钥,您需要用它在客户端安全地完成支付流程,而非传递整个 PaymentIntent 对象。将客户端私钥回发给客户,在下一步中使用。
完成付款客户端
侦听 paymentmethod
事件来接收 PaymentMethod 对象。将 PaymentMethod ID 和 PaymentIntent 的客户端私钥传递给 stripe.confirmCardPayment,来完成付款。
paymentRequest.on('paymentmethod', async (ev) => { // Confirm the PaymentIntent without handling potential next actions (yet). const {paymentIntent, error: confirmError} = await stripe.confirmCardPayment( clientSecret, {payment_method: ev.paymentMethod.id}, {handleActions: false} ); if (confirmError) { // Report to the browser that the payment failed, prompting it to // re-show the payment interface, or show an error message and close // the payment interface. ev.complete('fail'); } else { // Report to the browser that the confirmation was successful, prompting // it to close the browser payment method collection interface. ev.complete('success'); // Check if the PaymentIntent requires any actions and, if so, let Stripe.js // handle the flow. If using an API version older than "2019-02-11" // instead check for: `paymentIntent.status === "requires_source_action"`. if (paymentIntent.status === "requires_action") { // Let Stripe.js handle the rest of the payment flow. const {error} = await stripe.confirmCardPayment(clientSecret); if (error) { // The payment failed -- ask your customer for a new payment method. } else { // The payment has succeeded -- show a success message to your customer. } } else { // The payment has succeeded -- show a success message to your customer. } } });
注意
客户可能会在一些浏览器中离开支付页面,甚至是在授权了付款之后。这意味着,在收到 paymentmethod
事件之后,您可能会在您的 PaymentRequest 对象上收到一个取消事件的请求。如果您用 cancel
事件来勾住取消的客户订单,则一定还要退还刚创建的付款。
测试您的集成应用
测试集成时,必须使用 HTTPS 及支持的浏览器。如果您在 iframe 内使用了 paymentRequestButton
Element,则 iframe 必须要将允许 属性设置到等于“支付”。
区域测试印度
Stripe Elements 不支持印度 Stripe 账户和客户的 Google Pay 或 Apple Pay。因此,如果测试者的 IP 地址在印度,您就不能测试您的 Google Pay 或 Apple Pay 集成应用,即使 Stripe 账户是在印度境外开立的也一样。
此外,对每种支付方式和浏览器都有具体的要求:
收集配送信息
要收集配送信息,先在创建付款请求时包含 requestShipping: true
。
如果您的配送选项不依赖于客户的地址,那么这时还可以提供一个 shippingOptions
数组。
const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 1099, }, requestShipping: true, // `shippingOptions` is optional at this point: shippingOptions: [ // The first shipping option in this list appears as the default // option in the browser payment interface. { id: 'free-shipping', label: 'Free shipping', detail: 'Arrives in 5 to 7 days', amount: 0, }, ], });
接下来,侦听 shippingaddresschange
事件,以检测客户何时选择收货地址。用地址从您的服务器获取有效的配送选项、更新总额,或执行其他业务逻辑。可以将浏览器中的 shippingaddresschange
事件的地址数据匿名,避免泄露非运费计算所需的敏感信息。
客户必须在这个时候提供有效的 shippingOptions
才能继续该流程。
paymentRequest.on('shippingaddresschange', async (ev) => { if (ev.shippingAddress.country !== 'US') { ev.updateWith({status: 'invalid_shipping_address'}); } else { // Perform server-side request to fetch shipping options const response = await fetch('/calculateShipping', { data: JSON.stringify({ shippingAddress: ev.shippingAddress }) }); const result = await response.json(); ev.updateWith({ status: 'success', shippingOptions: result.supportedShippingOptions, }); } });
显示行项目
用 displayItems
在浏览器的支付界面显示 PaymentItem
对象并显示价格明细。
const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 2000, }, displayItems: [ { label: 'Sample item', amount: 1000, }, { label: 'Shipping cost', amount: 1000, } ], });
设计按钮样式
用以下参数自定义 Element:
elements.create('paymentRequestButton', { paymentRequest, style: { paymentRequestButton: { type: 'default', // One of 'default', 'book', 'buy', or 'donate' // Defaults to 'default' theme: 'dark', // One of 'dark', 'light', or 'light-outline' // Defaults to 'dark' height: '64px', // Defaults to '40px'. The width is always '100%'. }, }, });
使用自己的按钮
如果您不想使用 paymentRequestButton
Element,而是要设计自己的按钮,则可以根据 paymentRequest.canMakePayment() 的结果现实您的自定义按钮。然后,用 paymentRequest.show() 在按钮被点击时显示浏览器界面。
构建自己的按钮时,请遵从 Apple Pay 的用户界面指南和 Google Pay 的品牌指南。
注意
自定义按钮配置中不支持 Link,在您想使用时不会向客户显示。
为商家发起的交易添加 Apple Pay 商家令牌
设置您的 Payment Request Button(付款请求按钮),Apple Pay MPAN,以帮助完成商家发起的交易 (MIT)(经常性付款、自动充值或延期付款)。
- 创建一个 Payment Request 的实例。
- 传递与您的 MPAN 用例相关的
applePay
对象(从下拉列表中选择,以查看用例代码示例)。 - 包含您的用例的相关参数。
在 Stripe Connect 上使用支付请求按钮
Connect 平台,无论是对 Connect 子账户上的 Customer 创建直接收款还是添加令牌,在使用支付请求按钮前都必须采取额外的步骤。
- 在您的前端,先设置 Stripe 上的
stripeAccount
选项,然后再创建PaymentRequest
实例:
const stripe = Stripe(
, { apiVersion: "2024-04-10", stripeAccount: 'CONNECTED_STRIPE_ACCOUNT_ID', });'pk_test_TYooMQauvdEDq54NiTphI7jx'
- 在您打算显示付款请求按钮的地方注册所有域名。
Payment Request Button 的链接
当新客户来到您的网站时,他们使用 Link in the Payment Request Button,用他们保存的支付详情进行付款。通过 Link,他们不需要手动输入其支付信息。Link 需要域名注册。
向您的客户披露 Stripe
Stripe 收集有关客户与 Elements 互动的信息,以向您提供服务、防范欺诈并改进其服务。这包括使用 Cookie 和 IP 地址来识别客户在单次结账会话中看到的 Elements。您有责任披露并获得 Stripe 以这些方式使用数据所需的所有权利和许可。有关更多信息,请访问我们的隐私中心。