UNPKG

braintree-web

Version:

A suite of tools for integrating Braintree in the browser

1,480 lines (1,307 loc) 62.7 kB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.braintree || (g.braintree = {})).usBankAccount = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){ "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PromiseGlobal = void 0; var promise_polyfill_1 = __importDefault(_dereq_("promise-polyfill")); var PromiseGlobal = // eslint-disable-next-line no-undef typeof Promise !== "undefined" ? Promise : promise_polyfill_1.default; exports.PromiseGlobal = PromiseGlobal; },{"promise-polyfill":9}],2:[function(_dereq_,module,exports){ "use strict"; var promise_1 = _dereq_("./lib/promise"); var scriptPromiseCache = {}; function loadScript(options) { var scriptLoadPromise; var stringifiedOptions = JSON.stringify(options); if (!options.forceScriptReload) { scriptLoadPromise = scriptPromiseCache[stringifiedOptions]; if (scriptLoadPromise) { return scriptLoadPromise; } } var script = document.createElement("script"); var attrs = options.dataAttributes || {}; var container = options.container || document.head; script.src = options.src; script.id = options.id || ""; script.async = true; if (options.crossorigin) { script.setAttribute("crossorigin", "" + options.crossorigin); } Object.keys(attrs).forEach(function (key) { script.setAttribute("data-" + key, "" + attrs[key]); }); scriptLoadPromise = new promise_1.PromiseGlobal(function (resolve, reject) { script.addEventListener("load", function () { resolve(script); }); script.addEventListener("error", function () { reject(new Error(options.src + " failed to load.")); }); script.addEventListener("abort", function () { reject(new Error(options.src + " has aborted.")); }); container.appendChild(script); }); scriptPromiseCache[stringifiedOptions] = scriptLoadPromise; return scriptLoadPromise; } loadScript.clearCache = function () { scriptPromiseCache = {}; }; module.exports = loadScript; },{"./lib/promise":1}],3:[function(_dereq_,module,exports){ module.exports = _dereq_("./dist/load-script"); },{"./dist/load-script":2}],4:[function(_dereq_,module,exports){ "use strict"; var GlobalPromise = (typeof Promise !== "undefined" ? Promise // eslint-disable-line no-undef : null); var ExtendedPromise = /** @class */ (function () { function ExtendedPromise(options) { var _this = this; if (typeof options === "function") { this._promise = new ExtendedPromise.Promise(options); return; } this._promise = new ExtendedPromise.Promise(function (resolve, reject) { _this._resolveFunction = resolve; _this._rejectFunction = reject; }); options = options || {}; this._onResolve = options.onResolve || ExtendedPromise.defaultOnResolve; this._onReject = options.onReject || ExtendedPromise.defaultOnReject; if (ExtendedPromise.shouldCatchExceptions(options)) { this._promise.catch(function () { // prevents unhandled promise rejection warning // in the console for extended promises that // that catch the error in an asynchronous manner }); } this._resetState(); } ExtendedPromise.defaultOnResolve = function (result) { return ExtendedPromise.Promise.resolve(result); }; ExtendedPromise.defaultOnReject = function (err) { return ExtendedPromise.Promise.reject(err); }; ExtendedPromise.setPromise = function (PromiseClass) { ExtendedPromise.Promise = PromiseClass; }; ExtendedPromise.shouldCatchExceptions = function (options) { if (options.hasOwnProperty("suppressUnhandledPromiseMessage")) { return Boolean(options.suppressUnhandledPromiseMessage); } return Boolean(ExtendedPromise.suppressUnhandledPromiseMessage); }; // start Promise methods documented in: // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Methods ExtendedPromise.all = function (args) { return ExtendedPromise.Promise.all(args); }; ExtendedPromise.allSettled = function (args) { return ExtendedPromise.Promise.allSettled(args); }; ExtendedPromise.race = function (args) { return ExtendedPromise.Promise.race(args); }; ExtendedPromise.reject = function (arg) { return ExtendedPromise.Promise.reject(arg); }; ExtendedPromise.resolve = function (arg) { return ExtendedPromise.Promise.resolve(arg); }; ExtendedPromise.prototype.then = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return (_a = this._promise).then.apply(_a, args); }; ExtendedPromise.prototype.catch = function () { var _a; var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return (_a = this._promise).catch.apply(_a, args); }; ExtendedPromise.prototype.resolve = function (arg) { var _this = this; if (this.isFulfilled) { return this; } this._setResolved(); ExtendedPromise.Promise.resolve() .then(function () { return _this._onResolve(arg); }) .then(function (argForResolveFunction) { _this._resolveFunction(argForResolveFunction); }) .catch(function (err) { _this._resetState(); _this.reject(err); }); return this; }; ExtendedPromise.prototype.reject = function (arg) { var _this = this; if (this.isFulfilled) { return this; } this._setRejected(); ExtendedPromise.Promise.resolve() .then(function () { return _this._onReject(arg); }) .then(function (result) { _this._setResolved(); _this._resolveFunction(result); }) .catch(function (err) { return _this._rejectFunction(err); }); return this; }; ExtendedPromise.prototype._resetState = function () { this.isFulfilled = false; this.isResolved = false; this.isRejected = false; }; ExtendedPromise.prototype._setResolved = function () { this.isFulfilled = true; this.isResolved = true; this.isRejected = false; }; ExtendedPromise.prototype._setRejected = function () { this.isFulfilled = true; this.isResolved = false; this.isRejected = true; }; ExtendedPromise.Promise = GlobalPromise; return ExtendedPromise; }()); module.exports = ExtendedPromise; },{}],5:[function(_dereq_,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function deferred(fn) { return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } setTimeout(function () { try { fn.apply(void 0, args); } catch (err) { /* eslint-disable no-console */ console.log("Error in callback function"); console.log(err); /* eslint-enable no-console */ } }, 1); }; } exports.deferred = deferred; },{}],6:[function(_dereq_,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function once(fn) { var called = false; return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (!called) { called = true; fn.apply(void 0, args); } }; } exports.once = once; },{}],7:[function(_dereq_,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable consistent-return */ function promiseOrCallback(promise, callback) { if (!callback) { return promise; } promise.then(function (data) { return callback(null, data); }).catch(function (err) { return callback(err); }); } exports.promiseOrCallback = promiseOrCallback; },{}],8:[function(_dereq_,module,exports){ "use strict"; var deferred_1 = _dereq_("./lib/deferred"); var once_1 = _dereq_("./lib/once"); var promise_or_callback_1 = _dereq_("./lib/promise-or-callback"); function wrapPromise(fn) { // eslint-disable-next-line @typescript-eslint/no-explicit-any return function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var callback; var lastArg = args[args.length - 1]; if (typeof lastArg === "function") { callback = args.pop(); callback = once_1.once(deferred_1.deferred(callback)); } // I know, I know, this looks bad. But it's a quirk of the library that // we need to allow passing the this context to the original function // eslint-disable-next-line @typescript-eslint/ban-ts-ignore // @ts-ignore: this has an implicit any return promise_or_callback_1.promiseOrCallback(fn.apply(this, args), callback); // eslint-disable-line no-invalid-this }; } wrapPromise.wrapPrototype = function (target, options) { if (options === void 0) { options = {}; } var ignoreMethods = options.ignoreMethods || []; var includePrivateMethods = options.transformPrivateMethods === true; var methods = Object.getOwnPropertyNames(target.prototype).filter(function (method) { var isNotPrivateMethod; var isNonConstructorFunction = method !== "constructor" && typeof target.prototype[method] === "function"; var isNotAnIgnoredMethod = ignoreMethods.indexOf(method) === -1; if (includePrivateMethods) { isNotPrivateMethod = true; } else { isNotPrivateMethod = method.charAt(0) !== "_"; } return (isNonConstructorFunction && isNotPrivateMethod && isNotAnIgnoredMethod); }); methods.forEach(function (method) { var original = target.prototype[method]; target.prototype[method] = wrapPromise(original); }); return target; }; module.exports = wrapPromise; },{"./lib/deferred":5,"./lib/once":6,"./lib/promise-or-callback":7}],9:[function(_dereq_,module,exports){ 'use strict'; /** * @this {Promise} */ function finallyConstructor(callback) { var constructor = this.constructor; return this.then( function(value) { // @ts-ignore return constructor.resolve(callback()).then(function() { return value; }); }, function(reason) { // @ts-ignore return constructor.resolve(callback()).then(function() { // @ts-ignore return constructor.reject(reason); }); } ); } function allSettled(arr) { var P = this; return new P(function(resolve, reject) { if (!(arr && typeof arr.length !== 'undefined')) { return reject( new TypeError( typeof arr + ' ' + arr + ' is not iterable(cannot read property Symbol(Symbol.iterator))' ) ); } var args = Array.prototype.slice.call(arr); if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call( val, function(val) { res(i, val); }, function(e) { args[i] = { status: 'rejected', reason: e }; if (--remaining === 0) { resolve(args); } } ); return; } } args[i] = { status: 'fulfilled', value: val }; if (--remaining === 0) { resolve(args); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); } // Store setTimeout reference so promise-polyfill will be unaffected by // other code modifying setTimeout (like sinon.useFakeTimers()) var setTimeoutFunc = setTimeout; function isArray(x) { return Boolean(x && typeof x.length !== 'undefined'); } function noop() {} // Polyfill for Function.prototype.bind function bind(fn, thisArg) { return function() { fn.apply(thisArg, arguments); }; } /** * @constructor * @param {Function} fn */ function Promise(fn) { if (!(this instanceof Promise)) throw new TypeError('Promises must be constructed via new'); if (typeof fn !== 'function') throw new TypeError('not a function'); /** @type {!number} */ this._state = 0; /** @type {!boolean} */ this._handled = false; /** @type {Promise|undefined} */ this._value = undefined; /** @type {!Array<!Function>} */ this._deferreds = []; doResolve(fn, this); } function handle(self, deferred) { while (self._state === 3) { self = self._value; } if (self._state === 0) { self._deferreds.push(deferred); return; } self._handled = true; Promise._immediateFn(function() { var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { (self._state === 1 ? resolve : reject)(deferred.promise, self._value); return; } var ret; try { ret = cb(self._value); } catch (e) { reject(deferred.promise, e); return; } resolve(deferred.promise, ret); }); } function resolve(self, newValue) { try { // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.'); if ( newValue && (typeof newValue === 'object' || typeof newValue === 'function') ) { var then = newValue.then; if (newValue instanceof Promise) { self._state = 3; self._value = newValue; finale(self); return; } else if (typeof then === 'function') { doResolve(bind(then, newValue), self); return; } } self._state = 1; self._value = newValue; finale(self); } catch (e) { reject(self, e); } } function reject(self, newValue) { self._state = 2; self._value = newValue; finale(self); } function finale(self) { if (self._state === 2 && self._deferreds.length === 0) { Promise._immediateFn(function() { if (!self._handled) { Promise._unhandledRejectionFn(self._value); } }); } for (var i = 0, len = self._deferreds.length; i < len; i++) { handle(self, self._deferreds[i]); } self._deferreds = null; } /** * @constructor */ function Handler(onFulfilled, onRejected, promise) { this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.promise = promise; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, self) { var done = false; try { fn( function(value) { if (done) return; done = true; resolve(self, value); }, function(reason) { if (done) return; done = true; reject(self, reason); } ); } catch (ex) { if (done) return; done = true; reject(self, ex); } } Promise.prototype['catch'] = function(onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function(onFulfilled, onRejected) { // @ts-ignore var prom = new this.constructor(noop); handle(this, new Handler(onFulfilled, onRejected, prom)); return prom; }; Promise.prototype['finally'] = finallyConstructor; Promise.all = function(arr) { return new Promise(function(resolve, reject) { if (!isArray(arr)) { return reject(new TypeError('Promise.all accepts an array')); } var args = Array.prototype.slice.call(arr); if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call( val, function(val) { res(i, val); }, reject ); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.allSettled = allSettled; Promise.resolve = function(value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function(resolve) { resolve(value); }); }; Promise.reject = function(value) { return new Promise(function(resolve, reject) { reject(value); }); }; Promise.race = function(arr) { return new Promise(function(resolve, reject) { if (!isArray(arr)) { return reject(new TypeError('Promise.race accepts an array')); } for (var i = 0, len = arr.length; i < len; i++) { Promise.resolve(arr[i]).then(resolve, reject); } }); }; // Use polyfill for setImmediate for performance gains Promise._immediateFn = // @ts-ignore (typeof setImmediate === 'function' && function(fn) { // @ts-ignore setImmediate(fn); }) || function(fn) { setTimeoutFunc(fn, 0); }; Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) { if (typeof console !== 'undefined' && console) { console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console } }; module.exports = Promise; },{}],10:[function(_dereq_,module,exports){ "use strict"; var createAuthorizationData = _dereq_("./create-authorization-data"); var jsonClone = _dereq_("./json-clone"); var constants = _dereq_("./constants"); function addMetadata(configuration, data) { var key; var attrs = data ? jsonClone(data) : {}; var authAttrs = createAuthorizationData(configuration.authorization).attrs; var _meta = jsonClone(configuration.analyticsMetadata); attrs.braintreeLibraryVersion = constants.BRAINTREE_LIBRARY_VERSION; for (key in attrs._meta) { if (attrs._meta.hasOwnProperty(key)) { _meta[key] = attrs._meta[key]; } } attrs._meta = _meta; if (authAttrs.tokenizationKey) { attrs.tokenizationKey = authAttrs.tokenizationKey; } else { attrs.authorizationFingerprint = authAttrs.authorizationFingerprint; } return attrs; } module.exports = addMetadata; },{"./constants":15,"./create-authorization-data":18,"./json-clone":22}],11:[function(_dereq_,module,exports){ "use strict"; var Promise = _dereq_("./promise"); var constants = _dereq_("./constants"); var addMetadata = _dereq_("./add-metadata"); function sendAnalyticsEvent(clientInstanceOrPromise, kind, callback) { var timestamp = Date.now(); // milliseconds return Promise.resolve(clientInstanceOrPromise) .then(function (client) { var timestampInPromise = Date.now(); var configuration = client.getConfiguration(); var request = client._request; var url = configuration.gatewayConfiguration.analytics.url; var data = { analytics: [ { kind: constants.ANALYTICS_PREFIX + kind, isAsync: Math.floor(timestampInPromise / 1000) !== Math.floor(timestamp / 1000), timestamp: timestamp, }, ], }; request( { url: url, method: "post", data: addMetadata(configuration, data), timeout: constants.ANALYTICS_REQUEST_TIMEOUT_MS, }, callback ); }) .catch(function (err) { // for all non-test cases, we don't provide a callback, // so this error will always be swallowed. In this case, // that's fine, it should only error when the deferred // client fails to set up, in which case we don't want // that error to report over and over again via these // deferred analytics events if (callback) { callback(err); } }); } module.exports = { sendEvent: sendAnalyticsEvent, }; },{"./add-metadata":10,"./constants":15,"./promise":25}],12:[function(_dereq_,module,exports){ "use strict"; var loadScript = _dereq_("@braintree/asset-loader/load-script"); module.exports = { loadScript: loadScript, }; },{"@braintree/asset-loader/load-script":3}],13:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("./braintree-error"); var Promise = _dereq_("./promise"); var sharedErrors = _dereq_("./errors"); var VERSION = "3.87.0"; function basicComponentVerification(options) { var client, authorization, name; if (!options) { return Promise.reject( new BraintreeError({ type: sharedErrors.INVALID_USE_OF_INTERNAL_FUNCTION.type, code: sharedErrors.INVALID_USE_OF_INTERNAL_FUNCTION.code, message: "Options must be passed to basicComponentVerification function.", }) ); } name = options.name; client = options.client; authorization = options.authorization; if (!client && !authorization) { return Promise.reject( new BraintreeError({ type: sharedErrors.INSTANTIATION_OPTION_REQUIRED.type, code: sharedErrors.INSTANTIATION_OPTION_REQUIRED.code, // NEXT_MAJOR_VERSION in major version, we expose passing in authorization for all components // instead of passing in a client instance. Leave this a silent feature for now. message: "options.client is required when instantiating " + name + ".", }) ); } if (!authorization && client.getVersion() !== VERSION) { return Promise.reject( new BraintreeError({ type: sharedErrors.INCOMPATIBLE_VERSIONS.type, code: sharedErrors.INCOMPATIBLE_VERSIONS.code, message: "Client (version " + client.getVersion() + ") and " + name + " (version " + VERSION + ") components must be from the same SDK version.", }) ); } return Promise.resolve(); } module.exports = { verify: basicComponentVerification, }; },{"./braintree-error":14,"./errors":21,"./promise":25}],14:[function(_dereq_,module,exports){ "use strict"; var enumerate = _dereq_("./enumerate"); /** * @class * @global * @param {object} options Construction options * @classdesc This class is used to report error conditions, frequently as the first parameter to callbacks throughout the Braintree SDK. * @description <strong>You cannot use this constructor directly. Interact with instances of this class through {@link callback callbacks}.</strong> */ function BraintreeError(options) { if (!BraintreeError.types.hasOwnProperty(options.type)) { throw new Error(options.type + " is not a valid type."); } if (!options.code) { throw new Error("Error code required."); } if (!options.message) { throw new Error("Error message required."); } this.name = "BraintreeError"; /** * @type {string} * @description A code that corresponds to specific errors. */ this.code = options.code; /** * @type {string} * @description A short description of the error. */ this.message = options.message; /** * @type {BraintreeError.types} * @description The type of error. */ this.type = options.type; /** * @type {object=} * @description Additional information about the error, such as an underlying network error response. */ this.details = options.details; } BraintreeError.prototype = Object.create(Error.prototype); BraintreeError.prototype.constructor = BraintreeError; /** * Enum for {@link BraintreeError} types. * @name BraintreeError.types * @enum * @readonly * @memberof BraintreeError * @property {string} CUSTOMER An error caused by the customer. * @property {string} MERCHANT An error that is actionable by the merchant. * @property {string} NETWORK An error due to a network problem. * @property {string} INTERNAL An error caused by Braintree code. * @property {string} UNKNOWN An error where the origin is unknown. */ BraintreeError.types = enumerate([ "CUSTOMER", "MERCHANT", "NETWORK", "INTERNAL", "UNKNOWN", ]); BraintreeError.findRootError = function (err) { if ( err instanceof BraintreeError && err.details && err.details.originalError ) { return BraintreeError.findRootError(err.details.originalError); } return err; }; module.exports = BraintreeError; },{"./enumerate":20}],15:[function(_dereq_,module,exports){ "use strict"; var VERSION = "3.87.0"; var PLATFORM = "web"; var CLIENT_API_URLS = { production: "https://api.braintreegateway.com:443", sandbox: "https://api.sandbox.braintreegateway.com:443", }; var ASSETS_URLS = { production: "https://assets.braintreegateway.com", sandbox: "https://assets.braintreegateway.com", }; var GRAPHQL_URLS = { production: "https://payments.braintree-api.com/graphql", sandbox: "https://payments.sandbox.braintree-api.com/graphql", }; // endRemoveIf(production) module.exports = { ANALYTICS_PREFIX: PLATFORM + ".", ANALYTICS_REQUEST_TIMEOUT_MS: 2000, ASSETS_URLS: ASSETS_URLS, CLIENT_API_URLS: CLIENT_API_URLS, FRAUDNET_SOURCE: "BRAINTREE_SIGNIN", FRAUDNET_FNCLS: "fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99", FRAUDNET_URL: "https://c.paypal.com/da/r/fb.js", BUS_CONFIGURATION_REQUEST_EVENT: "BUS_CONFIGURATION_REQUEST", GRAPHQL_URLS: GRAPHQL_URLS, INTEGRATION_TIMEOUT_MS: 60000, VERSION: VERSION, INTEGRATION: "custom", SOURCE: "client", PLATFORM: PLATFORM, BRAINTREE_LIBRARY_VERSION: "braintree/" + PLATFORM + "/" + VERSION, }; },{}],16:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("./braintree-error"); var sharedErrors = _dereq_("./errors"); module.exports = function (instance, methodNames) { methodNames.forEach(function (methodName) { instance[methodName] = function () { throw new BraintreeError({ type: sharedErrors.METHOD_CALLED_AFTER_TEARDOWN.type, code: sharedErrors.METHOD_CALLED_AFTER_TEARDOWN.code, message: methodName + " cannot be called after teardown.", }); }; }); }; },{"./braintree-error":14,"./errors":21}],17:[function(_dereq_,module,exports){ "use strict"; // endRemoveIf(production) var ASSETS_URLS = _dereq_("./constants").ASSETS_URLS; function createAssetsUrl(authorization) { // endRemoveIf(production) return ASSETS_URLS.production; } /* eslint-enable */ module.exports = { create: createAssetsUrl, }; },{"./constants":15}],18:[function(_dereq_,module,exports){ "use strict"; var atob = _dereq_("../lib/vendor/polyfill").atob; var CLIENT_API_URLS = _dereq_("../lib/constants").CLIENT_API_URLS; function _isTokenizationKey(str) { return /^[a-zA-Z0-9]+_[a-zA-Z0-9]+_[a-zA-Z0-9_]+$/.test(str); } function _parseTokenizationKey(tokenizationKey) { var tokens = tokenizationKey.split("_"); var environment = tokens[0]; var merchantId = tokens.slice(2).join("_"); return { merchantId: merchantId, environment: environment, }; } function createAuthorizationData(authorization) { var parsedClientToken, parsedTokenizationKey; var data = { attrs: {}, configUrl: "", }; if (_isTokenizationKey(authorization)) { parsedTokenizationKey = _parseTokenizationKey(authorization); data.environment = parsedTokenizationKey.environment; data.attrs.tokenizationKey = authorization; data.configUrl = CLIENT_API_URLS[parsedTokenizationKey.environment] + "/merchants/" + parsedTokenizationKey.merchantId + "/client_api/v1/configuration"; } else { parsedClientToken = JSON.parse(atob(authorization)); data.environment = parsedClientToken.environment; data.attrs.authorizationFingerprint = parsedClientToken.authorizationFingerprint; data.configUrl = parsedClientToken.configUrl; data.graphQL = parsedClientToken.graphQL; } return data; } module.exports = createAuthorizationData; },{"../lib/constants":15,"../lib/vendor/polyfill":26}],19:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("./braintree-error"); var Promise = _dereq_("./promise"); var assets = _dereq_("./assets"); var sharedErrors = _dereq_("./errors"); var VERSION = "3.87.0"; function createDeferredClient(options) { var promise = Promise.resolve(); if (options.client) { return Promise.resolve(options.client); } if (!(window.braintree && window.braintree.client)) { promise = assets .loadScript({ src: options.assetsUrl + "/web/" + VERSION + "/js/client.min.js", }) .catch(function (err) { return Promise.reject( new BraintreeError({ type: sharedErrors.CLIENT_SCRIPT_FAILED_TO_LOAD.type, code: sharedErrors.CLIENT_SCRIPT_FAILED_TO_LOAD.code, message: sharedErrors.CLIENT_SCRIPT_FAILED_TO_LOAD.message, details: { originalError: err, }, }) ); }); } return promise.then(function () { if (window.braintree.client.VERSION !== VERSION) { return Promise.reject( new BraintreeError({ type: sharedErrors.INCOMPATIBLE_VERSIONS.type, code: sharedErrors.INCOMPATIBLE_VERSIONS.code, message: "Client (version " + window.braintree.client.VERSION + ") and " + options.name + " (version " + VERSION + ") components must be from the same SDK version.", }) ); } return window.braintree.client.create({ authorization: options.authorization, debug: options.debug, }); }); } module.exports = { create: createDeferredClient, }; },{"./assets":12,"./braintree-error":14,"./errors":21,"./promise":25}],20:[function(_dereq_,module,exports){ "use strict"; function enumerate(values, prefix) { prefix = prefix == null ? "" : prefix; return values.reduce(function (enumeration, value) { enumeration[value] = prefix + value; return enumeration; }, {}); } module.exports = enumerate; },{}],21:[function(_dereq_,module,exports){ "use strict"; /** * @name BraintreeError.Shared Internal Error Codes * @ignore * @description These codes should never be experienced by the merchant directly. * @property {INTERNAL} INVALID_USE_OF_INTERNAL_FUNCTION Occurs when the client is created without a gateway configuration. Should never happen. */ /** * @name BraintreeError.Shared Errors - Component Creation Error Codes * @description Errors that occur when creating components. * @property {MERCHANT} INSTANTIATION_OPTION_REQUIRED Occurs when a component is created that is missing a required option. * @property {MERCHANT} INCOMPATIBLE_VERSIONS Occurs when a component is created with a client with a different version than the component. * @property {NETWORK} CLIENT_SCRIPT_FAILED_TO_LOAD Occurs when a component attempts to load the Braintree client script, but the request fails. */ /** * @name BraintreeError.Shared Errors - Component Instance Error Codes * @description Errors that occur when using instances of components. * @property {MERCHANT} METHOD_CALLED_AFTER_TEARDOWN Occurs when a method is called on a component instance after it has been torn down. */ var BraintreeError = _dereq_("./braintree-error"); module.exports = { INVALID_USE_OF_INTERNAL_FUNCTION: { type: BraintreeError.types.INTERNAL, code: "INVALID_USE_OF_INTERNAL_FUNCTION", }, INSTANTIATION_OPTION_REQUIRED: { type: BraintreeError.types.MERCHANT, code: "INSTANTIATION_OPTION_REQUIRED", }, INCOMPATIBLE_VERSIONS: { type: BraintreeError.types.MERCHANT, code: "INCOMPATIBLE_VERSIONS", }, CLIENT_SCRIPT_FAILED_TO_LOAD: { type: BraintreeError.types.NETWORK, code: "CLIENT_SCRIPT_FAILED_TO_LOAD", message: "Braintree client script could not be loaded.", }, METHOD_CALLED_AFTER_TEARDOWN: { type: BraintreeError.types.MERCHANT, code: "METHOD_CALLED_AFTER_TEARDOWN", }, }; },{"./braintree-error":14}],22:[function(_dereq_,module,exports){ "use strict"; module.exports = function (value) { return JSON.parse(JSON.stringify(value)); }; },{}],23:[function(_dereq_,module,exports){ "use strict"; module.exports = function (obj) { return Object.keys(obj).filter(function (key) { return typeof obj[key] === "function"; }); }; },{}],24:[function(_dereq_,module,exports){ "use strict"; function once(fn) { var called = false; return function () { if (!called) { called = true; fn.apply(null, arguments); } }; } module.exports = once; },{}],25:[function(_dereq_,module,exports){ "use strict"; var PromisePolyfill = _dereq_("promise-polyfill"); var ExtendedPromise = _dereq_("@braintree/extended-promise"); // eslint-disable-next-line no-undef var PromiseGlobal = typeof Promise !== "undefined" ? Promise : PromisePolyfill; ExtendedPromise.suppressUnhandledPromiseMessage = true; ExtendedPromise.setPromise(PromiseGlobal); module.exports = PromiseGlobal; },{"@braintree/extended-promise":4,"promise-polyfill":9}],26:[function(_dereq_,module,exports){ "use strict"; // NEXT_MAJOR_VERSION old versions of IE don't have atob, in the // next major version, we're dropping support for those versions // so we can eliminate the need to have this atob polyfill var atobNormalized = typeof atob === "function" ? atob : atobPolyfill; function atobPolyfill(base64String) { var a, b, c, b1, b2, b3, b4, i; var base64Matcher = new RegExp( "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})([=]{1,2})?$" ); var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var result = ""; if (!base64Matcher.test(base64String)) { throw new Error("Non base64 encoded input passed to window.atob polyfill"); } i = 0; do { b1 = characters.indexOf(base64String.charAt(i++)); b2 = characters.indexOf(base64String.charAt(i++)); b3 = characters.indexOf(base64String.charAt(i++)); b4 = characters.indexOf(base64String.charAt(i++)); a = ((b1 & 0x3f) << 2) | ((b2 >> 4) & 0x3); b = ((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf); c = ((b3 & 0x3) << 6) | (b4 & 0x3f); result += String.fromCharCode(a) + (b ? String.fromCharCode(b) : "") + (c ? String.fromCharCode(c) : ""); } while (i < base64String.length); return result; } module.exports = { atob: function (base64String) { return atobNormalized.call(window, base64String); }, _atob: atobPolyfill, }; },{}],27:[function(_dereq_,module,exports){ "use strict"; module.exports = { PLAID_LINK_JS: "https://cdn.plaid.com/link/v2/stable/link-initialize.js", }; },{}],28:[function(_dereq_,module,exports){ "use strict"; /** * @name BraintreeError.Us Bank Account - Creation Error Codes * @description Errors that occur when [creating the Us Bank Account component](./module-braintree-web_us-bank-account.html#.create). * @property {MERCHANT} US_BANK_ACCOUNT_NOT_ENABLED Occurs when US Bank Account is not enabled in the Braintree control panel. */ /** * @name BraintreeError.Us Bank Account - tokenize Error Codes * @description Errors that occur when using the [`tokenize` method](./UsBankAccount.html#tokenize). * @property {MERCHANT} US_BANK_ACCOUNT_OPTION_REQUIRED Occurs when a required option is not passed. * @property {MERCHANT} US_BANK_ACCOUNT_MUTUALLY_EXCLUSIVE_OPTIONS Occurs when 1 or more incompatible options are passed. * @property {NETWORK} US_BANK_ACCOUNT_LOGIN_LOAD_FAILED Occurs when bank login flow fails. * @property {CUSTOMER} US_BANK_ACCOUNT_LOGIN_CLOSED Occurs when bank login window is closed. * @property {MERCHANT} US_BANK_ACCOUNT_LOGIN_REQUEST_ACTIVE Occurs when a bank login flow is already active. * @property {NETWORK} US_BANK_ACCOUNT_TOKENIZATION_NETWORK_ERROR Occurs when payment details could not be tokenized. * @property {CUSTOMER} US_BANK_ACCOUNT_FAILED_TOKENIZATION Occurs when payment details failed to be tokenized. * @property {MERCHANT} US_BANK_ACCOUNT_BANK_LOGIN_NOT_ENABLED Occurs when bank login flow is not enabled in the Braintree control panel. */ var BraintreeError = _dereq_("../lib/braintree-error"); module.exports = { US_BANK_ACCOUNT_OPTION_REQUIRED: { type: BraintreeError.types.MERCHANT, code: "US_BANK_ACCOUNT_OPTION_REQUIRED", }, US_BANK_ACCOUNT_MUTUALLY_EXCLUSIVE_OPTIONS: { type: BraintreeError.types.MERCHANT, code: "US_BANK_ACCOUNT_MUTUALLY_EXCLUSIVE_OPTIONS", }, US_BANK_ACCOUNT_LOGIN_LOAD_FAILED: { type: BraintreeError.types.NETWORK, code: "US_BANK_ACCOUNT_LOGIN_LOAD_FAILED", message: "Bank login flow failed to load.", }, US_BANK_ACCOUNT_LOGIN_CLOSED: { type: BraintreeError.types.CUSTOMER, code: "US_BANK_ACCOUNT_LOGIN_CLOSED", message: "Customer closed bank login flow before authorizing.", }, US_BANK_ACCOUNT_LOGIN_REQUEST_ACTIVE: { type: BraintreeError.types.MERCHANT, code: "US_BANK_ACCOUNT_LOGIN_REQUEST_ACTIVE", message: "Another bank login tokenization request is active.", }, US_BANK_ACCOUNT_TOKENIZATION_NETWORK_ERROR: { type: BraintreeError.types.NETWORK, code: "US_BANK_ACCOUNT_TOKENIZATION_NETWORK_ERROR", message: "A tokenization network error occurred.", }, US_BANK_ACCOUNT_FAILED_TOKENIZATION: { type: BraintreeError.types.CUSTOMER, code: "US_BANK_ACCOUNT_FAILED_TOKENIZATION", message: "The supplied data failed tokenization.", }, US_BANK_ACCOUNT_NOT_ENABLED: { type: BraintreeError.types.MERCHANT, code: "US_BANK_ACCOUNT_NOT_ENABLED", message: "US bank account is not enabled.", }, US_BANK_ACCOUNT_BANK_LOGIN_NOT_ENABLED: { type: BraintreeError.types.MERCHANT, code: "US_BANK_ACCOUNT_BANK_LOGIN_NOT_ENABLED", message: "Bank login is not enabled.", }, }; },{"../lib/braintree-error":14}],29:[function(_dereq_,module,exports){ "use strict"; /** * @module braintree-web/us-bank-account * @description This module is for accepting payments of US bank accounts. */ var basicComponentVerification = _dereq_("../lib/basic-component-verification"); var BraintreeError = _dereq_("../lib/braintree-error"); var createDeferredClient = _dereq_("../lib/create-deferred-client"); var createAssetsUrl = _dereq_("../lib/create-assets-url"); var errors = _dereq_("./errors"); var USBankAccount = _dereq_("./us-bank-account"); var VERSION = "3.87.0"; var Promise = _dereq_("../lib/promise"); var wrapPromise = _dereq_("@braintree/wrap-promise"); /** * @static * @function create * @param {object} options Creation options: * @param {Client} [options.client] A {@link Client} instance. * @param {string} [options.authorization] A tokenizationKey or clientToken. Can be used in place of `options.client`. * @param {callback} [callback] The second argument, `data`, is the {@link USBankAccount} instance. If no callback is provided, `create` returns a promise that resolves with the {@link USBankAccount} instance. * @returns {(Promise|void)} Returns a promise if no callback is provided. */ function create(options) { var name = "US Bank Account"; return basicComponentVerification .verify({ name: name, client: options.client, authorization: options.authorization, }) .then(function () { return createDeferredClient.create({ authorization: options.authorization, client: options.client, debug: options.debug, assetsUrl: createAssetsUrl.create(options.authorization), name: name, }); }) .then(function (client) { var usBankAccount; options.client = client; usBankAccount = options.client.getConfiguration().gatewayConfiguration.usBankAccount; if (!usBankAccount) { return Promise.reject( new BraintreeError(errors.US_BANK_ACCOUNT_NOT_ENABLED) ); } return new USBankAccount(options); }); } module.exports = { create: wrapPromise(create), /** * @description The current version of the SDK, i.e. `{@pkg version}`. * @type {string} */ VERSION: VERSION, }; },{"../lib/basic-component-verification":13,"../lib/braintree-error":14,"../lib/create-assets-url":17,"../lib/create-deferred-client":19,"../lib/promise":25,"./errors":28,"./us-bank-account":30,"@braintree/wrap-promise":8}],30:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("../lib/braintree-error"); var constants = _dereq_("./constants"); var errors = _dereq_("./errors"); var sharedErrors = _dereq_("../lib/errors"); var analytics = _dereq_("../lib/analytics"); var once = _dereq_("../lib/once"); var convertMethodsToError = _dereq_("../lib/convert-methods-to-error"); var methods = _dereq_("../lib/methods"); var Promise = _dereq_("../lib/promise"); var wrapPromise = _dereq_("@braintree/wrap-promise"); var TOKENIZE_BANK_DETAILS_MUTATION = createGraphQLMutation("UsBankAccount"); var TOKENIZE_BANK_LOGIN_MUTATION = createGraphQLMutation("UsBankLogin"); /** * @typedef {object} USBankAccount~tokenizePayload * @property {string} nonce The payment method nonce. * @property {string} type The payment method type, always `us_bank_account`. * @property {object} details Additional account details. Currently empty. */ /** * @class * @param {object} options See {@link module:braintree-web/us-bank-account.create|us-bank-account.create}. * @classdesc This class represents a US Bank Account component. Instances of this class can tokenize raw bank details or present a bank login. <strong>You cannot use this constructor directly. Use {@link module:braintree-web/us-bank-account.create|braintree.us-bank-account.create} instead.</strong> */ function USBankAccount(options) { this._client = options.client; this._isTokenizingBankLogin = false; analytics.sendEvent(this._client, "usbankaccount.initialized"); } /** * Tokenizes bank information to return a payment method nonce. You can tokenize bank details by providing information like account and routing numbers. You can also tokenize with a bank login UI that prompts the customer to log into their bank account. * @public * @param {object} options All tokenization options for the US Bank Account component. * @param {string} options.mandateText A string for proof of customer authorization. For example, `'I authorize Braintree to debit my bank account on behalf of My Online Store.'`. * @param {object} [options.bankDetails] Bank detail information (such as account and routing numbers). `bankDetails` or `bankLogin` option must be provided. * @param {string} options.bankDetails.routingNumber The customer's bank routing number, such as `'307075259'`. * @param {string} options.bankDetails.accountNumber The customer's bank account number, such as `'999999999'`. * @param {string} options.bankDetails.accountType The customer's bank account type. Must be `'checking'` or `'savings'`. * @param {string} options.bankDetails.ownershipType The customer's bank account ownership type. Must be `'personal'` or `'business'`. * @param {string} [options.bankDetails.firstName] The customer's first name. Required when account ownership type is `personal`. * @param {string} [options.bankDetails.lastName] The customer's last name. Required when account ownership type is `personal`. * @param {string} [options.bankDetails.businessName] The customer's business name. Required when account ownership type is `business`. * @param {object} options.bankDetails.billingAddress The customer's billing address. * @param {string} options.bankDetails.billingAddress.streetAddress The street address for the customer's billing address, such as `'123 Fake St'`. * @param {string} [options.bankDetails.billingAddress.extendedAddress] The extended street address for the customer's billing address, such as `'Apartment B'`. * @param {string} options.bankDetails.billingAddress.locality The locality for the customer's billing address. This is typically a city, such as `'San Francisco'`. * @param {string} options.bankDetails.billingAddress.region The region for the customer's billing address. This is typically a state, such as `'CA'`. * @param {string} options.bankDetails.billingAddress.postalCode The postal code for the customer's billing address. This is typically a ZIP code, such as `'94119'`. * @param {object} [options.bankLogin] Bank login information. `bankLogin` or `bankDetails` option must be provided. * @param {string} options.bankLogin.displayName Display name for the bank login UI, such as `'My Store'`. * @param {string} options.bankLogin.ownershipType The customer's bank account ownership type. Must be `'personal'` or `'business'`. * @param {string} [options.bankLogin.firstName] The customer's first name. Required when account ownership type is `personal`. * @param {string} [options.bankLogin.lastName] The customer's last name. Required when account ownership type is `personal`. * @param {string} [options.bankLogin.businessName] The customer's business name. Required when account ownership type is `business`. * @param {object} options.bankLogin.billingAddress The customer's billing address. * @param {string} options.bankLogin.billingAddress.streetAddress The street address for the customer's billing address, such as `'123 Fake St'`. * @param {string} [options.bankLogin.billingAddress.extendedAddress] The extended street address for the customer's billing address, such as `'Apartment B'`. * @param {string} options.bankLogin.billingAddress.locality The locality for the customer's billing address. This is typically a city, such as `'San Francisco'`. * @param {string} options.bankLogin.billingAddress.region The region for the customer's billing address. This is typically a state, such as `'CA'`. * @param {string} options.bankLogin.billingAddress.postalCode The postal code for the customer's billing address. This is typically a ZIP code, such as `'94119'`. * @param {callback} [callback] The second argument, <code>data</code>, is a {@link USBankAccount~tokenizePayload|tokenizePayload}. If no callback is provided, `tokenize` returns a promise that resolves with {@link USBankAccount~tokenizePayload|tokenizePayload}. * @returns {(Promise|void)} Returns a promise if no callback is provided. * @example * <caption>Tokenizing raw bank details</caption> * var routingNumberInput = document.querySelector('input[name="routing-number"]'); * var accountNumberInput = document.querySelector('input[name="account-number"]'); * var accountTypeInput = document.querySelector('input[name="account-type"]:checked'); * var ownershipTypeInput = document.querySelector('input[name="ownership-type"]:checked'); * var firstNameInput = document.querySelector('input[name="first-name"]'); * var lastNameInput = document.querySelector('input[name="last-name"]'); * var businessNameInput = document.querySelector('input[name="business-name"]'); * var billingAddressStreetInput = document.querySelector('input[name="street-address"]'); * var billingAddressExtendedInput = document.querySelector('input[name="extended-address"]'); * var billingAddressLocalityInput = document.querySelector('input[name="locality"]'); * var billingAddressRegionSelect = document.querySelector('select[name="region"]'); * var billingAddressPostalInput = document.querySelector('input[name="postal-code"]'); * * submitButton.addEventListener('click', function (event) { * var bankDetails = { * routingNumber: routingNumberInput.value, * accountNumber: accountNumberInput.value, * accountType: accountTypeInput.value, * ownershipType: ownershipTypeInput.value, * billingAddress: { * streetAddress: billingAddressStreetInput.value, * extendedAddress: billingAddressExtendedInput.value, * locality: billingAddressLocalityInput.value, * region: billingAddressRegionSelect.value, * postalCode: billingAddressPostalInput.value * } * }; * * if (bankDetails.ownershipType === 'personal') { * bankDetails.firstName = firstNameInput.value; * bankDetails.lastName = lastNameInput.value; * } else { * bankDetails.businessName = businessNameInput.value; * } * * event.prev