跳转到主要内容

3D Secure 验证

Quick Reference

What授权前的持卡人认证
Why责任转移至发卡行(issuer),通过 challenge 或无摩擦(frictionless)流程防范欺诈
Reading Time15 分钟
Difficulty中级
Prerequisites主机到主机或 SDK → 身份验证

3DS 在 A55 中的工作方式

在收费上设置 threeds_authentication: true,并提供完整的 device_info 对象。A55 处理 3DS 协议、路由至发卡行并返回结果。

SDK 与 API

JavaScript SDK 通过 A55Pay.authentication() 自动运行设备数据采集(DDC,Device Data Collection)。服务端集成 H2H(主机到主机直连)在收费 JSON 中发送 device_info 字段。


无摩擦(frictionless)与 challenge

方面无摩擦(Frictionless)Challenge
决策发卡行根据风险分静默批准发卡行要求持卡人交互
对体验的影响零(买家无感)跳转至 url_3ds 或 iframe 弹窗
何时发生低风险且设备数据丰富高风险或发卡行策略
转化最高较低(增加摩擦)
责任转移
典型占比3DS 交易的 70–85%15–30%

ECI 值


分步集成

1

从浏览器采集 device_info

在客户端采集真实浏览器值。每个字段都有助于发卡行的风险模型。

const deviceInfo = {
ip_address: await fetch('/api/ip').then(r => r.text()),
user_agent: navigator.userAgent,
http_accept_content: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
http_accept_browser_value: '*/*',
http_browser_language: navigator.language,
http_browser_java_enabled: navigator.javaEnabled?.() ?? false,
http_browser_javascript_enabled: true,
http_browser_color_depth: String(screen.colorDepth),
http_browser_screen_height: String(screen.height),
http_browser_screen_width: String(screen.width),
http_browser_time_difference: String(new Date().getTimezoneOffset()),
};
// 将 deviceInfo 发送至后端用于收费请求
2

创建收费并设置 threeds_authentication: true

curl -sS -X POST "https://core-manager.a55.tech/api/v1/bank/wallet/charge/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"wallet_uuid": "00000000-0000-4000-8000-000000000001",
"type_charge": "credit_card",
"card_name": "张伟",
"card_number": "4111111111111111",
"card_expiry_month": 12,
"card_expiry_year": 2030,
"card_cvv": "123",
"amount": 10000,
"currency": "BRL",
"installment_count": 1,
"threeds_authentication": true,
"device_info": {
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 ...",
"http_accept_content": "text/html",
"http_accept_browser_value": "*/*",
"http_browser_language": "pt-BR",
"http_browser_java_enabled": false,
"http_browser_javascript_enabled": true,
"http_browser_color_depth": "24",
"http_browser_screen_height": "900",
"http_browser_screen_width": "1440",
"http_browser_time_difference": "180"
},
"webhook_url": "https://merchant.example/webhooks/a55",
"redirect_url": "https://merchant.example/return"
}'
3

处理响应

{
"uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "confirmed",
"eci": "05",
"authentication_status": "success",
"reference_external_id": "ord_001"
}

无需跳转——收费已静默完成认证。

4

处理 3DS challenge(若为 `pending`)

若响应包含 url_3ds,请重定向买家。challenge 完成后,监听 postMessage

window.addEventListener('message', function (event) {
if (event.data?.event === '3ds-auth-complete') {
const chargeUuid = event.data.chargeUuid;
// 从后端查询收费状态并更新 UI
}
});
challenge 在内部如何运作
  1. 您的页面重定向(或 iframe)至 confirmacion.a55.tech/charge/{uuid}
  2. 3DS 页面在嵌套 iframe 中加载发卡行的 ACS(Access Control Server,访问控制服务器)
  3. 持卡人完成验证(OTP、生物识别等)
  4. ACS 重定向至 confirmacion.a55.tech/validate/{uuid}
  5. A55 验证认证结果,并沿窗口链向上发送带有 3ds-auth-completepostMessage
5

通过 webhook 确认

请始终将 Webhook(网络钩子)作为事实来源(source of truth)。在收费上配置 webhook_url,以便在买家关闭浏览器时仍能收到异步更新。

{
"charge_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "paid",
"transaction_reference": "txn_ref_001"
}

端到端流程


device_info 字段

字段类型必填说明
ip_addressstring客户端公网 IP
user_agentstring浏览器 user agent 字符串
http_accept_contentstringHTTP Accept 头
http_accept_browser_valuestring浏览器 Accept 值
http_browser_languagestring浏览器语言(例如 pt-BR
http_browser_java_enabledboolean是否启用 Java 插件
http_browser_javascript_enabledboolean是否启用 JavaScript
http_browser_color_depthstring屏幕色深
http_browser_screen_heightstring屏幕高度(像素)
http_browser_screen_widthstring屏幕宽度(像素)
http_browser_time_differencestring相对 UTC 的偏移(分钟)
device_idstring稳定设备标识
session_idstring结账会话 ID
数据质量

不完整或合成的 device_info提高 challenge 率与拒绝率。请在客户端采集真实浏览器值并传给服务器,切勿硬编码这些值。


SDK DDC(A55Pay.authentication

使用 JavaScript SDK 时,可单独运行 DDC:

A55Pay.authentication({
transactionReference: 'charge-uuid-or-ref',
cardBrand: 'visa',
cardNumber: '4111111111111111',
cardExpiryMonth: '12',
cardExpiryYear: '2030',
onSuccess: (payload) => {
// payload 包含 sessionId、accessToken、referenceId
// 将 sessionId 用于收费请求
},
onError: (err) => {
// DDC 失败——继续(不使用会话)或处理错误
},
});

说明: payV2() 会在处理前自动运行 DDC。仅当您手动管理流程时才需要调用 authentication()


验证端点

POST /api/v1/bank/public/charge/authentication/{uuid}/validate

请使用 3DS 流程中的收费 uuid。A55 会验证认证元数据并返回最终结果。


使用沙箱测试卡

Card NumberBrandScenarioExpected Status
4111 1111 1111 1111Visa3DS 无摩擦——通过confirmed
4000 0000 0000 0101Visa3DS 需要 challengeconfirmed
4000 0000 0000 0002Visa3DS——发卡行拒绝declined
5500 0000 0000 0004Mastercard3DS 无摩擦——通过confirmed
4000 0000 0000 0069Visa3DS——处理错误error

希望在无 challenge 的情况下提高通过率?

Visa Data Only 通过 3DS 通道向发卡行共享增强的交易数据——无需任何 challenge 跳转。在 Square 试点中,商户在 9 个月内、约 600 万笔交易上最高获得 +646 个基点 的提升。

无摩擦。无购物车放弃。A55 现支持通过单一标志启用:data_only: true

代价是:无责任转移(欺诈由商户承担)。在拉美高流量、低风险的场景下,这一取舍往往能带来数倍回报。

了解如何启用 Data Only →