fengketrade/doc/ccblife_test_guide.md
2025-10-20 15:29:15 +08:00

18 KiB
Raw Blame History

建行生活H5商城对接 - 测试指南

文档版本: v1.0 更新时间: 2025-01-18 作者: Billy


📋 目录

  1. 测试概述
  2. 测试环境准备
  3. 自动化测试流程
  4. 手动测试流程
  5. 常见问题排查
  6. 测试检查清单

测试概述

本测试方案分为两个阶段:

🤖 阶段一:模拟测试(当前可用)

目的: 在没有建行加密数据的情况下,验证系统核心逻辑是否正确

范围:

  • 环境配置检查
  • 数据库表结构验证
  • 用户和订单创建
  • 支付串生成逻辑
  • 支付流水号规则
  • 订单状态更新逻辑
  • 字段映射正确性

不包含:

  • 真实RSA加密/解密
  • 真实建行API调用
  • 建行回调签名验证
  • JSBridge通信

🌐 阶段二:真实环境测试(需建行配置)

前提: 已获得建行提供的测试/生产环境配置

范围:

  • 完整RSA加密流程
  • 建行API接口调用
  • 订单同步到建行
  • 建行收银台支付
  • 支付回调验证
  • 异步通知验证

测试环境准备

1. 系统要求

# 检查PHP版本需要 >= 7.0
php -v

# 检查必需扩展
php -m | grep -E 'openssl|pdo|json|mbstring'

# 检查数据库连接
mysql -h <host> -u <user> -p<password> -e "SELECT VERSION();"

2. 配置文件检查

确保已创建配置文件:/application/extra/ccblife.php

<?php
return [
    // 基础配置
    'merchant_id' => '***',      // 商户代码
    'pos_id' => '***',           // 柜台代码
    'branch_id' => '***',        // 分行代码
    'service_id' => '***',       // 服务方编号

    // 密钥配置
    'private_key' => '***',      // 服务方私钥1024位
    'merchant_public_key' => '***',  // 商户公钥1024位

    // API地址测试环境
    'api_url' => 'http://test.ccb.com/api',
    'cashier_url' => 'comccbpay://pay',

    // 回调地址
    'callback_url' => 'https://your-domain.com/addons/shopro/ccbpayment/callback',
    'notify_url' => 'https://your-domain.com/addons/shopro/ccbpayment/notify',
];

3. 数据库表检查

确保已执行以下SQL如未执行

-- 订单表添加建行支付流水号字段
ALTER TABLE `fa_shopro_order`
ADD COLUMN `ccb_pay_flow_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '建行支付流水号'
AFTER `order_sn`;

-- 用户表添加建行用户ID字段
ALTER TABLE `fa_user`
ADD COLUMN `ccb_user_id` VARCHAR(50) NULL DEFAULT NULL COMMENT '建行用户ID'
AFTER `mobile`;

-- 支付日志表已在install.sql中
-- fa_ccb_payment_log

-- 同步日志表已在install.sql中
-- fa_ccb_sync_log

自动化测试流程

运行自动化测试脚本

cd /Users/billy/Code/fengketrade.com

# 运行完整测试套件
php addons/shopro/test/ccblife_test.php

预期输出示例

========================================
   建行生活H5商城对接 - 自动化测试
========================================
测试时间: 2025-01-18 14:30:00
========================================

【环境检查】
   ✓ PHP版本检查 (7.4.33 >= 7.0)
   ✓ 检查OpenSSL扩展
   ✓ 检查PDO扩展
   ✓ 检查JSON扩展
   ✓ 检查文件: CcbPaymentService.php
   ✓ 检查文件: CcbOrderService.php
   ✓ 检查文件: CcbRSA.php
   ✓ 检查文件: CcbMD5.php
   ✓ 检查文件: CcbEncryption.php

【配置文件检查】
   ✓ 配置文件存在
   ✓ 商户ID配置
   ✓ POS ID配置
   ✓ 分行代码配置
   ✓ 服务方编号配置
   ✓ 服务方私钥配置
   ✓ 商户公钥配置

【数据库表检查】
   ✓ 检查表: fa_ccb_payment_log
   ✓ 检查表: fa_ccb_sync_log
   ✓ 检查表: fa_shopro_order
   ✓ 检查表: fa_user
   ✓ 检查订单表ccb_pay_flow_id字段

【创建测试用户】
   ✓ 用户创建成功 (ID: 123)

【创建测试订单】
   ✓ 订单创建成功 (ID: 456, SN: SO20250118143000001)

【支付串生成测试】
   ✓ 支付串生成状态
   ✓ 支付串不为空
   ✓ 支付流水号不为空
   ✓ MAC签名不为空
   ✓ 支付流水号长度正确 (23位)
   ✓ 支付流水号前缀正确 (PAY)
   ✓ 订单表支付流水号已更新
   ✓ 支付日志已记录
   支付串长度: 512 字节
   支付流水号: PAY20250118143000123456
   MAC签名: a1b2c3d4e5f6...

【支付回调测试】
   ✓ 回调处理成功
   ✓ 回调消息正确
   ✓ 订单状态已更新为已支付
   ✓ 支付方式正确 (offline代表建行)
   ✓ 支付时间已记录
   ✓ 交易单号正确
   订单状态: paid
   支付时间: 2025-01-18 14:30:05

【异步通知测试】
   通知处理结果: fail
   ✓ 通知处理逻辑测试完成

【订单同步测试】
   ✓ 订单字段 ORD_NUM 存在
   ✓ 订单字段 PAY_AMT 存在
   ✓ 订单字段 ORD_TIME 存在
   ✓ 订单字段 PAY_TIME 存在
   ✓ 订单字段 ORD_STATUS 存在
   ✓ 订单字段 REFUND_STATUS 存在
   ✓ 订单号正确
   ✓ 支付金额正确
   订单号: SO20250118143000001
   支付金额: 100.00
   订单状态: 02

【清理测试数据】
   ✓ 删除测试订单 (ID: 456)
   ✓ 删除支付日志
   ✓ 删除测试用户 (ID: 123)

========================================
            测试报告
========================================
✓ 通过  环境检查
       所有环境检查通过
✓ 通过  配置文件检查
       所有配置项完整
✓ 通过  数据库表检查
       所有表结构完整
✓ 通过  创建测试用户
       用户ID: 123
✓ 通过  创建测试订单
       订单ID: 456
✓ 通过  支付串生成测试
       支付流水号: PAY20250118143000123456
✓ 通过  支付回调测试
       支付回调处理成功
✓ 通过  异步通知测试
       通知处理逻辑测试完成
✓ 通过  订单同步测试
       订单数据构建正确
✓ 通过  清理测试数据
       所有测试数据已清理

========================================
总计: 10 项测试
通过: 10 项
失败: 0 项
耗时: 1.23 秒
========================================

🎉 所有测试通过!系统运行正常。

手动测试流程

测试1: 前端环境检测

目的: 验证建行生活APP环境识别

步骤:

  1. 在建行生活APP内打开H5商城链接待建行提供测试链接
  2. 打开浏览器控制台
  3. 查看输出:
// 预期输出
[CcbLife] 初始化完成, 是否在建行App内: true
[CcbLife] JSBridge 已就绪

验证点:

  • isInCcbApp 应为 true
  • isReady 应为 true
  • User-Agent 包含 'ccblife' 或 'ccb'

测试2: 用户自动登录

目的: 验证建行用户自动登录流程

前提:

  • 测试1通过
  • 已在建行APP内打开H5商城

步骤:

  1. 清除商城登录态:localStorage.clear()
  2. 刷新页面
  3. 观察控制台输出

预期输出:

[CcbLife] 自动登录成功

验证点:

  • localStorage.getItem('token') 不为空
  • localStorage.getItem('userInfo') 包含用户信息
  • 数据库 fa_user 表中 ccb_user_id 已绑定

测试3: 创建订单

目的: 验证订单创建流程

步骤:

  1. 选择商品加入购物车
  2. 进入结算页
  3. 填写收货地址
  4. 提交订单

验证点:

  • 订单创建成功返回订单ID和订单号
  • 数据库 fa_shopro_order 表中订单状态为 unpaid
  • ccb_pay_flow_id 字段为空

测试4: 生成支付串

目的: 验证支付串生成逻辑

接口: POST /addons/shopro/ccbpayment/pay

请求参数:

{
  "order_id": 123
}

预期响应:

{
  "code": 1,
  "msg": "支付串生成成功",
  "data": {
    "payment_string": "MERCHANTID=...&POSID=...&MAC=...",
    "payment_url": "comccbpay://pay?MERCHANTID=...&MAC=...",
    "mac": "a1b2c3d4e5f6...",
    "order_id": 123,
    "order_sn": "SO20250118001",
    "pay_flow_id": "PAY20250118143000123456",
    "amount": "100.00"
  }
}

验证点:

  1. payment_string 包含所有必需参数
  2. pay_flow_id 格式正确PAY + 14位时间戳 + 6位随机数
  3. mac 签名不为空
  4. 数据库订单表 ccb_pay_flow_id 已更新
  5. fa_ccb_payment_log 表中已记录支付请求

关键参数检查:

// 从 payment_string 中提取参数
const params = new URLSearchParams(payment_string);

console.log('ORDERID:', params.get('ORDERID'));  // 应等于 pay_flow_id
console.log('USER_ORDERID:', params.get('USER_ORDERID'));  // 应等于 order_sn
console.log('PAYMENT:', params.get('PAYMENT'));  // 应等于订单实际支付金额
console.log('MAC:', params.get('MAC'));  // MD5签名
console.log('PLATFORMID:', params.get('PLATFORMID'));  // 服务方编号

测试5: 调起支付(需建行环境)

目的: 验证JSBridge调起建行收银台

前提:

  • 测试1-4全部通过
  • 已在建行APP内

步骤:

  1. 点击"去支付"按钮
  2. 前端调用 CcbLifePlatform.payment()

前端代码示例:

// sheep/platform/provider/ccblife/index.js

const paymentResult = await CcbLifePlatform.payment({
  payment_string: '支付串内容'
});

console.log('支付结果:', paymentResult);

iOS预期行为:

  • 跳转到 comccbpay://pay?支付参数
  • 打开建行收银台

Android预期行为:

  • 调用 window.mbspay.payment()
  • 打开建行收银台

验证点:

  • 收银台显示正确的订单金额
  • 收银台显示正确的商品信息

测试6: 支付回调(需建行环境)

目的: 验证支付完成后的同步回调

触发方式:

  • 在建行收银台完成支付(或取消支付)
  • 建行会重定向到 callback_url

回调URL示例:

https://your-domain.com/addons/shopro/ccbpayment/callback?ccbParamSJ=加密参数

预期流程:

  1. 解密 ccbParamSJ 参数
  2. 获取支付结果参数
  3. 根据 SUCCESS=Y/N 判断支付成功或失败
  4. 更新订单状态

支付成功验证点:

  • 订单状态 → paid
  • 支付时间 paid_time 已记录(毫秒时间戳)
  • 支付方式 pay_typeoffline
  • 交易单号 transaction_id → 支付流水号
  • 页面跳转到订单详情或支付成功页

支付失败验证点:

  • 订单状态保持 unpaid
  • 页面显示失败原因

测试7: 异步通知(需建行环境)

目的: 验证建行异步通知处理

触发方式:

  • 支付成功后建行会POST请求到 notify_url

接口: POST /addons/shopro/ccbpayment/notify

建行会发送的参数(示例):

POST数据:
ORDERID=PAY20250118143000123456
&USER_ORDERID=SO20250118001
&POSID=100001
&PAYMENT=100.00
&SUCCESS=Y
&SIGN=签名值

预期处理逻辑:

  1. 验证签名 SIGN
  2. 验证 POSID 是否匹配
  3. 根据 USER_ORDERIDccb_pay_flow_id 查询订单
  4. 更新订单状态
  5. 返回 SUCCESSFAIL

验证点:

  • 响应体必须返回字符串 SUCCESSFAIL
  • 订单状态正确更新
  • 日志 runtime/log/ 中记录通知详情

测试异步通知的方法模拟建行POST请求:

curl -X POST 'https://your-domain.com/addons/shopro/ccbpayment/notify' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'ORDERID=PAY20250118143000123456&USER_ORDERID=SO20250118001&POSID=100001&PAYMENT=100.00&SUCCESS=Y&SIGN=mock_sign'

测试8: 订单同步到建行(需建行环境)

目的: 验证支付成功后订单推送到建行

触发时机:

  • 支付回调成功后自动触发
  • 或手动调用同步接口

手动触发方式:

$orderService = new \addons\shopro\library\ccblife\CcbOrderService();
$result = $orderService->pushOrder($orderId);

var_dump($result);

验证点:

  1. API请求成功HTTP 200
  2. 返回 CLD_HEAD.ERR_CODE === '0'
  3. fa_ccb_sync_log 表中记录同步成功
  4. 订单同步状态更新

失败处理:

  • 如果同步失败,日志中记录错误原因
  • 支持重试机制(通过定时任务)

常见问题排查

问题1: 支付串生成失败

错误信息: "订单状态不正确"

原因: 订单已支付或已关闭

解决:

-- 检查订单状态
SELECT id, order_sn, status, pay_status FROM fa_shopro_order WHERE id = <order_id>;

-- 如需重测,重置订单状态
UPDATE fa_shopro_order SET status = 'unpaid', pay_status = 'unpaid' WHERE id = <order_id>;

问题2: 支付串签名错误

错误信息: "签名验证失败"

排查步骤:

  1. 检查配置文件中私钥是否正确
  2. 检查参数是否按ASCII排序
  3. 检查MD5签名是否为小写

验证签名算法:

// 测试代码
$params = [/* 支付参数 */];
ksort($params);
$signString = http_build_query($params);
$mac = md5($signString . config('ccblife.private_key'));

echo "签名字符串: {$signString}\n";
echo "MAC签名: {$mac}\n";

问题3: 订单查询失败

错误信息: "订单不存在"

原因:

  • 使用了错误的订单号字段
  • ORDERID支付流水号和 USER_ORDERID商户订单号混淆

排查:

-- 检查订单数据
SELECT
  id,
  order_sn,  -- 商户订单号
  ccb_pay_flow_id,  -- 建行支付流水号
  status
FROM fa_shopro_order
WHERE order_sn = 'SO20250118001'  -- 使用商户订单号查询
   OR ccb_pay_flow_id = 'PAY20250118143000123456';  -- 使用支付流水号查询

问题4: 订单状态未更新

可能原因:

  1. 字段名错误(paytime vs paid_time
  2. 时间戳单位错误(秒 vs 毫秒)
  3. pay_type 枚举值不存在

验证:

-- 检查订单表字段
SHOW COLUMNS FROM fa_shopro_order LIKE 'paid_time';

-- 检查pay_type枚举值
SHOW COLUMNS FROM fa_shopro_order LIKE 'pay_type';

-- 查看订单更新时间
SELECT
  id,
  paid_time,  -- 应为毫秒时间戳
  FROM_UNIXTIME(paid_time/1000) as paid_datetime,
  pay_type,  -- 应为 'offline'
  status
FROM fa_shopro_order
WHERE id = <order_id>;

问题5: RSA加密失败

错误信息: "RSA加密失败" 或 "key size too small"

原因:

  • 密钥格式不正确
  • 密钥长度不是1024位
  • 数据块大小超过117字节

验证密钥:

# 检查私钥
echo "<私钥内容>" | openssl rsa -text -noout

# 检查公钥
echo "<公钥内容>" | openssl rsa -pubin -text -noout

# 查看密钥长度
# 应显示: Private-Key: (1024 bit)

修复:

  1. 确保密钥包含完整的 -----BEGIN-----END 标记
  2. 数据分块处理每块不超过117字节
  3. 使用正确的填充模式 OPENSSL_PKCS1_PADDING

测试检查清单

阶段一:模拟测试(可立即执行)

  • 运行自动化测试脚本,所有测试通过
  • 配置文件已正确配置
  • 数据库表结构完整
  • 订单表 ccb_pay_flow_id 字段存在
  • 用户表 ccb_user_id 字段存在
  • 支付日志表 fa_ccb_payment_log 存在
  • 同步日志表 fa_ccb_sync_log 存在
  • 支付串生成逻辑正确
  • 支付流水号格式正确PAY+14位+6位
  • 订单字段映射正确paid_time、total_fee等

阶段二:真实环境测试(需建行配置)

  • 已获得建行测试环境配置
  • RSA密钥对配置正确1024位
  • API地址配置正确
  • 回调地址已配置且可访问
  • 在建行APP内能正确识别环境
  • JSBridge初始化成功
  • 用户自动登录成功
  • ccb_user_id正确绑定
  • 支付串加密正确ENCPUB字段
  • 建行收银台能正确打开
  • 支付回调能正确接收和处理
  • 异步通知能正确接收和处理
  • 签名验证通过
  • 订单状态正确更新
  • 订单同步到建行成功
  • 重复通知幂等性处理正确
  • 小额支付测试通过0.01元)
  • 正常金额支付测试通过
  • 支付取消测试通过
  • 支付超时测试通过

附录

A. 支付流水号规则

格式: PAY + YmdHis(14位) + 随机数(6位)
示例: PAY20250118143000123456
长度: 23位固定长度

组成:
- PAY: 固定前缀(3位)
- 20250118143000: 时间戳 yyMMddHHmmss (14位)
- 123456: 随机数 (6位)

B. 重要字段映射表

Shopro字段 建行字段 说明 示例
order_sn USER_ORDERID 商户订单号 SO20250118001
ccb_pay_flow_id ORDERID 建行支付流水号 PAY20250118143000123456
total_fee PAYMENT / PAY_AMT 实际支付金额 100.00
discount_fee - 优惠金额 5.00
paid_time PAY_TIME 支付时间(毫秒) 1737183000000
createtime ORD_TIME 订单创建时间(秒) 20250118143000
status ORD_STATUS 订单状态 paid → 02
pay_type - 支付方式 offline代表建行
transaction_id ORDERID 交易单号 PAY20250118143000123456

C. 订单状态映射

Shopro状态 建行状态码 说明
unpaid 01 未支付
paid 02 已支付
closed 03 已关闭
cancelled 04 已取消

D. 日志文件位置

建行支付日志:
- runtime/log/202501/18.log

关键日志标识:
- [建行支付] 支付串生成
- [建行支付] 生成支付串失败
- [建行回调] 收到同步回调
- [建行通知] 收到异步通知
- [建行订单同步] 推送订单

总结

本测试指南提供了完整的测试方案,分为两个阶段:

  1. 模拟测试阶段(当前可用)

    • 运行自动化测试脚本即可验证核心逻辑
    • 无需建行真实配置
    • 适合开发阶段自测
  2. 真实环境测试阶段(需建行配置)

    • 需要建行提供测试环境
    • 包含完整的支付流程
    • 适合联调和上线前测试

下一步行动:

  1. 立即运行自动化测试脚本
  2. ⏸️ 等待建行提供测试环境配置
  3. 🔄 获得配置后执行阶段二测试

如有问题,请查看"常见问题排查"章节或联系开发人员。