测试卡
Quick Reference
What沙箱测试卡行为与模拟
Why无需真实资金即可测试每种支付场景——批准、拒绝、超时
Reading Time5 分钟
Difficulty初级
Prerequisites身份验证 → 环境配置
为什么测试卡很重要
| 缺少系统化测试 | 使用 A55 测试卡 |
|---|---|
| 在生产环境中才发现拒付问题,影响真实客户 | 上线前在沙箱中模拟每种结果 |
| 边界场景(超时、过期卡、冻结卡)未经测试 | 修改一位数字即可触发任意场景 |
| QA 需要数天手动刷卡测试 | 单个脚本运行即可批量测试 9 种场景 |
| 不清楚 UI 如何展示失败状态 | 精确看到错误页面的实际表现 |
模拟器工作原理
在沙箱中,仅卡号末位数字决定交易结果。前 15 位数字可以是任意值。
规则:
- 使用任意合理的 16 位卡号——只有末位数字起作用。
- CVV(卡片验证码):任意 3 位数字(例如
123)。 - 有效期:任意未来日期,格式为
MM/YYYY(例如12/2030)。
末位数字对照表
| 末位数字 | 状态 | 返回码 | 消息 | 使用场景 |
|---|---|---|---|---|
| 0、1、4 | 已授权 | 4 或 6 | Operation completed successfully | 正常路径——测试成功支付 |
| 2 | 未授权 | 05 | Not authorized | 通用拒绝——测试错误处理 |
| 3 | 未授权 | 57 | Expired card | 测试过期卡 UX |
| 5 | 未授权 | 78 | Blocked card | 测试冻结卡/疑似欺诈卡 |
| 6 | 未授权 | 99 | Timeout | 测试超时处理与重试 |
| 7 | 未授权 | 77 | Canceled card | 测试注销卡 UX |
| 8 | 未授权 | 70 | Credit card problems | 测试通用卡片错误 |
| 9 | 随机 | 4–99 | Success or timeout (random) | 混沌测试——验证系统韧性 |
速查卡号
使用以下预设卡号——仅需修改末位数字:
| 场景 | 卡号 |
|---|---|
| 确认 | 4024 0071 5376 3191 |
| 拒绝 | 4024 0071 5376 3192 |
| 过期 | 4024 0071 5376 3193 |
| 冻结 | 4024 0071 5376 3195 |
| 超时 | 4024 0071 5376 3196 |
分步测试每种场景
1. 测试成功支付
- cURL
- Python
- JavaScript
curl -s -X POST https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"wallet_uuid": "YOUR_WALLET_UUID",
"merchant_id": "YOUR_MERCHANT_UUID",
"payer_name": "测试用户",
"payer_email": "zhangwei@example.com",
"payer_tax_id": "12345678909",
"payer_cell_phone": "+5511999999999",
"installment_count": 1,
"installment_value": 100.00,
"currency": "BRL",
"due_date": "2026-12-31",
"description": "沙箱测试——确认",
"type_charge": "credit_card",
"card_name": "测试用户",
"card_number": "4024007153763191",
"card_expiry_month": "12",
"card_expiry_year": "2030",
"card_cvv": "123"
}'
import requests
API_BASE = "https://sandbox.api.a55.tech/api/v1"
def create_test_charge(token: str, card_number: str, description: str):
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
payload = {
"wallet_uuid": "YOUR_WALLET_UUID",
"merchant_id": "YOUR_MERCHANT_UUID",
"payer_name": "测试用户",
"payer_email": "zhangwei@example.com",
"payer_tax_id": "12345678909",
"payer_cell_phone": "+5511999999999",
"installment_count": 1,
"installment_value": 100.00,
"currency": "BRL",
"due_date": "2026-12-31",
"description": description,
"type_charge": "credit_card",
"card_name": "测试用户",
"card_number": card_number,
"card_expiry_month": "12",
"card_expiry_year": "2030",
"card_cvv": "123",
}
resp = requests.post(f"{API_BASE}/bank/wallet/charge/", json=payload, headers=headers)
return resp.json()
result = create_test_charge(token, "4024007153763191", "沙箱测试——确认")
print(f"状态:{result['status']}")
const API_BASE = "https://sandbox.api.a55.tech/api/v1";
async function createTestCharge(token, cardNumber, description) {
const resp = await fetch(`${API_BASE}/bank/wallet/charge/`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
wallet_uuid: "YOUR_WALLET_UUID",
merchant_id: "YOUR_MERCHANT_UUID",
payer_name: "测试用户",
payer_email: "zhangwei@example.com",
payer_tax_id: "12345678909",
payer_cell_phone: "+5511999999999",
installment_count: 1,
installment_value: 100.0,
currency: "BRL",
due_date: "2026-12-31",
description,
type_charge: "credit_card",
card_name: "测试用户",
card_number: cardNumber,
card_expiry_month: "12",
card_expiry_year: "2030",
card_cvv: "123",
}),
});
return resp.json();
}
const result = await createTestCharge(token, "4024007153763191", "沙箱测试——确认");
console.log(`状态:${result.status}`);
2. 测试拒绝支付
将末位数字改为 2:
Card: 4024007153763192 → 返回码 05(未授权)
您的应用应显示适当的错误消息,并允许用户使用其他卡片重试。
3. 测试超时
将末位数字改为 6:
Card: 4024007153763196 → 返回码 99(超时)
您的应用应实现带指数退避的重试逻辑,并显示"请稍候"状态。
批量测试所有场景
运行单个脚本即可测试全部 9 种场景,验证您的错误处理逻辑。
- Python
- JavaScript
scenarios = [
("4024007153763190", "确认 (0)"),
("4024007153763191", "确认 (1)"),
("4024007153763192", "拒绝 (2)"),
("4024007153763193", "过期卡 (3)"),
("4024007153763194", "确认 (4)"),
("4024007153763195", "冻结卡 (5)"),
("4024007153763196", "超时 (6)"),
("4024007153763197", "注销卡 (7)"),
("4024007153763198", "卡片问题 (8)"),
("4024007153763199", "随机 (9)"),
]
for card_number, label in scenarios:
result = create_test_charge(token, card_number, f"批量测试——{label}")
print(f"{label:15s} → 状态={result.get('status', 'N/A'):15s} 代码={result.get('return_code', 'N/A')}")
const scenarios = [
["4024007153763190", "确认 (0)"],
["4024007153763191", "确认 (1)"],
["4024007153763192", "拒绝 (2)"],
["4024007153763193", "过期卡 (3)"],
["4024007153763194", "确认 (4)"],
["4024007153763195", "冻结卡 (5)"],
["4024007153763196", "超时 (6)"],
["4024007153763197", "注销卡 (7)"],
["4024007153763198", "卡片问题 (8)"],
["4024007153763199", "随机 (9)"],
];
for (const [cardNumber, label] of scenarios) {
const result = await createTestCharge(token, cardNumber, `批量测试——${label}`);
console.log(`${label.padEnd(15)} → 状态=${(result.status || "N/A").padEnd(15)} 代码=${result.return_code || "N/A"}`);
}
沙箱中的零额验证
零额验证端点(POST /api/v1/bank/wallet/zeroauth/)使用与收款相同的末位数字模拟器。当卡号完全匹配时,专用 3DS 测试卡 优先。
前提条件: 商户配置中 zeroauth_enabled 必须为 true。请联系客户经理启用。
| 末位数字 | is_valid | 典型 code | 用例 |
|---|---|---|---|
| 0, 1, 4 | true | 00、4 或 6 | 卡片通过验证 |
| 2 | false | 05 | 通用拒绝 |
| 3 | false | 57 | 过期 / 不允许 |
| 5 | false | 78 | 卡片被冻结 |
| 6 | false | 99 | 超时 / 发卡行不可用 |
| 7 | false | 77 | 卡片已注销 |
| 8 | false | 70 | 余额不足 / 卡片问题 |
| 9 | 随机 | 4 或 99 | 混沌测试 |
端点始终返回 HTTP 200——请检查响应体中的 is_valid 和 code。
# 拒绝 — 末位数字 2
curl -s -X POST https://sandbox.api.a55.tech/api/v1/bank/wallet/zeroauth/ \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"wallet_uuid": "YOUR_WALLET_UUID",
"holder_name": "TEST USER",
"card_number": "4024007153763192",
"expiry_month": "12",
"expiry_year": "2030",
"cvv": "123",
"brand": "visa"
}'
预期响应:{ "is_valid": false, "code": "05", ... }
沙箱中的令牌化
令牌化端点(POST /api/v1/bank/wallet/tokenization/)遵循相同的末位数字模拟器。失败时返回 HTTP 400 和 card_tokenization_failed。
前提条件: 商户配置中 tokenization_enabled 必须为 true。
| 末位数字 | 结果 | HTTP | 用例 |
|---|---|---|---|
| 0, 1, 4 | 成功 — 返回 token_uuid | 200 | 正常路径 |
| 2, 5, 7, 8 | declined | 400 | 注册被拒绝 |
| 3 | not_eligible | 400 | 卡片不符合条件(如已过期) |
| 6 | retryable_error | 400 | 超时 — 使用退避重试 |
| 9 | 随机成功或超时 | 200 或 400 | 混沌测试 |
在 card.number 中使用 4024007153763191 可成功令牌化。完整请求格式见令牌化卡片。
推荐的沙箱流程
测试完整的验证 → 存储 → 扣款序列:
在每个步骤使用 ...3192 重复测试,以验证拒绝场景的错误处理。
重要限制
沙箱 ≠ 生产行为
- 沙箱返回码和消息是模拟的。生产环境的响应来自真实发卡行和卡组织网络——返回码和消息会有所不同。
- 切勿在沙箱中使用真实卡号。模拟器会根据末位数字覆盖交易结果,不论 PAN(主账号)是否有效。
- 如果您的支付网关需要特定卡格式(如 BIN(银行识别号)前缀),请保持末位数字符合上表规则,调整其他数字以满足网关要求。
沙箱支持的流程
模拟器支持授权、捕获(全额和部分)、撤销、状态查询、零额验证和令牌化。所有流程遵循相同的末位数字规则(匹配时 3DS 测试卡 优先)。