Google Pay PAN_ONLY 检查与自定义 CVV 收集
概述
本文档介绍如何使用 PAN_ONLY 检查接口判断是否需要 CVV,并通过 cardInfo.cvv 字段自行传递 CVV,避免使用 Onerway 的重定向页面。
与标准集成的主要区别:
| 特性 | 标准集成(Onerway 重定向) | 自定义方案(自行收集 CVV) |
|---|---|---|
| CVV 收集方式 | Onerway 提供的重定向页面 | 商户自行设计 UI |
| 用户体验 | 需要页面跳转 | 无需跳转,更流畅 |
| 实现复杂度 | 简单 | 较复杂 |
| 技术要求 | 基础 | 较高 |
| CVV 安全处理 | Onerway 负责 | 商户负责(不存储、不记录日志) |
完整的 Google Pay 标准集成流程请参考:Google Pay 集成
集成前置条件
在实施自定义 CVV 收集方案之前,请确保您具备:
- 有效的 Google Pay 商户账户,且已启用令牌处理
- 已在您的网站或应用上实现 Google Pay 基础集成
- 可访问 Onerway 支付网关 API
- 具备设计和实现自定义 CVV 输入界面的技术能力
- 了解并能遵守 CVV 安全处理规范
CVV 安全处理要求
虽然不需要 PCI DSS 认证,但您必须遵守以下 CVV 安全处理规范:
- 禁止存储:CVV 仅在内存中处理,禁止存储到数据库或文件
- 禁止记录:禁止将 CVV 记录到日志文件
- HTTPS 传输:所有包含 CVV 的请求必须使用 HTTPS 加密传输
- 及时清除:支付完成后立即从内存中清除 CVV
接口请求参数
注意
- 所有
JSON字段必须在提交前进行字符串化处理 - 嵌套对象必须序列化为
JSON字符串格式 JSON字段不能包含未转义的特殊字符JSON中的数组应该正确格式化JSON字符串字段示例:
{
"object": "{\"obj-key1\":\"v1\",\"obj-key2\":\"v2\"}",
"complex": "{\"k1\":\"v1\",\"array\":\"[{\\\"obj-key3\\\":\\\"v3\\\",\\\"obj-key4\\\":\\\"v4\\\"}]\"}"
}2
3
4
| Parameter | Type | Length | Required | Signed | Description |
|---|---|---|---|---|---|
appId | String | 20 | Yes | Yes | Merchant application ID assigned by Onerway for website identification. |
gatewayName | String | 64 | Yes | Yes | Payment gateway identifier for Google Pay token processing. |
merchantNo | String | 20 | Yes | Yes | Merchant number assigned by |
merchantTxnId | String | 64 | Yes | Yes | Unique transaction identifier for each customer payment, generated by the merchant system. |
sign | String | / | Yes | No | Digital signature string for request verification and security. Please refer to Signature for signature generation method. |
tokenInfoJson | String | / | Yes | Yes | Serialized tokenInfo structure as JSON string for checking Google Pay PAN_ONLY mode. See TokenInfofor structure details. |
响应
| Name | Type | Description |
|---|---|---|
respCode | String | Response code from |
respMsg | String | Response message from |
data | Object | Response data. Refer to object data |
data
| Name | Type | Description |
|---|---|---|
└cardNum | String | Masked card number extracted from Google Pay token. |
└checkResult | Boolean | PAN_ONLY mode check result. |
集成流程概览
关键步骤:
- 获取 Google Pay 令牌(标准流程,参考主集成文档)
- 调用 PAN_ONLY 检查接口判断是否需要 CVV
- 根据检查结果:
checkResult=false(PAN_ONLY): 收集 CVV,在cardInfo.cvv中传递checkResult=true(CRYPTOGRAM_3DS): 直接支付,无需 CVV
接口使用示例
{
"appId": "1727880846378401792",
"gatewayName": "ronghan",
"merchantNo": "800209",
"merchantTxnId": "07f6d404-0de4-45fb-b80d-df47815422b4",
"sign": "14d4b20492692820c39944ad6b63d871161da4b2c9ee15a106565c74fe85fbad",
"tokenInfoJson": "{\"provider\":\"GooglePay\",\"tokenId\":\"{\\\"signature\\\":\\\"MEYCIQCvwmUnXStC/Qhdv6XQxe5xu3yiOCXYMpEp9tzdeHcQmgIhAOHakh9S47uHSPoObcSjHhIlQncEv+1oRkVY9zoYrYP7\\\",\\\"intermediateSigningKey\\\":{\\\"signedKey\\\":\\\"{\\\\\\\"keyValue\\\\\\\":\\\\\\\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+F0IUGuqIge8NpRKXdhF+mHIu90N1X+uLJ0KuiYgqtMCNU/xQyn7FfeMUuIeLFFoFoRr/rvK/y3EtZUpTqjo5A\\\\\\\\u003d\\\\\\\\u003d\\\\\\\",\\\\\\\"keyExpiration\\\\\\\":\\\\\\\"1752655434646\\\\\\\"}\\\",\\\"signatures\\\":[\\\"MEQCID26+6e9vq0IHaWT3ORBCYJVR2Sr6eCpIO7V9fbKnXodAiBcu5gBmT/qwFjTsuRKmRPYYQfmhj4HV0auXrmHaPCPTw==\\\"]},\\\"protocolVersion\\\":\\\"ECv2\\\",\\\"signedMessage\\\":\\\"{\\\\\\\"encryptedMessage\\\\\\\":\\\\\\\"LFCsimI+8uLb6tX1mn0/c63DbvdPqOlLq8fJCJ8MnsTwvvQmaVWnLVFDikH5cePDCLz/D7Y8bUVW+Bfz38qB5WpcHtQrRoIQB1JEVoOL6tnFcrmQ87OeIfq9zgzWUp4TUF9NNJwYUit+2mrUeUR8elxq0ulavtiefhi7K0oIIFemBI2BfrlpIb/YjEsMbaAOLiYL+FvVyVxYiWeeGbsc5gAv0KJ9HrTKSIoMJ2fWoV/aMdX3iNnWTijr5x77JqHUdkMeo5xu/AUiODzqVAUl2UPCj/met2MFQpbvOea0102WdzrsviXisFniG5LQuxHyqXbYuoYRJhnpdk0F0XBL0tUAjiMd9rsULeCBc6JhxGgH+XnYorVVdXNKO08ZrFTQ+ZdaLEsiM+SatwGDa+Pt2+v5nbAq3SPwI0SgNmRdbkiOxdSKd//ZaooR0IQPQ21EJQAtdfr4KfMN0wmqA81VFrSuUySK8sVukyFde/OL9Fa/T0rLi7fqccF0d8Udl+C9Z3xReeMb03UuO+YcLT8g8QrdtDqungfCcP11hpmfx6M5/pebvZ1vYNFi\\\\\\\",\\\\\\\"ephemeralPublicKey\\\\\\\":\\\\\\\"BHcjhYHhu2QxoIGui2b451KY0ISiwi6u1y33bR0BHzqipB8XDx6YPAiRHYPI9umvwM+Pd9jGyNWBvOvI8xXiFaE\\\\\\\\u003d\\\\\\\",\\\\\\\"tag\\\\\\\":\\\\\\\"Ntfma/N099yxBNEd3lwB8aOjQws+K07IYa2Djfm5OeQ\\\\\\\\u003d\\\\\\\"}\\\"}\"}"
}2
3
4
5
6
7
8
9
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"cardNum": "411111******1111",
"checkResult": false
}
}2
3
4
5
6
7
8
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"cardNum": "411111******1111",
"checkResult": true
}
}2
3
4
5
6
7
8
传递 CVV 到支付接口
支付接口详细文档请参考:Google Pay 集成 - 后端支付处理
关键要点
当 checkResult 为 false 时,必须在支付请求的 cardInfo 字段中传递 CVV:
{
"merchantNo": "800209",
"merchantTxnId": "unique-transaction-id",
"orderAmount": "100.00",
"orderCurrency": "USD",
"productType": "CARD",
"subProductType": "DIRECT",
"tokenInfo": "{\"provider\":\"GooglePay\",\"tokenId\":\"...\"}",
"cardInfo": "{\"cvv\":\"123\"}", // PAN_ONLY 模式必须包含
"billingInformation": "...",
"txnOrderMsg": "...",
"sign": "..."
}2
3
4
5
6
7
8
9
10
11
12
13
当 checkResult 为 true 时,无需传递 cardInfo 字段:
{
"merchantNo": "800209",
"merchantTxnId": "unique-transaction-id",
"orderAmount": "100.00",
"orderCurrency": "USD",
"productType": "CARD",
"subProductType": "DIRECT",
"tokenInfo": "{\"provider\":\"GooglePay\",\"tokenId\":\"...\"}",
// 无 cardInfo 字段
"billingInformation": "...",
"txnOrderMsg": "...",
"sign": "..."
}2
3
4
5
6
7
8
9
10
11
12
13
CVV 安全要求
- CVV 仅在内存中处理,禁止存储到数据库
- 禁止记录 CVV 到日志文件
- 使用 HTTPS 加密传输
- 支付完成后立即清除
常见错误场景
无效令牌格式
错误:令牌解析失败
原因:tokenInfoJson 参数包含格式错误或无效的 Google Pay 令牌数据
解决方案:验证 Google Pay 令牌格式正确并包含所有必需字段
令牌过期
错误:令牌验证失败
原因:Google Pay 令牌已过期且不再有效
解决方案:从客户请求新的 Google Pay 令牌并重试检查
无效签名
错误:请求签名验证失败
原因:sign 参数不正确或使用错误参数生成
解决方案:验证您的签名生成过程并确保包含所有参数
商户配置错误
错误:商户未配置 Google Pay
原因:您的商户账户未正确配置 Google Pay 处理
解决方案:联系 Onerway 支持以验证您的 Google Pay 商户配置
实施最佳实践
CVV 安全处理
- CVV 仅在内存处理,禁止存储到数据库或文件
- 禁止将 CVV 记录到日志文件
- 所有 CVV 相关请求必须使用 HTTPS
- 支付完成后立即从内存中清除 CVV
API 调用
- 先调用 PAN_ONLY 检查接口,再决定是否收集 CVV
- 检查和支付使用同一个 Google Pay 令牌
- 设置合理的超时时间(建议 10-15 秒)
CVV 收集 UI
- 向用户清晰说明为何需要 CVV
- 实时验证 CVV 格式(3 位数字)
- 使用安全的输入方式(password 类型或遮罩显示)
错误处理
- 优雅处理 API 失败和网络错误
- 准备降级方案(可回退到标准重定向方式)
商户集成检查清单
前置条件
- 联系 Onerway 启用 PAN_ONLY 检查功能
- 了解 CVV 安全处理规范
API 集成
- 成功调用 PAN_ONLY 检查接口
- 正确解析
checkResult字段 - 支付接口中正确传递
cardInfo.cvv(当需要时)
CVV 处理
- 实现 CVV 输入界面
- 根据
checkResult条件性收集 CVV - CVV 不存储到数据库
- CVV 不记录到日志文件
安全要求
- 所有 CVV 相关请求使用 HTTPS
- 支付完成后清除内存中的 CVV
测试
- 测试 PAN_ONLY 场景(需要 CVV)
- 测试 CRYPTOGRAM_3DS 场景(无需 CVV)
- 测试错误处理流程