# Konbini 支付 用 Payment Intents 和 Payment Methods APIs 实现 Konbini 收款,这是日本在便利店常用的一种支付方式。 # Checkout > This is a Checkout for when payment-ui is checkout. View the full page at https://docs.stripe.com/payments/konbini/accept-a-payment?payment-ui=checkout. > Stripe 可以通过评估货币、付款方式限制和其他参数,自动为客户展示相关支付方式。 > > - 请遵循[接受付款](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=checkout&ui=stripe-hosted)指南,构建一个使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md)的 Checkout 集成。 - 如果您不想使用动态支付方式,请按照以下步骤在 Checkout 集成中手动配置支付方式。 Konbini 是一种[一次性使用](https://docs.stripe.com/payments/payment-methods.md#usage)的支付方式,客户需要[进行额外的步骤](https://docs.stripe.com/payments/payment-methods.md#customer-actions)来完成付款。客户通过在日本便利店提供一个付款码、确认码并支付现金,完成付款。Stripe 会在付款完成时给您通知。 ## 确定兼容性 **支持的商家所在地**:JP **支持的货币**:`jpy` **展示货币**:`jpy` **支付模式**:Yes **设置模式**:No **订阅模式**:No Checkout Session 必须满足以下所有条件才能支持 Konbini 付款: - 所有行项目的*价格* (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)都必须使用同一币种 (JPY)。 - 您只能使用一次性行项目(不支持经常性*订阅* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis)方案)。 ## 接受付款 > 使用本指南之前,先构建一个集成来用 Checkout [接受付款](https://docs.stripe.com/payments/accept-a-payment.md?integration=checkout)。 本指南将指导您启用 Konbini,并说明使用动态支付方式收款与手动配置支付方式之间的差异。 ### 启用 Konbini 这一支付方式 创建新的 [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) 时,您需要: 1. 将 `konbini` 添加到 `payment_method_types`列表。 1. 确保您的所有 `line_items` 都使用 `jpy` 货币。 #### Stripe 托管页面 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=jpy" \ -d "line_items[0][price_data][product_data][name]=Tシャツ" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=konbini" \ --data-urlencode "success_url=https://example.com/success" ``` #### 完整嵌入式页面 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=jpy" \ -d "line_items[0][price_data][product_data][name]=Tシャツ" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=konbini" \ --data-urlencode "return_url=https://example.com/return" \ -d ui_mode=embedded_page ``` ### 其他支付方式选项 支付方式选项可以在 [payment method options](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-konbini)(`konbini` 参数下)中指定。 | 字段 | 值 | 必填 | 默认值 | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -- | --- | | `expires_after_days` | 待处理的 Konbini 付款到期前的自然天数。有效值为 1 到 60 天。见[有效期](https://docs.stripe.com/payments/konbini/accept-a-payment.md#checkout-additional-options-expiration)。 | 否 | 3 | #### 有效期 待处理的 Konbini 付款在特定日期的午夜 (23:59:59 JST) 准时过期。例如,如果 `expires_after_days` 设置为 2,然后未在周一确认 PaymentIntent,则待处理的 Konbini 付款将在日本时间 (UTC+9) 周三的 23:59:59 过期。 #### Stripe 托管页面 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=jpy" \ -d "line_items[0][price_data][product_data][name]=Tシャツ" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_options[konbini][expires_after_days]=7" \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=konbini" \ --data-urlencode "success_url=https://example.com/success" ``` #### 完整嵌入式页面 ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]=jpy" \ -d "line_items[0][price_data][product_data][name]=Tシャツ" \ -d "line_items[0][price_data][unit_amount]=2000" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d "payment_method_options[konbini][expires_after_days]=7" \ -d "payment_method_types[0]=card" \ -d "payment_method_types[1]=konbini" \ --data-urlencode "return_url=https://example.com/return" \ -d ui_mode=embedded_page ``` #### 电话号码 在 Konbini 结账表单上,您的客户可以选择提供一个电话号码作为他们的确认码。这简化了他们在便利店的支付过程,店内的 UI 要求客户提供付款码和确认码。这两者都反映在客户提交完结账表单后 Stripe 显示的付款说明中。如果您的客户没有提供电话号码,则 Stripe 会生成一个随机的确认码。 Stripe 主动阻止仅包含零的电话号码。 ### 重定向到 Stripe 托管的付款凭单页面 > 与银行卡付款不同,用 Konbini 付款时,客户不会被重定向到 [success_url](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-success_url)。 成功提交 Checkout 表单后,客户被重定向到 `hosted_voucher_url`。客户可以参考托管页面的付款说明,了解如何完成付款的详细信息。该页面可以在桌面电脑和手机上查看,还可以打印。 成功创建 Konbini 付款凭单时,Stripe 会发送一个 [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) 事件。如果您需要通过邮件给客户发送付款凭单的付款说明链接,可以在 [payment_intent.next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-hosted_voucher_url) 中找到 `hosted_voucher_url`。了解如何[用 Webhook 监测 PaymentIntent](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks)。 Stripe 允许在[品牌设置](https://dashboard.stripe.com/account/branding)页面自定义面向客户的 UI。下列品牌设置项可应用付款凭单: - **图标**——您的品牌图片及公开的商家名称 - **强调色**——用作复印数字按钮的颜色 - **品牌颜色**——用作背景颜色 ### 履行订单 由于 Konbini 是一种延迟通知型支付方式,因此您需要用一种方式(例如 *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests))来监测付款状态并处理订单*履行* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)情况。了解有关[设置 Webhook 和履行订单](https://docs.stripe.com/checkout/fulfillment.md)的更多信息。 付款状态变化时会发送以下事件: | 事件名称 | 描述 | 后续步骤 | | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | 客户成功提交了 Checkout 表单。Stripe 已生成 Konbini 付款凭单。 您可以选择通过邮件将 `hosted_voucher_url` 发给您的客户,以防他们丢掉 Konbini 付款凭单。 | 等待客户支付 Konbini 付款。 | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | 客户成功支付了 Konbini 付款凭单。`PaymentIntent` 状态变为 `succeeded`。 | 履行客户购买的商品或服务。 | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | Konbini 付款凭单已过期,或付款因其他原因失败了。`PaymentIntent` 返回到 `requires_payment_method` 的状态。 | 通过电子邮件联系客户,请求其重新下单。 | ## 测试您的集成 测试您的 Checkout 集成时,选择 Konbini 这一支付方式,然后点击**支付**按钮。 在 Checkout 内提供以下值,以测试不同的场景。您可以用专用确认码或邮件样式来测试。如果两者都用,则专用确认码的行为适用。 | 邮件地址 | 确认码 | 描述 | | ---------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | `11111111110` | 模拟一笔三分钟后成功的 Konbini 付款,然后收到 `payment_intent.succeeded` Webhook。 例如:hanako@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | `22222222220` | 模拟一笔立即成功的 Konbini 付款,然后收到 `payment_intent.succeeded` Webhook。 例如:succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | `33333333330` | 模拟一笔立即过期 Konbini 付款,然后收到 `payment_intent.payment_failed` Webhook。 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 字段设置为当前时间,不要管 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中的 `expires_after_days` 或 `expires_at` 参数设置的是什么时间。 例如:expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | `44444444440` | 模拟一笔永远不会成功的 Konbini 付款,然后收到 `payment_intent.payment_failed` Webhook。 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 字段设置为未来 3 分钟,不要管 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中的 `expires_after_days` 或 `expires_at` 参数设置的是什么时间。 例如:expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | `55555555550` | 模拟一笔永远不会成功的 Konbini 付款;按照 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中提供的各个参数的 `next_action.konbini_display_details` 中的 `expires_at` 字段的时间过期,然后收到 `payment_intent.payment_failed` Webhook。 例如:fill_never@test.com | 要测试[确认码](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-confirm-payment-intent-additional-options-confirmation-number)的错误,可以使用以下值: - `01234567890` 模拟确认码被拒绝的情况。 - `00000000000` 会导致验证错误。 ## 过期和取消 在由 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 值指定的时间过后,客户将无法在便利店自助终端为待处理的 Konbini 支付_发起_支付流程。但是,如果他们在截止日期前发出了有效的付款单,则也许能够在 `expires_at` 时间过后在收银台_完成_付款。 这种情况下,会有一个缓冲期,避免在提前付款失败。PaymentIntent 的状态会变成 `requires_payment_method`。这时,可以用另一支付方式取消或确认 PaymentIntent。 您也可以在确认后以及 `next_action.konbini_display_details.expires_at` 指定的时间到达前,取消待处理的 Konbini 付款。更新 PaymentIntent 或用另一种支付方式确认它也将隐式地取消现有的 Konbini 付款。 如果客户当前正在便利店进行 Konbini 支付,则取消请求将失败。如果客户放弃付款尝试且付款单过期后,可重新尝试取消。 请注意,[支付方式暂时性的可用性问题](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-handling-temporary-availability-issues)也会影响(既有显示又有隐式影响)取消请求。 > 取消待处理的支付时,原始支付说明会失效。大多数情况下,建议您联系您的客户,通知他们取消支付。 > > 成功地重新确认了 `requires_action` 状态的 PaymentIntent 后,我们会创建新的说明和新的 `hosted_voucher_url`。您要保证客户意识到这些问题。 ## 退款 可以通过[管理平台](https://dashboard.stripe.com/payments)或 [API](https://docs.stripe.com/api.md#create_refund) 来退还 Konbini 付款。 要直接完成转到客户银行账户的退款,您的客户必须提供用来接收资金的银行账户的详细信息。Stripe 会通过支付方式上的账单详情中的邮件地址联系客户,并请求他们提供这些信息。收到银行详情后,我们会自动处理退款。 退款的状态变化如下: | 活动 | 退款状态 | | ----------------------------------- | ----------------- | | 退款已创建 | `requires_action` | | 客户提交银行账户详情,Stripe 开始处理退款 | `pending` | | 退款预计会到达客户的银行 | `succeeded` | | 客户的银行将资金退回到 Stripe | `requires_action` | | 创建 45 天以后,退款状态变为 `requires_action`。 | `failed` | | 退款从 `requires_action` 状态取消 | `canceled` | 如果客户的银行不能成功完成转账,资金会退到 Stripe,然后退款状态变为 `requires_action`。在账户持有人的姓名与收款行记录的姓名不匹配,或提供的银行账号有输入错误时,就会发生这种情况。这些情况下,Stripe 会邮件通知客户发生的故障,并让他们重新提交银行账户详情。 如果您的客户不能在 45 天内提供他们的银行账户详细信息,退款的状态将变为 `failed`,我们发送 [refund.failed](https://docs.stripe.com/api/events/types.md#event_types-refund.failed) 事件。这意味着 Stripe 不能处理这笔退款,您必须[在 Stripe 外部将资金退给客户](https://docs.stripe.com/refunds.md#failed-refunds)。 退款上的 [instructions_email](https://docs.stripe.com/api/refunds/object.md#refund_object-instructions_email) 字段是退款发至的邮件地址。当退款等待客户回复时,还可以在退款的 [next_action.display_details.email_sent](https://docs.stripe.com/api/refunds/object.md#refund_object-next_action-display_details-email_sent) 字段中找到发给客户的电子邮件的详细信息。 每笔退款(包括部分退款)都可能产生费用。请联系您的 Stripe 联系人,了解更多信息。 ### 测试退款 您可以在测试模式下,通过发送给客户邮件中的银行账户详情收集页面,使用以下测试用银行账户来测试退款流程。非这些测试账户以外的银行账户详情将不予受理。 | 路径 | 账户 | 类型 | | --------- | ------------------------------------------------------------- | ----- | | `1100000` | `0001234` | 退款成功。 | | `1100000` | `1111113` `1111116` `1111113` `3333335` `4444440` | 退款失败。 | #### 测试退款有效时间 您可以发起一个 API 调用来模拟一笔测试退款的有效时间。 ```bash curl https://api.stripe.com/v1/test_helpers/refunds/{{REFUND_ID}}/expire \ -X POST \ -u <>: ``` ## See also - [Checkout 订单履行](https://docs.stripe.com/checkout/fulfillment.md) - [自定义 Checkout](https://docs.stripe.com/payments/checkout/customization.md) # 直接收款 API > This is a 直接收款 API for when payment-ui is direct-api. View the full page at https://docs.stripe.com/payments/konbini/accept-a-payment?payment-ui=direct-api. 日本的用户可以接收在日本的客户用 Payment Intents 和 Payment Methods APIs 进行的 Konbini 付款。客户通过在日本便利店提供一个付款码、确认码并支付现金,完成付款。Stripe 会在付款完成时给您通知。 ## 设置 Stripe [服务器端] 首先,您需要有 Stripe 账户。[立即注册](https://dashboard.stripe.com/test/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 [服务器端] Stripe 用一个 [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) 对象来表示您从客户收款的意图,跟踪从 Konbini PaymentIntent 创建直至完成整个过程中的状态变化。 请在您的服务器上创建 PaymentIntent,并设定金额与 `jpy` 货币(便利店支付不支持其他货币)。如果您已使用 [Payment Intents API](https://docs.stripe.com/payments/payment-intents.md) 进行集成,请在 PaymentIntent 的[支付方式类型](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types)列表中添加 `konbini`。 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=jpy \ -d "payment_method_types[]=konbini" \ -d "payment_method_options[konbini][product_description]=Tシャツ" \ -d "payment_method_options[konbini][expires_after_days]=3" ``` ### 检索客户端私钥 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)),用于在客户端安全地完成支付流程。有不同的方法可以将客户端私钥传递到客户端。 #### 单页应用 使用浏览器的 `fetch` 功能,从您的服务器上的端点获取客户端私钥。如果您的客户端是单页应用,特别是用现代的前端框架(例如 React)搭建的情况,则该方法最为合适。创建服务于客户端私钥的服务器端点: #### 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
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` ### 其他支付方式选项 支付方式选项可以在 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini)(`konbini` 参数下)中指定。 | 字段 | 值 | 必填 | 默认值 | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -- | ----- | | `expires_after_days` | 待处理的 Konbini 付款到期前的自然天数。有效值为 1 到 60 天。参见[有效期](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-additional-options-expiration)。 | 否 | 3 | | `expires_at` | 待处理的 Konbini 付款到期的一个 Unix 时间戳。有效期必须至少在当前时间 30 分钟以后,且在将设置应用到 PaymentIntent 之后的 60 天以内。参见[有效期](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-additional-options-expiration)。 | 否 | *复位* | | `product_description` | 产品描述符最多包含 22 个字符,将在便利店向客户展示。如果包含非 Shift JIS ([JIS X 0208:1997](https://en.wikipedia.org/wiki/Shift_JIS)) 字符,将返回错误。虽然此项非必需,但我们建议设置此选项。否则,我们将自行选择一个通用占位符,例如“お買い上げ商品・サービス”(所购商品/服务)。 | 否 | *占位符* | #### 有效期 待处理的 Konbini 付款在特定日期的午夜 (23:59:59 JST) 准时过期。例如,如果 `expires_after_days` 设置为 2,然后未在周一确认 PaymentIntent,则待处理的 Konbini 付款将在日本时间 (UTC+9) 周三的 23:59:59 过期。 `expires_at` 设置为 Unix 时间戳,精确到秒。如果该值小于当前时间 30 分钟,或 PaymentIntent 确认操作距离到期时间不足 30 分钟,则会返回一个错误。 `expires_after_days` 和 `expires_at` 彼此互斥。如两个都设置,会返回一个错误。两个也都是可选的,如果两个都不设置,则到期时间默认为创建 PaymentIntent 3 天后的日本时间 23:59 (UTC+9)。 ### 错误处理 对 PaymentIntent 的请求(如创建、更新和确认)可能会失败。您可以查看 API 响应中的 `error` 值来确定原因,并且在许多情况下可以重新提交请求或修正错误。特别地,如果您为 `confirmation_number` 支付方式选项提供了值,您可能需要处理我们返回的特定错误码。更多详情,请参阅 [确认号](https://docs.stripe.com/payments/konbini/accept-a-payment.md#confirm-payment-intent-additional-options-confirmation-number)。 支付方式有时可能因服务中断、计划维护或您的使用模式而暂时不可用。更多详情,请参阅[处理临时可用性问题](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-handling-temporary-availability-issues)。 ## 收集支付方式详情 [客户端] 在您的客户端创建一个支付表单,从客户那里收集要求的账单详情: | 字段 | 值 | | ------- | ------------------------------------------------------------------------------------------------------------------ | | `name` | 客户的全名,会在便利店的 UI 和收据中截短为 20 个字符。非 Shift JIS ([JIS X 0208:1997](https://en.wikipedia.org/wiki/Shift_JIS)) 字符将被删除或替换。 | | `email` | 客户的完整邮件地址。 | 此表单示例中还收集了电话号码,用作客户提供的确认码。 ```html
``` ## 向 Stripe 提交付款 [客户端] 客户通过 Konbini 点击支付时,用 Stripe.js 向 Stripe 提交付款。[Stripe.js](https://docs.stripe.com/payments/elements.md) 是我们构建支付流程的基础 JavaScript 库。 在您的结账页面包含 Stripe.js 脚本,方法是将它添加到您的 HTML 文件的 `head` 部分。 ```html Checkout ``` 用下面的 JavaScript 在您的结账页面创建一个 Stripe.js 实例。 ```javascript // Set your publishable key. Remember to switch to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` 用您在[第 2 步](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-create-payment-intent)创建的 PaymentIntent 对象的 [stripe.confirmKonbiniPayment](https://docs.stripe.com/js/payment_intents/confirm_konbini_payment) 和 [client secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) 提交客户的账单详情。 一经确认,Stripe 将自动打开一个模态,向客户显示 Konbini 付款说明。 ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmKonbiniPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, }, }, payment_method_options: { konbini: { confirmation_number: document.getElementById('phone').value.replace(/\D/g,''), }, }, } ); // Stripe.js will open a modal to display the Konbini payment instructions to your customer // This async function finishes when the customer closes the modal if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } }); ``` > `stripe.confirmKonbiniPayment` 可能需要几秒钟才能完成。在此期间,请禁用表单,以防止重复提交,并显示等待指示器(如加载动画)。如果收到错误信息,请将其展示给客户,重新启用表单,并隐藏等待指示器。 ### 其他支付方式选项 确认 Konbini PaymentIntent 时,您可以在 [payment method options](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-payment_method_options-konbini)(`konbini` 参数下)中指定其他支付方式选项。 | 字段 | 值 | 必填 | 默认值 | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -- | ---- | | `confirmation_number` | 10 至 11 位数字字符串。此字符串也会显示在支付说明中,不能只包含零。如果您没有为 `confirmation_number` 提供值,Stripe 会为您随机生成一个值。有关更多信息,请参见[确认码](https://docs.stripe.com/payments/konbini/accept-a-payment.md#confirm-payment-intent-additional-options-confirmation-number)。 | 否 | *复位* | #### 确认码 您的客户在付款时可能需要参考 `confirmation_number`。如果您选择您来设置或允许客户设置,那通常建议将此值设置成客户的手机号码。在服务器端创建 PaymentIntent 的过程中,也可以设置 `confirmation_number`,但更常见的情况是在确认 PaymentIntent 时由客户在客户端设置。从创建 PaymentIntent 直至确认,设定的值可能会一直更新。 如果指定的某个 `confirmation_number` 在进行中的便利店交易中过于普遍,则在确认 PaymentIntent 时可能会被拒绝。这种情况下返回的错误代码是 `payment_intent_konbini_rejected_confirmation_number`,只有在确认 PaymentIntent 时才会出现。 在创建 PaymentIntent 时以及更新和确认过程中,Stripe 会主动阻止仅包含零的确认码。请确保在您这一端没有设置这样的值或没有允许客户设置这样的值。 ### 错误处理 确认 PaymentIntent 客户端时也可能会失败。您应检查 `error` 返回值,以确定失败原因,并视情况向客户显示错误信息,或修正错误后重试。 ## Optional: 向客户显示您自己的 Konbini 支付说明 [客户端] 建议依靠 Stripe.js,用 `confirmKonbiniPayment` 来处理 Konbini 支付说明的显示。但是,您也可以手动向客户显示您自己的支付说明。 要手动处理向客户显示 Konbini 详情的下一步操作,请在[第 4 步](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-submit-payment)中调用 `stripe.confirmKonbiniPayment` 时使用 `handleActions: false`。 ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmKonbiniPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, }, }, payment_method_options: { konbini: { confirmation_number: document.getElementById('phone').value.replace(/\D/g,''), }, }, }, {handleActions: false}, ); // This async function finishes when the PaymentIntent is confirmed if (result.error) { // Display error to your customer var errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } else { // A Konbini PaymentIntent was successfully created var amount = result.paymentIntent.amount; var currency = result.paymentIntent.currency; var details = result.paymentIntent.next_action.konbini_display_details; for (var store in details.stores) { // Do something with each store's details } var expires_at = details.expires_at; // Display Konbini details to end customer } }); ``` ### 介绍 您可以指定如何向客户显示支付说明。您的说明中必须至少包含以下内容: - 与购买有关的常规信息,例如产品描述、金额及付款有效期。 - 通过确认 PaymentIntent 获得的每个连锁便利店的付款码和确认码。 - 告诉客户如何完成 Konbini 付款的说明。下面是一个示例: ### Konbini 付款说明 1. 找出您计划支付的连锁便利店的支付码和确认码。 1. 在便利店,在支付机器或收银员处提供支付码和确认码。 1. 完成支付后,保留收据以作记录。 1. 如有任何疑问,请联系我们。 ## Optional: 从您的服务器向 Stripe 提交支付 [服务器端] 我们建议使用 Stripe.js 通过 [stripe.confirmKonbiniPayment](https://docs.stripe.com/js/payment_intents/confirm_konbini_payment) 在客户端处理 Konbini 支付。使用 Stripe.js 有助于将您的集成扩展至其他支付方式。但您也可以按照以下步骤在服务器端手动重定向客户: - 在创建 `konbini` 类型的 [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) 时,将 `confirm` 设置为 `true`,或 [confirm](https://docs.stripe.com/api/payment_intents/confirm.md) 现有 PaymentIntent。必须提供 `payment_method_data.billing_details.name` 和 `payment_method_data.billing_details.email` 属性。您还可以选择设置 `payment_method_options.konbini.confirmation_number` 或其他 [payment_method_options](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-additional-options)。通过指定 `payment_method_data`,我们将创建一个 *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs),并立即用于该 PaymentIntent。 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=jpy \ -d confirm=true \ -d "payment_method_types[]=konbini" \ -d "payment_method_data[type]=konbini" \ -d "payment_method_data[billing_details][name]=Jenny Rosen" \ --data-urlencode "payment_method_data[billing_details][email]=jenny@example.com" ``` 创建的 `PaymentIntent` 的状态为 `requires_action`,而 `next_action` 的类型为 `konbini_display_details`。 #### Json ```json {"status": "requires_action", "next_action": { "type": "konbini_display_details", "konbini_display_details": { "expires_at": 1642431599, "hosted_voucher_url": "https://payments.stripe.com/konbini/voucher/...", "stores": { "familymart": { "confirmation_number": "12345678901", "payment_code": "123456" }, ... } } }, "id": "pi_1G1sgdKi6xqXeNtkldRRE6HT", "object": "payment_intent", "amount": 1099, "client_secret": "pi_1G1sgdKi6xqXeNtkldRRE6HT_secret_h9B56ObhTN72fQiBAuzcVPb2E", "confirmation_method": "automatic", "created": 1642126547, "currency": "jpy", "livemode": true, "charges": { "data": [], "object": "list", "has_more": false, "url": "/v1/charges?payment_intent=pi_1G1sgdKi6xqXeNtkldRRE6HT" }, "payment_method_options": { "konbini": { "confirmation_number": null, "expires_after_days": null, "expires_at": null, "product_description": null } }, "payment_method_types": [ "konbini" ] } ``` - 将客户重定向到 `next_action.konbini_display_details.hosted_voucher_url` 属性中提供的 URL。此处的代码示例为近似值。您的 Web 框架中的重定向方法可能有所不同。 #### Ruby ```ruby if payment_intent.status == 'requires_action' && payment_intent.next_action.type == 'konbini_display_details' url = payment_intent.next_action.konbini_display_details.hosted_voucher_url redirect(url) end ``` 建议您[依靠 Webhook](https://docs.stripe.com/payments/payment-intents/verifying-status.md#webhooks) 来确认付款状态。 ## Optional: 自定义支付说明 您可以使用[品牌设置](https://dashboard.stripe.com/account/branding)页面自定义客户看到的内容。如果某个 [customer](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer) 关联到了 PaymentIntent,则托管的付款说明将使用该客户的首选语言。如果不是,则使用客户的浏览器语言。 您可以将以下品牌设置应用到托管的支付说明: - **图标** — 您的品牌形象及公开的商家名称 - **徽标** — 您的品牌形象 - **强调颜色** —“打印”按钮的颜色 - **品牌颜色** — 背景颜色 ## Optional: 发送付款说明邮件 您可以在管理平台中的[电子邮件设置](https://dashboard.stripe.com/settings/emails)页面上启用 Konbini 支付说明和提醒电子邮件。在启用说明电子邮件后,Stripe 会在确认 PaymentIntent 时发送支付说明电子邮件。这些电子邮件包含支付码、确认码以及在便利店支付所需的其他详情。其中包含一个指向托管支付说明页面的链接。 ## Optional: 发送提醒电子邮件 您可以在管理平台中的[电子邮件设置](https://dashboard.stripe.com/settings/emails)页面上启用支付提醒电子邮件并配置每个 PaymentIntent 的提醒电子邮件最大数量。Stripe 每天最多发送一封提醒电子邮件,直到支付成功、过期或取消。 > 在测试环境中,说明和提醒邮件只会发送到 Stripe 账户关联的邮件地址。 ## 处理付款后事件 [服务器端] Konbini 是一种[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)支付方式,因此资金不会立即到账。客户在结账后,可能不会立即在便利店支付待处理的 Konbini 款项。 待处理的 Konbini 付款完成后,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) 处理程序来接收这些事件并运行动作。这些动作包括:向客户发送订单确认邮件、在数据库中记录订单,或启动配送流程。 在可以稳妥地确定待处理的 Konbini 付款未完成时(通常在过期一小时以后),Stripe 会发送一个 [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) 事件。 | 活动 | 描述 | 后续步骤 | | -------------------------------- | ------------------------------- | ------------------------------------- | | `payment_intent.requires_action` | 创建了待处理的 Konbini 支付。 | (可选)将客户转至支付说明页面。等待客户对 Konbini 支付进行付款。 | | `payment_intent.succeeded` | 客户在到期时间之前支付待处理的 Konbini 付款。 | 履行客户购买的商品或服务。 | | `payment_intent.payment_failed` | 客户未在到期时间之前对待处理的 Konbini 支付进行付款。 | 通过电子邮件或推送通知联系客户,请求另一支付方式。 | > 测试时,Konbini PaymentIntent 的状态可能会根据发送的参数自动变化,例如 `email`。可以在[管理平台](https://dashboard.stripe.com/test/payments)确认发生的更新。参见[测试集成](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-test-integration)中的更多信息。 ### 接收事件并启动公司操作 #### 手动 用 Stripe 管理平台查看您的所有 Stripe 付款,发送邮件收据,处理提现或重试失败的付款。 - [在管理平台内查看测试付款](https://dashboard.stripe.com/test/payments) #### 自定义代码 构建一个 Webhook 处理程序,侦听事件并构建自定义同步付款流程。用 Stripe CLI 在本地测试并调试您的 Webhook 集成。 - [构建自定义 Webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) ## 测试集成 测试时,调用 [stripe.confirmKonbiniPayment](https://docs.stripe.com/js/payment_intents/confirm_konbini_payment) 来测试不同场景时将 `payment_method.billing_details.email` 设置到下列值。您可以用专用确认码或邮件样式来测试。如果两者都用,则专用确认码的行为适用。 | 邮件地址 | 确认码 | 描述 | | ---------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | `11111111110` | 模拟一笔三分钟后成功的 Konbini 付款,然后收到 `payment_intent.succeeded` Webhook。 例如:hanako@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | `22222222220` | 模拟一笔立即成功的 Konbini 付款,然后收到 `payment_intent.succeeded` Webhook。 例如:succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | `33333333330` | 模拟一笔立即过期 Konbini 付款,然后收到 `payment_intent.payment_failed` Webhook。 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 字段设置为当前时间,不要管 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中的 `expires_after_days` 或 `expires_at` 参数设置的是什么时间。 例如:expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | `44444444440` | 模拟一笔永远不会成功的 Konbini 付款,然后收到 `payment_intent.payment_failed` Webhook。 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 字段设置为未来 3 分钟,不要管 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中的 `expires_after_days` 或 `expires_at` 参数设置的是什么时间。 例如:expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | `55555555550` | 模拟一笔永远不会成功的 Konbini 付款;按照 [payment method options](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-konbini-expires_after_days) 中提供的各个参数的 `next_action.konbini_display_details` 中的 `expires_at` 字段的时间过期,然后收到 `payment_intent.payment_failed` Webhook。 例如:fill_never@test.com | 要测试[确认码](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-confirm-payment-intent-additional-options-confirmation-number)的错误处理情况,可以使用 `payment_method_options[confirmation_number]` 的以下值: - `01234567890` 生成 `payment_intent_konbini_rejected_confirmation_number` 错误代码。 - `00000000000` 生成一般验证错误代码。您应该通过预验证来避免在集成中出现这一错误。 ## 过期和取消 在由 [next_action.konbini_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-konbini_display_details-expires_at) 中的 `expires_at` 值指定的时间过后,客户将无法在便利店自助终端为待处理的 Konbini 支付_发起_支付流程。但是,如果他们在截止日期前发出了有效的付款单,则也许能够在 `expires_at` 时间过后在收银台_完成_付款。 这种情况下,会有一个缓冲期,避免在提前付款失败。PaymentIntent 的状态会变成 `requires_payment_method`。这时,可以用另一支付方式取消或确认 PaymentIntent。 您也可以在确认后以及 `next_action.konbini_display_details.expires_at` 指定的时间到达前,取消待处理的 Konbini 付款。更新 PaymentIntent 或用另一种支付方式确认它也将隐式地取消现有的 Konbini 付款。 如果客户当前正在便利店进行 Konbini 支付,则取消请求将失败。如果客户放弃付款尝试且付款单过期后,可重新尝试取消。 请注意,[支付方式暂时性的可用性问题](https://docs.stripe.com/payments/konbini/accept-a-payment.md#web-handling-temporary-availability-issues)也会影响(既有显示又有隐式影响)取消请求。 > 取消待处理的支付时,原始支付说明会失效。大多数情况下,建议您联系您的客户,通知他们取消支付。 > > 成功地重新确认了 `requires_action` 状态的 PaymentIntent 后,我们会创建新的说明和新的 `hosted_voucher_url`。您要保证客户意识到这些问题。 ## 处理临时性的可用性问题 以下错误代码表明支付方式的可用性出现了临时性的问题: | 代码 | 描述 | 处理 | | ------------------------------------ | ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | | `payment_method_rate_limit_exceeded` | 该支付方式的连续请求太多,其限制比我们的 [API 范围的速率限制](https://docs.stripe.com/rate-limits.md)更严格。 | 用退避方式重新尝试一般是可以解决这种问题的。但是,在持续大量使用支付方式的情况下(例如,您的网站持续促销期间),一些特定数量的请求可能会持续发生这些错误。这种情况下,让您的客户考虑选择不同的支付方式可能也是一种缓解措施。 | | `payment_method_not_available` | 支付方式遇到了未知的临时性问题,这些问题可能会持续一段时间(例如,在中断或计划性的维护期间)。 | 最好邀请用户使用其他支付方式完成购买,或稍后再试。 | > 如果您预计整体用量会很大,或者即将有大型活动,请提前与我们联系。 ## 退款 可以通过[管理平台](https://dashboard.stripe.com/payments)或 [API](https://docs.stripe.com/api.md#create_refund) 来退还 Konbini 付款。 要直接完成转到客户银行账户的退款,您的客户必须提供用来接收资金的银行账户的详细信息。Stripe 会通过支付方式上的账单详情中的邮件地址联系客户,并请求他们提供这些信息。收到银行详情后,我们会自动处理退款。 退款的状态变化如下: | 活动 | 退款状态 | | ----------------------------------- | ----------------- | | 退款已创建 | `requires_action` | | 客户提交银行账户详情,Stripe 开始处理退款 | `pending` | | 退款预计会到达客户的银行 | `succeeded` | | 客户的银行将资金退回到 Stripe | `requires_action` | | 创建 45 天以后,退款状态变为 `requires_action`。 | `failed` | | 退款从 `requires_action` 状态取消 | `canceled` | 如果客户的银行不能成功完成转账,资金会退到 Stripe,然后退款状态变为 `requires_action`。在账户持有人的姓名与收款行记录的姓名不匹配,或提供的银行账号有输入错误时,就会发生这种情况。这些情况下,Stripe 会邮件通知客户发生的故障,并让他们重新提交银行账户详情。 如果您的客户不能在 45 天内提供他们的银行账户详细信息,退款的状态将变为 `failed`,我们发送 [refund.failed](https://docs.stripe.com/api/events/types.md#event_types-refund.failed) 事件。这意味着 Stripe 不能处理这笔退款,您必须[在 Stripe 外部将资金退给客户](https://docs.stripe.com/refunds.md#failed-refunds)。 退款上的 [instructions_email](https://docs.stripe.com/api/refunds/object.md#refund_object-instructions_email) 字段是退款发至的邮件地址。当退款等待客户回复时,还可以在退款的 [next_action.display_details.email_sent](https://docs.stripe.com/api/refunds/object.md#refund_object-next_action-display_details-email_sent) 字段中找到发给客户的电子邮件的详细信息。 每笔退款(包括部分退款)都可能产生费用。请联系您的 Stripe 联系人,了解更多信息。 ### 测试退款 您可以在测试模式下,通过发送给客户邮件中的银行账户详情收集页面,使用以下测试用银行账户来测试退款流程。非这些测试账户以外的银行账户详情将不予受理。 | 路径 | 账户 | 类型 | | --------- | ------------------------------------------------------------- | ----- | | `1100000` | `0001234` | 退款成功。 | | `1100000` | `1111113` `1111116` `1111113` `3333335` `4444440` | 退款失败。 | #### 测试退款有效时间 您可以发起一个 API 调用来模拟一笔测试退款的有效时间。 ```bash curl https://api.stripe.com/v1/test_helpers/refunds/{{REFUND_ID}}/expire \ -X POST \ -u <>: ```