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.