UNPKG

braintree-web

Version:

A suite of tools for integrating Braintree in the browser

1,516 lines (1,334 loc) 47.5 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 = {})).vaultManager = 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":24}],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":24}],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":25}],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":24}],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"; 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}],25:[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, }; },{}],26:[function(_dereq_,module,exports){ "use strict"; /** * @name BraintreeError.Vault Manager - deletePaymentMethod Error Codes * @description Errors that occur when using the [`deletePaymentMethod` method](./VaultManager.html#deletePaymentMethod). * @property {MERCHANT} VAULT_MANAGER_DELETE_PAYMENT_METHOD_NONCE_REQUIRES_CLIENT_TOKEN Occurs when vault manager is initialized with a tokenization key instead of a Client Token. * @property {MERCHANT} VAULT_MANAGER_PAYMENT_METHOD_NONCE_NOT_FOUND Occurs when the specified payment method can not be found. * @property {UNKNOWN} VAULT_MANAGER_DELETE_PAYMENT_METHOD_UNKNOWN_ERROR Occurs when there is an error attempting to delete the payment method. */ var BraintreeError = _dereq_("../lib/braintree-error"); module.exports = { VAULT_MANAGER_DELETE_PAYMENT_METHOD_NONCE_REQUIRES_CLIENT_TOKEN: { type: BraintreeError.types.MERCHANT, code: "VAULT_MANAGER_DELETE_PAYMENT_METHOD_NONCE_REQUIRES_CLIENT_TOKEN", message: "A client token with a customer id must be used to delete a payment method nonce.", }, VAULT_MANAGER_PAYMENT_METHOD_NONCE_NOT_FOUND: { type: BraintreeError.types.MERCHANT, code: "VAULT_MANAGER_PAYMENT_METHOD_NONCE_NOT_FOUND", }, VAULT_MANAGER_DELETE_PAYMENT_METHOD_UNKNOWN_ERROR: { type: BraintreeError.types.UNKNOWN, code: "VAULT_MANAGER_DELETE_PAYMENT_METHOD_UNKNOWN_ERROR", }, }; },{"../lib/braintree-error":14}],27:[function(_dereq_,module,exports){ "use strict"; /** * @module braintree-web/vault-manager * @description Manages customer's payment methods. */ var basicComponentVerification = _dereq_("../lib/basic-component-verification"); var createDeferredClient = _dereq_("../lib/create-deferred-client"); var createAssetsUrl = _dereq_("../lib/create-assets-url"); var VaultManager = _dereq_("./vault-manager"); var VERSION = "3.87.0"; 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 VaultManager} instance. * @returns {void} */ function create(options) { var name = "Vault Manager"; return basicComponentVerification .verify({ name: name, client: options.client, authorization: options.authorization, }) .then(function () { return new VaultManager({ createPromise: createDeferredClient.create({ authorization: options.authorization, client: options.client, debug: options.debug, assetsUrl: createAssetsUrl.create(options.authorization), name: name, }), }); }); } 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/create-assets-url":17,"../lib/create-deferred-client":19,"./vault-manager":28,"@braintree/wrap-promise":8}],28:[function(_dereq_,module,exports){ "use strict"; var analytics = _dereq_("../lib/analytics"); var BraintreeError = _dereq_("../lib/braintree-error"); var errors = _dereq_("./errors"); 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 DELETE_PAYMENT_METHOD_MUTATION = "mutation DeletePaymentMethodFromSingleUseToken($input: DeletePaymentMethodFromSingleUseTokenInput!) {" + " deletePaymentMethodFromSingleUseToken(input: $input) {" + " clientMutationId" + " }" + "}"; /** * @typedef {array} VaultManager~fetchPaymentMethodsPayload The customer's payment methods. * @property {object} paymentMethod The payment method object. * @property {string} paymentMethod.nonce A nonce that can be sent to your server to transact on the payment method. * @property {boolean} paymentMethod.default Whether or not this is the default payment method for the customer. * @property {object} paymentMethod.details Any additional details about the payment method. Varies depending on the type of payment method. * @property {string} paymentMethod.type A constant indicating the type of payment method. * @property {?string} paymentMethod.description Additional description about the payment method. * @property {?object} paymentMethod.binData Bin data about the payment method. * */ /** * @class * @param {object} options Options * @description <strong>You cannot use this constructor directly. Use {@link module:braintree-web/vault-manager.create|braintree.vault-manager.create} instead.</strong> * @classdesc This class allows you to manage a customer's payment methods on the client. */ function VaultManager(options) { this._createPromise = options.createPromise; } /** * Fetches payment methods owned by the customer whose id was used to generate the client token used to create the {@link module:braintree-web/client|client}. * @public * @param {object} [options] Options for fetching payment methods. * @param {boolean} [options.defaultFirst = false] If `true`, the payment methods will be returned with the default payment method for the customer first. Otherwise, order is not guaranteed. * @param {callback} [callback] The second argument is a {@link VaultManager~fetchPaymentMethodsPayload|fetchPaymentMethodsPayload}. This is also what is resolved by the promise if no callback is provided. * @returns {(Promise|void)} Returns a promise if no callback is provided. * @example * vaultManagerInstance.fetchPaymentMethods(function (err, paymentMethods) { * paymentMethods.forEach(function (paymentMethod) { * // add payment method to UI * // paymentMethod.nonce <- transactable nonce associated with payment method * // paymentMethod.details <- object with additional information about payment method * // paymentMethod.type <- a constant signifying the type * }); * }); */ VaultManager.prototype.fetchPaymentMethods = function (options) { var defaultFirst; options = options || {}; defaultFirst = options.defaultFirst === true ? 1 : 0; return this._createPromise .then(function (client) { return client.request({ endpoint: "payment_methods", method: "get", data: { defaultFirst: defaultFirst, }, }); }) .then( function (paymentMethodsPayload) { analytics.sendEvent( this._createPromise, "vault-manager.fetch-payment-methods.succeeded" ); return paymentMethodsPayload.paymentMethods.map( formatPaymentMethodPayload ); }.bind(this) ); }; // TODO hide from jsdoc for now until the GraphQL API is on for all merchants by default /** * Deletes a payment method owned by the customer whose id was used to generate the client token used to create the {@link module:braintree-web/client|client}. * @public * @ignore * @param {string} paymentMethodNonce The payment method nonce that references a vaulted payment method. * @param {callback} [callback] No data is returned if the operation is successful. * @returns {(Promise|void)} Returns a promise if no callback is provided. * @example * vaultManagerInstance.deletePaymentMethod('nonce-to-delete', function (err) { * // handle err if it exists * }); */ VaultManager.prototype.deletePaymentMethod = function (paymentMethodNonce) { return this._createPromise.then(function (client) { var usesClientToken = client.getConfiguration().authorizationType === "CLIENT_TOKEN"; if (!usesClientToken) { return Promise.reject( new BraintreeError( errors.VAULT_MANAGER_DELETE_PAYMENT_METHOD_NONCE_REQUIRES_CLIENT_TOKEN ) ); } return client .request({ api: "graphQLApi", data: { query: DELETE_PAYMENT_METHOD_MUTATION, variables: { input: { singleUseTokenId: paymentMethodNonce, }, }, operationName: "DeletePaymentMethodFromSingleUseToken", }, }) .then(function () { analytics.sendEvent( client, "vault-manager.delete-payment-method.succeeded" ); // noop to prevent sending back the raw graphql data }) .catch(function (error) { var originalError = error.details.originalError; var formattedError; analytics.sendEvent( client, "vault-manager.delete-payment-method.failed" ); if ( originalError[0] && originalError[0].extensions.errorClass === "NOT_FOUND" ) { formattedError = new BraintreeError({ type: errors.VAULT_MANAGER_PAYMENT_METHOD_NONCE_NOT_FOUND.type, code: errors.VAULT_MANAGER_PAYMENT_METHOD_NONCE_NOT_FOUND.code, message: "A payment method for payment method nonce `" + paymentMethodNonce + "` could not be found.", details: { originalError: originalError, }, }); } if (!formattedError) { formattedError = new BraintreeError({ type: errors.VAULT_MANAGER_DELETE_PAYMENT_METHOD_UNKNOWN_ERROR.type, code: errors.VAULT_MANAGER_DELETE_PAYMENT_METHOD_UNKNOWN_ERROR.code, message: "An unknown error occured when attempting to delete the payment method assocaited with the payment method nonce `" + paymentMethodNonce + "`.", details: { originalError: originalError, }, }); } return Promise.reject(formattedError); }); }); }; function formatPaymentMethodPayload(paymentMethod) { var formattedPaymentMethod = { nonce: paymentMethod.nonce, default: paymentMethod.default, details: paymentMethod.details, hasSubscription: paymentMethod.hasSubscription, type: paymentMethod.type, }; if (paymentMethod.description) { formattedPaymentMethod.description = paymentMethod.description; } if (paymentMethod.binData) { formattedPaymentMethod.binData = paymentMethod.binData; } return formattedPaymentMethod; } /** * Cleanly tear down anything set up by {@link module:braintree-web/vault-manager.create|create}. * @public * @param {callback} [callback] Called once teardown is complete. No data is returned if teardown completes successfully. * @example * vaultManagerInstance.teardown(); * @example <caption>With callback</caption> * vaultManagerInstance.teardown(function () { * // teardown is complete * }); * @returns {(Promise|void)} Returns a promise if no callback is provided. */ VaultManager.prototype.teardown = function () { convertMethodsToError(this, methods(VaultManager.prototype)); return Promise.resolve(); }; module.exports = wrapPromise.wrapPrototype(VaultManager); },{"../lib/analytics":11,"../lib/braintree-error":14,"../lib/convert-methods-to-error":16,"../lib/methods":23,"../lib/promise":24,"./errors":26,"@braintree/wrap-promise":8}]},{},[27])(27) });