沙盒测试
概述
沙盒环境允许您模拟不同的 webhook 场景,而不影响真实交易。在任何请求中使用 X-Sandbox-Scenario 请求头来控制收到的 webhook 结果。
此功能仅在沙盒环境中有效。在生产环境中,该请求头将被忽略,行为由实际交易结果决定。
如何使用
在任何 Cash-In、Cash-Out 或退款请求中添加 X-Sandbox-Scenario 请求头:
curl -X POST https://api.ntxpay.com/api/pix/cash-out \
-H "Authorization: Bearer $TOKEN" \
-H "X-Sandbox-Scenario: error:insufficient-funds" \
-H "Content-Type: application/json" \
-d '{
"value": 150.00,
"details": {
"key": "recipient@email.com",
"keyType": "EMAIL",
"name": "Recipient Name",
"document": "39284918812"
},
"externalId": "test-error-001"
}'const response = await axios.post(
'https://api.ntxpay.com/api/pix/cash-out',
{
value: 150.00,
details: {
key: 'recipient@email.com',
keyType: 'EMAIL',
name: 'Recipient Name',
document: '39284918812',
},
externalId: 'test-error-001',
},
{
headers: {
Authorization: `Bearer ${token}`,
'X-Sandbox-Scenario': 'error:insufficient-funds',
},
}
);response = requests.post(
"https://api.ntxpay.com/api/pix/cash-out",
json={
"value": 150.00,
"details": {
"key": "recipient@email.com",
"keyType": "EMAIL",
"name": "Recipient Name",
"document": "39284918812",
},
"externalId": "test-error-001",
},
headers={
"Authorization": f"Bearer {token}",
"X-Sandbox-Scenario": "error:insufficient-funds",
},
)可用场景
错误场景
模拟不同类型的 webhook 失败:
| 请求头值 | 描述 | Webhook 状态 |
|---|---|---|
error:insufficient-funds | 账户余额不足 | ERROR |
error:invalid-pix-key | PIX 密钥在 DICT 中不存在 | ERROR |
error:document-mismatch | 证件号与密钥持有人不匹配 | ERROR |
error:account-blocked | 目标账户被冻结或已关闭 | ERROR |
error:duplicate-id | 重复的提交 ID | ERROR |
成功场景
| 请求头值 | 描述 | Webhook 状态 |
|---|---|---|
success | 强制成功(默认行为) | CONFIRMED |
| (不传请求头) | 默认沙盒行为 | CONFIRMED |
延迟场景
模拟慢处理以测试超时和重试:
| 请求头值 | 描述 | Webhook 状态 |
|---|---|---|
delayed:5s | 额外延迟 5 秒后成功 | CONFIRMED |
delayed:30s | 额外延迟 30 秒后成功 | CONFIRMED |
delayed:60s | 额外延迟 60 秒后成功 | CONFIRMED |
最大允许延迟为 120 秒。超过此值将自动截断。
收到的 Webhook 示例
成功 Webhook(默认)
{
"event": "CashOut",
"status": "CONFIRMED",
"transactionType": "PIX",
"movementType": "DEBIT",
"transactionId": "12345",
"externalId": "test-success-001",
"endToEndId": "E17745159XI4QA0EGFU",
"feeAmount": 0.50,
"originalAmount": 150.00,
"finalAmount": 150.50,
"processingDate": "2026-03-26T10:00:00.000Z",
"errorCode": null,
"errorMessage": null,
"counterpart": {
"name": "Recipient Name",
"document": "*.284.918-**",
"bank": {}
},
"metadata": {}
}错误 Webhook (error:insufficient-funds)
{
"event": "CashOut",
"status": "ERROR",
"transactionType": "PIX",
"movementType": "DEBIT",
"transactionId": "12345",
"externalId": "test-error-001",
"endToEndId": null,
"feeAmount": 0.50,
"originalAmount": 150.00,
"finalAmount": 150.50,
"processingDate": "2026-03-26T10:00:00.000Z",
"errorCode": "INSUFFICIENT_FUNDS",
"errorMessage": "Conta sem saldo",
"counterpart": {
"name": null,
"document": null,
"bank": {}
},
"metadata": {}
}当状态为 ERROR 时,endToEndId 字段为 null(因为 PIX 从未被中央银行确认),errorCode 和 errorMessage 字段描述失败原因。
兼容端点
X-Sandbox-Scenario 请求头适用于所有交易端点:
| 端点 | 方法 | 描述 |
|---|---|---|
/api/pix/cash-in | POST | 生成 PIX 收款(二维码) |
/api/pix/cash-out | POST | 按密钥发送 PIX 付款 |
/api/pix/cash-out/qrcode | POST | 按二维码发送 PIX 付款 |
/api/pix/refund-in | POST | 退款请求 |
行为
API 正常处理请求并返回 201 Created,状态为 PENDING。
请求头不会改变即时响应 -- 仅影响后续的 webhook。
约 1 秒后(或更长时间,如果使用 delayed:),webhook 会发送到配置的 URL,包含模拟的场景。
您的系统收到 webhook,状态对应场景(CONFIRMED 或 ERROR),应相应处理。
重要: X-Sandbox-Scenario 请求头仅控制 webhook。端点的 HTTP 响应始终返回成功(201 Created),状态为 "PENDING",无论选择哪个场景。最终结果(成功或错误)通过 webhook 送达。
限制
X-Sandbox-Scenario 请求头仅适用于配置为沙盒模式的账户。如果您的账户配置了生产提供商并发送此请求头,API 将返回错误:
{
"statusCode": 400,
"message": "X-Sandbox-Scenario header is only supported in sandbox mode. This account is not configured with a sandbox provider."
}使用此功能前,请确保您的账户处于沙盒模式。如果收到此错误,请联系 suporte@ntxpay.com 验证您的账户配置。
最佳实践
测试所有场景
在上线生产前,实现对每种 webhook 状态(CONFIRMED、PENDING、ERROR)的处理。
验证错误字段
当 status 为 ERROR 时,使用 errorCode 和 errorMessage 确定适当的操作(重试、通知用户等)。
测试延迟
使用 delayed: 场景验证您的系统能正确处理延迟到达的 webhooks。
幂等性
使用 transactionId 作为幂等键。在交付失败的情况下,相同的 webhook 可能会被重新发送。