Refund
适用于 EC 和 In-Store(线下)场景。
如果您希望将资金退还给用户(例如,用户退货),您需要 refund 该笔支付。
您只能在支付已被 captured 之后才能进行 refund。尚未 captured 的支付必须改用 cancel。详见 Cancel 章节。
您可以 refund 全部已 captured 金额,也可以 refund 部分已 captured 金额。如果多次部分 refund 的总额不超过已 captured 金额,您也可以进行多次部分 refund。
最长 refund 时限为支付完成后的 365 天。
Make a refund request
Step 1: Make a refund request
当您收到 payment.status 为 Captured 的 capture 结果时,可以从您的服务器向 EVO Cloud 端点
/g2/v1/payment/mer/{sid}/refund
发起 HTTP POST 请求以 refund 初始 payment,并指定以下参数。
| 查询参数 | 必填 | 说明 |
|---|---|---|
merchantTransID | M | 初始 Payment 的 merchantTransInfo.merchantTransID。 |
| Body 参数 | 必填 | 说明 |
|---|---|---|
merchantTransInfo | M | 本次 refund 的引用信息,包含唯一的 merchantTransID 和 merchantTransTime(发起请求的时间)。 |
transAmount | M | refund 支付的币种与金额。金额须符合该币种的最小货币单位。 |
initiatingReason | O | 可在该字段中说明本次请求的原因。 |
webhook | O | 用于接收通知的 URL。指定后可在支付成功后从 EVO Cloud 接收通知。 |
paymentMethod | O | 支付方式对象。 |
paymentMethod.type | O | 本文档场景下须为 card。 |
metadata | O | 您可在请求中自定义的引用信息,将在响应中原样回显。 |
paymentMethod 对象的更多细节:
1.paymentMethod.type:请求中设置为 card。
2.paymentMethod.card.encryptedCardInfo:加密后的卡信息。如果使用 EVO Cloud 客户端方案安全加密用户卡信息,前端会从 EVO Cloud SDK 获取该值,需发送至您的服务器,再由服务器原样转发至 EVO Cloud。
3.paymentMethod.card.cardInfo:卡信息原始数据。如果将原始卡数据采集并发送至 EVO Cloud,需要在此对象中指定 cardNumber、expiryDate、cvc(可选)、track2 与 holderName。对于部分 UnionPay 借记卡,expiryDate 也为可选。 (如果 paymentMethod.card.encryptedCardInfo 和 paymentMethod.card.cardInfo 同时存在,将以 paymentMethod.card.cardInfo 为准。)
4.paymentMethod.card字段
| 字段路径 | 必填/选填 | 条件 | 说明 |
|---|---|---|---|
paymentMethod.card | M | paymentMethod.type=card | 卡相关交易对象。 |
paymentMethod.card.encryptedCardInfo | O | 已批准加密卡集成方案 | 加密卡信息。 |
paymentMethod.card.cardInfo | O | 已批准卡信息集成方案 | 卡信息容器。 |
paymentMethod.card.cardInfo.cardNumber | M | 手动/MOTO 或最终 schema 要求 | 卡号。在示例或测试数据中请勿使用真实值。 |
paymentMethod.card.cardInfo.expiryDate | O | MOTO 必填 | 过期日期,MMYY 格式。 |
paymentMethod.card.posEntryMode | O | POS 卡通道 | 卡数据输入方式。 |
paymentMethod.card.pinFlag | O | 终端支持 PIN | true 表示终端可接受 PIN;false 表示不接受。 |
paymentMethod.card.termReadability | O | 提供终端能力时 | 终端卡数据输入能力。 |
paymentMethod.card.icCardCondCode | O | UnionPay IC 场景 | UnionPay 卡条件码。 |
paymentMethod.card.noSecretNoSignFlag | O | UnionPay 场景 | UnionPay 无密/无签标识。 |
paymentMethod.card.cardInfo.track1 | O | 磁条或特定通道要求 | Track 1 数据。最终字段名以已批准的 schema 为准。 |
paymentMethod.card.cardInfo.track2 | O | 磁条、ICC、contactless 或 fallback 场景 | Track 2 数据。禁止以明文存储或记录。 |
paymentMethod.card.cardInfo.cardSequenceNum | O | ICC 或 contactless 场景 | IC 卡序列号。 |
paymentMethod.card.cardInfo.icCardData | O | ICC 或 contactless 场景 | EMV/ICC TLV 数据。 |
paymentMethod.card.pin | O | PIN 交易 | PIN 容器(如最终 schema 中包含)。 |
paymentMethod.card.pin.encryptedPin | M | PIN 交易 | 加密后的 PIN block。禁止以明文记录或持久化。 |
paymentMethod.card.pin.pinEncryptMethod | M | PIN 交易 | 已批准的 PIN 加密方式,例如支持时的 3DES。 |
paymentMethod.card.pin.checkValue | O | 启用密钥版本查询 | 用于识别适用工作密钥版本的值(如支持)。 |
5.Card posEntryMode 模式
| posEntryMode 模式 | 交易活动 | 典型条件数据 |
|---|---|---|
magnetic | 磁条读取 | track2 |
ICC | 接触式芯片插入 | track2 、icCardData 、cardSequenceNum |
contactless | NFC EMV 挥卡 | track2 、icCardData 、cardSequenceNum |
contactless magnetic | 使用磁条通道的 contactless 交易 | track2 |
fallback | EMV 回退至磁条 | track2 |
manual | 手工输入卡 | cardNumber 、expiryDate |
MOTO | 邮购/电话订购 | cardNumber 、expiryDate |
最终 API schema 是字段名、长度、条件必填与 PSP 特定限制的权威依据。
以下为 10 USD Refund 请求示例:
1.curl -X POST https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/refund?merchantTransID={YOUR_TRANS_ID_OF_INITIAL_PAYMENT}\
2.-H "Content-Type: application/json" \
3.-H "DateTime: 2021-12-31T08:30:59+0800" \
4.-H "MsgID: 2d21a5715c034efb7e0aa383b885fc7a" \
5.-H "SignType: SHA256" \
6.-H "Authorization: YOUR_MESSAGE_SIGNATURE" \
7.-d '{
8. "merchantTransInfo": {
9. "merchantTransID": "YOUR_TRANS_ID_OF_INITIAL_REFUND",
10. "merchantTransTime": "2021-12-31T08:35:59+08:00"
11. },
12. "transAmount": {
13. "currency": "USD",
14. "value": "10.00"
15. },
16. "paymentMethod": {
17. "type": "card",
18. "card": {
19. "posEntryMode": "ICC",
20. "pinFlag": true,
21. "cardInfo": {
22. "cardNumber": "6222021234567890123",
23. "track2": "6222021234567890123=26122011234567890123",
24. "icCardData": "9F02069F03069F1A029F26089F27019F36029F37049F1008",
25. "cardSequenceNum": "001"
26. },
27. "pin": {
28. "encryptedPin": "base64encodedPinBlock==",
29. "pinEncryptMethod": "3DES",
30. "checkValue": "A1B2C3"
31. }
32. }
33. },
34. "webhook": "https://YOUR_COMPANY.com/WEBHOOK",
35. "initiatingReason": "Goods returned by customers",
36. "metadata": "This is a metadata" ,
37. "transInitiator": {
38. "platform": "POS",
39. "terminalID": "30100101",
40. "paymentScenario": "inStore"
41. }
42.}'如果请求成功,响应中将包含一个 refund 对象和一个 payment 对象,分别展示 refund 和原始 payment 的状态及相关信息。
refund 对象详细信息:
refund.status:本次 refund 的状态,必填。取值可为Success、Failed或Received。如果refund.status为Received,您需要再发起一次 HTTP GET 请求以获取 refund 的最终状态(详见 Step 2),或等待 EVO Cloud 的通知 webhook。refund.transAmount:refund 的币种与金额,必填。从您的请求中原样回显。refund.merchantTransInfo:本次 refund 的引用对象,由您的服务器生成,必填。从您的请求中原样回显。refund.evoTransInfo:本次 refund 的引用对象,由 EVO Cloud 生成,必填。包含evoTransID、evoTransTime,以及部分 PSP(如 Visa 或 Mastercard)的可选字段traceNum与retrievalReferenceNum。refund.pspTransInfo:本次 refund 的引用对象,由 PSP 生成,可选。包含pspTransID、pspTransTime与authorizationCode。如果 PSP 返回,EVO Cloud 会将该信息从 PSP 转发至您的服务器。refund.billingAmount与refund.billingFXRate:refund 的用户账单币种与金额,以及refund.transAmount.currency与refund.billingAmount.currency之间的汇率,可选。如果 PSP 返回,EVO Cloud 会将该信息从 PSP 转发至您的服务器。适用于 PSP 进行货币换算的 E-Wallet 支付,或您启用了 DCC 功能的卡支付。详情请联系 EVO Cloud 客户经理。refund.convertTransAmount与refund.convertTransFXRate:EVO Cloud 在将交易发送至 PSP 时,基于transAmount与transAmount.currency到目标币种的汇率计算出的币种与金额,以及refund.transAmount.currency与refund.convertTransAmount.currency之间的汇率,可选。如果您在 EVO Cloud 启用了货币换算功能且本次 refund 适用,将提供该汇率。详情请联系 EVO Cloud 客户经理。
以下为成功响应示例:
1.{
2. "result": {
3. "code": "S0000",
4. "message": "Success"
5. },
6. "paymentMethod": {
7. "card": {
8. "first6No": "476134",
9. "last4No": "0019",
10. "paymentBrand": "Visa",
11. "fundingType": "credit"
12. }
13. },
14. "payment": {
15. "status": "Refunding",
16. "merchantTransInfo": {
17. "merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
18. "merchantTransTime": "2021-12-31T08:30:59+08:00"
19. },
20. "evoTransInfo": {
21. "evoTransID": "8a0d5cd24b5b4156b94010cee115bceb",
22. "evoTransTime": "2021-12-31T00:30:59Z"
23. },
24. "pspTransInfo": {
25. "pspTransTime": "2021-12-31T08:30:59+08:00",
26. "authorizationCode": "091410",
27. "retrievalReferenceNum": "135616370503"
28. },
29. "transAmount": {
30. "currency": "USD",
31. "value": "10.00"
32. }
33. },
34. "refund": {
35. "status": "Received",
36. "merchantTransInfo": {
37. "merchantTransID": "YOUR_TRANS_ID_OF_INITIAL_REFUND",
38. "merchantTransTime": "2021-12-31T08:35:59+08:00"
39. },
40. "evoTransInfo": {
41. "evoTransID": "2cf248d44a0f4ed5991fa4f77879d71e",
42. "evoTransTime": "2021-12-31T08:35:59+08:00"
43. },
44. "transAmount": {
45. "currency": "USD",
46. "value": "10.00"
47. }
48. },
49. "pspData": {
50. "name": "Visa"
51. },
52. "metadata": "This is a metadata"
}Step 2: Retrieve the refund result
如果收到 refund.status 为 Received,且您未使用 notification webhook,可以从 EVO Cloud 查询最终结果。
从您的服务器向 EVO Cloud 端点
/g2/v1/payment/mer/{sid}/refund
发起 HTTP GET 请求。
| 查询参数 | 必填 | 说明 |
|---|---|---|
merchantTransID | M | 初始 refund 的 merchantTransInfo.merchantTransID。 |
以下为查询 refund 结果示例:
1.curl https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/refund?merchantTransID={YOUR_TRANS_ID_OF_INITIAL_REFUND} \
2.-H "Content-Type: application/json" \
3.-H "DateTime: 2021-12-31T08:30:59+0800" \
4.-H "MsgID: 2d21a5715c034efb7e0aa383b885fc7a" \
5.-H "SignType: SHA256" \
6.-H "Authorization: YOUR_MESSAGE_SIGNATURE"以下为 GET 响应示例。POST 响应与 GET 响应类似。
1.{
2. "result": {
3. "code": "S0000",
4. "message": "Success"
5. },
6. "paymentMethod": {
7. "card": {
8. "first6No": "476134",
9. "last4No": "0019",
10. "paymentBrand": "Visa",
11. "fundingType": "credit"
12. }
13. },
14. "payment": {
15. "status": "Refunded",
16. "merchantTransInfo": {
17. "merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
18. "merchantTransTime": "2021-12-31T08:30:59+08:00"
19. },
20. "evoTransInfo": {
21. "evoTransID": "8a0d5cd24b5b4156b94010cee115bceb",
22. "evoTransTime": "2021-12-31T00:30:59Z"
23. },
24. "pspTransInfo": {
25. "pspTransTime": "2021-12-31T08:30:59+08:00",
26. "authorizationCode": "091410",
27. "retrievalReferenceNum": "135616370503"
28. },
29. "transAmount": {
30. "currency": "USD",
31. "value": "10.00"
32. }
33. },
34. "refund": {
35. "status": "Success",
36. "merchantTransInfo": {
37. "merchantTransID": "YOUR_TRANS_ID_OF_INITIAL_REFUND",
38. "merchantTransTime": "2021-12-31T08:35:59+08:00"
39. },
40. "evoTransInfo": {
41. "evoTransID": "2cf248d44a0f4ed5991fa4f77879d71e",
42. "evoTransTime": "2021-12-31T08:35:59+08:00"
43. },
44. "pspTransInfo": {
45. "pspTransTime": "2021-12-31T08:30:59+08:00"
46. },
47. "transAmount": {
48. "currency": "USD",
49. "value": "10.00"
50. }
51. },
52. "pspData": {
53. "name": "Visa"
54. },
55. "metadata": "This is a metadata"
56.}Make a cancel instead
如果您发起 refund 请求并收到 result.code 为 B0012,请再次核对响应消息中 payment.status 显示的原始交易状态。如果为 authorised,则表示该笔支付尚未被 captured,您无法 refund 该笔支付。这种情况下,您需要改用 cancel。详见 Cancel 章节。
Error handling
For HTTP POST request to EVO Cloud: 建议在请求发送后至少等待 45 秒。如果在规定时间内未收到响应,需要从 EVO Cloud 查询结果。请参阅 Step 2 发起请求。 For HTTP GET request to EVO Cloud: 可以多次发起请求直到获取结果,建议相邻两次请求之间至少等待 45 秒。如果多次请求后仍无法获取结果,可以改为发起一次新的 cancel 请求。

