# API da ByteMax

Receba Pix em BRL na sua carteira CNY ou USD. A moeda é escolhida na abertura do perfil e não pode ser alterada. Acompanhe ordens e reembolsos por HTTPS com JSON.

- URL base: https://bytemax.exchange/api/v1
- [Baixar OpenAPI 3.1](https://bytemax.exchange/api-v1.openapi.json)
- [Página da documentação](https://bytemax.exchange/pt-BR/docs/api)

## Começar

Para integrar, você vai usar:

- Chave de API: vai em toda chamada, no cabeçalho `Authorization`.
- `Idempotency-Key`: use uma chave por operação. Se precisar repetir a mesma operação por falha de rede ou 5xx, reutilize a mesma chave (Valores e idempotência).
- `payment.url`: o link de pagamento para onde você leva o pagador.
- Webhook `order.completed`: avisa quando a ordem foi paga; confirme com `GET /orders/{id}` ([webhook](https://bytemax.exchange/pt-BR/docs/webhooks)).

Cada ordem tem dois lados:

| Campos | Significa | Moeda |
| --- | --- | --- |
| `source_*` | O que o pagador paga | `BRL` |
| `target_*` | O que você recebe | `CNY` / `USD` |

Quatro passos até a primeira ordem.

1. **Crie a chave de API**
   Na página [API](https://bytemax.exchange/pt-BR/api) do seu painel, crie a chave e guarde no seu servidor: ela aparece uma vez só e dá acesso a toda a sua conta. Recomendado: ative a lista de IPs permitidos com os endereços dos servidores que vão chamar a API. Com a lista desativada, qualquer IP pode usar a chave.

2. **Envie os cabeçalhos**
   `Authorization` vai em toda chamada. Em `POST` e `PATCH`, envie também `Content-Type: application/json` e o corpo em JSON UTF-8, mesmo quando ele for `{}`. Ao criar ordens e reembolsos, inclua `Idempotency-Key`: veja Valores e idempotência.

   **Toda chamada**

   ```http
   Authorization: Bearer <API_KEY>
   ```

   **POST e PATCH**

   ```http
   Content-Type: application/json
   ```

3. **Faça uma cotação (opcional)**
   A cotação não cria nada. Use para conferir a chave e ver os valores da conversão.

   ```bash
   curl --request GET "https://bytemax.exchange/api/v1/quote?source_currency=BRL&target_currency=CNY&source_amount_cents=10000" \
     --header "Authorization: Bearer <API_KEY>"
   ```

   **Resposta 200**

   ```json
   {
     "source_currency": "BRL",
     "source_amount_cents": "10000",
     "target_currency": "CNY",
     "target_amount_cents": "12500"
   }
   ```

4. **Crie sua primeira ordem**
   `POST /orders` com uma `Idempotency-Key` nova cria uma ordem de verdade. Leve o pagador até `payment.url`: é lá que ele paga. Sem pagamento, a ordem expira em `expires_at`, 48 horas depois da criação.

   ```bash
   curl --request POST "https://bytemax.exchange/api/v1/orders" \
     --header "Authorization: Bearer <API_KEY>" \
     --header "Idempotency-Key: order-8412" \
     --header "Content-Type: application/json" \
     --data '{"source_currency":"BRL","source_amount_cents":"10000","target_currency":"CNY"}'
   ```

   **Resposta 201**

   ```json
   {
     "id": "ord_example",
     "status": "pending_payment",
     "source_currency": "BRL",
     "source_amount_cents": "10000",
     "target_currency": "CNY",
     "target_amount_cents": "12500",
     "refunded_source_amount_cents": "0",
     "blocked_source_amount_cents": "0",
     "payment": {
       "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
       "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
     },
     "created_at": "2026-09-10T13:05:00.000Z",
     "expires_at": "2026-09-12T13:05:00.000Z"
   }
   ```

## Fluxo de pagamento

Uma ordem começa aguardando pagamento e termina concluída (paga), expirada ou cancelada. Acompanhe por webhook ou por consulta.

1. **Cotação (opcional)**
   `GET /quote` informa quanto o pagador paga e quanto você recebe. É só uma prévia: a ordem usa a cotação do momento em que é criada, e só então o mínimo e o máximo do Pix são conferidos.

2. **Crie a ordem**
   `POST /orders` com as duas moedas e um dos dois valores: quanto o pagador paga ou quanto você recebe. A resposta traz `payment.url`, o link de pagamento, e `payment.pix_copy_paste`, o código Pix que o pagador pode colar no aplicativo do banco.

3. **Leve o pagador ao link de pagamento**
   Redirecione o pagador para `payment.url` ou envie esse link a ele. Depois de pagar, ele volta sozinho, em 5 segundos, para a URL de retorno configurada na página [API](https://bytemax.exchange/pt-BR/api) do seu painel; o link "Voltar para a loja" da página de pagamento leva ao mesmo endereço. Sem essa URL, ele volta para o site de onde veio.

4. **Acompanhe a ordem**
   Cadastre um [webhook](https://bytemax.exchange/pt-BR/docs/webhooks): `order.completed` avisa quando a ordem foi paga, e `GET /orders/{id}` confirma o estado atual.

5. **Reembolse se precisar**
   `POST /orders/{id}/refunds` com quanto você quer devolver, em CNY ou USD, do valor que recebeu. Esse valor sai do seu saldo, e a ByteMax calcula quanto o pagador recebe de volta em BRL, na mesma proporção da ordem: devolver metade do valor recebido devolve metade dos reais pagos. Se a resposta for 202, o reembolso ainda está em processamento: acompanhe com `GET /orders/{id}/refunds/{refund_id}` e não crie outro.

### Estados da ordem

- `pending_payment`: Aguardando o pagamento. O código Pix pode ser pago até `expires_at`, 48 horas depois da criação.
- `completed`: Paga. O valor em CNY ou USD já está no seu saldo. Estado final.
- `expired`: Não foi paga até `expires_at`. Estado final.
- `canceled`: Cancelada pela ByteMax, por exemplo quando um pagamento não pôde ser aceito e foi devolvido ao pagador. Estado final.

### Estados do reembolso

- `processing`: Em andamento. Consulte até chegar a um estado final. Um reembolso que continua em `processing` por muito tempo está em análise pela ByteMax: fale com o suporte.
- `succeeded`: Concluído. Estado final.
- `failed`: Não foi possível concluir o reembolso. O valor em CNY ou USD volta para o seu saldo. Estado final.

## Valores e idempotência

### Valores e IDs

Todo valor monetário é uma string com um inteiro positivo em centavos, sem zeros à esquerda, sinal, ponto ou notação científica. BRL, CNY e USD usam escala 2: "20000" significa 200 unidades da moeda informada. Envie exatamente um valor: `source_amount_cents` ou `target_amount_cents`.

O mínimo e o máximo do Pix são conferidos na criação da ordem, não na cotação. O pagador precisa pagar pelo menos R$ 30,00 (`ORDER_MINIMUM_NOT_MET`). O máximo pago por Pix acompanha o câmbio: acima dele a API responde `PIX_RECEIPT_LIMIT_EXCEEDED` e a `message` informa o máximo atual em BRL. Em qualquer chamada, o valor que você envia não pode passar de `"100000000"` (1.000.000,00).

Todo ID também é uma string: guarde e compare como texto, sem converter para número. Um ID de reembolso, como `"9007199254741001"`, pode passar do maior inteiro que o JavaScript representa com exatidão.

### Idempotência

- Use uma `Idempotency-Key` por operação: cada ordem ou reembolso novo tem a sua.
- Para repetir a mesma operação depois de uma falha de rede ou de uma resposta 5xx, reutilize a mesma chave com o mesmo corpo. A API devolve a ordem ou o reembolso já criado, no estado atual, sem criar outro.
- Guarde a chave junto do pedido no seu sistema.

A chave tem de 1 a 80 caracteres entre letras, números, `.`, `_`, `:` e `-`. Não use chaves que diferem só em maiúsculas e minúsculas. As chaves não expiram, e as de ordem valem também para as ordens criadas pela API anterior. Na repetição, a ordem volta com 200; o reembolso, com 202 enquanto estiver em processamento e 200 depois.

Casos especiais: a mesma chave com outro corpo devolve 409 `IDEMPOTENCY_CONFLICT`. Uma recusa antes da reserva da chave não a ocupa. Depois da reserva para criar uma ordem, uma falha de cobrança ou persistência pode manter a chave em processamento, mesmo sem ordem criada. Em falha de rede ou 5xx, repita a mesma intenção com a mesma chave; não envie outro corpo nem troque a chave para tentar novamente. Enquanto a criação com a chave estiver em processamento, a repetição recebe 409 `CONFLICT`.

## Referência

Cinco operações. Os exemplos usam `<API_KEY>` e IDs fictícios.

### Cotação

`GET /quote`

Informa os valores de uma conversão sem criar nada. A cotação não fica reservada e não confere o mínimo e o máximo do Pix: um valor cotado ainda pode ser recusado ao criar a ordem. Envie as duas moedas e um dos dois valores na query.

**Parâmetros**

| Parâmetro | Onde | Obrigatório |
| --- | --- | --- |
| `source_currency` | query | Sim |
| `target_currency` | query | Sim |
| `source_amount_cents` | query | Condicional |
| `target_amount_cents` | query | Condicional |

**Requisição**

```bash
curl --request GET "https://bytemax.exchange/api/v1/quote?source_currency=BRL&target_currency=CNY&source_amount_cents=10000" \
  --header "Authorization: Bearer <API_KEY>"
```

**Resposta 200**

```json
{
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500"
}
```

### Criar ordem

`POST /orders`

Cria a ordem e devolve o link de pagamento. Exige `Idempotency-Key`.

**Parâmetros**

| Parâmetro | Onde | Obrigatório |
| --- | --- | --- |
| `Idempotency-Key` | cabeçalho | Sim |

**Corpo JSON**

| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `source_currency` | `string` | Sim | Moeda que o pagador paga. Hoje, só `BRL`. |
| `target_currency` | `string` | Sim | Moeda que você recebe: `CNY` ou `USD`, obrigatoriamente igual à moeda da sua carteira. |
| `source_amount_cents` | `string` | Condicional | Valor que o pagador paga, em centavos de BRL. |
| `target_amount_cents` | `string` | Condicional | Valor que você recebe, em centavos de CNY ou USD. |

Informe exatamente um entre `source_amount_cents` e `target_amount_cents`. A ordem calcula o outro.

**Requisição**

```bash
curl --request POST "https://bytemax.exchange/api/v1/orders" \
  --header "Authorization: Bearer <API_KEY>" \
  --header "Idempotency-Key: order-8412" \
  --header "Content-Type: application/json" \
  --data '{"source_currency":"BRL","source_amount_cents":"10000","target_currency":"CNY"}'
```

**Resposta 201**

```json
{
  "id": "ord_example",
  "status": "pending_payment",
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500",
  "refunded_source_amount_cents": "0",
  "blocked_source_amount_cents": "0",
  "payment": {
    "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
    "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
  },
  "created_at": "2026-09-10T13:05:00.000Z",
  "expires_at": "2026-09-12T13:05:00.000Z"
}
```

### Consultar ordem

`GET /orders/{id}`

Estado atual e valores da ordem. `refunded_source_amount_cents` é quanto já foi devolvido ao pagador, e `blocked_source_amount_cents`, quanto está retido por contestações, ambos em centavos de BRL. `expires_at` é o fim do prazo para pagar, 48 horas depois de `created_at`: uma ordem ainda em `pending_payment` nesse instante não pode mais ser paga e passa a `expired`. O campo continua na ordem depois disso; para saber se ela foi paga, use `status`.

**Parâmetros**

| Parâmetro | Onde | Obrigatório |
| --- | --- | --- |
| `id` | caminho | Sim |

**Requisição**

```bash
curl --request GET "https://bytemax.exchange/api/v1/orders/ord_example" \
  --header "Authorization: Bearer <API_KEY>"
```

**Resposta 200**

```json
{
  "id": "ord_example",
  "status": "pending_payment",
  "source_currency": "BRL",
  "source_amount_cents": "10000",
  "target_currency": "CNY",
  "target_amount_cents": "12500",
  "refunded_source_amount_cents": "0",
  "blocked_source_amount_cents": "0",
  "payment": {
    "url": "https://bytemax.exchange/pt-br/payment/0123456789abcdef0123456789abcdef",
    "pix_copy_paste": "00020101021226820014br.gov.bcb.pix2560pix.example/qr/v2/0123456789abcdef0123456789abcdef5204000053039865406100.005802BR5907BYTEMAX6009SAO PAULO62070503***6304ABCD"
  },
  "created_at": "2026-09-10T13:05:00.000Z",
  "expires_at": "2026-09-12T13:05:00.000Z"
}
```

### Criar reembolso

`POST /orders/{id}/refunds`

Reembolsa parte ou todo o valor recebido, em centavos de CNY ou USD. Exige `Idempotency-Key`. Só ordens `completed` podem ser reembolsadas, um reembolso por vez, e o seu saldo em CNY ou USD precisa cobrir o valor. Responde 202 enquanto o reembolso estiver em processamento e 200 quando ele já terminou: confira o `status`.

**Parâmetros**

| Parâmetro | Onde | Obrigatório |
| --- | --- | --- |
| `id` | caminho | Sim |
| `Idempotency-Key` | cabeçalho | Sim |

**Corpo JSON**

| Campo | Tipo | Obrigatório | Descrição |
| --- | --- | --- | --- |
| `target_amount_cents` | `string` | Sim | Valor a reembolsar, em centavos de CNY ou USD, tirado do seu saldo. O pagador recebe em BRL a mesma proporção do que pagou, arredondada ao centavo (`source_amount_cents` na resposta). |

**Requisição**

```bash
curl --request POST "https://bytemax.exchange/api/v1/orders/ord_example/refunds" \
  --header "Authorization: Bearer <API_KEY>" \
  --header "Idempotency-Key: refund-8412-1" \
  --header "Content-Type: application/json" \
  --data '{"target_amount_cents":"2500"}'
```

**Resposta 202**

```json
{
  "id": "9007199254741001",
  "order_id": "ord_example",
  "status": "processing",
  "source_currency": "BRL",
  "source_amount_cents": "2000",
  "target_currency": "CNY",
  "target_amount_cents": "2500",
  "created_at": "2026-09-10T13:05:00.000Z",
  "updated_at": "2026-09-10T13:05:00.000Z"
}
```

### Consultar reembolso

`GET /orders/{id}/refunds/{refund_id}`

Estado atual de um reembolso pedido pela sua conta, pela API ou pelo painel.

**Parâmetros**

| Parâmetro | Onde | Obrigatório |
| --- | --- | --- |
| `id` | caminho | Sim |
| `refund_id` | caminho | Sim |

**Requisição**

```bash
curl --request GET "https://bytemax.exchange/api/v1/orders/ord_example/refunds/9007199254741001" \
  --header "Authorization: Bearer <API_KEY>"
```

**Resposta 200**

```json
{
  "id": "9007199254741001",
  "order_id": "ord_example",
  "status": "processing",
  "source_currency": "BRL",
  "source_amount_cents": "2000",
  "target_currency": "CNY",
  "target_amount_cents": "2500",
  "created_at": "2026-09-10T13:05:00.000Z",
  "updated_at": "2026-09-10T13:05:00.000Z"
}
```

## Erros e limites

Toda resposta de erro traz `code` e `message`. Programe usando o `code`: a `message` é um texto para os seus logs e pode mudar. Guarde o cabeçalho de resposta `X-Request-Id`: ele identifica a chamada quando você falar com o suporte. Campos desconhecidos e parâmetros repetidos são rejeitados com 400. Durante uma manutenção ou instabilidade, a resposta pode vir sem `code`: trate qualquer 5xx, ou um corpo que não seja JSON, como falha temporária.

```json
{
  "code": "INVALID_INPUT",
  "message": "Use source_currency BRL and the supplier wallet currency, CNY or USD."
}
```

### Status HTTP

| Status HTTP | Quando acontece |
| --- | --- |
| 400 | Dados inválidos, valor fora dos limites ou par de moedas não suportado. |
| 401 | Chave de API ausente ou inválida. |
| 403 | IP fora da lista de IPs permitidos ou operação não autorizada para sua conta. |
| 404 | Ordem, reembolso, webhook ou evento não encontrado, ou endereço que não existe na API. |
| 409 | A requisição conflita com o estado atual: chave de idempotência repetida com outro corpo ou ainda em uso, ordem que ainda não pode ser reembolsada, reembolso ainda em andamento ou webhook com a mesma URL. |
| 410 | A ordem foi paga por um meio que não é mais aceito e não pode ser reembolsada pela API. |
| 413 | Corpo maior que 1 MB. |
| 415 | `POST` ou `PATCH` sem `Content-Type: application/json`, mesmo quando o corpo é `{}`. |
| 429 | Limite de chamadas excedido. Espere o tempo de `Retry-After` e repita. |
| 500 | Falha inesperada. Repita depois de alguns segundos; nas criações, com a mesma `Idempotency-Key`. |
| 503 | Serviço indisponível. Repita depois de alguns segundos, aumentando a espera a cada tentativa. |

### Códigos de erro

Os códigos mais comuns. Outros podem aparecer: trate um código desconhecido com status 4xx como uma recusa que não passa se você repetir, e com status 5xx como falha temporária.

- `WALLET_CURRENCY_MISMATCH` (HTTP 409): A moeda de destino deve ser igual à moeda do saldo da sua conta.
- `UNAUTHORIZED` (HTTP 401): Chave de API ausente, malformada ou que não vale mais. Confira o cabeçalho `Authorization: Bearer <API_KEY>`; se você criou uma chave nova, a anterior deixou de funcionar.
- `API_IP_NOT_ALLOWED` (HTTP 403): A chamada veio de um IP fora da sua lista de IPs permitidos. Inclua o endereço do seu servidor na página [API](https://bytemax.exchange/pt-BR/api).
- `USER_BLOCKED` (HTTP 403): Sua conta está bloqueada ou foi encerrada. [Fale com o suporte](https://bytemax.exchange/pt-BR/support).
- `KYC_KYB_REQUIRED` (HTTP 403): Sua conta ainda não pode criar ordens. Conclua a verificação de identidade no painel; se ela já foi aprovada, fale com o suporte.
- `INVALID_INPUT` (HTTP 400): A requisição está malformada: um campo, parâmetro ou cabeçalho falta, é desconhecido, está repetido ou é inválido; o corpo não é JSON; o par não é BRL → CNY ou USD; ou o valor passa de `"100000000"` (1.000.000,00). A `message` diz o que corrigir. Valores são strings só com dígitos, maiores que zero, como `"10000"`.
- `JSON_REQUIRED` (HTTP 415): Envie `Content-Type: application/json` em todo `POST` e `PATCH`, mesmo quando o corpo for `{}`.
- `ORDER_MINIMUM_NOT_MET` (HTTP 400): O pagador pagaria menos que o mínimo de R$ 30,00. Vale também quando você informa só o valor em CNY ou USD.
- `PIX_RECEIPT_LIMIT_EXCEEDED` (HTTP 400): O pagador pagaria mais que o máximo atual do Pix, informado na `message`. Crie a ordem de novo com um valor menor; a mesma `Idempotency-Key` pode ser usada.
- `IDEMPOTENCY_CONFLICT` (HTTP 409): Esta chave já foi usada com outro corpo. Use uma chave nova para uma operação nova.
- `CONFLICT` (HTTP 409): A criação de uma ordem com esta chave ainda está em andamento. Espere alguns segundos e repita com a mesma `Idempotency-Key`.
- `ORDER_NOT_FOUND` (HTTP 404): Não há ordem com este ID na sua conta. Ordens expiradas são removidas 6 meses depois de criadas.
- `ORDER_NOT_REFUNDABLE` (HTTP 409): A ordem ainda não foi paga, expirou ou foi cancelada. Só ordens `completed` podem ser reembolsadas.
- `REFUND_NOT_FOUND` (HTTP 404): Não há reembolso com este ID nesta ordem. Só aparecem reembolsos pedidos pela sua conta.
- `REFUND_AMOUNT_NOT_AVAILABLE` (HTTP 400): O valor é maior que o que ainda pode ser reembolsado: parte da ordem já foi reembolsada ou está retida por uma contestação.
- `REFUND_INVALID_AMOUNT_OR_RATIO` (HTTP 400): O valor é pequeno demais para virar um reembolso em BRL.
- `REFUND_IN_PROGRESS` (HTTP 409): Outro reembolso desta ordem ainda não terminou. Espere ele chegar a um estado final.
- `INSUFFICIENT_BALANCE` (HTTP 400): O seu saldo em CNY ou USD não cobre o reembolso.
- `PAYMENT_METHOD_RETIRED` (HTTP 410): A ordem foi paga por um meio que não é mais aceito. Fale com o suporte para reembolsar.
- `NOT_FOUND` (HTTP 404): O endereço ou o método não existe na API. Não há operação para listar ou cancelar ordens.
- `PAYLOAD_TOO_LARGE` (HTTP 413): O corpo é maior que 1 MB.
- `SECURITY_BLOCKED` (HTTP 403): O filtro de segurança recusou a requisição por causa de uma sequência incomum na URL ou no corpo. Repetir a mesma requisição logo em seguida recebe 429 `RATE_LIMIT_EXCEEDED`. Se os seus dados são legítimos, fale com o suporte informando o `X-Request-Id`.
- `RATE_LIMIT_EXCEEDED` (HTTP 429): Limite de chamadas excedido. Espere o tempo de `Retry-After`.
- `SERVICE_UNAVAILABLE` (HTTP 503): Um serviço necessário para a operação está temporariamente indisponível, ou as conversões estão pausadas. Repita depois de alguns segundos, aumentando a espera, com a mesma `Idempotency-Key`.
- `INTERNAL_ERROR` (HTTP 500): Falha inesperada. Repita depois de alguns segundos com a mesma `Idempotency-Key`. Se continuar, fale com o suporte informando o `X-Request-Id`.

### Limite de chamadas

Cada endereço IP pode fazer até 300 requisições por minuto à ByteMax, somando a API e o site. `GET /quote` aceita 300 chamadas por minuto por conta, e a criação de reembolsos, 30 por minuto por conta, somando os reembolsos pedidos no painel. Ao receber 429, espere os segundos indicados em `Retry-After` antes de repetir. As respostas de cotação e de reembolso também informam o limite da conta nos cabeçalhos `RateLimit-*` abaixo; `RateLimit-Reset` é o número de segundos até a janela recomeçar. Para acompanhar ordens, use webhooks em vez de consultar a cada poucos segundos.

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 60
RateLimit-Policy: 300;w=60
RateLimit-Limit: 300
RateLimit-Remaining: 0
RateLimit-Reset: 60
```

## Resumo da integração

O caminho de um pedido pago, do início ao fim:

1. **Crie a ordem**
   `POST /orders` com uma `Idempotency-Key` nova para o pedido.

2. **Guarde o `id`**
   Grave o `id` da ordem junto do pedido no seu sistema.

3. **Redirecione o pagador para `payment.url`**
   Ou mostre `payment.pix_copy_paste` no seu checkout.

4. **Receba `order.completed`**
   No seu [webhook](https://bytemax.exchange/pt-BR/docs/webhooks), verifique a assinatura e grave o `id` do evento.

5. **Consulte `GET /orders/{id}`**
   O evento só avisa; a consulta traz o estado atual.

6. **Libere o pedido se `status` for `completed`**
   Libere uma vez só por ordem, mesmo que o evento chegue repetido.

Dúvidas na integração? [Fale com o suporte](https://bytemax.exchange/pt-BR/support).
