PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 All 85 releases
← All changes | resources/js/lib/invoice-download.ts +43 -11 3.0.9 → 3.0.17 View file →
@@ -22,10 +22,9 @@
22 22 const nonce = w?.yatraAdmin?.nonce || "";
23 23 return { base, nonce };
24 24 }
25 25
26 -function buildInvoiceUrl(base: string, paymentId: number): string {
27 - const suffix = `/yatra/v1/payment/${paymentId}/invoice`;
26 +function buildInvoiceUrl(base: string, suffix: string): string {
28 27 const origin =
29 28 typeof window !== "undefined" ? window.location.origin : "http://localhost";
30 29
31 30 let u: URL;
@@ -64,24 +63,24 @@
64 63 return msg;
65 64 }
66 65
67 66 /**
68 - * Download a payment invoice PDF as a file.
67 + * Fetch an invoice PDF from `suffix` and save it, falling back to
68 + * `fallbackName` when the response carries no Content-Disposition.
69 69 *
70 70 * Authentication is handled server-side via the admin REST nonce + cookie
71 - * (administrators bypass the ownership check inside `download_invoice`).
71 + * (administrators bypass the ownership check inside the endpoint).
72 72 */
73 -export async function downloadAdminInvoice(paymentId: number): Promise<void> {
74 - if (!paymentId || paymentId <= 0) {
75 - throw new Error("Invalid payment ID");
76 - }
77 -
73 +async function downloadInvoicePdf(
74 + suffix: string,
75 + fallbackName: string,
76 +): Promise<void> {
78 77 const { base, nonce } = getAdminRestConfig();
79 78 if (!nonce) {
80 79 throw new Error("Missing REST nonce; please reload the page.");
81 80 }
82 81
83 - const url = buildInvoiceUrl(base, paymentId);
82 + const url = buildInvoiceUrl(base, suffix);
84 83 const res = await fetch(url, {
85 84 method: "GET",
86 85 credentials: "include",
87 86 headers: {
@@ -95,9 +94,9 @@
95 94 }
96 95
97 96 const blob = await res.blob();
98 97 const dispo = res.headers.get("Content-Disposition");
99 - let filename = `invoice-${paymentId}.pdf`;
98 + let filename = fallbackName;
100 99 if (dispo) {
101 100 const m = /filename\*?=(?:UTF-8'')?["']?([^";\n]+)/i.exec(dispo);
102 101 if (m?.[1]) {
103 102 try {
@@ -115,5 +114,38 @@
115 114 document.body.appendChild(link);
116 115 link.click();
117 116 document.body.removeChild(link);
118 117 URL.revokeObjectURL(objectUrl);
118 +}
119 +
120 +/**
121 + * Download a payment invoice (receipt for one recorded payment).
122 + */
123 +export async function downloadAdminInvoice(paymentId: number): Promise<void> {
124 + if (!paymentId || paymentId <= 0) {
125 + throw new Error("Invalid payment ID");
126 + }
127 +
128 + await downloadInvoicePdf(
129 + `/yatra/v1/payment/${paymentId}/invoice`,
130 + `invoice-${paymentId}.pdf`,
131 + );
132 +}
133 +
134 +/**
135 + * Download a booking invoice — the whole booking rather than a single
136 + * payment, so it also works for bookings with no payment recorded yet
137 + * (bank transfer, pay later), where it renders as a pro-forma invoice with
138 + * the gateway's payment instructions.
139 + */
140 +export async function downloadAdminBookingInvoice(
141 + bookingId: number,
142 +): Promise<void> {
143 + if (!bookingId || bookingId <= 0) {
144 + throw new Error("Invalid booking ID");
145 + }
146 +
147 + await downloadInvoicePdf(
148 + `/yatra/v1/booking/${bookingId}/invoice`,
149 + `invoice-booking-${bookingId}.pdf`,
150 + );
119 151 }