Skip to content

Commit

Permalink
feat(payments): INT-1577 Add support for paymentIntent creations endp…
Browse files Browse the repository at this point in the history
…oint
  • Loading branch information
Carlos Lopez committed Jul 25, 2019
1 parent 34002fc commit fdc3c5d
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 3 deletions.
24 changes: 22 additions & 2 deletions src/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import PaymentSubmitter from '../payment/payment-submitter';
import ClientTokenGenerator from '../payment/client-token-generator';
import StoreRequestSender from '../store/store-request-sender';
import DEFAULT_CONFIG from './default-config';
import PaymentIntentGenerator from '../payment/payment-intent-generator';

export default class Client {
/**
Expand All @@ -16,13 +17,15 @@ export default class Client {
const paymentSubmitter = PaymentSubmitter.create(clientConfig);
const clientTokenGenerator = ClientTokenGenerator.create(clientConfig);
const storeRequestSender = StoreRequestSender.create(clientConfig);
const paymentIntentGenerator = PaymentIntentGenerator.create(clientConfig);

return new Client(
clientConfig,
paymentSubmitter,
offsitePaymentInitializer,
clientTokenGenerator,
storeRequestSender
storeRequestSender,
paymentIntentGenerator
);
}

Expand All @@ -32,13 +35,15 @@ export default class Client {
* @param {OffsitePaymentInitializer} offsitePaymentInitializer
* @param {ClientTokenGenerator} clientTokenGenerator
* @param {StoreRequestSender} storeRequestSender
* @param {PaymentIntentGenerator} paymentIntentGenerator
*/
constructor(
config,
paymentSubmitter,
offsitePaymentInitializer,
clientTokenGenerator,
storeRequestSender
storeRequestSender,
paymentIntentGenerator
) {
/**
* @private
Expand Down Expand Up @@ -69,6 +74,12 @@ export default class Client {
* @type {StoreRequestSender}
*/
this.storeRequestSender = storeRequestSender;

/**
* @private
* @type {PaymentIntentGenerator}
*/
this.paymentIntentGenerator = paymentIntentGenerator;
}

/**
Expand Down Expand Up @@ -159,4 +170,13 @@ export default class Client {
deleteShopperInstrument(data, callback) {
this.storeRequestSender.deleteShopperInstrument(data, callback);
}

/**
* @param {PaymentRequestData} data
* @param {Function} [callback]
* @returns {void}
*/
generatePaymentIntent(data, callback) {
this.paymentIntentGenerator.generatePaymentIntent(data, callback);
}
}
55 changes: 55 additions & 0 deletions src/payment/payment-intent-generator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import RequestSender from '../common/http-request/request-sender';
import UrlHelper from './url-helper';
import PaymentIntentMapper from './v2/payment-mappers/payment-intent-mapper';

export default class PaymentIntentGenerator {
/**
* @param {Object} config
* @returns {PaymentSubmitter}
*/
static create(config) {
const urlHelper = UrlHelper.create(config);
const requestSender = RequestSender.create();
const paymentIntentMapper = PaymentIntentMapper.create();

return new PaymentIntentGenerator(urlHelper, requestSender, paymentIntentMapper);
}

/**
* @param {UrlHelper} urlHelper
* @param {RequestSender} requestSender
* @param {PaymentIntentMapper} paymentIntentMapper
* @returns {void}
*/
constructor(urlHelper, requestSender, paymentIntentMapper) {
/**
* @private
* @type {UrlHelper}
*/
this.urlHelper = urlHelper;

/**
* @private
* @type {RequestSender}
*/
this.requestSender = requestSender;

/**
* @private
* @type {PaymentIntentMapper}
*/
this.paymentIntentMapper = paymentIntentMapper;
}

/**
* @param {PaymentRequestData} data
* @param {Function} [callback]
* @returns {void}
*/
generatePaymentIntent(data, callback) {
const url = this.urlHelper.getGeneratePaymentIntentUrl();
const payload = this.paymentIntentMapper.mapToPaymentIntent(data);

this.requestSender.postRequest(url, payload, {}, callback);
}
}
7 changes: 7 additions & 0 deletions src/payment/url-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,11 @@ export default class UrlHelper {
getGenerateClientTokenUrl() {
return `${this.host}/api/v2/public/payments/client_tokens`;
}

/**
* @returns {string}
*/
getGeneratePaymentIntentUrl() {
return `${this.host}/api/v2/public/payments/payment_intents`;
}
}
55 changes: 55 additions & 0 deletions src/payment/v2/payment-mappers/payment-intent-mapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { omitNil } from '../../../common/utils';
import GatewayMapper from './gateway-mapper';

export default class PaymentIntentMapper {
/**
* @returns {PaymentIntentMapper}
*/
static create() {
const gatewayMapper = GatewayMapper.create();

return new PaymentIntentMapper(gatewayMapper);
}

/**
* @param {GatewayMapper} gatewayMapper
*/
constructor(gatewayMapper) {
/**
* @private
* @type {GatewayMapper}
*/
this.gatewayMapper = gatewayMapper;
}

/**
* @param {PaymentRequestData} data
* @returns {Object}
*/
mapToPaymentIntent(data) {
return omitNil({
stripe_data: this.mapStripeData(data),
gateway: this.gatewayMapper.mapToGateway(data),
});
}

mapStripeData(data) {
const {
shouldSavePaymentInstrument = false,
customer = {},
cart = {},
store = {},
} = data;

return omitNil({
should_save_payment_instrument: shouldSavePaymentInstrument,
customer_id: customer.customerId,
customer_name: customer.name,
customer_email: customer.email,
grand_total: cart.grandTotal.integerAmount,
currency_code: cart.currency,
store_id: store.storeId,
store_name: store.storeName,
});
}
}
17 changes: 16 additions & 1 deletion test/client/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('Client', () => {
let offsitePaymentInitializer;
let paymentSubmitter;
let storeRequestSender;
let paymentIntentGenerator;

beforeEach(() => {
config = { host: 'https://bigpay.dev' };
Expand All @@ -35,12 +36,17 @@ describe('Client', () => {
deleteShopperInstrument: jasmine.createSpy('deleteShopperInstrument'),
};

paymentIntentGenerator = {
generatePaymentIntent: jasmine.createSpy('generatePaymentIntent'),
};

client = new Client(
config,
paymentSubmitter,
offsitePaymentInitializer,
clientTokenGenerator,
storeRequestSender
storeRequestSender,
paymentIntentGenerator
);
});

Expand Down Expand Up @@ -126,4 +132,13 @@ describe('Client', () => {

expect(storeRequestSender.deleteShopperInstrument).toHaveBeenCalledWith(data, callback);
});

it('Generate a payment intent', () => {
const callback = () => {};
const data = storeIntrumentDataMock;

client.generatePaymentIntent(data, callback);

expect(paymentIntentGenerator.generatePaymentIntent).toHaveBeenCalledWith(data, callback);
});
});
42 changes: 42 additions & 0 deletions test/payment/payment-intent-generator.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import paymentRequestDataMock from '../mocks/payment-request-data';
import PaymentIntentGenerator from '../../src/payment/payment-intent-generator';

describe('PaymentIntentGenerator', () => {
let data;
let urlHelper;
let requestSender;
let paymentIntentMapper;
let paymentIntentGenerator;

beforeEach(() => {
data = paymentRequestDataMock;

urlHelper = {
getGeneratePaymentIntentUrl:
jasmine.createSpy('getPaymentUrl').and.returnValue('/api/v2/public/payments/payment_intents'),
};

requestSender = {
postRequest: jasmine.createSpy('postRequest'),
};

paymentIntentMapper = {
mapToPaymentIntent: jasmine.createSpy('mapToPaymentIntent'),
};

paymentIntentGenerator = new PaymentIntentGenerator(urlHelper, requestSender, paymentIntentMapper);
});

it('Create an instance of PaymentIntentGenerator', () => {
const config = { host: 'https://bigpay.dev' };
const instance = PaymentIntentGenerator.create(config);

expect(instance instanceof PaymentIntentGenerator).toBeTruthy();
});

it('Maps the input data into a payment intent object required to create a payment intent', () => {
paymentIntentGenerator.generatePaymentIntent(data, () => {});

expect(paymentIntentMapper.mapToPaymentIntent).toHaveBeenCalled();
});
});
4 changes: 4 additions & 0 deletions test/payment/url-helper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ describe('UrlHelper', () => {
it('returns a URL for generating a client token', () => {
expect(urlHelper.getGenerateClientTokenUrl()).toEqual(`${host}/api/v2/public/payments/client_tokens`);
});

it('returns a URL for generating a payment intent', () => {
expect(urlHelper.getGeneratePaymentIntentUrl()).toEqual(`${host}/api/v2/public/payments/payment_intents`);
});
});
41 changes: 41 additions & 0 deletions test/payment/v2/payment-mappers/payment-intent-mapper.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import GatewayMapper from '../../../../src/payment/v2/payment-mappers/gateway-mapper';
import paymentRequestDataMock from '../../../mocks/payment-request-data';
import PaymentIntentMapper from '../../../../src/payment/v2/payment-mappers/payment-intent-mapper';

describe('PaymentIntentMapper', () => {
let data;
let gatewayMapper;
let paymentIntentMapper;
let mappedData;
let paymentMethodIdMapper;

beforeEach(() => {
data = paymentRequestDataMock;
mappedData = {
name: 'id',
};

paymentMethodIdMapper = {
mapToId: jasmine.createSpy('mapToId').and.returnValue(mappedData.name),
};

gatewayMapper = new GatewayMapper(paymentMethodIdMapper);

paymentIntentMapper = new PaymentIntentMapper(gatewayMapper);
});

it('create a instance of paymentIntentMapper', () => {
const instance = PaymentIntentMapper.create();

expect(instance instanceof PaymentIntentMapper).toBeTruthy();
});

it('map the data to the payment intent', () => {
const output = paymentIntentMapper.mapToPaymentIntent(data);

expect(output).toEqual({
stripe_data: paymentIntentMapper.mapStripeData(data),
gateway: gatewayMapper.mapToGateway(data),
});
});
});

0 comments on commit fdc3c5d

Please sign in to comment.