3D Secure
概述
符合 3D Secure 2 条件的交易,会根据发卡行的要求走无感认证流程或挑战认证流程。
A. 3D Secure 2 无感认证流程(Frictionless)
在无感认证流程中,收单机构、发卡行和卡组织在后台交换所需信息,通过用户的设备指纹完成被动认证。整个交易无需用户进一步操作。
B. 3D Secure 2 挑战认证流程(Challenge)
在挑战认证流程中,发卡行要求用户进一步操作,例如生物识别、双因素认证、输入手机收到的一次性验证码,或输入密码。
C. EVO Payment 实现方式
在 EVO Payment 中,每个商户会在门店层级配置以下选项之一:
无需认证(Non-Authentication):
- 门店未开通认证,所有支付都不会进入认证流程。
- 在此选项下,无法启用令牌化功能。
强制认证(Require-Authentication):
- 门店的每笔卡支付都必须进行认证。
- 你必须在首次支付请求中提交认证相关字段。
- 在此选项下,配置好令牌化所需参数后,即可启用令牌化功能。
- 认证完成后,应答报文中会返回认证结果参数
threeDS.mpiData或securePlus.securePlusData。
可选认证(Optional-Authentication):
- 发起支付请求时,由你通过
allowAuthentication字段决定支付前是否进行认证。 - 如果
allowAuthentication设为 true,你必须在首次支付请求中提交认证相关字段。 - 在此选项下,配置好令牌化所需参数后,即可启用令牌化功能。
- 认证完成后,应答报文中会返回认证结果参数
threeDS.mpiData或securePlus.securePlusData。
- 发起支付请求时,由你通过
EVO Payment 3D Secure 支持方案
EVO Payment 提供以下 2 种方案,支持两个 3D Secure 版本:
3D Secure 2 重定向方案:
- 支持 3D Secure 最快的接入方式:将用户重定向到另一个站点完成支付验证。
- 该模式名为 threeDSPage,是接入 3D Secure 时 EVO Payment 的默认设置;如需使用另一种方案,请将
authentication.type设为threeDSIntegrator。
3D Secure 2 原生方案:
- 在你的网站或移动 App 内完成 3D Secure 2 认证,提供更好的用户体验。
3D Secure 2 重定向方案
EVO Payment 通过重定向实现 3D Secure 2。EVO Payment 会检查发卡行支持的版本,并提供一个重定向 URL,用户在该页面完成 3D Secure 2 认证。
这是支持 3D Secure 最简单的方式,大部分后台处理步骤都由 EVO Payment 提供的重定向 URL 完成。
上图描述了你需要实现的服务端集成和客户端实现。
步骤 1:采集附加参数
除了支付 / 令牌化中采集的基础参数外,你还需要向用户采集额外信息以进行 3D Secure 认证。附加参数列表可以从 /g2/v1/payment/mer/{sid}/paymentMethod 的 HTTP GET 应答中返回的 authenticationInfo 数组获取。详见“支付”章节的步骤 2。
万事达要求发起 3DS 认证时请尽量完整准确上送持卡人数据。持卡人标识、地址/收货、技术三类各至少提供一个完整且准确字段(当地法规禁止除外);上送 email 可同时满足“持卡人标识”与“地址/收货”两类。
步骤 2:发起支付或令牌化
采集到附加参数后,从你的服务端向 EVO Payment 发起 HTTP POST 请求:
支付请求地址:
/g2/v1/payment/mer/{sid}/payment
令牌化请求地址:
/g2/v1/payment/mer/{sid}/paymentMethod
threeDSPage 模式下,进行 3D Secure 认证需要在请求中额外携带以下参数(M = 必填,O = 可选):
| Body 参数 | 是否必填 | 说明 |
|---|---|---|
authentication | O | 支付或令牌化前用于用户认证的信息。 |
transInitiator | M | 支付或令牌化前用于用户认证的信息。 |
transInitiator.browserInfo | O | 用于 3DS 认证的用户浏览器信息,会发送给认证服务提供方。 |
userInfo | O | 支付或令牌化前用于用户认证的信息。 |
returnURL | M | 用户完成认证后重定向回的 URL。 |
authenticationOnly | O | 在 POST /g2/v1/payment/mer/{sid}/payment 请求中,表示是否为仅认证的支付请求。详见“仅认证”章节。 |
allowAuthentication | O | 门店配置为可选认证时适用。在 POST /g2/v1/payment/mer/{sid}/payment 或 POST /g2/v1/payment/mer/{sid}/paymentMethod 请求中,表示该笔支付是否需要进行认证。注意:authenticationOnly 为 true 时该字段不适用。 |
authentication 对象详细说明:
authentication.type:该笔支付使用的认证模式,可选。可设为threeDSPage(也是默认值),告知 EVO Payment 你要使用 3D Secure 2 重定向方案。authentication.threeDS.merchantRiskIndicator:包含 3D Secure 2 附加风险字段的对象,可选。详见 EVO Payment API 规范。
transInitiator 对象详细说明:
transInitiator.userCreateIP:发起支付的设备 IP 地址,可选。transInitiator.browserInfo.acceptHeader:用户浏览器的 accept header 值,必填。transInitiator.browserInfo.colorDepth:用户浏览器的颜色深度(单位:位/像素),必填。通过浏览器的screen.colorDepth属性获取。可接受的值:1、4、8、15、16、24、32 或 48 位。transInitiator.browserInfo.javaEnabled:布尔值,表示用户浏览器是否能执行 Java,必填。transInitiator.browserInfo.language:按 IETF BCP47 定义的浏览器语言,必填。通过浏览器的navigator.language属性获取。例如 NL、FR、US。transInitiator.browserInfo.screenHeight:用户屏幕总高度(单位:像素),必填。通过浏览器的screen.height属性获取。transInitiator.browserInfo.screenWidth:用户屏幕总宽度(单位:像素),必填。通过浏览器的screen.width属性获取。transInitiator.browserInfo.timeZoneOffset:UTC 时间与用户浏览器本地时间的差值(单位:分钟),必填。通过浏览器的getTimezoneOffset()方法获取。transInitiator.browserInfo.userAgent:用户浏览器的 user agent 值,必填。
userInfo 对象详细说明:
userInfo.billingAddress:包含用户账单地址的对象,可选。详见 EVO Payment API 规范。userInfo.deliveryAddress:包含商品收货地址的对象,可选。详见 EVO Payment API 规范。userInfo.accountInfo:包含 3D Secure 2 所需用户账户信息的对象,可选。详见 EVO Payment API 规范。userInfo.email:用户邮箱地址,可选。
以下示例为一笔需要 3D Secure 认证的 10 USD 信用卡支付:
curl -X POST https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/payment \
-H "Content-Type: application/json" \
-H "DateTime: 2021-12-31T08:30:59+0800" \
-H "MsgID: 2d21a5715c034efb7e0aa383b885fc7a" \
-H "SignType: SHA256" \
-H "Authorization: YOUR_MESSAGE_SIGNATURE" \
-d '{
"merchantTransInfo": {
"merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
"merchantTransTime": "2021-12-31T08:30:59+08:00"
},
"transAmount": {
"currency": "USD",
"value": "10.00"
},
"allowAuthentication": true,
"returnURL": "https://YOUR_COMPANY.com/RETURNURL",
"paymentMethod": {
"type": "card",
"card": {
"cardInfo": {
"cardNumber": "4761340000000019",
"expiryDate": "2212",
"cvc": "946"
}
}
},
"transInitiator": {
"browserInfo": {
"acceptHeader": "application/json, text/plain, */*",
"colorDepth": "1",
"javaEnabled": true,
"language": "US",
"screenHeight": "300",
"screenWidth": "200",
"timeZoneOffset": "480",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36"
}
},
"webhook": "https://YOUR_COMPANY.com/WEBHOOK",
"metadata": "This is a metadata"
}'如果应答中没有 action 对象,使用 result.code 和 payment.status / paymentMethod.token.status 向用户展示支付 / 令牌化结果。
否则,说明还需要额外步骤才能完成支付 / 令牌化。你需要把 action 对象发给 Web 前端或客户端 App,然后进入下一步。
以下为需要重定向的支付应答示例:
{
"result": {
"code": "S0000",
"message": "Success"
},
"action": {
"type": "threeDSRedirect",
"threeDSData": {
"url": "https://YOUR_REDIRECT_URL",
"method": "GET"
}
},
"paymentMethod": {
"card": {
"first6No": "476134",
"last4No": "0019",
"paymentBrand": "Visa",
"fundingType": "credit"
}
},
"payment": {
"status": "Verifying",
"merchantTransInfo": {
"merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
"merchantTransTime": "2021-12-31T08:30:59+08:00"
},
"evoTransInfo": {
"evoTransID": "8a0d5cd24b5b4156b94010cee115bceb",
"evoTransTime": "2021-12-31T00:30:59Z"
},
"pspTransInfo": {
"pspTransTime": "2021-12-31T08:30:59+08:00",
"authorizationCode": "091410"
},
"transAmount": {
"currency": "USD",
"value": "10.00"
}
},
"pspData": {
"name": "Visa"
},
"metadata": "This is a metadata"
}步骤 3:处理 threeDSRedirect
在 3D Secure 2 重定向方案下(authentication.type 为 threeDSPage),应答中收到的 action.type 通常是 threeDSRedirect,表示你需要使用同一应答中的 action.threeDSData,将用户重定向到 EVO Payment 托管页面完成 3DS 2 认证。
A. 将用户重定向到 EVO Payment 托管页面
使用 action.threeDSData.method 指定的 HTTP 方法,将用户重定向到 action.threeDSData.url。
以下为 action.threeDSData.method 为 GET 时,在前端执行 threeDSRedirect 操作的示例:
:::tip[提示]
用户随后会被重定向到 EVO Payment 托管页面,EVO Payment 会与用户及发卡行 ACS 完成后续的 3D Secure 认证流程。
:::
B. 用户完成认证后重定向回商户
EVO Payment 会在 10 分钟内通过 HTTP GET 请求将用户重定向回你的 returnURL。你可以用应答中的 merchantTransID 参数匹配首次请求。
- 如果应答中的
status参数为finished,表示 3D Secure 认证成功。你需要调用 GET 接口或接收 EVO Payment 的通知来获取交易详情。 - 如果 10 分钟内没有收到任何应答,或
status参数不是finished,表示 3D Secure 认证失败。此时同样应调用 GET 接口或接收 EVO Payment 的通知来获取交易详情。
步骤 4:展示结果
用户完成支付或令牌化、前端或客户端 App 无需进一步操作后,你可以接收通知或发起 GET 请求获取详情。使用 result.code 和 payment.status / paymentMethod.status 告知用户支付或令牌化的状态。
| 结果码 | 说明 |
|---|---|
S0000 | Success |
其他可能的 result.code 值及建议向用户展示的提示信息,见 EVO Payment API 规范附录。
| 状态 | 说明 |
|---|---|
| Authorised | 用于卡交易,表示交易授权已成功,等待完成(商户可发起撤销)。 |
| Captured | 卡交易表示授权和完成均已成功;电子钱包交易表示交易已成功。 |
| Failed | 支付失败 |
| 状态 | 说明 |
|---|---|
| Success | 令牌已创建 |
| Failed | 令牌创建失败 |
其他可能的 payment.status / paymentMethod.status 值及说明,见 EVO Payment API 规范中的 payment.status / paymentMethod.status。
异常处理
- 向 EVO Payment 发起的 HTTP POST 请求:建议请求发出后至少等待 45 秒。如果在该时间内没有收到应答,需要向 EVO Payment 查询结果。发起查询请参考“支付 / 令牌化”章节的步骤 6。
- 向 EVO Payment 发起的 HTTP PUT 请求:HTTP PUT 请求是幂等的。如果在一定时间内(例如 45 秒)没有收到 EVO Payment 的应答,可以用完全相同的请求报文重新发送。多次重发仍未收到应答时,可以改为发起一笔新的支付 / 令牌化请求。
3D Secure 2 原生方案
EVO Payment 可以通过原生方式实现 3D Secure 2,提供更好的用户体验。
步骤 1:采集附加参数
此步骤与“3D Secure 2 重定向方案”的步骤 1 相同,详见该章节。
万事达要求发起 3DS 认证时请尽量完整准确上送持卡人数据。持卡人标识、地址/收货、技术三类各至少提供一个完整且准确字段(当地法规禁止除外);上送 email 可同时满足“持卡人标识”与“地址/收货”两类。
步骤 2:发起支付或令牌化
此步骤与“3D Secure 2 重定向方案”的步骤 2 相同,详见该章节。区别仅在于:
- POST 请求中需将
authentication.type设为threeDSIntegrator,而不是threeDSPage。 - POST 请求中需传入
transInitiator.browserInfo。 - 建议在
returnURL中带上你的merchantTransInfo.merchantTransID,便于后续步骤处理应答。例如:R_COMPANY.com/RETURNURL/YOUR_MERCHANT_TRANS_ID。 - 除了
action.type为threeDSRedirect外,EVO Payment 的应答中还可能返回threeDSIdentify或threeDSChallenge。
步骤 3-1:处理 threeDSIdentify
如果服务端收到 action.type 为 threeDSIdentify,你需要执行 3D Secure 2 设备指纹采集。
A. 创建 iframe 并向发卡行发起设备指纹请求
在浏览器中渲染一个隐藏的 HTML iframe,并在 iframe 中使用 action.threeDSData.method 指定的 HTTP 方法向 action.threeDSData.url 发起 HTTP 请求。
如果 action.threeDSData.method 为 GET:
curl {action.threeDSData.url}如果 action.threeDSData.method 为 POST 且存在 action.threeDSData.parameter,则 action.threeDSData.parameter 中应包含 base64 编码的 threeDSMethodData:
{
"threeDSMethodData": "eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly9ZT1VSX0NPTVBBTlkuY29tL1JFVFVSTlVSTCIsInRocmVlRFNTZXJ2ZXJUcmFuc0lEIjoiN2MzOWJkOTYtOThlZS00N2IwLTgzYWYtNjMwNjE2NmE3MDE4In0="
}此时需要在前端通过表单 POST 执行 threeDSIdentify 操作:
<form method="POST" action="{action.threeDSData.url}" id="threeDSIdentify" target="NAME_OF_YOUR_IFRAME">
<input type="hidden" name="threeDSMethodData" value="eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly9ZT1VSX0NPTVBBTlkuY29tL1JFVFVSTlVSTCIsInRocmVlRFNTZXJ2ZXJUcmFuc0lEIjoiN2MzOWJkOTYtOThlZS00N2IwLTgzYWYtNjMwNjE2NmE3MDE4In0=" />
</form>POST 请求中 key 的大小写必须与 EVO Payment 应答中 action.threeDSData.parameter 返回的参数名保持一致。
提示:
- 如果之前的 POST 请求中
returnURL没有带merchantTransID,你需要对 base64 编码的threeDSMethodData进行解码。 - 从解码后的数据中获取并保存
threeDSServerTransID,用于下一步处理应答。
B. 在 Return URL 等待设备指纹结果
从发起请求开始,在 returnURL 上等待发卡行推送的应答,等待时长 10 秒。使用 returnURL 中的 merchantTransID 匹配首次请求:
- 将
threeDSCompInd标记为 Y。 - 保存应答中的
threeDSMethodData参数,进入下一步。
如果 returnURL 中没有带 merchantTransID,你需要:
- 使用 base64 方法解码应答中的
threeDSMethodData参数。 - 获取
threeDSServerTransID以匹配首次请求。
如果 10 秒内没有收到任何应答,或应答中取不到 threeDSMethodData 参数,可将 threeDSCompInd 标记为 N,进入下一步。
C. 提交设备指纹结果
从服务端向 EVO Payment 发起 HTTP PUT 请求:
- 支付:
/g2/v1/payment/mer/{sid}/payment - 令牌化:
/g2/v1/payment/mer/{sid}/paymentMethod
需传入以下参数:
| Query 参数 | 是否必填 | 说明 |
|---|---|---|
merchantTransID | M | 首次支付 / 令牌化请求中的 merchantTransInfo.merchantTransID。 |
| Body 参数 | 是否必填 | 说明 |
|---|---|---|
authentication.threeDS.redirectData.threeDSCompInd | M | 设备指纹采集结果。 |
示例:
curl -X PUT https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/payment?merchantTransID={YOUR_TRANS_ID_OF_INITIAL_REQUEST} \
-H "Content-Type: application/json" \
-H "DateTime: 2021-12-31T08:30:59+0800" \
-H "MsgID: 2d21a5715c034efb7e0aa383b885fc7a" \
-H "SignType: SHA256" \
-H "Authorization: YOUR_MESSAGE_SIGNATURE" \
-d '{
"authentication": {
"threeDS": {
"redirectData": {
"threeDSCompInd": "Y"
}
}
},
"metadata": "This is a metadata"
}'如果应答中不含 action 对象,可使用 result.code 和 payment.status / paymentMethod.token.status 向用户展示支付 / 令牌化结果。
如果应答中包含 action 对象,说明还需要额外步骤才能完成支付 / 令牌化。你需要把 action 对象发给 Web 前端或客户端 App,然后进入下一步。
以下为需要用户进行挑战认证的应答示例:
{
"result": {
"code": "S0000",
"message": "Success"
},
"action": {
"type": "threeDSChallenge",
"threeDSData": {
"url": "https://YOUR_REDIRECT_URL",
"method": "GET",
"parameter": {
"creq": "eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI3YzM5YmQ5Ni05OGVlLTQ3YjAtODNhZi02MzA2MTY2YTcwMTgiLCJhY3nUcmFuc0lEIjoiMTE4ZDNiNjEtYjU5Ny00Nzg2LTg1ZWMtNzA0Mzc3ZDhjMWU4IiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0="
}
}
},
"paymentMethod": {
"card": {
"first6No": "476134",
"last4No": "0019",
"paymentBrand": "Visa",
"fundingType": "credit"
}
},
"authentication": {
"type": "threeDSIntegrator"
},
"payment": {
"status": "Verifying",
"merchantTransInfo": {
"merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
"merchantTransTime": "2021-12-31T08:30:59+08:00"
},
"evoTransInfo": {
"evoTransID": "8a0d5cd24b5b4156b94010cee115bceb",
"evoTransTime": "2021-12-31T00:30:59Z"
},
"pspTransInfo": {
"pspTransTime": "2021-12-31T08:30:59+08:00",
"authorizationCode": "091410"
},
"transAmount": {
"currency": "USD",
"value": "10.00"
}
},
"pspData": {
"name": "Visa"
},
"metadata": "This is a metadata"
}步骤 3-2:处理 threeDSChallenge
如果服务端收到 action.type 为 threeDSChallenge,表示发卡行要进行额外校验,确认该用户确实是持卡人本人。
A. 创建 iframe 并向发卡行发送 cReq(挑战请求)
在浏览器中渲染一个 HTML iframe,并在 iframe 中使用 action.threeDSData.method 指定的 HTTP 方法向 action.threeDSData.url 发起 HTTP 请求。
如果 action.threeDSData.method 为 POST 且存在 action.threeDSData.parameter,将 parameter 对象中的子字段作为 POST 请求的表单数据传入。iframe 中会随之打开挑战窗口。
在前端执行 threeDSChallenge 操作的示例(GET 方法):
curl {action.threeDSData.url}如果 action.threeDSData.method 为 POST 且存在 action.threeDSData.parameter,则 action.threeDSData.parameter 中应包含 base64 编码的 creq:
{
"creq": "eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI3YzM5YmQ5Ni05OGVlLTQ3YjAtODNhZi02MzA2MTY2YTcwMTgiLCJhY3nUcmFuc0lEIjoiMTE4ZDNiNjEtYjU5Ny00Nzg2LTg1ZWMtNzA0Mzc3ZDhjMWU4IiwiY2hhbGVuZ2V3aW5kb3dTaXplIjoiMDIifQ=="
}此时需要在前端通过表单 POST 执行 threeDSData 操作:
<form method="POST" action="{action.threeDSData.url}" id="threeDSChallenge" target="NAME_OF_YOUR_IFRAME">
<input name="creq" value="eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI3YzM5YmQ5Ni05OGVlLTQ3YjAtODNhZi02MzA2MTY2YTcwMTgiLCJhY3nUcmFuc0lEIjoiMTE4ZDNiNjEtYjU5Ny00Nzg2LTg1ZWMtNzA0Mzc3ZDhjMWU4IiwiY2hhbGxlbmdlV2luZG93U2l6ZSI6IjAyIn0=" />
</form>POST 请求中 key 的大小写必须与 EVO Payment 应答中 action.threeDSData.parameter 返回的参数名保持一致。
:::tip[提示]
如果之前的 POST 请求中 returnURL 没有带 merchantTransID,你需要对 base64 编码的 creq 进行解码,从解码后的数据中获取并保存 threeDSServerTransID,用于下一步处理应答。
:::
B. 在 Return URL 等待 cRes(挑战应答)
从发送请求开始,在 returnURL 上等待发卡行推送的应答,等待时长 10 分钟。使用 returnURL 中的 merchantTransID 匹配首次请求:
- 将
threeDSFinished标记为 Y。 - 保存应答中的
cres参数,然后进入下一步。
提示:
- 如果
returnURL中没有带merchantTransID,你需要使用 base64 方法解码应答中的cres参数,并获取threeDSServerTransID以匹配首次请求。 - 如果 10 分钟内没有收到任何应答,或应答中取不到
cres参数,可将threeDSFinished标记为 N,进入下一步。
C. 提交挑战结果
从服务端向 EVO Payment 发起 HTTP PUT 请求:
- 支付:
/g2/v1/payment/mer/{sid}/payment - 令牌化:
/g2/v1/payment/mer/{sid}/paymentMethod
需传入以下参数:
| Query 参数 | 是否必填 | 说明 |
|---|---|---|
merchantTransID | M | 首次支付 / 令牌化请求中的 merchantTransInfo.merchantTransID。 |
| Body 参数 | 是否必填 | 说明 |
|---|---|---|
authentication.threeDS.redirectData.threeDSFinished | M | 挑战结果。 |
authentication.threeDS.redirectData.cres | O | 发卡行在推送到你 returnURL 的应答中返回的挑战应答,base64 编码。请不要解码,原样转发给 EVO Payment。 |
示例:
curl -X PUT https://{EVO_Cloud_DOMAIN_NAME.com}/g2/v1/payment/mer/{sid}/payment?merchantTransID={YOUR_TRANS_ID_OF_INITIAL_REQUEST} \
-H "Content-Type: application/json" \
-H "DateTime: 2021-12-31T08:30:59+0800" \
-H "MsgID: 2d21a5715c034efb7e0aa383b885fc7a" \
-H "SignType: SHA256" \
-H "Authorization: YOUR_MESSAGE_SIGNATURE" \
-d '{
"authentication": {
"threeDS": {
"redirectData": {
"cres":"eyJtZXNzYWdlVHlwZSI6IkNSZXMiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIiwidGhyZWVEU1NlcnZlclRyYW5zSUQiOiI3YzM5YmQ5Ni05OGVlLTQ3YjAtODNhZi02MzA2MTY2YTcwMTgiLCJhY3nUcmFuc0lEIjoiMTE4ZDNiNjEtYjU5Ny00Nzg2LTg1ZWMtNzA0Mzc3ZDhjMWU4IiwiY2hhbGxlbmdlQ29tcGxldGlvbkluZCI6IlkiLCJ0cmFuc1N0YXR1cyI6IlkifQ==",
"threeDSFinished": "Y"
}
}
},
"metadata": "This is a metadata"
}'INFO
如果支付或令牌化成功,你会收到 result.code 为 S0000,表示成功。
{
"result": {
"code": "S0000",
"message": "Success",
"pspResponseCode": "00",
"pspMessage": " Approval and completed successfully; Accepted and processed"
},
"paymentMethod": {
"card": {
"first6No": "476134",
"last4No": "0019",
"paymentBrand": "Visa",
"fundingType": "credit"
}
},
"authentication": {
"type": "threeDSIntegrator",
"threeDS": {
"mpiData": {
"status": "Y",
"eci": "05"
}
}
},
"payment": {
"status": "Authorised",
"merchantTransInfo": {
"merchantTransID": "f2d45e3397704f2a818b7b74bc94e7ce",
"merchantTransTime": "2021-12-31T08:30:59+08:00"
},
"evoTransInfo": {
"evoTransID": "8a0d5cd24b5b4156b94010cee115bceb",
"evoTransTime": "2021-12-31T00:30:59Z"
},
"pspTransInfo": {
"pspTransTime": "2021-12-31T08:30:59+08:00",
"authorizationCode": "091410"
},
"transAmount": {
"currency": "USD",
"value": "10.00"
}
},
"pspData": {
"name": "Visa"
},
"metadata": "This is a metadata"
}步骤 4:展示结果
用户完成支付或令牌化、前端或客户端 App 无需进一步操作后,使用 result.code 和 payment.status / paymentMethod.status 告知用户支付或令牌化的状态。
| 结果码 | 说明 |
|---|---|
S0000 | Success |
V0007 | Missing field {} when |
B0025 | Authentication not finished |
B0026 | 3DS version not supported |
其他可能的 result.code 值及建议向用户展示的提示信息,见 EVO Payment API 规范附录。
如果 result.code 为 S0000,还需要检查 payment.status / paymentMethod.status,确定支付或令牌化状态并告知用户。
| 状态 | 说明 |
|---|---|
| Authorised | 用于卡交易,表示交易授权已成功,等待完成(商户可发起撤销)。 |
| Captured | 卡交易表示授权和完成均已成功;电子钱包交易表示交易已成功。 |
| Failed | 支付失败。 |
| 状态 | 说明 |
|---|---|
| Success | 令牌已创建。 |
| Failed | 令牌创建失败。 |
其他可能的 payment.status / paymentMethod.status 值及说明,见 EVO Payment API 规范中的 payment.status / paymentMethod.status 部分。
异常处理
向 EVO Payment 发起的 HTTP POST 请求:建议请求发出后至少等待 45 秒。如果在该时间内没有收到应答,需要向 EVO Payment 查询结果。发起查询请参考“支付 / 令牌化”章节的步骤 6。
向 EVO Payment 发起的 HTTP PUT 请求:HTTP PUT 请求是幂等的。如果在一定时间内(例如 45 秒)没有收到 EVO Payment 的应答,可以用完全相同的请求报文重新发送。多次重发仍未收到应答时,可以改为发起一笔新的支付 / 令牌化请求。

