From 02911d9d30234189904f978bfbad17108b576fb2 Mon Sep 17 00:00:00 2001 From: Vigar Date: Thu, 20 Jan 2022 15:32:26 +0530 Subject: [PATCH 01/11] Add getPaymentsByFixedPaymentCodeId API support --- src/retail_outlet/retail_outlet.d.ts | 1 + src/retail_outlet/retail_outlet.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/retail_outlet/retail_outlet.d.ts b/src/retail_outlet/retail_outlet.d.ts index 836862c..4813a1b 100644 --- a/src/retail_outlet/retail_outlet.d.ts +++ b/src/retail_outlet/retail_outlet.d.ts @@ -21,4 +21,5 @@ export = class RetailOutlet { expirationDate?: Date; }): Promise; getFixedPaymentCode(data: { id: string }): Promise; + getPaymentsByFixedPaymentCodeId(data: { id: string }): Promise; }; diff --git a/src/retail_outlet/retail_outlet.js b/src/retail_outlet/retail_outlet.js index 4bc5a4e..bb8a88b 100644 --- a/src/retail_outlet/retail_outlet.js +++ b/src/retail_outlet/retail_outlet.js @@ -90,4 +90,19 @@ RetailOutlet.prototype.getFixedPaymentCode = function(data) { }); }; +RetailOutlet.prototype.getPaymentsByFixedPaymentCodeId = function(data) { + return promWithJsErr((resolve, reject) => { + Validate.rejectOnMissingFields(['id'], data, reject); + + fetchWithHTTPErr(`${this.API_ENDPOINT}/${data.id}/payments`, { + method: 'GET', + headers: { + Authorization: Auth.basicAuthHeader(this.opts.secretKey), + }, + }) + .then(resolve) + .catch(reject); + }); +}; + module.exports = RetailOutlet; From c7e76244faa529e3680d42af7cdf8fd3ff519308 Mon Sep 17 00:00:00 2001 From: Vigar Date: Thu, 20 Jan 2022 15:32:41 +0530 Subject: [PATCH 02/11] Add tests for getPaymentsByFixedPaymentCodeId --- test/retail_outlet/constants.js | 13 ++++++++++++- test/retail_outlet/retail_outlet.test.js | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/test/retail_outlet/constants.js b/test/retail_outlet/constants.js index d691df4..9be3753 100644 --- a/test/retail_outlet/constants.js +++ b/test/retail_outlet/constants.js @@ -20,6 +20,16 @@ const FIXED_PAYMENT_CODE_DETAILS = { id: FIXED_PAYMENT_CODE_ID, }; +const PAYMENTS_BY_FIXED_PAYMENT_CODE_ID = { + data: [FIXED_PAYMENT_CODE_DETAILS], + has_more: true, + links: { + href: "https://api.xendit.co/fixed_payment_code/5e0ed8797bc384e60435ec62/payments?limit=1&after_id=61c53c4f6", + rel: "next", + method: "GET" + } +}; + const UPDATED_FIXED_PAYMENT_CODE_DETAILS = Object.assign( {}, FIXED_PAYMENT_CODE_DETAILS, @@ -36,5 +46,6 @@ module.exports = { FIXED_PAYMENT_CODE_ID, UPDATED_AMOUNT, FIXED_PAYMENT_CODE_DETAILS, + PAYMENTS_BY_FIXED_PAYMENT_CODE_ID, UPDATED_FIXED_PAYMENT_CODE_DETAILS, -}; +}; \ No newline at end of file diff --git a/test/retail_outlet/retail_outlet.test.js b/test/retail_outlet/retail_outlet.test.js index 0a331b2..93b7607 100644 --- a/test/retail_outlet/retail_outlet.test.js +++ b/test/retail_outlet/retail_outlet.test.js @@ -28,6 +28,8 @@ before(function() { .reply(200, TestConstants.FIXED_PAYMENT_CODE_DETAILS) .get(`/${TestConstants.FIXED_PAYMENT_CODE_ID}`) .reply(200, TestConstants.FIXED_PAYMENT_CODE_DETAILS) + .get(`/${TestConstants.FIXED_PAYMENT_CODE_ID}/payments`) + .reply(200, TestConstants.PAYMENTS_BY_FIXED_PAYMENT_CODE_ID) .patch(`/${TestConstants.FIXED_PAYMENT_CODE_ID}`, { expected_amount: TestConstants.UPDATED_AMOUNT, }) @@ -84,6 +86,28 @@ describe('Retaiil Outlet Service', () => { }); }); + describe('getPaymentsByFixedPaymentCodeId', () => { + it('should retrieve payments by fixed payment code id', done => { + expect( + ro.getPaymentsByFixedPaymentCodeId({ id: TestConstants.FIXED_PAYMENT_CODE_ID }), + ) + .to.eventually.deep.equal(TestConstants.PAYMENTS_BY_FIXED_PAYMENT_CODE_ID) + .and.notify(done); + }); + + it('should report missing required fields', done => { + expect(ro.getPaymentsByFixedPaymentCodeId({})) + .to.eventually.be.rejected.then(e => + Promise.all([ + expect(e).to.have.property('status', 400), + expect(e).to.have.property('code', Errors.API_VALIDATION_ERROR), + ]), + ) + .then(() => done()) + .catch(e => done(e)); + }); + }); + describe('updateFixedPaymentCode', () => { it('should update a fixed payment code', done => { expect( From 8e8355ae2d03946b982d9d5747fab0671f06f92d Mon Sep 17 00:00:00 2001 From: Vigar Date: Thu, 20 Jan 2022 16:40:47 +0530 Subject: [PATCH 03/11] Update test constants and fix linting issues --- test/retail_outlet/constants.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/retail_outlet/constants.js b/test/retail_outlet/constants.js index 9be3753..505edb3 100644 --- a/test/retail_outlet/constants.js +++ b/test/retail_outlet/constants.js @@ -4,6 +4,8 @@ const NAME = 'Uvuvwevwevwe Osas'; const ALFMART_RETAIL_OUTLET_NAME = 'ALFAMART'; const FIXED_PAYMENT_CODE_ID = '5e0ed8797bc384e60435ec62'; const UPDATED_AMOUNT = 12000; +const API_ENDPOINT = 'https://api.xendit.co'; +const AFTER_ID = '61c53c4f6'; const FIXED_PAYMENT_CODE_DETAILS = { owner_id: '12121212', @@ -24,10 +26,12 @@ const PAYMENTS_BY_FIXED_PAYMENT_CODE_ID = { data: [FIXED_PAYMENT_CODE_DETAILS], has_more: true, links: { - href: "https://api.xendit.co/fixed_payment_code/5e0ed8797bc384e60435ec62/payments?limit=1&after_id=61c53c4f6", - rel: "next", - method: "GET" - } + href: + `${API_ENDPOINT}/fixed_payment_code/` + + `${FIXED_PAYMENT_CODE_ID}/payments?after_id=${AFTER_ID}`, + rel: 'next', + method: 'GET', + }, }; const UPDATED_FIXED_PAYMENT_CODE_DETAILS = Object.assign( From 3711a4e50d1f1ebbfe847c3f5f8eff2111cc64cf Mon Sep 17 00:00:00 2001 From: Vigar Date: Thu, 20 Jan 2022 16:41:14 +0530 Subject: [PATCH 04/11] Fix whitespace --- test/retail_outlet/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/retail_outlet/constants.js b/test/retail_outlet/constants.js index 505edb3..221321e 100644 --- a/test/retail_outlet/constants.js +++ b/test/retail_outlet/constants.js @@ -52,4 +52,4 @@ module.exports = { FIXED_PAYMENT_CODE_DETAILS, PAYMENTS_BY_FIXED_PAYMENT_CODE_ID, UPDATED_FIXED_PAYMENT_CODE_DETAILS, -}; \ No newline at end of file +}; From ff8ebf3d00fcdf6d8785d27a52f4f478f4282016 Mon Sep 17 00:00:00 2001 From: Vigar Date: Thu, 20 Jan 2022 16:43:59 +0530 Subject: [PATCH 05/11] Fix eslint issues --- integration_test/regional_retail_outlet.test.js | 12 ++++++++---- src/xendit.js | 1 + 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/integration_test/regional_retail_outlet.test.js b/integration_test/regional_retail_outlet.test.js index 33388a7..5ea9084 100644 --- a/integration_test/regional_retail_outlet.test.js +++ b/integration_test/regional_retail_outlet.test.js @@ -3,7 +3,7 @@ const x = require('./xendit_ph.test'); const RegionalRetailOutlet = x.RegionalRetailOutlet; const ro = new RegionalRetailOutlet({}); -const dynamicReferenceId = Math.floor((Math.random() * 9999) + 1) +const dynamicReferenceId = Math.floor(Math.random() * 9999 + 1); module.exports = function() { return ro @@ -13,15 +13,19 @@ module.exports = function() { customerName: 'Dharma', amount: 50, currency: 'PHP', - market: 'PH' + market: 'PH', }) .then(({ id }) => ro.getPaymentCode({ id })) - .then(({ id }) => ro.updatePaymentCode({ id: id, customerName: "DharmaLain" })) + .then(({ id }) => + ro.updatePaymentCode({ id: id, customerName: 'DharmaLain' }), + ) .then(() => { // eslint-disable-next-line no-console console.log('Regional Retail outlet integration test done...'); }) .catch(e => { - throw new Error(`Regional RO integration tests failed with error: ${e.message}`); + throw new Error( + `Regional RO integration tests failed with error: ${e.message}`, + ); }); }; diff --git a/src/xendit.js b/src/xendit.js index f980b84..7d3f3e2 100644 --- a/src/xendit.js +++ b/src/xendit.js @@ -39,6 +39,7 @@ function Xendit(options) { this.RetailOutlet = RetailOutletService._constructorWithInjectedXenditOpts( this.opts, ); + // eslint-disable-next-line max-len this.RegionalRetailOutlet = RegionalRetailOutletService._constructorWithInjectedXenditOpts( this.opts, ); From bd24120b66e129a5c44e463c63b487ba169e390d Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 08:37:51 +0530 Subject: [PATCH 06/11] Add integration test --- integration_test/retail_outlet.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/integration_test/retail_outlet.test.js b/integration_test/retail_outlet.test.js index 69fa56d..f40caa4 100644 --- a/integration_test/retail_outlet.test.js +++ b/integration_test/retail_outlet.test.js @@ -12,6 +12,7 @@ module.exports = function() { expectedAmt: 10000, }) .then(({ id }) => ro.getFixedPaymentCode({ id })) + .then(({ id }) => ro.getPaymentsByFixedPaymentCodeId({ id })) .then(({ id }) => ro.updateFixedPaymentCode({ id: id, expectedAmt: 12000 })) .then(() => { // eslint-disable-next-line no-console From f41b255b1ba2e2a36bb278c11acc75476a8854d5 Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 10:20:48 +0530 Subject: [PATCH 07/11] Fix getPaymentsByFixedPaymentCodeId integration tests --- integration_test/retail_outlet.test.js | 12 +++++++++++- src/retail_outlet/retail_outlet.d.ts | 5 +++++ src/retail_outlet/retail_outlet.js | 25 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/integration_test/retail_outlet.test.js b/integration_test/retail_outlet.test.js index f40caa4..91338ca 100644 --- a/integration_test/retail_outlet.test.js +++ b/integration_test/retail_outlet.test.js @@ -12,8 +12,18 @@ module.exports = function() { expectedAmt: 10000, }) .then(({ id }) => ro.getFixedPaymentCode({ id })) - .then(({ id }) => ro.getPaymentsByFixedPaymentCodeId({ id })) .then(({ id }) => ro.updateFixedPaymentCode({ id: id, expectedAmt: 12000 })) + .then(({ id, payment_code }) => + Promise.all([ + id, + ro.simulatePayment({ + retailOutletName: 'ALFAMART', + paymentCode: payment_code, + transferAmount: 12000, + }), + ]), + ) + .then(([id]) => ro.getPaymentsByFixedPaymentCodeId({ id })) .then(() => { // eslint-disable-next-line no-console console.log('Retail outlet integration test done...'); diff --git a/src/retail_outlet/retail_outlet.d.ts b/src/retail_outlet/retail_outlet.d.ts index 4813a1b..f221ac0 100644 --- a/src/retail_outlet/retail_outlet.d.ts +++ b/src/retail_outlet/retail_outlet.d.ts @@ -22,4 +22,9 @@ export = class RetailOutlet { }): Promise; getFixedPaymentCode(data: { id: string }): Promise; getPaymentsByFixedPaymentCodeId(data: { id: string }): Promise; + simulatePayment(data: { + retailOutletName: string; + paymentCode: string; + transferAmount: number; + }): Promise; }; diff --git a/src/retail_outlet/retail_outlet.js b/src/retail_outlet/retail_outlet.js index bb8a88b..b5d6a7e 100644 --- a/src/retail_outlet/retail_outlet.js +++ b/src/retail_outlet/retail_outlet.js @@ -105,4 +105,29 @@ RetailOutlet.prototype.getPaymentsByFixedPaymentCodeId = function(data) { }); }; +RetailOutlet.prototype.simulatePayment = function(data) { + return promWithJsErr((resolve, reject) => { + Validate.rejectOnMissingFields( + ['retailOutletName', 'paymentCode', 'transferAmount'], + data, + reject, + ); + + fetchWithHTTPErr(`${this.API_ENDPOINT}/simulate_payment`, { + method: 'POST', + headers: { + Authorization: Auth.basicAuthHeader(this.opts.secretKey), + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + retail_outlet_name: data.retailOutletName, + payment_code: data.paymentCode, + transfer_amount: data.transferAmount, + }), + }) + .then(resolve) + .catch(reject); + }); +}; + module.exports = RetailOutlet; From 395312eab98dfdae863c9e1599cdea258c5c72cc Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 10:26:14 +0530 Subject: [PATCH 08/11] Fix eslint warnings --- test/retail_outlet/retail_outlet.test.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/retail_outlet/retail_outlet.test.js b/test/retail_outlet/retail_outlet.test.js index 93b7607..609c2a4 100644 --- a/test/retail_outlet/retail_outlet.test.js +++ b/test/retail_outlet/retail_outlet.test.js @@ -89,9 +89,13 @@ describe('Retaiil Outlet Service', () => { describe('getPaymentsByFixedPaymentCodeId', () => { it('should retrieve payments by fixed payment code id', done => { expect( - ro.getPaymentsByFixedPaymentCodeId({ id: TestConstants.FIXED_PAYMENT_CODE_ID }), + ro.getPaymentsByFixedPaymentCodeId({ + id: TestConstants.FIXED_PAYMENT_CODE_ID, + }), ) - .to.eventually.deep.equal(TestConstants.PAYMENTS_BY_FIXED_PAYMENT_CODE_ID) + .to.eventually.deep.equal( + TestConstants.PAYMENTS_BY_FIXED_PAYMENT_CODE_ID, + ) .and.notify(done); }); From b04f6a411ea578c596d9ed9434a4382062b1d141 Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 10:56:33 +0530 Subject: [PATCH 09/11] Update readme --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index d2d4cc7..1bb2daf 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,9 @@ For PCI compliance to be maintained, tokenization of credit cards info should be * [Retail Outlet Services](#retail-outlet-services) + [Create fixed payment code](#create-fixed-payment-code) + [Get fixed payment code](#get-fixed-payment-code) + + [Get payments by fixed payment code ID](#get-payments-by-fixed-payment-code-id) + [Update fixed payment code](#update-fixed-payment-code) + + [Simulate payment (only in dev mode)](#simulate-payment) * [QR Code Services](#qr-code-services) + [Create code](#create-code) + [Get code](#get-code) @@ -844,6 +846,12 @@ ro.createFixedPaymentCode(data: { ro.getFixedPaymentCode(data: { id: string }) ``` +#### Get payments by fixed payment code ID + +```ts +ro.getPaymentsByFixedPaymentCodeId(data: { id: string }) +``` + #### Update fixed payment code ```ts @@ -855,6 +863,16 @@ ro.updateFixedPaymentCode(data: { }) ``` +#### Simulate payment + +```ts +ro.simulatePayment(data: { + retailOutletName: string; + paymentCode: string; + transferAmount: number; +}) +``` + ### QR Code Services Instanitiate QR Code service using constructor that has been injected with Xendit keys From 72a92ff346d47196cd04e195641aa145ca10044c Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 10:57:59 +0530 Subject: [PATCH 10/11] Update package version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46d03e3..becd1ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "xendit-node", - "version": "1.19.1", + "version": "1.19.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "xendit-node", - "version": "1.19.1", + "version": "1.19.6", "license": "MIT", "dependencies": { "node-fetch": "^2.6.1" diff --git a/package.json b/package.json index 65f494a..e73d5d2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xendit-node", - "version": "1.19.5", + "version": "1.19.6", "description": "NodeJS client for Xendit API", "main": "index.js", "types": "index.d.ts", From ab15a94bd1f3067b36ddd817c9f2ad26d96eae1d Mon Sep 17 00:00:00 2001 From: Vigar Date: Fri, 21 Jan 2022 11:21:53 +0530 Subject: [PATCH 11/11] Add examples --- examples/with_async/retail_outlet.js | 12 ++++++++++++ examples/with_promises/retail_outlet.js | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/examples/with_async/retail_outlet.js b/examples/with_async/retail_outlet.js index 2db7fad..d28013d 100644 --- a/examples/with_async/retail_outlet.js +++ b/examples/with_async/retail_outlet.js @@ -26,6 +26,18 @@ const ro = new RetailOutlet({}); // eslint-disable-next-line no-console console.log('updated payment code details:', updatedPmCode); + await ro.simulatePayment({ + retailOutletName: 'ALFAMART', + paymentCode: updatedPmCode.payment_code, + transferAmount: 12000, + }); + // eslint-disable-next-line no-console + console.log('simulated payment:', updatedPmCode); + + const paymentsByCodeId = await ro.getPaymentsByFixedPaymentCodeId({ id }); + // eslint-disable-next-line no-console + console.log('payments by fixed payment code ID:', paymentsByCodeId); + process.exit(0); } catch (e) { console.error(e); // eslint-disable-line no-console diff --git a/examples/with_promises/retail_outlet.js b/examples/with_promises/retail_outlet.js index f360948..8c25328 100644 --- a/examples/with_promises/retail_outlet.js +++ b/examples/with_promises/retail_outlet.js @@ -31,6 +31,27 @@ ro.createFixedPaymentCode({ console.log('updated payment code details:', r); return r; }) + .then(({ id, payment_code }) => + Promise.all([ + id, + ro.simulatePayment({ + retailOutletName: 'ALFAMART', + paymentCode: payment_code, + transferAmount: 12000, + }), + ]), + ) + .then(r => { + // eslint-disable-next-line no-console + console.log('simulated payment:', r); + return r; + }) + .then(([id]) => ro.getPaymentsByFixedPaymentCodeId({ id })) + .then(r => { + // eslint-disable-next-line no-console + console.log('payments by fixed payment code ID:', r); + return r; + }) .catch(e => { console.error(e); // eslint-disable-line no-console process.exit(1);