Skip to content

Commit

Permalink
feat: add Google Pay through Braintree
Browse files Browse the repository at this point in the history
To use Google Pay through Braintree, ensure that you have enabled
Google Pay on a Braintree gateway in the Recurly Admin UI and on your
Braintree account.

Then, initialize `recurly.GooglePay(...)` with the
`braintree.clientAuthorization` option:

```js
const googlePay = recurly.GooglePay({
  ...options,
  gatewayCode: '<Recurly Braintree gateway code>',
  braintree: {
    clientAuthorization: '<Braintree client authorization key>',
  },
})
```
  • Loading branch information
cbarton committed Aug 26, 2024
1 parent f674740 commit ebc0429
Show file tree
Hide file tree
Showing 4 changed files with 721 additions and 555 deletions.
64 changes: 64 additions & 0 deletions lib/recurly/google-pay/google-pay.braintree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Promise from 'promise';
import { GooglePay } from './google-pay';
import Debug from 'debug';
import BraintreeLoader from '../../util/braintree-loader';
import errors from '../errors';
import { payWithGoogle } from './pay-with-google';

const debug = Debug('recurly:google-pay:braintree');

export class GooglePayBraintree extends GooglePay {
configure (options) {
debug('Initializing client');

const authorization = options.braintree.clientAuthorization;

BraintreeLoader.loadModules('googlePayment', 'dataCollector')
.then(() => window.braintree.client.create({ authorization }))
.then(client => Promise.all([
window.braintree.dataCollector.create({ client }),
window.braintree.googlePayment.create({
client,
googlePayVersion: 2,
googleMerchantId: options.googleMerchantId,
})
]))
.then(([dataCollector, googlePayment]) => { this.braintree = { dataCollector, googlePayment }; })
.catch(err => this.emit('error', errors('google-pay-init-error', { err })))
.then(() => super.configure(options));
}

createButton ({ paymentOptions, isReadyToPayRequest, paymentDataRequest: recurlyPaymentDataRequest, buttonOptions }) {
// allow Braintree to set the tokenizationSpecification for its gateway
recurlyPaymentDataRequest.allowedPaymentMethods.forEach(method => {
if (method.tokenizationSpecification) delete method.tokenizationSpecification;
});
const paymentDataRequest = this.braintree.googlePayment.createPaymentDataRequest(recurlyPaymentDataRequest);
debug('Creating button', recurlyPaymentDataRequest, paymentDataRequest);
return payWithGoogle({
paymentOptions,
isReadyToPayRequest,
paymentDataRequest,
buttonOptions,
});
}

token (paymentData) {
debug('Creating token', paymentData);

return this.braintree.googlePayment
.parseResponse(paymentData)
.then(token => {
token.deviceData = this.braintree.dataCollector.deviceData;
paymentData.paymentMethodData.gatewayToken = token;
return super.token(paymentData);
});
}

mapPaymentData (paymentData) {
return {
type: 'braintree',
...super.mapPaymentData(paymentData),
};
}
}
5 changes: 4 additions & 1 deletion lib/recurly/google-pay/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { GooglePay } from './google-pay';
import { GooglePayBraintree } from './google-pay.braintree';

/**
* Returns a GooglePay instance.
Expand All @@ -7,7 +8,9 @@ import { GooglePay } from './google-pay';
* @return {GooglePay}
*/
export function factory (options) {
const factoryClass = GooglePay;
const factoryClass = options?.braintree?.clientAuthorization
? GooglePayBraintree
: GooglePay;

return new factoryClass(Object.assign({}, options, { recurly: this }));
}
Loading

0 comments on commit ebc0429

Please sign in to comment.