--- title: 交易状态与幂等 permalink: /notes/zh/onlinePayment/bestPractices/paystatus/ createTime: '2025/03/07 16:01:49' description: '说明支付状态机、支付状态处理建议和交易幂等规则,覆盖成功、失败、处理中、关单、预授权、退款和重试场景。' --- ## 页面定位 本文用于说明 PingPongCheckout 交易状态的流转逻辑,以及商户侧如何基于 `merchantTransactionId`、`requestId` 做幂等处理。如何通过异步通知和交易查询获取订单结果,请参考如何获取订单状态。 ## 交易生命周期总览 交易生命周期描述一笔支付订单从创建到终态的主要状态变化。下面按收银台模式和 Direct API 模式分别展示失败非终态、失败终态两种幂等模式下的状态流转,并覆盖 `Sales`(自动请款)和 `Auth/Capture`(预授权后请款)的差异;商户服务端应将 `status` 作为订单处理依据,并对重复通知、重复查询结果做幂等处理,避免重复发货、重复记账或状态回退。 ### 收银台模式 收银台模式下,商户先创建支付会话,订单从 `INIT` 进入 `PROCESSING`,买家再通过 PingPong 收银台完成后续支付流程。 ```mermaid flowchart LR START((Create payment intent)) --> INIT[INIT] INIT --> PROCESSING[PROCESSING] PROCESSING -->|Success(Sales)| SUCCESS[SUCCESS] PROCESSING -->|Success(Auth - Capture)| AUTH_SUCCESS[AUTH_SUCCESS] AUTH_SUCCESS -->|capture| SUCCESS PROCESSING -.-> FAILED[FAILED] FAILED -.->|失败非终态重新支付| PROCESSING PROCESSING -.->|风控审核拒绝| CANCEL[CANCEL] AUTH_SUCCESS -.->|Void| CANCEL PROCESSING -.->|超时关单| CLOSED[CLOSED] SUCCESS --> END((END)) FAILED --> END CANCEL --> END CLOSED --> END ``` ```mermaid flowchart LR START((Create payment intent)) --> INIT[INIT] INIT --> PROCESSING[PROCESSING] PROCESSING -->|Success(Sales)| SUCCESS[SUCCESS] PROCESSING -->|Success(Auth - Capture)| AUTH_SUCCESS[AUTH_SUCCESS] AUTH_SUCCESS -->|capture| SUCCESS PROCESSING -.-> FAILED[FAILED] PROCESSING -.->|风控审核拒绝| CANCEL[CANCEL] AUTH_SUCCESS -.->|Void| CANCEL PROCESSING -.->|超时关单| CLOSED[CLOSED] SUCCESS --> END((END)) FAILED --> END CANCEL --> END CLOSED --> END ``` ### Direct API 模式 Direct API 模式下,商户服务端通过下单并支付接口发起支付请求,状态通常从 `PROCESSING` 开始推进;失败非终态模式下,买家可重新下单支付。 ```mermaid flowchart LR START((Create payment intent)) --> PROCESSING[PROCESSING] PROCESSING -->|Success(Sales)| SUCCESS[SUCCESS] PROCESSING -->|Success(Auth - Capture)| AUTH_SUCCESS[AUTH_SUCCESS] AUTH_SUCCESS -->|Capture| SUCCESS PROCESSING -.-> FAILED[FAILED] FAILED -.->|失败非终态重新下单支付| START PROCESSING -.->|风控审核拒绝| CANCEL[CANCEL] AUTH_SUCCESS -.->|Void| CANCEL PROCESSING -.->|超时关单| CLOSED[CLOSED] SUCCESS --> END((END)) FAILED --> END CANCEL --> END CLOSED --> END ``` ```mermaid flowchart LR START((Create payment intent)) --> PROCESSING[PROCESSING] PROCESSING -->|Success(Sales)| SUCCESS[SUCCESS] PROCESSING -->|Success(Auth - Capture)| AUTH_SUCCESS[AUTH_SUCCESS] AUTH_SUCCESS -->|Capture| SUCCESS PROCESSING -.-> FAILED[FAILED] PROCESSING -.->|风控审核拒绝| CANCEL[CANCEL] AUTH_SUCCESS -.->|Void| CANCEL PROCESSING -.->|超时关单| CLOSED[CLOSED] SUCCESS --> END((END)) FAILED --> END CANCEL --> END CLOSED --> END ``` `captureDelayHours=0` 时,支付成功后会自动完成扣款,主交易进入 `SUCCESS`。`captureDelayHours=-1` 时,支付会先进入 `AUTH_SUCCESS`,商户需要继续发起 Capture 完成请款,或发起 Void 撤销预授权。退款只能在主交易进入 `SUCCESS` 后发起,且退款结果不会改变原支付交易的 `SUCCESS` 状态。 ### 核心状态转移表 下表用于补充状态机图中的核心路径,帮助商户快速判断不同事件触发后应更新到哪个交易状态,以及服务端应采取的处理动作。 | 适用模式 | 当前状态 | 触发事件 | 条件/场景 | 下一状态 | 商户处理建议 | |:---|:---|:---|:---|:---|:---| | 收银台 | `INIT` | 进入支付处理 | 支付会话创建后,买家进入 PingPong 收银台。 | `PROCESSING` | 保持订单为待支付或支付中,等待买家完成支付、异步通知或交易查询结果。 | | 收银台 / Direct API | `PROCESSING` | `Success (Sales)` | 自动请款模式,支付成功后直接完成扣款。 | `SUCCESS` | 标记订单支付成功,并按业务规则发货、开通服务或入账;重复结果需幂等忽略。 | | 收银台 / Direct API | `PROCESSING` | `Success (Auth - Capture)` | 预授权模式,授权成功但尚未完成最终请款。 | `AUTH_SUCCESS` | 标记为预授权成功,后续按业务需要发起 Capture 完成请款,或发起 Void 撤销预授权。 | | 收银台 / Direct API | `AUTH_SUCCESS` | `Capture` | 预授权请款成功。 | `SUCCESS` | 标记订单最终支付成功,并按业务规则履约;请款通知或查询结果需幂等处理。 | | 收银台 / Direct API | `AUTH_SUCCESS` | `Void` | 商户撤销预授权,或业务不再继续请款。 | `CANCEL` | 标记订单取消或失败,不继续发货、不履约。 | | 收银台 / Direct API | `PROCESSING` | 支付失败 | 失败终态模式下,失败结果不可继续推进为成功。 | `FAILED` | 标记订单失败;如买家仍需支付,应重新创建支付请求或引导重新下单。 | | 收银台 | `FAILED` | 重新支付 | 失败非终态模式下,买家在原收银台会话内继续支付。 | `PROCESSING` | 允许买家更换支付方式后继续支付,商户侧保持订单等待最终结果。 | | Direct API | `FAILED` | 重新下单支付 | 失败非终态模式下,商户重新发起支付请求。 | `PROCESSING`(新请求) | 使用新的支付请求推进支付,并在商户侧做好原失败结果与新请求的关联和幂等控制。 | | 收银台 / Direct API | `PROCESSING` | 风控审核拒绝 | 人工审核或风控规则拒绝交易。 | `CANCEL` | 标记订单取消或失败,不发货、不履约;如已生成履约动作需按业务规则拦截。 | | 收银台 / Direct API | `PROCESSING` | 超时关单/主动关单 | 订单超时关闭,或商户主动关闭订单。 | `CLOSED` | 标记订单关闭,禁止买家继续支付;如需继续购买,应重新创建订单。 | ::: note 提示 `SUCCESS`、`CANCEL`、`CLOSED` 以及失败终态模式下的 `FAILED` 均为终态,商户不应将订单状态回退或覆盖为处理中。所有异步通知和查询结果都应基于商户订单号、请求号和交易号做幂等处理。 ::: ## 支付状态处理建议 如果您通过异步通知或交易查询获取到支付 `status`,可按下表更新商户侧订单状态。查询接口可能返回 `INIT`、`PROCESSING`、`SUCCESS`、`FAILED`、`AUTH_SUCCESS`、`CANCEL`、`CLOSED`;支付通知通常返回 `SUCCESS`、`FAILED`、`CANCEL`、`AUTH_SUCCESS`;如果下单时上送了 `closeNotificationUrl`,订单关闭时会发送 `CLOSED` 关单通知。 | 状态 | 状态类型 | 含义 | 商户处理建议 | |:---|:---|:---|:---| | `INIT` | 中间态 | 订单已创建,尚未进入最终处理结果。 | 保持订单为待支付,不发货、不履约,可继续等待通知或定时查询。 | | `PROCESSING` | 中间态 | 支付处理中,仍在等待渠道或风控结果。 | 保持订单为支付中,不发货、不履约,等待异步通知或后续查询结果。 | | `SUCCESS` | 终态 | 支付成功或最终 Capture 成功。 | 标记订单成功,并按业务规则发货、开通服务或入账;重复通知需幂等忽略。 | | `FAILED` | 取决于幂等模式 | 支付失败。失败终态模式下该笔交易不可继续推进;失败非终态模式下可继续支付或重新发起支付请求。 | 失败终态模式下标记订单失败,不再等待该笔交易成功;失败非终态模式下可引导买家更换支付方式继续支付,或重新发起支付请求,并做好新旧请求关联和幂等控制。 | | `AUTH_SUCCESS` | 待后续操作 | 预授权成功,资金尚未完成最终请款。 | 根据业务场景发起 Capture 完成请款,或发起 Void 撤销预授权。 | | `CANCEL` | 终态 | 预授权取消或人工/风控审核拒绝。 | 标记订单取消或失败,不发货、不履约;如已生成履约动作需按业务规则拦截。 | | `CLOSED` | 终态 | 订单超时关闭或商户主动关单。 | 标记订单关闭,禁止买家继续支付;如需继续购买,应重新创建订单。 | ::: note 提示 交易查询请求成功只表示查询接口处理成功,不代表支付成功。商户订单状态仍应以查询响应中的 `status` 为准。 ::: ## 支付后操作状态机 退款、预授权请款和预授权撤销属于支付主交易之后的独立后置操作,建议在对应集成文档中查看完整状态机、状态处理建议和接口接入说明: - [退款](https://acquirer-api-docs-v4-en.pingpongx.com/notes/zh/integrate/modify/Refund/):原支付单处于 `SUCCESS` 后,可发起退款;退款成功不会改变原支付单的 `SUCCESS` 状态。 - [预授权请款](https://acquirer-api-docs-v4-en.pingpongx.com/notes/zh/integrate/modify/Capture/):原支付单处于 `AUTH_SUCCESS` 后,可发起 Capture 完成最终扣款。 - [预授权撤销](https://acquirer-api-docs-v4-en.pingpongx.com/notes/zh/integrate/modify/Void/):原支付单处于 `AUTH_SUCCESS` 且尚未 Capture 时,可发起 Void 释放预留资金。 ## 幂等模式 支持的幂等模式有两种,您可以从下面选择适合自己的幂等模式: 1. 非失败终态(默认) 2. 失败终态 ## 交易幂等规则 商户侧需要围绕订单号和请求号建立清晰的幂等规则: 1. `merchantTransactionId` 是商户侧订单号,应在商户维度下保持全局唯一。对于同一笔商户订单,重复创建支付订单时会幂等返回该支付订单信息。 2. Direct API 模式下,支付请求通常通过 `merchantTransactionId + requestId` 判断唯一性。相同组合重复请求时,会幂等返回同一支付请求的状态信息。 3. 如果商户不希望同一笔订单产生多次支付请求,应复用同一个 `requestId`。 4. 如果需要让买家重新发起一笔新的支付请求,应明确区分原支付请求和新支付请求,并在商户侧做好订单关联和重复支付防护。 5. 收到重复异步通知或多次查询到同一终态时,商户服务端应幂等处理,不能重复发货、重复入账或覆盖更晚的订单状态。 在以上幂等规则基础上,我们提供了一些重试窗口,详见交易挽回。 ## 订单关联关系