Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [4.17.0] 2026-04-27
### Added
- Add `receipts.toInvoice` to create customer invoices from multiple receipt keys.
- Add `receipts.previewToInvoicePdf` to generate PDF previews for to-invoice payloads.

## [4.16.0] 2026-04-23
### Added
- Add new export catalogs for customs regimes, transport keys, SCT permits, COFEPRIS sectors, pharmaceutical forms, special transport conditions, customs documents, transport types, transport figures, ISTMO registry, loading keys, maritime configurations, rail traffic, containers, rail cars, rail service types, transfer reasons, incoterms, and customs units.
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "facturapi",
"version": "4.15.0",
"version": "4.16.0",
"description": "SDK oficial de Facturapi para Node.js y navegadores. Integra facturación electrónica en México (CFDI) de forma simple y obtén una perspectiva fiscal completa de tu operación, con búsquedas indexadas, envío de documentos y trazabilidad.",
"main": "dist/index.cjs.js",
"module": "dist/index.es.js",
Expand Down Expand Up @@ -95,4 +95,4 @@
"vite": "^8.0.3",
"vitest": "^4.1.2"
}
}
}
53 changes: 39 additions & 14 deletions src/resources/receipts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@ import {
BinaryDownload,
GenericResponse,
Invoice,
ReceiptsToInvoiceInput,
Receipt,
SearchResult,
SendEmailBody,
} from '../types';
import { WrapperClient } from '../wrapper';
PreviewReceiptsToInvoicePdfInput,
} from '../types'
import { WrapperClient } from '../wrapper'

export default class Receipts {
client: WrapperClient;
client: WrapperClient
constructor(client: WrapperClient) {
this.client = client;
this.client = client
}

/**
Expand All @@ -20,7 +22,7 @@ export default class Receipts {
* @returns Receipt object
*/
create(data: Record<string, any>): Promise<Receipt> {
return this.client.post('/receipts', { body: data });
return this.client.post('/receipts', { body: data })
}

/**
Expand All @@ -29,8 +31,8 @@ export default class Receipts {
* @returns Search results object. The object contains a `data` property with the list of receipts.
*/
list(params?: Record<string, any> | null): Promise<SearchResult<Receipt>> {
if (!params) params = {};
return this.client.get('/receipts', { params });
if (!params) params = {}
return this.client.get('/receipts', { params })
}

/**
Expand All @@ -39,8 +41,8 @@ export default class Receipts {
* @returns Receipt object
*/
retrieve(id: string): Promise<Receipt> {
if (!id) return Promise.reject(new Error('id is required'));
return this.client.get('/receipts/' + id);
if (!id) return Promise.reject(new Error('id is required'))
return this.client.get('/receipts/' + id)
}

/**
Expand All @@ -50,7 +52,7 @@ export default class Receipts {
* @returns Invoice object
*/
invoice(id: string, data: Record<string, any>): Promise<Invoice> {
return this.client.post('/receipts/' + id + '/invoice', { body: data });
return this.client.post('/receipts/' + id + '/invoice', { body: data })
}

/**
Expand All @@ -59,7 +61,30 @@ export default class Receipts {
* @returns
*/
createGlobalInvoice(data: Record<string, any>): Promise<Invoice> {
return this.client.post('/receipts/global-invoice', { body: data });
return this.client.post('/receipts/global-invoice', { body: data })
}

/**
* Creates an invoice from multiple receipts by key.
* Supports dry-run summaries when `dry_run` is true.
* @param data Receipts to-invoice request data
* @returns Invoice object or dry-run summary
*/
toInvoice(data: ReceiptsToInvoiceInput): Promise<Invoice> {
return this.client.post('/receipts/to-invoice', { body: data })
}

/**
* Generates a PDF preview for a receipts-to-invoice request before stamping.
* @param data Receipts-to-invoice preview data
* @returns PDF file in a stream (Node.js) or Blob (browser)
*/
previewToInvoicePdf(
data: PreviewReceiptsToInvoicePdfInput,
): Promise<BinaryDownload> {
return this.client.post('/receipts/to-invoice/preview/pdf', {
body: data,
})
}

/**
Expand All @@ -68,7 +93,7 @@ export default class Receipts {
* @returns
*/
cancel(id: string): Promise<Receipt> {
return this.client.delete('/receipts/' + id);
return this.client.delete('/receipts/' + id)
}

/**
Expand All @@ -79,7 +104,7 @@ export default class Receipts {
* @returns Email sent confirmation
*/
sendByEmail(id: string, data?: SendEmailBody): Promise<GenericResponse> {
return this.client.post('/receipts/' + id + '/email', { body: data });
return this.client.post('/receipts/' + id + '/email', { body: data })
}

/**
Expand All @@ -88,6 +113,6 @@ export default class Receipts {
* @returns PDF file in a stream (Node.js) or Blob (browser)
*/
downloadPdf(id: string): Promise<BinaryDownload> {
return this.client.get('/receipts/' + id + '/pdf');
return this.client.get('/receipts/' + id + '/pdf')
}
}
59 changes: 37 additions & 22 deletions src/types/receipt.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
import type { ReceiptStatus } from '../enums';
import type { InvoiceItem } from './common';
import type { ReceiptStatus } from '../enums'
import type { InvoiceItem } from './common'
import type { Invoice } from './invoice'

export interface Receipt {
id: string;
created_at: Date;
date: Date;
api_version: number;
livemode: boolean;
organization: string;
folio_number?: number;
external_id?: string;
idempotency_key?: string;
branch: string;
payment_form: string;
items: InvoiceItem[];
currency: string;
exchange: number;
total: number;
invoice: string;
expires_at: Date;
key: string;
status: ReceiptStatus;
self_invoice_url: string;
id: string
created_at: Date
date: Date
api_version: number
livemode: boolean
organization: string
folio_number?: number
external_id?: string
idempotency_key?: string
branch: string
payment_form: string
items: InvoiceItem[]
currency: string
exchange: number
total: number
invoice: string
expires_at: Date
key: string
status: ReceiptStatus
self_invoice_url: string
}

export interface ReceiptsToInvoiceInput {
keys: string[]
customer?: Record<string, any>
use?: string
dry_run?: boolean
payment_form?: string | null
}

export interface PreviewReceiptsToInvoicePdfInput {
keys: string[]
customer?: Record<string, any> | null
use?: string
}
Loading
Loading