curl --request POST \
--url https://api.malga.io/v1/sessions/{id}/purchase \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"payments": [
{
"amount": 10000,
"paymentMethod": {
"paymentType": "credit",
"installments": 1
},
"paymentSource": {
"sourceType": "card",
"cardId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"cardCvv": "123"
}
},
{
"amount": 5000,
"paymentMethod": {
"paymentType": "credit",
"installments": 3
},
"paymentSource": {
"sourceType": "token",
"tokenId": "9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09"
}
}
]
}
'const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
payments: [
{
amount: 10000,
paymentMethod: {paymentType: 'credit', installments: 1},
paymentSource: {
sourceType: 'card',
cardId: '7c9e6679-7425-40de-944b-e07fc1f90ae7',
cardCvv: '123'
}
},
{
amount: 5000,
paymentMethod: {paymentType: 'credit', installments: 3},
paymentSource: {sourceType: 'token', tokenId: '9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09'}
}
]
})
};
fetch('https://api.malga.io/v1/sessions/{id}/purchase', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.malga.io/v1/sessions/{id}/purchase"
payload := strings.NewReader("{\n \"payments\": [\n {\n \"amount\": 10000,\n \"paymentMethod\": {\n \"paymentType\": \"credit\",\n \"installments\": 1\n },\n \"paymentSource\": {\n \"sourceType\": \"card\",\n \"cardId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n \"cardCvv\": \"123\"\n }\n },\n {\n \"amount\": 5000,\n \"paymentMethod\": {\n \"paymentType\": \"credit\",\n \"installments\": 3\n },\n \"paymentSource\": {\n \"sourceType\": \"token\",\n \"tokenId\": \"9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantId": "3b8c1f2a-4d5e-6f70-8192-a3b4c5d6e7f8",
"amount": 15000,
"currency": "BRL",
"capture": true,
"status": "pending",
"orderId": "pedido-1001",
"metadata": {
"channel": "checkout"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
],
"payments": [
{
"slotIndex": 0,
"amount": 10000,
"paymentMethod": {
"paymentType": "credit",
"installments": 1
},
"status": "pending",
"refundedAmount": 0,
"paymentSource": {
"sourceType": "card",
"cardId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
]
},
{
"slotIndex": 1,
"amount": 5000,
"paymentMethod": {
"paymentType": "credit",
"installments": 3
},
"status": "pending",
"refundedAmount": 0,
"paymentSource": {
"sourceType": "token",
"tokenId": "9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
]
}
],
"createdAt": "2026-07-27T18:00:00Z",
"updatedAt": "2026-07-27T18:00:00Z",
"operation": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "authorize",
"status": "pending"
}
}Pagar uma sessão com múltiplos cartões
Paga uma sessão configurada com paymentType: multiple, dividindo o valor entre 2 ou 3 cartões de crédito. A chamada cria uma Venda e responde 202: o processamento é assíncrono. Acompanhe o desfecho consultando a Venda e a sessão.
O valor total, o merchant, a moeda, o modo de captura, o orderId e as regras de split vêm da própria sessão. Você informa apenas os cartões em payments. A quantidade de cartões vai de 2 até o quantity configurado na sessão, a soma dos valores deve ser igual ao valor da sessão e as parcelas de cada cartão não podem passar do installments configurado. A moeda da sessão deve ser BRL.
Use este endpoint no lugar de POST /v1/sessions/{id}/charge: uma sessão com multiple não aceita paymentType: multiple no /charge.
O header X-Idempotency-Key é opcional aqui. Quando ausente, a Malga gera uma chave a partir da sessão e dos cartões enviados, e uma repetição idêntica devolve a mesma Venda. Informe os cartões por referência, com cardId ou tokenId. Dados de cartão em claro devolvem 422 com pan_not_allowed.
Enquanto uma Venda está em andamento, a sessão recusa novas chamadas com purchase_in_progress. Depois de uma Venda recusada (failed), a sessão volta a aceitar uma nova tentativa, com uma chave de idempotência nova. A liberação acontece no processamento assíncrono do desfecho, então uma tentativa feita no mesmo instante pode receber purchase_in_progress: tente de novo depois de alguns segundos. Uma Venda paga encerra a sessão.
curl --request POST \
--url https://api.malga.io/v1/sessions/{id}/purchase \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Client-Id: <api-key>' \
--data '
{
"payments": [
{
"amount": 10000,
"paymentMethod": {
"paymentType": "credit",
"installments": 1
},
"paymentSource": {
"sourceType": "card",
"cardId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"cardCvv": "123"
}
},
{
"amount": 5000,
"paymentMethod": {
"paymentType": "credit",
"installments": 3
},
"paymentSource": {
"sourceType": "token",
"tokenId": "9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09"
}
}
]
}
'const options = {
method: 'POST',
headers: {
'X-Client-Id': '<api-key>',
'X-Api-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
payments: [
{
amount: 10000,
paymentMethod: {paymentType: 'credit', installments: 1},
paymentSource: {
sourceType: 'card',
cardId: '7c9e6679-7425-40de-944b-e07fc1f90ae7',
cardCvv: '123'
}
},
{
amount: 5000,
paymentMethod: {paymentType: 'credit', installments: 3},
paymentSource: {sourceType: 'token', tokenId: '9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09'}
}
]
})
};
fetch('https://api.malga.io/v1/sessions/{id}/purchase', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.malga.io/v1/sessions/{id}/purchase"
payload := strings.NewReader("{\n \"payments\": [\n {\n \"amount\": 10000,\n \"paymentMethod\": {\n \"paymentType\": \"credit\",\n \"installments\": 1\n },\n \"paymentSource\": {\n \"sourceType\": \"card\",\n \"cardId\": \"7c9e6679-7425-40de-944b-e07fc1f90ae7\",\n \"cardCvv\": \"123\"\n }\n },\n {\n \"amount\": 5000,\n \"paymentMethod\": {\n \"paymentType\": \"credit\",\n \"installments\": 3\n },\n \"paymentSource\": {\n \"sourceType\": \"token\",\n \"tokenId\": \"9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Client-Id", "<api-key>")
req.Header.Add("X-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchantId": "3b8c1f2a-4d5e-6f70-8192-a3b4c5d6e7f8",
"amount": 15000,
"currency": "BRL",
"capture": true,
"status": "pending",
"orderId": "pedido-1001",
"metadata": {
"channel": "checkout"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
],
"payments": [
{
"slotIndex": 0,
"amount": 10000,
"paymentMethod": {
"paymentType": "credit",
"installments": 1
},
"status": "pending",
"refundedAmount": 0,
"paymentSource": {
"sourceType": "card",
"cardId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
]
},
{
"slotIndex": 1,
"amount": 5000,
"paymentMethod": {
"paymentType": "credit",
"installments": 3
},
"status": "pending",
"refundedAmount": 0,
"paymentSource": {
"sourceType": "token",
"tokenId": "9f8e7d6c-5b4a-3928-1706-5e4d3c2b1a09"
},
"splitRules": [
{
"sellerId": "11111111-1111-1111-1111-111111111111",
"percentage": 60,
"processingFee": true,
"liable": true
},
{
"sellerId": "22222222-2222-2222-2222-222222222222",
"percentage": 40,
"processingFee": false,
"liable": false
}
]
}
],
"createdAt": "2026-07-27T18:00:00Z",
"updatedAt": "2026-07-27T18:00:00Z",
"operation": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "authorize",
"status": "pending"
}
}Headers
Chave de idempotência da chamada. Quando ausente, a Malga gera uma a partir da sessão e dos cartões enviados
Path Parameters
Identificador da sessão a ser paga
Body
Cartões da Venda e dados opcionais. Valor total, merchant, moeda, modo de captura, orderId e regras de split vêm da sessão
Cartões da Venda, de 2 até o quantity configurado na sessão
2 - 3 elementsShow child attributes
Show child attributes
Identificador de um customer para atribuir a Venda. Se ele não pertencer ao seu cliente, a Malga o ignora e o pagamento segue sem a atribuição
Dados de antifraude da Venda, informados uma única vez. A Malga repete o objeto em cada cobrança da Venda. O campo faz parte da comparação de idempotência e nunca é retornado nas respostas, por conter dados pessoais do comprador. Dados de cartão em claro devolvem 422 com pan_not_allowed.
Show child attributes
Show child attributes
Pares de chave e valor livres, devolvidos na resposta. Dados de cartão em claro devolvem 422 com pan_not_allowed
Response
Venda aceita com status: pending, ou repetição idempotente com o estado atual da Venda. O corpo é o mesmo de POST /v1/purchases, com o sessionId da sessão
Venda paga com 2 ou 3 cartões
Identificador da Venda
Identificador do merchant da Venda
Valor total da Venda em centavos
x >= 200BRL Indica o modo de captura informado na criação. false exige captura explícita; true captura automaticamente
Status da Venda
pending, paid, failed, cancelled 2 - 3 elementsShow child attributes
Show child attributes
Sinal de que a Venda precisa de revisão. A Venda permanece pending e você deve interromper o polling automático
Show child attributes
Show child attributes
Operação pending ou processing em andamento na Venda (a mais recente). Omitido quando não há operação ativa. Nas respostas 202, a operação aceita vem em operation
Show child attributes
Show child attributes
Identificador do pedido no seu sistema
Session de origem informada na criação
Metadados informados na criação. Omitido quando não enviados
Regras de split informadas na criação. Omitido quando não enviadas
Show child attributes
Show child attributes
Operação assíncrona aceita por esta chamada. Na criação, vem com type: authorize e pode ser omitida numa repetição idempotente
Show child attributes
Show child attributes
Was this page helpful?