Saltar para o conteúdo principal

Integração Payments

A integração Payments é uma API REST agnóstica de provedor para as operações financeiras essenciais que todo backoffice precisa:
  1. Emitir Invoice (cobrança)POST /payments/invoices. Uma Invoice aqui é uma cobrança — um pedido de pagamento coletado via PIX, boleto, cartão, ACH ou SEPA dependendo da região.
  2. Cancelar InvoicePOST /payments/invoices/{id}/cancel (anula cobrança não paga).
  3. Emitir documento fiscal (NFS-e/NF-e/PEPPOL)POST /payments/invoices/{id}/tax-documents. Opcional, específico por região (Brasil hoje, Europa depois). Pode também ser auto-emitido na criação da Invoice.
  4. Pagar beneficiário (prêmio ou qualquer payout)POST /payments/payouts.
  5. Ler o extrato bancárioGET /payments/balance-transactions.
Toda transação carrega campos de controle de primeira classe usados pelo seu time financeiro para reconciliação: cost_center (centro de custos) e contractor_reference (número do contratante) você envia no request; our_number (nosso número) é gerado pelo SalesOS e devolvido no response (e em todo lançamento do extrato). Por baixo, o SalesOS roteia a requisição para o provedor certo — você não precisa escolher provedor a menos que queira.
Cobrança ≠ documento fiscal. Uma Invoice é o pedido de pagamento (boleto, PIX, cartão). O documento fiscal (NFS-e no BR, PEPPOL na UE) é um recurso separado e opcional anexado à Invoice. Essa separação mantém a API portável entre BR / US / UE.
A API segue convenções de mercado: modelo REST por recurso, valores em unidades menores inteiras, timestamps ISO-8601, RFC 9457 Problem Details para erros, header Idempotency-Key para retry seguro, paginação por cursor e webhooks assinados. Se você já integrou com qualquer API moderna de pagamentos, vai se sentir em casa.

Roteamento por Região

O SalesOS escolhe o backend correto automaticamente a partir de customer.country e currency. Você não precisa escolher.
País do clienteMoedaStatusMétodos
BRBRLativopix, boleto, bolepix, card (card-as-PIX)
USUSDem brevecard, ach_debit, bank_transfer
Estados-membros UEEUR / localem brevecard, sepa_debit, bank_transfer
RegiãoTipo de documento fiscalStatus
BRnfse (serviços)ativo
BRnfe (produtos)em breve
UEpeppol (e-invoice)em breve
USn/asales tax via metadata da Invoice; sem documento fiscal
Payouts roteiam pelo destino: BRL → PIX cashout; demais moedas → transferência internacional.

Como Funciona

  1. Você obtém uma Chave de API no Dashboard do SalesOS (Admin > Integrações > Chaves de API) com os escopos corretos (payments:write, payments:read).
  2. Você emite Invoices (cobranças). O SalesOS cria o pedido de pagamento na região do cliente (BR ativo; US/UE em breve). Você recebe um artefato pagável: QR-code/copia-e-cola PIX, código de barras de boleto, URL de checkout de cartão.
  3. (Opcional) Um documento fiscal é anexado. Quando currency = BRL e tax_document.auto_issue: true, o SalesOS emite uma NFS-e automaticamente após a cobrança ser confirmada como paga. Você também pode chamar POST /invoices/{id}/tax-documents mais tarde para emitir ou tentar de novo.
  4. Você paga beneficiários (colaboradores, parceiros, ganhadores de prêmios). O SalesOS roteia BRL via PIX e demais moedas via transferência internacional.
  5. Você lê um extrato unificado — toda cobrança, payout, taxa e fee de documento fiscal em um único livro-razão, filtrável por cost_center, our_number, contractor_reference, período e provedor.
  6. Você escuta webhooks para eventos terminais (invoice.paid, invoice.canceled, tax_document.issued, payout.paid, …) em vez de fazer polling.

Início Rápido

1

Obtenha sua Chave de API

Vá até Admin > Integrações > Chaves de API no Dashboard do SalesOS. Crie uma nova chave com os escopos payments:write e payments:read. Copie a chave — ela só será exibida uma vez.Sua chave terá este formato: sk_live_a1b2c3d4e5f6g7h8i9j0...
2

Emita sua primeira Invoice (BR — cobrança PIX com NFS-e automática)

Crie uma cobrança PIX para um cliente brasileiro. O bloco opcional tax_document instrui o SalesOS a emitir a NFS-e automaticamente após a cobrança ser paga.
curl -X POST https://api.play2sell.com/functions/v1/payments/invoices \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: inv-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "country": "BR",
      "tax_id": "12345678000190",
      "name": "Acme Corp Ltda",
      "email": "billing@acme.com.br"
    },
    "amount": 12345,
    "currency": "BRL",
    "description": "Consultoria — Abril/2026",
    "payment_method": { "type": "pix", "expires_in_seconds": 3600 },
    "tax_document": {
      "auto_issue": true,
      "type": "nfse",
      "service_code": "01.05"
    },
    "cost_center": "CC-OPERATIONS",
    "contractor_reference": "PO-9981",
    "metadata": { "campaign": "spring-2026", "owner_user_id": "usr-7782" }
  }'
Resposta (201 Created):
{
  "id": "inv_01HW1Z3K8C7G6Y9PQ4M5R2X0NA",
  "status": "open",
  "amount": 12345,
  "currency": "BRL",
  "region": "br",
  "payment_method": {
    "type": "pix",
    "pix": {
      "qr_code": "00020126580014br.gov.bcb.pix...",
      "qr_code_image_url": "https://api.play2sell.com/.../qr.png",
      "expires_at": "2026-04-27T15:00:00Z"
    }
  },
  "tax_document": {
    "id": "txd_01HW1Z3K8C7G6Y9PQ4M5R2X0NX",
    "type": "nfse",
    "status": "pending",
    "auto_issue": true
  },
  "cost_center": "CC-OPERATIONS",
  "our_number": "INV-2026-000123",
  "contractor_reference": "PO-9981",
  "metadata": { "campaign": "spring-2026", "owner_user_id": "usr-7782" },
  "created": "2026-04-27T14:00:00Z"
}
Status passa por openpaid (na confirmação PIX, ~segundos) → tax_document.status: issued (emissão da NFS-e, segundos a minutos). Escute os webhooks invoice.paid e tax_document.issued em vez de fazer polling.
3

(Opcional) Emita uma Invoice para cliente US (em breve)

Para clientes US/UE o SalesOS roteia a cobrança para o backend internacional. Esse caminho está aguardando o onboarding da Play2Sell LLC — chamadas hoje retornam 501 provider_not_configured.
curl -X POST https://api.play2sell.com/functions/v1/payments/invoices \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: inv-us-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "country": "US",
      "name": "Acme Inc",
      "email": "billing@acme.com"
    },
    "amount": 12345,
    "currency": "USD",
    "description": "Consulting services — April/2026",
    "payment_method": { "type": "card" },
    "cost_center": "CC-OPERATIONS",
    "contractor_reference": "PO-9981"
  }'
Sem bloco tax_document — US não possui documento fiscal nacional. Sales tax vai dentro de metadata ou de futuros line_items. O SSN do cliente não é coletado neste endpoint: cobranças B2C/B2B regulares nos EUA não exigem. Tratamento de SSN/EIN para reporting 1099 (quando você paga contractors US) é fluxo separado em Payouts, não em Invoices.
4

Pague um beneficiário

Pague um ganhador de prêmio via PIX (BRL — roteamento automático):
curl -X POST https://api.play2sell.com/functions/v1/payments/payouts \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: payout-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{
    "beneficiary": {
      "name": "Maria Santos",
      "document": "12345678901",
      "phone": "+5511999000111",
      "email": "maria@example.com",
      "bank_account": { "type": "pix", "key_type": "cpf", "key": "12345678901" }
    },
    "amount": 50000,
    "currency": "BRL",
    "purpose": "prize",
    "cost_center": "CC-AWARDS",
    "contractor_reference": "EVENT-Q2-WINNER-12",
    "metadata": { "event_id": "evt-2026-q2", "user_id": "usr-1101" }
  }'
Resposta (201 Created):
{
  "id": "po_01HW1Z9P7B5F2X8KQ4M5R2X0NB",
  "status": "processing",
  "amount": 50000,
  "currency": "BRL",
  "region": "br",
  "cost_center": "CC-AWARDS",
  "our_number": "PO-2026-000045",
  "contractor_reference": "EVENT-Q2-WINNER-12",
  "created": "2026-04-27T14:05:00Z"
}
Você receberá um webhook payout.paid em segundos no sandbox ou em menos de um minuto em produção (PIX).
5

Leia seu extrato

Liste todos os lançamentos com cost_center=CC-AWARDS no mês:
curl -X GET "https://api.play2sell.com/functions/v1/payments/balance-transactions?cost_center=CC-AWARDS&created[gte]=2026-04-01&created[lte]=2026-04-30&limit=50" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Resposta (200 OK):
{
  "data": [
    {
      "id": "btxn_01HW1Z9P7B5F2X8KQ4M5R2X0NC",
      "type": "payout",
      "amount": -50000,
      "currency": "BRL",
      "net": -50100,
      "fee": 100,
      "available_on": "2026-04-27",
      "created": "2026-04-27T14:05:30Z",
      "source": { "resource": "payout", "id": "po_01HW1Z9P7B5F2X8KQ4M5R2X0NB" },
      "cost_center": "CC-AWARDS",
      "our_number": "PO-2026-000045",
      "contractor_reference": "EVENT-Q2-WINNER-12"
    }
  ],
  "has_more": false
}

Autenticação

Todas as requisições exigem uma Chave de API no header Authorization:
Authorization: Bearer sk_live_YOUR_API_KEY
Consulte a página de Autenticação para detalhes sobre como criar e gerenciar Chaves de API.
PropriedadeDetalhes
HeaderAuthorization: Bearer sk_live_xxx
Escopospayments:write (criar/cancelar), payments:read (listar/consultar)
Limite de requisiçõesConfigurável por chave (padrão: 1000 requisições/hora)
Formato da chavesk_live_ (produção) ou sk_test_ (teste)

Ambientes

URL Base: https://api.play2sell.comDashboard: https://dashboard.play2sell.com

Referência de Endpoints

Path base: /functions/v1/payments. Todos os endpoints aceitam e retornam JSON.

Invoices (Cobranças)

Uma Invoice é uma cobrança — um pedido de pagamento que será coletado do seu cliente via PIX, boleto, cartão ou outro método dependendo da região. A Invoice não inclui um documento fiscal por padrão; veja Tax Documents abaixo.

POST /functions/v1/payments/invoices — criar uma cobrança

customer
object
obrigatório
Cliente que será cobrado.
customer.country
string
obrigatório
ISO-3166-1 alpha-2 (BR, US, DE, …). Decide o roteamento de provedor.
customer.tax_id
string
CPF (11 dígitos) ou CNPJ (14 dígitos) para BR (obrigatório quando tax_document está presente). Para cobranças US/UE este campo não é obrigatório — deixe de fora a menos que seu fluxo contábil precise. SSN/EIN não são coletados aqui em cobranças normais.
customer.name
string
obrigatório
Razão social ou nome completo (max 255 caracteres).
customer.email
string
obrigatório
Email válido — usado para recibos e (quando aplicável) entrega do documento fiscal.
amount
integer
obrigatório
Valor total em unidades menores (ex: 12345 = R$ 123,45). Deve ser positivo.
currency
string
obrigatório
Código ISO-4217. Decide o roteamento de provedor junto com customer.country.
description
string
obrigatório
Descrição que aparece no artefato de pagamento e (quando emitido) na discriminação do documento fiscal (max 1000 caracteres).
O campo description é exibido ao pagador. Em cobranças PIX aparece no app bancário/carteira do pagador junto ao QR-code; em boleto vai impresso no documento; em NFS-e entra na discriminação do serviço. Escolha um valor que faça sentido nos três contextos (ex: "Consultoria — Abril/2026", não "INV-2026-000123 linha-billing-interna").
payment_method
object
obrigatório
Como a cobrança será coletada.
payment_method.type
string
obrigatório
Um de pix, boleto, bolepix, card (BR); card, ach_debit, bank_transfer (US — em breve); card, sepa_debit, bank_transfer (UE — em breve).
payment_method.expires_in_seconds
integer
Para pix / boleto / bolepix: por quanto tempo o artefato de pagamento permanece válido. Padrão 3600 (PIX) / 3 dias (boleto).
payment_method.return_url
string
Para card: para onde redirecionar o cliente após o checkout do cartão.
tax_document
object
Opcional. Quando presente, o SalesOS emitirá um documento fiscal automaticamente após a cobrança ser paga. Hoje apenas BR.
tax_document.auto_issue
boolean
Quando true, o documento fiscal é emitido no momento em que a cobrança transita para paid. Quando false (ou ausente), use POST /v1/invoices/{id}/tax-documents mais tarde.
tax_document.type
string
"nfse" (serviços BR — ativo), "nfe" (produtos BR — em breve), "peppol" (UE — em breve).
tax_document.service_code
string
Código municipal de serviço, obrigatório quando type="nfse" (ex: "01.05" para consultoria em SP).
cost_center
string
obrigatório
Código do centro de custos interno (max 64 caracteres). Veja Campos de Controle Comuns.
contractor_reference
string
Número do contratante — referência externa do cliente/contrato (max 64 caracteres).
metadata
object
Pares chave-valor livres (max 50 chaves, valor max 500 caracteres).
our_number (nosso número) não vai no request — o SalesOS gera no momento da emissão e devolve no response (formato: INV-<AAAA>-<sequência>). Armazene para reconciliação.

GET /functions/v1/payments/invoices/{id} — consultar

curl -X GET https://api.play2sell.com/functions/v1/payments/invoices/inv_01HW1Z3K8C7G6Y9PQ4M5R2X0NA \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
A resposta sempre inclui o artefato corrente de payment_method (QR PIX, código de barras de boleto, URL de checkout de cartão) e o resumo inline de tax_document quando presente.

GET /functions/v1/payments/invoices — listar

Filtros: status (open|paid|canceled|failed), payment_method.type, cost_center, our_number, contractor_reference, created[gte], created[lte]. Paginação por cursor via limit (≤ 100), starting_after, ending_before.
curl -X GET "https://api.play2sell.com/functions/v1/payments/invoices?status=paid&cost_center=CC-OPERATIONS&limit=50" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

POST /functions/v1/payments/invoices/{id}/cancel — anular cobrança não paga

curl -X POST https://api.play2sell.com/functions/v1/payments/invoices/inv_01HW1Z3K8C7G6Y9PQ4M5R2X0NA/cancel \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: cancel-inv-001" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "customer_request" }'
Se a Invoice tiver um tax_document anexado já em estado issued, o cancelamento é cascateado para o documento fiscal quando o município ainda está dentro da janela de cancelamento. Caso contrário, retorna cancellation_window_expired.
Estorno de cobrança paga não está exposto na v1. Se você precisa reverter um pagamento já liquidado, fale com o suporte — o time pode processar manualmente. Uma versão futura da API pode expor um fluxo de estorno programático conforme os casos de uso amadurecerem.

Tax Documents (Documentos Fiscais)

Um TaxDocument é o artefato fiscal anexado a uma Invoice — hoje NFS-e (serviços BR). Tem ciclo de vida próprio e pode ser emitido, consultado ou cancelado independentemente da cobrança subjacente. Use este recurso quando você optou por não usar auto_issue na criação da Invoice, quando uma tentativa de auto-emissão falhou e você quer retentar, ou quando precisa cancelar apenas o documento fiscal.

POST /functions/v1/payments/invoices/{id}/tax-documents — emitir/retentar

type
string
obrigatório
"nfse" hoje. Futuro: "nfe", "peppol".
service_code
string
Obrigatório quando type="nfse".
metadata
object
Metadata livre opcional, persistido no documento.
curl -X POST https://api.play2sell.com/functions/v1/payments/invoices/inv_01HW1Z3K8C7G6Y9PQ4M5R2X0NA/tax-documents \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: txd-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{ "type": "nfse", "service_code": "01.05" }'
Resposta (202 Accepted):
{
  "id": "txd_01HW1Z3K8C7G6Y9PQ4M5R2X0NX",
  "invoice_id": "inv_01HW1Z3K8C7G6Y9PQ4M5R2X0NA",
  "type": "nfse",
  "status": "pending",
  "created": "2026-04-27T14:10:00Z"
}
A emissão é assíncrona. Escute os webhooks tax_document.issued (ou tax_document.failed). Em sucesso o documento traz document_number, xml_url, pdf_url e issued_at.

GET /functions/v1/payments/invoices/{id}/tax-documents/{doc_id} — consultar

POST /functions/v1/payments/invoices/{id}/tax-documents/{doc_id}/cancel — cancelar

curl -X POST "https://api.play2sell.com/functions/v1/payments/invoices/inv_.../tax-documents/txd_.../cancel" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: cancel-txd-001" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "billing_correction" }'
Sujeito à janela de cancelamento do município (tipicamente o dia da emissão para NFS-e). cancellation_window_expired é retornado quando fora da janela.

Payouts (Pagamentos a Beneficiários)

POST /functions/v1/payments/payouts — pagar beneficiário

Roteamento automático: currency = "BRL" → PIX cashout; demais moedas → transferência internacional.
beneficiary
object
obrigatório
Destinatário do pagamento.
beneficiary.name
string
obrigatório
Nome completo ou razão social (max 255 caracteres).
beneficiary.document
string
obrigatório
Documento de identificação fiscal do beneficiário. CPF (11 dígitos) ou CNPJ (14 dígitos) para BR; passaporte ou identificador fiscal local para internacional. Obrigatório.
beneficiary.phone
string
obrigatório
Telefone em formato E.164 (ex: "+5511999000111"). Obrigatório — usado para AML/KYC e notificações de status do payout.
beneficiary.email
string
Email opcional. Quando informado, recibos do payout são enviados para este endereço.
beneficiary.bank_account
object
obrigatório
Conta destino. Para PIX, use type: "pix" com key_type (cpf|cnpj|email|phone|evp) e key. Para internacional, use type: "bank_transfer" com country, iban ou account_number + routing_number conforme exigências bancárias do país de destino.
amount
integer
obrigatório
Valor em unidades menores. Deve ser positivo.
currency
string
obrigatório
ISO-4217. Determina o roteamento de provedor.
purpose
string
obrigatório
Um de "prize", "commission", "vendor_payment", "other".
cost_center
string
obrigatório
Código do centro de custos (max 64 caracteres).
contractor_reference
string
Número do contratante — referência externa (max 64 caracteres).
metadata
object
Pares chave-valor livres (max 50 chaves, valor max 500 caracteres).
our_number (nosso número) não vai no request — o SalesOS gera no momento da emissão e devolve no response (formato: PO-<AAAA>-<sequência>). Armazene para reconciliação.

GET /functions/v1/payments/payouts/{id} — consultar

GET /functions/v1/payments/payouts — listar

Filtros: status, provider, cost_center, our_number, contractor_reference, created[gte], created[lte]. Paginação por cursor.

POST /functions/v1/payments/payouts/{id}/cancel — cancelar

Disponível apenas para transferências internacionais nos estados created / incoming_payment_waiting. PIX é síncrono e final — uma vez aceito, não é cancelável; emita um payout no sentido oposto para compensar.

Balance Transactions (Extrato Bancário)

Livro-razão unificado entre provedores. Somente leitura.

GET /functions/v1/payments/balance-transactions — listar

Filtros:
FiltroValores
accountomie, rinne, wise
typecharge, payout, fee, adjustment
cost_centerqualquer string
our_numberqualquer string
contractor_referencequalquer string
currencycódigo ISO-4217
created[gte] / created[lte]timestamps ISO-8601
curl -X GET "https://api.play2sell.com/functions/v1/payments/balance-transactions?type=payout&created[gte]=2026-04-01&limit=100" \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

GET /functions/v1/payments/balance-transactions/{id} — consultar

Cada lançamento expõe:
id
string
ID estável do lançamento (btxn_...).
type
string
charge | payout | fee | adjustment.
amount
integer
Valor em unidades menores, com sinal. Negativo = saída, positivo = entrada.
currency
string
ISO-4217.
net
integer
amount - fee para saídas; amount para entradas.
fee
integer
Taxa do provedor em unidades menores, sempre positiva.
available_on
string
Data ISO-8601 de liquidação dos fundos.
created
string
Timestamp ISO-8601 do lançamento.
source
object
{ resource, id } — aponta para a nota/payout de origem.
cost_center
string
Herdado do recurso de origem.
our_number
string
Herdado do recurso de origem.
contractor_reference
string
Herdado do recurso de origem.

Campos de Controle Comuns

Toda Invoice, Payout e Balance Transaction carrega os mesmos campos de controle. Eles fazem round-trip em GET e são filtráveis em LIST.
CampoDireçãoFormatoMaxIndexadoUso
cost_centerinput (obrigatório)string, FK para sua tabela de centros de custo64simClassifica toda transação numa linha de orçamento.
contractor_referenceinput (opcional)string64simNúmero do contratante — referência externa do cliente/contrato (PO, ID de contrato, ID de evento).
metadatainput (opcional)Record<string, string>50 chaves, valor 500 caracteresnãoLivre. Use com moderação; não é pesquisável.
our_numbersomente outputstring, formato <PREFIXO>-<AAAA>-<sequência>64simNosso número — gerado pelo SalesOS na emissão e devolvido no response. Distinto de id (ULID para uso na API). Estável, sequencial por tipo de recurso por tenant. Use como chave de reconciliação no lado bancário.
Por que our_number é gerado no servidor. No banking brasileiro o cedente atribui o “nosso número” — mas nesta API o SalesOS é o gateway de emissão, então é o SalesOS que atribui o valor e devolve. Se você precisar carregar um identificador interno seu, use contractor_reference (top-level, indexado) ou metadata.* (livre).

Idempotência

Todos os endpoints POST exigem o header Idempotency-Key — uma string única à sua escolha (max 255 caracteres; recomendamos UUIDv4 ou uma chave determinística baseada no seu domínio).
  • A primeira chamada com a chave processa normalmente e a resposta é armazenada por 24 h.
  • Replays com a mesma chave e o mesmo body retornam a mesma resposta, com header Idempotent-Replay: true.
  • Replays com a mesma chave mas body diferente retornam 409 idempotency_key_reused.
# Primeira chamada — processa
curl -X POST https://api.play2sell.com/functions/v1/payments/invoices \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: inv-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 12345, "currency": "BRL", "payment_method": { "type": "pix" }, "...": "..." }'

# Segunda chamada (retry de rede) — retorna mesma resposta, sem duplicação
curl -X POST https://api.play2sell.com/functions/v1/payments/invoices \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Idempotency-Key: inv-2026-04-27-001" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 12345, "currency": "BRL", "payment_method": { "type": "pix" }, "...": "..." }'

Valores e Moeda

Valores são inteiros em unidades menores para evitar erros de ponto flutuante:
MoedaUnidade menor12345 significa
BRLcentavoR$ 123,45
USDcentUS$ 123.45
EURcent€123,45
Moedas seguem ISO-4217 (3 letras maiúsculas). Sempre pareie amount com currency. Rejeite no servidor qualquer payload que misture escalas (ex: enviar decimais).

Tratamento de Erros

Todos os erros seguem RFC 9457 Problem Details:
{
  "type": "https://docs.play2sell.com/errors/validation_error",
  "title": "Invalid request",
  "status": 422,
  "detail": "amount must be a positive integer",
  "instance": "req_01HW1Z3K8C7G6Y9PQ4M5R2X0NA",
  "code": "validation_error",
  "errors": [
    { "field": "amount", "message": "must be a positive integer" }
  ]
}
JSON malformado ou headers obrigatórios ausentes. Corrija a requisição e reenvie.
Chave de API ausente, inválida ou expirada. Verifique o header Authorization. Gere uma nova chave se expirada.
Chave válida mas sem o escopo necessário (payments:write ou payments:read). Edite a chave no Dashboard.
O ID do recurso não existe ou pertence a outro tenant.
Mesma Idempotency-Key usada com body diferente. Use uma chave nova ou envie o body original.
Validação do body falhou. O array errors[] lista os problemas a nível de campo.
Muitas requisições. O header Retry-After indica quantos segundos aguardar.
O backend downstream retornou erro. O campo detail contém uma mensagem sanitizada. Reenvie com a mesma Idempotency-Key.
Erro interno. Reenvie com backoff exponencial (2s, 4s, 8s). Contate o suporte se persistir.

Webhooks

Configure um endpoint de webhook por ambiente em Admin > Integrações > Webhooks. O SalesOS fará POST com JSON assinado para todo evento terminal:
EventoRecursoDisparado quando
invoice.paidinvoiceCobrança confirmada paga pelo provedor
invoice.canceledinvoiceCobrança não paga anulada
invoice.failedinvoiceCobrança falhou definitivamente (ex: cartão recusado, boleto expirado)
tax_document.issuedtax_documentDocumento fiscal aceito pelo município
tax_document.canceledtax_documentCancelamento do documento fiscal aceito
tax_document.failedtax_documentEmissão falhou definitivamente
payout.paidpayoutFundos confirmadamente entregues
payout.failedpayoutProvedor rejeitou a transferência
payout.canceledpayoutCancelamento aceito (apenas transferências internacionais)
Cada requisição inclui:
  • X-Pay-Event — tipo do evento (ex: payout.paid).
  • X-Pay-Signaturet=<unix>,v1=<hex-hmac-sha256>. Verifique com o segredo configurado no Dashboard.
  • X-Pay-Delivery — ID único de entrega, útil para deduplicação.
Verificação de assinatura (Node.js):
import crypto from 'node:crypto';

function verifyWebhook(rawBody, signatureHeader, secret) {
  const parts = Object.fromEntries(
    signatureHeader.split(',').map(kv => kv.split('=')),
  );
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');
  const ok = crypto.timingSafeEqual(
    Buffer.from(parts.v1, 'hex'),
    Buffer.from(expected, 'hex'),
  );
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; // 5 min
  return ok && fresh;
}
Payload de exemplo:
{
  "id": "evt_01HW1Z9P7B5F2X8KQ4M5R2X0ND",
  "type": "payout.paid",
  "created": "2026-04-27T14:05:30Z",
  "data": {
    "id": "po_01HW1Z9P7B5F2X8KQ4M5R2X0NB",
    "status": "paid",
    "amount": 50000,
    "currency": "BRL",
    "cost_center": "CC-AWARDS",
    "our_number": "PO-2026-000045",
    "contractor_reference": "EVENT-Q2-WINNER-12"
  }
}

Exemplos Completos de Código

export SALESOS_KEY="sk_live_YOUR_API_KEY"
export SALESOS_URL="https://api.play2sell.com/functions/v1/payments"

# 1. Issue an invoice (BR PIX charge with auto NFS-e)
curl -s -X POST "$SALESOS_URL/invoices" \
  -H "Authorization: Bearer $SALESOS_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": { "country": "BR", "tax_id": "12345678000190", "name": "Acme Corp", "email": "billing@acme.com" },
    "amount": 12345, "currency": "BRL",
    "description": "Consulting — April/2026",
    "payment_method": { "type": "pix", "expires_in_seconds": 3600 },
    "tax_document": { "auto_issue": true, "type": "nfse", "service_code": "01.05" },
    "cost_center": "CC-OPERATIONS", "contractor_reference": "PO-9981"
  }' | jq .

# 2. Pay a prize via PIX
curl -s -X POST "$SALESOS_URL/payouts" \
  -H "Authorization: Bearer $SALESOS_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "beneficiary": {
      "name": "Maria Santos", "document": "12345678901", "phone": "+5511999000111", "email": "maria@example.com",
      "bank_account": { "type": "pix", "key_type": "cpf", "key": "12345678901" }
    },
    "amount": 50000, "currency": "BRL", "purpose": "prize",
    "cost_center": "CC-AWARDS", "contractor_reference": "EVENT-Q2-WINNER-12"
  }' | jq .

# 3. Read the statement for the cost center
curl -s -X GET "$SALESOS_URL/balance-transactions?cost_center=CC-AWARDS&created[gte]=2026-04-01&limit=100" \
  -H "Authorization: Bearer $SALESOS_KEY" | jq .

Boas Práticas

Higiene de centros de custo

Escolha um conjunto pequeno e estável de códigos (≤ 50). Documente no wiki do financeiro. Rejeite no servidor chamadas que referenciem código desconhecido — falhar alto é melhor que classificar errado em silêncio.

Use as duas chaves juntas para reconciliação

  • our_number (gerado pelo servidor) é sua chave bancária — impressa no boleto / enviada ao provedor, presente no arquivo do extrato bancário.
  • contractor_reference (você fornece) é sua chave de contrato — o PO, ID do contrato com fornecedor ou ID do evento referente; presente no seu ERP.
Cruzar as duas no fechamento mensal entrega reconciliação de 1 clique entre o banco, a API Payments do SalesOS e seu ERP.

Roteamento por região

O SalesOS roteia automaticamente por customer.country e currency. Você não precisa escolher backend; confie no roteamento.

Confiabilidade dos webhooks

Trate webhooks como fonte de verdade para status terminal. Polling funciona mas consome rate limit. Sempre verifique X-Pay-Signature e dedupe por X-Pay-Delivery.

Tratamento de falhas

  • 422: corrija os dados e reenvie com Idempotency-Key nova.
  • 429: aguarde conforme Retry-After.
  • 502 (provider_error): reenvie com a mesma Idempotency-Key — a requisição original não foi commit, então retry é seguro.
  • 5xx: backoff exponencial (2s, 4s, 8s). Contate o suporte se persistir.

Limites de Requisições

Cada chave de API possui um limite configurável (padrão: 1000 requisições por hora). O contador reinicia a cada hora.
LimiteValor
Requisições por hora (padrão)1000
Tamanho máximo do payload1 MB
Tamanho máximo de página em listas100
Timeout por requisição60 segundos
Respostas com rate limit incluem o header Retry-After (segundos).

Segurança

  • Chaves de API são hasheadas com bcrypt — nunca armazenadas em texto puro.
  • Cada chave é restrita a um único tenant — sem acesso entre tenants.
  • Listas de IPs permitidos podem ser configuradas por chave.
  • Todas as requisições são registradas em log para auditoria (imutável, retenção de 7 anos).
  • As chaves podem ser revogadas instantaneamente pelo Dashboard.
Nunca exponha sua chave de API em código client-side (JavaScript no navegador, apps mobile ou repositórios públicos). A API Payments deve ser chamada apenas do seu servidor backend.

Próximos Passos

Autenticação

Saiba como criar e gerenciar Chaves de API

Integração Activities

Envie atividades do CRM para o SalesOS

Suporte

Precisa de ajuda? Entre em contato com nosso time de suporte