Pagamentos Pix
O Pix é o trilho de pagamento instantâneo brasileiro. O dinheiro liquida em segundos, 24 horas por dia, todo dia. A Orbita Pay te dá um endpoint só que devolve o BR Code (Pix Copia e Cola) e o QR Code prontos para renderizar no seu checkout — na mesma resposta que cria a cobrança.
#O fluxo, de relance
1. POST /v1/charges ────────▶ a Orbita Pay devolve a Cobrança: ch_…, status "pending", pix.br_code + QR
2. Você renderiza o QR e o Pix Copia e Cola na sua tela
3. O cliente escaneia ou cola no app do banco dele
4. O webhook charge.paid chega no seu endpoint
5. Você libera o pedido#1. Criar a cobrança
Endpoint POST /v1/charges (atalho Pix-first: POST /v1/pix/charges já fixa payment_method: "pix" e devolve exatamente a mesma Cobrança)
Cabeçalhos
apikey: lq_live_...
Idempotency-Key: <único por cobrança que você pretende criar>
Content-Type: application/jsonCorpo
| Campo | Tipo | Obrigatório | Observação |
|---|---|---|---|
amount | inteiro | sim | Centavos. 1000 = R$ 10,00. Precisa ser inteiro positivo. |
currency | string | não | Padrão "BRL" — a única moeda que cobrança Pix aceita. |
payment_method | string | sim | "pix" (único valor aceito hoje; o atalho /v1/pix/charges preenche por você). |
description | string | não | Até 500 caracteres. Volta dentro de metadata.description. |
expires_in | inteiro | não | Segundos até a cobrança expirar (o tempo de vida do QR Pix). 60–86400 (24 h — o teto de uma cobrança Pix imediata; valores maiores são limitados). Omita para usar a janela padrão da conta (geralmente 3600 = 1 h). O pix.expires_at na resposta é sempre a expiração autoritativa. |
customer.name | string | não | Aparece no extrato do banco quando o provedor suporta. |
customer.document | string | não | CPF ou CNPJ. |
customer.email | string | não | Usado em comprovante. |
customer.phone | string | não | |
expected_payer_tax_id | string | não | Trava de CPF do pagador (opt-in). O CPF/CNPJ (11 ou 14 dígitos) que DEVE pagar esta cobrança. Um pagamento de qualquer outro documento é devolvido automaticamente — veja Trava de CPF do pagador abaixo. Exige customer.name. Precisa ser um CPF/CNPJ válido e, se você também enviar customer.document, precisa coincidir com ele. |
metadata | objeto | não | Chave/valor livre, devolvido igual (chaves reservadas e iniciadas com _ são removidas). |
Exemplo
curl -X POST https://liqfy.com.br/v1/charges \
-H "apikey: $LIQFY_API_KEY" \
-H "Idempotency-Key: ORD-7821" \
-H "Content-Type: application/json" \
-d '{
"amount": 24900,
"currency": "BRL",
"payment_method": "pix",
"description": "Pedido #7821",
"expires_in": 1800,
"customer": { "name": "Maria Silva", "document": "12345678901" },
"metadata": { "order_id": "ORD-7821", "sku": "premium-mensal" }
}'Resposta 201 Created
{
"id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
"object": "charge",
"amount": 24900,
"currency": "BRL",
"status": "pending",
"payment_method": "pix",
"customer": { "name": "Maria Silva", "document": "12345678901" },
"pix": {
"br_code": "000201BRCODEPIX",
"qr_code_url": "https://qr.example/img.png",
"expires_at": "2026-07-23T15:00:00.000Z"
},
"checkout_url": "https://checkout.liqfy.com.br/a1b2c3d4-0000-0000-0000-000000000009",
"settlement": {},
"metadata": { "order_id": "ORD-7821", "sku": "premium-mensal", "description": "Pedido #7821" },
"created_at": "2026-07-23T14:30:00.000Z"
}| Campo | O que fazer com ele |
|---|---|
pix.br_code | O payload EMV do "Pix Copia e Cola". Renderize num botão de copiar. |
pix.qr_code_url / qr_code_base64 | Um dos dois sempre vem quando o Pix está disponível. Jogue a URL num <img src="...">, ou decodifique o PNG em base64. |
checkout_url | O checkout hospedado da Orbita Pay para esta cobrança — uma página de pagamento pronta (QR, copia-e-cola, status ao vivo). Redirecione o pagador para cá em vez de montar a sua própria tela. Também vem no GET /v1/charges/{id}, então dá para buscar depois a partir de um id guardado. Você não consegue montar essa URL sozinho: o checkout espera o id sem o prefixo ch_. |
pix.expires_at | Quando a cobrança expira. Mostre uma contagem regressiva; depois disso o status vira expired. |
pix.txid | TXID do BACEN — opcional, só aparece quando o provedor vinculou um. Nunca trate como id da cobrança. |
settlement | {} na criação. O settlement.end_to_end_id só aparece depois que a cobrança chega em paid e foi liquidada/conciliada — nunca na criação. |
#TXID e end_to_end_id
ch_… é sempre o id Orbita Pay da cobrança — o que você guarda, consulta e usa para conciliar webhook. pix.txid e settlement.end_to_end_id são dado contextual do Pix definido pelo BACEN, expostos só quando se aplicam:
{
"id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
"pix": { "txid": "BACEN-TXID-77" },
"settlement": {}
}charge.id !== charge.pix.txid, sempre — mesmo quando os dois existem. Nunca chaveie seu banco pelo TXID nem pelo end_to_end_id; use o ch_….
#Trava de CPF do pagador
Use expected_payer_tax_id para exigir que apenas um CPF/CNPJ específico pague a cobrança — por exemplo, garantir que o comprador pague da própria conta, e não de um terceiro.
curl -X POST https://liqfy.com.br/v1/charges \
-H "apikey: $LIQFY_API_KEY" \
-H "Idempotency-Key: ORD-7821" \
-H "Content-Type: application/json" \
-d '{
"amount": 24900,
"payment_method": "pix",
"customer": { "name": "Maria Silva", "document": "12345678901" },
"expected_payer_tax_id": "12345678901"
}'Como funciona:
- A cobrança é criada e paga como qualquer outra cobrança Pix.
- Na liquidação, a Orbita Pay lê o documento real do pagador no banco e compara com
expected_payer_tax_id. - Coincide → a cobrança vira
paide seu saldo é creditado, normalmente. - Pagou um documento diferente → a cobrança NÃO é creditada. A Orbita Pay devolve o dinheiro automaticamente a quem pagou (uma devolução Pix padrão, endereçada pelo
end_to_end_idoriginal) e a cobrança terminarefunded. Você nunca recebe dinheiro de terceiro. - O banco não informou o documento do pagador → a cobrança fica em
processing(nunca creditada) para revisão manual, em vez de creditar um pagador não verificável.
Observações:
- É uma garantia no momento da liquidação, não um bloqueio no banco: o BACEN deixa qualquer pagador ler o QR, então o app do pagador ainda pode exibir a cobrança. A proteção é que um pagamento que não coincide é capturado e devolvido automaticamente — seu saldo de lojista só é creditado para um pagador que coincide.
expected_payer_tax_idexigecustomer.name(necessário na cobrança e para a devolução), precisa ser um CPF (11 dígitos) ou CNPJ (14 dígitos) com dígito verificador válido e — se você também enviarcustomer.document— precisa coincidir com ele. Caso contrário, a requisição é rejeitada com400.- O valor é devolvido na cobrança (
expected_payer_tax_id); o documento real do pagador nunca é exposto.
#2. Consultar a cobrança
Endpoint GET /v1/charges/{id}
curl https://liqfy.com.br/v1/charges/ch_a1b2c3d4-0000-0000-0000-000000000009 \
-H "apikey: $LIQFY_API_KEY"Aceita tanto o id com prefixo ch_ quanto o id cru. Depois que o Pix é pago e liquidado, o settlement.end_to_end_id aparece e o status vira paid:
{
"id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
"object": "charge",
"status": "paid",
"amount": 24900,
"currency": "BRL",
"payment_method": "pix",
"customer": { "name": "Maria Silva", "document": "12345678901" },
"settlement": { "end_to_end_id": "E-END-TO-END-99" },
"metadata": { "order_id": "ORD-7821" },
"created_at": "2026-07-23T14:30:00.000Z"
}#Consultar em laço ou usar webhook?
Use exclusivamente webhook para liberar pedido e gravar no banco — o webhook é a fonte da verdade. O GET /v1/charges/{id} serve para consulta pontual (ferramenta de suporte, um botão "verificar status" que alguém aperta), não para ficar consultando em laço.
#3. Receber o webhook
Quando o pagador paga, você recebe um POST assinado no seu endpoint registrado, com o envelope canônico de evento:
{
"id": "evt_5f3a9b2c1d4e5f6a7b8c9d0e1f2a3b4c",
"object": "event",
"api_version": "2026-07-23",
"type": "charge.paid",
"created_at": "2026-07-23T14:31:00.000Z",
"data": {
"object": {
"id": "ch_a1b2c3d4-0000-0000-0000-000000000009",
"object": "charge",
"amount": 24900,
"currency": "BRL",
"status": "paid",
"payment_method": "pix",
"settlement": { "end_to_end_id": "E-END-TO-END-99" }
}
}
}Veja Webhooks para verificação de assinatura, retentativa e registro do endpoint.
#Exemplos de código
Os trechos abaixo usam HTTP direto. Se preferir, há SDKs oficiais para Node.js, Python e .NET, que já cuidam de idempotência, retry e verificação de webhook.
#Node.js (fetch)
const res = await fetch('https://liqfy.com.br/v1/charges', {
method: 'POST',
headers: {
'apikey': process.env.LIQFY_API_KEY,
'Idempotency-Key': pedido.id,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 24900,
currency: 'BRL',
payment_method: 'pix',
customer: { name: pedido.cliente.nome, document: pedido.cliente.documento },
metadata: { order_id: pedido.id },
}),
});
if (!res.ok) throw new Error(`Orbita Pay ${res.status}: ${await res.text()}`);
const cobranca = await res.json();
// cobranca.id (ch_…) → guarde no pedido
// cobranca.pix.br_code / qr_code_url → renderize na hora#PHP
$ch = curl_init('https://liqfy.com.br/v1/charges');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'apikey: ' . getenv('LIQFY_API_KEY'),
'Idempotency-Key: ' . $pedido->id,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 24900,
'currency' => 'BRL',
'payment_method' => 'pix',
'customer' => ['name' => $pedido->nomeCliente],
'metadata' => ['order_id' => $pedido->id],
]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 201) throw new Exception("Orbita Pay $status: $body");
$cobranca = json_decode($body, true);#Python (requests)
import os, requests
r = requests.post(
"https://liqfy.com.br/v1/charges",
headers={
"apikey": os.environ['LIQFY_API_KEY'],
"Idempotency-Key": pedido.id,
},
json={
"amount": 24900,
"currency": "BRL",
"payment_method": "pix",
"customer": {"name": pedido.cliente.nome},
"metadata": {"order_id": pedido.id},
},
timeout=10,
)
r.raise_for_status()
cobranca = r.json()#Casos de borda e dúvidas
P: Os campos pix.br_code / QR não vieram na resposta.
R: A criação Pix-first devolve os dois de forma síncrona. Se faltarem, o status normalmente já vem failed — confira primeiro se a requisição não tem erro de validação (GET /v1/charges/{id} relê a cobrança guardada).
P: Por quanto tempo o QR vale?
R: Veja o pix.expires_at da cobrança — é definido por cobrança. Depois de expirar, o status vira expired e é preciso criar uma cobrança nova.
P: Dá para estornar uma cobrança Pix?
R: Sim — POST /v1/payments/{id}/refund, total ou parcial (tire o prefixo ch_ para obter o id que ele espera). Veja a Referência da API. Um atalho /v1/charges/{id}/refund ainda não existe.
P: Pago taxa se o cliente nunca pagar?
R: Não. A taxa incide só em cobrança paid, e nunca é discriminada na resposta pública de charge.
P: Meu cliente pagou o valor errado.
R: O Pix é de valor exato. Cobrança paga a menor continua pending e o banco devolve o pagador. Pagar a mais é raro, e é tratado do mesmo jeito.