跳转到内容

Cancel

适用于 EC 和 In-Store(线下)场景。

如果您已预授权一笔支付但不希望 Capture 该笔支付(例如由于商品缺货或系统超时错误),您需要 cancel 该笔支付。

  • 适用的支付方式(Applicable Payment Methods):您只能对支持 Authorization 与 Capture 分离的支付方式执行 cancel,并且必须在支付被 Capture 之前完成。
  • 时效(Timing):建议在 Authorization 后的 7 天内 发起 cancel 请求,因为大多数发卡行会在该时限后清除预授权。
  • Cancel 金额(Cancel Amount):Cancel 金额始终与初始 Payment 金额相同,因此您在 cancel 请求中无需指定金额参数。

Make cancel request

Step 1: Make a cancel request

当您收到 payment.statusAuthorisedPendingVerifying 的支付结果,或如果支付超时时,您可以从您的服务器向 EVO Cloud 端点

/g2/v1/payment/mer/{sid}/cancel

发起 HTTP POST 请求以 cancel 该笔支付,

并指定以下参数。

参数必填说明
merchantTransIDM初始 Payment 的 merchantTransInfo.merchantTransID
参数必填说明
merchantTransInfoM本次 cancel 的引用信息,包含唯一的 merchantTransIDmerchantTransTime(发起请求的时间)。
initiatingReasonO可选:本次请求的原因。
webhook O用于接收通知的 URL。指定后可在支付成功后从 EVO Cloud 接收通知。
paymentMethodO支付方式对象。
paymentMethod.typeO本文档场景下须为 card
metadataO您可在请求中自定义的引用信息,将在响应中原样回显。Notification 中的 metadata 与请求中的 metadata 一致。

paymentMethod 对象的更多细节:

1.paymentMethod.type:请求中设置为 card

2.paymentMethod.card.encryptedCardInfo:加密后的卡信息。如果使用 EVO Cloud 客户端方案安全加密用户卡信息,前端会从 EVO Cloud SDK 获取该值,需发送至您的服务器,再由服务器原样转发至 EVO Cloud。

3.paymentMethod.card.cardInfo:卡信息原始数据。如果将原始卡数据采集并发送至 EVO Cloud,需要在此对象中指定 cardNumberexpiryDatecvc(可选)、track2holderName。对于部分 UnionPay 借记卡,expiryDate 也为可选。 (如果 paymentMethod.card.encryptedCardInfopaymentMethod.card.cardInfo 同时存在,将以 paymentMethod.card.cardInfo 为准。)

4.paymentMethod.card字段

字段路径必填/选填条件说明
paymentMethod.cardMpaymentMethod.type=card卡相关交易对象。
paymentMethod.card.encryptedCardInfoO已批准加密卡集成方案加密卡信息。
paymentMethod.card.cardInfoO已批准卡信息集成方案卡信息容器。
paymentMethod.card.cardInfo.cardNumberM手动/MOTO 或最终 schema 要求卡号。在示例或测试数据中请勿使用真实值。
paymentMethod.card.cardInfo.expiryDateOMOTO 必填过期日期,MMYY 格式。
paymentMethod.card.posEntryModeOPOS 卡通道卡数据输入方式。
paymentMethod.card.pinFlagO终端支持 PINtrue 表示终端可接受 PIN;false 表示不接受。
paymentMethod.card.termReadabilityO提供终端能力时终端卡数据输入能力。
paymentMethod.card.icCardCondCodeOUnionPay IC 场景UnionPay 卡条件码。
paymentMethod.card.noSecretNoSignFlagOUnionPay 场景UnionPay 无密/无签标识。
paymentMethod.card.cardInfo.track1O磁条或特定通道要求Track 1 数据。最终字段名以已批准的 schema 为准。
paymentMethod.card.cardInfo.track2O磁条、ICC、contactless 或 fallback 场景Track 2 数据。禁止以明文存储或记录。
paymentMethod.card.cardInfo.cardSequenceNumOICC 或 contactless 场景IC 卡序列号。
paymentMethod.card.cardInfo.icCardDataOICC 或 contactless 场景EMV/ICC TLV 数据。
paymentMethod.card.pinOPIN 交易PIN 容器(如最终 schema 中包含)。
paymentMethod.card.pin.encryptedPinMPIN 交易加密后的 PIN block。禁止以明文记录或持久化。
paymentMethod.card.pin.pinEncryptMethodMPIN 交易已批准的 PIN 加密方式,例如支持时的 3DES
paymentMethod.card.pin.checkValueO启用密钥版本查询用于识别适用工作密钥版本的值(如支持)。

5.Card posEntryMode 模式

posEntryMode 模式交易活动典型条件数据
magnetic磁条读取track2
ICC接触式芯片插入track2 、icCardData 、cardSequenceNum
contactlessNFC EMV 挥卡track2 、icCardData 、cardSequenceNum
contactless magnetic使用磁条通道的 contactless 交易track2
fallbackEMV 回退至磁条track2
manual手工输入卡cardNumber 、expiryDate
MOTO邮购/电话订购cardNumber 、expiryDate

最终 API schema 是字段名、长度、条件必填与 PSP 特定限制的权威依据。

以下为 cancel 请求示例:

js
1.curl -X POST https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/cancel?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_CANCEL",  
11.        "merchantTransTime": "2021-12-31T08:35:59+08:00"  
12.    },  
13.      "paymentMethod": {
14.         "type": "card",
15.         "card": {
16.             "posEntryMode": "ICC",
17.             "pinFlag": true,
18.             "cardInfo": {
19.                 "cardNumber": "6222021234567890123",
20.                 "track2": "6222021234567890123=26122011234567890123",
21.                 "icCardData": "9F02069F03069F1A029F26089F27019F36029F37049F1008",
22.                 "cardSequenceNum": "001"
23.             },
24.             "pin": {
25.                 "encryptedPin": "base64encodedPinBlock==",
26.                 "pinEncryptMethod": "3DES",
27.                 "checkValue": "A1B2C3"
28.             }
29.         }
30.     },  
31.     "webhook": "https://YOUR_COMPANY.com/WEBHOOK",  
32.    "initiatingReason": "Customer cancels order",  
33.    "metadata": "This is a metadata"  ,
34.     "transInitiator": {
35.         "platform": "POS",
36.         "terminalID": "30100101",
37.         "paymentScenario": "inStore"
38.     }
39.}'

如果请求成功,响应中将包含一个 cancel 对象和一个 payment 对象,分别提供 cancel 和原始 payment 的状态及相关信息。

  1. cancel.status:本次 cancel 的状态,必填。取值可为 SuccessFailedReceived。如果 cancel.statusReceived,您需要再发起一次 HTTP GET 请求以获取 cancel 的最终状态(详见 Step 2),或等待 EVO Cloud 的通知 webhook。

  2. cancel.merchantTransInfo:本次 cancel 的引用对象,由您的服务器生成,必填。从您的请求中原样回显。

  3. cancel.evoTransInfo:本次 cancel 的引用对象,由 EVO Cloud 生成,必填。包含 evoTransIDevoTransTime

  4. cancel.pspTransInfo:本次 cancel 的引用对象,由 PSP 生成,可选。包含 pspTransIDpspTransTime。如果 PSP 返回,EVO Cloud 会将该信息从 PSP 转发至您的服务器。

以下为成功响应示例:

js
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": "Cancelling",  
16.        "merchantTransInfo": {  
17.            "merchantTransID": "37693fac0946498f8afe35b9ffdcfe89",  
18.            "merchantTransTime": "2021-12-31T08:30:59+08:00"  
19.        },  
20.        "evoTransInfo": {  
21.            "evoTransID": "ecf19b3be090407b97d74884077f08a4",  
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.    "cancel": {  
35.        "status": "Received",  
36.        "merchantTransInfo": {  
37.            "merchantTransID": "YOUR_TRANS_ID_OF_INITIAL_CANCEL",  
38.            "merchantTransTime": "2021-12-31T08:35:59+08:00"  
39.        },  
40.        "evoTransInfo": {  
41.            "evoTransID": "a36a6c5c6b224eaf923ca2c93ff3e63a",  
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"  
53.}

Step 2: Retrieve the cancel result

如果收到 cancel.statusReceived,且您未使用 notification webhook,可以从 EVO Cloud 查询最终结果。

从您的服务器向 EVO Cloud 端点

/g2/v1/payment/mer/{sid}/cancel

发起 HTTP GET 请求,并指定以下参数。

参数必填说明
merchantTransIDM初始 cancel 的 merchantTransInfo.merchantTransID

以下为查询 cancel 结果示例:

js
1.curl https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/cancel?merchantTransID={YOUR_TRANS_ID_OF_INITIAL_CANCEL} \  
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 响应类似。

js
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": "Cancelled",  
16.        "merchantTransInfo": {  
17.            "merchantTransID": "37693fac0946498f8afe35b9ffdcfe89",  
18.            "merchantTransTime": "2021-12-31T08:30:59+08:00"  
19.        },  
20.        "evoTransInfo": {  
21.            "evoTransID": "ecf19b3be090407b97d74884077f08a4",  
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.    "cancel": {  
35.        "status": "Success",  
36.        "merchantTransInfo": {  
37.            "merchantTransID": "YOUR_TRANS_ID_OF_INITIAL_CANCEL",  
38.            "merchantTransTime": "2021-12-31T08:35:59+08:00"  
39.        },  
40.        "evoTransInfo": {  
41.            "evoTransID": "a36a6c5c6b224eaf923ca2c93ff3e63a",  
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 refund instead

如果您发起 cancel 请求并收到 result.codeB0012,请再次核对响应中 payment.status 显示的原始交易状态。如果为 Captured,则表示该笔支付已被 Capture,您无法 cancel 该笔支付。这种情况下,您需要改用 refund。详见 Refund 章节。

Error handling

For HTTP POST request to EVO Cloud: 建议在请求发送后至少等待 45 秒。如果在规定时间内未收到响应,需要从 EVO Cloud 查询结果。请参阅 Step 2 发起请求。

For HTTP GET request to EVO Cloud: 可以多次发起请求直到获取结果,建议相邻两次请求之间至少等待 45 秒。如果多次请求后仍无法获取结果,可以改为发起一次新的 cancel 请求。