--- title: 跳转收银台 permalink: /notes/zh/integrate/link/ createTime: '2025/03/07 16:01:51' description: '说明跳转收银台接入流程,适合希望快速上线支付并让买家跳转至 PingPong 托管页面完成付款的商户。' --- PingPong Checkout 是一款专为全球化业务打造的高效、低代码支付收银台解决方案。我们致力于以极简的接入成本,为商户提供安全、合规、高转化的一站式支付体验,助力业务快速出海与规模化增长。 适用场景:适合希望快速上线支付能力,且采用重定向托管模式(即买家跳转至 PingPong 专属安全页面完成支付)的商户。 ::: tip 适用场景 适合希望快速上线支付能力,且采用重定向托管模式(即买家跳转至 PingPong 专属安全页面完成支付)的团队;若需将收银台直接嵌入商户页面,建议选择[内嵌 SDK 方案](/notes/zh/integrate/sdk-v4-preview/)。 ::: ## 支付体验 ### Web 体验 在跳转收银台模式下,买家在商户网页确认订单后,会跳转至 PingPong 托管收银台完成支付。PingPong Checkout 负责承载支付方式展示、支付信息填写、结果页展示与商户回跳,帮助商户以更低开发成本快速上线标准化网页支付体验。 ![跳转收银台 Web 体验示意图](/images/integrate/hosted-experience/hosted_web_ui.png) ### Mobile 体验 在移动端场景下,买家从手机网页或 App 跳转至 PingPong 托管收银台完成支付。收银台针对小屏幕与触控交互进行了专门优化,并可在支付完成后按配置回跳至商户页面,帮助商户更快提供一致、顺畅的移动端支付体验。 ![跳转收银台 Mobile 体验示意图](/images/integrate/hosted-experience/hosted_mobile_ui.png) ## 支付流程 ```mermaid %%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#E3F2FD', 'primaryTextColor': '#0D47A1', 'primaryBorderColor': '#1976D2', 'lineColor': '#1565C0', 'secondaryColor': '#BBDEFB', 'tertiaryColor': '#90CAF9', 'background': '#F8FBFF', 'mainBkg': '#E3F2FD', 'secondBkg': '#BBDEFB', 'tertiaryBkg': '#90CAF9', 'actorBkg': '#2196F3', 'actorBorder': '#1976D2', 'actorTextColor': '#FFFFFF', 'actorLineColor': '#1565C0', 'signalColor': '#0D47A1', 'signalTextColor': '#0D47A1', 'c0': '#E8F4FD', 'c1': '#D1E7DD', 'c2': '#B3D9FF', 'c3': '#81C784', 'noteBkgColor': '#E1F5FE', 'noteTextColor': '#01579B', 'noteBorderColor': '#0288D1', 'loopTextColor': '#0D47A1', 'activationBkgColor': '#B3E5FC', 'activationBorderColor': '#0277BD' } }}%% %% agent-tag: hosted-redirect-checkout-flow sequenceDiagram participant Client as 💻 客户端 participant Merchant as 🏪 商户服务端 participant PP as 🔄 PingPong服务端 participant Checkout as 🛒 PingPong收银台 participant Bank as 🏦 发卡行 Note over Client, Merchant: 📦 订单创建阶段 Client->>Merchant: 1. 提交订单并发起支付 Merchant->>PP: 2. 调用 prePay(预下单)接口 PP-->>Merchant: 3. 返回 paymentUrl Merchant-->>Client: 4. 返回 paymentUrl Note over Client, Bank: 🛒 收银台支付阶段 Client->>Checkout: 5. 跳转到 PingPong 收银台 Checkout->>PP: 6. 初始化会话并加载支付方式 PP-->>Checkout: 7. 返回可用支付方式 Client->>Checkout: 8. 选择支付方式并确认支付 Checkout->>PP: 9. 提交支付请求 alt 🟢 支付成功 PP-->>Checkout: 10. 返回支付成功结果 Checkout-->>Client: 11. 展示结果页并按配置回跳商户 else 🔐 需要3D验证 PP->>Bank: 12. 发起 3D Secure 验证 Bank-->>Client: 13. 买家完成验证 Bank-->>PP: 14. 返回验证结果 PP-->>Checkout: 15. 返回最终支付结果 Checkout-->>Client: 16. 展示结果页并按配置回跳商户 else ❌ 支付失败 PP-->>Checkout: 17. 返回支付失败结果 Checkout-->>Client: 18. 展示失败页或引导重试 end Note over Merchant, PP: 📡 异步通知与结果确认 PP->>Merchant: 19. 异步通知支付结果 Merchant->>Merchant: 20. 更新订单状态 Merchant-->>PP: 21. 返回 HTTP 200 ``` 流程说明: 1. 买家在商户站点提交订单并发起支付。 2. 商户服务端调用 [prePay(预下单)接口](/notes/zh/checkout/api/reserve/) 创建收银台支付会话。 3. PingPongCheckout 返回 `paymentUrl`、`transactionId` 等信息。 4. 商户服务端将 `paymentUrl` 返回给前端,前端跳转至 PingPong Checkout Page。 5. 买家在 PingPong 托管收银台选择支付方式并完成支付;如需 3D Secure 验证,由收银台引导买家完成验证。 6. 支付完成后,PingPongCheckout 通过 `notificationUrl` 推送支付结果。 7. 如果商户长时间未收到异步通知,或需要在买家回到商户页面后立即核验结果,应主动调用 [交易查询](/notes/zh/checkout/api/getOne/) 确认最终状态。 ::: warning 注意 买家看到收银台结果页或回到商户结果页,只表示前端支付流程已经结束,不代表订单一定支付成功。订单落账、发货或发放权益必须以服务端异步通知或交易查询结果为准。 ::: ## 接口列表 跳转收银台通常涉及以下接口和通知: | 阶段 | 类型 | 文档 | 是否必接 | 用途 | |:---|:---|:---|:---:|:---| | 支付创建 | API | [prePay(预下单)接口](/notes/zh/checkout/api/reserve/) | 必接 | 创建托管收银台支付会话并获取 `paymentUrl` | | 支付结果 | 通知 | [支付通知](/notes/zh/notify/payment/notify/) | 必接 | 接收最终支付结果并更新商户订单状态 | | 支付结果 | API | [交易查询](/notes/zh/checkout/api/getOne/) | 推荐 | 在通知延迟、未达或买家回跳后需要补偿确认时主动核验交易状态 | | 请款 | API | [预授权请款](/notes/zh/checkout/api/modifications/capture/) | 按需 | 对已授权且需手动请款的交易发起 capture | | 请款 | 通知 | [预授权请款通知](/notes/zh/notify/status/captureNotify/) | 按需 | 接收手动请款结果并更新请款状态 | | 请款 | API | [预授权请款查询](/notes/zh/checkout/api/getCapture/) | 推荐 | 在请款通知延迟、未达或对账时主动确认请款状态 | | 退款 | API | [申请退款](/notes/zh/checkout/api/modifications/refund/) | 按需 | 对成功支付的交易发起退款 | | 退款 | 通知 | [退款通知](/notes/zh/notify/refundNotify/) | 按需 | 接收退款结果并更新退款状态 | | 退款 | API | [退款查询](/notes/zh/checkout/api/getRefund/) | 推荐 | 在退款通知延迟、未达或对账时主动确认退款状态 | ## 集成准备 开始开发前,请确认以下信息已经准备完成。 | 准备项 | 说明 | |:---|:---| | 账号信息 | 已获取 `clientId`、`accId`,并确认店铺状态可正常交易 | | 支付方式 | 已开通本次需要展示在收银台中的支付方式,并确认支持的国家、币种、金额范围和退款能力 | | 签名能力 | 已根据 [签名规约](/notes/zh/onlinePayment/developer/sign/) 完成请求签名,所有请求参数都需要参与签名 | | 验签能力 | 已能对 PingPongCheckout 返回响应和异步通知中的 `sign` 执行验签 | | 通知地址 | 已准备公网可访问的 `notificationUrl`,用于接收支付结果异步通知 | | 结果页地址 | 已准备 `payResultUrl`,用于买家完成支付流程后回到商户页面 | | 订单状态处理 | 已在商户系统内保存 `merchantTransactionId`、`transactionId` 和订单状态,并支持幂等更新 | | 前端跳转能力 | 已确认 Web、WAP 或 App 场景中可以正常打开 `paymentUrl`,并完成浏览器兼容性验证 | ::: warning 注意 `notificationUrl` 必须是公网可访问的完整地址,不能填写 `localhost`、`127.0.0.1`、内网 IP,也不要在 URL 后携带 query 参数。 ::: ## 集成步骤 请按以下步骤完成集成: 1. [步骤 1:创建支付会话](#步骤-1-创建支付会话) 2. [步骤 2:跳转至 PingPong 收银台](#步骤-2-跳转至-pingpong-收银台) 3. [步骤 3:买家完成支付](#步骤-3-买家完成支付) 4. [步骤 4:获取最终支付结果](#步骤-4-获取最终支付结果) ### 步骤 1:创建支付会话 买家在商户站点确认订单后,商户服务端调用 [prePay(预下单)接口](/notes/zh/checkout/api/reserve/) 创建支付会话。请不要在浏览器或 App 客户端直接调用该接口,避免签名密钥暴露。 支付请求关键参数: | 参数 | 必填 | 说明 | |:---|:---:|:---| | `captureDelayHours` | O | 资金请款方式。默认自动请款;如需手动请款,请按支付方式能力和接口规则配置 | | `amount` | M | 交易金额 | | `currency` | M | ISO 4217 三位交易币种 | | `merchantTransactionId` | M | 商户网站订单流水号,订单唯一标识 | | `shopperIP` | M | 买家下单 IP | | `merchantUserId` | M | 商户侧用户唯一 ID | | `goods` | M | 商品信息,至少包含商品名称、单价和数量 | | `customer` | C | 买家信息。不同支付方式可能要求邮箱、手机号或账单信息,请以目标支付方式要求为准 | | `paymentMethods` | O | 指定收银台可展示的支付方式范围,不传或为空时按店铺配置展示 | | `notificationUrl` | O | 支付结果通知地址,强烈建议传入 | | `closeNotificationUrl` | O | 关单通知地址。传入后,可接收主动关单或被动关单结果通知 | | `payResultUrl` | O | 买家完成支付流程后的商户结果页地址 | | `language` | O | 收银台展示语言,未传入时默认展示英文,枚举值参考[语言列表](/notes/zh/appendix/languageCode/) | 有关完整参数的更多信息,请参阅 [prePay(预下单)接口](/notes/zh/checkout/api/reserve/)。 支付请求示例: ```json { "captureDelayHours": "0", "amount": "100", "currency": "USD", "merchantTransactionId": "{{merchantTransactionId}}", "payResultUrl": "https://test-acquirerpay.pingpongx.com/qa/result.html", "notificationUrl": "https://test-acquirerpay.pingpongx.com/qa/result.html", "language": "en", "shopperIP": "222.126.52.23", "merchantUserId": "USER_12345", "customer": { "email": "buyer@gmail.com" }, "paymentMethods": [ "VISA", "Mastercard", "Alipay", "GooglePay", "ApplePay" ], "goods": [ { "name": "商品名称mepsking1", "description": "商品描述", "unitPrice": "1", "number": "1", "virtualProduct": "Y", "imgUrl": "https://xiu.mepsking.top/material/1/16606169805015585.png" } ] } ``` 支付响应示例: ```json { "amount": "100", "paymentUrl": "https://sandbox-safepay.pingpongx.com?token=EU:OYUi5wmfOMRNFJnqmPRR2QHvtJihf8cTKvay2yeHTuRbnqIBpMJra9KtN9YQ_sXo8DsnSxGh_e_6tMpzRzlXjA==", "transactionId": "26070600000751051115", "token": "EU:OYUi5wmfOMRNFJnqmPRR2QHvtJihf8cTKvay2yeHTuRbnqIBpMJra9KtN9YQ_sXo8DsnSxGh_e_6tMpzRzlXjA==", "merchantTransactionId": "PMT-A1XGH96WNE1783303688835", "currency": "USD", "innerJsUrl": "https://payssr-cdn.pingpongx.com/production-fra/acquirer-checkout-web/sandbox/pp-checkout.js?token=EU:OYUi5wmfOMRNFJnqmPRR2QHvtJihf8cTKvay2yeHTuRbnqIBpMJra9KtN9YQ_sXo8DsnSxGh_e_6tMpzRzlXjA==" } ``` 支付响应关键字段: | 参数 | 说明 | |:---|:---| | `transactionId` | PingPong 交易流水号,用于后续查询、退款、对账 | | `merchantTransactionId` | 商户网站订单流水号 | | `paymentUrl` | PingPong 托管收银台访问地址,跳转收银台模式使用 | | `token` | 收银台 Token,内嵌 SDK 或其他收银台能力可能使用 | | `innerJsUrl` | JS-SDK 地址,内嵌 SDK 模式使用 | ### 步骤 2:跳转至 PingPong 收银台 商户服务端获取 `bizContent.paymentUrl` 后,将该地址返回给前端。前端应直接使用 PingPongCheckout 返回的完整链接跳转,不要自行拼接额外参数,也不要替换域名或路径。 以下为商户前端加载 `paymentUrl` 的示例代码:
::: tabs @tab Web ```js function redirectOnWeb(paymentUrl) { if (!paymentUrl) return; const paymentWindow = window.open(paymentUrl, '_blank'); if (!paymentWindow) { window.location.assign(paymentUrl); } } ``` @tab WAP ```js function redirectOnWap(paymentUrl) { if (!paymentUrl) return; window.location.href = paymentUrl; } ``` @tab App (iOS) ```objc // Objective-C 示例: NSURL *url = [NSURL URLWithString:paymentUrl]; if (url) { [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { if (!success) { // 引导买家重试或更换支付方式 } }]; } // Swift 示例: guard let url = URL(string: paymentUrl) else { return } UIApplication.shared.open(url, options: [:]) { success in if !success { // 引导买家重试或更换支付方式 } } ``` @tab App (Android) ```java // Java 示例: try { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(paymentUrl)); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } catch (Exception e) { e.printStackTrace(); } // Kotlin 示例: try { val intent = Intent(Intent.ACTION_VIEW, Uri.parse(paymentUrl)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) startActivity(intent) } catch (e: Exception) { e.printStackTrace() } ``` :::
::: warning 支付跳转注意事项 - `paymentUrl` 具有支付会话属性,应在服务端创建订单后及时返回给买家使用。 - App 场景建议优先使用系统浏览器、Custom Tabs、SFSafariViewController 等系统级能力打开收银台;如果必须使用 WebView,请提前完成真机验证。 - 不要把 `paymentUrl` 当作支付成功凭证保存或展示给非当前买家使用。 ::: ### 步骤 3:买家完成支付 买家进入 PingPong Checkout Page 后,会在托管收银台中选择支付方式、填写必要信息并确认支付。若交易需要 3D Secure 验证,PingPongCheckout 会在收银台流程中引导买家完成验证。 收银台展示语言由 `bizContent.language` 控制。未传入 `language` 时,收银台默认展示英文;传入后,以传入值为准。具体枚举值请参考[语言列表](/notes/zh/appendix/languageCode/)。 支付完成后,PingPongCheckout 默认先展示收银台结果页,再按配置跳转至商户结果页。商户也可在 PingPong Checkout Dashboard 后台配置支付完成后的跳转行为。 ### 步骤 4:获取最终支付结果 跳转收银台的最终支付结果,建议优先通过服务端异步通知确认。若异步通知延迟、未达、通知处理失败,或商户在买家回跳后需要立即核验结果,可再主动调用 [交易查询](/notes/zh/checkout/api/getOne/)。 支付通知示例: ```json { "clientId": "2023121216311410287", "code": "000000", "bizContent": "{\"exchangedCurrency\":\"USD\",\"amount\":\"100.000000\",\"transactionTime\":\"1783303837000\",\"transactionId\":\"26070600000751051115\",\"notifyType\":\"RECHARGE\",\"transactionEndTime\":\"1783303856604\",\"requestId\":\"aaa364ab-c811-47b6-899d-92a4de8189be\",\"merchantTransactionId\":\"PMT-A1XGH96WNE1783303688835\",\"paymentMethod\":{\"type\":\"Alipay\"},\"currency\":\"USD\",\"exchangedAmount\":\"100.000000\",\"captureDelayHours\":0,\"status\":\"SUCCESS\"}", "sign": "A9383DCF4FF42C07423C2BDD77490622AA08DF9155D125683BA8BB794C24CCEC", "accId": "2023121216311410287522", "description": "Transaction succeeded", "signType": "SHA256" } ``` 通知关键字段: | 参数 | 说明 | 处理建议 | |:---|:---|:---| | `notifyType` | 通知类型,支付通知固定为 `RECHARGE` | 用于区分通知事件类型 | | `transactionId` | PingPong 交易流水号 | 保存并用于后续查询、退款、对账 | | `merchantTransactionId` | 商户网站订单流水号 | 用于定位商户订单 | | `amount` / `currency` | 交易金额和币种 | 必须与商户订单金额、币种核对 | | `status` | 支付结果状态 | 按状态更新商户订单 | 通知中的 `status` 建议按以下方式处理: | `status` | 处理指引 | |:---|:---| | `SUCCESS` | 支付成功,可以进行发货、权益发放或订单完成处理 | | `FAILED` | 支付失败,订单保持未支付或失败状态,可允许买家重新支付 | | `CANCEL` | 风控审核拒绝,不可按成功处理 | | `CLOSED` | 订单关闭。备注:只有在上送关单通知地址的情况下,才会发送主动关单或者被动关单的通知 | 收到通知后,您无需对响应内容进行加签处理。但无论订单支付是否成功,均必须严格按照以下固定格式返回响应。商户服务端应优先返回 HTTP `2xx` 确认已接收。 通知响应示例: ```http HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Content-Length: 2 OK ``` ::: warning 关键注意事项 1. 支付结果以服务端异步通知或交易查询结果为准,前端结果页仅用于买家展示; 2. 对异步通知必须执行验签、金额币种核对和幂等处理,避免重复落账; 3. 若未收到异步通知或通知存在延迟,应调用 [交易查询](/notes/zh/checkout/api/getOne/) 补充确认; 4. 可结合[订单状态流转逻辑](/notes/zh/guide/paystatus/),统一处理前端结果展示与服务端订单记账流程。 ::: ## 支付后操作 ### 查询交易 当买家从收银台回到商户结果页、异步通知延迟、通知处理失败,或商户需要执行补偿任务时,可以调用 [交易查询](/notes/zh/checkout/api/getOne/) 获取交易最新状态。 查询时建议优先使用商户侧保存的 `merchantTransactionId` 或 PingPong 返回的 `transactionId` 定位交易。查询请求成功只表示查询接口处理成功,不代表支付成功;商户订单状态仍应以查询响应中的交易状态为准。 查询请求示例: ```json { "merchantTransactionId": "PMT-A1XGH96WNE1783303688835" } ``` 查询响应示例: ```json { "threeDSecure": "", "resultCode": "000000", "transactionTime": "1783303690000", "requestId": "aaa364ab-c811-47b6-899d-92a4de8189be", "merchantTransactionId": "PMT-A1XGH96WNE1783303688835", "currency": "USD", "exchangedAmount": "100.000000", "resultMessage": "Transaction succeeded", "exchangedCurrency": "USD", "amount": "100.000000", "transactionEndingTime": "1783303857000", "transactionId": "26070600000751051115", "paymentMethod": { "type": "Alipay" }, "captureDelayHours": 0, "status": "SUCCESS" } ``` 查询响应关键字段: | 参数 | 处理方式 | |:---|:---| | `resultCode` | `000000` 表示查询请求成功;查询请求成功不等于支付成功 | | `status` | 商户订单状态应以该字段为准 | | `transactionId` | 保存为 PingPong 交易流水号,用于后续退款、对账或查询 | | `amount` / `currency` | 与商户订单金额和币种核对 | | `transactionEndingTime` | 交易到达终态时间,可用于订单完成时间记录 | 查询状态处理建议: | `status` | 处理指引 | |:---|:---| | `INIT` | 初始态,订单已创建,等待支付流程继续推进 | | `PROCESSING` | 进行中,继续等待异步通知或稍后查询 | | `SUCCESS` | 支付成功,可以进行发货、权益发放或订单完成处理 | | `FAILED` | 支付失败,订单保持未支付或失败状态,可允许买家重新支付 | | `AUTH_SUCCESS` | 预授权成功,尚未完成最终扣款;如采用手动请款,请按业务流程继续发起请款 | | `CANCEL` | 预授权撤销或人工审核拒绝,不可按成功处理 | | `CLOSED` | 订单已关闭,买家不能继续使用该订单支付 | ### 请款 默认情况下,PingPongCheckout 会根据支付请求和支付方式能力完成自动请款。如果商户业务需要先授权、后请款,应在创建支付会话时按接口规则配置手动请款,并在交易达到可请款状态后调用 [预授权请款](/notes/zh/checkout/api/modifications/capture/)。 请款结果可通过以下方式确认: | 方式 | 文档 | 使用场景 | |:---|:---|:---| | 异步通知 | [预授权请款通知](/notes/zh/notify/status/captureNotify/) | 接收 PingPongCheckout 主动推送的请款结果 | | 主动查询 | [预授权请款查询](/notes/zh/checkout/api/getCapture/) | 请款通知延迟、未达或对账时补充确认 | ### 退款 支付成功后,如买家申请退款、商户取消已支付订单或需要退回部分或全部款项,可调用 [申请退款](/notes/zh/checkout/api/modifications/refund/) 对原交易发起退款。退款能力与支付方式有关,接入前请确认目标支付方式是否支持退款、退款有效期、是否支持部分退款以及是否支持多次部分退款。 退款结果可通过 [退款通知](/notes/zh/notify/refundNotify/) 接收;如通知延迟、未达或需要对账确认,可调用 [退款查询](/notes/zh/checkout/api/getRefund/) 主动查询。 ### 对账 如需了解账单生成规则与结算周期,可参考 [结算周期和对账单](/notes/zh/reconciliation/settlementCycle/);如需开通账单下载能力,可参阅 [SFTP服务申请](/notes/zh/reconciliation/transactionStatementDownload/)。