5 分钟完成首笔收款
Quick Reference
What在 A55 沙箱(sandbox)中完成首笔信用卡收款
Why在编写生产代码之前,端到端验证您的集成配置
Reading Time5 分钟
Difficulty初级
Prerequisites沙箱凭证(client_id + client_secret)
概览
本指南将引导您完成完整流程:认证、创建 wallet(钱包)、发起信用卡收款并查看结果。所有命令均在沙箱中运行——不会产生真实资金流动。
测试卡
| Card Number | Brand | Scenario | Expected Status |
|---|---|---|---|
4111 1111 1111 1111 | Visa | 支付成功 | confirmed |
4000 0000 0000 0002 | Visa | 卡片被拒 | declined |
4000 0000 0000 0069 | Visa | 处理错误 | error |
步骤
1
获取沙箱凭证
发送邮件至 tech.services@a55.tech 申请沙箱访问权限。您将收到:
| 凭证 | 说明 |
|---|---|
client_id | OAuth2(开放授权)客户端标识符 |
client_secret | OAuth2 客户端密钥 |
entity_uuid | 您的实体标识符 |
merchant_uuid | 您的商户标识符 |
将它们存储为环境变量:
export A55_CLIENT_ID="your_client_id"
export A55_CLIENT_SECRET="your_client_secret"
2
获取访问令牌
A55 使用 OAuth2 client_credentials(客户端凭证)授权模式。用您的凭证换取 Bearer Token(持有者令牌)。
- cURL
- Python
- Node.js
curl -s -X POST "https://auth.sandbox.a55.tech/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=${A55_CLIENT_ID}" \
-d "client_secret=${A55_CLIENT_SECRET}" \
-d "scope=api/readwrite" | python3 -m json.tool
import os
import requests
try:
response = requests.post(
"https://auth.sandbox.a55.tech/oauth2/token",
data={
"grant_type": "client_credentials",
"client_id": os.environ["A55_CLIENT_ID"],
"client_secret": os.environ["A55_CLIENT_SECRET"],
"scope": "api/readwrite",
},
)
response.raise_for_status()
token = response.json()["access_token"]
print(f"令牌:{token[:20]}...")
except requests.RequestException as e:
print(f"认证失败:{e}")
raise
const fetch = require("node-fetch");
async function getToken() {
try {
const res = await fetch("https://auth.sandbox.a55.tech/oauth2/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: process.env.A55_CLIENT_ID,
client_secret: process.env.A55_CLIENT_SECRET,
scope: "api/readwrite",
}),
});
if (!res.ok) throw new Error(`请求失败(HTTP ${res.status}):${await res.text()}`);
const { access_token } = await res.json();
console.log("令牌:", access_token.slice(0, 20) + "...");
return access_token;
} catch (err) {
console.error("认证失败:", err.message);
throw err;
}
}
getToken();
保存令牌:
export A55_ACCESS_TOKEN="eyJhbGciOiJSUzI1NiIs..."
3
创建钱包
钱包将收款记录归组到单个实体下。在创建收款之前,您需要先创建一个钱包。
- cURL
- Python
- Node.js
curl -s -X POST "https://sandbox.api.a55.tech/api/v1/bank/wallet/" \
-H "Authorization: Bearer ${A55_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "我的第一个钱包"
}' | python3 -m json.tool
import os
import requests
try:
response = requests.post(
"https://sandbox.api.a55.tech/api/v1/bank/wallet/",
headers={"Authorization": f"Bearer {os.environ['A55_ACCESS_TOKEN']}"},
json={"name": "我的第一个钱包"},
)
response.raise_for_status()
wallet = response.json()
print(f"钱包 UUID:{wallet['uuid']}")
except requests.RequestException as e:
print(f"钱包创建失败:{e}")
raise
async function createWallet() {
try {
const res = await fetch("https://sandbox.api.a55.tech/api/v1/bank/wallet/", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.A55_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "我的第一个钱包" }),
});
if (!res.ok) throw new Error(`请求失败(HTTP ${res.status}):${await res.text()}`);
const wallet = await res.json();
console.log("钱包 UUID:", wallet.uuid);
return wallet;
} catch (err) {
console.error("钱包创建失败:", err.message);
throw err;
}
}
响应:
{
"uuid": "wal_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "我的第一个钱包",
"status": "active",
"created_at": "2026-03-21T12:00:00Z"
}
4
创建信用卡收款
向收款 endpoint(端点)发送 POST 请求,使用测试卡 4111 1111 1111 1111。
- cURL
- Python
- Node.js
curl -s -X POST "https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/" \
-H "Authorization: Bearer ${A55_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"amount": "100.00",
"currency": "BRL",
"type_charge": "credit_card",
"card": {
"number": "4111111111111111",
"holder_name": "测试持卡人",
"expiration_month": "12",
"expiration_year": "2030",
"cvv": "123"
},
"payer": {
"name": "测试用户",
"email": "zhangwei@example.com",
"document": "12345678909",
"document_type": "CPF"
},
"description": "快速入门测试收款"
}' | python3 -m json.tool
import os
import requests
try:
response = requests.post(
"https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/",
headers={"Authorization": f"Bearer {os.environ['A55_ACCESS_TOKEN']}"},
json={
"amount": "100.00",
"currency": "BRL",
"type_charge": "credit_card",
"card": {
"number": "4111111111111111",
"holder_name": "测试持卡人",
"expiration_month": "12",
"expiration_year": "2030",
"cvv": "123",
},
"payer": {
"name": "测试用户",
"email": "zhangwei@example.com",
"document": "12345678909",
"document_type": "CPF",
},
"description": "快速入门测试收款",
},
)
response.raise_for_status()
charge = response.json()
print(f"收款 UUID:{charge['uuid']}")
print(f"状态:{charge['status']}")
except requests.RequestException as e:
print(f"收款失败:{e}")
raise
async function createCharge() {
try {
const res = await fetch("https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.A55_ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: "100.00",
currency: "BRL",
type_charge: "credit_card",
card: {
number: "4111111111111111",
holder_name: "测试持卡人",
expiration_month: "12",
expiration_year: "2030",
cvv: "123",
},
payer: {
name: "测试用户",
email: "zhangwei@example.com",
document: "12345678909",
document_type: "CPF",
},
description: "快速入门测试收款",
}),
});
if (!res.ok) throw new Error(`请求失败(HTTP ${res.status}):${await res.text()}`);
const charge = await res.json();
console.log("收款 UUID:", charge.uuid);
console.log("状态:", charge.status);
return charge;
} catch (err) {
console.error("收款失败:", err.message);
throw err;
}
}
响应:
{
"uuid": "chg_f1e2d3c4-b5a6-7890-fedc-ba0987654321",
"status": "confirmed",
"amount": "100.00",
"currency": "BRL",
"type_charge": "credit_card",
"created_at": "2026-03-21T12:01:00Z"
}
5
查询收款状态
查询收款记录以确认最终状态。
- cURL
- Python
- Node.js
CHARGE_UUID="chg_f1e2d3c4-b5a6-7890-fedc-ba0987654321"
curl -s -X GET "https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/?charge_uuid=${CHARGE_UUID}" \
-H "Authorization: Bearer ${A55_ACCESS_TOKEN}" | python3 -m json.tool
import os
import requests
charge_uuid = "chg_f1e2d3c4-b5a6-7890-fedc-ba0987654321"
try:
response = requests.get(
"https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/",
headers={"Authorization": f"Bearer {os.environ['A55_ACCESS_TOKEN']}"},
params={"charge_uuid": charge_uuid},
)
response.raise_for_status()
charge = response.json()
print(f"状态:{charge['status']}")
except requests.RequestException as e:
print(f"状态查询失败:{e}")
raise
async function checkStatus(chargeUuid) {
try {
const url = new URL("https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/");
url.searchParams.set("charge_uuid", chargeUuid);
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.A55_ACCESS_TOKEN}` },
});
if (!res.ok) throw new Error(`请求失败(HTTP ${res.status}):${await res.text()}`);
const charge = await res.json();
console.log("状态:", charge.status);
return charge;
} catch (err) {
console.error("状态查询失败:", err.message);
throw err;
}
}
checkStatus("chg_f1e2d3c4-b5a6-7890-fedc-ba0987654321");
创建收款时的幕后流程
- A55 接收您的收款请求并验证所有字段
- 根据卡片 BIN(银行识别号)、币种和商户配置,将请求路由到最佳可用收单机构(acquirer)
- 收单机构通过卡组织(Visa/Mastercard)处理授权
- A55 同步返回授权结果
- 如果您配置了
webhook_url,A55 会异步发送包含最终状态的通知