UNPKG

braintree-web

Version:

A suite of tools for integrating Braintree in the browser

1,311 lines (1,197 loc) 63.3 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 = {})).applePay = 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 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.type) { script.setAttribute("type", "".concat(options.type)); } if (options.crossorigin) { script.setAttribute("crossorigin", "".concat(options.crossorigin)); } Object.keys(attrs).forEach(function (key) { script.setAttribute("data-".concat(key), "".concat(attrs[key])); }); scriptLoadPromise = new Promise(function (resolve, reject) { script.addEventListener("load", function () { resolve(script); }); script.addEventListener("error", function () { reject(new Error("".concat(options.src, " failed to load."))); }); script.addEventListener("abort", function () { reject(new Error("".concat(options.src, " has aborted."))); }); container.appendChild(script); }); scriptPromiseCache[stringifiedOptions] = scriptLoadPromise; return scriptLoadPromise; } loadScript.clearCache = function () { scriptPromiseCache = {}; }; module.exports = loadScript; },{}],2:[function(_dereq_,module,exports){ module.exports = _dereq_("./dist/load-script"); },{"./dist/load-script":1}],3:[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; },{}],4:[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; },{}],5:[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; },{}],6:[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":3,"./lib/once":4,"./lib/promise-or-callback":5}],7:[function(_dereq_,module,exports){ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.loadAxo = {})); })(this, (function (exports) { 'use strict'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ function __awaiter(thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } var dist = {}; var scriptPromiseCache = {}; function loadScript$1(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.type) { script.setAttribute("type", "".concat(options.type)); } if (options.crossorigin) { script.setAttribute("crossorigin", "".concat(options.crossorigin)); } Object.keys(attrs).forEach(function (key) { script.setAttribute("data-".concat(key), "".concat(attrs[key])); }); scriptLoadPromise = new Promise(function (resolve, reject) { script.addEventListener("load", function () { resolve(script); }); script.addEventListener("error", function () { reject(new Error("".concat(options.src, " failed to load."))); }); script.addEventListener("abort", function () { reject(new Error("".concat(options.src, " has aborted."))); }); container.appendChild(script); }); scriptPromiseCache[stringifiedOptions] = scriptLoadPromise; return scriptLoadPromise; } loadScript$1.clearCache = function () { scriptPromiseCache = {}; }; var loadScript_1$1 = loadScript$1; var loadStylesheet$1 = function loadStylesheet(options) { var stylesheet = document.querySelector("link[href=\"".concat(options.href, "\"]")); if (stylesheet) { return Promise.resolve(stylesheet); } stylesheet = document.createElement("link"); var container = options.container || document.head; stylesheet.setAttribute("rel", "stylesheet"); stylesheet.setAttribute("type", "text/css"); stylesheet.setAttribute("href", options.href); stylesheet.setAttribute("id", options.id); if (container.firstChild) { container.insertBefore(stylesheet, container.firstChild); } else { container.appendChild(stylesheet); } return Promise.resolve(stylesheet); }; Object.defineProperty(dist, "__esModule", { value: true }); dist.loadStylesheet = loadScript_1 = dist.loadScript = void 0; var loadScript = loadScript_1$1; var loadScript_1 = dist.loadScript = loadScript; var loadStylesheet = loadStylesheet$1; dist.loadStylesheet = loadStylesheet; var CDNX_PROD = "https://www.paypalobjects.com"; var ASSET_NAME = { minified: "axo.min", unminified: "axo", }; var FL_NAMESPACE = "fastlane"; var ASSET_PATH = "connect-boba"; var LOCALE_PATH = "".concat(ASSET_PATH, "/locales/"); var constants = { AXO_ASSET_NAME: ASSET_NAME, AXO_ASSET_PATH: ASSET_PATH, LOCALE_PATH: LOCALE_PATH, CDNX_PROD: CDNX_PROD, }; var AxoSupportedPlatforms = { BT: "BT", PPCP: "PPCP", }; /** * Checks if the current environment is an AMD environment. * * @returns {boolean} True if the environment is AMD, false otherwise. */ function isAmdEnv() { return typeof window.define === "function" && !!window.define.amd; } /** * Checks if the current environment is a RequireJS environment. * * @returns {boolean} True if the environment is RequireJS, false otherwise. */ function isRequireJsEnv() { return (isAmdEnv() && typeof window.requirejs === "function" && typeof window.requirejs.config === "function"); } /** * Safely loads BT modules by checking if the module already exists and verifying if versions mismatch * * @param loadConfig <BtModuleLoadConfig> Configuration of BT Module to load * @param version <string> version that should be passed from the client getVersion * @returns Promise<HTMLScriptElement> * @returns Promise<true> when BT module with same version already exists * @returns Promise.reject(err) when BT module already exists but versions mismatch or empty version passed in */ function safeLoadBtModule(loadConfig, version, minified) { var _a, _b; if (minified === void 0) { minified = true; } return __awaiter(this, void 0, void 0, function () { var bt, existingVersion; return __generator(this, function (_c) { bt = getBraintree(); if (bt && bt[loadConfig.module]) { if (version && ((_a = bt[loadConfig.module]) === null || _a === void 0 ? void 0 : _a.VERSION) !== version) { existingVersion = (_b = bt[loadConfig.module]) === null || _b === void 0 ? void 0 : _b.VERSION; throw new Error("".concat(loadConfig.module, " already loaded with version ").concat(existingVersion, " cannot load version ").concat(version)); } else { return [2 /*return*/, true]; } } if (!version) { throw new Error("Attempted to load ".concat(loadConfig.module, " without specifying version")); } return [2 /*return*/, loadBtModule(loadConfig, version, minified)]; }); }); } /** * Reads the version and to load the correct version of Bt module * * @param loadConfig <BtModuleLoadConfig> Configuration of BT Module to load * @param version <string> Bt module version * @returns Promise<HTMLScriptElement> or */ function loadBtModule(loadConfig, version, minified) { if (minified === void 0) { minified = true; } if (isAmdEnv()) { var module_1 = minified ? loadConfig.amdModule.minified : loadConfig.amdModule.unminified; return new Promise(function (resolve, reject) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore window.require([module_1], resolve, reject); }); } var script = minified ? loadConfig.script.minified : loadConfig.script.unminified; return loadScript_1({ id: "".concat(loadConfig.id, "-").concat(version), src: "https://js.braintreegateway.com/web/".concat(version, "/js/").concat(script), }); } /** * Looks for the Braintree web sdk on the window object * * @returns Braintree web sdk */ function getBraintree() { return window === null || window === void 0 ? void 0 : window.braintree; } var _a, _b; /** * Maps to the BT module namespace created on the window.braintree object */ var BtModule = { Client: "client", HostedCardFields: "hostedFields", }; var BT_NAMESPACE = "braintree"; var BT_ASSET_NAME = (_a = {}, _a[BtModule.Client] = "client", _a[BtModule.HostedCardFields] = "hosted-fields", _a); var btModulesLoadConfig = (_b = {}, _b[BtModule.Client] = { id: "client", module: BtModule.Client, amdModule: { unminified: "".concat(BT_NAMESPACE, "/").concat(BT_ASSET_NAME[BtModule.Client]), minified: "".concat(BT_NAMESPACE, "/").concat(BT_ASSET_NAME[BtModule.Client], ".min"), }, script: { unminified: "".concat(BT_ASSET_NAME[BtModule.Client], ".js"), minified: "".concat(BT_ASSET_NAME[BtModule.Client], ".min.js"), }, }, _b[BtModule.HostedCardFields] = { id: "hcf", module: BtModule.HostedCardFields, amdModule: { unminified: "".concat(BT_NAMESPACE, "/").concat(BT_ASSET_NAME[BtModule.HostedCardFields]), minified: "".concat(BT_NAMESPACE, "/").concat(BT_ASSET_NAME[BtModule.HostedCardFields], ".min"), }, script: { unminified: "".concat(BT_ASSET_NAME[BtModule.HostedCardFields], ".js"), minified: "".concat(BT_ASSET_NAME[BtModule.HostedCardFields], ".min.js"), }, }, _b); /** * Loads accelerated checkout components. * @param options object with a minified parameter to determine if the script that is loaded should be minified or not (defaults to true if) * @returns an object with metadata with a localeUrl parameter to be read by AXO SDK */ function loadAxo(options) { return __awaiter(this, void 0, void 0, function () { var btSdkVersion, minified, assetUrl, localeUrl; return __generator(this, function (_a) { switch (_a.label) { case 0: performance.mark("pp_axo_sdk_init_invoked"); btSdkVersion = options.btSdkVersion, minified = options.minified; assetUrl = getAssetsUrl(options); localeUrl = getLocaleUrl(options); if (!(options.platform === AxoSupportedPlatforms.BT)) return [3 /*break*/, 2]; return [4 /*yield*/, Promise.all([ safeLoadBtModule(btModulesLoadConfig.hostedFields, btSdkVersion, minified), loadAXOScript(assetUrl, minified), ])]; case 1: _a.sent(); return [3 /*break*/, 5]; case 2: if (!(options.platform === AxoSupportedPlatforms.PPCP)) return [3 /*break*/, 4]; return [4 /*yield*/, Promise.all([ safeLoadBtModule(btModulesLoadConfig.client, btSdkVersion, minified), safeLoadBtModule(btModulesLoadConfig.hostedFields, btSdkVersion, minified), loadAXOScript(assetUrl, minified), ])]; case 3: _a.sent(); return [3 /*break*/, 5]; case 4: throw new Error("unsupported axo platform"); case 5: return [2 /*return*/, { metadata: { localeUrl: localeUrl } }]; } }); }); } /** * Reads the url and to load the axo bundle script * @param url (Required) string url for the correct axo asset * @returns Promise<HTMLScriptElement> */ function loadAXOScript(url, minified) { var _a; if (minified === void 0) { minified = true; } if (isAmdEnv()) { // AMD environment if (isRequireJsEnv()) { // Let's configure RequireJS requirejs.config({ paths: (_a = {}, _a[FL_NAMESPACE] = url, _a), }); } var moduleName_1 = "".concat(FL_NAMESPACE, "/").concat(minified ? constants.AXO_ASSET_NAME.minified : constants.AXO_ASSET_NAME.unminified); return new Promise(function (resolve, reject) { window.require([moduleName_1], resolve, reject); }); } // Not an AMD environment return loadScript_1({ id: "axo-id", src: url, forceScriptReload: true, }); } /** * Prepends the domain to the asset url * @param options object with assetUrl and bundleid parameters to determine which URL to return * @returns full domain and assets URL as string */ function generateAssetUrl(_a) { var assetUrl = _a.assetUrl, bundleId = _a.bundleId; return bundleId ? "https://cdn-".concat(bundleId, ".static.engineering.dev.paypalinc.com/").concat(assetUrl) : "".concat(constants.CDNX_PROD, "/").concat(assetUrl); } /** * Retrieves either the minified or unminified assets URL as specified * @param options (Optional) object with a minified and metadata with bundleIdOverride parameters to determine which URL to return * @returns assets URL as string */ function getAssetsUrl(options) { var _a; var assetName = (options === null || options === void 0 ? void 0 : options.minified) !== false ? constants.AXO_ASSET_NAME.minified : constants.AXO_ASSET_NAME.unminified; var assetUrl = isAmdEnv() ? constants.AXO_ASSET_PATH : "".concat(constants.AXO_ASSET_PATH, "/").concat(assetName, ".js"); return generateAssetUrl({ assetUrl: assetUrl, bundleId: (_a = options === null || options === void 0 ? void 0 : options.metadata) === null || _a === void 0 ? void 0 : _a.bundleIdOverride, }); } /** * Retrieves the Locales URL, the path to our language files * @param options (Optional) object with a minified and metadata with bundleIdOverride parameters to determine which URL to return * @returns locale URL as string */ function getLocaleUrl(options) { var _a; return generateAssetUrl({ assetUrl: constants.LOCALE_PATH, bundleId: (_a = options === null || options === void 0 ? void 0 : options.metadata) === null || _a === void 0 ? void 0 : _a.bundleIdOverride, }); } exports.constants = constants; exports.loadAxo = loadAxo; })); },{}],8:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("../lib/braintree-error"); var analytics = _dereq_("../lib/analytics"); var errors = _dereq_("./errors"); var methods = _dereq_("../lib/methods"); var convertMethodsToError = _dereq_("../lib/convert-methods-to-error"); var wrapPromise = _dereq_("@braintree/wrap-promise"); /** * @typedef {object} ApplePay~tokenizePayload * @property {string} nonce The payment method nonce. * @property {object} details Additional details. * @property {string} details.cardType Type of card, ex: Visa, MasterCard. * @property {string} details.cardHolderName The name of the card holder. * @property {string} details.dpanLastTwo Last two digits of card number. * @property {boolean} details.isDeviceToken Whether this tokenized card is a * device-specific account number (DPAN) ('true') or merchant/cloud token (MPAN) ('false'). * @property {string} description A human-readable description. * @property {string} type The payment method type, always `ApplePayCard`. * @property {object} binData Information about the card based on the bin. * @property {string} binData.commercial Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.countryOfIssuance The country of issuance. * @property {string} binData.debit Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.durbinRegulated Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.healthcare Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.issuingBank The issuing bank. * @property {string} binData.payroll Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.prepaid Possible values: 'Yes', 'No', 'Unknown'. * @property {string} binData.productId The product id. */ /** * An Apple Pay Payment Authorization Event object. * @typedef {object} ApplePayPaymentAuthorizedEvent * @external ApplePayPaymentAuthorizedEvent * @see {@link https://developer.apple.com/reference/applepayjs/applepaypaymentauthorizedevent ApplePayPaymentAuthorizedEvent} */ /** * An Apple Pay Payment Request object. * @typedef {object} ApplePayPaymentRequest * @external ApplePayPaymentRequest * @see {@link https://developer.apple.com/reference/applepayjs/1916082-applepay_js_data_types/paymentrequest PaymentRequest} */ /** * @class * @param {object} options Options * @description <strong>You cannot use this constructor directly. Use {@link module:braintree-web/apple-pay.create|braintree.applePay.create} instead.</strong> * @classdesc This class represents an Apple Pay component. Instances of this class have methods for validating the merchant server and tokenizing payments. */ function ApplePay(options) { this._instantiatedWithClient = Boolean(!options.useDeferredClient); this._client = options.client; this._createPromise = options.createPromise; if (this._client) { this._setMerchantIdentifier(); } } ApplePay.prototype._waitForClient = function () { if (this._client) { return Promise.resolve(); } return this._createPromise.then( function (client) { this._client = client; this._setMerchantIdentifier(); }.bind(this) ); }; ApplePay.prototype._setMerchantIdentifier = function () { var applePayConfig = this._client.getConfiguration().gatewayConfiguration.applePayWeb; if (!applePayConfig) { return; } /** * @name ApplePay#merchantIdentifier * @description A special merchant ID which represents the merchant association with Braintree. Required when using `ApplePaySession.canMakePaymentsWithActiveCard`. * @example * var promise = ApplePaySession.canMakePaymentsWithActiveCard(applePayInstance.merchantIdentifier); * promise.then(function (canMakePaymentsWithActiveCard) { * if (canMakePaymentsWithActiveCard) { * // Set up Apple Pay buttons * } * }); */ Object.defineProperty(this, "merchantIdentifier", { value: applePayConfig.merchantIdentifier, configurable: false, writable: false, }); }; /** * Merges a payment request with Braintree defaults to return an {external:ApplePayPaymentRequest}. * * The following properties are assigned to `paymentRequest` if not already defined. Their default values come from the Braintree gateway. * - `countryCode` * - `currencyCode` * - `merchantCapabilities` * - `supportedNetworks` * @public * @param {external:ApplePayPaymentRequest} paymentRequest The payment request details to apply on top of those from Braintree. * @returns {external:ApplePayPaymentRequest|Promise} The decorated `paymentRequest` object. If `useDeferredClient` is used along with an `authorization`, this method will return a promise that resolves with the `paymentRequest` object. * @example * var applePay = require('braintree-web/apple-pay'); * * applePay.create({client: clientInstance}, function (applePayErr, applePayInstance) { * if (applePayErr) { * // Handle error here * return; * } * * var paymentRequest = applePayInstance.createPaymentRequest({ * total: { * label: 'My Company', * amount: '19.99' * } * }); * * var session = new ApplePaySession(3, paymentRequest); * * // ... * @example <caption>With deferred client</caption> * var applePay = require('braintree-web/apple-pay'); * * applePay.create({ * authorization: 'client-token-or-tokenization-key', * useDeferredClient: true * }, function (applePayErr, applePayInstance) { * if (applePayErr) { * // Handle error here * return; * } * * applePayInstance.createPaymentRequest({ * total: { * label: 'My Company', * amount: '19.99' * } * }).then(function (paymentRequest) { * var session = new ApplePaySession(3, paymentRequest); * * // ... * }); */ ApplePay.prototype.createPaymentRequest = function (paymentRequest) { if (this._instantiatedWithClient) { return this._createPaymentRequestSynchronously(paymentRequest); } return this._waitForClient().then( function () { return this._createPaymentRequestSynchronously(paymentRequest); }.bind(this) ); }; ApplePay.prototype._createPaymentRequestSynchronously = function ( paymentRequest ) { var applePay = this._client.getConfiguration().gatewayConfiguration.applePayWeb; var defaults = { countryCode: applePay.countryCode, currencyCode: applePay.currencyCode, merchantCapabilities: applePay.merchantCapabilities || ["supports3DS"], supportedNetworks: applePay.supportedNetworks.map(function (network) { return network === "mastercard" ? "masterCard" : network; }), }; return Object.assign({}, defaults, paymentRequest); }; /** * Validates your merchant website, as required by `ApplePaySession` before payment can be authorized. * @public * @param {object} options Options * @param {string} options.validationURL The validationURL from an `ApplePayValidateMerchantEvent`. * @param {string} options.displayName The canonical name for your store. Use a non-localized name. This parameter should be a UTF-8 string that is a maximum of 64 characters. The system may display this name to the user. * @param {callback} [callback] The second argument, <code>data</code>, is the Apple Pay merchant session object. If no callback is provided, `performValidation` returns a promise. * Pass the merchant session to your Apple Pay session's `completeMerchantValidation` method. * @returns {(Promise|void)} Returns a promise if no callback is provided. * @example * var applePay = require('braintree-web/apple-pay'); * * applePay.create({client: clientInstance}, function (applePayErr, applePayInstance) { * if (applePayErr) { * // Handle error here * return; * } * * var paymentRequest = applePayInstance.createPaymentRequest({ * total: { * label: 'My Company', * amount: '19.99' * } * }); * var session = new ApplePaySession(3, paymentRequest); * * session.onvalidatemerchant = function (event) { * applePayInstance.performValidation({ * validationURL: event.validationURL, * displayName: 'My Great Store' * }, function (validationErr, validationData) { * if (validationErr) { * console.error(validationErr); * session.abort(); * return; * } * * session.completeMerchantValidation(validationData); * }); * }; * }); */ ApplePay.prototype.performValidation = function (options) { var self = this; if (!options || !options.validationURL) { return Promise.reject( new BraintreeError(errors.APPLE_PAY_VALIDATION_URL_REQUIRED) ); } return this._waitForClient() .then(function () { var applePayWebSession = { validationUrl: options.validationURL, domainName: options.domainName || window.location.hostname, merchantIdentifier: options.merchantIdentifier || self.merchantIdentifier, }; if (options.displayName != null) { applePayWebSession.displayName = options.displayName; } return self._client.request({ method: "post", endpoint: "apple_pay_web/sessions", data: { _meta: { source: "apple-pay" }, applePayWebSession: applePayWebSession, }, }); }) .then(function (response) { analytics.sendEvent(self._client, "applepay.performValidation.succeeded"); return Promise.resolve(response); }) .catch(function (err) { analytics.sendEvent(self._client, "applepay.performValidation.failed"); if (err.code === "CLIENT_REQUEST_ERROR") { return Promise.reject( new BraintreeError({ type: errors.APPLE_PAY_MERCHANT_VALIDATION_FAILED.type, code: errors.APPLE_PAY_MERCHANT_VALIDATION_FAILED.code, message: errors.APPLE_PAY_MERCHANT_VALIDATION_FAILED.message, details: { originalError: err.details.originalError, }, }) ); } return Promise.reject( new BraintreeError({ type: errors.APPLE_PAY_MERCHANT_VALIDATION_NETWORK.type, code: errors.APPLE_PAY_MERCHANT_VALIDATION_NETWORK.code, message: errors.APPLE_PAY_MERCHANT_VALIDATION_NETWORK.message, details: { originalError: err, }, }) ); }); }; /** * Tokenizes an Apple Pay payment. This will likely be called in your `ApplePaySession`'s `onpaymentauthorized` callback. * @public * @param {object} options Options * @param {object} options.token The `payment.token` property of an {@link external:ApplePayPaymentAuthorizedEvent}. * @param {callback} [callback] The second argument, <code>data</code>, is a {@link ApplePay~tokenizePayload|tokenizePayload}. If no callback is provided, `tokenize` returns a promise that resolves with a {@link ApplePay~tokenizePayload|tokenizePayload}. * @returns {(Promise|void)} Returns a promise if no callback is provided. * @example * var applePay = require('braintree-web/apple-pay'); * * applePay.create({client: clientInstance}, function (applePayErr, applePayInstance) { * if (applePayErr) { * // Handle error here * return; * } * * var paymentRequest = applePayInstance.createPaymentRequest({ * total: { * label: 'My Company', * amount: '19.99' * } * }); * var session = new ApplePaySession(3, paymentRequest); * * session.onpaymentauthorized = function (event) { * applePayInstance.tokenize({ * token: event.payment.token * }, function (tokenizeErr, tokenizedPayload) { * if (tokenizeErr) { * session.completePayment(ApplePaySession.STATUS_FAILURE); * return; * } * // Send the tokenizedPayload to your server here! * * // Once the transaction is complete, call completePayment * // to close the Apple Pay sheet * session.completePayment(ApplePaySession.STATUS_SUCCESS); * }); * }; * * // ... * }); */ ApplePay.prototype.tokenize = function (options) { var self = this; if (!options.token) { return Promise.reject( new BraintreeError(errors.APPLE_PAY_PAYMENT_TOKEN_REQUIRED) ); } return this._waitForClient() .then(function () { return self._client.request({ method: "post", endpoint: "payment_methods/apple_payment_tokens", data: { _meta: { source: "apple-pay", }, applePaymentToken: Object.assign({}, options.token, { // The gateway requires this key to be base64-encoded. paymentData: btoa(JSON.stringify(options.token.paymentData)), }), }, }); }) .then(function (response) { analytics.sendEvent(self._client, "applepay.tokenize.succeeded"); return Promise.resolve(response.applePayCards[0]); }) .catch(function (err) { analytics.sendEvent(self._client, "applepay.tokenize.failed"); return Promise.reject( new BraintreeError({ type: errors.APPLE_PAY_TOKENIZATION.type, code: errors.APPLE_PAY_TOKENIZATION.code, message: errors.APPLE_PAY_TOKENIZATION.message, details: { originalError: err, }, }) ); }); }; /** * Cleanly tear down anything set up by {@link module:braintree-web/apple-pay.create|create}. * @public * @param {callback} [callback] Called once teardown is complete. No data is returned if teardown completes successfully. * @example * applePayInstance.teardown(); * @example <caption>With callback</caption> * applePayInstance.teardown(function () { * // teardown is complete * }); * @returns {(Promise|void)} Returns a promise if no callback is provided. */ ApplePay.prototype.teardown = function () { convertMethodsToError(this, methods(ApplePay.prototype)); return Promise.resolve(); }; module.exports = wrapPromise.wrapPrototype(ApplePay); },{"../lib/analytics":12,"../lib/braintree-error":16,"../lib/convert-methods-to-error":18,"../lib/methods":25,"./errors":9,"@braintree/wrap-promise":6}],9:[function(_dereq_,module,exports){ "use strict"; /** * @name BraintreeError.Apple Pay - Creation Error Codes * @description Errors that occur when [creating the Apple Pay component](./module-braintree-web_apple-pay.html#.create). * @property {MERCHANT} APPLE_PAY_NOT_ENABLED Occurs when the authorization used is not authorized to process Apple Pay. */ /** * @name BraintreeError.Apple Pay - performValidation Error Codes * @description Errors that occur when [validating](./ApplePay.html#performValidation). * @property {MERCHANT} APPLE_PAY_VALIDATION_URL_REQUIRED Occurs when the `validationURL` option is not passed in. * @property {MERCHANT} APPLE_PAY_MERCHANT_VALIDATION_FAILED Occurs when the website domain has not been registered in the Braintree control panel. * @property {NETWORK} APPLE_PAY_MERCHANT_VALIDATION_NETWORK Occurs when an unknown network error occurs. */ /** * @name BraintreeError.Apple Pay - tokenize Error Codes * @description Errors that occur when [tokenizing](./ApplePay.html#tokenize). * @property {MERCHANT} APPLE_PAY_PAYMENT_TOKEN_REQUIRED Occurs when the `token` option is not passed in. * @property {NETWORK} APPLE_PAY_TOKENIZATION Occurs when an unknown network error occurs. */ var BraintreeError = _dereq_("../lib/braintree-error"); module.exports = { APPLE_PAY_NOT_ENABLED: { type: BraintreeError.types.MERCHANT, code: "APPLE_PAY_NOT_ENABLED", message: "Apple Pay is not enabled for this merchant.", }, APPLE_PAY_VALIDATION_URL_REQUIRED: { type: BraintreeError.types.MERCHANT, code: "APPLE_PAY_VALIDATION_URL_REQUIRED", message: "performValidation must be called with a validationURL.", }, APPLE_PAY_MERCHANT_VALIDATION_NETWORK: { type: BraintreeError.types.NETWORK, code: "APPLE_PAY_MERCHANT_VALIDATION_NETWORK", message: "A network error occurred when validating the Apple Pay merchant.", }, APPLE_PAY_MERCHANT_VALIDATION_FAILED: { type: BraintreeError.types.MERCHANT, code: "APPLE_PAY_MERCHANT_VALIDATION_FAILED", message: "Make sure you have registered your domain name in the Braintree Control Panel.", }, APPLE_PAY_PAYMENT_TOKEN_REQUIRED: { type: BraintreeError.types.MERCHANT, code: "APPLE_PAY_PAYMENT_TOKEN_REQUIRED", message: "tokenize must be called with a payment token.", }, APPLE_PAY_TOKENIZATION: { type: BraintreeError.types.NETWORK, code: "APPLE_PAY_TOKENIZATION", message: "A network error occurred when processing the Apple Pay payment.", }, }; },{"../lib/braintree-error":16}],10:[function(_dereq_,module,exports){ "use strict"; /** * @module braintree-web/apple-pay * @description Accept Apple Pay on the Web. *This component is currently in beta and is subject to change.* */ var ApplePay = _dereq_("./apple-pay"); var analytics = _dereq_("../lib/analytics"); var BraintreeError = _dereq_("../lib/braintree-error"); var basicComponentVerification = _dereq_("../lib/basic-component-verification"); var createAssetsUrl = _dereq_("../lib/create-assets-url"); var createDeferredClient = _dereq_("../lib/create-deferred-client"); var errors = _dereq_("./errors"); var VERSION = "3.118.2"; 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 {boolean} [options.useDeferredClient] Used in conjunction with `authorization`, allows the Apple Pay instance to be available right away by fetching the client configuration in the background. When this option is used, {@link ApplePay#createPaymentRequest} will return a promise that resolves with the configuration instead of returning synchronously. * @param {callback} [callback] The second argument, `data`, is the {@link ApplePay} instance. If no callback is provided, `create` returns a promise that resolves with the {@link ApplePay} instance. * @returns {(Promise|void)} Returns a promise if no callback is provided. */ function create(options) { var name = "Apple Pay"; return basicComponentVerification .verify({ name: name, client: options.client, authorization: options.authorization, }) .then(function () { var applePayInstance; var createPromise = createDeferredClient .create({ authorization: options.authorization, client: options.client, debug: options.debug, assetsUrl: createAssetsUrl.create(options.authorization), name: name, }) .then(function (client) { if (!client.getConfiguration().gatewayConfiguration.applePayWeb) { return Promise.reject( new BraintreeError(errors.APPLE_PAY_NOT_ENABLED) ); } analytics.sendEvent(client, "applepay.initialized"); return client; }); options.createPromise = createPromise; applePayInstance = new ApplePay(options); if (!options.useDeferredClient) { return createPromise.then(function (client) { applePayInstance._client = client; return applePayInstance; }); } return applePayInstance; }); } module.exports = { create: wrapPromise(create), /** * @description The current version of the SDK, i.e. `{@pkg version}`. * @type {string} */ VERSION: VERSION, }; },{"../lib/analytics":12,"../lib/basic-component-verification":15,"../lib/braintree-error":16,"../lib/create-assets-url":19,"../lib/create-deferred-client":21,"./apple-pay":8,"./errors":9,"@braintree/wrap-promise":6}],11:[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; } function addEventMetadata(clientInstanceOrPromise) { var configuration = clientInstanceOrPromise.getConfiguration(); var authAttrs = createAuthorizationData(configuration.authorization).attrs; var isProd = configuration.gatewayConfiguration.environment === "production"; /* eslint-disable camelcase */ var metadata = { api_integration_type: configuration.analyticsMetadata.integrationType, app_id: window.location.host, c_sdk_ver: constants.VERSION, component: "braintreeclientsdk", merchant_sdk_env: isProd ? "production" : "sandbox", merchant_id: configuration.gatewayConfiguration.merchantId, event_source: "web", platform: constants.PLATFORM, platform_version: window.navigator.userAgent, session_id: configuration.analyticsMetadata.sessionId, client_session_id: configuration.analyticsMetadata.sessionId, tenant_name: "braintree", }; if (authAttrs.tokenizationKey) { metadata.tokenization_key = authAttrs.tokenizationKey; } else { metadata.auth_fingerprint = authAttrs.authorizationFingerprint; } /* eslint-enable camelcase */ return metadata; } module.exports = { addMetadata: addMetadata, addEventMetadata: addEventMetadata, }; },{"./constants":17,"./create-authorization-data":20,"./json-clone":24}],12:[function(_dereq_,module,exports){ "use strict"; var constants = _dereq_("./constants"); var metadata = _dereq_("./add-metadata"); var assign = _dereq_("./assign").assign; function sendPaypalEvent(clientInstanceOrPromise, eventName, callback) { return sendPaypalEventPlusFields( clientInstanceOrPromise, eventName, {}, callback ); } function sendPaypalEventPlusFields( clientInstanceOrPromise, eventName, extraFields, callback ) { var timestamp = Date.now(); return Promise.resolve(clientInstanceOrPromise) .then(function (client) { var request = client._request; var url = constants.ANALYTICS_URL; var qualifiedEvent = constants.ANALYTICS_PREFIX + eventName; var configuration = client.getConfiguration(); var isProd = configuration.gatewayConfiguration.environment === "production"; var data = { events: [], tracking: [], }; var trackingMeta = metadata.addEventMetadata(client, data); trackingMeta.event_name = qualifiedEvent; // eslint-disable-line camelcase trackingMeta.t = timestamp; // eslint-disable-line camelcase data.events = [ { level: "info", event: qualifiedEvent, payload: { env: isProd ? "production" : "sandbox", timestamp: timestamp, }, }, ]; data.tracking = [trackingMeta]; if (extraFields && typeof extraFields === "object") { data.tracking = [appendExtraFieldsTo(trackingMeta, extraFields)]; } return request( { url: url, method: "post", data: data, timeout: constants.ANALYTICS_REQUEST_TIMEOUT_MS, }, callback ); }) .catch(function (err) { if (callback) { callback(err); } }); } function appendExtraFieldsTo(trackingMeta, extraFields) { var result = {}; var allowedExtraFields = assign({}, extraFields); Object.keys(allowedExtraFields).forEach(function (field) { if (constants.ALLOWED_EXTRA_EVENT_FIELDS.indexOf(field) === -1) { delete allowedExtraFields[field]; } }); result = assign(trackingMeta, allowedExtraFields); return result; } module.exports = { sendEvent: sendPaypalEvent, sendEventPlus: sendPaypalEventPlusFields, }; },{"./add-metadata":11,"./assign":14,"./constants":17}],13:[function(_dereq_,module,exports){ "use strict"; var loadScript = _dereq_("@braintree/asset-loader/load-script"); var loadConnectScript = _dereq_("@paypal/accelerated-checkout-loader"); module.exports = { loadScript: loadScript, loadFastlane: loadConnectScript.loadAxo, }; },{"@braintree/asset-loader/load-script":2,"@paypal/accelerated-checkout-loader":7}],14:[function(_dereq_,module,exports){ "use strict"; var assignNormalized = typeof Object.assign === "function" ? Object.assign : assignPolyfill; function assignPolyfill(destination) { var i, source, key; for (i = 1; i < arguments.length; i++) { source = arguments[i]; for (key in source) { if (source.hasOwnProperty(key)) { destination[key] = source[key]; } } } return destination; } module.exports = { assign: assignNormalized, _assign: assignPolyfill, }; },{}],15:[function(_dereq_,module,exports){ "use strict"; var BraintreeError = _dereq_("./braintree-error"); var sharedErrors = _dereq_("./errors"); var VERSION = "3.118.2"; function basicComponentVerification(options) { var client, authorization, name; if (!options) { return Promise.reject( new BraintreeError({ type: share