测试卡
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://core-manager.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_value": 100.00,
"currency": "BRL",
"due_date": "2026-12-31",
"description": "沙箱测试——确认",
"type_charge": "credit_card",
"card": {
"number": "4024007153763191",
"holder_name": "测试用户",
"expiration_month": "12",
"expiration_year": "2030",
"cvv": "123"
}
}'
import requests
API_BASE = "https://core-manager.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_value": 100.00,
"currency": "BRL",
"due_date": "2026-12-31",
"description": description,
"type_charge": "credit_card",
"card": {
"number": card_number,
"holder_name": "测试用户",
"expiration_month": "12",
"expiration_year": "2030",
"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://core-manager.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_value: 100.0,
currency: "BRL",
due_date: "2026-12-31",
description,
type_charge: "credit_card",
card: {
number: cardNumber,
holder_name: "测试用户",
expiration_month: "12",
expiration_year: "2030",
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"}`);
}
重要限制
沙箱 ≠ 生产行为
- 沙箱返回码和消息是模拟的。生产环境的响应来自真实发卡行和卡组织网络——返回码和消息会有所不同。
- 切勿在沙箱中使用真实卡号。模拟器会根据末位数字覆盖交易结果,不论 PAN(主账号)是否有效。
- 如果您的支付网关需要特定卡格式(如 BIN(银行识别号)前缀),请保持末位数字符合上表规则,调整其他数字以满足网关要求。
沙箱支持的流程
模拟器支持授权、捕获(全额和部分)、撤销和状态查询。所有流程遵循相同的末位数字规则。