From 89b1294f1e0a6371334b0ed7f6c85ac315b82055 Mon Sep 17 00:00:00 2001 From: Akshat Sachani Date: Thu, 3 Jul 2025 18:30:42 +0530 Subject: [PATCH 1/4] feat(utils): add invoice support in validatePaymentVerification method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extended the `validatePaymentVerification` method to support invoice-based payment verification. - Added logic to handle the following payload structure: - ```razorpay_invoice_id|razorpay_invoice_receipt|razorpay_invoice_status|payment_id``` - This is useful when using Razorpay’s Invoice API to create invoices and collect payments. - The change is backward compatible and preserves existing flows for order_id, subscription_id, and payment_link_id. --- lib/utils/razorpay-utils.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/utils/razorpay-utils.js b/lib/utils/razorpay-utils.js index 6ba6468..05abf70 100644 --- a/lib/utils/razorpay-utils.js +++ b/lib/utils/razorpay-utils.js @@ -138,8 +138,18 @@ function validatePaymentVerification(params={}, signature, secret){ var payload = paymentLinkId + '|' + paymentLinkRefId + '|' + paymentLinkStatus + '|' + paymentId; + }else if(isDefined(params.invoice_id) === true){ + + var invoiceId = params.invoice_id; + var invoiceReceiptId = params.invoice_receipt_id; + var invoiceStatus = params.invoice_status; + + var payload = invoiceId + '|' + invoiceReceiptId + '|' + invoiceStatus + '|' + paymentId; + }else{ - throw new Error('Either order_id or subscription_id is mandatory'); + throw new Error( + 'One of order_id, subscription_id, payment_link_id or razorpay_invoice_id is mandatory for verification.' + ); } return validateWebhookSignature(payload,signature,secret); }; From 8efdcd5271d51d7a94033d848d45bea6560fee5e Mon Sep 17 00:00:00 2001 From: Akshat Sachani Date: Thu, 3 Jul 2025 18:34:17 +0530 Subject: [PATCH 2/4] feat(types): add RazorpayVerifyInvoicePayment interface for invoice payment verification - Introduced a new interface **```RazorpayVerifyInvoicePayment```** extending RazorpayWebhook. - This interface defines the required fields for verifying invoice-based payments: - invoice_id - invoice_receipt_id - invoice_status - Helps improve type safety and developer experience when working with invoice payment signature verification. - Complements the logic added in ```validatePaymentVerification``` to support invoice-based flows. --- lib/utils/razorpay-utils.d.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/utils/razorpay-utils.d.ts b/lib/utils/razorpay-utils.d.ts index f584875..ac75784 100644 --- a/lib/utils/razorpay-utils.d.ts +++ b/lib/utils/razorpay-utils.d.ts @@ -36,6 +36,30 @@ export interface RazorpayVerifyPaymentLink extends RazorpayWebhook { payment_link_status: string; } +export interface RazorpayVerifyInvoicePayment extends RazorpayWebhook { + /** + * Unique identifier of the invoice generated by Razorpay. + * Example: "inv_KY9Xb8W2Xx1e1A" + */ + invoice_id: string; + + /** + * Internal reference ID (or receipt ID) provided by the business at the time of invoice creation. + * This is typically set using the `reference_id` field. + * Example: "order_rcptid_11" + * + * Note: May be null or undefined if not provided during invoice creation. + */ + invoice_receipt_id: string; + + /** + * Current status of the invoice. + * This will usually be `"paid"` if the payment was completed successfully. + * Example: "paid" + */ + invoice_status: string; +} + export function getDateInSecs(date: string): number export function normalizeDate(date: number | string): number @@ -87,4 +111,4 @@ export function validatePaymentVerification(payload: RazorpayVerifyPayment | Raz */ export function prettify(val: Object): string -export function generateOnboardingSignature(params: any, secret: string): string \ No newline at end of file +export function generateOnboardingSignature(params: any, secret: string): string From 02b294e9bef9bdaca0ea7d0cdf1f7e3c50eb99ed Mon Sep 17 00:00:00 2001 From: Akshat Sachani Date: Thu, 3 Jul 2025 18:41:54 +0530 Subject: [PATCH 3/4] test: add unit test for invoice payment verification in validatePaymentVerification - Added a test case to verify the new invoice payment verification logic in ```validatePaymentVerification```. - Test uses a sample payload with: - invoice_id - invoice_receipt_id - invoice_status - payment_id - Validates both a correct and incorrect signature to ensure robustness of the verification logic. - Complements the recent enhancement for invoice-based signature support. --- test/utils/razorpay-utils.spec.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/utils/razorpay-utils.spec.js b/test/utils/razorpay-utils.spec.js index a5242a3..921667e 100644 --- a/test/utils/razorpay-utils.spec.js +++ b/test/utils/razorpay-utils.spec.js @@ -159,4 +159,22 @@ describe('Razorpay Utils', () => { 'Validates payment' ); }) + it('Invoice Payment Verfication', () => { + + const respBody = { + 'payment_id':'pay_IH4NVgf4Dreq1l', + 'invoice_id':'inv_KY9Xb8W2Xx1e1A', + 'invoice_receipt_id':'order_rcptid_11', + 'invoice_status':'paid', + }, + correctSignature = '3d8ca5c0b03c702d5675b36faf63b5f42bdd78dc946ef99b797a42bd42ab8104', + wrongSignature = 'sddsfdsfs', + secret = 'EnLs21M47BllR3X8PSFtjtbd'; + + assert.ok( + validatePaymentVerification(respBody, correctSignature, secret) && + !validatePaymentVerification(respBody, wrongSignature, secret), + 'Validates invoice payment' + ); + }) }) From 7d1e112d188aab0435ebe2033ab20899cd3b169c Mon Sep 17 00:00:00 2001 From: Akshat Sachani Date: Thu, 3 Jul 2025 19:09:15 +0530 Subject: [PATCH 4/4] - update correct signature for test case --- test/utils/razorpay-utils.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/utils/razorpay-utils.spec.js b/test/utils/razorpay-utils.spec.js index 921667e..0276a02 100644 --- a/test/utils/razorpay-utils.spec.js +++ b/test/utils/razorpay-utils.spec.js @@ -167,7 +167,7 @@ describe('Razorpay Utils', () => { 'invoice_receipt_id':'order_rcptid_11', 'invoice_status':'paid', }, - correctSignature = '3d8ca5c0b03c702d5675b36faf63b5f42bdd78dc946ef99b797a42bd42ab8104', + correctSignature = '797a05a35631be3d8c88b65d449952cb5314fba3d5fa89709d0c4faf931608be', wrongSignature = 'sddsfdsfs', secret = 'EnLs21M47BllR3X8PSFtjtbd';