Documentação
Documentação, do token ao repasse.
Tudo o que um desenvolvedor precisa para assinar um pedido, abrir o checkout e dividir o valor entre os recebedores. Sem SDK, sem integrar API: um token já carrega a informação.
Começando
Comece em 3 passos
O CheckoutPP roda na sua infraestrutura e entende um único idioma: um token assinado. Sua loja, seu ERP ou um parceiro assina o pedido e redireciona o cliente. Pronto: nenhuma chamada de API do seu lado.
Se o seu sistema sabe assinar um JWT, ele já sabe integrar.
Passo 1
Suba o CheckoutPP e crie a sua store
Localmente, docker compose up sobe o PostgreSQL e o app em localhost:8091 (as migrações e o seed de demonstração rodam na inicialização). Em produção é um binário Go com PostgreSQL, e há deploy em um clique no Railway. Cada store tem um ORDER_SECRET, o segredo que assina os pedidos:
# Aplica o schema e cria a store (gera ORDER_SECRET e SELLER_SECRET)
./bin/server migrate up
./bin/server store create MINHA_STORE
# Cria o acesso ao painel admin
./bin/server add-admin [email protected] <senha> MINHA_STORE Passo 2
Assine o pedido no seu backend
O pedido viaja como um JWT HS256 assinado com o ORDER_SECRET. O segredo nunca deve chegar ao navegador. Qualquer linguagem com uma biblioteca JWT serve; veja outras em Como funciona.
import { SignJWT } from 'jose';
// ORDER_SECRET da store: fica no seu backend, nunca no navegador
const secret = new TextEncoder().encode(process.env.ORDER_SECRET);
const token = await new SignJWT({
store_id: 'MINHA_STORE',
external_id: 'PED_1042', // o ID do pedido no seu sistema
idempotency_key: 'PED_1042_v1', // única por pedido
seller_id: 'seller_123', // opcional: habilita o split
customer: { email: '[email protected]', name: 'Ana Lima' },
order: {
amount: 15000, // em centavos
items: [{ desc: 'Plano anual', qty: 1, price: 15000 }],
},
})
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime('30m')
.sign(secret);
// O cliente abre o checkout com um redirecionamento:
const url = `https://checkout.suaempresa.com/pay?session_token=${token}`; Passo 3
Redirecione o cliente
Envie o cliente para /pay?session_token=<jwt>. A página troca o token por um pedido (GET /checkout?session_key=…) e abre o checkout hospedado em /checkout/<order_id>.
# O checkout hospedado faz esta troca por você em /pay
curl "https://checkout.suaempresa.com/checkout?session_key=<jwt>" {
"status": "success",
"order_id": "0198a3c2-7c2a-7e1f-b9a4-3f2c9d1e4a10",
"redirect_url": "/checkout/0198a3c2-7c2a-7e1f-b9a4-3f2c9d1e4a10"
} Integração
O token
O pedido inteiro viaja dentro de um JWT assinado com o ORDER_SECRET da store. O servidor localiza o segredo pela store informada no token, confere a assinatura (e a expiração, se houver) e só então cria o pedido, de forma idempotente.
Sem SDK e sem chamadas de API: o token é o contrato.
{
"store_id": "MINHA_STORE",
"external_id": "PED_1042",
"idempotency_key": "PED_1042_v1",
"seller_id": "seller_123",
"customer": { "email": "[email protected]", "name": "Ana Lima" },
"order": {
"amount": 15000,
"items": [
{ "desc": "Plano anual", "qty": 1, "price": 15000 }
]
},
"iat": 1760000000,
"exp": 1760001800
} -
store_id · issstringobrigatórioIdentifica a store. O servidor usa store_id e, se ausente, iss. A assinatura é conferida com o ORDER_SECRET dessa store.
-
idempotency_keystringobrigatórioÚnica por pedido dentro da store. A mesma chave devolve o pedido já criado, sem duplicar os itens. Se for omitida, todos os pedidos sem chave colidem e o servidor devolve sempre o primeiro.
-
order.amountinteiroobrigatórioTotal do pedido, em centavos. Precisa ser maior que zero para o pagamento ser aceito.
-
order.items[]arrayrecomendadoItens do pedido: desc, qty e price (em centavos). Aparecem no resumo do checkout.
-
external_idstringrecomendadoID do pedido no seu sistema. Fica guardado no pedido.
-
seller_idstringopcionalO external_id do recebedor cadastrado no onboarding; habilita o split. Numa store com modo marketplace ligado é obrigatório (400 sem ele); nas demais é ignorado.
-
split_rulestringopcionalNome de uma regra de split cadastrada em Admin → Regras de split. Vale antes da regra do vendedor e do padrão da store, nas formas de pagamento que ela define. Só em store marketplace; se o nome não existir na store, a troca do token falha com 400.
-
customerobjetoopcionalJSON livre, guardado no pedido. O painel exibe name e email.
-
iat · expnúmerorecomendadoEmissão e expiração (segundos Unix). Se exp existir, é verificada. Recomendado: 30 minutos.
A assinatura usa a família HS (use HS256). O token trafega na URL do redirecionamento; por isso, mantenha a validade curta.
Mesma chave, mesmo pedido: reenviar um token é seguro.
Quando o token é recusado
A troca GET /checkout?session_key=… responde em texto puro. A página /pay mostra a mensagem quando algo falha.
Se o token falhar, a página /pay diz por quê.
-
400
session_key is requiredO parâmetro session_key não foi enviado.
-
400
Invalid token formatO valor não é um JWT.
-
400
Store ID (iss) is requiredO token não traz store_id nem iss.
-
401
Store keys not foundNão existe store com esse identificador.
-
401
Invalid token signature or expiredAssinatura inválida (outro segredo) ou token expirado.
-
400
seller_id is required for marketplace storesA store está em modo marketplace e o token não traz seller_id.
-
404
Seller not foundO seller_id não corresponde a nenhum recebedor dessa store.
-
500
Internal error processing orderFalha ao gravar o pedido; tente de novo.
Arquitetura
Fluxo de pagamento
Da intenção de compra até a confirmação: o pedido nasce pending e muda de status conforme os webhooks do Pagar.me chegam. O checkout hospedado acompanha o pedido por GET /api/v1/orders/{id}.
O checkout consulta o pedido até o status mudar.
Para quem paga, o checkout hospedado tem duas etapas e nenhuma forma de pagamento vem escolhida. Na I · Forma de pagamento aparecem só as formas que a store ligou em Integrações. Escolhendo cartão, os campos do cartão surgem abaixo e o Prosseguir, sempre visível, só é liberado quando todos estiverem válidos; Pix e boleto liberam na hora. Na II · Seus dados ele informa contato, nome e CPF/CNPJ e endereço de cobrança, e paga. O endereço pergunta primeiro só o CEP: ao informá-lo, o restante abre já preenchido; se o CEP não for encontrado (ou a consulta falhar), o formulário completo abre vazio para ser digitado. O botão Alterar (ou o voltar do navegador) retorna à etapa I sem apagar nada; se a store tem uma única forma, ela já vem escolhida.
- i
Seu backend → Cliente
redireciona → /pay?session_token
- ii
Cliente → CheckoutPP
GET /checkout?session_key=JWT
- iii
CheckoutPPvalida assinatura · cria pedido (pending)
- iv
CheckoutPP → Cliente
{ order_id, redirect_url }
- v
Cliente → CheckoutPP
POST /api/v1/checkout
- vi
CheckoutPP → Pagar.me
cria order + split (Activity)
- vii
Pagar.me → CheckoutPP
webhook order.paid
- viii
CheckoutPPstatus do pedido = paid
- ix
Cliente → CheckoutPP
GET /api/v1/orders/{id}
Status do pedido
O webhook POST /api/v1/webhooks/pagarme atualiza o status local de acordo com o evento recebido.
| Evento do Pagar.me | Status local |
|---|---|
| order.paid · charge.paid | paid |
| order.payment_failed | failed |
| order.canceled | canceled |
| charge.refunded | refunded |
Todo pedido começa em pending. Quando o Temporal está ativo, a resposta do checkout traz status: "processing" até o workflow concluir.
Marketplace
Recebedores
Recebedor (ou seller) é quem recebe uma parte da venda. Ele entra por um convite assinado, preenche os dados uma única vez e o CheckoutPP o registra no gateway, o Pagar.me hoje.
O external_id é a ponte entre o seu ID de vendedor e o recebedor no gateway.
- i
O admin gera o convite. No painel, em Convites, “Gerar convite” cria um JWT de 7 dias assinado com
SELLER_JWT_SECRET. - ii
Você envia o link.
/onboarding?token=<convite>. Acrescente&storeId=<store>&externalId=<id-no-seu-sistema>para vincular o recebedor ao seu sistema. - iii
O recebedor se cadastra em quatro passos: identificação, endereço, dados bancários e repasses.
- iv
O servidor registra.
POST /api/v1/recipients(com o convite emAuthorization: Bearer) cria o recebedor no Pagar.me (na conta da store) e o salva com o status devolvido pelo gateway e oexternal_id. O e-mail é único por store: um e-mail que já é vendedor da store devolve409, porque o cadastro nunca sobrescreve um vendedor existente.
Do cadastro ao split
No token, seller_id é o externalId do recebedor (e só vale em uma store com modo marketplace). A plataforma fica com uma comissão de cada venda, em percentual ou valor fixo, e o vendedor recebe o resto. A regra é por forma de pagamento (cartão, Pix, boleto) e vem de, nesta ordem: a regra própria do vendedor para aquela forma, o padrão da store para ela e, sem nenhum dos dois, 10%.
Os valores são calculados em centavos no servidor (a comissão arredonda para cima na metade) e as duas partes sempre somam o total. A parte da plataforma vai para o recebedor da plataforma (campo em Integrações → Pagar.me, ou o padrão da conta): sem ele, o pagamento é recusado em vez de dar tudo ao vendedor.
Sem seller_id, a venda é direta e o valor não é dividido.
Exemplo · taxa de 10%
- Seller · 90%
- R$ 135,00
- Plataforma · 10%
- R$ 15,00
Pagamentos
Gateways
O CheckoutPP foi desenhado para falar com mais de um gateway: o contrato mínimo está em domain/provider.go. Hoje o Pagar.me v5 é o único integrado (cartão, Pix e boleto, recebedores e split).
Planejado: o token continua o mesmo, só o adaptador muda.
// domain/provider.go — o contrato mínimo de um gateway
type Provider interface {
ProcessPayment(ctx context.Context, req PaymentRequest) (*PaymentResponse, error)
RegisterSeller(ctx context.Context, params SellerParams) (*SellerResponse, error)
} Um adaptador precisa, no mínimo, de duas coisas: ProcessPayment (cria a cobrança com as regras de split e devolve o ProviderOrderID e o status) e RegisterSeller (cadastra o recebedor e devolve o ProviderSellerID e o status). Na prática, ele também traduz os webhooks do gateway para os status locais.
| Gateway | Estado | Nota |
|---|---|---|
| iPagar.me | disponível | Cartão, Pix e boleto · API v5 · recebedores e split |
| iiWoovi | planejado | — |
| iiiPague.dev | planejado | — |
| ivAbacatePay | planejado | — |
| vCriptoPag | planejado | — |
| viHodle | planejado | — |
Marca
Alfaiataria
O checkout hospedado pode vestir a sua marca. Em Admin → Alfaiataria você escolhe o nome e o logo, a cor da marca, o destaque, o corte dos cantos e a tipografia, e vê o resultado ao vivo, no papel claro e no escuro, antes de salvar.
| Campo | Valores | Efeito no checkout |
|---|---|---|
| name | até 40 caracteres | Nome da loja no alto do recibo, no lugar do identificador. |
| logo_url | https, até 300 caracteres | Imagem do selo do recibo. Vazio: a inicial do nome. |
| brand | #rrggbb | Botão de pagar e estados selecionados. |
| accent | #rrggbb | Numerais romanos e marcas pequenas. |
| corners | retos · suaves · redondos | Raio dos campos, cartões e botões. |
| font | classica · moderna · elegante | Tipografia dos títulos e do valor total. |
Pela API
O painel usa estes dois endereços, protegidos pela sessão do admin. O PUT aceita os campos acima; o que for omitido volta ao padrão, e um valor inválido devolve 400 com a mensagem de cada campo.
# Lê o tema atual (cookie de sessão do admin)
curl -b cookies.txt https://checkout.suaempresa.com/api/v1/admin/theme
# Salva: campos omitidos voltam ao padrão
curl -b cookies.txt -X PUT https://checkout.suaempresa.com/api/v1/admin/theme \
-H "Content-Type: application/json" \
-d '{"name":"Ateliê Lume","brand":"#0f5c63","accent":"#b8892a","font":"elegante","corners":"redondos"}' {
"theme": {
"name": "Ateliê Lume",
"logo_url": "https://suaempresa.com/logo.png",
"brand": "#0f5c63",
"accent": "#b8892a",
"font": "elegante",
"corners": "redondos"
},
"defaults": { "brand": "#1b1713", "accent": "#b8341a", "font": "classica", "corners": "suaves", "name": "", "logo_url": "" },
"store_id": "MINHA_STORE"
} { "errors": { "logo_url": "O logo precisa ser servido por https." } } No checkout, o tema chega junto do pedido: GET /api/v1/orders/{id} devolve o campo theme. Se a store não personalizou nada, ou se a leitura falhar, o campo some e a página mantém o visual padrão. Um tema nunca impede um pagamento.
A mudança vale a partir do próximo checkout aberto: não há deploy nem reinício. Pedidos que já estão abertos na tela de quem paga mantêm o visual com que foram carregados.
Marca
Stores e integrações
Uma store é uma separação: tem os seus próprios pedidos, vendedores, convites, visual (Alfaiataria) e integrações. Só o identificador é obrigatório (o store_id que vai nos tokens); o nome é opcional. Uma mesma conta de admin gerencia várias stores: o seletor no topo do painel troca a store em que tudo trabalha, e Nova store cria outra.
| Endpoint | O que faz |
|---|---|
| GET · POST /admin/stores | Lista as stores da conta; cria uma (store_id e label opcionais). |
| PATCH /admin/stores/{id} | Renomeia (só o label). |
| POST /admin/stores/switch | Troca a store da sessão. O servidor confere no banco que a conta gerencia a store. |
| GET · POST /admin/signing-key[/rotate] | Lê ou renova o ORDER_SECRET da store (a chave que assina o token). |
| GET /admin/integrations | Gateways (com o estado de cada um nesta store), formas de pagamento e o que o checkout oferece agora. |
| PUT · DELETE /admin/integrations/gateways/{gateway} | Cadastra, atualiza (enabled e fields) ou remove as credenciais da store. |
| PUT /admin/integrations/methods | Liga ou desliga cada forma de pagamento, escolhe o gateway que a atende e, no Pagar.me de uma store marketplace, o split padrão dela ({"type":"percentage","percent":7.5} ou {"type":"flat","flat_cents":250}). |
| PUT /admin/integrations/marketplace | Liga ou desliga o modo marketplace da store ({"enabled":true}). |
| GET · PUT /admin/sellers/{id}/split | Lê e grava as regras de split próprias de um vendedor, por forma de pagamento (null remove a regra e o vendedor volta a seguir a store). |
| GET /admin/split | Todas as regras da store numa resposta: padrão por forma de pagamento, regras com nome, vendedores com regra própria e o padrão do sistema. |
| PUT · DELETE /admin/split/presets/{key} | Cria, substitui ou remove uma regra com nome ({"label":"Premium","methods":{"card":{"type":"percentage","percent":6}}}). A chave tem minúsculas, números, hífen e _; a regra precisa definir ao menos uma forma de pagamento. |
# Cria uma store (o identificador sai do nome, se omitido) e passa a trabalhar nela
curl -b cookies.txt -X POST https://checkout.suaempresa.com/api/v1/admin/stores \
-H "Content-Type: application/json" -d '{"label":"Ateliê Lume"}'
curl -b cookies.txt -X POST https://checkout.suaempresa.com/api/v1/admin/stores/switch \
-H "Content-Type: application/json" -d '{"store_id":"ATELIE_LUME"}'
# Cadastra o Pagar.me da store e liga só cartão e boleto
curl -b cookies.txt -X PUT https://checkout.suaempresa.com/api/v1/admin/integrations/gateways/pagarme \
-H "Content-Type: application/json" \
-d '{"enabled":true,"fields":{"secret_key":"sk_…","public_key":"pk_…"}}'
curl -b cookies.txt -X PUT https://checkout.suaempresa.com/api/v1/admin/integrations/methods \
-H "Content-Type: application/json" \
-d '{"methods":{"card":{"enabled":true,"gateway":"pagarme"},"pix":{"enabled":false,"gateway":"pagarme"},"boleto":{"enabled":true,"gateway":"pagarme"}}}' Modo marketplace
O modo marketplace é uma opção da integração com o Pagar.me v5, a única que faz split até o momento: o interruptor fica no cartão do Pagar.me, em Integrações. Ligado, a store vende por vendedores e só o Pagar.me pode ser usado (a API recusa rotear uma forma para outro gateway). Desligado, a store vende direto: não há vendedores nem split, um seller_id no token é ignorado e o painel esconde Vendedores e Convites.
- Só liga com o Pagar.me ativo e com chaves (da store ou da instalação), e sem nenhuma forma de pagamento em outro gateway.
- Enquanto estiver ligado, o Pagar.me não pode ser desativado na store, nem ter as chaves da store removidas se a instalação não tiver chaves para assumir: primeiro se desliga o modo.
- Uma store nova começa desligada. As stores que já tinham vendedores foram ligadas pela migração.
- Ligado, todo token precisa de
seller_idde um vendedor da própria store (400sem ele,404se não existir). - As regras de split têm quatro níveis, e vale o primeiro que existir para a forma de pagamento: a regra com nome que o token indica em
split_rule, a regra própria do vendedor (na página dele), o padrão da store (em cada forma de pagamento) e, por fim, os 10% do sistema. Tudo fica reunido em Regras de split. Uma regra com nome pode definir só algumas formas de pagamento; as demais seguem para o nível seguinte. O nome é guardado no pedido; apagar a regra depois faz os pedidos em aberto caírem no nível seguinte, e tokens novos com esse nome são recusados. - O corpo do
POST /checkoutnunca decide o split: percentuais e valores enviados pelo navegador são descartados quando o pedido existe.
Como o checkout escolhe
Cada store cadastra os gateways que usa, com credenciais próprias (criptografadas com AES-GCM; a chave secreta nunca volta ao navegador, só uma máscara). Em Formas de pagamento ela liga ou desliga cartão, Pix e boleto e escolhe o gateway de cada um. O pedido público (GET /api/v1/orders/{id}) devolve payment_methods e a chave pública da store; a página mostra só essas formas, e o servidor recusa (400) qualquer outra, porque a página não é uma barreira de segurança.
- Sem credenciais próprias, a store usa as da instalação (variáveis de ambiente ou a tabela de configurações da API), como sempre foi. Se não houver nenhuma, o checkout avisa que a loja não aceita pagamentos.
- Desativar o gateway numa store tira as formas dele do checkout, mesmo que a instalação tenha chaves.
- A store de um pagamento vem sempre do pedido no banco, nunca do corpo da requisição: um pagamento nunca é assinado com a chave de outra store.
Hoje só o Pagar.me tem adaptador (cartão, Pix e boleto). Woovi, Pague.dev, AbacatePay, CriptoPag e Hodle aparecem como planejados e não podem ser escolhidos; Cripto também é uma forma planejada.
A escolha por forma de pagamento já está pronta para o dia em que houver mais de um gateway.
Arquitetura
Componentes
A aplicação separa a entrada (handlers), as regras de negócio (serviços) e a infraestrutura (cliente do Pagar.me, banco, Temporal). Os handlers só validam e coordenam; os serviços concentram as regras.
ICliente
Seu backend
Assina o JWT do pedido com o ORDER_SECRET da store.
Navegador do cliente
Abre o checkout hospedado: cartão, Pix ou boleto.
IIEntrada
Handlers · API
Valida JWT, cookies de sessão e payloads. Rotas de checkout, pedidos, sellers, convites e webhook.
IIINúcleo
Checkout Service
Cálculo do split e criação do pedido.
Recipient Service
Cadastro de sellers e vínculo com o Pagar.me.
Settings Service
Chaves e segredos criptografados (AES).
IVAdaptadores
Pagar.me v5
Orders, split rules e recipients.
PostgreSQL · sqlc
Pedidos, sellers, convites e configurações.
Temporal worker
CheckoutWorkflow e Activities com retry (opcional).
Outros gateways
Woovi, Pague.dev, AbacatePay, CriptoPag, Hodle — planejado.
Configuração
Variáveis de ambiente
O servidor lê estas variáveis na inicialização. Use o .env.example do repositório como ponto de partida.
-
DATABASE_URLString de conexão do PostgreSQL.
postgres://user:pass@host:5432/db
-
TEMPORAL_ADDREndereço do servidor Temporal usado pelo worker e pelo cliente de workflows.
localhost:7233
-
TEMPORAL_NAMESPACENamespace do Temporal.
default
-
TEMPORAL_API_KEYChave de API do Temporal (Temporal Cloud). Opcional em ambiente local.
-
USE_TEMPORAL_FOR_ACTIONStrue: o checkout inicia o CheckoutWorkflow e responde 202 (processing). false: processa de forma síncrona.
false
-
ENABLE_SPLIT_MARKETPLACEPadrão do modo marketplace para pedidos sem store e para stores sem registro próprio. Cada store liga ou desliga o seu em Admin → Integrações.
true
-
JWT_SECRETSegredo dos tokens JWT de clientes.
um-segredo-forte
-
SELLER_JWT_SECRETSegredo dos tokens de convite e das sessões de seller/admin.
outro-segredo-forte
-
PAGARME_SECRET_KEYChave secreta da API do Pagar.me v5.
sk_test_…
-
PAGARME_PUBLIC_KEYChave pública usada na tokenização do cartão no navegador. Lida primeiro da tabela de configurações e, se ausente, desta variável.
pk_test_…
-
PAGARME_WEBHOOK_SECRETSegredo do webhook configurado no Pagar.me (reservado para validação de assinatura).
-
PAGARME_BASE_URLURL base da API do Pagar.me.
https://api.pagar.me/core/v5
-
SETTINGS_ENCRYPTION_KEYChave AES-GCM que criptografa os valores sensíveis das configurações e as credenciais dos gateways das stores. 16, 24 ou 32 caracteres são usados como estão; qualquer outro tamanho passa por SHA-256.
32 caracteres
-
PORTPorta HTTP do servidor.
8080
DATABASE_URL=postgres://postgres:postgres@localhost:5432/checkout_db?sslmode=disable
USE_TEMPORAL_FOR_ACTIONS=false
ENABLE_SPLIT_MARKETPLACE=true
JWT_SECRET=your-customer-jwt-secret
SELLER_JWT_SECRET=your-seller-jwt-secret
PAGARME_SECRET_KEY=sk_test_...
PAGARME_PUBLIC_KEY=pk_test_...
PAGARME_BASE_URL=https://api.pagar.me/core/v5
PORT=8080 Configuração
Segurança
O pedido é assinado com HS256 usando o ORDER_SECRET da store. O servidor localiza o segredo pela store informada no token, verifica a assinatura e a expiração e só então cria o pedido. Os claims estão descritos em O token.
Boas práticas
- Assine sempre no backend. O playground assina no navegador apenas para demonstração.
- Mantenha o token curto (≈ 30 minutos): ele trafega na URL do redirecionamento.
- Use
idempotency_keyestável por pedido para tolerar reenvios e cliques duplicados. - Chaves do Pagar.me e demais segredos guardados nas configurações e nas integrações das stores são criptografados com AES-GCM (
SETTINGS_ENCRYPTION_KEY). - O painel admin usa sessão por cookie HTTP-only, ligada a uma store; trocar de store reemite a sessão depois de conferir no banco que a conta a gerencia. Convites de seller são JWTs com validade de 7 dias e não valem como sessão de admin.
- Vendedores, pedidos, saldos, repasses e estornos são sempre da store da sessão: o de outra store responde
404, mesmo que o identificador seja conhecido. - As configurações da instalação (
/api/v1/settings) só aceitam sessão de admin, e a listagem nunca devolve valores, só os nomes e se estão criptografadas.
O segredo da store é a única coisa que não pode vazar.
Operação
CLI
A administração acontece pelo mesmo binário do servidor. Em desenvolvimento, go run main.go <comando> é equivalente, e as tarefas mise run db:migrate, db:seed-demo e db:add-admin são atalhos.
Comandos essenciais
./bin/server # inicia a API (padrão)
./bin/server migrate up # aplica as migrações
./bin/server migrate down # reverte TODAS as migrações (destrutivo)
./bin/server seed-demo # cria store, seller e admin de demonstração
./bin/server add-admin <email> <senha> <store_id>
./bin/server keygen [--save] # gera 32 bytes aleatórios (hex) para criptografia Gestão de stores
Cada store possui um ORDER_SECRET, que assina os pedidos (o JWT do checkout). A CLI também gera um SELLER_SECRET e o guarda junto, mas os convites de onboarding são assinados com a variável SELLER_JWT_SECRET.
# Provisiona as chaves da store (aleatórias se omitidas)
./bin/server store create <store_id> [--order-secret s1] [--seller-secret s2]
# Gera um JWT de teste para o checkout
./bin/server store jwt <store_id> <amount_cents> "<item_name>" Store 'MINHA_STORE' created successfully!
--------------------------------------------------
ORDER_SECRET: 9f2c…d41a
SELLER_SECRET: 51be…07c3
--------------------------------------------------
Keep these secrets safe. They are stored in the database. Os segredos ficam no banco. O ORDER_SECRET pode ser consultado e renovado em Admin → Integrações; stores criadas pelo painel já nascem com ele. A CLI também registra a store e o vínculo do admin.