Skip to content

Commit 36f52ea

Browse files
Merge pull request #101 from FacturAPI/chore/multi-invoice_receipts
chore(multiInvoices): add new methods for receipts to invoice
2 parents 4e64fb9 + 96af720 commit 36f52ea

7 files changed

Lines changed: 457 additions & 258 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
66
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
77

8+
## [4.17.0] 2026-04-27
9+
### Added
10+
- Add `receipts.toInvoice` to create customer invoices from multiple receipt keys.
11+
- Add `receipts.previewToInvoicePdf` to generate PDF previews for to-invoice payloads.
12+
813
## [4.16.0] 2026-04-23
914
### Added
1015
- 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.

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "facturapi",
3-
"version": "4.15.0",
3+
"version": "4.16.0",
44
"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.",
55
"main": "dist/index.cjs.js",
66
"module": "dist/index.es.js",
@@ -95,4 +95,4 @@
9595
"vite": "^8.0.3",
9696
"vitest": "^4.1.2"
9797
}
98-
}
98+
}

src/resources/receipts.ts

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@ import {
22
BinaryDownload,
33
GenericResponse,
44
Invoice,
5+
ReceiptsToInvoiceInput,
56
Receipt,
67
SearchResult,
78
SendEmailBody,
8-
} from '../types';
9-
import { WrapperClient } from '../wrapper';
9+
PreviewReceiptsToInvoicePdfInput,
10+
} from '../types'
11+
import { WrapperClient } from '../wrapper'
1012

1113
export default class Receipts {
12-
client: WrapperClient;
14+
client: WrapperClient
1315
constructor(client: WrapperClient) {
14-
this.client = client;
16+
this.client = client
1517
}
1618

1719
/**
@@ -20,7 +22,7 @@ export default class Receipts {
2022
* @returns Receipt object
2123
*/
2224
create(data: Record<string, any>): Promise<Receipt> {
23-
return this.client.post('/receipts', { body: data });
25+
return this.client.post('/receipts', { body: data })
2426
}
2527

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

3638
/**
@@ -39,8 +41,8 @@ export default class Receipts {
3941
* @returns Receipt object
4042
*/
4143
retrieve(id: string): Promise<Receipt> {
42-
if (!id) return Promise.reject(new Error('id is required'));
43-
return this.client.get('/receipts/' + id);
44+
if (!id) return Promise.reject(new Error('id is required'))
45+
return this.client.get('/receipts/' + id)
4446
}
4547

4648
/**
@@ -50,7 +52,7 @@ export default class Receipts {
5052
* @returns Invoice object
5153
*/
5254
invoice(id: string, data: Record<string, any>): Promise<Invoice> {
53-
return this.client.post('/receipts/' + id + '/invoice', { body: data });
55+
return this.client.post('/receipts/' + id + '/invoice', { body: data })
5456
}
5557

5658
/**
@@ -59,7 +61,30 @@ export default class Receipts {
5961
* @returns
6062
*/
6163
createGlobalInvoice(data: Record<string, any>): Promise<Invoice> {
62-
return this.client.post('/receipts/global-invoice', { body: data });
64+
return this.client.post('/receipts/global-invoice', { body: data })
65+
}
66+
67+
/**
68+
* Creates an invoice from multiple receipts by key.
69+
* Supports dry-run summaries when `dry_run` is true.
70+
* @param data Receipts to-invoice request data
71+
* @returns Invoice object or dry-run summary
72+
*/
73+
toInvoice(data: ReceiptsToInvoiceInput): Promise<Invoice> {
74+
return this.client.post('/receipts/to-invoice', { body: data })
75+
}
76+
77+
/**
78+
* Generates a PDF preview for a receipts-to-invoice request before stamping.
79+
* @param data Receipts-to-invoice preview data
80+
* @returns PDF file in a stream (Node.js) or Blob (browser)
81+
*/
82+
previewToInvoicePdf(
83+
data: PreviewReceiptsToInvoicePdfInput,
84+
): Promise<BinaryDownload> {
85+
return this.client.post('/receipts/to-invoice/preview/pdf', {
86+
body: data,
87+
})
6388
}
6489

6590
/**
@@ -68,7 +93,7 @@ export default class Receipts {
6893
* @returns
6994
*/
7095
cancel(id: string): Promise<Receipt> {
71-
return this.client.delete('/receipts/' + id);
96+
return this.client.delete('/receipts/' + id)
7297
}
7398

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

85110
/**
@@ -88,6 +113,6 @@ export default class Receipts {
88113
* @returns PDF file in a stream (Node.js) or Blob (browser)
89114
*/
90115
downloadPdf(id: string): Promise<BinaryDownload> {
91-
return this.client.get('/receipts/' + id + '/pdf');
116+
return this.client.get('/receipts/' + id + '/pdf')
92117
}
93118
}

src/types/receipt.ts

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,40 @@
1-
import type { ReceiptStatus } from '../enums';
2-
import type { InvoiceItem } from './common';
1+
import type { ReceiptStatus } from '../enums'
2+
import type { InvoiceItem } from './common'
3+
import type { Invoice } from './invoice'
34

45
export interface Receipt {
5-
id: string;
6-
created_at: Date;
7-
date: Date;
8-
api_version: number;
9-
livemode: boolean;
10-
organization: string;
11-
folio_number?: number;
12-
external_id?: string;
13-
idempotency_key?: string;
14-
branch: string;
15-
payment_form: string;
16-
items: InvoiceItem[];
17-
currency: string;
18-
exchange: number;
19-
total: number;
20-
invoice: string;
21-
expires_at: Date;
22-
key: string;
23-
status: ReceiptStatus;
24-
self_invoice_url: string;
6+
id: string
7+
created_at: Date
8+
date: Date
9+
api_version: number
10+
livemode: boolean
11+
organization: string
12+
folio_number?: number
13+
external_id?: string
14+
idempotency_key?: string
15+
branch: string
16+
payment_form: string
17+
items: InvoiceItem[]
18+
currency: string
19+
exchange: number
20+
total: number
21+
invoice: string
22+
expires_at: Date
23+
key: string
24+
status: ReceiptStatus
25+
self_invoice_url: string
26+
}
27+
28+
export interface ReceiptsToInvoiceInput {
29+
keys: string[]
30+
customer?: Record<string, any>
31+
use?: string
32+
dry_run?: boolean
33+
payment_form?: string | null
34+
}
35+
36+
export interface PreviewReceiptsToInvoicePdfInput {
37+
keys: string[]
38+
customer?: Record<string, any> | null
39+
use?: string
2540
}

0 commit comments

Comments
 (0)