> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spedy.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Integração para plataformas e checkouts

> Como plataformas de pagamento, checkouts e marketplaces integram a Spedy para emitir as notas das vendas dos seus clientes.

Este guia é para **plataformas de pagamento, checkouts, plataformas de
infoprodutos, marketplaces e afins** que querem oferecer a Spedy como o
sistema de emissão de notas fiscais dos seus clientes.

Esse tipo de integração é diferente de um ERP ou SaaS que emite as próprias
notas pela API. Aqui, a plataforma **não monta a nota fiscal**: ela **envia a
venda** para a Spedy e **mantém o status dela atualizado** a cada mudança. A
Spedy decide quando emitir, monta a nota com a configuração fiscal do cliente e
cancela a nota quando a venda é reembolsada.

| | ERP / SaaS emissor | Plataforma ou checkout |
| - | - | - |
| Quem integra | O sistema que emite as próprias notas (ou as dos seus clientes) | A plataforma, em nome de cada vendedor que habilita a integração |
| O que envia | A nota fiscal completa, ou a venda | **Sempre a venda** (`/v1/orders`) |
| Tributação | Enviada pela API ou configurada na Spedy | Configurada pelo vendedor no painel da Spedy |
| Depois do envio | Acompanha a nota | **Atualiza o status da venda** a cada evento de pagamento |

## Como funciona

**1. O vendedor habilita a integração na sua plataforma**

Na tela de integrações da plataforma, o vendedor informa a **chave de API
da Spedy** da empresa dele. A chave fica no painel da Spedy, em **menu do
perfil do usuário → Minha empresa → Credenciais de API**.

**2. A plataforma envia cada venda**

A cada pedido, a plataforma cria a venda com `POST /v1/orders`, usando a
chave do vendedor no header `X-Api-Key`.

**3. A plataforma atualiza o status da venda**

A cada evento de pagamento (aprovação, recusa, reembolso, chargeback), a
plataforma atualiza a venda com `PUT /v1/orders/{id}/status`.

**4. A Spedy emite e cancela as notas**

Conforme o `autoIssueMode` e o status da venda, a Spedy emite a nota no
momento certo — e cancela as notas autorizadas quando a venda é
reembolsada, sofre chargeback ou é cancelada.

```mermaid theme={null}
sequenceDiagram
    participant Comprador
    participant Plataforma
    participant Spedy as API Spedy
    participant Fisco as SEFAZ / Prefeitura

    Comprador->>Plataforma: Finaliza o pedido
    Plataforma->>Spedy: POST /v1/orders (status: awaitingPayment)
    Comprador->>Plataforma: Paga
    Plataforma->>Spedy: PUT /v1/orders/{id}/status (approved)
    Spedy->>Fisco: Emite a nota (conforme o autoIssueMode)
    Fisco-->>Spedy: Autoriza
    Spedy-->>Comprador: E-mail com a nota (opcional)
```

## Sandbox e produção

A Spedy tem dois ambientes, com contas e chaves separadas:

| Ambiente | Base URL | Quem usa nesta integração |
| - | - | - |
| Sandbox | `https://sandbox-api.spedy.com.br/v1` | **Só a sua plataforma**, durante o desenvolvimento, com uma conta de testes própria. |
| Produção | `https://api.spedy.com.br/v1` | **Os seus clientes.** A chave que o vendedor informa na sua plataforma é sempre de produção. |

* **Desenvolva e homologue no sandbox.** Crie uma conta no [ambiente de
  testes](https://docs.spedy.com.br/start/ambiente-de-testes.md) e use a chave dela para percorrer todo o
  fluxo deste guia.
* **Em produção, use `https://api.spedy.com.br/v1`.** Deixe a base URL em
  configuração, nunca fixa no código: uma chave de produção enviada ao sandbox
  (ou o contrário) recebe `401`.
* **Não ofereça o sandbox aos seus clientes.** A integração que o vendedor
  habilita deve apontar sempre para produção.

> [!WARNING]
>
> O sandbox **pode emitir notas com validade fiscal**: isso acontece quando o
> ambiente de emissão de um modelo de nota está configurado como Produção na
> conta de testes. Mantenha a conta de sandbox em Simulação (NFS-e) ou
> Homologação (NF-e e NFC-e). Veja [Ambiente de
> testes](https://docs.spedy.com.br/start/ambiente-de-testes.md#efeitos-fiscais-por-modelo).

> [!NOTE]
>
> **Os exemplos deste guia usam o sandbox.** Ao levar a integração para
> produção, troque `https://sandbox-api.spedy.com.br` por
> `https://api.spedy.com.br`.

## Habilitando a integração

A chave de API identifica **uma empresa (CNPJ)** e só opera em nome dela. Na
sua tela de integração, guarde a chave por conta (ou loja) do vendedor. Se o
vendedor vende por mais de um CNPJ, ele precisa informar a chave de cada
empresa.

Algumas recomendações para a tela de integração:

* **Valide a chave ao salvar.** Uma chamada simples, como
  `GET /v1/orders?transactionId=teste`, devolve `401` quando a chave é
  inválida.
* **Guarde a chave como segredo.** Ela permite emitir e cancelar notas em nome
  do vendedor — trate-a como uma senha.
* **Valide contra produção.** A chave do vendedor é de produção: valide-a em
  `https://api.spedy.com.br`. Veja [Sandbox e produção](#sandbox-e-produção).

> [!NOTE]
>
> A tributação da nota (códigos de serviço, NCM, CFOP, alíquotas e retenções)
> **não é enviada pela plataforma**. O vendedor configura isso no painel da
> Spedy, por produto e por empresa. Veja [Configuração
> inicial](https://docs.spedy.com.br/guides/configuracao-inicial.md).

## Criando a venda

Crie a venda com `POST /v1/orders`. O exemplo abaixo é um pedido de um curso
pago por Pix, ainda aguardando o pagamento:

```bash cURL (sandbox) theme={null}
curl -X POST https://sandbox-api.spedy.com.br/v1/orders \
  -H "X-Api-Key: sua-chave-de-sandbox" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "PED-2026-000123",
    "date": "2026-11-05T14:30:00-03:00",
    "status": "awaitingPayment",
    "autoIssueMode": "afterPayment",
    "paymentMethod": "pix",
    "amount": 297.00,
    "sendEmailToCustomer": true,
    "customer": {
      "name": "Maria Souza",
      "federalTaxNumber": "12345678909",
      "email": "maria@exemplo.com.br",
      "address": {
        "street": "Rua das Flores",
        "number": "100",
        "district": "Centro",
        "postalCode": "01310100",
        "city": { "name": "São Paulo", "state": "SP" }
      }
    },
    "items": [
      {
        "quantity": 1,
        "price": 297.00,
        "amount": 297.00,
        "product": {
          "code": "CURSO-FOTOGRAFIA",
          "name": "Curso de Fotografia",
          "price": 297.00
        }
      }
    ]
  }'
```

A resposta traz o `id` da venda na Spedy. **Guarde esse `id` junto do pedido**
na sua plataforma: ele é usado em todas as atualizações seguintes.

Os campos que mais importam para uma plataforma:

| Campo | Descrição |
| - | - |
| `transactionId` | Código do pedido na sua plataforma. **Único por empresa**: uma segunda venda com o mesmo `transactionId` é recusada com o erro `Já existe venda com o código de transação informado.` — o que protege contra vendas duplicadas em retentativas. |
| `date` | Data da venda. |
| `status` | Status da venda no momento do envio (padrão: `created`). Veja [os status](#mapeando-os-eventos-da-plataforma). |
| `autoIssueMode` | Quando a nota deve ser emitida. Veja [Quando a nota é emitida](#quando-a-nota-é-emitida). |
| `warrantyDate` | Último dia da garantia (prazo de reembolso). Usado com `autoIssueMode: "afterWarrency"`. |
| `paymentMethod` | Forma de pagamento: `creditCard`, `debitCard`, `pix`, `billetBank`, `bankTransfer`, `paypal`, `balanceWallets`, `cash` ou `other`. |
| `amount` | Valor total da venda. |
| `sendEmailToCustomer` | Envia a nota por e-mail ao comprador quando autorizada (padrão: `false`). |
| `customer` | Comprador (tomador ou destinatário da nota). Envie CPF/CNPJ, e-mail e endereço sempre que tiver. |
| `items[].product.code` | Código do produto na sua plataforma. A Spedy cadastra o produto na primeira venda e o reconhece pelo código nas seguintes — é nesse cadastro que o vendedor configura a tributação. |
| `items[].product.invoiceModel` | Modelo da nota do produto: `serviceInvoice` (NFS-e, padrão), `productInvoice` (NF-e) ou `consumerInvoice` (NFC-e). |

A referência completa dos campos está em [Criar
Venda](https://docs.spedy.com.br/api-reference/vendas/criar-venda.md).

### Envie a venda assim que o pedido existir

Recomendamos criar a venda **assim que o pedido é gerado** — inclusive Pix e
boleto ainda não pagos, com `status: "awaitingPayment"` — e depois só
atualizar o status. Assim a venda na Spedy acompanha a vida do pedido, e o
vendedor vê no painel também as vendas recusadas e expiradas.

Se a sua plataforma preferir enviar apenas pedidos pagos, crie a venda já com
`status: "approved"`. Nesse caso, o restante do fluxo (reembolso, chargeback,
cancelamento) continua igual.

## Mapeando os eventos da plataforma

Cada mudança no pedido vira uma atualização de status da venda:

```bash cURL (sandbox) theme={null}
curl -X PUT https://sandbox-api.spedy.com.br/v1/orders/{id}/status \
  -H "X-Api-Key: sua-chave-de-sandbox" \
  -H "Content-Type: application/json" \
  -d '{ "status": "approved" }'
```

| Evento na plataforma | Chamada na Spedy | Efeito na nota |
| - | - | - |
| Pedido criado, Pix ou boleto gerado | `POST /v1/orders` com `status: "awaitingPayment"` | Nenhum, com `afterPayment` ou `afterWarrency`. |
| Pagamento aprovado | `status: "approved"` | Dispara a emissão com `afterPayment`; inicia a espera da garantia com `afterWarrency`. |
| Pagamento recusado | `status: "refused"` | Nenhuma nota é emitida, com `afterPayment` ou `afterWarrency`. |
| Pix ou boleto expirado | `status: "expired"` | Nenhuma nota é emitida, com `afterPayment` ou `afterWarrency`. |
| Reembolso solicitado | `status: "refundRequested"` | Suspende a emissão por garantia enquanto o pedido estiver nesse status. |
| Reembolso negado | `status: "approved"` se a venda ainda não tem nota; `status: "completed"` se a nota já foi autorizada | Retoma o fluxo normal. |
| Reembolso efetuado | `status: "refunded"` | A Spedy cancela as notas autorizadas da venda. |
| Chargeback | `status: "chargeback"` | A Spedy cancela as notas autorizadas da venda. |
| Pedido cancelado | `status: "canceled"` | A Spedy cancela as notas autorizadas da venda. |

> [!WARNING]
>
> O cancelamento de uma nota autorizada segue as **regras e prazos fiscais**
> de cada modelo e município. Fora do prazo, a nota não pode mais ser
> cancelada pelo fisco, e o vendedor precisa tratar a devolução pelo caminho
> fiscal adequado. Veja [Cancelamento, correção e
> inutilização](https://docs.spedy.com.br/guides/cancelamento-correcao-inutilizacao.md).

Os status `refused` e `expired` **não cancelam** notas. Com
`autoIssueMode: "immediately"`, a nota é emitida na criação da venda e
continua válida mesmo que o pagamento seja recusado ou expire.

### A Spedy conclui a venda

Quando a nota é autorizada, a Spedy muda a venda para **`completed`**
automaticamente. A sua plataforma **não precisa enviar `completed`**. Depois
disso, a venda só aceita os status de reembolso, chargeback e cancelamento.

### Regras da mudança de status

A Spedy recusa algumas mudanças de status. Trate essas respostas de erro sem
retentar:

* **Mesmo status:** enviar o status que a venda já tem retorna `A venda já está
  com status desejado.` Pode ser tratado como sucesso (por exemplo, quando a
  sua plataforma reenvia um evento).
* **`completed` sem nota autorizada:** não é permitido. Para "pagamento
  aprovado", use sempre `approved`.
* **Voltar para `awaitingPayment` ou `approved` depois da nota autorizada:**
  não é permitido. Um `approved` que chegue atrasado, depois que a Spedy já
  concluiu a venda, é recusado — trate como sucesso.

Já o erro `A nota fiscal dessa venda está em processamento.` é temporário: a
nota está sendo transmitida ao fisco. Aguarde alguns segundos e reenvie a
mesma atualização.

### Corrigindo dados da venda

Para corrigir dados da venda antes da emissão (por exemplo, o endereço do
comprador), use `PUT /v1/orders/{id}`. Notas já autorizadas não são alteradas
por essa chamada.

> [!WARNING]
>
> O `PUT /v1/orders/{id}` **substitui a venda inteira**: envie o **payload
> completo**, com todos os campos e itens, e não só o que quer alterar. Um campo
> que fica de fora pode ser gravado vazio ou com o valor padrão, inclusive o
> `autoIssueMode` e o `warrantyDate`. Monte o corpo a partir da venda que você
> enviou na criação e altere apenas os campos necessários.

Para mudar só o status, use sempre `PUT /v1/orders/{id}/status`.

## Quando a nota é emitida

O campo `autoIssueMode`, enviado na criação da venda, define em que momento a
Spedy emite a nota:

| `autoIssueMode` | Quando a nota é emitida | Indicado para |
| - | - | - |
| `afterPayment` | Quando a venda chega a `approved` (ou já é criada aprovada). | **A maioria das plataformas e checkouts.** |
| `afterWarrency` | No dia seguinte ao fim da garantia (`warrantyDate`), se a venda continuar aprovada. | Produtos com prazo de reembolso, como infoprodutos. |
| `immediately` (padrão) | Assim que a venda é criada, **qualquer que seja o status**. | Plataformas que só enviam vendas já pagas. |
| `disabled` | Nunca automaticamente. A emissão é feita pelo vendedor no painel ou por `POST /v1/orders/{id}/invoices/issue`. | Vendedores que preferem revisar cada venda antes de emitir. |

> [!WARNING]
>
> **Sempre envie o `autoIssueMode`.** Se ele for omitido, a venda usa
> `immediately` e a nota é emitida na criação — mesmo que o pedido ainda esteja
> aguardando pagamento. Em plataformas que enviam o pedido antes do pagamento,
> use `afterPayment` ou `afterWarrency`.

O ideal é deixar o vendedor escolher o modo de emissão na tela de integração
da sua plataforma (por exemplo: "Emitir após o pagamento" ou "Emitir após a
garantia") e enviar a escolha em cada venda.

### Emissão após a garantia

Com `autoIssueMode: "afterWarrency"`, a nota só é emitida depois que o prazo
de reembolso termina. Isso evita emitir e depois ter de cancelar a nota de uma
venda que foi reembolsada durante a garantia.

Informe em `warrantyDate` o **último dia da garantia**. Por exemplo, para uma
garantia de 7 dias de uma venda aprovada em 05/11:

```json theme={null}
{
  "transactionId": "PED-2026-000124",
  "date": "2026-11-05T14:30:00-03:00",
  "status": "approved",
  "autoIssueMode": "afterWarrency",
  "warrantyDate": "2026-11-12",
  "...": "demais campos da venda"
}
```

Nesse caso:

1. A venda fica aprovada, sem nota, até o fim da garantia (12/11).
2. No dia seguinte (13/11), a Spedy emite a nota, com **data de competência
   13/11**.
3. Se, até lá, a venda mudar para `refundRequested`, `refunded`, `chargeback`
   ou for cancelada, a nota **não é emitida**. Se o reembolso for negado e a
   venda voltar para `approved`, a emissão segue para o dia seguinte ao fim da
   garantia.

> [!NOTE]
>
> A emissão após a garantia depende do `warrantyDate`. Sem ele, a nota da venda
> aprovada é emitida imediatamente, como no `afterPayment`.

> [!WARNING]
>
> A emissão automática após a garantia vale para **garantias de até 90 dias**,
> contados da aprovação da venda. Para prazos maiores, a nota é emitida pelo
> painel ou por `POST /v1/orders/{id}/invoices/issue`.

### Emissão manual e vendas de meses anteriores

A emissão automática acontece dentro do **mês de competência** da nota. Se a
venda chegar à Spedy depois da virada do mês (por exemplo, um pedido aprovado
em 31/10 enviado em 02/11), a nota não é emitida automaticamente — o vendedor
emite pelo painel, ou a plataforma dispara a emissão informando a data de
competência:

```bash cURL (sandbox) theme={null}
curl -X POST https://sandbox-api.spedy.com.br/v1/orders/{id}/invoices/issue \
  -H "X-Api-Key: sua-chave-de-sandbox" \
  -H "Content-Type: application/json" \
  -d '{ "effectiveDate": "2026-11-02" }'
```

Sem `effectiveDate`, a nota usa a data original da venda. A mesma chamada
serve para vendas com `autoIssueMode: "disabled"`.

## Acompanhando a nota

A plataforma não precisa acompanhar a nota para a integração funcionar. Se
quiser exibir a nota dentro da plataforma (por exemplo, o link do PDF na
página do pedido), há dois caminhos:

* **Consulta:** `GET /v1/orders/{id}` traz as notas da venda no campo
  `invoices`.
* **Webhook:** o evento `invoice.status_changed` envia a nota em `data`. Veja
  [Webhooks: visão geral](https://docs.spedy.com.br/webhooks/visao-geral.md).

### Ligando a nota ao pedido

Toda nota gerada a partir de uma venda traz o objeto **`order`**, com os dados
da venda de origem. Ele vem em `data.order` no payload do webhook e em `order`
no `GET` da nota:

```json theme={null}
{
  "id": "caaf34ab-6c65-4ca6-b6bf-b2d8f497c721",
  "event": "invoice.status_changed",
  "data": {
    "id": "833e8e0e-3bda-4394-ab70-5edf4ee70988",
    "status": "authorized",
    "order": {
      "id": "fa15d7af-991d-467d-961a-f564b76d771c",
      "date": "2026-11-05T14:30:00",
      "transactionId": "PED-2026-000123"
    },
    "...": "demais campos da nota"
  }
}
```

| Campo | Descrição |
| - | - |
| `data.order.id` | `id` da venda na Spedy — o mesmo devolvido pelo `POST /v1/orders`. |
| `data.order.transactionId` | O `transactionId` que a sua plataforma enviou ao criar a venda — o código do pedido. |
| `data.order.date` | Data da venda. |

Use `data.order.id` (ou `data.order.transactionId`) para localizar o pedido na
sua plataforma. O `transactionId` é único **por empresa**: se o vendedor tiver
mais de um CNPJ na mesma conta, combine-o com `data.company` para identificar
a empresa.

> [!WARNING]
>
> Webhooks são configurados **por conta**: um webhook criado com a chave do
> vendedor recebe as notas de **toda a conta dele**, inclusive as emitidas
> manualmente no painel ou vindas de outras integrações. **Descarte os eventos
> cujo `data.order` não corresponda a uma venda enviada pela sua plataforma**,
> e também os eventos sem `order`.

## Boas práticas

* **Um pedido, uma venda.** Use sempre o mesmo `transactionId` para o mesmo
  pedido.
* **Respeite a ordem dos eventos.** Atualize o status na ordem em que os
  eventos acontecem na sua plataforma, e só depois que a venda tiver sido
  criada.
* **Trate erros de validação como definitivos.** Respostas `4xx` com mensagem
  de validação não mudam com retentativa — registre e, se for o caso, mostre
  ao vendedor. Retente apenas falhas de rede, `429` e `5xx`. Veja [Erros e
  respostas](https://docs.spedy.com.br/start/erros-e-respostas.md) e [Rate limit](https://docs.spedy.com.br/start/rate-limit.md).
* **Envie os dados do comprador.** CPF/CNPJ, e-mail e endereço completos
  evitam rejeições, principalmente em NF-e e em municípios que exigem
  endereço do tomador.
* **Teste em sandbox.** Crie uma conta no [ambiente de
  testes](https://docs.spedy.com.br/start/ambiente-de-testes.md) e percorra todos os eventos da tabela
  acima antes de liberar a integração aos seus clientes.

## Sua plataforma dentro da Spedy

Quando a sua integração tiver **3 clientes ativos** emitindo pela Spedy, você
pode solicitar a inclusão do **App da sua plataforma** na Spedy. Com o App, os
vendedores encontram a sua plataforma na lista de integrações da Spedy e a
ativam a partir de lá.

Para solicitar, escreva para
[suporte@spedy.com.br](mailto:suporte@spedy.com.br) com o nome da plataforma e
os clientes que já usam a integração. A equipe da Spedy avalia a solicitação e
informa os próximos passos.

## Relacionado

* [Fluxo de emissão](https://docs.spedy.com.br/guides/fluxo-de-emissao.md)
* [Ciclo de vida da nota](https://docs.spedy.com.br/guides/ciclo-de-vida-da-nota.md)
* [Idempotência](https://docs.spedy.com.br/start/idempotencia.md)
* [Webhooks: visão geral](https://docs.spedy.com.br/webhooks/visao-geral.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.