Saltar al contenido principal

Comprobante de Pago

El comprobante de tipo Pago, también llamado Recibo Electrónico de Pago (REP), o simplemente complemento de pago se utiliza para dar constancia fiscal de que la empresa o la persona recibió un pago por una mercancía o servicio entregado con anterioridad.

Para emitir un comprobante de tipo Pago, debe existir un Comprobante de Ingreso que se haya creado al momento de la entrega de la mercancía o servicio, y cuyo método de pago se haya registrado el valor "PPD" (Pago en Parcialidades o Diferido).

Ejemplos​

A continuación se enlistan algunos casos de uso comunes.

Para conocer a fondo todas las opciones disponibles al crear un Comprobante de Pago, descripciones detalladas de cada campo y los catálogos más utilizados consulta la referencia del método Crear Factura, y posteriormente haz clic sobre el tipo de factura Pago.

Pago total de una factura pendiente​

En este ejemplo, se recibe un sólo pago para liquidar el total de una factura pendiente de pago por $345.60 MXN.

import Facturapi from 'facturapi'
const facturapi = new Facturapi('sk_test_API_KEY');

const invoice = await facturapi.invoices.create({
type: 'P',
customer: {
legal_name: 'Dunder Mifflin',
email: 'email@example.com',
tax_id: 'ABC101010111',
tax_system: '601',
address: {
zip: '85900'
}
},
complements: [
{
type: 'pago',
data: [{
payment_form: '28', // Tarjeta de Crédito
related_documents: [
{
uuid: '39c85a3f-275b-4341-b259-e8971d9f8a94',
amount: 345.60,
installment: 1,
last_balance: 345.60,
taxes: [
{
base: 297.93,
type: 'IVA',
rate: 0.16
}
]
}
]
}]
}
]
});

Pago en parcialidades de una factura pendiente​

En este ejemplo, se reciben $100 MXN como pago por la segunda parcialidad de una factura pendiente de pago cuyo total era de $345.60 MXN. Se considera que en la primera parcialidad también se pagaron $100 MXN.

import Facturapi from 'facturapi'
const facturapi = new Facturapi('sk_test_API_KEY');

const invoice = await facturapi.invoices.create({
type: 'P',
customer: {
legal_name: 'Dunder Mifflin',
email: 'email@example.com',
tax_id: 'ABC101010111',
tax_system: '601',
address: {
zip: '85900'
}
},
complements: [
{
type: 'pago',
data: [{
payment_form: '28', // Tarjeta de Crédito
related_documents: [
{
uuid: '39c85a3f-275b-4341-b259-e8971d9f8a94',
amount: 100, // Monto de la factura relacionada que se paga en la presente parcialidad
installment: 2, // Esta es la segunda parcialidad
last_balance: 245.60, // Saldo insoluto de la primera parcialidad
taxes: [
{
base: 86.21, // Base de IVA de la segunda parcialidad
type: 'IVA',
rate: 0.16
}
]
}
]
}]
}
]
});

Resumen de pago​

Para construir los related_documents de un Complemento de Pago necesitas, por cada factura relacionada: el número de parcialidad que corresponde, el saldo anterior y el desglose de impuestos prorrateado al monto que se paga. Calcular estos valores a mano es propenso a errores, sobre todo en pagos en varias parcialidades o con retenciones.

El endpoint Resumen de pago hace ese cálculo por ti: devuelve el objeto related_document listo para agregarse al complemento.

import Facturapi from 'facturapi'
const facturapi = new Facturapi('sk_test_API_KEY');

// Monto que se paga de esta factura, en la divisa de la factura.
// No puede exceder el saldo pendiente (amount_due).
const summary = await facturapi.invoices.paymentSummary(
'58e93bd8e86eb318b019743d',
{ amount: 100 }
);

// El resumen es un elemento de related_documents listo para usarse
const invoice = await facturapi.invoices.create({
type: 'P',
customer: customer.id,
complements: [
{
type: 'pago',
data: [
{
payment_form: '28',
related_documents: [summary]
}
]
}
]
});

Cada resumen contiene, listo para el CFDI: uuid, installment (la parcialidad que corresponde según el historial de pagos), last_balance (el saldo anterior), amount (el monto pagado en esta parcialidad) y taxes con las bases e impuestos ya prorrateados al monto pagado. No necesitas mapear nada: el objeto completo va como elemento de related_documents.

Un pago que cubre varias facturas​

Cuando un mismo pago liquida varias facturas, pide un resumen por factura con el monto que le corresponde a cada una y arma el complemento con todos los resúmenes:

import Facturapi from 'facturapi'
const facturapi = new Facturapi('sk_test_API_KEY');

// Los montos que decide el negocio: cuánto se abona a cada factura.
const pagos = [
{ invoiceId: '58e93bd8e86eb318b019743d', amount: 100 },
{ invoiceId: '7f104ce9f97eb428c130854e', amount: 250 }
];

const related_documents = await Promise.all(
pagos.map(({ invoiceId, amount }) =>
facturapi.invoices.paymentSummary(invoiceId, { amount })
)
);

const invoice = await facturapi.invoices.create({
type: 'P',
customer: customer.id,
complements: [
{
type: 'pago',
data: [
{
payment_form: '28',
related_documents
}
]
}
]
});

Si el monto excede el saldo de alguna factura, el endpoint responde un error (amount_exceeds_related_document_balance) antes de crear nada. Lo mismo sucede si la factura no es candidata a pago: el endpoint solo acepta facturas de ingreso timbradas con método de pago PPD que sigan vigentes.