Pular para o conteúdo principal

Sipru — API de parceiros ERP (1.0.0)

Download OpenAPI specification:Download

Handoff SSO, canal ao vivo e push de produto para a tela do vendedor.

Contrato server-to-server entre o ERP parceiro e o Sipru. Cobre os dois modos de integração hoje em produção:

  • Handoff SSO (POST /api/erp/sso/session): o ERP pede uma URL de entrada e o vendedor "sai" do ERP já logado na conta Sipru real dele, com a cotação e o cliente anexados ao contexto.
  • Canal ao vivo (POST /api/erp/channel): além do handoff, abre um canal em que o ERP empurra produtos para a tela que o vendedor está olhando (POST /api/erp/channel/{channelId}/product).

O caminho de volta — o Sipru avisando o ERP que um item entrou no carrinho — está descrito em webhooks, e é implementado pelo parceiro.

Autenticação. Toda rota exige as duas credenciais juntas: X-Sipru-Partner-Id: <id do parceiro> e Authorization: Bearer <segredo do parceiro>. O segredo é emitido em /integracoes/erp-sso e guardado apenas como hash — ele é exibido uma única vez, na emissão ou na rotação.

environment é sandbox por padrão. Esse campo decide qual banco do ERP recebe a gravação do pedido, e apenas o literal "prd" seleciona a base real. Qualquer outro valor, incluindo o campo ausente, cai no sandbox — deliberadamente, para que um campo esquecido nunca escreva na base de produção do parceiro.

Handoff SSO

Entrada do vendedor no catálogo Sipru a partir de uma cotação do ERP.

Emite a URL de entrada do vendedor

Devolve uma URL de uso único, válida por ERP_SSO_TOKEN_TTL_SEC (600 s por padrão). A URL funciona exatamente uma vez: um segundo clique ou um reload da mesma URL responde ERP_SSO_TOKEN_ALREADY_USED. Para testar de novo, gere uma URL nova — esse comportamento é a proteção contra replay, não um defeito.

Authorizations:
(partnerIdpartnerSecret)
Request Body schema: application/json
required
tempQuoteId
required
string <= 120 characters

Identificador da cotação em aberto no ERP. É a chave de idempotência da gravação do pedido — uma gravação por cotação.

quoteId
string <= 120 characters

Número definitivo da cotação/orçamento, quando já existe.

required
object
object (Cliente)

Cliente da cotação. Todos os campos são opcionais.

companyId
string <= 120 characters

Tenant no Sipru. Opcional: se omitido, locationId é tratado como o CNPJ da loja e o Sipru resolve companyId e o locationId real pelo catálogo de lojas.

locationId
required
string <= 120 characters

Loja. Com companyId presente, é o identificador da loja no tenant; sem ele, é o CNPJ da loja (string opaca, aceita caracteres não numéricos).

pricingPolicy
string (PricingPolicy)
Enum: "margem1" "margem2" "margem3" "margem4"

Faixa de margem aplicada aos preços exibidos. Valor desconhecido ou ausente cai em margem1.

environment
string (Environment)
Enum: "dev" "prd"

Banco do ERP que recebe a gravação do pedido. Só o literal "prd" seleciona a base real; qualquer outro valor, ou o campo ausente, significa sandbox.

redirectPath
string

Caminho interno para onde mandar o vendedor depois do login. Precisa começar com / e não pode começar com // — qualquer outro valor é ignorado.

Responses

Request samples

Content type
application/json
{
  • "tempQuoteId": "TMP-90321",
  • "quoteId": "ORC-2026-1187",
  • "vendedor": {
    },
  • "cliente": {
    },
  • "locationId": "07526557000100",
  • "pricingPolicy": "margem2",
  • "environment": "dev"
}

Response samples

Content type
application/json
{
  • "expiresAt": "2019-08-24T14:15:22Z",
  • "contextId": "84451116-c600-49e2-9c60-5b6b34fae0d6"
}

Canal ao vivo

Canal por cotação em que o ERP empurra produtos para a tela do vendedor.

Abre um canal ao vivo para a cotação

Faz tudo o que /api/erp/sso/session faz e ainda cria um canal identificado por channelId, com os endpoints para o ERP empurrar produtos e para a tela do vendedor consumir os eventos.

Se cartCallbackUrl for informado, ele tem precedência sobre a configuração de loja em /integracoes/cart-erp para o webhook de item adicionado (ver webhooks).

Authorizations:
(partnerIdpartnerSecret)
Request Body schema: application/json
required
tempQuoteId
required
string <= 120 characters

Identificador da cotação em aberto no ERP. É a chave de idempotência da gravação do pedido — uma gravação por cotação.

quoteId
string <= 120 characters

Número definitivo da cotação/orçamento, quando já existe.

required
object
object (Cliente)

Cliente da cotação. Todos os campos são opcionais.

companyId
string <= 120 characters

Tenant no Sipru. Opcional: se omitido, locationId é tratado como o CNPJ da loja e o Sipru resolve companyId e o locationId real pelo catálogo de lojas.

locationId
required
string <= 120 characters

Loja. Com companyId presente, é o identificador da loja no tenant; sem ele, é o CNPJ da loja (string opaca, aceita caracteres não numéricos).

pricingPolicy
string (PricingPolicy)
Enum: "margem1" "margem2" "margem3" "margem4"

Faixa de margem aplicada aos preços exibidos. Valor desconhecido ou ausente cai em margem1.

environment
string (Environment)
Enum: "dev" "prd"

Banco do ERP que recebe a gravação do pedido. Só o literal "prd" seleciona a base real; qualquer outro valor, ou o campo ausente, significa sandbox.

cartCallbackUrl
string <uri> <= 500 characters

Endpoint do parceiro que recebe o webhook cart_item_added desta cotação. Precisa ser HTTPS em produção (HTTP é aceito apenas em DEV, para apontar para host interno na homologação).

object

Credencial estática do callback. OAuth não é suportado aqui.

ttlSec
integer [ 1 .. 86400 ]

Validade do canal em segundos. Valores acima de 86400 são truncados; valor inválido cai no padrão do servidor.

Responses

Request samples

Content type
application/json
{
  • "tempQuoteId": "TMP-90321",
  • "vendedor": {
    },
  • "locationId": "07526557000100",
  • "pricingPolicy": "margem1",
  • "environment": "dev",
  • "cartCallbackAuth": {
    },
  • "ttlSec": 14400
}

Response samples

Content type
application/json
{
  • "channelId": "5f6d08bc-455a-4532-98b8-19e2cee51160",
  • "contextId": "84451116-c600-49e2-9c60-5b6b34fae0d6",
  • "expiresAt": "2019-08-24T14:15:22Z",
  • "channelExpiresAt": "2019-08-24T14:15:22Z",
  • "endpoints": {}
}

Empurra um produto para a tela do vendedor

Resolve o termo no catálogo da loja do canal — com o tenant e a política de preço do próprio canal — e publica o resultado na tela que o vendedor está olhando, junto com substitutos, cross-sell e upsell.

A precedência do termo é productCodeeanquery, porque o código do parceiro é o mais determinístico e o texto livre é o último recurso (cobre o caso de o código não existir no catálogo Sipru).

Authorizations:
(partnerIdpartnerSecret)
path Parameters
channelId
required
string <uuid>

O channelId devolvido por POST /api/erp/channel.

Request Body schema: application/json
required
Any of
productCode
required
string <= 120 characters

Código do produto no ERP do parceiro.

ean
string <= 60 characters
query
string <= 120 characters

Texto livre.

quantity
integer [ 1 .. 9999 ]
Default: 1

Valor inválido ou ausente vira 1; acima de 9999 é truncado.

Responses

Request samples

Content type
application/json
Example
{
  • "productCode": "72411",
  • "quantity": 4
}

Response samples

Content type
application/json
{
  • "seq": 0,
  • "product": {
    },
  • "recommendations": {
    }
}

(parceiro implementa) Item adicionado ao carrinho Webhook

Quando o vendedor clica em "adicionar" na tela do Sipru, o Sipru faz POST no endpoint do parceiro. O destino é resolvido nesta ordem:

  1. cartCallbackUrl do canal, quando enviado na criação;
  2. cartCallbackUrl cadastrada para a loja em /integracoes/cart-erp;
  3. erpBaseUrl + orderEndpointPath da mesma configuração.

Sem nenhum dos três, o clique não vira POST.

Contrato esperado do parceiro: responder 2xx. O Sipru tenta 2 vezes, com timeout de 8 s, e só repete em status transitório (408, 429, 5xx) — um 4xx não transitório recusa o item de vez. Deduplique por Idempotency-Key, que também vem no corpo como idempotencyKey.

Authorizations:
(partnerIdpartnerSecret)
header Parameters
Idempotency-Key
required
string

Igual ao idempotencyKey do corpo. Formato erp_cart_<uuid>.

Request Body schema: application/json
required
idempotencyKey
required
string
event
required
string
Value: "cart_item_added"
channelId
required
string <uuid>
tempQuoteId
required
string
quoteId
string or null
object (Cliente)

Cliente da cotação. Todos os campos são opcionais.

required
object
required
object
required
object
timestamp
required
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "idempotencyKey": "erp_cart_4f1c…",
  • "event": "cart_item_added",
  • "channelId": "5f6d08bc-455a-4532-98b8-19e2cee51160",
  • "tempQuoteId": "string",
  • "quoteId": "string",
  • "cliente": {
    },
  • "vendedor": {
    },
  • "tenant": {
    },
  • "item": {
    },
  • "timestamp": "2019-08-24T14:15:22Z"
}