From 0224b5b5a9b0705b918ab7c99d83cc1f1d8d47d2 Mon Sep 17 00:00:00 2001 From: Tejas H Date: Tue, 18 Aug 2020 10:40:54 +0530 Subject: [PATCH 1/3] Commit to share code --- src/Instamojo.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/Instamojo.js b/src/Instamojo.js index f13cf72..6b7d80d 100644 --- a/src/Instamojo.js +++ b/src/Instamojo.js @@ -104,6 +104,44 @@ const getAllPaymentLinksCreatedOnInstamojo = async () => { } }; +const RefundRequest = function ({ payment_id, type, body }) { + return { + payment_id, + type, // Available : ['RFD', 'TNR', 'QFL', 'QNR', 'EWN', 'TAN', 'PTH'] + body, + setOptionalRefundAmount: function (refundAmount) { + this.refund_amount = refundAmount; + }, + }; +}; + +const initiateRefund = async (refundRequest) => { + try { + const response = await axios.post(ENDPOINT.refunds, refundRequest); + return response.data; + } catch (error) { + return error.response; + } +}; + +const getAllRefunds = async () => { + try { + const response = await axios.get(ENDPOINT.refunds); + return response.data; + } catch (error) { + return error.response; + } +}; + +const getRefundDetails = async (id) => { + try { + const response = await axios.get(`${ENDPOINT.refunds}/${id}`); + return response.data; + } catch (error) { + return error.response; + } +}; + module.exports = { isSandboxMode, setKeys, @@ -113,4 +151,8 @@ module.exports = { getOnePayedPaymentDetails, getAllPaymentRequests, getAllPaymentLinksCreatedOnInstamojo, + RefundRequest, + initiateRefund, + getAllRefunds, + getRefundDetails, }; From 44aca5c7a0a9f842437f44405928333eec3558ea Mon Sep 17 00:00:00 2001 From: Tejas H Date: Tue, 18 Aug 2020 13:58:20 +0530 Subject: [PATCH 2/3] =?UTF-8?q?Added=20refund=20APIs,=20updated=20docs,=20?= =?UTF-8?q?code=20coverage=20=F0=9F=92=AF=20=F0=9F=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 153 +++++++++++++++++++++++++------- src/Instamojo.js | 35 +++++--- src/__tests__/Instamojo.test.js | 138 ++++++++++++++++++++++++++++ 3 files changed, 283 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 6731d8c..0ea5d15 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,12 @@ **Promise based Instamojo payment gateway integrator for NodeJS based projects** -![Coverage](https://img.shields.io/badge/Coverage-75%25-brightgreen.svg) +- No callback hell ✅ +- Clean, readable code with async-await 💖 + +![Coverage](https://img.shields.io/badge/Code_Coverage-100%25-brightgreen.svg) + +> If you face any problems using this package, please create an issue on this repo OR even better, create a PR! 🙂 ## Installation @@ -17,6 +22,9 @@ npm i instamojo-payment-nodejs // OR yarn add instamojo-payment-nodejs 1. [Get single payment request details](#Get-single-payment-request-details) 1. [Get single payment details](#Get-single-payment-details) 1. [Get all payment requests](#Get-all-payment-requests) +1. [Initiate refund](#Initiate-refund) +1. [Get all refund requests](#Get-all-refund-requests) +1. [Get single refund details with `refundId`](#Get-single-refund-details-with-refundId) ### **Setup keys** @@ -234,34 +242,115 @@ const response = await Instamojo.getAllPaymentRequests();
Response from getAllPaymentRequests +```json +{} +``` + +
+ +
+ +### **Initiate refund** + +```js +const refundInstance = new Instamojo.RefundRequestOptions({ + payment_id: "MOJO0816705N15845280", + type: "RFD", // Refer below section + body: "Reason for refund", +}); + +refundInstance.setOptionalRefundAmount(99); + +const refundResponse = await Instamojo.initiateRefund( + refundInstance.getObject() +); +``` + +**Valid values for type parameter:** + +- `RFD`: Duplicate/delayed payment. +- `TNR`: Product/service no longer available. +- `QFL`: Customer not satisfied. +- `QNR`: Product lost/damaged. +- `EWN`: Digital download issue. +- `TAN`: Event was canceled/changed. +- `PTH`: Problem not described above. + +For more, refer: https://docs.instamojo.com/docs/creating-a-refund, + +
Response from initiateRefund + ```json { - "success": true, - // List of payment requests - "payment_requests": [ + "refund": { + "id": "C5c0751269", + "payment_id": "MOJO5a06005J21512197", + "status": "Refunded", + "type": "QFL", + "body": "Customer isn't satisfied with the quality", + "refund_amount": "2500.00", + "total_amount": "2500.00", + "created_at": "2015-12-07T11:01:37.640Z" + }, + "success": true +} +``` + +
+ +
+ +### **Get all refund requests** + +```js +const response = await Instamojo.getAllRefunds(); +``` + +
Response from getAllRefunds + +```json +{ + "refunds": [ { - "id": PAYMENT_REQUEST_ID, - "phone": null, - "email": "", - "buyer_name": "", - "amount": "20.00", - "purpose": "Product name", - "expires_at": null, - "status": "Pending", - "send_sms": false, - "send_email": false, - "sms_status": null, - "email_status": null, - "shorturl": null, - "longurl": "https://test.instamojo.com/@USER/PAYMENT_REQUEST_ID", - "redirect_url": "", - "webhook": "", - "allow_repeated_payments": false, - "customer_id": null, - "created_at": "2020-08-16T15:46:42.970983Z", - "modified_at": "2020-08-16T15:46:42.971001Z" + "id": "C5c0751269", + "payment_id": "MOJO5a06005J21512197", + "status": "Refunded", + "type": "QFL", + "body": "Customer isn't satisfied with the quality", + "refund_amount": "2500.00", + "total_amount": "2500.00", + "created_at": "2015-12-07T11:01:37.640Z" } - ] + ], + "success": true +} +``` + +
+ +
+ +### **Get single refund details with refundId** + +```js +const response = await Instamojo.getRefundDetails("C5c0751272"); +``` + +
Response from getRefundDetails + +```json +{ + "refund": { + "id": "C5c0751272", + "payment_id": "MOJO5a06005J21512197", + "status": "Refunded", + "type": "QFL", + "body": "Customer isn't satisfied with the quality", + "refund_amount": "2500.00", + "total_amount": "2500.00", + "created_at": "2015-12-07T11:04:09.500Z" + }, + "success": true } ``` @@ -277,16 +366,20 @@ const response = await Instamojo.getAllPaymentRequests(); 1. ✅ Implement Sandbox mode for developers 1. ✅ Create a payment request - 1. 📈 Write easy-to-follow docs for package consumers + 1. ✅ Write an easy-to-follow docs for package consumers 1. ✅ Get Single payment request details 1. ✅ Get Single payment details 1. ✅ Get all payment requests - 1. Get all payments - 1. Initiate refund - 1. Get refund details - 1. Get all refunds + 1. ✅ Get all payments + +1. Refund + + 1. ✅ Initiate refund + 1. ✅ Get all refund requests + 1. ✅ Get single refund details with refundId 1. ✅ Reach code test coverage threshold 60% +1. ✅ Reach code test coverage threshold 100% ## Far diff --git a/src/Instamojo.js b/src/Instamojo.js index 6b7d80d..c648d05 100644 --- a/src/Instamojo.js +++ b/src/Instamojo.js @@ -104,16 +104,25 @@ const getAllPaymentLinksCreatedOnInstamojo = async () => { } }; -const RefundRequest = function ({ payment_id, type, body }) { - return { - payment_id, - type, // Available : ['RFD', 'TNR', 'QFL', 'QNR', 'EWN', 'TAN', 'PTH'] - body, - setOptionalRefundAmount: function (refundAmount) { - this.refund_amount = refundAmount; - }, - }; -}; +class RefundRequestOptions { + constructor({ payment_id, type, body }) { + this.payment_id = payment_id; + this.type = type; + this.body = body; + } + setOptionalRefundAmount(refundAmount) { + this.refund_amount = refundAmount; + } + + getObject() { + return { + payment_id: this.payment_id, + type: this.type, + body: this.body, + refund_amount: this.refund_amount, + }; + } +} const initiateRefund = async (refundRequest) => { try { @@ -133,9 +142,9 @@ const getAllRefunds = async () => { } }; -const getRefundDetails = async (id) => { +const getRefundDetails = async (refundId) => { try { - const response = await axios.get(`${ENDPOINT.refunds}/${id}`); + const response = await axios.get(`${ENDPOINT.refunds}/${refundId}`); return response.data; } catch (error) { return error.response; @@ -151,7 +160,7 @@ module.exports = { getOnePayedPaymentDetails, getAllPaymentRequests, getAllPaymentLinksCreatedOnInstamojo, - RefundRequest, + RefundRequestOptions, initiateRefund, getAllRefunds, getRefundDetails, diff --git a/src/__tests__/Instamojo.test.js b/src/__tests__/Instamojo.test.js index 9baa025..52ed24a 100644 --- a/src/__tests__/Instamojo.test.js +++ b/src/__tests__/Instamojo.test.js @@ -361,3 +361,141 @@ describe("should get payment details", () => { expect(maxios.get).toHaveBeenCalledWith("/links"); }); }); + +describe("Refund API tests", () => { + test("Create refund options object", () => { + const refundObject = new Instamojo.RefundRequestOptions({ + payment_id: "MOJO0816705N15845280", + type: "RFD", + body: "Reason for refund", + }); + + expect(refundObject).toEqual({ + payment_id: "MOJO0816705N15845280", + type: "RFD", + body: "Reason for refund", + }); + + expect(refundObject.getObject()).toEqual({ + payment_id: "MOJO0816705N15845280", + type: "RFD", + body: "Reason for refund", + }); + + refundObject.setOptionalRefundAmount(99); + expect(refundObject.getObject()).toEqual({ + payment_id: "MOJO0816705N15845280", + refund_amount: 99, + type: "RFD", + body: "Reason for refund", + }); + }); + + const expectedrefundResponse = { + refund: { + id: "C5c0751269", + payment_id: "MOJO5a06005J21512197", + status: "Refunded", + type: "QFL", + body: "Customer isn't satisfied with the quality", + refund_amount: "2500.00", + total_amount: "2500.00", + created_at: "2015-12-07T11:01:37.640Z", + }, + success: true, + }; + + test("Initiate refund request with refund options object", async () => { + maxios.post.mockImplementationOnce(() => + Promise.resolve({ data: expectedrefundResponse }) + ); + maxios.post.mockImplementationOnce(() => + Promise.reject(promiseRejectResponse) + ); + + const refundObject = new Instamojo.RefundRequestOptions({ + payment_id: "MOJO0816705N15845280", + type: "RFD", + body: "Reason for refund", + }); + + const refundResponse = await Instamojo.initiateRefund(refundObject); + const rejectedResponse = await Instamojo.initiateRefund(refundObject); + + expect(refundResponse).toStrictEqual(expectedrefundResponse); + expect(rejectedResponse).toStrictEqual(promiseRejectResponse.response); + expect(maxios.post).toHaveBeenCalledTimes(2); + expect(maxios.post).toHaveBeenCalledWith("/refunds", { + body: "Reason for refund", + payment_id: "MOJO0816705N15845280", + type: "RFD", + }); + }); + const allRefundExpectedrefundResponse = { + refunds: [ + { + id: "C5c0751269", + payment_id: "MOJO5a06005J21512197", + status: "Refunded", + type: "QFL", + body: "Customer isn't satisfied with the quality", + refund_amount: "2500.00", + total_amount: "2500.00", + created_at: "2015-12-07T11:01:37.640Z", + }, + ], + success: true, + }; + test("Get all refund requests", async () => { + maxios.get.mockImplementationOnce(() => + Promise.resolve({ data: allRefundExpectedrefundResponse }) + ); + maxios.get.mockImplementationOnce(() => + Promise.reject(promiseRejectResponse) + ); + + const allRefundResponse = await Instamojo.getAllRefunds(); + const allRefundRejectedResponse = await Instamojo.getAllRefunds(); + + expect(allRefundResponse).toStrictEqual(allRefundResponse); + expect(allRefundRejectedResponse).toStrictEqual( + promiseRejectResponse.response + ); + expect(maxios.get).toHaveBeenCalledTimes(2); + expect(maxios.get).toHaveBeenCalledWith("/refunds"); + }); + + const singleRefundResponse = { + refund: { + id: "C5c0751272", + payment_id: "MOJO5a06005J21512197", + status: "Refunded", + type: "QFL", + body: "Customer isn't satisfied with the quality", + refund_amount: "2500.00", + total_amount: "2500.00", + created_at: "2015-12-07T11:04:09.500Z", + }, + success: true, + }; + test("Get single refund details with refundId", async () => { + maxios.get.mockImplementationOnce(() => + Promise.resolve({ data: singleRefundResponse }) + ); + maxios.get.mockImplementationOnce(() => + Promise.reject(promiseRejectResponse) + ); + + const allRefundResponse = await Instamojo.getRefundDetails("C5c0751272"); + const allRefundRejectedResponse = await Instamojo.getRefundDetails( + "C5c0751272" + ); + + expect(allRefundResponse).toStrictEqual(allRefundResponse); + expect(allRefundRejectedResponse).toStrictEqual( + promiseRejectResponse.response + ); + expect(maxios.get).toHaveBeenCalledTimes(2); + expect(maxios.get).toHaveBeenCalledWith("/refunds/C5c0751272"); + }); +}); From cc341093f5631425e4c999695637005aa73e501d Mon Sep 17 00:00:00 2001 From: Tejas H Date: Tue, 18 Aug 2020 13:58:58 +0530 Subject: [PATCH 3/3] 2.3.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8080c84..d9c49e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "instamojo-payment-nodejs", - "version": "2.2.0-rc", + "version": "2.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0aeb68f..829b4fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "instamojo-payment-nodejs", - "version": "2.2.0-rc", + "version": "2.3.0", "description": "Promise based Instamojo payment gateway integration for NodeJS", "main": "main.js", "scripts": {