调至内容部分
创建账户或登录
Stripe 文档徽标
/
询问人工智能
创建账户登录
开始
付款
销售收入
平台和交易市场
资金管理
开发人员资源
API 和 SDK帮助

不用 Webhook 接受银行卡付款

了解如何在您的服务器确认银行卡付款并处理银行卡验证要求。

注意

Stripe 建议使用更新的 Payment Element 而非 Card Element。通过单一Element 即可支持多种支付方式。进一步了解 Card Element 与 Payment Element 的适用场景。

为获得更广泛的支持并且未来可继续使用,请为异步付款使用标准集成。

该集成会等待客户端返回的响应,并在服务器上完成付款,而不使用 webhooks 或处理离线事件。虽然看似更简单了,但随着您业务的增长,这种集成很难扩展,并且有几个限制:

迁移?

如果您要从 Charges API 迁移现有的 Stripe 集成,请遵循迁移指南。

  • 仅支持卡 — 必须编写更多代码来分别支持 ACH 及流行的区域性支付方式。
  • 重复扣款风险——通过在客户每次尝试付款时同步创建新的 PaymentIntent,您可能会意外地对客户进行重复扣款。请务必遵循最佳实践。
  • 在客户端的额外步骤 — 需进行 3DS 验证或受强客户认证等法规约束的银行卡需要在客户端执行额外的步骤。 ​

如果您打算使用这种集成,请留意这些限制。否则,请使用标准集成。

设置 Stripe

首先,您需要有 Stripe 账户。立即注册。

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

Command Line
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# Available as a gem sudo gem install stripe
Gemfile
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
# If you use bundler, you can add this line to your Gemfile gem 'stripe'

收集银行卡详情
客户端

用 Stripe.js 和 Stripe Elements 在客户端收集银行卡信息。Elements 是一组预构建的 UI 组件,用于收集并验证银行卡卡号、邮编和有效期。

Stripe Element 中包含一个 iframe,它通过一个 HTTPS 连接安全地将支付信息发送到 Stripe。结账页面上的地址也必须以 https:// 开头,不能是 http://,否则您的集成不能工作。

您可以在不使用 HTTPS 的情况下测试您的集成。准备好进行真实收款时启用它。

在您网站的每个页面头部包含 Stripe.js 脚本。Elements 自动可以获取,这是 Stripe.js 的功能。

<script src="https://js.stripe.com/clover/stripe.js"></script>

在您网站的每个页面都包含脚本的好处是您可以利用 Stripe 的高级欺诈功能,并且可以检测异常的浏览行为。

构建支付表单

为了安全地从客户那里收集银行卡详情,Elements 会为您创建一个由 Stripe 托管的 UI 组件。然后将它们作为 iframe 放入您的支付表单。要确定在哪里插入这些组件,请用您的支付表单中的唯一 ID 创建空的 DOM 元素(容器)。

index.html
HTML
CSS
No results
<form id='payment-form'> <label> Card details <!-- placeholder for Elements --> <div id="card-element"></div> </label> <button type="submit">Submit Payment</button> </form>

接下来,创建一个 Stripe 对象实例,提供您可公开的 API 密钥作为第一个参数。之后,创建一个 Elements 对象实例,并用它在页面上的相关占位符内挂载一个 Card 元素。

script.js
查看完整示例
const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
); const elements = stripe.elements(); // Set up Stripe.js and Elements to use in checkout form const style = { base: { color: "#32325d", fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: "antialiased", fontSize: "16px", "::placeholder": { color: "#aab7c4" } }, invalid: { color: "#fa755a", iconColor: "#fa755a" }, }; const cardElement = elements.create('card', {style}); cardElement.mount('#card-element');

card Element 通过插入一个可安全地收集所有必要的银行卡和账单信息的单一灵活的输入字段,对支付表单进行了简化,并且将需要的字段数降到了最低。

否则,对 cardNumber、cardExpiry、和 cardCvc Elements 加以组合,获取灵活的多重输入银行卡表单。

注意

始终要收集邮编,以提高卡的接受率并减少欺诈。

此单行 Card Element 会自动收集邮编并将其发给 Stripe。如果您用分割的 Elements(卡号、有效期、CVC)创建支付表单,那么为客户的邮编添加一个单独的输入字段。

创建 PaymentMethod

最后,在用户点击提交按钮时,用您的客户端上的 stripe.createPaymentMethod 收集银行卡详情并创建一个 PaymentMethod。

script.js
const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); const result = await stripe.createPaymentMethod({ type: 'card', card: cardElement, billing_details: { // Include any additional collected billing details. name: 'Jenny Rosen', }, }) stripePaymentMethodHandler(result); });

向服务器提交 PaymentMethod
客户端

如果 PaymentMethod 创建成功,则将它的 ID 发送到您的服务器。

script.js
const stripePaymentMethodHandler = async (result) => { if (result.error) { // Show error in payment form } else { // Otherwise send paymentMethod.id to your server (see Step 4) const res = await fetch('/pay', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ payment_method_id: result.paymentMethod.id, }), }) const paymentResponse = await res.json(); // Handle server response (see Step 4) handleServerResponse(paymentResponse); } }

创建 PaymentIntent
服务器端

在您的服务器上设置一个端点来接收请求。稍后在处理需要额外验证的付款时,也会用到此端点。

用在您的客户端创建的 PaymentMethod 的 ID 创建新的 PaymentIntent。您可以通过在创建 PaymentIntent 时将 confirm 属性设置为 true 或在创建后调用 confirm 来 确认 PaymentIntent。也支持对银行卡付款进行单独授权和捕获。

如果支付需要额外的操作,如 3DS 验证,PaymentIntent 的状态将设置为 requires_action。如果支付失败,状态将设置回 requires_payment_method,您应该向用户显示错误。如果支付不需要任何额外的验证,则创建一个收款,且 PaymentIntent 状态设置为 succeeded。

注意

在 2019-02-11 以前的 API 版本中,requires_payment_method 显示为 requires_source,而 requires_action 显示为 requires_source_action。

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "payment_method"="{{PAYMENT_METHOD_ID}}" \ -d "amount"=1099 \ -d "currency"="usd" \ -d "confirmation_method"="manual" \ -d "confirm"="true"

如果您想保存该卡以便以后重复使用,请创建一个 Customer 来存储 PaymentMethod,并在创建 PaymentIntent 时传递以下附加参数:

  • customer。设置为 Customer 的 ID。
  • setup_future_usage. Set to off_session to tell Stripe that you plan to reuse this PaymentMethod for off-session payments when your customer isn’t present. Setting this property saves the PaymentMethod to the Customer after the PaymentIntent is confirmed and any required actions from the user are complete. See the code sample on saving cards after a payment for more details.

处理任何后续操作
客户端

编写代码来处理需要客户干预的情况。您在第 4 步时在服务器上确认后,付款会直接成功。但是,当 PaymentIntent 要求客户采取额外操作时,例如通过 3DS 验证进行身份验证,这个代码就开始发挥作用。

用 stripe.handleCardAction 触发处理客户操作的 UI。如果验证成功,则 PaymentIntent 的状态变为 requires_confirmation。在服务器上再次确认 PaymentIntent,以完成付款。

测试时,使用需要验证的测试卡卡号(例如,)来强制实现该流程。使用不需要验证的卡(例如,)会跳过流程中的这个部分,然后在第 4 步去完成。

script.js
const handleServerResponse = async (response) => { if (response.error) { // Show error from server on payment form } else if (response.requires_action) { // Use Stripe.js to handle the required card action const { error: errorAction, paymentIntent } = await stripe.handleCardAction(response.payment_intent_client_secret); 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 } }

注意

stripe.handleCardAction 可能需要几秒才能完成。该时间内,禁止表单重复提交,并显示一个类似于微调器的等待指示器。如果收到错误,则向客户显示,重新启用表单,然后隐藏掉等待指示器。如果客户必须执行额外的步骤来完成付款,如身份验证,Stripe.js 将引导其完成该流程。

再次确认 PaymentIntent
服务器端

该代码仅在支付需要额外验证时才执行,这与上一步的处理方式类似。该代码本身不是可选的,因为任何支付都需要这个额外步骤。

使用您在上方设置的同一个端点再次确认 PaymentIntent 以完成付款,并履行订单。请务必在尝试付款后一小时内确认。否则,付款将失败,并回到 requires_payment_method。

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/confirm \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -X "POST"

测试集成

​​我们为您提供了多张测试卡,供您在沙盒中使用,保证您的集成可顺利完成。可随意搭配 CVC 和未来的一个到期日。

卡号描述
成功并且立即处理付款。
要求验证。Stripe 将触发一个模态,要求客户进行身份验证。
始终会失败,显示拒付码 insufficient_funds。

如需完整的测试卡列表,可查看测试指南。

可选重新收集 CVC

对保存的银行卡创建后续付款时,您可能希望重新收集银行卡的 CVC,以此作为验证用户的额外欺诈预防措施。

先 listing 与您的 Customer 关联的支付方式,确定重新收集 CVC 时显示哪一个。在您的客户端,用 cardCvc Element 从用户那里重新收集某种支付方式的 CVC 值,然后用 stripe.createToken 令牌化 CVC 数据。

在将 CVC 令牌发送到您的服务器后,在服务器上创建一个 PaymentIntent,在 payment_method_options[card][cvc_token] 参数中包含金额、货币和 CVC 令牌。与所有其他令牌一样,CVC 令牌也只能使用一次,因此每个 PaymentIntent 都应该使用它自己的唯一 CVC 令牌。

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d payment_method={{PAYMENT_METHOD_ID}} \ -d customer={{CUSTOMER_ID}} \ -d amount=1099 \ -d currency=usd \ -d confirmation_method=manual \ -d confirm=true \ -d "payment_method_options[card][cvc_token]"={{CVC_TOKEN_ID}}

即使未通过 CVC 检查,付款也可能成功。为防止这个问题的出现,可配置您的 Radar 规则,在 CVC 验证失败时阻止付款。

此页面的内容有帮助吗?
是否
  • 需要帮助?联系支持。
  • 在 Discord 上与 Stripe 开发人员聊天。
  • 查看我们的更改日志。
  • 有问题?联系销售。
  • LLM? Read llms.txt.
  • Powered by Markdoc