From dc76d99d8ce588a0894b7aea22ff76358add3456 Mon Sep 17 00:00:00 2001 From: rzpamidi Date: Mon, 9 Oct 2017 19:16:19 +0530 Subject: [PATCH 1/5] Adds basic api --- lib/razorpay.js | 1 + lib/resources/invoices.js | 230 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 lib/resources/invoices.js diff --git a/lib/razorpay.js b/lib/razorpay.js index 259fc00c..272637f8 100644 --- a/lib/razorpay.js +++ b/lib/razorpay.js @@ -37,6 +37,7 @@ class Razorpay { customers : require('./resources/customers')(this.api), transfers : require('./resources/transfers')(this.api), virtualAccounts: require('./resources/virtualAccounts')(this.api), + invoices : require('./resources/invoices')(this.api), }) } } diff --git a/lib/resources/invoices.js b/lib/resources/invoices.js new file mode 100644 index 00000000..fcc6a50f --- /dev/null +++ b/lib/resources/invoices.js @@ -0,0 +1,230 @@ +"use strict"; + +/* + * DOCS: https://razorpay.com/docs/invoices/ + */ + +const Promise = require("promise"), + { normalizeDate, normalizeNotes } = require('../utils/razorpay-utils'); + +module.exports = function invoicesApi (api) { + + const BASE_URL = "/invoices", + MISSING_ID_ERROR = "Invoice ID is mandatory"; + + /** + * Invoice entity gets used for both Payment Links and Invoices system. + * Few of the methods are only meaningful for Invoices system and calling those + * for against/for a Payment Link would throw Bad request error. + */ + + return { + + create (params={}, callback) { + + /* + * Creates invoice of any type(invoice|link|ecod). + * + * @param {Object} params + * @param {Function} callback + * + * @return {Promise} + */ + + let url = BASE_URL, + { notes, ...rest } = params, + data = Object.assign(rest, normalizeNotes(notes)); + + return api.post({ + url, + data + }, callback) + }, + + edit (invoiceId, params={}, callback) { + + /* + * Patches given invoice with new attributes + * + * @param {String} invoiceId + * @param {Object} params + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + let url = `${BASE_URL}/${invoiceId}`, + { notes, ...rest } = params, + data = Object.assign(rest, normalizeNotes(notes)); + + + return api.patch({ + url, + data + }, callback); + }, + + issue (invoiceId, callback) { + + /* + * Issues drafted invoice + * + * @param {String} invoiceId + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + let url = `${BASE_URL}/${invoiceId}/issue`; + + return api.post({ + url + }, callback); + }, + + delete (invoiceId, callback) { + + /* + * Deletes drafted invoice + * + * @param {String} invoiceId + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + let url = `${BASE_URL}/${invoiceId}`; + + return api.delete({ + url + }, callback); + }, + + cancel (invoiceId, callback) { + + /* + * Cancels issued invoice + * + * @param {String} invoiceId + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + let url = `${BASE_URL}/${invoiceId}/cancel`; + + return api.post({ + url + }, callback); + }, + + fetch (invoiceId, callback) { + + /* + * Fetches invoice entity with given id + * + * @param {String} invoiceId + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + let url = `${BASE_URL}/${invoiceId}`; + + return api.get({ + url + }, callback); + }, + + all (params={}, callback) { + + /* + * Fetches multiple invoices with given query options + * + * @param {Object} invoiceId + * @param {Function} callback + * + * @return {Promise} + */ + + let { from, to, count, skip } = params, + url = BASE_URL; + + if (from) { + from = normalizeDate(from) + } + + if (to) { + to = normalizeDate(to) + } + + count = Number(count) || 10 + skip = Number(skip) || 0 + + return api.get({ + url, + data: { + ...params, + from, + to, + count, + skip + } + }, callback); + }, + + notifyBy (invoiceId, medium, callback) { + + /* + * Send/re-send notification for invoice by given medium + * + * @param {String} invoiceId + * @param {String} medium + * @param {Function} callback + * + * @return {Promise} + */ + + if (!invoiceId) { + + return Promise.reject(MISSING_ID_ERROR); + } + + if (!medium) { + + return Promise.reject("`medium` is required"); + } + + let url = `${BASE_URL}/${invoiceId}/notify_by/${medium}`; + + return api.post({ + url + }, callback); + } + }; +}; From 29da9153bec203afff928371839b05257b291005 Mon Sep 17 00:00:00 2001 From: rzpamidi Date: Wed, 11 Oct 2017 12:56:12 +0530 Subject: [PATCH 2/5] Adds complete tests for invoices api --- lib/resources/invoices.js | 14 +- lib/utils/predefined-tests.js | 171 +++++++++++++++++++ lib/utils/razorpay-utils.js | 33 +++- test/mocker.js | 6 + test/resources/invoices.spec.js | 288 ++++++++++++++++++++++++++++++++ 5 files changed, 504 insertions(+), 8 deletions(-) create mode 100644 lib/utils/predefined-tests.js create mode 100644 test/resources/invoices.spec.js diff --git a/lib/resources/invoices.js b/lib/resources/invoices.js index fcc6a50f..7e7daf22 100644 --- a/lib/resources/invoices.js +++ b/lib/resources/invoices.js @@ -14,8 +14,9 @@ module.exports = function invoicesApi (api) { /** * Invoice entity gets used for both Payment Links and Invoices system. - * Few of the methods are only meaningful for Invoices system and calling those - * for against/for a Payment Link would throw Bad request error. + * Few of the methods are only meaningful for Invoices system and + * calling those for against/for a Payment Link would throw + * Bad request error. */ return { @@ -53,15 +54,14 @@ module.exports = function invoicesApi (api) { * @return {Promise} */ - if (!invoiceId) { - - return Promise.reject(MISSING_ID_ERROR); - } - let url = `${BASE_URL}/${invoiceId}`, { notes, ...rest } = params, data = Object.assign(rest, normalizeNotes(notes)); + if (!invoiceId) { + + return Promise.reject("Invoice ID is mandatory"); + } return api.patch({ url, diff --git a/lib/utils/predefined-tests.js b/lib/utils/predefined-tests.js new file mode 100644 index 00000000..5bbd523d --- /dev/null +++ b/lib/utils/predefined-tests.js @@ -0,0 +1,171 @@ +'use strict'; + +const mocker = require('../../test/mocker'), + equal = require('deep-equal'), + chai = require('chai'), + { assert } = chai, + { prettify, + getTestError } = require("../../dist/utils/razorpay-utils"); + + + +const runCallbackCheckTest = (params) => { + + let { + apiObj, + methodName, + methodArgs, + mockerParams + } = params; + + methodArgs = methodArgs || []; + + it ("Checks if the passed api callback gets called", (done) => { + + mocker.mock(mockerParams); + + apiObj[methodName](...methodArgs, (err) => { + done(); + }); + }); + + it ("Checks for error flow", (done) => { + + mocker.mock({...mockerParams, replyWithError: true}); + + apiObj[methodName](...methodArgs, (err) => { + + assert.ok(!!err, "Error callback called with error"); + done(); + }); + }); + + it ("Checks if the api call returns a Promise", (done) => { + + mocker.mock(mockerParams); + + const retVal = apiObj[methodName](...methodArgs); + + retVal && typeof retVal.then === "function" + ? done() + : done(getTestError("Invalid Return Value", String("Promise"), retVal)) + }); +} + +const runURLCheckTest = (params) => { + + let { + apiObj, + methodName, + methodArgs, + expectedUrl, + mockerParams + } = params; + + methodArgs = methodArgs || []; + + it ("Checks if the URL is formed correctly", (done) => { + + mocker.mock(mockerParams); + + apiObj[methodName](...methodArgs).then((resp) => { + + const respData = resp.__JUST_FOR_TESTS__; + + if (respData.url === expectedUrl) { + + assert.ok(true, "URL Matched"); + done(); + } else { + + done(getTestError( + "URL Mismatch", + expectedUrl, + respData.url + )); + } + }); + }); +} + +const runParamsCheckTest = (params) => { + + let { + apiObj, + methodName, + methodArgs, + expectedParams, + mockerParams, + testTitle + } = params; + + methodArgs = methodArgs || []; + testTitle = testTitle || "Validates URL and Params"; + + it (testTitle, (done) => { + + mocker.mock(mockerParams); + + apiObj[methodName](...methodArgs).then((resp) => { + + const respData = resp.__JUST_FOR_TESTS__, + respParams = respData[respData.method === "GET" + ? "requestQueryParams" + : "requestBody"]; + + if (equal(respParams, expectedParams)) { + + assert.ok(true, "Params Matched"); + } else { + + return getTestError( + "Params Mismatch", + expectedParams, + respParams + ); + } + }, (err) => { + + return new Error(prettify(err)); + }).then((err) => { + + done(err); + }); + }); +} + +const runCommonTests = (params) => { + + let { + apiObj, + methodName, + methodArgs, + expectedUrl, + expectedParams, + mockerParams + } = params; + + methodArgs = methodArgs || []; + + runURLCheckTest({ + ...params + }); + + if (expectedParams) { + + runParamsCheckTest({ + ...params + }); + } + + runCallbackCheckTest({ + ...params + }); +} + +module.exports = { + runCallbackCheckTest, + runParamsCheckTest, + runURLCheckTest, + runCommonTests +}; diff --git a/lib/utils/razorpay-utils.js b/lib/utils/razorpay-utils.js index 22c545ca..a502ecb5 100644 --- a/lib/utils/razorpay-utils.js +++ b/lib/utils/razorpay-utils.js @@ -26,10 +26,41 @@ function normalizeNotes(notes = {}) { return normalizedNotes } +function prettify (val) { + + /* + * given an object , returns prettified string + * + * @param {Object} val + * @return {String} + */ + + return JSON.stringify(val, null, 2); +} + +function getTestError (summary, expectedVal, gotVal) { + + /* + * @param {String} summary + * @param {*} expectedVal + * @param {*} gotVal + * + * @return {Error} + */ + + return new Error( + `\n${summary}\n`+ + `Expected(${typeof expectedVal})\n${prettify(expectedVal)}\n\n`+ + `Got(${typeof gotVal})\n${prettify(gotVal)}` + ); +} + module.exports = { normalizeNotes, normalizeDate, normalizeBoolean, isNumber, - getDateInSecs + getDateInSecs, + prettify, + getTestError } diff --git a/test/mocker.js b/test/mocker.js index e86d6aff..4558df7b 100644 --- a/test/mocker.js +++ b/test/mocker.js @@ -38,6 +38,7 @@ Mocker.prototype.mock = function(params) { "success": true, __JUST_FOR_TESTS__: { url, + method, requestQueryParams, requestBody: parseReqBody(requestBody), headers: this.req.headers @@ -51,6 +52,11 @@ const normalizeUrl = function(url) { } const parseReqBody = function(raw) { + + if (raw.length === 0) { + return {}; + } + return raw.split('&').reduce((prev, curr) => { let parts = curr.split('=') prev[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]) diff --git a/test/resources/invoices.spec.js b/test/resources/invoices.spec.js new file mode 100644 index 00000000..d2ea5e30 --- /dev/null +++ b/test/resources/invoices.spec.js @@ -0,0 +1,288 @@ +'use strict'; + +const Promise = require('promise') +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay'); +const mocker = require('../mocker') +const equal = require('deep-equal') +const { getDateInSecs, + normalizeDate, + normalizeNotes + } = require('../../dist/utils/razorpay-utils'); +const { runCallbackCheckTest, + runParamsCheckTest, + runURLCheckTest, + runCommonTests } = require("../../dist/utils/predefined-tests.js"); + +const SUB_PATH = "/invoices", + FULL_PATH = `/v1${SUB_PATH}`, + TEST_INVOICE_ID = "inv_8l7Qvjbguwm3Dq", + apiObj = rzpInstance.invoices; + +const runIDRequiredTest = (params) => { + + let {apiObj, methodName, mockerParams} = params; + + mocker.mock(mockerParams); + + it (`method ${methodName} checks for Invoice ID as param`, + (done) => { + + apiObj[methodName]().then(() => { + + done(new Error(`method ${methodName} does not`+ + ` check for Invoice ID`)); + },(err) => { + + done(); + }); + }); +} + +describe("INVOICES", () => { + + describe('Create Invoice', () => { + + let expectedUrl = `${FULL_PATH}`, + params = { + param1: "something", + param2: "something else", + notes: {"something": "something else"} + }, + expectedParams = { + param1: params.param1, + param2: params.param2, + ...(normalizeNotes(params.notes)) + }, + methodArgs = [params], + methodName = "create", + mockerParams = { + url: `${SUB_PATH}`, + method: "POST" + }; + + runCommonTests({ + apiObj, + methodName, + methodArgs, + expectedUrl, + expectedParams, + mockerParams + }); + }); + + describe('Edit Invoice', () => { + + let expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}`, + methodName = "edit", + params = { + param1: "something", + param2: "something else", + notes: {"something": "something else"} + }, + expectedParams = { + param1: params.param1, + param2: params.param2, + ...(normalizeNotes(params.notes)) + }, + methodArgs = [TEST_INVOICE_ID, params], + mockerParams = { + url: `${SUB_PATH}/${TEST_INVOICE_ID}`, + method: "PATCH" + }; + + runIDRequiredTest({ + apiObj, + methodName, + mockerParams: { + url: `${SUB_PATH}/${undefined}`, + method: mockerParams.method + } + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + expectedUrl, + expectedParams, + mockerParams + }); + }); + + describe('Issue Invoice', () => { + + let expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}/issue`, + methodName = "issue", + methodArgs = [TEST_INVOICE_ID], + mockerParams = { + url: `${SUB_PATH}/${TEST_INVOICE_ID}/issue`, + method: "POST" + }; + + runIDRequiredTest({ + apiObj, + methodName, + mockerParams: { + url: `${SUB_PATH}/${undefined}/issue`, + method: mockerParams.method + } + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedUrl + }); + }); + + describe('Delete Invoice', () => { + + let expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}`, + methodName = "delete", + methodArgs = [TEST_INVOICE_ID], + mockerParams = { + url: `${SUB_PATH}/${TEST_INVOICE_ID}`, + method: "DELETE" + }; + + runIDRequiredTest({ + apiObj, + methodName, + mockerParams: { + url: `${SUB_PATH}/${undefined}`, + method: mockerParams.method + } + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedUrl + }); + }); + + describe("Cancel Invoice", () => { + + let expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}/cancel`, + methodName = "cancel", + methodArgs = [TEST_INVOICE_ID], + mockerParams = { + url: `${SUB_PATH}/${TEST_INVOICE_ID}/cancel`, + method: "POST" + }; + + runIDRequiredTest({ + apiObj, + methodName, + mockerParams: { + url: `${SUB_PATH}/${undefined}/cancel`, + method: mockerParams.method + } + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedUrl + }); + }); + + describe("Fetch Invoice", () => { + + let expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}`, + methodName = "fetch", + methodArgs = [TEST_INVOICE_ID], + mockerParams = { + url: `${SUB_PATH}/${TEST_INVOICE_ID}` + }; + + runIDRequiredTest({ + apiObj, + methodName, + mockerParams: { + url: `${SUB_PATH}/${undefined}` + } + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedUrl + }); + }); + + describe("Fetch Multiple", () => { + + let methodName = "all", + params = { + "param1": "something", + "skip": 10, + "count": 10 + }, + methodArgs = [params], + expectedParams = { + ...params + }, + expectedUrl = FULL_PATH, + mockerParams = { + url: SUB_PATH + }; + + runParamsCheckTest({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedParams, + testTitle: "Check if all params passed are being sent" + }); + + params = {}; + methodArgs = [params]; + expectedParams = {"skip": 0, "count": 10}; + + runParamsCheckTest({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedParams, + testTitle: "Check if skip and count are automatically populated" + }); + + params = {"from": 'Aug 25, 2016', "to": 'Aug 30, 2016'}; + methodArgs = [params]; + expectedParams = {"from": getDateInSecs(params.from), + "to": getDateInSecs(params.to), + "count": "10", + "skip": "0"}; + + runParamsCheckTest({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedParams, + testTitle: "Check if dates are converted to ms" + }); + + methodArgs = [{}]; + + runCallbackCheckTest({ + apiObj, + methodName, + mockerParams, + methodArgs + }); + }); +}); From 5c7a9e60abf6157eff1cab8a54c99a752c3a3b17 Mon Sep 17 00:00:00 2001 From: rzpamidi Date: Wed, 11 Oct 2017 12:56:40 +0530 Subject: [PATCH 3/5] Adds swap files created by vim to gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 0a739ee2..cc690bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,7 @@ dist/ *.orig *.log +*.swp +*.swo +*.swn +*.swm From 18f21d78cf80694c23ea2edab527a0fe7c0d9d2b Mon Sep 17 00:00:00 2001 From: rzpamidi Date: Wed, 11 Oct 2017 16:14:49 +0530 Subject: [PATCH 4/5] Adds missing testcase for notifyBy method of invoices --- README.md | 2 ++ lib/utils/predefined-tests.js | 11 +----- test/resources/invoices.spec.js | 62 ++++++++++++++++++++++++++++++--- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 3ca25d98..02bc712f 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ instance.payments.all({ - [Transfers](https://github.com/razorpay/razorpay-node/wiki#transfers) - [Virtual Accounts](https://github.com/razorpay/razorpay-node/wiki#virtual-accounts) + +- [Invoices](https://github.com/razorpay/razorpay-node/wiki#invoices) --- diff --git a/lib/utils/predefined-tests.js b/lib/utils/predefined-tests.js index 5bbd523d..4f81a9f5 100644 --- a/lib/utils/predefined-tests.js +++ b/lib/utils/predefined-tests.js @@ -7,8 +7,6 @@ const mocker = require('../../test/mocker'), { prettify, getTestError } = require("../../dist/utils/razorpay-utils"); - - const runCallbackCheckTest = (params) => { let { @@ -18,8 +16,6 @@ const runCallbackCheckTest = (params) => { mockerParams } = params; - methodArgs = methodArgs || []; - it ("Checks if the passed api callback gets called", (done) => { mocker.mock(mockerParams); @@ -62,13 +58,11 @@ const runURLCheckTest = (params) => { mockerParams } = params; - methodArgs = methodArgs || []; - it ("Checks if the URL is formed correctly", (done) => { mocker.mock(mockerParams); - apiObj[methodName](...methodArgs).then((resp) => { + apiObj[methodName](...methodArgs, (err, resp) => { const respData = resp.__JUST_FOR_TESTS__; @@ -99,7 +93,6 @@ const runParamsCheckTest = (params) => { testTitle } = params; - methodArgs = methodArgs || []; testTitle = testTitle || "Validates URL and Params"; it (testTitle, (done) => { @@ -145,8 +138,6 @@ const runCommonTests = (params) => { mockerParams } = params; - methodArgs = methodArgs || []; - runURLCheckTest({ ...params }); diff --git a/test/resources/invoices.spec.js b/test/resources/invoices.spec.js index d2ea5e30..b1984f4f 100644 --- a/test/resources/invoices.spec.js +++ b/test/resources/invoices.spec.js @@ -22,19 +22,19 @@ const SUB_PATH = "/invoices", const runIDRequiredTest = (params) => { - let {apiObj, methodName, mockerParams} = params; + let {apiObj, methodName, methodArgs, mockerParams} = params; mocker.mock(mockerParams); it (`method ${methodName} checks for Invoice ID as param`, (done) => { - apiObj[methodName]().then(() => { + apiObj[methodName](...methodArgs).then(() => { done(new Error(`method ${methodName} does not`+ ` check for Invoice ID`)); },(err) => { - + done(); }); }); @@ -59,7 +59,7 @@ describe("INVOICES", () => { methodName = "create", mockerParams = { url: `${SUB_PATH}`, - method: "POST" + method: "POST" }; runCommonTests({ @@ -95,6 +95,7 @@ describe("INVOICES", () => { runIDRequiredTest({ apiObj, methodName, + methodArgs: [undefined], mockerParams: { url: `${SUB_PATH}/${undefined}`, method: mockerParams.method @@ -120,10 +121,11 @@ describe("INVOICES", () => { url: `${SUB_PATH}/${TEST_INVOICE_ID}/issue`, method: "POST" }; - + runIDRequiredTest({ apiObj, methodName, + methodArgs: [undefined], mockerParams: { url: `${SUB_PATH}/${undefined}/issue`, method: mockerParams.method @@ -152,6 +154,7 @@ describe("INVOICES", () => { runIDRequiredTest({ apiObj, methodName, + methodArgs: [undefined], mockerParams: { url: `${SUB_PATH}/${undefined}`, method: mockerParams.method @@ -180,6 +183,7 @@ describe("INVOICES", () => { runIDRequiredTest({ apiObj, methodName, + methodArgs: [undefined], mockerParams: { url: `${SUB_PATH}/${undefined}/cancel`, method: mockerParams.method @@ -207,6 +211,7 @@ describe("INVOICES", () => { runIDRequiredTest({ apiObj, methodName, + methodArgs: [undefined], mockerParams: { url: `${SUB_PATH}/${undefined}` } @@ -285,4 +290,51 @@ describe("INVOICES", () => { methodArgs }); }); + + describe("Notify", () => { + + let medium = "email", + expectedUrl = `${FULL_PATH}/${TEST_INVOICE_ID}/notify_by/${medium}`, + methodName = "notifyBy", + methodArgs = [TEST_INVOICE_ID, medium], + mockerParams = { + "url": `${SUB_PATH}/${TEST_INVOICE_ID}/notify_by/${medium}`, + "method": "POST" + }; + + runIDRequiredTest({ + apiObj, + methodName, + methodArgs: [undefined, medium], + mockerParams: { + "url": `${SUB_PATH}/${undefined}/notify_by/${medium}`, + "method": "POST" + } + }); + + it ("notify method checks for `medium` parameter", (done) => { + + mocker.mock({ + url: `${SUB_PATH}/${TEST_INVOICE_ID}/notify_by/${undefined}`, + method: "POST" + }); + + apiObj[methodName](TEST_INVOICE_ID, undefined).then(() => { + + done(new Error("medium parameter is not checked for")); + }).catch(() => { + + assert.ok("medium parameter is checked"); + done(); + }); + }); + + runCommonTests({ + apiObj, + methodName, + methodArgs, + mockerParams, + expectedUrl + }); + }); }); From 09cb22e3e80dff79a9cbb960fcaeb387b74706c9 Mon Sep 17 00:00:00 2001 From: rzpamidi Date: Wed, 11 Oct 2017 16:35:30 +0530 Subject: [PATCH 5/5] Increased the version to 1.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 89dd1828..252d2b9b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "razorpay", - "version": "1.4.0", + "version": "1.5.0", "description": "Official Node SDK for Razorpay API", "main": "dist/razorpay.js", "scripts": {