--- title: 退款 permalink: /notes/zh/integrate/modify/Refund/ createTime: '2025/03/07 16:02:02' description: '说明如何对成功支付交易发起全额或部分退款,并通过退款通知或退款查询确认最终结果。' --- 退款是指在一笔交易已经成功支付,且资金状态允许退款后,商户将部分或全部交易金额返还给买家的过程。您可以发起全额退款,也可以发起部分退款;若支付方式支持,多次部分退款的累计金额不得超过原交易的可退金额。 对于支持单独 Capture 的支付方式,只有在 Capture 成功后才能退款;如果原交易仍处于已授权未捕获状态,应使用 [Void](/notes/zh/integrate/modify/Void/) 而不是退款。 ## 退款方式 在支付成功后,您可以通过以下两种方法发起退款: 1. 调用退款接口对成功支付的交易发起退款。 2. 在商户后台退款。 ## 退款流程 ```mermaid sequenceDiagram participant Server as 🏪 商户服务端 participant PP as 🔄 PingPongCheckout Server->>PP: 1. 调用退款接口 PP-->>Server: 2. 返回退款结果(SUCCESS / FAILED / PROCESSING) opt [status = PROCESSING] Server->>PP: 3. 调用退款查询获取退款结果 PP-->>Server: 4. 返回退款状态 end PP-->>Server: 5. 推送退款通知(成功 / 失败) ``` 流程说明: 1. 商户服务端调用 [申请退款](/notes/zh/checkout/api/modifications/refund/) 发起退款。 2. 同步响应可能直接返回 `SUCCESS`、`FAILED` 或 `PROCESSING`。 3. 如果同步响应为 `PROCESSING`,商户可调用 [退款查询](/notes/zh/checkout/api/getRefund/) 主动确认退款状态。 4. PingPongCheckout 也会通过 [退款通知](/notes/zh/notify/refundNotify/) 返回最终退款结果。 ## 退款状态机 退款属于支付成功后的独立后置操作。原支付单应已处于 `SUCCESS`,退款成功或失败不会将原支付单的 `status` 改为退款状态;商户应使用 `merchantRefundId` 或 `refundId` 跟踪退款对象的状态。 ```mermaid flowchart LR ORIGINAL[原支付单状态: SUCCESS] -.-> START((发起退款)) START --> PROCESSING[PROCESSING] PROCESSING -->|退款成功| SUCCESS[SUCCESS] PROCESSING -.->|退款失败| FAILED[FAILED] SUCCESS --> END((END)) FAILED --> END ``` ## 集成步骤 请按以下步骤完成集成: 1. [发起退款请求](#步骤-1-发起退款请求) 2. [获取退款结果](#步骤-2-获取退款结果) ### 步骤 1:发起退款请求 支付成功后,调用 [申请退款](/notes/zh/checkout/api/modifications/refund/) API 发起退款。请根据原交易流水号和本次退款流水号组装请求;如果希望在 `PROCESSING` 场景下异步接收最终结果,建议正确配置 `notificationUrl`。 退款请求关键字段: | 字段 | 必填 | 说明 | |:---|:---:|:---| | `bizContent.merchantRefundId` | 是 | 商户侧退款流水请求唯一标识 | | `bizContent.merchantTransactionId` | 是 | 商户支付时定义的商户网站订单号 | | `bizContent.amount` | 是 | 退款金额 | | `bizContent.currency` | 是 | 退款币种 | | `bizContent.notificationUrl` | 否 | 用于接收退款结果的异步通知地址 | 有关完整参数的更多信息,请参阅[退款接口](/notes/zh/checkout/api/modifications/refund/)。 退款请求示例: ```json { "accId": "2023121216311410287522", "clientId": "2023121216311410287", "signType": "SHA256", "sign": "{{Sign}}", "version": "1.0", "bizContent": { "amount": 50, "currency": "USD", "merchantTransactionId": "PMT-KRTTYPSLBE1782370463605", "notificationUrl": "https://www.example.com/refund/notify", "merchantRefundId": "refund2026062514001" } } ``` ::: warning 注意 - 仅对已成功支付且当前仍允许退款的交易发起退款;如果是手动 Capture 的交易,请先确认已完成 Capture;如无法确认原交易当前状态,可先调用 [交易查询](/notes/zh/checkout/api/getOne/) 确认原交易状态。 - 不同支付方式可能存在是否支持退款、退款有效期、是否支持部分退款或多次部分退款等差异,具体信息详见[支付方式](/notes/zh/paymentMethods/overview/);部分支付方式在退款时需要额外参数,详见 [特殊支付方式退款说明](/notes/zh/guide/bestPractices/specialRefund/)。 - [申请退款](/notes/zh/checkout/api/modifications/refund/) API 基于 `merchantRefundId` 做幂等控制:同一笔退款请求重复提交时请保持 `merchantRefundId` 不变;如果上一笔退款请求失败且需要重新发起,请使用新的 `merchantRefundId`。 - 如需对同一原交易执行多次部分退款,每次退款都应使用新的 `merchantRefundId`;多次部分退款的累计金额不得超过原交易的可退金额。 ::: 退款响应关键字段: | 字段 | 说明 | |:---|:---| | `bizContent.merchantRefundId` | 商户侧退款流水请求唯一标识 | | `bizContent.refundId` | PingPong 退款流水号,可用于后续查询或对账 | | `bizContent.transactionId` | PingPong 原交易流水号 | | `bizContent.status` | 退款状态,可能为 `SUCCESS`、`FAILED` 或 `PROCESSING` | 退款响应示例: ```json { "accId": "2023121216311410287522", "bizContent": "{\"exchangeAmount\":\"50.000000\",\"merchantTransactionId\":\"PMT-KRTTYPSLBE1782370463605\",\"currency\":\"USD\",\"amount\":\"50\",\"refundTime\":\"1782370583121\",\"transactionId\":\"26062500000650916958\",\"exchangeCurrency\":\"USD\",\"merchantRefundId\":\"refund2026062514001\",\"refundId\":\"26062500010650916976\",\"status\":\"SUCCESS\"}", "clientId": "2023121216311410287", "code": "000000", "description": "Transaction succeeded", "sign": "5063B78230FCCCFDF5C05171F129A8691FAE030FC196E11557003F6217E361D2", "signType": "SHA256" } ``` 调用退款接口后,同步响应中的 `status` 可能为以下值: - `SUCCESS`:退款成功,可直接更新退款状态 - `FAILED`:退款失败,应结合错误原因决定是否重试 - `PROCESSING`:退款处理中,需继续等待退款通知或主动查询 ### 步骤 2:获取退款结果 退款发起后,商户应通过以下方式确认最终结果: 1. 接收 [退款通知](/notes/zh/notify/refundNotify/) 2. 如异步通知延迟、未达、网络异常或需要再次核验结果,可主动调用 [退款查询](/notes/zh/checkout/api/getRefund/) 如果您通过异步通知接收结果,可参考以下通知示例与处理方式。 退款通知示例: ```json { "clientId": "2023121216311410287", "code": "000000", "bizContent": "{\"amount\":\"50.000000\",\"refundTime\":\"1782370582000\",\"transactionId\":\"26062500000650916958\",\"notifyType\":\"REFUND\",\"merchantTransactionId\":\"PMT-KRTTYPSLBE1782370463605\",\"currency\":\"USD\",\"merchantRefundId\":\"refund2026062514001\",\"refundEndingTime\":\"1782370583083\",\"refundId\":\"26062500010650916976\",\"status\":\"SUCCESS\"}", "sign": "5505326E5FEAB26C1DAD253DD06E0E13F4BBA74AA69D7E156B5E26C17CAE0B4F", "accId": "2023121216311410287522", "description": "Transaction succeeded", "signType": "SHA256" } ``` 在退款异步通知场景下,`status` 会返回最终退款结果,即 `SUCCESS` 或 `FAILED`。收到 `SUCCESS` 时可将退款更新为成功;收到 `FAILED` 时可将退款更新为失败。 收到通知后,商户服务端建议按以下方式处理: - 先返回 HTTP `2xx` 确认已接收,避免触发重复通知 - 再根据通知中的 `status` 更新退款结果,并执行对应业务处理 通知响应示例: ```http HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Content-Length: 2 OK ``` 如果异步通知延迟、未达,或商户侧因网络异常、回调处理失败、结果核验等原因暂时无法确认最终状态,可主动调用 [退款查询](/notes/zh/checkout/api/getRefund/) 获取退款结果。 退款查询请求关键字段: | 字段 | 必填 | 说明 | |:---|:---:|:---| | `bizContent.merchantTransactionId` | 是 | 商户支付时定义的商户网站订单号 | | `bizContent.merchantRefundId` | 条件必填 | 商户侧退款流水号,与 `bizContent.refundId` 至少上送一项 | | `bizContent.refundId` | 条件必填 | PingPong 退款流水号,与 `bizContent.merchantRefundId` 至少上送一项 | 有关完整参数的更多信息,请参阅[退款查询接口](/notes/zh/checkout/api/getRefund/)。 退款查询请求示例: ```json { "accId": "2023121216311410287522", "clientId": "2023121216311410287", "signType": "SHA256", "sign": "{{Sign}}", "version": "1.0", "bizContent": { "merchantRefundId": "PMT-KZW7XVPKVL1782370581548", "merchantTransactionId": "PMT-KRTTYPSLBE1782370463605" } } ``` 退款查询响应示例: ```json { "accId": "2023121216311410287522", "bizContent": "{\"amount\":\"50.000000\",\"refundTime\":\"1782370582000\",\"resultCode\":\"000000\",\"transactionId\":\"26062500000650916958\",\"merchantTransactionId\":\"PMT-KRTTYPSLBE1782370463605\",\"currency\":\"USD\",\"resultMessage\":\"Transaction succeeded\",\"refundEndingTime\":\"1782370583000\",\"refundId\":\"26062500010650916976\",\"status\":\"SUCCESS\"}", "clientId": "2023121216311410287", "code": "001000", "description": "Successful request", "sign": "CDEAD58D00E75DD79642290B6D85190622986A978F23A9FAC1653C876A93F97E", "signType": "SHA256" } ``` 退款查询响应关键字段: | 字段 | 说明 | |:---|:---| | `bizContent.merchantTransactionId` | 商户订单号,用于关联原支付订单 | | `bizContent.refundId` | PingPong 退款流水号 | | `bizContent.status` | 退款状态,可能为 `SUCCESS`、`FAILED` 或 `PROCESSING` | | `bizContent.refundEndingTime` | 退款到达终态时间,可用于记录最终完成时间 | 退款查询响应中的 `status` 可能返回 `SUCCESS`、`FAILED` 或 `PROCESSING`。如果查询结果为 `PROCESSING`,说明退款结果尚未最终确认,建议稍后重试查询,或继续等待退款通知。 ::: note 提示 退款查询请在退款同步响应返回之后调用;若查询过早,可能会出现查询异常。 :::