Skip to main content
Com múltiplos cartões, você cobra um mesmo pedido em 2 ou 3 cartões de crédito em uma única operação. A cobrança é representada por uma Venda (purchase), que reúne o valor total e o valor de cada cartão. A Malga realiza o papel de hub de pagamentos, porém não realiza a liquidação financeira. Você envia os dados da Venda para o serviço de Purchases e a Malga processa a cobrança de cada cartão com os adquirentes e PSPs.

Regras da Venda

  • A Venda tem de 2 a 3 cartões em payments.
  • Todos os cartões são de crédito (paymentType: credit) e a moeda é BRL.
  • O valor total (amount) deve ser igual à soma dos valores dos cartões. O mínimo é de 200 centavos para a Venda e de 100 centavos para cada cartão.
  • Cada cartão é informado por referência, com cardId (cartão salvo) ou tokenId (token de cartão). Dados de cartão em claro são recusados com pan_not_allowed.
  • Cada cartão define o próprio número de parcelas em paymentMethod.installments.
  • A Malga processa os cartões na ordem em que eles aparecem em payments, a partir do slotIndex 0.

Fluxo de pagamento

Para cobrar por um link de pagamento ou por uma Session, crie a Session com um item paymentType: "multiple" em paymentMethods. A configuração está em Criar link de pagamento via API. Depois, pague a Session em POST /v1/sessions/{id}/purchase. O valor, o merchant, a moeda, o modo de captura e as regras de split vêm da Session. Você informa apenas os cartões em payments, de 2 até o quantity configurado, e cada cartão respeita o limite de installments da Session. A chamada cria uma Venda e segue o mesmo fluxo descrito nesta página.
Uma Session com múltiplos cartões não aceita paymentType: multiple em POST /v1/sessions/{id}/charge. Use sempre o endpoint /purchase.

Captura

O campo capture da criação define o que acontece depois das autorizações:
A captura explícita só vale para Vendas criadas com capture: false. Em uma Venda criada com capture: true, a rota de captura devolve 409 com purchase_invalid_state.

Status da Venda

Cada cartão da Venda também tem um status próprio em payments[].status: pending, processing, undetermined, pre_authorized, authorized, failed, voided, canceled ou charged_back. O status authorized indica cartão capturado.
Se uma Venda pending trouxer o campo pendingReview, interrompa o polling automático. O campo indica uma anomalia no processamento (reconciliation_failed, amount_mismatch ou claims_exhausted) e a Venda permanece pending.

Exemplo de cobrança

O exemplo a seguir cria uma Venda de R$ 150,00 em dois cartões, com captura automática.
cURL
A resposta 202 traz a Venda com status: pending e a operação authorize em andamento:
Resposta 202

Notificações por webhook

Em vez de consultar a Venda continuamente, você pode receber os eventos purchase.* no seu endpoint: purchase.created, purchase.charge_authorized, purchase.pre_authorized, purchase.paid, purchase.failed, purchase.cancelled e purchase.void_failed. Cadastre o webhook na versão 1.1. Uma versão anterior não recebe eventos de Venda. Use a notificação como gatilho e confirme o estado em GET /v1/purchases/{id} antes de liberar o pedido. O formato de cada evento está em Webhooks v1.1.

Idempotência

O header X-Idempotency-Key é obrigatório na criação, na captura e no cancelamento de uma Venda.
  • Reenviar a mesma chave com o mesmo corpo devolve 202 com o estado atual da Venda.
  • Reenviar a mesma chave com um corpo diferente, ou com uma chave já usada em outra operação, devolve 409 com idempotency_key_payload_mismatch.

Cancelamento e estorno

Use POST /v1/purchases/{id}/void para desfazer uma Venda, com o campo opcional intent:
  • cancel: cancela as pré-autorizações de uma Venda pending. A Venda termina cancelled.
  • refund: estorna o valor integral de uma Venda paid. A Venda permanece paid.
Envie intent explicitamente para garantir que um cancelamento nunca vire estorno, caso a Venda seja capturada entre a sua leitura e a chamada.

Split

A Venda aceita splitRules no nível raiz, informado uma única vez para o pedido. A resposta devolve a parcela correspondente a cada cartão em payments[].splitRules.