# 自定义重定向行为 显示包含客户订单信息的确认页面。 # 托管页面 > This is a 托管页面 for when payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/checkout/custom-success-page?payment-ui=stripe-hosted. 如果您的 Connect 平台使用[客户配置账户](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer),请参阅我们的[指南](https://docs.stripe.com/connect/use-accounts-as-customers.md),将代码中对 `Customer` 和事件的引用替换为相应的 Accounts v2 API 参考文件。 如果您的 Checkout 集成使用了托管页面,Stripe 会将客户重定向到您创建并托管在您网站上的成功页面。您可以使用 [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) 中的详细信息,在付款后为客户显示订单确认页面(例如,显示客户的姓名或付款金额)。 ## 将客户重定向到成功页面 使用来自 Checkout Session 的详情: 1. 修改 [success_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-success_url),将 Checkout Session ID 传递到客户端。 1. 用 ID 在您的成功页面上查找 Checkout Session。 1. 用 Checkout Session 自定义成功页面的显示内容。 > #### 履行需要 Webhook > > 由于客户并不能保证一定会访问您的 Checkout 登录页面,因此您不能只依赖通过此页面触发履行。例如,客户支付成功后,可能会在登录页面加载完成前就失去了与互联网的连接。 > > [设置 Webhook 事件处理程序](https://docs.stripe.com/checkout/fulfillment.md?payment-ui=stripe-hosted#create-payment-event-handler),由此 Stripe 可以完全绕过客户端,直接向您的服务器发送支付事件。Webhook 提供了最可靠的收款确认方式。如果 Webhook 事件发送失败,Stripe 会[重试多次](https://docs.stripe.com/webhooks.md#automatic-retries)。 ## 修改成功 URL (Server-side) 您在创建 Checkout Session 时,需将 `{CHECKOUT_SESSION_ID}` 模板变量添加到 `success_url`。请注意:这是字面字符串,必须严格按照此处所示原样添加。请勿用 Checkout Session ID 替代它——客户付款后会自动触发并重定向到成功页面。 #### Ruby ```ruby session = Stripe::Checkout::Session.create(success_url: "http://yoursite.com/order/success?session_id={CHECKOUT_SESSION_ID}", # other options..., ) ``` ## 创建成功页面 (Server-side) 用 ID 查找 Checkout Session,并创建一个成功页面,用以显示订单信息。该例会打印出客户的姓名: #### Ruby ```ruby # This example sets up an endpoint using the Sinatra framework. # Set your secret key. Remember to switch to your live secret key in production. # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = '<>' require 'sinatra' get '/order/success' dosession = Stripe::Checkout::Session.retrieve(params[:session_id]) customer = Stripe::Customer.retrieve(session.customer) "

Thanks for your order, #{customer.name}!

" end ``` ## 测试集成 要确认您的重定向操作能够正常进行,请执行以下操作: 1. 点击结账按钮。 1. 填写客户名称和其他付款详情。 1. 点击**支付**。 成功之后,您会被重定向到带有自定义消息的成功页面。例如,如果您在代码示例中使用了该消息,则成功页会显示以下消息:**感谢您的订单,Jenny Rosen!** # 嵌入式页面 > This is a 嵌入式页面 for when payment-ui is embedded-form. View the full page at https://docs.stripe.com/payments/checkout/custom-success-page?payment-ui=embedded-form. 如果您的 Connect 平台使用[客户配置账户](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer),请参阅我们的[指南](https://docs.stripe.com/connect/use-accounts-as-customers.md),将代码中对 `Customer` 和事件的引用替换为相应的 Accounts v2 API 参考文件。 如果您的 Checkout 集成使用的是嵌入式表单,那么您可以自定义 Stripe 如何在客户完成付款后对客户进行重定向以及是否进行重定向。您可以让 Stripe 始终重定向客户,仅重定向某些支付方式,或完全禁用重定向。 设置重定向,在 `return_url` [参数](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url)中指定返回页面。 或者,您可以: - [仅当支付方式要求时才重定向客户](https://docs.stripe.com/payments/checkout/custom-success-page.md#redirect-if-required)(例如,基于借记方式的银行授权页面)。 - 不使用返回页面并[禁用基于重定向的支付方式](https://docs.stripe.com/payments/checkout/custom-success-page.md#disable-redirects)。 > #### 履行需要 Webhook > > 由于客户并不能保证一定会访问您的 Checkout 登录页面,因此您不能只依赖通过此页面触发履行。例如,客户支付成功后,可能会在登录页面加载完成前就失去了与互联网的连接。 > > [设置 Webhook 事件处理程序](https://docs.stripe.com/checkout/fulfillment.md?payment-ui=embedded-form#create-payment-event-handler),由此 Stripe 可以完全绕过客户端,直接向您的服务器发送支付事件。Webhook 提供了最可靠的收款确认方式。如果 Webhook 事件发送失败,Stripe 会[重试多次](https://docs.stripe.com/webhooks.md#automatic-retries)。 ## 将客户重定向到返回页面 创建 [Checkout Session](https://docs.stripe.com/api/checkout/sessions.md) 时,在 `return_url` [参数](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url) 中指定返回页面的 URL。在 URL 中包含 `{CHECKOUT_SESSION_ID}` 模板变量。当 Checkout 重定向客户时,它会用实际的 Checkout Session ID 替换该变量。呈现您的返回页面时,用 URL 中的 Checkout Session ID 检索 Checkout Session 的状态。 ```javascript app.get('/session_status', async (req, res) => { const session = await stripe.checkout.sessions.retrieve(req.query.session_id); const customer = await stripe.customers.retrieve(session.customer); res.send({ status: session.status, payment_status: session.payment_status, customer_email: customer.email }); }); ``` 根据会话状态处理结果,如下所示: - `complete`:支付成功。使用来自 Checkout Session 的信息来呈现成功页面。 - `open`:支付失败或已取消。重新加载 Checkout,以便客户重试。 ```javascript const session = await fetch(`/session_status?session_id=${session_id}`) if (session.status == 'open') { // Remount embedded Checkout else if (session.status == 'complete') { // Show success page // Optionally use session.payment_status or session.customer_email // to customize the success page } ``` ## 基于重定向的支付方式 支付过程中,某些支付方式会将客户重定向到一个中间页面,例如银行授权页面。完成该页面上的操作后,Stripe 会将他们重定向到您的返回页面。 ### 仅对基于重定向的支付方式使用重定向 在完成不需要重定向的付款后,如果您不想对客户进行重定,可将 [redirect_on_completion](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-redirect_on_completion) 设置为 `if_required`。这样的话,只会对使用基于重定向的支付方式的客户进行重定向。 对于银行卡支付,Checkout 会呈现默认的成功状态,而不会进行重定向。如需使用自己的成功状态,请传入 [onComplete](https://docs.stripe.com/js/embedded_checkout/create#embedded_checkout_create-options-onComplete) 回调函数,以销毁 Checkout 实例并呈现您自定义的成功状态。 当 Checkout Session 成功完成或发送 [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) Webhook 事件时,调用 `onComplete`。 #### HTML + JS ```javascript const stripe = Stripe('<>'); initialize(); async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Example `onComplete` callback const handleComplete = async function() { // Destroy Checkout instance checkout.destroy() // Retrieve details from server (which loads Checkout Session) const details = await retrievePurchaseDetails(); // Show custom purchase summary showPurchaseSummary(details); } const checkout = await stripe.createEmbeddedCheckoutPage({ fetchClientSecret, onComplete: handleComplete }); checkout.mount('#checkout'); } ``` #### React ```jsx const stripePromise = loadStripe('pk_test_123'); const App = ({fetchClientSecret}) => { const options = {fetchClientSecret}; const [isComplete, setIsComplete] = useState(false); const handleComplete = () => setIsComplete(true); return isComplete ? ( ) : ( ) } ``` ### 禁用基于重定向的支付方式 如果您不想创建返回页面,请创建您的 Checkout Session,将 [redirect_on_completion](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-redirect_on_completion) 设置为 `never`。 这将禁用基于重定向的支付方式: - 如果您使用[动态支付方式](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md),您仍然可以从管理平台管理支付方式,但需要重定向的支付方式不适用。 - 如果您使用 [payment_method_types](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-payment_method_types) 手动指定支付方式,请不要包含任何基于重定向的支付方式。 设置 `redirect_on_completion: never` 可取消对 `return_url` 的要求。对于此类会话,Checkout 会呈现默认的成功状态,而不会进行重定向。您可以通过传入 [onComplete](https://docs.stripe.com/js/embedded_checkout/create#embedded_checkout_create-options-onComplete) 回调函数来使用您自己的成功状态,该函数会销毁 Checkout 实例并呈现您自定义的成功状态。 当 Checkout Session 成功完成或发送 [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) Webhook 事件时,调用 `onComplete`。 #### HTML + JS ```javascript const stripe = Stripe('<>'); initialize(); async function initialize() { const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Example `onComplete` callback const handleComplete = async function() { // Destroy Checkout instance checkout.destroy() // Retrieve details from server (which loads Checkout Session) const details = await retrievePurchaseDetails(); // Show custom purchase summary showPurchaseSummary(details); } const checkout = await stripe.createEmbeddedCheckoutPage({ fetchClientSecret, onComplete: handleComplete }); checkout.mount('#checkout'); } ``` #### React ```jsx const stripePromise = loadStripe('pk_test_123'); const App = ({fetchClientSecret}) => { const options = {fetchClientSecret}; const [isComplete, setIsComplete] = useState(false); const handleComplete = () => setIsComplete(true); return isComplete ? ( ) : ( ) } ```