Skip to content

Estrutura da venda

Uma Venda (Sale) representa uma venda, contendo informações sobre o cliente, itens adquiridos, pagamento, entrega e histórico de estados. Cada venda pode gerar múltiplas Cobrânças (Payables) quando parcelada.

json
{
  "_id": "698b8a805eaf8de7c5af1cb9",
  "code": "LP-NNK26-MG463",
  "saleGroupCode": "LP-NNK26",
  "saleGroupId": "000000000000000000000001",
  "community": "test",
  "kind": "order",
  "currency": "BRL",
  "token": "dc1bb36a-62f1-4c94-bc7c-b05152ab3418",
  "checkoutId": "698b8a805eaf8de7c5af1cbb",
  "marketplaceId": null,
  "customerId": "698b8a805eaf8de7c5af1cbc",
  "embedded": null,
  "trackingUrl": "https://example.com/track/dc1bb36a",
  "requiresApproval": false,
  "approvedAt": "2026-02-12T20:45:01.549Z",
  "createdAt": "2026-02-10T19:44:01.198Z",
  "updatedAt": "2026-02-12T20:45:01.697Z",
  "confirmed": true,
  "confirmedAt": "2026-02-12T20:45:01.600Z",
  "completed": false,
  "completedAt": null,
  "failed": false,
  "failedAt": null,
  "failureReason": null,
  "canceled": false,
  "canceledAt": null,
  "refunded": false,
  "refundedAt": null,
  "canEditPaymentMethod": false,
  "sentEmailWithAllBankSlips": false,
  "hasPayableWithManualUpdate": false,
  "context": {
    "name": null,
    "alias": null,
    "entity": "698b8a805eaf8de7c5af1cb9",
    "kind": "order",
    "hash": "abc123def456"
  },
  "customer": {
    "name": "John Doe Silva",
    "email": "john@example.com",
    "phone": "(11) 91123-1233",
    "birth": "1990-05-15T00:00:00.000Z",
    "document": {
      "kind": "cpf",
      "value": "000.000.000-00"
    },
    "address": {
      "address": "Rua Exemplo",
      "number": "875",
      "address2": "Apto 101",
      "district": "Vila Nova",
      "city": "São Paulo",
      "state": "SP",
      "country": "BR",
      "code": "09510112",
      "createdAt": "2026-02-10T19:44:02.346Z",
      "updatedAt": "2026-02-10T19:44:02.346Z"
    },
    "stateLicense": null,
    "token": "3eef5671-a707-45ef-8c8a-d825e3ddd3d0"
  },
  "user": {
    "_id": "123456",
    "name": "John Doe",
    "alias": "johndoe",
    "accountId": "acc_123",
    "email": "john@example.com"
  },
  "coupon": null,
  "items": [],
  "discounts": [],
  "taxes": [],
  "payment": {
    "status": "pending",
    "statusTransitions": {
      "open": "2026-02-12T20:45:01.609Z"
    },
    "statusChangedAt": "2026-02-12T20:45:01.609Z",
    "tags": ["open"],
    "method": {
      "method": "credit_card",
      "key": "zoop:credit_card",
      "gateway": "zoop",
      "strategy": "installment",
      "installments": 5,
      "custom": false,
      "startAnchorAt": null,
      "sourceId": "698b8a805eaf8de7c5af1cce",
      "discounts": [],
      "taxes": [],
      "card": {
        "token": "CARD_TOKEN",
        "first_digits": "1234",
        "last_digits": "1111",
        "brand": "mastercard",
        "brandPretty": "Mastercard"
      },
      "multi_cards": [],
      "bank_slip": {
        "dueDays": 7,
        "lateFee": 0,
        "lateInterestRate": 0,
        "generateAllAtOnce": false
      },
      "pix": {
        "expiresInMinutes": 15
      }
    },
    "qrCode": null
  },
  "owned": {
    "items": { "amount": 20000, "currency": "BRL" },
    "discounts": { "amount": 0, "currency": "BRL" },
    "shipping": { "amount": 0, "currency": "BRL" },
    "taxes": { "amount": 0, "currency": "BRL" },
    "total": { "amount": 20000, "currency": "BRL" }
  },
  "recipients": [],
  "shipping": {
    "required": true,
    "method": null,
    "address": {
      "address": "Rua Exemplo",
      "number": "875",
      "address2": "Apto 101",
      "district": "Vila Nova",
      "city": "São Paulo",
      "state": "SP",
      "country": "BR",
      "createdAt": "2026-02-10T19:44:01.575Z",
      "updatedAt": "2026-02-10T19:44:01.575Z"
    }
  },
  "integration": {
    "status": "not_integrated",
    "statusChangedAt": "2026-02-10T19:44:01.235Z",
    "reason": null,
    "explanation": null,
    "metadata": {},
    "payload": {},
    "assignee": "DEFAULT_ASSIGNEE",
    "externalIdentifiers": []
  },
  "feedback": {
    "rate": null,
    "comment": null,
    "createdAt": null,
    "updatedAt": null
  },
  "device": {
    "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
    "colorDepth": 24,
    "ip": "192.168.1.1",
    "javaEnabled": false,
    "language": "pt-BR",
    "screenHeight": 1080,
    "screenWidth": 1920,
    "timeZoneOffSet": -180,
    "fingerprint": "abc123def456",
    "geoip": {
      "ip": "192.168.1.1",
      "country": "BR",
      "region": "SP",
      "city": "São Paulo",
      "ll": "-23.5505,-46.6333"
    }
  },
  "stepVerification": {
    "code": "123456",
    "validAt": "2026-02-13T19:44:01.198Z"
  },
  "externalFormAnswers": []
}

Campos principais

CampoTipoDescrição
_idstringID único da venda no formato ObjectId
codestringCódigo legível único da venda. Ex: LP-NNK26-MG463
saleGroupCodestring | nullCódigo do grupo de vendas. Ex: LP-NNK26. Caso não agrupada, null
saleGroupIdstring | nullID do grupo de vendas ao qual esta venda pertence. Caso não agrupada, null
communitystringComunidade (tenant) onde a venda foi realizada
kindstringTipo da venda. Valores possíveis: order, recurrence, subscription, commission, gift, voucher
currencystringMoeda da transação no formato ISO 4217. Ex: BRL, USD
tokenstringToken único de acesso público para a venda (UUID v4)
checkoutIdstring | nullID do checkout associado. Caso não vinculado, null
customerIdstring | nullID do cliente. Caso não vinculado, null
marketplaceIdstring | nullID do marketplace de origem. Caso não aplicável, null
embeddedobject | nullDados do checkout embutido (origem do checkout). Caso não aplicável, null
trackingUrlstring | nullURL pública para rastreamento e acompanhamento da venda. Caso não gerada, null
requiresApprovalbooleanIndica se a venda requer aprovação manual antes de prosseguir
approvedAtstring (ISO 8601) | nullData e hora da aprovação. Caso não aprovada, null
createdAtstring (ISO 8601)Data e hora de criação da venda
updatedAtstring (ISO 8601)Data e hora da última atualização
confirmedbooleanIndica se o pagamento foi confirmado pelo gateway
confirmedAtstring (ISO 8601) | nullData e hora da confirmação. Caso não confirmada, null
completedbooleanIndica se a venda foi finalizada com sucesso
completedAtstring (ISO 8601) | nullData e hora da conclusão. Caso não concluída, null
failedbooleanIndica se o pagamento falhou
failedAtstring (ISO 8601) | nullData e hora da falha. Caso não falhou, null
failureReasonstring | nullDescrição do motivo da falha (ex: "Cartão recusado"). Caso não falhou, null
canceledbooleanIndica se a venda foi cancelada
canceledAtstring (ISO 8601) | nullData e hora do cancelamento. Caso não cancelada, null
refundedbooleanIndica se a venda teve reembolso
refundedAtstring (ISO 8601) | nullData e hora do reembolso. Caso não reembolsada, null
canEditPaymentMethodbooleanIndica se o método de pagamento pode ser alterado
sentEmailWithAllBankSlipsbooleanIndica se email com todos os boletos foi enviado
hasPayableWithManualUpdatebooleanIndica se há parcelas com atualização manual (bloqueia cobranças automáticas)
couponobject | nullCupom de desconto aplicado. Caso não houver, null
externalFormAnswersarrayRespostas de formulários externos vinculados à venda
discountsarrayLista de descontos aplicados à venda
taxesarrayLista de impostos aplicados à venda

context

Informações sobre o contexto da loja onde a venda foi realizada.

json
{
  "name": null,
  "alias": null,
  "entity": "698b8a805eaf8de7c5af1cb9",
  "kind": "order",
  "hash": "abc123def456"
}
CampoTipoDescrição
namestring | nullNome da loja. Caso não configurado, null
aliasstring | nullAlias da loja. Caso não configurado, null
entitystringIdentificador da entidade (channel) da loja
kindstringTipo do contexto da venda
hashstringHash computado do contexto da venda

customer

Dados do cliente que realizou a compra.

json
{
  "name": "John Doe Silva",
  "email": "john@example.com",
  "phone": "(11) 91123-1233",
  "birth": "1990-05-15T00:00:00.000Z",
  "document": {
    "kind": "cpf",
    "value": "000.000.000-00"
  },
  "address": {
    "address": "Rua Exemplo",
    "number": "875",
    "address2": "Apto 101",
    "district": "Vila Nova",
    "city": "São Paulo",
    "state": "SP",
    "country": "BR",
    "code": "09510112",
    "createdAt": "2026-02-10T19:44:02.346Z",
    "updatedAt": "2026-02-10T19:44:02.346Z"
  },
  "stateLicense": null,
  "token": "3eef5671-a707-45ef-8c8a-d825e3ddd3d0"
}
CampoTipoDescrição
namestringNome completo do cliente (mínimo 2 palavras com 2+ caracteres cada)
emailstringEndereço de e-mail do cliente (validado)
phonestring | nullNúmero de telefone do cliente. Caso não informado, null
birthstring (ISO 8601) | nullData de nascimento do cliente (apenas data, sem hora). Caso não informado, null
tokenstring | nullToken de pagamento. Caso não informado, null
document.kindstringTipo do documento. Valores possíveis: cpf, cnpj
document.valuestringNúmero do documento
stateLicensestring | nullInscrição estadual (apenas para CNPJ). Caso não informado, null
address.addressstring | nullLogradouro. Caso não informado, null
address.numberstring | nullNúmero. Caso não informado, null
address.address2string | nullComplemento (apto, sala, etc). Caso não informado, null
address.districtstring | nullBairro. Caso não informado, null
address.citystring | nullCidade. Caso não informado, null
address.statestring | nullEstado (UF). Caso não informado, null
address.countrystringPaís no formato ISO 3166-1 alpha-2. Ex: BR
address.codestring | nullCEP/Código postal. Caso não informado, null
address.createdAtstring (ISO 8601)Data de criação do endereço
address.updatedAtstring (ISO 8601)Data da última atualização do endereço

user

Dados do usuário autenticado que completou a compra (apenas quando aplicável).

json
{
  "_id": "123456",
  "name": "John Doe",
  "alias": "johndoe",
  "accountId": "acc_123",
  "email": "john@example.com"
}
CampoTipoDescrição
_idstringID do usuário
namestringNome completo do usuário
aliasstringAlias/username do usuário
accountIdstringID da conta associada
emailstringEmail do usuário

Nota: Este objeto só está presente quando um usuário autenticado completou a compra. Para compras de visitantes, este campo é null.


items

Lista de produtos adquiridos na venda. Note que a estrutura do objeto items é diferente da estrutura do objeto Item do catálogo. Um exemplo: o objeto aqui contém itemKind, enquanto o objeto Item tem campos adicionais.

json
{
  "itemId": "5be99fd8dd405c6c7acfc0c4",
  "itemKind": "product",
  "name": "My at once product",
  "sku": "my-once-product-0001",
  "alias": "my-once-product",
  "caption": "Branco | 1kg",
  "quantity": 2,
  "maxQuantity": null,
  "variantId": "0001",
  "channelId": "698b8a805eaf8de7c5af1cb9",
  "inventoryId": "698b8a805eaf8de7c5af1d7e",
  "custom": false,
  "shippable": true,
  "sole": false,
  "requiresApproval": false,
  "isPriceVisible": true,
  "isRecurring": false,
  "startAnchorAt": null,
  "recurrentCycles": null,
  "linkingGroup": null,
  "schoolName": null,
  "tab": null,
  "plan": null,
  "forms": null,
  "observations": [],
  "attributes": [
    { "id": "000000000000000000000001", "value": "Branco" },
    { "id": "000000000000000000000002", "value": "1kg" }
  ],
  "package": {
    "width": 5,
    "depth": 5,
    "height": 5,
    "weight": 0.2
  },
  "price": {
    "amount": 10000,
    "currency": "BRL"
  },
  "subtotal": {
    "amount": 20000,
    "currency": "BRL"
  },
  "media": {
    "url": "https://cdn.exemplo.com/imagem.png",
    "path": "/community/uploads/.../imagem.png",
    "mime": "image/png",
    "width": 456,
    "height": 783,
    "size": 379264,
    "name": "imagem.png",
    "orientation": null
  }
}
CampoTipoDescrição
itemIdstringIdentificador do produto no catálogo
itemKindstringTipo do item (discriminator). Valores: product, recurrence, gift
namestringNome do item
skustringCódigo SKU do item
aliasstringAlias do item
captionstringDescrição curta do item, frequentemente com os atributos selecionados. Ex: Branco | 1kg
quantityintegerQuantidade adquirida
maxQuantityinteger | nullQuantidade máxima permitida por compra. Caso não limitado, null
variantIdstringIdentificador da variante do produto selecionada
channelIdstringIdentificador do canal de venda
inventoryIdstring | nullIdentificador do registro de estoque associado. Caso não aplicável, null
custombooleanIndica se o item foi personalizado pelo cliente
shippablebooleanIndica se o item requer envio físico
solebooleanIndica se o item é vendido de forma exclusiva/individual
requiresApprovalbooleanIndica se a entrega do item requer aprovação manual
isPriceVisiblebooleanIndica se o preço é exibido publicamente no catálogo
isRecurringbooleanIndica se o item possui cobrança recorrente
startAnchorAtstring (ISO 8601) | nullData de início da recorrência, quando aplicável. Caso contrário, null
recurrentCyclesinteger | nullNúmero de ciclos de recorrência. Caso não aplicável, null
linkingGroupstring | nullGrupo de vinculação do item (para itens vinculados). Caso não aplicável, null
schoolNamestring | nullNome da instituição vinculada, quando aplicável. Caso contrário, null
tabobject | nullAba/categoria de categorização do item no catálogo. Caso não houver, null
planobject | nullDados do plano de recorrência vinculado. Caso não houver, null
formsobject | nullRespostas de formulários vinculados ao item. Caso não houver, null
observationsarrayLista de observações registradas para o item
attributesarrayLista de atributos selecionados para o item (como cor e tamanho). Cada elemento contém id e value
price.amountintegerValor unitário em centavos. Ex: 10000 = R$ 100,00
price.currencystringMoeda no formato ISO 4217
subtotal.amountintegerValor total do item em centavos (price × quantity)
subtotal.currencystringMoeda no formato ISO 4217
package.widthnumberLargura em centímetros
package.depthnumberProfundidade em centímetros
package.heightnumberAltura em centímetros
package.weightnumberPeso em quilogramas
media.urlstringURL pública da imagem do item
media.pathstringCaminho interno da imagem
media.mimestringTipo MIME da imagem. Ex: image/png, image/jpeg
media.widthintegerLargura da imagem em pixels
media.heightintegerAltura da imagem em pixels
media.sizeintegerTamanho do arquivo em bytes
media.namestringNome do arquivo da imagem
media.orientationstring | nullOrientação da imagem. Caso não informada, null

payment

Informações sobre o pagamento da venda.

json
{
  "status": "pending",
  "statusTransitions": {
    "open": "2026-02-12T20:45:01.609Z"
  },
  "statusChangedAt": "2026-02-12T20:45:01.609Z",
  "tags": ["open"],
  "method": {
    "method": "credit_card",
    "key": "zoop:credit_card",
    "gateway": "zoop",
    "strategy": "installment",
    "installments": 5,
    "custom": false,
    "startAnchorAt": null,
    "sourceId": "698b8a805eaf8de7c5af1cce",
    "discounts": [],
    "taxes": [],
    "card": {
      "token": "CARD_TOKEN",
      "first_digits": "1234",
      "last_digits": "1111",
      "brand": "mastercard",
      "brandPretty": "Mastercard"
    },
    "multi_cards": [],
    "bank_slip": {
      "dueDays": 7,
      "lateFee": 0,
      "lateInterestRate": 0,
      "generateAllAtOnce": false
    },
    "pix": {
      "expiresInMinutes": 15
    }
  },
  "qrCode": null
}
CampoTipoDescrição
statusstringStatus atual do pagamento. Valores possíveis: open, pending, paid, released, late, expired, failed, canceled, refunded, chargeback, in_protest, waiting_approval, gifted, voucher
statusTransitionsobjectHistórico de timestamps de cada status atingido
statusChangedAtstring (ISO 8601)Data e hora da última mudança de status
tagsarray<string>Tags descritivas do status atual
method.methodstringForma de pagamento. Valores possíveis: credit_card, bank_slip, pix, multi_card, gift, voucher, bolepix
method.keystringChave composta que identifica o gateway e o método. Ex: zoop:credit_card
method.gatewaystringGateway de pagamento. Valores: barte, zoop, pagarme, maxipago, bempaggo, getnet, vindi
method.strategystringEstratégia de cobrança. Valores possíveis: installment, recurrence
method.installmentsintegerNúmero de parcelas (1-36)
method.custombooleanIndica se o método de pagamento foi customizado
method.startAnchorAtstring (ISO 8601) | nullData âncora de início das cobranças. Caso não aplicável, null
method.sourceIdstring | nullIdentificador da fonte de pagamento. Caso não vinculado, null
method.discountsarrayDescontos aplicados ao método de pagamento
method.taxesarrayTaxas aplicadas ao método de pagamento
method.cardobjectObjeto com dados do cartão (apenas para credit_card)
method.card.tokenstring | nullToken do cartão no gateway. Caso não tokenizado, null
method.card.first_digitsstringPrimeiros dígitos do cartão
method.card.last_digitsstringÚltimos dígitos do cartão (máx 6 caracteres)
method.card.brandstringBandeira do cartão. Ex: mastercard, visa, amex
method.card.brandPrettystringBandeira formatada para exibição. Ex: Mastercard
method.multi_cardsarray<object>Lista de cartões quando o pagamento é dividido entre múltiplos cartões (mesma estrutura de card)
method.bank_slipobjectObjeto com dados do boleto (apenas para bank_slip)
method.bank_slip.dueDaysintegerPrazo de vencimento em dias corridos
method.bank_slip.lateFeenumberPercentual de multa por atraso
method.bank_slip.lateInterestRatenumberPercentual de juros por atraso ao mês
method.bank_slip.generateAllAtOncebooleanIndica se todos os boletos parcelados são gerados de uma vez
method.pixobjectObjeto com dados do PIX (apenas para pix)
method.pix.expiresInMinutesintegerMinutos até expiração do PIX (padrão: 15)
qrCodestring | nullString do QR Code (para PIX). Caso não gerado, null

owned

Resumo dos valores da venda sob responsabilidade do vendedor.

json
{
  "items": { "amount": 20000, "currency": "BRL" },
  "discounts": { "amount": 0, "currency": "BRL" },
  "shipping": { "amount": 0, "currency": "BRL" },
  "taxes": { "amount": 0, "currency": "BRL" },
  "total": { "amount": 20000, "currency": "BRL" }
}
CampoTipoDescrição
itemsobjectValor total dos itens antes de descontos
discountsobjectTotal de descontos aplicados
shippingobjectCusto de envio
taxesobjectTotal de impostos
totalobjectValor final da venda (items - discounts + shipping + taxes)

Todos os campos acima seguem o padrão: amount (valor em centavos) e currency (moeda no formato ISO 4217).


recipients

Lista de destinatários dos valores da venda. Cada entrada representa um recebedor, como o vendedor ou a plataforma.

json
{
  "sourceId": "698b8a805eaf8de7c5af1cce",
  "items": { "amount": 4000, "currency": "BRL" },
  "discounts": { "amount": 0, "currency": "BRL" },
  "taxes": { "amount": 0, "currency": "BRL" },
  "shipping": { "amount": 0, "currency": "BRL" },
  "total": { "amount": 4000, "currency": "BRL" },
  "options": {},
  "itemsInfo": []
}
CampoTipoDescrição
sourceIdstringIdentificador do recebedor
itemsobjectValor dos itens atribuído a este recebedor
discountsobjectDescontos aplicados sobre o valor deste recebedor
taxesobjectImpostos atribuídos a este recebedor
shippingobjectCusto de frete atribuído a este recebedor
totalobjectValor total a ser recebido
optionsobjectOpções de split específicas do recebedor
itemsInfoarrayInformações detalhadas dos itens atribuídos a este recebedor

Todos os campos de valor seguem o padrão: amount (centavos) e currency (ISO 4217).


shipping

Informações sobre a entrega da venda.

json
{
  "required": true,
  "method": null,
  "address": {
    "address": "Rua Exemplo",
    "number": "875",
    "address2": "Apto 101",
    "district": "Vila Nova",
    "city": "São Paulo",
    "state": "SP",
    "country": "BR",
    "createdAt": "2026-02-10T19:44:01.575Z",
    "updatedAt": "2026-02-10T19:44:01.575Z"
  }
}
CampoTipoDescrição
requiredbooleanIndica se a entrega física é necessária para esta venda
methodobject | nullMétodo de entrega selecionado. Caso não definido, null
address.addressstring | nullLogradouro de entrega. Caso não informado, null
address.numberstring | nullNúmero. Caso não informado, null
address.address2string | nullComplemento. Caso não informado, null
address.districtstring | nullBairro. Caso não informado, null
address.citystring | nullCidade. Caso não informado, null
address.statestring | nullEstado (UF). Caso não informado, null
address.countrystringPaís no formato ISO 3166-1 alpha-2. Ex: BR
address.createdAtstring (ISO 8601)Data de criação do endereço de entrega
address.updatedAtstring (ISO 8601)Data da última atualização do endereço de entrega

integration

Status da integração da venda com sistemas externos.

json
{
  "status": "not_integrated",
  "statusChangedAt": "2026-02-10T19:44:01.235Z",
  "reason": null,
  "explanation": null,
  "metadata": {},
  "payload": {},
  "assignee": "DEFAULT_ASSIGNEE",
  "externalIdentifiers": []
}
CampoTipoDescrição
statusstringStatus da integração. Valores possíveis: not_integrated, pending, integrated, approved, received, failed, ignored, invoiced
statusChangedAtstring (ISO 8601)Data e hora da última alteração de status
reasonstring | nullMotivo da integração/falha
explanationstring | nullExplicação adicional sobre o status
metadataobjectDados adicionais e metadados da integração
payloadobjectCarga da integração com informações completas
assigneestring | nullResponsável pela integração. Ex: DEFAULT_ASSIGNEE
externalIdentifiersarray<string>Identificadores da venda em sistemas externos

embedded

Dados do checkout embutido (quando a venda é originária de um checkout embutido).

json
{
  "source": "comunicados",
  "entityId": "entity-123",
  "userId": "user-456"
}
CampoTipoDescrição
sourcestringOrigem do checkout embutido. Valor: comunicados
entityIdstringID da entidade de origem
userIdstringID do usuário que criou o checkout

externalFormAnswers

Respostas de formulários externos vinculados à venda.

json
[
  {
    "externalId": "ext-form-001",
    "externalValue": "valor-resposta",
    "externalAlias": "alias-opcional",
    "formAnswerId": "form-ans-123"
  }
]
CampoTipoDescrição
externalIdstringID do formulário externo
externalValuestringValor da resposta no sistema externo
externalAliasstring | nullAlias da resposta (opcional)
formAnswerIdstringID da resposta de formulário vinculada

feedback

Avaliação do cliente sobre a venda.

json
{
  "rate": null,
  "comment": null,
  "createdAt": null,
  "updatedAt": null
}
CampoTipoDescrição
rateinteger (1-5) | nullNota atribuída pelo cliente (1-5). Caso não avaliado, null
commentstring | nullComentário do cliente. Caso não avaliado, null
createdAtstring (ISO 8601) | nullData de criação da avaliação. Caso não avaliado, null
updatedAtstring (ISO 8601) | nullData da última atualização da avaliação. Caso não avaliado, null

device

Informações sobre o dispositivo usado para completar a compra (para detecção de fraude).

json
{
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
  "colorDepth": 24,
  "ip": "192.168.1.1",
  "javaEnabled": false,
  "language": "pt-BR",
  "screenHeight": 1080,
  "screenWidth": 1920,
  "timeZoneOffSet": -180,
  "fingerprint": "abc123def456",
  "geoip": {
    "ip": "192.168.1.1",
    "country": "BR",
    "region": "SP",
    "city": "São Paulo",
    "ll": "-23.5505,-46.6333"
  }
}
CampoTipoDescrição
userAgentstringUser Agent do navegador
colorDepthintegerProfundidade de cor do dispositivo
ipstringEndereço IP do cliente
javaEnabledbooleanSe Java está habilitado no navegador
languagestringIdioma do navegador (ex: pt-BR)
screenHeightintegerAltura da tela em pixels
screenWidthintegerLargura da tela em pixels
timeZoneOffSetintegerOffset do timezone em minutos
fingerprintstring | nullHash de fingerprinting do dispositivo
geoip.ipstringIP resolvido
geoip.countrystringPaís (ISO 3166-1 alpha-2)
geoip.regionstringRegião/Estado
geoip.citystringCidade
geoip.llstringCoordenadas latitude,longitude

stepVerification

Dados de verificação de etapa (código OTP para confirmação adicional).

json
{
  "code": "123456",
  "validAt": "2026-02-13T19:44:01.198Z"
}
CampoTipoDescrição
codestring | nullCódigo de verificação da etapa (6 dígitos). Caso não gerado, null
validAtstring (ISO 8601) | nullData e hora de validade do código. Caso não gerado, null

Ciclo de Vida e Estados

Estados de Pagamento

O status do pagamento segue uma máquina de estados:

open → pending → (paid → released | failed | canceled | expired)
     ↘ refunded ↙
     ↘ chargeback ↙
     ↘ in_protest ↙
EstadoDescrição
openPagamento aberto, aguardando processamento
pendingPagamento em processamento
paidPagamento confirmado pelo gateway
releasedPagamento liberado/liquidado
failedPagamento falhou
expiredPagamento expirou
canceledPagamento cancelado
refundedPagamento reembolsado
chargebackDisputa/chargeback iniciado
in_protestEm protesto (boleto)
latePagamento em atraso
up_to_datePagamento em dia
waiting_approvalAguardando aprovação manual
giftedPresente/cupom (sem cobrança)
voucherVoucher/vale (sem cobrança)
partially_paidPagamento foi parcialmente pago
partially_refundedPagamento foi parcialmente reembolsado

Bandeiras de Estado (State Flags)

Além do status de pagamento, a venda possui bandeiras de estado independentes:

FlagRelacionadoSignificado
confirmedconfirmedAtPagamento confirmado pelo gateway
completedcompletedAtVenda finalizada com sucesso
failedfailedAt, failureReasonPagamento falhou
canceledcanceledAtVenda cancelada
refundedrefundedAtReembolso processado
requiresApprovalapprovedAtAguardando aprovação

Ciclo Típico de Uma Compra

  1. Criação: Venda criada com payment.status = open
  2. Processamento: Status muda para pending
  3. Confirmação: Gateway confirma → confirmed = true, confirmedAt = now()
  4. Sucesso: Status muda para paidcompleted = true, completedAt = now()
  5. Liquidação: Status muda para released

Ciclo de Falha

  1. Criação: Venda criada com payment.status = open
  2. Processamento: Status muda para pending
  3. Falha: Gateway recusa → failed = true, failedAt = now(), failureReason = "Cartão recusado"

Validações

Nome do Cliente

✓ Mínimo 2 palavras
✓ Cada palavra com mínimo 2 caracteres
✓ Regex: (\S{2,}\s)(\S{2,}\s?)+
✗ "João" = falha (1 palavra)
✗ "Jo Silva" = falha (1º palavra < 2 chars)
✓ "John Doe Silva" = ok

Email

✓ Validação de email padrão
✓ Trimmed e lowercase
✗ Email inválido resulta em erro

StateLicense

✓ Apenas para documents.kind = 'cnpj'
✓ Validação específica de inscrição estadual
✗ Se document.kind = 'cpf' e stateLicense informado = erro

StepVerification.code

✓ Exatamente 6 dígitos/caracteres
✓ Obrigatório quando step verification é criado
✗ Menos de 6 ou mais de 6 caracteres = erro

Installments

✓ Inteiro
✓ Mínimo: 1
✓ Máximo: 36
✗ Decimais não são permitidos
✗ < 1 ou > 36 = erro

Relacionamentos

Venda (1) ← → Cobrança (N)

  • Uma Venda pode gerar múltiplas Cobrânças (uma por parcela)
  • Cada Cobrança referencia exatamente uma Venda
  • Relacionamento via saleId em Payable

Venda ← Checkout (1:1)

  • Um Checkout resulta em exatamente uma Venda
  • Relacionamento via checkoutId
  • Checkout é efêmero, Venda é permanente

Venda ← SaleGroup (N:1)

  • Múltiplas Vendas podem pertencer a um SaleGroup
  • Permite agrupar vendas relacionadas
  • Relacionamento via saleGroupId

Venda ← Customer (N:1)

  • Um Customer pode ter múltiplas Vendas
  • Relacionamento via customerId
  • Customer é o perfil persistente

Venda ← LineItem (1:N)

  • Uma Venda contém múltiplos LineItems (produtos comprados)
  • LineItem é snapshot da venda, não Item do catálogo
  • Relacionamento direto no array items

Comparação: Venda vs Cobrança vs Checkout

AspectoVendaCobrançaCheckout
EscopoVenda completaParcela individualSessão de compra
DuraçãoPermanenteAté liquidaçãoEfêmera
Relação1 por checkoutN por venda1 por venda
StatusMúltiplos flagsStatus únicoAberto/Fechado
HistóricoCompletoPor parcelaNão persistido
ClienteSnapshot completoReferênciaIncompleto