Registrar pagaments
Registra pagaments parcials contra factures i factures de compra, i consulta el saldo en curs des del ledger.
Les factures i les factures de compra mantenen un ledger de pagaments:
una llista de pagaments individuals, cadascun amb el seu propi import, data
i mètode. Registra els pagaments d'un en un a mesura que entra els diners —
l'API recalcula els imports cobrat i pendent després de cada
entrada i passa el document a paid quan el saldo arriba a zero.
No existeix un estat «parcialment pagada» a part. L'avanç del cobrament es
llegeix a partir de dos camps derivats, només de presentació, a la factura:
paid_amount (suma del ledger) i pending_amount
(total − paid_amount). Un document amb pending_amount > 0 continua
pending; aquell el pending_amount del qual arriba a 0 passa a paid.
Registrar un pagament de venda
POST /v1/invoices/{id}/payments afegeix un pagament a una factura de
venda. El body és petit:
| Camp | Tipus | Requerit | Notes |
|---|---|---|---|
amount | number | Sí | Més gran que 0. No pot superar pending_amount. |
paid_on | string (YYYY-MM-DD) | Sí | La data en què es va rebre els diners. |
payment_method | string (enum) | Sí | Un dels valors del catàleg (vegeu a sota). |
reference | string | No | La teva pròpia referència (p. ex. un número de transferència). |
notes | string | No | Nota interna lliure. |
payment_method és un enum tancat de set valors: bank_transfer,
direct_debit, cash, credit_card, check, paypal, other. Obtén el
catàleg amb etiquetes des de GET /v1/payment-methods
en lloc de fixar els valors a mà.
La resposta és 201 Created amb el pagament acabat de crear sota data:
{
"data": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b",
"object": "payment",
"invoice_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"amount": 500.00,
"payment_date": "2026-05-20",
"payment_method": "bank_transfer",
"payment_method_text": "Transferencia bancaria",
"reference": "TRF-2026-0042",
"notes": null,
"created_at": "2026-05-20T10:30:00Z",
"updated_at": "2026-05-20T10:30:00Z"
}
}import os, requests
resp = requests.post(
'https://api.factuarea.com/v1/invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01/payments',
json={
'amount': 500.00,
'paid_on': '2026-05-20',
'payment_method': 'bank_transfer',
'reference': 'TRF-2026-0042',
},
headers={'Authorization': f"Bearer {os.environ['FACTUAREA_API_KEY']}"},
)
resp.raise_for_status()
payment = resp.json()['data']
print(payment['id'], payment['amount'])const res = await fetch(
'https://api.factuarea.com/v1/invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01/payments',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.FACTUAREA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 500.0,
paid_on: '2026-05-20',
payment_method: 'bank_transfer',
reference: 'TRF-2026-0042',
}),
},
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data } = await res.json();
console.log(data.id, data.amount);curl -s -X POST \
https://api.factuarea.com/v1/invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01/payments \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 500.00,
"paid_on": "2026-05-20",
"payment_method": "bank_transfer",
"reference": "TRF-2026-0042"
}' | jq '.data'Pagaments parcials i saldo
El saldo en curs no viu a l'objecte del pagament — viu a la
factura. Després de registrar un o diversos pagaments, llegeix la
factura (GET /v1/invoices/{id}) per veure com està:
{
"data": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"object": "invoice",
"status": "pending",
"total": 1210.00,
"paid_amount": 500.00,
"pending_amount": 710.00,
"payments": {
"detail": [
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b",
"object": "payment",
"invoice_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"amount": 500.00,
"payment_date": "2026-05-20",
"payment_method": "bank_transfer",
"payment_method_text": "Transferencia bancaria",
"reference": "TRF-2026-0042",
"notes": null,
"created_at": "2026-05-20T10:30:00Z",
"updated_at": "2026-05-20T10:30:00Z"
}
],
"total": 500.00,
"pending": 710.00
}
}
}paid_amount/pending_amount— els totals cobrat i pendent. Sempre presents, calculats a partir del ledger.payments.total/payments.pending— les mateixes dues xifres, reflectides dins de l'objectepayments. Sempre presents.payments.detail— l'array de pagaments individuals. Es materialitza només a l'endpoint de detall (GET /v1/invoices/{id}); als endpoints de llistat arriba com a[](mentretotalipendingcontinuen poblats) perquè els llistats siguin lleugers. Fes servir el sub-recurs per obtenir el detall per separat.
Quan l'últim pagament tanca el saldo (pending_amount arriba a 0), la
factura passa a paid.
Un pagament l'amount del qual supera pending_amount es rebutja amb
422 i subcode: "payment_exceeds_pending_amount" (param: "amount").
Un pagament exactament igual a l'import pendent és vàlid i salda la
factura. Consulta Errors.
Llistar pagaments
GET /v1/invoices/{id}/payments retorna el ledger complet d'una factura,
del més recent al més antic. Una factura sense pagaments retorna
{ "data": [] }, mai un 404.
{
"data": [
{
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0b",
"object": "payment",
"invoice_id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a01",
"amount": 500.00,
"payment_date": "2026-05-20",
"payment_method": "bank_transfer",
"payment_method_text": "Transferencia bancaria",
"reference": "TRF-2026-0042",
"notes": null,
"created_at": "2026-05-20T10:30:00Z",
"updated_at": "2026-05-20T10:30:00Z"
}
]
}Pagaments de factura de compra
Les factures de compra mantenen el seu propi ledger (total_retention, la
retenció IRPF agregada, viu al recurs de la factura de compra). El contracte
és asimètric respecte al de venda — llegeix-lo amb atenció abans de
reutilitzar codi:
POST /v1/purchase_invoices/{id}/paymentsretorna201amb el pagament creat sotadata(objectepurchase_invoice_payment), no la factura completa.GET /v1/purchase_invoices/{id}/paymentsretorna{ "data": [...] }, del més recent al més antic.- El body afegeix un
bank_account_idopcional (enter), i aquípayment_methodés un string lliure (màx. 30 caràcters), no l'enum tancat que es fa servir al costat de venda.
| Camp | Tipus | Requerit | Notes |
|---|---|---|---|
amount | number | Sí | Més gran que 0. No pot superar l'import pendent. |
paid_on | string (YYYY-MM-DD) | Sí | Entre la data d'emissió i avui. |
payment_method | string | Sí | Text lliure, màx. 30 caràcters. |
bank_account_id | integer | No | Compte bancari des del qual es va fer el pagament. |
reference | string | No | La teva pròpia referència. |
notes | string | No | Nota interna lliure. |
{
"data": {
"id": "01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a0c",
"object": "purchase_invoice_payment",
"amount": 423.50,
"paid_on": "2026-05-21",
"payment_method": "transferencia",
"bank_account_id": 12,
"reference": "TRF-2026-0099",
"notes": null,
"created_at": "2026-05-21T09:00:00Z"
}
}import os, requests
resp = requests.post(
'https://api.factuarea.com/v1/purchase_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a05/payments',
json={
'amount': 423.50,
'paid_on': '2026-05-21',
'payment_method': 'transferencia',
'bank_account_id': 12,
},
headers={'Authorization': f"Bearer {os.environ['FACTUAREA_API_KEY']}"},
)
resp.raise_for_status()
print(resp.json()['data']['id'])const res = await fetch(
'https://api.factuarea.com/v1/purchase_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a05/payments',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.FACTUAREA_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: 423.5,
paid_on: '2026-05-21',
payment_method: 'transferencia',
bank_account_id: 12,
}),
},
);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data } = await res.json();
console.log(data.id);curl -s -X POST \
https://api.factuarea.com/v1/purchase_invoices/01931b3e-7c4a-7f2e-9a8b-3c5d6e7f8a05/payments \
-H "Authorization: Bearer $FACTUAREA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 423.50,
"paid_on": "2026-05-21",
"payment_method": "transferencia",
"bank_account_id": 12
}' | jq '.data'Les regles de pagament de la factura de compra (BR-PUR-019) s'apliquen
com a 422: un import per sobre del saldo pendent
(subcode: "payment_exceeds_pending_amount"), una data fora de
data_emissió … avui (subcode: "invalid_payment_date"), o un pagament
sobre una factura cancel·lada (subcode: "purchase_invoice_not_payable").
Mètodes de pagament
GET /v1/payment-methods retorna el catàleg tancat que dona suport al camp
payment_method de venda, cadascun amb un value i una etiqueta llegible
(en castellà). És un catàleg d'enum global — no específic d'empresa.
{
"data": [
{ "value": "bank_transfer", "label": "Transferencia bancaria" },
{ "value": "direct_debit", "label": "Domiciliación bancaria" },
{ "value": "cash", "label": "Efectivo" },
{ "value": "credit_card", "label": "Tarjeta de crédito" },
{ "value": "check", "label": "Cheque" },
{ "value": "paypal", "label": "PayPal" },
{ "value": "other", "label": "Otro" }
]
}Llegeix-lo un cop en arrencar i mostra les etiquetes a la teva interfície;
retorna el value a payment_method.
Errors
422payment_exceeds_pending_amount— l'import és més gran que el saldo pendent (param: "amount"). És una violació de regla de negoci, així que és422, mai409.409en unPOSTde pagament es reserva per a l'embolcall estàndard d'idempotència / conflicte (unIdempotency-Keyreutilitzat amb un body diferent, o un conflicte de concurrència) — no per a les dades del pagament en si.
Consulta Errors per a l'embolcall complet i el catàleg de codis.