Skip to content

Commit

Permalink
Merge pull request #315 from recurly/apple-pay
Browse files Browse the repository at this point in the history
Apple Pay part 2
  • Loading branch information
snodgrass23 authored Jan 25, 2017
2 parents 5d13d30 + 34f5f65 commit 1fd6b05
Show file tree
Hide file tree
Showing 9 changed files with 446 additions and 11 deletions.
69 changes: 62 additions & 7 deletions lib/recurly/apple-pay.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import {Pricing} from './pricing';
const debug = require('debug')('recurly:apple-pay');

const SESSION_TIMEOUT = 300000; // 5m
const APPLE_PAY_API_VERSION = 2;

/**
* Instantiation factory
*
* @param {Object} options
* @return {ApplePay}
*/
export function factory (options) {
return new ApplePay(Object.assign({}, options, { recurly: this }));
};
Expand All @@ -28,9 +35,9 @@ class ApplePay extends Emitter {
this.once('ready', () => this._ready = true);

// Detect whether Apple Pay is available
if (!ApplePaySession) {
if (!global.ApplePaySession) {
this.initError = this.error('apple-pay-not-supported');
} else if (!ApplePaySession.canMakePayments()) {
} else if (!global.ApplePaySession.canMakePayments()) {
this.initError = this.error('apple-pay-not-available');
}

Expand All @@ -39,12 +46,16 @@ class ApplePay extends Emitter {
}
}

/**
* @return {ApplePaySession} Bound Apple Pay session
* @private
*/
get session () {
if (this._session) return this._session;

debug('Creating new Apple Pay session');

let session = new ApplePaySession(2, {
let session = new global.ApplePaySession(APPLE_PAY_API_VERSION, {
countryCode: this.config.country,
currencyCode: this.config.currency,
supportedNetworks: this.config.supportedNetworks,
Expand All @@ -62,25 +73,49 @@ class ApplePay extends Emitter {
return this._session = session;
}

/**
* @return {Array} subtotal line items for display on payment sheet
*/
get lineItems () {
// Clone configured line items
return [].concat(this.config.lineItems);
}

/**
* @return {Object} total cost line item
* @private
*/
get total () {
return { type: 'final', label: this.config.label, amount: this.config.total };
}

/**
* @return {String} name for plan line item
* @private
*/
get planLabel () {
if (this.config.pricing && this.config.pricing.items.plan) return this.config.pricing.items.plan.name;
else return 'Subscription plan';
}

/**
* Initialized state callback registry
*
* @param {Function} cb callback
* @private
*/
ready (cb) {
if (this._ready) cb();
else this.once('ready', cb);
}

/**
* Configures a new instance
*
* @param {Object} options
* @emit 'ready'
* @private
*/
configure (options) {
if ('label' in options) this.config.label = options.label;
else return this.initError = this.error('apple-pay-config-missing', { opt: 'label' });
Expand Down Expand Up @@ -120,6 +155,8 @@ class ApplePay extends Emitter {

/**
* Begins Apple Pay transaction
*
* @public
*/
begin () {
if (this.initError) return this.error('apple-pay-init-error', { err: this.initError });
Expand All @@ -131,6 +168,7 @@ class ApplePay extends Emitter {
* Updates line items and total price on pricing module changes
*
* @param {Object} price Pricing.price
* @private
*/
onPricingChange (price) {
// Reset line items
Expand All @@ -143,6 +181,7 @@ class ApplePay extends Emitter {
*
* @param {Event} event ApplePayValidateMerchantEvent
* @return {[type]} [description]
* @private
*/
onValidateMerchant (event) {
debug('Validating Apple Pay merchant session', event);
Expand All @@ -151,7 +190,6 @@ class ApplePay extends Emitter {

this.recurly.request('post', '/apple_pay/start', { validationURL }, (err, merchantSession) => {
if (err) return this.error(err);
console.info('session started', err, merchantSession);
this.session.completeMerchantValidation(merchantSession);
});
}
Expand All @@ -160,6 +198,7 @@ class ApplePay extends Emitter {
* Handles payment method selection
*
* @param {Event} event
* @private
*/
onPaymentMethodSelected (event) {
debug('Payment method selected', event);
Expand All @@ -170,6 +209,7 @@ class ApplePay extends Emitter {
* Handles shipping contact selection. Not utilized
*
* @param {Event} event
* @private
*/
onShippingContactSelected (event) {
const status = this.session.STATUS_SUCCESS;
Expand All @@ -181,6 +221,7 @@ class ApplePay extends Emitter {
* Handles shipping method selection. Not utilized
*
* @param {Event} event
* @private
*/
onShippingMethodSelected (event) {
this.session.completeShippingMethodSelection(this.total, this.lineItems);
Expand All @@ -190,10 +231,9 @@ class ApplePay extends Emitter {
* Handles payment authorization. Submits payment token and
* emits the resultant authorization token
*
* @emit 'token'
* @emit
*
* @param {Event} event
* @emit 'token'
* @private
*/
onPaymentAuthorized (event) {
debug('Payment authorization received', event);
Expand All @@ -211,12 +251,27 @@ class ApplePay extends Emitter {
});
}

/**
* Handles customer cancelation. Passes on the event
*
* @param {Event} event
* @emit 'cancel'
* @private
*/
onCancel (event) {
debug('User canceled Apple Pay payment', event);

this.emit('cancel', event);
}

/**
* Creates and emits a RecurlyError
*
* @param {...Mixed} params to be passed to the Recurlyerror factory
* @return {RecurlyError}
* @emit 'error'
* @private
*/
error (...params) {
let err = params[0] instanceof Error ? params[0] : errors(...params);
this.emit('error', err);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"combinations": "^0.1.1",
"express": "^4.13.3",
"glob": "^6.0.1",
"json-loader": "^0.5.4",
"karma": "^0.13.15",
"karma-chrome-launcher": "^2.0.0",
"karma-firefox-launcher": "^0.1.7",
Expand Down
Loading

0 comments on commit 1fd6b05

Please sign in to comment.