Avistadocs
集成指南

沙盒测试

什么是沙盒?

沙盒是您账户的测试模式 — 不是单独的环境。它使用与生产环境相同的 API、相同的基础 URL 和相同的端点。区别在于您的沙盒账户连接到模拟银行提供商:交易即时处理,不会进行真实资金转账,也不会向 BACEN 发送 PIX。

沙盒和生产是独立的账户,每个账户都有自己的凭证(证书、clientId、clientSecret)。您的证书可以在两个账户之间共享,具体取决于配置 — 请咨询您的客户经理。

您的代码在沙盒和生产之间不需要更改。 当您准备上线时,只需切换到生产账户的凭证即可。无需更改端点,无需更改代码。

沙盒 vs 生产

沙盒生产
基础 URL相同 (https://api.avista.global)相同
账户专用沙盒账户专用生产账户
凭证独立的证书 + clientId/clientSecret独立的证书 + clientId/clientSecret
余额模拟(虚拟)真实资金
交易模拟(已持久化 — 可通过 API 查询)通过 BACEN 的真实 PIX
Webhooks模拟(~1秒送达),相同的 payload 结构真实,送达取决于提供商
X-Sandbox-Scenario支持(控制 webhook 结果)返回 400 Bad Request
文档与生产相同 — 所有 API Reference 页面均适用相同

开始使用沙盒

联系您的客户经理或 suporte@avista.global 申请沙盒账户。

您将收到沙盒账户的证书和 OAuth 凭证(clientId + clientSecret)。

通过 POST /api/webhooks 注册您的 webhook URL,以便接收模拟的 webhook 事件。

在控制面板中,前往设置确认您的账户已配置为沙盒模式。

进行身份验证,调用 API,并使用 X-Sandbox-Scenario 请求头模拟不同的结果。


概述

X-Sandbox-Scenario 请求头允许您控制任何交易的 webhook 结果。不使用该请求头时,沙盒始终返回成功 webhook。使用它来测试错误处理、延迟和边缘情况。

不发送 X-Sandbox-Scenario 请求头时,沙盒始终返回成功 webhook。 要测试错误场景(余额不足、无效密钥等),您必须在每个请求中显式发送该请求头。

此功能仅在沙盒环境中有效。在生产环境中,该请求头将被忽略,行为由实际交易结果决定。

工作原理

X-Sandbox-Scenario 不会改变 HTTP 响应 -- API 始终返回 201 Created,状态为 "PENDING"。模拟的场景仅影响发送到您回调 URL 的异步 webhook

┌─────────────┐         ┌──────────────┐         ┌─────────────────┐
│   您的应用  │──POST──▶│  Avista API   │──────▶  │   Mock 提供商   │
│             │◀──201───│              │         │                 │
│             │         │              │         │  处理请求头中   │
│             │         │              │         │  指定的场景     │
│             │         │              │         │                 │
│             │◀────────│──webhook─────│◀────────│                 │
│             │         │              │         │  约 1 秒后      │
└─────────────┘         └──────────────┘         └─────────────────┘
      │                                                  │
      │              HTTP 响应:始终 201                  │
      │              Webhook:成功或错误                  │
      │              (取决于请求头)                      │
请求HTTP 响应收到的 Webhook
不含 X-Sandbox-Scenario201 PENDINGCONFIRMED(成功)
X-Sandbox-Scenario: success201 PENDINGCONFIRMED(成功)
X-Sandbox-Scenario: error:insufficient-funds201 PENDINGERRORerrorCode
X-Sandbox-Scenario: delayed:5s201 PENDINGCONFIRMED 额外延迟 5 秒后

如何使用

在任何 Cash-In、Cash-Out 或退款请求中添加 X-Sandbox-Scenario 请求头:

curl -X POST https://api.avista.global/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.avista.global/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.avista.global/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-keyPIX 密钥在 DICT 中不存在ERROR
error:document-mismatch证件号与密钥持有人不匹配ERROR
error:account-blocked目标账户被冻结或已关闭ERROR
error:duplicate-id重复的提交 IDERROR

成功场景

请求头值描述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 从未被中央银行确认),errorCodeerrorMessage 字段描述失败原因。

兼容端点

X-Sandbox-Scenario 请求头适用于所有交易端点:

端点方法描述
/api/pix/cash-inPOST生成 PIX 收款(二维码)
/api/pix/cash-outPOST按密钥发送 PIX 付款
/api/pix/cash-out/qrcodePOST按二维码发送 PIX 付款
/api/pix/refund-inPOST退款请求

MED 场景

MED(特殊退款机制)模块无法直接通过 X-Sandbox-Scenario 进行测试。MED 依赖于与 BACEN 以及已配置的 PIX 提供方(Woovi、Hyperwallet 等)的集成,因此无法由沙盒的 mock 提供方模拟。

要验证您对 MED webhook(MedCreatedMedAcceptedMedRejected)的集成,请使用以下方法:

使用 POST /api/webhooks/{id}/resend 将账户中已存在的 MED webhook 重新发送到已配置的 URL。这对于在变更后在本地调试处理器非常有用。

使用 GET /api/med 列出与账户关联的 MED,按状态筛选,并与本地交易进行对账。

如果您需要端到端模拟 MED 流程(开启、分析、批准/拒绝),请联系 suporte@avista.global 申请预生产环境的访问权限。

MED webhook 使用与其他事件相同的认证方式(Basic Auth)和重试机制。完整 payload 已记录在 MedCreatedMedAcceptedMedRejected 中。

行为

API 正常处理请求并返回 201 Created,状态为 PENDING。 请求头不会改变即时响应 -- 仅影响后续的 webhook。

约 1 秒后(或更长时间,如果使用 delayed:),webhook 会发送到配置的 URL,包含模拟的场景。

您的系统收到 webhook,状态对应场景(CONFIRMEDERROR),应相应处理。

重要: 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@avista.global 验证您的账户配置。

最佳实践

测试所有场景

在上线生产前,实现对每种 webhook 状态(CONFIRMEDPENDINGERROR)的处理。

验证错误字段

statusERROR 时,使用 errorCodeerrorMessage 确定适当的操作(重试、通知用户等)。

测试延迟

使用 delayed: 场景验证您的系统能正确处理延迟到达的 webhooks。

幂等性

使用 transactionId 作为幂等键。在交付失败的情况下,相同的 webhook 可能会被重新发送。

本页目录