From bdfb2053e24bc53fbe7756fa0b00d5ccc603102e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Tue, 2 Jan 2024 12:04:20 +0100 Subject: [PATCH] adds payment sessions support --- src/Checkout.js | 1 + src/api/payment-sessions/payment-sessions.js | 39 ++++++++++++++++ src/index.js | 1 + src/services/validation.js | 1 + .../payment-sessions-common.js | 46 +++++++++++++++++++ test/payment-sessions/payment-sessions-it.js | 27 +++++++++++ .../payment-sessions/payment-sessions-unit.js | 28 +++++++++++ 7 files changed, 143 insertions(+) create mode 100644 src/api/payment-sessions/payment-sessions.js create mode 100644 test/payment-sessions/payment-sessions-common.js create mode 100644 test/payment-sessions/payment-sessions-it.js create mode 100644 test/payment-sessions/payment-sessions-unit.js diff --git a/src/Checkout.js b/src/Checkout.js index b1dbb73..77c198f 100644 --- a/src/Checkout.js +++ b/src/Checkout.js @@ -171,5 +171,6 @@ export default class Checkout { this.financial = new ENDPOINTS.Financial(this.config); this.issuing = new ENDPOINTS.Issuing(this.config); this.paymentContexts = new ENDPOINTS.PaymentContexts(this.config); + this.paymentSessions = new ENDPOINTS.PaymentSessions(this.config); } } \ No newline at end of file diff --git a/src/api/payment-sessions/payment-sessions.js b/src/api/payment-sessions/payment-sessions.js new file mode 100644 index 0000000..5efbc84 --- /dev/null +++ b/src/api/payment-sessions/payment-sessions.js @@ -0,0 +1,39 @@ +import { determineError } from '../../services/errors'; +import { post } from '../../services/http'; +import { validatePayment } from '../../services/validation'; + +/* + * Class dealing with the /payment-sessions endpoint + * + * @export + * @class PaymentSessions + */ +export default class PaymentSessions { + constructor(config) { + this.config = config; + } + + /** + * Sends payment sessions requests. + * + * @memberof PaymentSessions + * @param {object} body PaymentSessions Request body. + * @return {Promise} A promise to payment context response. + */ + async request(body) { + try { + validatePayment(body); + + const response = await post( + this.config.httpClient, + `${this.config.host}/payment-sessions`, + this.config, + this.config.sk, + body + ); + return await response.json; + } catch (error) { + throw await determineError(error); + } + } +} diff --git a/src/index.js b/src/index.js index 0431446..555ec5c 100644 --- a/src/index.js +++ b/src/index.js @@ -35,5 +35,6 @@ export { default as Reports } from './api/reports/reports'; export { default as Financial } from './api/financial/financial'; export { default as Issuing } from './api/issuing/issuing'; export { default as PaymentContexts } from './api/payment-contexts/payment-contexts'; +export { default as PaymentSessions } from './api/payment-sessions/payment-sessions'; export { default as Checkout } from './Checkout'; export { default } from './Checkout'; diff --git a/src/services/validation.js b/src/services/validation.js index 8b12843..95cf4eb 100644 --- a/src/services/validation.js +++ b/src/services/validation.js @@ -9,6 +9,7 @@ export const validatePayment = (request) => { if (request.amount && ('' + request.amount).indexOf('.') !== -1) { throw new ValueError('The amount can not contain decimals.'); } + if (!(request.currency in CURRENCIES)) { throw new ValueError('The currency value is not valid.'); } diff --git a/test/payment-sessions/payment-sessions-common.js b/test/payment-sessions/payment-sessions-common.js new file mode 100644 index 0000000..ba1d177 --- /dev/null +++ b/test/payment-sessions/payment-sessions-common.js @@ -0,0 +1,46 @@ +export const commonRequest = { + amount: 1000, + currency: 'GBP', + reference: 'ORD-123A', + billing: { + address: { + country: 'GB' + } + }, + customer: { + name: 'John Smith', + email: 'john.smith@example.com' + }, + success_url: 'https://example.com/payments/success', + failure_url: 'https://example.com/payments/failure' +}; + +export const commonResponse = { + id: 'ps_2aOig7knIeGNYPlyuxUEPQyOmxN', + amount: 1000, + locale: 'en-GB', + currency: 'GBP', + payment_methods: [ + { + type: 'card', + scheme_choice_enabled: false, + store_payment_details: 'disabled' + }, + { + type: 'applepay', + display_name: 'Parser Digital', + country_code: 'GB', + currency_code: 'GBP', + }, + { + type: 'googlepay', + } + ], + feature_flags: [], + risk: { enabled: true }, + _links: { + self: { + href: 'https://api.sandbox.checkout.com/payment-sessions/ps_2aOig7knIeGNYPlyuxUEPQyOmxN' + } + } +}; \ No newline at end of file diff --git a/test/payment-sessions/payment-sessions-it.js b/test/payment-sessions/payment-sessions-it.js new file mode 100644 index 0000000..712564c --- /dev/null +++ b/test/payment-sessions/payment-sessions-it.js @@ -0,0 +1,27 @@ +import { expect } from "chai"; +import nock from "nock"; +import Checkout from '../../src/Checkout.js' +import { commonRequest, commonResponse } from "./payment-sessions-common.js"; + +afterEach(() => { + nock.cleanAll(); + nock.enableNetConnect(); +}); + +const cko = new Checkout(process.env.CHECKOUT_DEFAULT_SECRET_KEY); + +describe('Integration::Payment-Sessions', () => { + + it('should request a payment session', async () => { + const response = await cko.paymentSessions.request(commonRequest); + + expect(response.id).not.to.be.null; + expect(response.amount).to.equal(commonResponse.amount); + expect(response.locale).to.equal(commonResponse.locale); + expect(response.currency).to.equal(commonResponse.currency); + expect(response.customer).not.to.be.null; + expect(response.payment_methods).not.to.be.null; + expect(response._links).not.to.be.null; + }); + +}); \ No newline at end of file diff --git a/test/payment-sessions/payment-sessions-unit.js b/test/payment-sessions/payment-sessions-unit.js new file mode 100644 index 0000000..459f7c3 --- /dev/null +++ b/test/payment-sessions/payment-sessions-unit.js @@ -0,0 +1,28 @@ +import nock from "nock"; +import { expect } from "chai"; +import Checkout from "../../src/Checkout.js"; +import { commonRequest, commonResponse } from "./payment-sessions-common.js"; + + +describe('Unit::Payment-Sessions', () => { + const SK = 'sk_test_0b9b5db6-f223-49d0-b68f-f6643dd4f808'; + + it('should request a payment session', async () => { + nock('https://api.sandbox.checkout.com') + .post('/payment-sessions') + .reply(201, commonResponse); + + const cko = new Checkout(SK); + + const paymentContextResponse = await cko.paymentSessions.request(commonRequest); + + expect(paymentContextResponse.id).to.equal('ps_2aOig7knIeGNYPlyuxUEPQyOmxN'); + expect(paymentContextResponse.amount).to.equal(1000); + expect(paymentContextResponse.locale).to.equal('en-GB'); + expect(paymentContextResponse.currency).to.equal('GBP'); + expect(paymentContextResponse.payment_methods[0].type).to.equal('card'); + expect(paymentContextResponse.risk.enabled).to.equal(true); + expect(paymentContextResponse._links.self.href).to.equal('https://api.sandbox.checkout.com/payment-sessions/ps_2aOig7knIeGNYPlyuxUEPQyOmxN'); + }); + +}); \ No newline at end of file