@paypal/react-paypal-js
Advanced tools
Comparing version 7.3.3 to 7.4.0
@@ -5,2 +5,14 @@ # Changelog | ||
## [7.4.0](https://github.com/paypal/react-paypal-js/compare/v7.3.3...v7.4.0) (2021-10-08) | ||
### Features | ||
- **hosted-fields:** add support for hosted-fields ([#160](https://github.com/paypal/react-paypal-js/issues/160)) ([e025d9a](https://github.com/paypal/react-paypal-js/commit/e025d9a1b45d43ad4b79e419188d59907b3cf1b8)) | ||
- update Marks to support the children prop ([#155](https://github.com/paypal/react-paypal-js/issues/155)) ([6aebf98](https://github.com/paypal/react-paypal-js/commit/6aebf98b2592ed7ac68d6b232ab2fa4121dd114e)) | ||
### Bug Fixes | ||
- **types:** standardize types for children ([#157](https://github.com/paypal/react-paypal-js/issues/157)) ([cc956be](https://github.com/paypal/react-paypal-js/commit/cc956beb1323a7516e30174b7d7fd20c9cd60e13)) | ||
- update Marks to rerender when fundingSource changes ([#154](https://github.com/paypal/react-paypal-js/issues/154)) ([f7b4a25](https://github.com/paypal/react-paypal-js/commit/f7b4a251b01e7777948fda846fe0b55d348ec60a)) | ||
### [7.3.3](https://github.com/paypal/react-paypal-js/compare/v7.3.2...v7.3.3) (2021-08-31) | ||
@@ -7,0 +19,0 @@ |
/*! | ||
* react-paypal-js v7.3.3 (2021-08-31T21:55:23.426Z) | ||
* react-paypal-js v7.4.0 (2021-10-08T14:28:13.235Z) | ||
* Copyright 2020-present, PayPal, Inc. All rights reserved. | ||
@@ -27,2 +27,7 @@ * | ||
/** | ||
* Enum for the SDK script resolve status, | ||
* | ||
* @enum {string} | ||
*/ | ||
exports.SCRIPT_LOADING_STATE = void 0; | ||
@@ -35,10 +40,31 @@ (function (SCRIPT_LOADING_STATE) { | ||
})(exports.SCRIPT_LOADING_STATE || (exports.SCRIPT_LOADING_STATE = {})); | ||
exports.DISPATCH_ACTION = void 0; | ||
(function (DISPATCH_ACTION) { | ||
DISPATCH_ACTION["LOADING_STATUS"] = "setLoadingStatus"; | ||
DISPATCH_ACTION["RESET_OPTIONS"] = "resetOptions"; | ||
DISPATCH_ACTION["SET_BRAINTREE_INSTANCE"] = "braintreeInstance"; | ||
})(exports.DISPATCH_ACTION || (exports.DISPATCH_ACTION = {})); | ||
/** | ||
* Enum for the PayPalScriptProvider context dispatch actions | ||
* | ||
* @enum {string} | ||
*/ | ||
exports.SCRIPT_PROVIDER_DISPATCH_ACTION = void 0; | ||
(function (SCRIPT_PROVIDER_DISPATCH_ACTION) { | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["LOADING_STATUS"] = "setLoadingStatus"; | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["RESET_OPTIONS"] = "resetOptions"; | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["SET_BRAINTREE_INSTANCE"] = "braintreeInstance"; | ||
})(exports.SCRIPT_PROVIDER_DISPATCH_ACTION || (exports.SCRIPT_PROVIDER_DISPATCH_ACTION = {})); | ||
/** | ||
* Enum for all the available hosted fields | ||
* | ||
* @enum {string} | ||
*/ | ||
exports.PAYPAL_HOSTED_FIELDS_TYPES = void 0; | ||
(function (PAYPAL_HOSTED_FIELDS_TYPES) { | ||
PAYPAL_HOSTED_FIELDS_TYPES["NUMBER"] = "number"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["CVV"] = "cvv"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_DATE"] = "expirationDate"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_MONTH"] = "expirationMonth"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_YEAR"] = "expirationYear"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["POSTAL_CODE"] = "postalCode"; | ||
})(exports.PAYPAL_HOSTED_FIELDS_TYPES || (exports.PAYPAL_HOSTED_FIELDS_TYPES = {})); | ||
// Common reference to the script identifier | ||
/********************************************* | ||
* Common reference to the script identifier * | ||
*********************************************/ | ||
var SCRIPT_ID = "data-react-paypal-script-id"; | ||
@@ -48,3 +74,6 @@ var DATA_CLIENT_TOKEN = "data-client-token"; | ||
var DATA_SDK_INTEGRATION_SOURCE_VALUE = "react-paypal-js"; | ||
var EMPTY_PROVIDER_CONTEXT_ERROR_MESSAGE = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; | ||
var DATA_NAMESPACE = "data-namespace"; | ||
/**************************** | ||
* Braintree error messages * | ||
****************************/ | ||
var EMPTY_PROVIDER_CONTEXT_CLIENT_TOKEN_ERROR_MESSAGE = "A client token wasn't found in the provider parent component"; | ||
@@ -54,5 +83,16 @@ var braintreeVersion = "3.81.0"; | ||
var BRAINTREE_PAYPAL_CHECKOUT_SOURCE = "https://js.braintreegateway.com/web/" + braintreeVersion + "/js/paypal-checkout.min.js"; | ||
// Namespaces | ||
/********************* | ||
* PayPal namespaces * | ||
*********************/ | ||
var DEFAULT_PAYPAL_NAMESPACE = "paypal"; | ||
var DEFAULT_BRAINTREE_NAMESPACE = "braintree"; | ||
/***************** | ||
* Hosted Fields * | ||
*****************/ | ||
var HOSTED_FIELDS_CHILDREN_ERROR = "To use HostedFields you must use it with at least 3 children with types: [number, cvv, expirationDate] includes"; | ||
var HOSTED_FIELDS_DUPLICATE_CHILDREN_ERROR = "Cannot use duplicate HostedFields as children"; | ||
/******************* | ||
* Script Provider * | ||
*******************/ | ||
var SCRIPT_PROVIDER_REDUCER_ERROR = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; | ||
@@ -84,3 +124,3 @@ var __assign = function () { | ||
} | ||
return to.concat(ar || from); | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
@@ -147,3 +187,3 @@ | ||
var scriptNode = self.document.querySelector("script[" + SCRIPT_ID + "=\"" + reactPayPalScriptID + "\"]"); | ||
if (scriptNode != null && scriptNode.parentNode) | ||
if (scriptNode === null || scriptNode === void 0 ? void 0 : scriptNode.parentNode) | ||
scriptNode.parentNode.removeChild(scriptNode); | ||
@@ -161,5 +201,5 @@ } | ||
switch (action.type) { | ||
case exports.DISPATCH_ACTION.LOADING_STATUS: | ||
case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS: | ||
return __assign(__assign({}, state), { loadingStatus: action.value }); | ||
case exports.DISPATCH_ACTION.RESET_OPTIONS: | ||
case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.RESET_OPTIONS: | ||
// destroy existing script to make sure only one script loads at a time | ||
@@ -170,3 +210,3 @@ destroySDKScript(state.options[SCRIPT_ID]); | ||
return __assign(__assign({}, state), { loadingStatus: exports.SCRIPT_LOADING_STATE.PENDING, options: __assign(__assign({}, action.value), (_a = {}, _a[SCRIPT_ID] = "" + getScriptID(action.value), _a[DATA_SDK_INTEGRATION_SOURCE] = DATA_SDK_INTEGRATION_SOURCE_VALUE, _a)) }); | ||
case exports.DISPATCH_ACTION.SET_BRAINTREE_INSTANCE: | ||
case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE: | ||
return __assign(__assign({}, state), { braintreePayPalCheckoutInstance: action.value }); | ||
@@ -188,6 +228,7 @@ default: { | ||
function contextNotEmptyValidator(scriptContext) { | ||
if (typeof (scriptContext === null || scriptContext === void 0 ? void 0 : scriptContext.dispatch) !== "function") { | ||
throw new Error(EMPTY_PROVIDER_CONTEXT_ERROR_MESSAGE); | ||
if (typeof (scriptContext === null || scriptContext === void 0 ? void 0 : scriptContext.dispatch) === "function" && | ||
scriptContext.dispatch.length !== 0) { | ||
return scriptContext; | ||
} | ||
return scriptContext; | ||
throw new Error(SCRIPT_PROVIDER_REDUCER_ERROR); | ||
} | ||
@@ -219,6 +260,35 @@ /** | ||
var derivedStatusContext = __assign(__assign({}, scriptContext), { isInitial: scriptContext.loadingStatus === exports.SCRIPT_LOADING_STATE.INITIAL, isPending: scriptContext.loadingStatus === exports.SCRIPT_LOADING_STATE.PENDING, isResolved: scriptContext.loadingStatus === exports.SCRIPT_LOADING_STATE.RESOLVED, isRejected: scriptContext.loadingStatus === exports.SCRIPT_LOADING_STATE.REJECTED }); | ||
return [derivedStatusContext, scriptContext.dispatch]; | ||
return [ | ||
derivedStatusContext, | ||
scriptContext.dispatch, | ||
]; | ||
} | ||
/** | ||
* Custom hook to get access to the ScriptProvider context | ||
* | ||
* @returns the latest state of the context | ||
*/ | ||
function useScriptProviderContext() { | ||
var scriptContext = contextOptionClientTokenNotEmptyValidator(contextNotEmptyValidator(React.useContext(ScriptContext))); | ||
return [ | ||
scriptContext, | ||
scriptContext.dispatch, | ||
]; | ||
} | ||
// Create the React context to use in the PayPal hosted fields provider | ||
var PayPalHostedFieldsContext = React.createContext(null); | ||
/** | ||
* Custom hook to get access to the PayPal Hosted Fields instance. | ||
* The instance represent the returned object after the render process | ||
* With this object a user can submit the fields and dynamically modify the cards | ||
* | ||
* @returns the hosted fields instance if is available in the component | ||
*/ | ||
function usePayPalHostedFields() { | ||
return React.useContext(PayPalHostedFieldsContext); | ||
} | ||
/** | ||
This `<PayPalButtons />` component renders the [Smart Payment Buttons](https://developer.paypal.com/docs/business/javascript-sdk/javascript-sdk-reference/#buttons). | ||
@@ -251,9 +321,11 @@ It relies on the `<PayPalScriptProvider />` parent component for managing state related to loading the JS SDK script. | ||
var PayPalButtons = function (_a) { | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.children, children = _d === void 0 ? null : _d, _e = _a.forceReRender, forceReRender = _e === void 0 ? [] : _e, buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, children = _a.children, _d = _a.forceReRender, forceReRender = _d === void 0 ? [] : _d, buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var isDisabledStyle = disabled ? { opacity: 0.38 } : {}; | ||
var classNames = (className + " " + (disabled ? "paypal-buttons-disabled" : "")).trim(); | ||
var buttonsContainerRef = React.useRef(null); | ||
var buttons = React.useRef(null); | ||
var _f = usePayPalScriptReducer()[0], isResolved = _f.isResolved, options = _f.options; | ||
var _g = React.useState(null), initActions = _g[0], setInitActions = _g[1]; | ||
var _h = React.useState(true), isEligible = _h[0], setIsEligible = _h[1]; | ||
var _j = React.useState(null), setErrorState = _j[1]; | ||
var _e = usePayPalScriptReducer()[0], isResolved = _e.isResolved, options = _e.options; | ||
var _f = React.useState(null), initActions = _f[0], setInitActions = _f[1]; | ||
var _g = React.useState(true), isEligible = _g[0], setIsEligible = _g[1]; | ||
var _h = React.useState(null), setErrorState = _h[1]; | ||
function closeButtonsComponent() { | ||
@@ -272,3 +344,3 @@ if (buttons.current !== null) { | ||
} | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); | ||
// verify dependency on window object | ||
@@ -301,3 +373,3 @@ if (paypalWindowNamespace === undefined || | ||
} | ||
if (buttonsContainerRef.current === null) { | ||
if (!buttonsContainerRef.current) { | ||
return closeButtonsComponent; | ||
@@ -319,3 +391,3 @@ } | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, __spreadArray(__spreadArray([isResolved], forceReRender), [buttonProps.fundingSource])); | ||
}, __spreadArray(__spreadArray([isResolved], forceReRender, true), [buttonProps.fundingSource], false)); | ||
// useEffect hook for managing disabled state | ||
@@ -337,11 +409,6 @@ React.useEffect(function () { | ||
}, [disabled, initActions]); | ||
var isDisabledStyle = disabled ? { opacity: 0.38 } : {}; | ||
var classNames = (className + " " + (disabled ? "paypal-buttons-disabled" : "")).trim(); | ||
if (isEligible === false) { | ||
return children; | ||
} | ||
return (React__default['default'].createElement("div", { ref: buttonsContainerRef, style: isDisabledStyle, className: classNames })); | ||
return (React__default["default"].createElement(React__default["default"].Fragment, null, isEligible ? (React__default["default"].createElement("div", { ref: buttonsContainerRef, style: isDisabledStyle, className: classNames })) : (children))); | ||
}; | ||
function getErrorMessage$2(_a) { | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = _a["data-namespace"], dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = DATA_NAMESPACE, _d = _a[_c], dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalButtons /> because window." + dataNamespace + ".Buttons is undefined."; | ||
@@ -529,12 +596,2 @@ // the JS SDK includes the Buttons component by default when no 'components' are specified. | ||
/** | ||
* Custom hook to get access to the ScriptProvider context | ||
* | ||
* @returns the state of the context | ||
*/ | ||
function useBraintreeProviderContext() { | ||
var scriptContext = contextOptionClientTokenNotEmptyValidator(contextNotEmptyValidator(React.useContext(ScriptContext))); | ||
return [scriptContext, scriptContext.dispatch]; | ||
} | ||
/** | ||
* Override the createOrder callback to send the PayPal checkout instance as argument | ||
@@ -609,3 +666,3 @@ * to the defined createOrder function for braintree component button | ||
} | ||
/>; | ||
/> | ||
</PayPalScriptProvider> | ||
@@ -616,5 +673,5 @@ ``` | ||
var BraintreePayPalButtons = function (_a) { | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, _d = _a.children, children = _d === void 0 ? null : _d, _e = _a.forceReRender, forceReRender = _e === void 0 ? [] : _e, buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var _f = React.useState(null), setErrorState = _f[1]; | ||
var _g = useBraintreeProviderContext(), providerContext = _g[0], dispatch = _g[1]; | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.disabled, disabled = _c === void 0 ? false : _c, children = _a.children, _d = _a.forceReRender, forceReRender = _d === void 0 ? [] : _d, buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var _e = React.useState(null), setErrorState = _e[1]; | ||
var _f = useScriptProviderContext(), providerContext = _f[0], dispatch = _f[1]; | ||
React.useEffect(function () { | ||
@@ -639,3 +696,3 @@ Promise.all([ | ||
dispatch({ | ||
type: exports.DISPATCH_ACTION.SET_BRAINTREE_INSTANCE, | ||
type: exports.SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE, | ||
value: paypalCheckoutInstance, | ||
@@ -651,3 +708,3 @@ }); | ||
}, [providerContext.options, dispatch]); | ||
return (React__default['default'].createElement(React__default['default'].Fragment, null, providerContext.braintreePayPalCheckoutInstance && (React__default['default'].createElement(PayPalButtons, __assign({ className: className, disabled: disabled, forceReRender: forceReRender }, decorateActions(buttonProps, providerContext.braintreePayPalCheckoutInstance)), children)))); | ||
return (React__default["default"].createElement(React__default["default"].Fragment, null, providerContext.braintreePayPalCheckoutInstance && (React__default["default"].createElement(PayPalButtons, __assign({ className: className, disabled: disabled, forceReRender: forceReRender }, decorateActions(buttonProps, providerContext.braintreePayPalCheckoutInstance)), children)))); | ||
}; | ||
@@ -659,13 +716,9 @@ | ||
It relies on the `<PayPalScriptProvider />` parent component for managing state related to loading the JS SDK script. | ||
```jsx | ||
<PayPalMarks /> | ||
``` | ||
This component can also be configured to use a single funding source similar to the [standalone buttons](https://developer.paypal.com/docs/business/checkout/configure-payments/standalone-buttons/) approach. | ||
A `FUNDING` object is exported by this library which has a key for every available funding source option. | ||
```jsx | ||
import { PayPalScriptProvider, PayPalMarks, FUNDING } from "@paypal/react-paypal-js"; | ||
<PayPalScriptProvider options={{ "client-id": "test", components: "buttons,marks" }}> | ||
@@ -677,37 +730,23 @@ <PayPalMarks fundingSource={FUNDING.PAYPAL}/> | ||
var PayPalMarks = function (_a) { | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, markProps = __rest(_a, ["className"]); | ||
var _b = _a.className, className = _b === void 0 ? "" : _b, children = _a.children, markProps = __rest(_a, ["className", "children"]); | ||
var _c = usePayPalScriptReducer()[0], isResolved = _c.isResolved, options = _c.options; | ||
var markContainerRef = React.useRef(null); | ||
var mark = React.useRef(null); | ||
var _d = React.useState(null), setErrorState = _d[1]; | ||
React.useEffect(function () { | ||
// verify the sdk script has successfully loaded | ||
if (isResolved === false) { | ||
return; | ||
} | ||
// don't rerender when already rendered | ||
if (mark.current !== null) { | ||
return; | ||
} | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); | ||
// verify dependency on window object | ||
if (paypalWindowNamespace === undefined || | ||
paypalWindowNamespace.Marks === undefined) { | ||
setErrorState(function () { | ||
throw new Error(getErrorMessage$1(options)); | ||
}); | ||
return; | ||
} | ||
mark.current = paypalWindowNamespace.Marks(__assign({}, markProps)); | ||
var _d = React.useState(true), isEligible = _d[0], setIsEligible = _d[1]; | ||
var _e = React.useState(null), setErrorState = _e[1]; | ||
/** | ||
* Render PayPal Mark into the DOM | ||
*/ | ||
var renderPayPalMark = function (mark) { | ||
var current = markContainerRef.current; | ||
// only render the mark when eligible | ||
if (mark.current.isEligible() === false) { | ||
return; | ||
if (!current || !mark.isEligible()) { | ||
return setIsEligible(false); | ||
} | ||
if (markContainerRef.current === null) { | ||
return; | ||
// Remove any children before render it again | ||
if (current.firstChild) { | ||
current.removeChild(current.firstChild); | ||
} | ||
mark.current.render(markContainerRef.current).catch(function (err) { | ||
mark.render(current).catch(function (err) { | ||
// component failed to render, possibly because it was closed or destroyed. | ||
if (markContainerRef.current === null || | ||
markContainerRef.current.children.length === 0) { | ||
if (current === null || current.children.length === 0) { | ||
// paypal marks container is no longer in the DOM, we can safely ignore the error | ||
@@ -721,8 +760,23 @@ return; | ||
}); | ||
}; | ||
React.useEffect(function () { | ||
// verify the sdk script has successfully loaded | ||
if (isResolved === false) | ||
return; | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); | ||
// verify dependency on window object | ||
if (paypalWindowNamespace === undefined || | ||
paypalWindowNamespace.Marks === undefined) { | ||
setErrorState(function () { | ||
throw new Error(getErrorMessage$1(options)); | ||
}); | ||
return; | ||
} | ||
renderPayPalMark(paypalWindowNamespace.Marks(__assign({}, markProps))); | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [isResolved, markProps.fundingSource]); | ||
return React__default['default'].createElement("div", { ref: markContainerRef, className: className }); | ||
return (React__default["default"].createElement(React__default["default"].Fragment, null, isEligible ? (React__default["default"].createElement("div", { ref: markContainerRef, className: className })) : (children))); | ||
}; | ||
function getErrorMessage$1(_a) { | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = _a["data-namespace"], dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = DATA_NAMESPACE, _d = _a[_c], dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalMarks /> because window." + dataNamespace + ".Marks is undefined."; | ||
@@ -750,3 +804,3 @@ // the JS SDK does not load the Marks component by default. It must be passed into the "components" query parameter. | ||
} | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); | ||
// verify dependency on window object | ||
@@ -779,7 +833,7 @@ if (paypalWindowNamespace === undefined || | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, __spreadArray([isResolved], forceReRender)); | ||
return React__default['default'].createElement("div", { ref: messagesContainerRef, className: className }); | ||
}, __spreadArray([isResolved], forceReRender, true)); | ||
return React__default["default"].createElement("div", { ref: messagesContainerRef, className: className }); | ||
}; | ||
function getErrorMessage(_a) { | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = _a["data-namespace"], dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = DATA_NAMESPACE, _d = _a[_c], dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalMessages /> because window." + dataNamespace + ".Messages is undefined."; | ||
@@ -806,3 +860,2 @@ // the JS SDK does not load the Messages component by default. It must be passed into the "components" query parameter. | ||
: exports.SCRIPT_LOADING_STATE.PENDING, | ||
dispatch: null, | ||
}), state = _e[0], dispatch = _e[1]; | ||
@@ -813,3 +866,3 @@ React.useEffect(function () { | ||
return dispatch({ | ||
type: exports.DISPATCH_ACTION.LOADING_STATUS, | ||
type: exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: exports.SCRIPT_LOADING_STATE.PENDING, | ||
@@ -825,3 +878,3 @@ }); | ||
dispatch({ | ||
type: exports.DISPATCH_ACTION.LOADING_STATUS, | ||
type: exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: exports.SCRIPT_LOADING_STATE.RESOLVED, | ||
@@ -834,3 +887,3 @@ }); | ||
dispatch({ | ||
type: exports.DISPATCH_ACTION.LOADING_STATUS, | ||
type: exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: exports.SCRIPT_LOADING_STATE.REJECTED, | ||
@@ -844,5 +897,258 @@ }); | ||
}, [state.options, deferLoading, state.loadingStatus]); | ||
return (React__default['default'].createElement(ScriptContext.Provider, { value: __assign(__assign({}, state), { dispatch: dispatch }) }, children)); | ||
return (React__default["default"].createElement(ScriptContext.Provider, { value: __assign(__assign({}, state), { dispatch: dispatch }) }, children)); | ||
}; | ||
/** | ||
* Throw an exception if the HostedFields is not found in the paypal namespace | ||
* Probably cause for this problem is not sending the hosted-fields string | ||
* as part of the components props in options | ||
* {@code <PayPalScriptProvider options={{ components: 'hosted-fields'}}>} | ||
* | ||
* @param param0 and object containing the components and namespace defined in options | ||
* @throws {@code Error} | ||
* | ||
*/ | ||
var throwMissingHostedFieldsError = function (_a) { | ||
var _b = _a.components, components = _b === void 0 ? "" : _b, _c = DATA_NAMESPACE, _d = _a[_c], dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var expectedComponents = components | ||
? components + ",hosted-fields" | ||
: "hosted-fields"; | ||
var errorMessage = "Unable to render <PayPalHostedFieldsProvider /> because window." + dataNamespace + ".HostedFields is undefined."; | ||
if (!components.includes("hosted-fields")) { | ||
errorMessage += "\nTo fix the issue, add 'hosted-fields' to the list of components passed to the parent PayPalScriptProvider: <PayPalScriptProvider options={{ components: '" + expectedComponents + "'}}>"; | ||
} | ||
throw new Error(errorMessage); | ||
}; | ||
/** | ||
* Identify all the valid hosted fields children and generate the valid options | ||
* to use in the HostedFields.render process | ||
* | ||
* @param childrenList the list of children received | ||
* @param possibleChildren a list of child type to transform into fields format | ||
* @returns the fields object required to render the HostedFields | ||
*/ | ||
var generateHostedFieldsFromChildren = function (childrenList) { | ||
return childrenList.reduce(function (fields, child) { | ||
var _a = child.props, hostedFieldType = _a.hostedFieldType, options = _a.options; | ||
if (Object.values(exports.PAYPAL_HOSTED_FIELDS_TYPES).includes(hostedFieldType)) { | ||
fields[hostedFieldType] = { | ||
selector: options.selector, | ||
placeholder: options.placeholder, | ||
type: options.type, | ||
formatInput: options.formatInput, | ||
maskInput: options.maskInput, | ||
select: options.select, | ||
maxlength: options.maxlength, | ||
minlength: options.minlength, | ||
prefill: options.prefill, | ||
rejectUnsupportedCards: options.rejectUnsupportedCards, | ||
}; | ||
} | ||
return fields; | ||
}, {}); | ||
}; | ||
/** | ||
* Get only PayPalHostedField children, exclude all the other children | ||
* | ||
* @param childrenList the list of children | ||
* @returns a new list containing only the PayPalHostedField components | ||
*/ | ||
var getPayPalHostedFieldChildren = function (childrenList) { | ||
return childrenList.reduce(function (accumulator, child) { | ||
var reactElement = child; | ||
if (reactElement.props.hostedFieldType) { | ||
accumulator.push(reactElement.props.hostedFieldType); | ||
} | ||
return accumulator; | ||
}, []); | ||
}; | ||
/** | ||
* Validate the expiration date children. Valid combinations are: | ||
* 1- Exists expirationDate field and not exists expirationMonth and expirationYear fields | ||
* 2- Exists expirationMonth and expirationYear and not exists expirationDate | ||
* All the other possible combinations are invalid | ||
* | ||
* @param registerTypes | ||
* @returns @type {true} when the children are valid | ||
*/ | ||
var validateExpirationDate = function (registerTypes) { | ||
return (!registerTypes.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_DATE) && | ||
!registerTypes.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_MONTH) && | ||
!registerTypes.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_YEAR)); | ||
}; | ||
/** | ||
* Check if we find the [number, expiration, cvv] in children | ||
* | ||
* @param requiredChildren the list with required children [number, expiration, cvv] | ||
* @param registerTypes the list of all the children types pass to the parent | ||
* @throw an @type {Error} when not find the default children | ||
*/ | ||
var hasDefaultChildren = function (registerTypes) { | ||
if (!registerTypes.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.NUMBER) || | ||
!registerTypes.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.CVV) || | ||
validateExpirationDate(registerTypes)) { | ||
throw new Error(HOSTED_FIELDS_CHILDREN_ERROR); | ||
} | ||
}; | ||
/** | ||
* Check if we don't have duplicate children types | ||
* | ||
* @param registerTypes the list of all the children types pass to the parent | ||
* @throw an @type {Error} when duplicate types was found | ||
*/ | ||
var notDuplicateChildren = function (registerTypes) { | ||
if (registerTypes.length !== new Set(registerTypes).size) { | ||
throw new Error(HOSTED_FIELDS_DUPLICATE_CHILDREN_ERROR); | ||
} | ||
}; | ||
/** | ||
* Validate the hosted fields children past to the PayPalHostedFieldsProvider component | ||
* These are the rule: | ||
* 1- We need to find 3 default children type [[number, expiration, cvv] | ||
* 2- We cannot find duplicate children type | ||
* 3- We cannot find expirationDate field combine with expirationMonth and expirationYear | ||
* | ||
* @param childrenList the list of children | ||
* @param requiredChildren the list with required children [number, expiration, cvv] | ||
*/ | ||
var validateHostedFieldChildren = function (childrenList) { | ||
var registerTypes = getPayPalHostedFieldChildren(childrenList); | ||
hasDefaultChildren(registerTypes); | ||
notDuplicateChildren(registerTypes); | ||
}; | ||
/** | ||
This `<PayPalHostedFieldsProvider />` provider component wraps the form field elements and accepts props like `createOrder()`. | ||
This provider component is designed to be used with the `<PayPalHostedField />` component. | ||
*/ | ||
var PayPalHostedFieldsProvider = function (_a) { | ||
var styles = _a.styles, createOrder = _a.createOrder, notEligibleError = _a.notEligibleError, children = _a.children; | ||
var childrenList = React.Children.toArray(children); | ||
var _b = useScriptProviderContext()[0], options = _b.options, loadingStatus = _b.loadingStatus; | ||
var _c = React.useState(true), isEligible = _c[0], setIsEligible = _c[1]; | ||
var _d = React.useState(null), cardFields = _d[0], setCardFields = _d[1]; | ||
var hostedFieldsContainerRef = React.useRef(null); | ||
var hostedFields = React.useRef(); | ||
var _e = React.useState(null), setErrorState = _e[1]; | ||
/** | ||
* Executed on the mount process to validate the children | ||
*/ | ||
React.useEffect(function () { | ||
validateHostedFieldChildren(childrenList); | ||
}, []); // eslint-disable-line react-hooks/exhaustive-deps | ||
React.useEffect(function () { | ||
var _a; | ||
var _b; | ||
// Only render the hosted fields when script is loaded and hostedFields is eligible | ||
if (!(loadingStatus === exports.SCRIPT_LOADING_STATE.RESOLVED)) | ||
return; | ||
// Get the hosted fields from the [window.paypal.HostedFields] SDK | ||
if (!hostedFields.current) { | ||
// Set HostedFields SDK in the mount process only | ||
hostedFields.current = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]).HostedFields; | ||
if (!hostedFields.current) { | ||
throwMissingHostedFieldsError((_a = { | ||
components: options.components | ||
}, | ||
_a[DATA_NAMESPACE] = options[DATA_NAMESPACE], | ||
_a)); | ||
} | ||
} | ||
if (!((_b = hostedFields === null || hostedFields === void 0 ? void 0 : hostedFields.current) === null || _b === void 0 ? void 0 : _b.isEligible())) { | ||
return setIsEligible(false); | ||
} | ||
// Clean all the fields before the rerender | ||
if (cardFields) { | ||
cardFields.teardown(); | ||
} | ||
hostedFields.current | ||
.render({ | ||
// Call your server to set up the transaction | ||
createOrder: createOrder, | ||
styles: styles, | ||
fields: generateHostedFieldsFromChildren(childrenList), | ||
}) | ||
.then(function (cardFieldsInstance) { | ||
setCardFields(cardFieldsInstance); | ||
}) | ||
.catch(function (err) { | ||
setErrorState(function () { | ||
throw new Error("Failed to render <PayPalHostedFieldsProvider /> component. " + err); | ||
}); | ||
}); | ||
}, [loadingStatus, styles]); // eslint-disable-line react-hooks/exhaustive-deps | ||
return (React__default["default"].createElement("div", { ref: hostedFieldsContainerRef }, isEligible ? (React__default["default"].createElement(PayPalHostedFieldsContext.Provider, { value: cardFields }, children)) : (notEligibleError))); | ||
}; | ||
/** | ||
This `<PayPalHostedField />` component renders individual fields for [Hosted Fields](https://developer.paypal.com/docs/business/checkout/advanced-card-payments/integrate#3-add-javascript-sdk-and-card-form) integrations. | ||
It relies on the `<PayPalHostedFieldsProvider />` parent component for managing state related to loading the JS SDK script | ||
and execute some validations before the rendering the fields. | ||
Use props for customizing your hosted fields. For example, here's how you would use the `style`, `className`, `id` options: | ||
```jsx | ||
import { | ||
PayPalScriptProvider, | ||
PayPalHostedFieldsProvider, | ||
PayPalHostedField | ||
} from "@paypal/react-paypal-js"; | ||
<PayPalScriptProvider options={{ "client-id": "test" }}> | ||
<PayPalHostedFieldsProvider | ||
createOrder={() => { | ||
// Manually call your server endpoint to create the client order | ||
return fetch("create_order_endpoint") | ||
.then(response => response.json()) | ||
.then(order => order.id) | ||
.catch(err => { | ||
// Handle exceptions | ||
}) | ||
}} | ||
> | ||
<PayPalHostedField style={{ color: "red", border: "1px solid" }} | ||
id="card-number" | ||
hostedFieldType="number" | ||
options={{ selector: "#card-number", placeholder: "4111 1111 1111 1111" }} /> | ||
<PayPalHostedField id="cvv" | ||
hostedFieldType="cvv" | ||
options={{ selector: "#cvv", placeholder: "CVV", maxlength: 3, maskInput: true }} /> | ||
<PayPalHostedField id="expiration-date" | ||
hostedFieldType="expirationDate" | ||
options={{ selector: "#expiration-date", placeholder: "MM/YY" }} /> | ||
</PayPalHostedFieldsProvider> | ||
</PayPalScriptProvider> | ||
``` | ||
To use the PayPal hosted fields you need to define at least three fields: | ||
- A card number field | ||
- The CVV code from the client card | ||
- The expiration date | ||
You can define the expiration date as a single field similar to the example above, | ||
or you are able to define it in two separate fields. One for the month and second for year. | ||
You can delete the last children component form the example above and use these: | ||
```jsx | ||
<PayPalHostedField id="expiration-month" | ||
hostedFieldType={PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_MONTH} | ||
options={{ selector: "#expiration-month", placeholder: "MM" }} /> | ||
<PayPalHostedField id="expiration-year" | ||
hostedFieldType={PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_YEAR} | ||
options={{ selector: "#expiration-year", placeholder: "YYYY" }} /> | ||
``` | ||
Note: Take care when using multiple instances of the PayPal Hosted Fields on the same page. | ||
The component will fail to render when any of the selectors return more than one element. | ||
*/ | ||
var PayPalHostedField = function (_a) { | ||
_a.hostedFieldType; // eslint-disable-line @typescript-eslint/no-unused-vars | ||
_a.options; // eslint-disable-line @typescript-eslint/no-unused-vars | ||
var props = __rest(_a, ["hostedFieldType", "options"]); | ||
return React__default["default"].createElement("div", __assign({}, props)); | ||
}; | ||
var FUNDING$1 = { | ||
@@ -885,2 +1191,4 @@ PAYPAL: 'paypal', | ||
exports.PayPalButtons = PayPalButtons; | ||
exports.PayPalHostedField = PayPalHostedField; | ||
exports.PayPalHostedFieldsProvider = PayPalHostedFieldsProvider; | ||
exports.PayPalMarks = PayPalMarks; | ||
@@ -893,2 +1201,4 @@ exports.PayPalMessages = PayPalMessages; | ||
exports.scriptReducer = scriptReducer; | ||
exports.usePayPalHostedFields = usePayPalHostedFields; | ||
exports.usePayPalScriptReducer = usePayPalScriptReducer; | ||
exports.useScriptProviderContext = useScriptProviderContext; |
/*! | ||
* react-paypal-js v7.3.3 (2021-08-31T21:55:23.426Z) | ||
* react-paypal-js v7.4.0 (2021-10-08T14:28:13.235Z) | ||
* Copyright 2020-present, PayPal, Inc. All rights reserved. | ||
@@ -17,2 +17,2 @@ * | ||
*/ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r,n,o=t(e);exports.SCRIPT_LOADING_STATE=void 0,(r=exports.SCRIPT_LOADING_STATE||(exports.SCRIPT_LOADING_STATE={})).INITIAL="initial",r.PENDING="pending",r.REJECTED="rejected",r.RESOLVED="resolved",exports.DISPATCH_ACTION=void 0,(n=exports.DISPATCH_ACTION||(exports.DISPATCH_ACTION={})).LOADING_STATUS="setLoadingStatus",n.RESET_OPTIONS="resetOptions",n.SET_BRAINTREE_INSTANCE="braintreeInstance";var a="data-react-paypal-script-id",i=function(){return(i=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function s(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]])}return r}function u(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||t)}function c(e){return void 0===e&&(e="paypal"),window[e]}function l(e){return"react-paypal-js-"+function(e){for(var t="",r=0;r<e.length;r++){var n=e[r].charCodeAt(0)*r;e[r+1]&&(n+=e[r+1].charCodeAt(0)*(r-1)),t+=String.fromCharCode(97+Math.abs(n)%26)}return t}(JSON.stringify(e))}function d(e){var t=self.document.querySelector("script["+a+'="'+e+'"]');null!=t&&t.parentNode&&t.parentNode.removeChild(t)}function p(e,t){var r;switch(t.type){case exports.DISPATCH_ACTION.LOADING_STATUS:return i(i({},e),{loadingStatus:t.value});case exports.DISPATCH_ACTION.RESET_OPTIONS:return d(e.options[a]),delete t.value[a],i(i({},e),{loadingStatus:exports.SCRIPT_LOADING_STATE.PENDING,options:i(i({},t.value),(r={},r[a]=""+l(t.value),r["data-sdk-integration-source"]="react-paypal-js",r))});case exports.DISPATCH_ACTION.SET_BRAINTREE_INSTANCE:return i(i({},e),{braintreePayPalCheckoutInstance:t.value});default:return e}}var f=e.createContext(null);function v(e){if("function"!=typeof(null==e?void 0:e.dispatch))throw new Error("usePayPalScriptReducer must be used within a PayPalScriptProvider");return e}function P(){var t=v(e.useContext(f));return[i(i({},t),{isInitial:t.loadingStatus===exports.SCRIPT_LOADING_STATE.INITIAL,isPending:t.loadingStatus===exports.SCRIPT_LOADING_STATE.PENDING,isResolved:t.loadingStatus===exports.SCRIPT_LOADING_STATE.RESOLVED,isRejected:t.loadingStatus===exports.SCRIPT_LOADING_STATE.REJECTED}),t.dispatch]}var S=function(t){var r=t.className,n=void 0===r?"":r,a=t.disabled,l=void 0!==a&&a,d=t.children,p=void 0===d?null:d,f=t.forceReRender,v=void 0===f?[]:f,S=s(t,["className","disabled","children","forceReRender"]),T=e.useRef(null),A=e.useRef(null),E=P()[0],h=E.isResolved,y=E.options,I=e.useState(null),m=I[0],N=I[1],b=e.useState(!0),O=b[0],R=b[1],g=e.useState(null)[1];function w(){null!==A.current&&A.current.close().catch((function(){}))}e.useEffect((function(){if(!1===h)return w;var e=c(y["data-namespace"]);if(void 0===e||void 0===e.Buttons)return g((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalButtons /> because window."+(void 0===n?"paypal":n)+".Buttons is undefined.";if(r.length&&!r.includes("buttons")){o+="\nTo fix the issue, add 'buttons' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r+",buttons")+"'}}>`."}return o}(y))})),w;try{A.current=e.Buttons(i(i({},S),{onInit:function(e,t){N(t),"function"==typeof S.onInit&&S.onInit(e,t)}}))}catch(e){return g((function(){throw new Error("Failed to render <PayPalButtons /> component. Failed to initialize: "+e)}))}return!1===A.current.isEligible()?(R(!1),w):(null===T.current||A.current.render(T.current).catch((function(e){null!==T.current&&0!==T.current.children.length&&g((function(){throw new Error("Failed to render <PayPalButtons /> component. "+e)}))})),w)}),u(u([h],v),[S.fundingSource])),e.useEffect((function(){null!==m&&(!0===l?m.disable().catch((function(){})):m.enable().catch((function(){})))}),[l,m]);var C=l?{opacity:.38}:{},_=(n+" "+(l?"paypal-buttons-disabled":"")).trim();return!1===O?p:o.default.createElement("div",{ref:T,style:C,className:_})};function T(e){var t="https://www.paypal.com/sdk/js";e.sdkBaseURL&&(t=e.sdkBaseURL,delete e.sdkBaseURL);var r=function(e,t){var r="",n="";Array.isArray(e)?e.length>1?(r="*",n=e.toString()):r=e.toString():"string"==typeof e&&e.length>0?r=e:"string"==typeof t&&t.length>0&&(r="*",n=t);return{"merchant-id":r,"data-merchant-id":n}}(e["merchant-id"],e["data-merchant-id"]),n=Object.assign({},e,r),o=Object.keys(n).filter((function(e){return void 0!==n[e]&&null!==n[e]&&""!==n[e]})).reduce((function(e,t){var r=n[t].toString();return"data-"===t.substring(0,5)?e.dataAttributes[t]=r:e.queryParams[t]=r,e}),{queryParams:{},dataAttributes:{}}),a=o.queryParams,i=o.dataAttributes;return{url:t+"?"+A(a),dataAttributes:i}}function A(e){var t="";return Object.keys(e).forEach((function(r){0!==t.length&&(t+="&"),t+=r+"="+e[r]})),t}function E(e,t){void 0===t&&(t={});var r=document.createElement("script");return r.src=e,Object.keys(t).forEach((function(e){r.setAttribute(e,t[e]),"data-csp-nonce"===e&&r.setAttribute("nonce",t["data-csp-nonce"])})),r}function h(e,t){if(void 0===t&&(t=I()),N(e,t),"undefined"==typeof window)return t.resolve(null);var r=T(e),n=r.url,o=r.dataAttributes,a=o["data-namespace"]||"paypal",i=m(a);return function(e,t){var r=document.querySelector('script[src="'+e+'"]');if(null===r)return null;var n=E(e,t),o=Object.assign({},r.dataset);if(delete o.uidAuto,Object.keys(o).length!==Object.keys(n.dataset).length)return null;var a=!0;return Object.keys(o).forEach((function(e){o[e]!==n.dataset[e]&&(a=!1)})),a?r:null}(n,o)&&i?t.resolve(i):y({url:n,attributes:o},t).then((function(){var e=m(a);if(e)return e;throw new Error("The window."+a+" global variable is not available.")}))}function y(e,t){void 0===t&&(t=I()),N(e,t);var r=e.url,n=e.attributes;if("string"!=typeof r||0===r.length)throw new Error("Invalid url.");if(void 0!==n&&"object"!=typeof n)throw new Error("Expected attributes to be an object.");return new t((function(e,t){if("undefined"==typeof window)return e();!function(e){var t=e.url,r=e.attributes,n=e.onSuccess,o=e.onError,a=E(t,r);a.onerror=o,a.onload=n,document.head.insertBefore(a,document.head.firstElementChild)}({url:r,attributes:n,onSuccess:function(){return e()},onError:function(){return t(new Error('The script "'+r+'" failed to load.'))}})}))}function I(){if("undefined"==typeof Promise)throw new Error("Promise is undefined. To resolve the issue, use a Promise polyfill.");return Promise}function m(e){return window[e]}function N(e,t){if("object"!=typeof e||null===e)throw new Error("Expected an options object.");if(void 0!==t&&"function"!=typeof t)throw new Error("Expected PromisePonyfill to be a function.")}function b(){var t=function(e){var t;if(!(null===(t=null==e?void 0:e.options)||void 0===t?void 0:t["data-client-token"]))throw new Error("A client token wasn't found in the provider parent component");return e}(v(e.useContext(f)));return[t,t.dispatch]}var O=function(e,t){return function(e,t){if("function"==typeof e.createOrder){var r=e.createOrder;e.createOrder=function(e,n){return r(e,i(i({},n),{braintree:t}))}}}(e,t),function(e,t){if("function"==typeof e.onApprove){var r=e.onApprove;e.onApprove=function(e,n){return r(e,i(i({},n),{braintree:t}))}}}(e,t),i({},e)};var R={PAYPAL:"paypal",VENMO:"venmo",APPLEPAY:"applepay",ITAU:"itau",CREDIT:"credit",PAYLATER:"paylater",CARD:"card",IDEAL:"ideal",SEPA:"sepa",BANCONTACT:"bancontact",GIROPAY:"giropay",SOFORT:"sofort",EPS:"eps",MYBANK:"mybank",P24:"p24",VERKKOPANKKI:"verkkopankki",PAYU:"payu",BLIK:"blik",TRUSTLY:"trustly",ZIMPLER:"zimpler",MAXIMA:"maxima",OXXO:"oxxo",BOLETO:"boleto",WECHATPAY:"wechatpay",MERCADOPAGO:"mercadopago"};exports.BraintreePayPalButtons=function(t){var r=t.className,n=void 0===r?"":r,a=t.disabled,u=void 0!==a&&a,c=t.children,l=void 0===c?null:c,d=t.forceReRender,p=void 0===d?[]:d,f=s(t,["className","disabled","children","forceReRender"]),v=e.useState(null)[1],P=b(),T=P[0],A=P[1];return e.useEffect((function(){Promise.all([y({url:"https://js.braintreegateway.com/web/3.81.0/js/client.min.js"}),y({url:"https://js.braintreegateway.com/web/3.81.0/js/paypal-checkout.min.js"})]).then((function(){var e,t=T.options["data-client-token"],r=(void 0===e&&(e="braintree"),window[e]);return r.client.create({authorization:t}).then((function(e){return r.paypalCheckout.create({client:e})})).then((function(e){A({type:exports.DISPATCH_ACTION.SET_BRAINTREE_INSTANCE,value:e})}))})).catch((function(e){v((function(){throw new Error("An error occurred when loading the Braintree scripts: "+e)}))}))}),[T.options,A]),o.default.createElement(o.default.Fragment,null,T.braintreePayPalCheckoutInstance&&o.default.createElement(S,i({className:n,disabled:u,forceReRender:p},O(f,T.braintreePayPalCheckoutInstance)),l))},exports.FUNDING=R,exports.PayPalButtons=S,exports.PayPalMarks=function(t){var r=t.className,n=void 0===r?"":r,a=s(t,["className"]),u=P()[0],l=u.isResolved,d=u.options,p=e.useRef(null),f=e.useRef(null),v=e.useState(null)[1];return e.useEffect((function(){if(!1!==l&&null===f.current){var e=c(d["data-namespace"]);void 0!==e&&void 0!==e.Marks?(f.current=e.Marks(i({},a)),!1!==f.current.isEligible()&&null!==p.current&&f.current.render(p.current).catch((function(e){null!==p.current&&0!==p.current.children.length&&v((function(){throw new Error("Failed to render <PayPalMarks /> component. "+e)}))}))):v((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalMarks /> because window."+(void 0===n?"paypal":n)+".Marks is undefined.";if(!r.includes("marks")){o+="\nTo fix the issue, add 'marks' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r?r+",marks":"marks")+"'}}>`."}return o}(d))}))}}),[l,a.fundingSource]),o.default.createElement("div",{ref:p,className:n})},exports.PayPalMessages=function(t){var r=t.className,n=void 0===r?"":r,a=t.forceReRender,l=void 0===a?[]:a,d=s(t,["className","forceReRender"]),p=P()[0],f=p.isResolved,v=p.options,S=e.useRef(null),T=e.useRef(null),A=e.useState(null)[1];return e.useEffect((function(){if(!1!==f){var e=c(v["data-namespace"]);void 0!==e&&void 0!==e.Messages?(T.current=e.Messages(i({},d)),null!==S.current&&T.current.render(S.current).catch((function(e){null!==S.current&&0!==S.current.children.length&&A((function(){throw new Error("Failed to render <PayPalMessages /> component. "+e)}))}))):A((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalMessages /> because window."+(void 0===n?"paypal":n)+".Messages is undefined.";if(!r.includes("messages")){o+="\nTo fix the issue, add 'messages' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r?r+",messages":"messages")+"'}}>`."}return o}(v))}))}}),u([f],l)),o.default.createElement("div",{ref:S,className:n})},exports.PayPalScriptProvider=function(t){var r,n=t.options,s=void 0===n?{"client-id":"test"}:n,u=t.children,c=t.deferLoading,d=void 0!==c&&c,v=e.useReducer(p,{options:i(i({},s),(r={},r[a]=""+l(s),r["data-sdk-integration-source"]="react-paypal-js",r)),loadingStatus:d?exports.SCRIPT_LOADING_STATE.INITIAL:exports.SCRIPT_LOADING_STATE.PENDING,dispatch:null}),P=v[0],S=v[1];return e.useEffect((function(){if(!1===d&&P.loadingStatus===exports.SCRIPT_LOADING_STATE.INITIAL)return S({type:exports.DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.PENDING});if(P.loadingStatus===exports.SCRIPT_LOADING_STATE.PENDING){var e=!0;return h(P.options).then((function(){e&&S({type:exports.DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.RESOLVED})})).catch((function(){e&&S({type:exports.DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.REJECTED})})),function(){e=!1}}}),[P.options,d,P.loadingStatus]),o.default.createElement(f.Provider,{value:i(i({},P),{dispatch:S})},u)},exports.ScriptContext=f,exports.destroySDKScript=d,exports.getScriptID=l,exports.scriptReducer=p,exports.usePayPalScriptReducer=P; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r,n,o,a=t(e);exports.SCRIPT_LOADING_STATE=void 0,(r=exports.SCRIPT_LOADING_STATE||(exports.SCRIPT_LOADING_STATE={})).INITIAL="initial",r.PENDING="pending",r.REJECTED="rejected",r.RESOLVED="resolved",exports.SCRIPT_PROVIDER_DISPATCH_ACTION=void 0,(n=exports.SCRIPT_PROVIDER_DISPATCH_ACTION||(exports.SCRIPT_PROVIDER_DISPATCH_ACTION={})).LOADING_STATUS="setLoadingStatus",n.RESET_OPTIONS="resetOptions",n.SET_BRAINTREE_INSTANCE="braintreeInstance",exports.PAYPAL_HOSTED_FIELDS_TYPES=void 0,(o=exports.PAYPAL_HOSTED_FIELDS_TYPES||(exports.PAYPAL_HOSTED_FIELDS_TYPES={})).NUMBER="number",o.CVV="cvv",o.EXPIRATION_DATE="expirationDate",o.EXPIRATION_MONTH="expirationMonth",o.EXPIRATION_YEAR="expirationYear",o.POSTAL_CODE="postalCode";var i="data-react-paypal-script-id",s=function(){return(s=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function u(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]])}return r}function c(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}function l(e){return void 0===e&&(e="paypal"),window[e]}function d(e){return"react-paypal-js-"+function(e){for(var t="",r=0;r<e.length;r++){var n=e[r].charCodeAt(0)*r;e[r+1]&&(n+=e[r+1].charCodeAt(0)*(r-1)),t+=String.fromCharCode(97+Math.abs(n)%26)}return t}(JSON.stringify(e))}function p(e){var t=self.document.querySelector("script["+i+'="'+e+'"]');(null==t?void 0:t.parentNode)&&t.parentNode.removeChild(t)}function f(e,t){var r;switch(t.type){case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS:return s(s({},e),{loadingStatus:t.value});case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.RESET_OPTIONS:return p(e.options[i]),delete t.value[i],s(s({},e),{loadingStatus:exports.SCRIPT_LOADING_STATE.PENDING,options:s(s({},t.value),(r={},r[i]=""+d(t.value),r["data-sdk-integration-source"]="react-paypal-js",r))});case exports.SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE:return s(s({},e),{braintreePayPalCheckoutInstance:t.value});default:return e}}var P=e.createContext(null);function E(e){if("function"==typeof(null==e?void 0:e.dispatch)&&0!==e.dispatch.length)return e;throw new Error("usePayPalScriptReducer must be used within a PayPalScriptProvider")}function S(){var t=E(e.useContext(P));return[s(s({},t),{isInitial:t.loadingStatus===exports.SCRIPT_LOADING_STATE.INITIAL,isPending:t.loadingStatus===exports.SCRIPT_LOADING_STATE.PENDING,isResolved:t.loadingStatus===exports.SCRIPT_LOADING_STATE.RESOLVED,isRejected:t.loadingStatus===exports.SCRIPT_LOADING_STATE.REJECTED}),t.dispatch]}function T(){var t=function(e){var t;if(!(null===(t=null==e?void 0:e.options)||void 0===t?void 0:t["data-client-token"]))throw new Error("A client token wasn't found in the provider parent component");return e}(E(e.useContext(P)));return[t,t.dispatch]}var v=e.createContext(null);var I=function(t){var r=t.className,n=void 0===r?"":r,o=t.disabled,i=void 0!==o&&o,d=t.children,p=t.forceReRender,f=void 0===p?[]:p,P=u(t,["className","disabled","children","forceReRender"]),E=i?{opacity:.38}:{},T=(n+" "+(i?"paypal-buttons-disabled":"")).trim(),v=e.useRef(null),I=e.useRef(null),h=S()[0],A=h.isResolved,y=h.options,m=e.useState(null),R=m[0],_=m[1],O=e.useState(!0),N=O[0],C=O[1],b=e.useState(null)[1];function D(){null!==I.current&&I.current.close().catch((function(){}))}return e.useEffect((function(){if(!1===A)return D;var e=l(y["data-namespace"]);if(void 0===e||void 0===e.Buttons)return b((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalButtons /> because window."+(void 0===n?"paypal":n)+".Buttons is undefined.";if(r.length&&!r.includes("buttons")){o+="\nTo fix the issue, add 'buttons' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r+",buttons")+"'}}>`."}return o}(y))})),D;try{I.current=e.Buttons(s(s({},P),{onInit:function(e,t){_(t),"function"==typeof P.onInit&&P.onInit(e,t)}}))}catch(e){return b((function(){throw new Error("Failed to render <PayPalButtons /> component. Failed to initialize: "+e)}))}return!1===I.current.isEligible()?(C(!1),D):v.current?(I.current.render(v.current).catch((function(e){null!==v.current&&0!==v.current.children.length&&b((function(){throw new Error("Failed to render <PayPalButtons /> component. "+e)}))})),D):D}),c(c([A],f,!0),[P.fundingSource],!1)),e.useEffect((function(){null!==R&&(!0===i?R.disable().catch((function(){})):R.enable().catch((function(){})))}),[i,R]),a.default.createElement(a.default.Fragment,null,N?a.default.createElement("div",{ref:v,style:E,className:T}):d)};function h(e){var t="https://www.paypal.com/sdk/js";e.sdkBaseURL&&(t=e.sdkBaseURL,delete e.sdkBaseURL);var r=function(e,t){var r="",n="";Array.isArray(e)?e.length>1?(r="*",n=e.toString()):r=e.toString():"string"==typeof e&&e.length>0?r=e:"string"==typeof t&&t.length>0&&(r="*",n=t);return{"merchant-id":r,"data-merchant-id":n}}(e["merchant-id"],e["data-merchant-id"]),n=Object.assign({},e,r),o=Object.keys(n).filter((function(e){return void 0!==n[e]&&null!==n[e]&&""!==n[e]})).reduce((function(e,t){var r=n[t].toString();return"data-"===t.substring(0,5)?e.dataAttributes[t]=r:e.queryParams[t]=r,e}),{queryParams:{},dataAttributes:{}}),a=o.queryParams,i=o.dataAttributes;return{url:t+"?"+A(a),dataAttributes:i}}function A(e){var t="";return Object.keys(e).forEach((function(r){0!==t.length&&(t+="&"),t+=r+"="+e[r]})),t}function y(e,t){void 0===t&&(t={});var r=document.createElement("script");return r.src=e,Object.keys(t).forEach((function(e){r.setAttribute(e,t[e]),"data-csp-nonce"===e&&r.setAttribute("nonce",t["data-csp-nonce"])})),r}function m(e,t){if(void 0===t&&(t=_()),N(e,t),"undefined"==typeof window)return t.resolve(null);var r=h(e),n=r.url,o=r.dataAttributes,a=o["data-namespace"]||"paypal",i=O(a);return function(e,t){var r=document.querySelector('script[src="'+e+'"]');if(null===r)return null;var n=y(e,t),o=Object.assign({},r.dataset);if(delete o.uidAuto,Object.keys(o).length!==Object.keys(n.dataset).length)return null;var a=!0;return Object.keys(o).forEach((function(e){o[e]!==n.dataset[e]&&(a=!1)})),a?r:null}(n,o)&&i?t.resolve(i):R({url:n,attributes:o},t).then((function(){var e=O(a);if(e)return e;throw new Error("The window."+a+" global variable is not available.")}))}function R(e,t){void 0===t&&(t=_()),N(e,t);var r=e.url,n=e.attributes;if("string"!=typeof r||0===r.length)throw new Error("Invalid url.");if(void 0!==n&&"object"!=typeof n)throw new Error("Expected attributes to be an object.");return new t((function(e,t){if("undefined"==typeof window)return e();!function(e){var t=e.url,r=e.attributes,n=e.onSuccess,o=e.onError,a=y(t,r);a.onerror=o,a.onload=n,document.head.insertBefore(a,document.head.firstElementChild)}({url:r,attributes:n,onSuccess:function(){return e()},onError:function(){return t(new Error('The script "'+r+'" failed to load.'))}})}))}function _(){if("undefined"==typeof Promise)throw new Error("Promise is undefined. To resolve the issue, use a Promise polyfill.");return Promise}function O(e){return window[e]}function N(e,t){if("object"!=typeof e||null===e)throw new Error("Expected an options object.");if(void 0!==t&&"function"!=typeof t)throw new Error("Expected PromisePonyfill to be a function.")}var C=function(e,t){return function(e,t){if("function"==typeof e.createOrder){var r=e.createOrder;e.createOrder=function(e,n){return r(e,s(s({},n),{braintree:t}))}}}(e,t),function(e,t){if("function"==typeof e.onApprove){var r=e.onApprove;e.onApprove=function(e,n){return r(e,s(s({},n),{braintree:t}))}}}(e,t),s({},e)};var b=function(e){return e.reduce((function(e,t){var r=t.props,n=r.hostedFieldType,o=r.options;return Object.values(exports.PAYPAL_HOSTED_FIELDS_TYPES).includes(n)&&(e[n]={selector:o.selector,placeholder:o.placeholder,type:o.type,formatInput:o.formatInput,maskInput:o.maskInput,select:o.select,maxlength:o.maxlength,minlength:o.minlength,prefill:o.prefill,rejectUnsupportedCards:o.rejectUnsupportedCards}),e}),{})},D=function(e){if(!e.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.NUMBER)||!e.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.CVV)||function(e){return!e.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_DATE)&&!e.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_MONTH)&&!e.includes(exports.PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_YEAR)}(e))throw new Error("To use HostedFields you must use it with at least 3 children with types: [number, cvv, expirationDate] includes")},w=function(e){var t=function(e){return e.reduce((function(e,t){var r=t;return r.props.hostedFieldType&&e.push(r.props.hostedFieldType),e}),[])}(e);D(t),function(e){if(e.length!==new Set(e).size)throw new Error("Cannot use duplicate HostedFields as children")}(t)},g={PAYPAL:"paypal",VENMO:"venmo",APPLEPAY:"applepay",ITAU:"itau",CREDIT:"credit",PAYLATER:"paylater",CARD:"card",IDEAL:"ideal",SEPA:"sepa",BANCONTACT:"bancontact",GIROPAY:"giropay",SOFORT:"sofort",EPS:"eps",MYBANK:"mybank",P24:"p24",VERKKOPANKKI:"verkkopankki",PAYU:"payu",BLIK:"blik",TRUSTLY:"trustly",ZIMPLER:"zimpler",MAXIMA:"maxima",OXXO:"oxxo",BOLETO:"boleto",WECHATPAY:"wechatpay",MERCADOPAGO:"mercadopago"};exports.BraintreePayPalButtons=function(t){var r=t.className,n=void 0===r?"":r,o=t.disabled,i=void 0!==o&&o,c=t.children,l=t.forceReRender,d=void 0===l?[]:l,p=u(t,["className","disabled","children","forceReRender"]),f=e.useState(null)[1],P=T(),E=P[0],S=P[1];return e.useEffect((function(){Promise.all([R({url:"https://js.braintreegateway.com/web/3.81.0/js/client.min.js"}),R({url:"https://js.braintreegateway.com/web/3.81.0/js/paypal-checkout.min.js"})]).then((function(){var e,t=E.options["data-client-token"],r=(void 0===e&&(e="braintree"),window[e]);return r.client.create({authorization:t}).then((function(e){return r.paypalCheckout.create({client:e})})).then((function(e){S({type:exports.SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE,value:e})}))})).catch((function(e){f((function(){throw new Error("An error occurred when loading the Braintree scripts: "+e)}))}))}),[E.options,S]),a.default.createElement(a.default.Fragment,null,E.braintreePayPalCheckoutInstance&&a.default.createElement(I,s({className:n,disabled:i,forceReRender:d},C(p,E.braintreePayPalCheckoutInstance)),c))},exports.FUNDING=g,exports.PayPalButtons=I,exports.PayPalHostedField=function(e){e.hostedFieldType,e.options;var t=u(e,["hostedFieldType","options"]);return a.default.createElement("div",s({},t))},exports.PayPalHostedFieldsProvider=function(t){var r=t.styles,n=t.createOrder,o=t.notEligibleError,i=t.children,s=e.Children.toArray(i),u=T()[0],c=u.options,d=u.loadingStatus,p=e.useState(!0),f=p[0],P=p[1],E=e.useState(null),S=E[0],I=E[1],h=e.useRef(null),A=e.useRef(),y=e.useState(null)[1];return e.useEffect((function(){w(s)}),[]),e.useEffect((function(){var e,t;if(d===exports.SCRIPT_LOADING_STATE.RESOLVED){if(A.current||(A.current=l(c["data-namespace"]).HostedFields,A.current||function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o=r?r+",hosted-fields":"hosted-fields",a="Unable to render <PayPalHostedFieldsProvider /> because window."+(void 0===n?"paypal":n)+".HostedFields is undefined.";throw r.includes("hosted-fields")||(a+="\nTo fix the issue, add 'hosted-fields' to the list of components passed to the parent PayPalScriptProvider: <PayPalScriptProvider options={{ components: '"+o+"'}}>"),new Error(a)}(((e={components:c.components})["data-namespace"]=c["data-namespace"],e))),!(null===(t=null==A?void 0:A.current)||void 0===t?void 0:t.isEligible()))return P(!1);S&&S.teardown(),A.current.render({createOrder:n,styles:r,fields:b(s)}).then((function(e){I(e)})).catch((function(e){y((function(){throw new Error("Failed to render <PayPalHostedFieldsProvider /> component. "+e)}))}))}}),[d,r]),a.default.createElement("div",{ref:h},f?a.default.createElement(v.Provider,{value:S},i):o)},exports.PayPalMarks=function(t){var r=t.className,n=void 0===r?"":r,o=t.children,i=u(t,["className","children"]),c=S()[0],d=c.isResolved,p=c.options,f=e.useRef(null),P=e.useState(!0),E=P[0],T=P[1],v=e.useState(null)[1];return e.useEffect((function(){if(!1!==d){var e=l(p["data-namespace"]);void 0!==e&&void 0!==e.Marks?function(e){var t=f.current;if(!t||!e.isEligible())return T(!1);t.firstChild&&t.removeChild(t.firstChild),e.render(t).catch((function(e){null!==t&&0!==t.children.length&&v((function(){throw new Error("Failed to render <PayPalMarks /> component. "+e)}))}))}(e.Marks(s({},i))):v((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalMarks /> because window."+(void 0===n?"paypal":n)+".Marks is undefined.";if(!r.includes("marks")){o+="\nTo fix the issue, add 'marks' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r?r+",marks":"marks")+"'}}>`."}return o}(p))}))}}),[d,i.fundingSource]),a.default.createElement(a.default.Fragment,null,E?a.default.createElement("div",{ref:f,className:n}):o)},exports.PayPalMessages=function(t){var r=t.className,n=void 0===r?"":r,o=t.forceReRender,i=void 0===o?[]:o,d=u(t,["className","forceReRender"]),p=S()[0],f=p.isResolved,P=p.options,E=e.useRef(null),T=e.useRef(null),v=e.useState(null)[1];return e.useEffect((function(){if(!1!==f){var e=l(P["data-namespace"]);void 0!==e&&void 0!==e.Messages?(T.current=e.Messages(s({},d)),null!==E.current&&T.current.render(E.current).catch((function(e){null!==E.current&&0!==E.current.children.length&&v((function(){throw new Error("Failed to render <PayPalMessages /> component. "+e)}))}))):v((function(){throw new Error(function(e){var t=e.components,r=void 0===t?"":t,n=e["data-namespace"],o="Unable to render <PayPalMessages /> because window."+(void 0===n?"paypal":n)+".Messages is undefined.";if(!r.includes("messages")){o+="\nTo fix the issue, add 'messages' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(r?r+",messages":"messages")+"'}}>`."}return o}(P))}))}}),c([f],i,!0)),a.default.createElement("div",{ref:E,className:n})},exports.PayPalScriptProvider=function(t){var r,n=t.options,o=void 0===n?{"client-id":"test"}:n,u=t.children,c=t.deferLoading,l=void 0!==c&&c,p=e.useReducer(f,{options:s(s({},o),(r={},r[i]=""+d(o),r["data-sdk-integration-source"]="react-paypal-js",r)),loadingStatus:l?exports.SCRIPT_LOADING_STATE.INITIAL:exports.SCRIPT_LOADING_STATE.PENDING}),E=p[0],S=p[1];return e.useEffect((function(){if(!1===l&&E.loadingStatus===exports.SCRIPT_LOADING_STATE.INITIAL)return S({type:exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.PENDING});if(E.loadingStatus===exports.SCRIPT_LOADING_STATE.PENDING){var e=!0;return m(E.options).then((function(){e&&S({type:exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.RESOLVED})})).catch((function(){e&&S({type:exports.SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS,value:exports.SCRIPT_LOADING_STATE.REJECTED})})),function(){e=!1}}}),[E.options,l,E.loadingStatus]),a.default.createElement(P.Provider,{value:s(s({},E),{dispatch:S})},u)},exports.ScriptContext=P,exports.destroySDKScript=p,exports.getScriptID=d,exports.scriptReducer=f,exports.usePayPalHostedFields=function(){return e.useContext(v)},exports.usePayPalScriptReducer=S,exports.useScriptProviderContext=T; |
/*! | ||
* react-paypal-js v7.3.3 (2021-08-31T21:55:23.426Z) | ||
* react-paypal-js v7.4.0 (2021-10-08T14:28:13.235Z) | ||
* Copyright 2020-present, PayPal, Inc. All rights reserved. | ||
@@ -17,3 +17,9 @@ * | ||
*/ | ||
import React, { createContext, useContext, useRef, useState, useEffect, useReducer } from 'react'; | ||
import React, { createContext, useContext, useRef, useState, useEffect, useReducer, Children } from 'react'; | ||
/** | ||
* Enum for the SDK script resolve status, | ||
* | ||
* @enum {string} | ||
*/ | ||
var SCRIPT_LOADING_STATE; | ||
@@ -27,12 +33,38 @@ | ||
})(SCRIPT_LOADING_STATE || (SCRIPT_LOADING_STATE = {})); | ||
/** | ||
* Enum for the PayPalScriptProvider context dispatch actions | ||
* | ||
* @enum {string} | ||
*/ | ||
var DISPATCH_ACTION; | ||
(function (DISPATCH_ACTION) { | ||
DISPATCH_ACTION["LOADING_STATUS"] = "setLoadingStatus"; | ||
DISPATCH_ACTION["RESET_OPTIONS"] = "resetOptions"; | ||
DISPATCH_ACTION["SET_BRAINTREE_INSTANCE"] = "braintreeInstance"; | ||
})(DISPATCH_ACTION || (DISPATCH_ACTION = {})); // Common reference to the script identifier | ||
var SCRIPT_PROVIDER_DISPATCH_ACTION; | ||
(function (SCRIPT_PROVIDER_DISPATCH_ACTION) { | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["LOADING_STATUS"] = "setLoadingStatus"; | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["RESET_OPTIONS"] = "resetOptions"; | ||
SCRIPT_PROVIDER_DISPATCH_ACTION["SET_BRAINTREE_INSTANCE"] = "braintreeInstance"; | ||
})(SCRIPT_PROVIDER_DISPATCH_ACTION || (SCRIPT_PROVIDER_DISPATCH_ACTION = {})); | ||
/** | ||
* Enum for all the available hosted fields | ||
* | ||
* @enum {string} | ||
*/ | ||
var PAYPAL_HOSTED_FIELDS_TYPES; | ||
(function (PAYPAL_HOSTED_FIELDS_TYPES) { | ||
PAYPAL_HOSTED_FIELDS_TYPES["NUMBER"] = "number"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["CVV"] = "cvv"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_DATE"] = "expirationDate"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_MONTH"] = "expirationMonth"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["EXPIRATION_YEAR"] = "expirationYear"; | ||
PAYPAL_HOSTED_FIELDS_TYPES["POSTAL_CODE"] = "postalCode"; | ||
})(PAYPAL_HOSTED_FIELDS_TYPES || (PAYPAL_HOSTED_FIELDS_TYPES = {})); | ||
/********************************************* | ||
* Common reference to the script identifier * | ||
*********************************************/ | ||
var SCRIPT_ID = "data-react-paypal-script-id"; | ||
@@ -42,11 +74,29 @@ var DATA_CLIENT_TOKEN = "data-client-token"; | ||
var DATA_SDK_INTEGRATION_SOURCE_VALUE = "react-paypal-js"; | ||
var EMPTY_PROVIDER_CONTEXT_ERROR_MESSAGE = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; | ||
var DATA_NAMESPACE = "data-namespace"; | ||
/**************************** | ||
* Braintree error messages * | ||
****************************/ | ||
var EMPTY_PROVIDER_CONTEXT_CLIENT_TOKEN_ERROR_MESSAGE = "A client token wasn't found in the provider parent component"; | ||
var braintreeVersion = "3.81.0"; | ||
var BRAINTREE_SOURCE = "https://js.braintreegateway.com/web/" + braintreeVersion + "/js/client.min.js"; | ||
var BRAINTREE_PAYPAL_CHECKOUT_SOURCE = "https://js.braintreegateway.com/web/" + braintreeVersion + "/js/paypal-checkout.min.js"; // Namespaces | ||
var BRAINTREE_PAYPAL_CHECKOUT_SOURCE = "https://js.braintreegateway.com/web/" + braintreeVersion + "/js/paypal-checkout.min.js"; | ||
/********************* | ||
* PayPal namespaces * | ||
*********************/ | ||
var DEFAULT_PAYPAL_NAMESPACE = "paypal"; | ||
var DEFAULT_BRAINTREE_NAMESPACE = "braintree"; | ||
/***************** | ||
* Hosted Fields * | ||
*****************/ | ||
var HOSTED_FIELDS_CHILDREN_ERROR = "To use HostedFields you must use it with at least 3 children with types: [number, cvv, expirationDate] includes"; | ||
var HOSTED_FIELDS_DUPLICATE_CHILDREN_ERROR = "Cannot use duplicate HostedFields as children"; | ||
/******************* | ||
* Script Provider * | ||
*******************/ | ||
var SCRIPT_PROVIDER_REDUCER_ERROR = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; | ||
var __assign = function () { | ||
@@ -84,3 +134,3 @@ __assign = Object.assign || function __assign(t) { | ||
} | ||
return to.concat(ar || from); | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
} | ||
@@ -165,3 +215,3 @@ /** | ||
var scriptNode = self.document.querySelector("script[" + SCRIPT_ID + "=\"" + reactPayPalScriptID + "\"]"); | ||
if (scriptNode != null && scriptNode.parentNode) scriptNode.parentNode.removeChild(scriptNode); | ||
if (scriptNode === null || scriptNode === void 0 ? void 0 : scriptNode.parentNode) scriptNode.parentNode.removeChild(scriptNode); | ||
} | ||
@@ -181,3 +231,3 @@ /** | ||
switch (action.type) { | ||
case DISPATCH_ACTION.LOADING_STATUS: | ||
case SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS: | ||
return __assign(__assign({}, state), { | ||
@@ -187,3 +237,3 @@ loadingStatus: action.value | ||
case DISPATCH_ACTION.RESET_OPTIONS: | ||
case SCRIPT_PROVIDER_DISPATCH_ACTION.RESET_OPTIONS: | ||
// destroy existing script to make sure only one script loads at a time | ||
@@ -198,3 +248,3 @@ destroySDKScript(state.options[SCRIPT_ID]); // exclude the old data-react-paypal-script-id value from the hash generated by getScriptID() | ||
case DISPATCH_ACTION.SET_BRAINTREE_INSTANCE: | ||
case SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE: | ||
return __assign(__assign({}, state), { | ||
@@ -221,7 +271,7 @@ braintreePayPalCheckoutInstance: action.value | ||
function contextNotEmptyValidator(scriptContext) { | ||
if (typeof (scriptContext === null || scriptContext === void 0 ? void 0 : scriptContext.dispatch) !== "function") { | ||
throw new Error(EMPTY_PROVIDER_CONTEXT_ERROR_MESSAGE); | ||
if (typeof (scriptContext === null || scriptContext === void 0 ? void 0 : scriptContext.dispatch) === "function" && scriptContext.dispatch.length !== 0) { | ||
return scriptContext; | ||
} | ||
return scriptContext; | ||
throw new Error(SCRIPT_PROVIDER_REDUCER_ERROR); | ||
} | ||
@@ -268,2 +318,27 @@ /** | ||
/** | ||
* Custom hook to get access to the ScriptProvider context | ||
* | ||
* @returns the latest state of the context | ||
*/ | ||
function useScriptProviderContext() { | ||
var scriptContext = contextOptionClientTokenNotEmptyValidator(contextNotEmptyValidator(useContext(ScriptContext))); | ||
return [scriptContext, scriptContext.dispatch]; | ||
} // Create the React context to use in the PayPal hosted fields provider | ||
var PayPalHostedFieldsContext = createContext(null); | ||
/** | ||
* Custom hook to get access to the PayPal Hosted Fields instance. | ||
* The instance represent the returned object after the render process | ||
* With this object a user can submit the fields and dynamically modify the cards | ||
* | ||
* @returns the hosted fields instance if is available in the component | ||
*/ | ||
function usePayPalHostedFields() { | ||
return useContext(PayPalHostedFieldsContext); | ||
} | ||
/** | ||
This `<PayPalButtons />` component renders the [Smart Payment Buttons](https://developer.paypal.com/docs/business/javascript-sdk/javascript-sdk-reference/#buttons). | ||
@@ -302,24 +377,27 @@ It relies on the `<PayPalScriptProvider />` parent component for managing state related to loading the JS SDK script. | ||
disabled = _c === void 0 ? false : _c, | ||
_d = _a.children, | ||
children = _d === void 0 ? null : _d, | ||
_e = _a.forceReRender, | ||
forceReRender = _e === void 0 ? [] : _e, | ||
children = _a.children, | ||
_d = _a.forceReRender, | ||
forceReRender = _d === void 0 ? [] : _d, | ||
buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var isDisabledStyle = disabled ? { | ||
opacity: 0.38 | ||
} : {}; | ||
var classNames = (className + " " + (disabled ? "paypal-buttons-disabled" : "")).trim(); | ||
var buttonsContainerRef = useRef(null); | ||
var buttons = useRef(null); | ||
var _f = usePayPalScriptReducer()[0], | ||
isResolved = _f.isResolved, | ||
options = _f.options; | ||
var _e = usePayPalScriptReducer()[0], | ||
isResolved = _e.isResolved, | ||
options = _e.options; | ||
var _g = useState(null), | ||
initActions = _g[0], | ||
setInitActions = _g[1]; | ||
var _f = useState(null), | ||
initActions = _f[0], | ||
setInitActions = _f[1]; | ||
var _h = useState(true), | ||
isEligible = _h[0], | ||
setIsEligible = _h[1]; | ||
var _g = useState(true), | ||
isEligible = _g[0], | ||
setIsEligible = _g[1]; | ||
var _j = useState(null), | ||
setErrorState = _j[1]; | ||
var _h = useState(null), | ||
setErrorState = _h[1]; | ||
@@ -340,3 +418,3 @@ function closeButtonsComponent() { | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); // verify dependency on window object | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); // verify dependency on window object | ||
@@ -374,3 +452,3 @@ if (paypalWindowNamespace === undefined || paypalWindowNamespace.Buttons === undefined) { | ||
if (buttonsContainerRef.current === null) { | ||
if (!buttonsContainerRef.current) { | ||
return closeButtonsComponent; | ||
@@ -392,3 +470,3 @@ } | ||
return closeButtonsComponent; // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, __spreadArray(__spreadArray([isResolved], forceReRender), [buttonProps.fundingSource])); // useEffect hook for managing disabled state | ||
}, __spreadArray(__spreadArray([isResolved], forceReRender, true), [buttonProps.fundingSource], false)); // useEffect hook for managing disabled state | ||
@@ -408,16 +486,7 @@ useEffect(function () { | ||
}, [disabled, initActions]); | ||
var isDisabledStyle = disabled ? { | ||
opacity: 0.38 | ||
} : {}; | ||
var classNames = (className + " " + (disabled ? "paypal-buttons-disabled" : "")).trim(); | ||
if (isEligible === false) { | ||
return children; | ||
} | ||
return React.createElement("div", { | ||
return React.createElement(React.Fragment, null, isEligible ? React.createElement("div", { | ||
ref: buttonsContainerRef, | ||
style: isDisabledStyle, | ||
className: classNames | ||
}); | ||
}) : children); | ||
}; | ||
@@ -428,4 +497,5 @@ | ||
components = _b === void 0 ? "" : _b, | ||
_c = _a["data-namespace"], | ||
dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
_c = DATA_NAMESPACE, | ||
_d = _a[_c], | ||
dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalButtons /> because window." + dataNamespace + ".Buttons is undefined."; // the JS SDK includes the Buttons component by default when no 'components' are specified. | ||
@@ -646,13 +716,2 @@ // The 'buttons' component must be included in the 'components' list when using it with other components. | ||
/** | ||
* Custom hook to get access to the ScriptProvider context | ||
* | ||
* @returns the state of the context | ||
*/ | ||
function useBraintreeProviderContext() { | ||
var scriptContext = contextOptionClientTokenNotEmptyValidator(contextNotEmptyValidator(useContext(ScriptContext))); | ||
return [scriptContext, scriptContext.dispatch]; | ||
} | ||
/** | ||
* Override the createOrder callback to send the PayPal checkout instance as argument | ||
@@ -738,3 +797,3 @@ * to the defined createOrder function for braintree component button | ||
} | ||
/>; | ||
/> | ||
</PayPalScriptProvider> | ||
@@ -751,14 +810,13 @@ ``` | ||
disabled = _c === void 0 ? false : _c, | ||
_d = _a.children, | ||
children = _d === void 0 ? null : _d, | ||
_e = _a.forceReRender, | ||
forceReRender = _e === void 0 ? [] : _e, | ||
children = _a.children, | ||
_d = _a.forceReRender, | ||
forceReRender = _d === void 0 ? [] : _d, | ||
buttonProps = __rest(_a, ["className", "disabled", "children", "forceReRender"]); | ||
var _f = useState(null), | ||
setErrorState = _f[1]; | ||
var _e = useState(null), | ||
setErrorState = _e[1]; | ||
var _g = useBraintreeProviderContext(), | ||
providerContext = _g[0], | ||
dispatch = _g[1]; | ||
var _f = useScriptProviderContext(), | ||
providerContext = _f[0], | ||
dispatch = _f[1]; | ||
@@ -781,3 +839,3 @@ useEffect(function () { | ||
dispatch({ | ||
type: DISPATCH_ACTION.SET_BRAINTREE_INSTANCE, | ||
type: SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE, | ||
value: paypalCheckoutInstance | ||
@@ -802,13 +860,9 @@ }); | ||
It relies on the `<PayPalScriptProvider />` parent component for managing state related to loading the JS SDK script. | ||
```jsx | ||
<PayPalMarks /> | ||
``` | ||
This component can also be configured to use a single funding source similar to the [standalone buttons](https://developer.paypal.com/docs/business/checkout/configure-payments/standalone-buttons/) approach. | ||
A `FUNDING` object is exported by this library which has a key for every available funding source option. | ||
```jsx | ||
import { PayPalScriptProvider, PayPalMarks, FUNDING } from "@paypal/react-paypal-js"; | ||
<PayPalScriptProvider options={{ "client-id": "test", components: "buttons,marks" }}> | ||
@@ -824,3 +878,4 @@ <PayPalMarks fundingSource={FUNDING.PAYPAL}/> | ||
className = _b === void 0 ? "" : _b, | ||
markProps = __rest(_a, ["className"]); | ||
children = _a.children, | ||
markProps = __rest(_a, ["className", "children"]); | ||
@@ -831,40 +886,29 @@ var _c = usePayPalScriptReducer()[0], | ||
var markContainerRef = useRef(null); | ||
var mark = useRef(null); | ||
var _d = useState(null), | ||
setErrorState = _d[1]; | ||
var _d = useState(true), | ||
isEligible = _d[0], | ||
setIsEligible = _d[1]; | ||
useEffect(function () { | ||
// verify the sdk script has successfully loaded | ||
if (isResolved === false) { | ||
return; | ||
} // don't rerender when already rendered | ||
var _e = useState(null), | ||
setErrorState = _e[1]; | ||
/** | ||
* Render PayPal Mark into the DOM | ||
*/ | ||
if (mark.current !== null) { | ||
return; | ||
} | ||
var renderPayPalMark = function (mark) { | ||
var current = markContainerRef.current; // only render the mark when eligible | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); // verify dependency on window object | ||
if (!current || !mark.isEligible()) { | ||
return setIsEligible(false); | ||
} // Remove any children before render it again | ||
if (paypalWindowNamespace === undefined || paypalWindowNamespace.Marks === undefined) { | ||
setErrorState(function () { | ||
throw new Error(getErrorMessage$1(options)); | ||
}); | ||
return; | ||
} | ||
mark.current = paypalWindowNamespace.Marks(__assign({}, markProps)); // only render the mark when eligible | ||
if (mark.current.isEligible() === false) { | ||
return; | ||
if (current.firstChild) { | ||
current.removeChild(current.firstChild); | ||
} | ||
if (markContainerRef.current === null) { | ||
return; | ||
} | ||
mark.current.render(markContainerRef.current).catch(function (err) { | ||
mark.render(current).catch(function (err) { | ||
// component failed to render, possibly because it was closed or destroyed. | ||
if (markContainerRef.current === null || markContainerRef.current.children.length === 0) { | ||
if (current === null || current.children.length === 0) { | ||
// paypal marks container is no longer in the DOM, we can safely ignore the error | ||
@@ -878,8 +922,23 @@ return; | ||
}); | ||
}); // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}); | ||
}; | ||
useEffect(function () { | ||
// verify the sdk script has successfully loaded | ||
if (isResolved === false) return; | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); // verify dependency on window object | ||
if (paypalWindowNamespace === undefined || paypalWindowNamespace.Marks === undefined) { | ||
setErrorState(function () { | ||
throw new Error(getErrorMessage$1(options)); | ||
}); | ||
return; | ||
} | ||
renderPayPalMark(paypalWindowNamespace.Marks(__assign({}, markProps))); // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [isResolved, markProps.fundingSource]); | ||
return React.createElement("div", { | ||
return React.createElement(React.Fragment, null, isEligible ? React.createElement("div", { | ||
ref: markContainerRef, | ||
className: className | ||
}); | ||
}) : children); | ||
}; | ||
@@ -890,4 +949,5 @@ | ||
components = _b === void 0 ? "" : _b, | ||
_c = _a["data-namespace"], | ||
dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
_c = DATA_NAMESPACE, | ||
_d = _a[_c], | ||
dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalMarks /> because window." + dataNamespace + ".Marks is undefined."; // the JS SDK does not load the Marks component by default. It must be passed into the "components" query parameter. | ||
@@ -925,3 +985,3 @@ | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options["data-namespace"]); // verify dependency on window object | ||
var paypalWindowNamespace = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]); // verify dependency on window object | ||
@@ -953,3 +1013,3 @@ if (paypalWindowNamespace === undefined || paypalWindowNamespace.Messages === undefined) { | ||
}); // eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, __spreadArray([isResolved], forceReRender)); | ||
}, __spreadArray([isResolved], forceReRender, true)); | ||
return React.createElement("div", { | ||
@@ -964,4 +1024,5 @@ ref: messagesContainerRef, | ||
components = _b === void 0 ? "" : _b, | ||
_c = _a["data-namespace"], | ||
dataNamespace = _c === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _c; | ||
_c = DATA_NAMESPACE, | ||
_d = _a[_c], | ||
dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var errorMessage = "Unable to render <PayPalMessages /> because window." + dataNamespace + ".Messages is undefined."; // the JS SDK does not load the Messages component by default. It must be passed into the "components" query parameter. | ||
@@ -990,4 +1051,3 @@ | ||
options: __assign(__assign({}, options), (_b = {}, _b[SCRIPT_ID] = "" + getScriptID(options), _b[DATA_SDK_INTEGRATION_SOURCE] = DATA_SDK_INTEGRATION_SOURCE_VALUE, _b)), | ||
loadingStatus: deferLoading ? SCRIPT_LOADING_STATE.INITIAL : SCRIPT_LOADING_STATE.PENDING, | ||
dispatch: null | ||
loadingStatus: deferLoading ? SCRIPT_LOADING_STATE.INITIAL : SCRIPT_LOADING_STATE.PENDING | ||
}), | ||
@@ -1000,3 +1060,3 @@ state = _e[0], | ||
return dispatch({ | ||
type: DISPATCH_ACTION.LOADING_STATUS, | ||
type: SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: SCRIPT_LOADING_STATE.PENDING | ||
@@ -1011,3 +1071,3 @@ }); | ||
dispatch({ | ||
type: DISPATCH_ACTION.LOADING_STATUS, | ||
type: SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: SCRIPT_LOADING_STATE.RESOLVED | ||
@@ -1019,3 +1079,3 @@ }); | ||
dispatch({ | ||
type: DISPATCH_ACTION.LOADING_STATUS, | ||
type: SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS, | ||
value: SCRIPT_LOADING_STATE.REJECTED | ||
@@ -1035,3 +1095,301 @@ }); | ||
}; | ||
/** | ||
* Throw an exception if the HostedFields is not found in the paypal namespace | ||
* Probably cause for this problem is not sending the hosted-fields string | ||
* as part of the components props in options | ||
* {@code <PayPalScriptProvider options={{ components: 'hosted-fields'}}>} | ||
* | ||
* @param param0 and object containing the components and namespace defined in options | ||
* @throws {@code Error} | ||
* | ||
*/ | ||
var throwMissingHostedFieldsError = function (_a) { | ||
var _b = _a.components, | ||
components = _b === void 0 ? "" : _b, | ||
_c = DATA_NAMESPACE, | ||
_d = _a[_c], | ||
dataNamespace = _d === void 0 ? DEFAULT_PAYPAL_NAMESPACE : _d; | ||
var expectedComponents = components ? components + ",hosted-fields" : "hosted-fields"; | ||
var errorMessage = "Unable to render <PayPalHostedFieldsProvider /> because window." + dataNamespace + ".HostedFields is undefined."; | ||
if (!components.includes("hosted-fields")) { | ||
errorMessage += "\nTo fix the issue, add 'hosted-fields' to the list of components passed to the parent PayPalScriptProvider: <PayPalScriptProvider options={{ components: '" + expectedComponents + "'}}>"; | ||
} | ||
throw new Error(errorMessage); | ||
}; | ||
/** | ||
* Identify all the valid hosted fields children and generate the valid options | ||
* to use in the HostedFields.render process | ||
* | ||
* @param childrenList the list of children received | ||
* @param possibleChildren a list of child type to transform into fields format | ||
* @returns the fields object required to render the HostedFields | ||
*/ | ||
var generateHostedFieldsFromChildren = function (childrenList) { | ||
return childrenList.reduce(function (fields, child) { | ||
var _a = child.props, | ||
hostedFieldType = _a.hostedFieldType, | ||
options = _a.options; | ||
if (Object.values(PAYPAL_HOSTED_FIELDS_TYPES).includes(hostedFieldType)) { | ||
fields[hostedFieldType] = { | ||
selector: options.selector, | ||
placeholder: options.placeholder, | ||
type: options.type, | ||
formatInput: options.formatInput, | ||
maskInput: options.maskInput, | ||
select: options.select, | ||
maxlength: options.maxlength, | ||
minlength: options.minlength, | ||
prefill: options.prefill, | ||
rejectUnsupportedCards: options.rejectUnsupportedCards | ||
}; | ||
} | ||
return fields; | ||
}, {}); | ||
}; | ||
/** | ||
* Get only PayPalHostedField children, exclude all the other children | ||
* | ||
* @param childrenList the list of children | ||
* @returns a new list containing only the PayPalHostedField components | ||
*/ | ||
var getPayPalHostedFieldChildren = function (childrenList) { | ||
return childrenList.reduce(function (accumulator, child) { | ||
var reactElement = child; | ||
if (reactElement.props.hostedFieldType) { | ||
accumulator.push(reactElement.props.hostedFieldType); | ||
} | ||
return accumulator; | ||
}, []); | ||
}; | ||
/** | ||
* Validate the expiration date children. Valid combinations are: | ||
* 1- Exists expirationDate field and not exists expirationMonth and expirationYear fields | ||
* 2- Exists expirationMonth and expirationYear and not exists expirationDate | ||
* All the other possible combinations are invalid | ||
* | ||
* @param registerTypes | ||
* @returns @type {true} when the children are valid | ||
*/ | ||
var validateExpirationDate = function (registerTypes) { | ||
return !registerTypes.includes(PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_DATE) && !registerTypes.includes(PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_MONTH) && !registerTypes.includes(PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_YEAR); | ||
}; | ||
/** | ||
* Check if we find the [number, expiration, cvv] in children | ||
* | ||
* @param requiredChildren the list with required children [number, expiration, cvv] | ||
* @param registerTypes the list of all the children types pass to the parent | ||
* @throw an @type {Error} when not find the default children | ||
*/ | ||
var hasDefaultChildren = function (registerTypes) { | ||
if (!registerTypes.includes(PAYPAL_HOSTED_FIELDS_TYPES.NUMBER) || !registerTypes.includes(PAYPAL_HOSTED_FIELDS_TYPES.CVV) || validateExpirationDate(registerTypes)) { | ||
throw new Error(HOSTED_FIELDS_CHILDREN_ERROR); | ||
} | ||
}; | ||
/** | ||
* Check if we don't have duplicate children types | ||
* | ||
* @param registerTypes the list of all the children types pass to the parent | ||
* @throw an @type {Error} when duplicate types was found | ||
*/ | ||
var notDuplicateChildren = function (registerTypes) { | ||
if (registerTypes.length !== new Set(registerTypes).size) { | ||
throw new Error(HOSTED_FIELDS_DUPLICATE_CHILDREN_ERROR); | ||
} | ||
}; | ||
/** | ||
* Validate the hosted fields children past to the PayPalHostedFieldsProvider component | ||
* These are the rule: | ||
* 1- We need to find 3 default children type [[number, expiration, cvv] | ||
* 2- We cannot find duplicate children type | ||
* 3- We cannot find expirationDate field combine with expirationMonth and expirationYear | ||
* | ||
* @param childrenList the list of children | ||
* @param requiredChildren the list with required children [number, expiration, cvv] | ||
*/ | ||
var validateHostedFieldChildren = function (childrenList) { | ||
var registerTypes = getPayPalHostedFieldChildren(childrenList); | ||
hasDefaultChildren(registerTypes); | ||
notDuplicateChildren(registerTypes); | ||
}; | ||
/** | ||
This `<PayPalHostedFieldsProvider />` provider component wraps the form field elements and accepts props like `createOrder()`. | ||
This provider component is designed to be used with the `<PayPalHostedField />` component. | ||
*/ | ||
var PayPalHostedFieldsProvider = function (_a) { | ||
var styles = _a.styles, | ||
createOrder = _a.createOrder, | ||
notEligibleError = _a.notEligibleError, | ||
children = _a.children; | ||
var childrenList = Children.toArray(children); | ||
var _b = useScriptProviderContext()[0], | ||
options = _b.options, | ||
loadingStatus = _b.loadingStatus; | ||
var _c = useState(true), | ||
isEligible = _c[0], | ||
setIsEligible = _c[1]; | ||
var _d = useState(null), | ||
cardFields = _d[0], | ||
setCardFields = _d[1]; | ||
var hostedFieldsContainerRef = useRef(null); | ||
var hostedFields = useRef(); | ||
var _e = useState(null), | ||
setErrorState = _e[1]; | ||
/** | ||
* Executed on the mount process to validate the children | ||
*/ | ||
useEffect(function () { | ||
validateHostedFieldChildren(childrenList); | ||
}, []); // eslint-disable-line react-hooks/exhaustive-deps | ||
useEffect(function () { | ||
var _a; | ||
var _b; // Only render the hosted fields when script is loaded and hostedFields is eligible | ||
if (!(loadingStatus === SCRIPT_LOADING_STATE.RESOLVED)) return; // Get the hosted fields from the [window.paypal.HostedFields] SDK | ||
if (!hostedFields.current) { | ||
// Set HostedFields SDK in the mount process only | ||
hostedFields.current = getPayPalWindowNamespace$1(options[DATA_NAMESPACE]).HostedFields; | ||
if (!hostedFields.current) { | ||
throwMissingHostedFieldsError((_a = { | ||
components: options.components | ||
}, _a[DATA_NAMESPACE] = options[DATA_NAMESPACE], _a)); | ||
} | ||
} | ||
if (!((_b = hostedFields === null || hostedFields === void 0 ? void 0 : hostedFields.current) === null || _b === void 0 ? void 0 : _b.isEligible())) { | ||
return setIsEligible(false); | ||
} // Clean all the fields before the rerender | ||
if (cardFields) { | ||
cardFields.teardown(); | ||
} | ||
hostedFields.current.render({ | ||
// Call your server to set up the transaction | ||
createOrder: createOrder, | ||
styles: styles, | ||
fields: generateHostedFieldsFromChildren(childrenList) | ||
}).then(function (cardFieldsInstance) { | ||
setCardFields(cardFieldsInstance); | ||
}).catch(function (err) { | ||
setErrorState(function () { | ||
throw new Error("Failed to render <PayPalHostedFieldsProvider /> component. " + err); | ||
}); | ||
}); | ||
}, [loadingStatus, styles]); // eslint-disable-line react-hooks/exhaustive-deps | ||
return React.createElement("div", { | ||
ref: hostedFieldsContainerRef | ||
}, isEligible ? React.createElement(PayPalHostedFieldsContext.Provider, { | ||
value: cardFields | ||
}, children) : notEligibleError); | ||
}; | ||
/** | ||
This `<PayPalHostedField />` component renders individual fields for [Hosted Fields](https://developer.paypal.com/docs/business/checkout/advanced-card-payments/integrate#3-add-javascript-sdk-and-card-form) integrations. | ||
It relies on the `<PayPalHostedFieldsProvider />` parent component for managing state related to loading the JS SDK script | ||
and execute some validations before the rendering the fields. | ||
Use props for customizing your hosted fields. For example, here's how you would use the `style`, `className`, `id` options: | ||
```jsx | ||
import { | ||
PayPalScriptProvider, | ||
PayPalHostedFieldsProvider, | ||
PayPalHostedField | ||
} from "@paypal/react-paypal-js"; | ||
<PayPalScriptProvider options={{ "client-id": "test" }}> | ||
<PayPalHostedFieldsProvider | ||
createOrder={() => { | ||
// Manually call your server endpoint to create the client order | ||
return fetch("create_order_endpoint") | ||
.then(response => response.json()) | ||
.then(order => order.id) | ||
.catch(err => { | ||
// Handle exceptions | ||
}) | ||
}} | ||
> | ||
<PayPalHostedField style={{ color: "red", border: "1px solid" }} | ||
id="card-number" | ||
hostedFieldType="number" | ||
options={{ selector: "#card-number", placeholder: "4111 1111 1111 1111" }} /> | ||
<PayPalHostedField id="cvv" | ||
hostedFieldType="cvv" | ||
options={{ selector: "#cvv", placeholder: "CVV", maxlength: 3, maskInput: true }} /> | ||
<PayPalHostedField id="expiration-date" | ||
hostedFieldType="expirationDate" | ||
options={{ selector: "#expiration-date", placeholder: "MM/YY" }} /> | ||
</PayPalHostedFieldsProvider> | ||
</PayPalScriptProvider> | ||
``` | ||
To use the PayPal hosted fields you need to define at least three fields: | ||
- A card number field | ||
- The CVV code from the client card | ||
- The expiration date | ||
You can define the expiration date as a single field similar to the example above, | ||
or you are able to define it in two separate fields. One for the month and second for year. | ||
You can delete the last children component form the example above and use these: | ||
```jsx | ||
<PayPalHostedField id="expiration-month" | ||
hostedFieldType={PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_MONTH} | ||
options={{ selector: "#expiration-month", placeholder: "MM" }} /> | ||
<PayPalHostedField id="expiration-year" | ||
hostedFieldType={PAYPAL_HOSTED_FIELDS_TYPES.EXPIRATION_YEAR} | ||
options={{ selector: "#expiration-year", placeholder: "YYYY" }} /> | ||
``` | ||
Note: Take care when using multiple instances of the PayPal Hosted Fields on the same page. | ||
The component will fail to render when any of the selectors return more than one element. | ||
*/ | ||
var PayPalHostedField = function (_a) { | ||
_a.hostedFieldType; // eslint-disable-line @typescript-eslint/no-unused-vars | ||
_a.options; // eslint-disable-line @typescript-eslint/no-unused-vars | ||
var props = __rest(_a, ["hostedFieldType", "options"]); | ||
return React.createElement("div", __assign({}, props)); | ||
}; | ||
var FUNDING$1 = { | ||
@@ -1069,2 +1427,2 @@ PAYPAL: 'paypal', | ||
var FUNDING = FUNDING$1; | ||
export { BraintreePayPalButtons, DISPATCH_ACTION, FUNDING, PayPalButtons, PayPalMarks, PayPalMessages, PayPalScriptProvider, SCRIPT_LOADING_STATE, ScriptContext, destroySDKScript, getScriptID, scriptReducer, usePayPalScriptReducer }; | ||
export { BraintreePayPalButtons, FUNDING, PAYPAL_HOSTED_FIELDS_TYPES, PayPalButtons, PayPalHostedField, PayPalHostedFieldsProvider, PayPalMarks, PayPalMessages, PayPalScriptProvider, SCRIPT_LOADING_STATE, SCRIPT_PROVIDER_DISPATCH_ACTION, ScriptContext, destroySDKScript, getScriptID, scriptReducer, usePayPalHostedFields, usePayPalScriptReducer, useScriptProviderContext }; |
/*! | ||
* react-paypal-js v7.3.3 (2021-08-31T21:55:23.426Z) | ||
* react-paypal-js v7.4.0 (2021-10-08T14:28:13.235Z) | ||
* Copyright 2020-present, PayPal, Inc. All rights reserved. | ||
@@ -17,2 +17,2 @@ * | ||
*/ | ||
import e,{createContext as t,useContext as n,useRef as r,useState as o,useEffect as a,useReducer as i}from"react";var c,u;!function(e){e.INITIAL="initial",e.PENDING="pending",e.REJECTED="rejected",e.RESOLVED="resolved"}(c||(c={})),function(e){e.LOADING_STATUS="setLoadingStatus",e.RESET_OPTIONS="resetOptions",e.SET_BRAINTREE_INSTANCE="braintreeInstance"}(u||(u={}));var s="data-react-paypal-script-id",l=function(){return(l=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function d(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function f(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||t)}function p(e){return void 0===e&&(e="paypal"),window[e]}function v(e){return"react-paypal-js-"+function(e){for(var t="",n=0;n<e.length;n++){var r=e[n].charCodeAt(0)*n;e[n+1]&&(r+=e[n+1].charCodeAt(0)*(n-1)),t+=String.fromCharCode(97+Math.abs(r)%26)}return t}(JSON.stringify(e))}function h(e){var t=self.document.querySelector("script["+s+'="'+e+'"]');null!=t&&t.parentNode&&t.parentNode.removeChild(t)}function y(e,t){var n;switch(t.type){case u.LOADING_STATUS:return l(l({},e),{loadingStatus:t.value});case u.RESET_OPTIONS:return h(e.options[s]),delete t.value[s],l(l({},e),{loadingStatus:c.PENDING,options:l(l({},t.value),(n={},n[s]=""+v(t.value),n["data-sdk-integration-source"]="react-paypal-js",n))});case u.SET_BRAINTREE_INSTANCE:return l(l({},e),{braintreePayPalCheckoutInstance:t.value});default:return e}}var m=t(null);function E(e){if("function"!=typeof(null==e?void 0:e.dispatch))throw new Error("usePayPalScriptReducer must be used within a PayPalScriptProvider");return e}function P(){var e=E(n(m));return[l(l({},e),{isInitial:e.loadingStatus===c.INITIAL,isPending:e.loadingStatus===c.PENDING,isResolved:e.loadingStatus===c.RESOLVED,isRejected:e.loadingStatus===c.REJECTED}),e.dispatch]}var b=function(t){var n=t.className,i=void 0===n?"":n,c=t.disabled,u=void 0!==c&&c,s=t.children,v=void 0===s?null:s,h=t.forceReRender,y=void 0===h?[]:h,m=d(t,["className","disabled","children","forceReRender"]),E=r(null),b=r(null),w=P()[0],g=w.isResolved,A=w.options,S=o(null),N=S[0],I=S[1],O=o(!0),R=O[0],T=O[1],k=o(null)[1];function j(){null!==b.current&&b.current.close().catch((function(){}))}a((function(){if(!1===g)return j;var e=p(A["data-namespace"]);if(void 0===e||void 0===e.Buttons)return k((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalButtons /> because window."+(void 0===r?"paypal":r)+".Buttons is undefined.";if(n.length&&!n.includes("buttons")){o+="\nTo fix the issue, add 'buttons' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n+",buttons")+"'}}>`."}return o}(A))})),j;try{b.current=e.Buttons(l(l({},m),{onInit:function(e,t){I(t),"function"==typeof m.onInit&&m.onInit(e,t)}}))}catch(e){return k((function(){throw new Error("Failed to render <PayPalButtons /> component. Failed to initialize: "+e)}))}return!1===b.current.isEligible()?(T(!1),j):(null===E.current||b.current.render(E.current).catch((function(e){null!==E.current&&0!==E.current.children.length&&k((function(){throw new Error("Failed to render <PayPalButtons /> component. "+e)}))})),j)}),f(f([g],y),[m.fundingSource])),a((function(){null!==N&&(!0===u?N.disable().catch((function(){})):N.enable().catch((function(){})))}),[u,N]);var L=u?{opacity:.38}:{},C=(i+" "+(u?"paypal-buttons-disabled":"")).trim();return!1===R?v:e.createElement("div",{ref:E,style:L,className:C})};function w(e){var t="https://www.paypal.com/sdk/js";e.sdkBaseURL&&(t=e.sdkBaseURL,delete e.sdkBaseURL);var n=function(e,t){var n="",r="";Array.isArray(e)?e.length>1?(n="*",r=e.toString()):n=e.toString():"string"==typeof e&&e.length>0?n=e:"string"==typeof t&&t.length>0&&(n="*",r=t);return{"merchant-id":n,"data-merchant-id":r}}(e["merchant-id"],e["data-merchant-id"]),r=Object.assign({},e,n),o=Object.keys(r).filter((function(e){return void 0!==r[e]&&null!==r[e]&&""!==r[e]})).reduce((function(e,t){var n=r[t].toString();return"data-"===t.substring(0,5)?e.dataAttributes[t]=n:e.queryParams[t]=n,e}),{queryParams:{},dataAttributes:{}}),a=o.queryParams,i=o.dataAttributes;return{url:t+"?"+g(a),dataAttributes:i}}function g(e){var t="";return Object.keys(e).forEach((function(n){0!==t.length&&(t+="&"),t+=n+"="+e[n]})),t}function A(e,t){void 0===t&&(t={});var n=document.createElement("script");return n.src=e,Object.keys(t).forEach((function(e){n.setAttribute(e,t[e]),"data-csp-nonce"===e&&n.setAttribute("nonce",t["data-csp-nonce"])})),n}function S(e,t){if(void 0===t&&(t=I()),R(e,t),"undefined"==typeof window)return t.resolve(null);var n=w(e),r=n.url,o=n.dataAttributes,a=o["data-namespace"]||"paypal",i=O(a);return function(e,t){var n=document.querySelector('script[src="'+e+'"]');if(null===n)return null;var r=A(e,t),o=Object.assign({},n.dataset);if(delete o.uidAuto,Object.keys(o).length!==Object.keys(r.dataset).length)return null;var a=!0;return Object.keys(o).forEach((function(e){o[e]!==r.dataset[e]&&(a=!1)})),a?n:null}(r,o)&&i?t.resolve(i):N({url:r,attributes:o},t).then((function(){var e=O(a);if(e)return e;throw new Error("The window."+a+" global variable is not available.")}))}function N(e,t){void 0===t&&(t=I()),R(e,t);var n=e.url,r=e.attributes;if("string"!=typeof n||0===n.length)throw new Error("Invalid url.");if(void 0!==r&&"object"!=typeof r)throw new Error("Expected attributes to be an object.");return new t((function(e,t){if("undefined"==typeof window)return e();!function(e){var t=e.url,n=e.attributes,r=e.onSuccess,o=e.onError,a=A(t,n);a.onerror=o,a.onload=r,document.head.insertBefore(a,document.head.firstElementChild)}({url:n,attributes:r,onSuccess:function(){return e()},onError:function(){return t(new Error('The script "'+n+'" failed to load.'))}})}))}function I(){if("undefined"==typeof Promise)throw new Error("Promise is undefined. To resolve the issue, use a Promise polyfill.");return Promise}function O(e){return window[e]}function R(e,t){if("object"!=typeof e||null===e)throw new Error("Expected an options object.");if(void 0!==t&&"function"!=typeof t)throw new Error("Expected PromisePonyfill to be a function.")}function T(){var e=function(e){var t;if(!(null===(t=null==e?void 0:e.options)||void 0===t?void 0:t["data-client-token"]))throw new Error("A client token wasn't found in the provider parent component");return e}(E(n(m)));return[e,e.dispatch]}var k=function(e,t){return function(e,t){if("function"==typeof e.createOrder){var n=e.createOrder;e.createOrder=function(e,r){return n(e,l(l({},r),{braintree:t}))}}}(e,t),function(e,t){if("function"==typeof e.onApprove){var n=e.onApprove;e.onApprove=function(e,r){return n(e,l(l({},r),{braintree:t}))}}}(e,t),l({},e)},j=function(t){var n=t.className,r=void 0===n?"":n,i=t.disabled,c=void 0!==i&&i,s=t.children,f=void 0===s?null:s,p=t.forceReRender,v=void 0===p?[]:p,h=d(t,["className","disabled","children","forceReRender"]),y=o(null)[1],m=T(),E=m[0],P=m[1];return a((function(){Promise.all([N({url:"https://js.braintreegateway.com/web/3.81.0/js/client.min.js"}),N({url:"https://js.braintreegateway.com/web/3.81.0/js/paypal-checkout.min.js"})]).then((function(){var e,t=E.options["data-client-token"],n=(void 0===e&&(e="braintree"),window[e]);return n.client.create({authorization:t}).then((function(e){return n.paypalCheckout.create({client:e})})).then((function(e){P({type:u.SET_BRAINTREE_INSTANCE,value:e})}))})).catch((function(e){y((function(){throw new Error("An error occurred when loading the Braintree scripts: "+e)}))}))}),[E.options,P]),e.createElement(e.Fragment,null,E.braintreePayPalCheckoutInstance&&e.createElement(b,l({className:r,disabled:c,forceReRender:v},k(h,E.braintreePayPalCheckoutInstance)),f))},L=function(t){var n=t.className,i=void 0===n?"":n,c=d(t,["className"]),u=P()[0],s=u.isResolved,f=u.options,v=r(null),h=r(null),y=o(null)[1];return a((function(){if(!1!==s&&null===h.current){var e=p(f["data-namespace"]);void 0!==e&&void 0!==e.Marks?(h.current=e.Marks(l({},c)),!1!==h.current.isEligible()&&null!==v.current&&h.current.render(v.current).catch((function(e){null!==v.current&&0!==v.current.children.length&&y((function(){throw new Error("Failed to render <PayPalMarks /> component. "+e)}))}))):y((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalMarks /> because window."+(void 0===r?"paypal":r)+".Marks is undefined.";if(!n.includes("marks")){o+="\nTo fix the issue, add 'marks' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n?n+",marks":"marks")+"'}}>`."}return o}(f))}))}}),[s,c.fundingSource]),e.createElement("div",{ref:v,className:i})};var C=function(t){var n=t.className,i=void 0===n?"":n,c=t.forceReRender,u=void 0===c?[]:c,s=d(t,["className","forceReRender"]),v=P()[0],h=v.isResolved,y=v.options,m=r(null),E=r(null),b=o(null)[1];return a((function(){if(!1!==h){var e=p(y["data-namespace"]);void 0!==e&&void 0!==e.Messages?(E.current=e.Messages(l({},s)),null!==m.current&&E.current.render(m.current).catch((function(e){null!==m.current&&0!==m.current.children.length&&b((function(){throw new Error("Failed to render <PayPalMessages /> component. "+e)}))}))):b((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalMessages /> because window."+(void 0===r?"paypal":r)+".Messages is undefined.";if(!n.includes("messages")){o+="\nTo fix the issue, add 'messages' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n?n+",messages":"messages")+"'}}>`."}return o}(y))}))}}),f([h],u)),e.createElement("div",{ref:m,className:i})};var D=function(t){var n,r=t.options,o=void 0===r?{"client-id":"test"}:r,d=t.children,f=t.deferLoading,p=void 0!==f&&f,h=i(y,{options:l(l({},o),(n={},n[s]=""+v(o),n["data-sdk-integration-source"]="react-paypal-js",n)),loadingStatus:p?c.INITIAL:c.PENDING,dispatch:null}),E=h[0],P=h[1];return a((function(){if(!1===p&&E.loadingStatus===c.INITIAL)return P({type:u.LOADING_STATUS,value:c.PENDING});if(E.loadingStatus===c.PENDING){var e=!0;return S(E.options).then((function(){e&&P({type:u.LOADING_STATUS,value:c.RESOLVED})})).catch((function(){e&&P({type:u.LOADING_STATUS,value:c.REJECTED})})),function(){e=!1}}}),[E.options,p,E.loadingStatus]),e.createElement(m.Provider,{value:l(l({},E),{dispatch:P})},d)},B={PAYPAL:"paypal",VENMO:"venmo",APPLEPAY:"applepay",ITAU:"itau",CREDIT:"credit",PAYLATER:"paylater",CARD:"card",IDEAL:"ideal",SEPA:"sepa",BANCONTACT:"bancontact",GIROPAY:"giropay",SOFORT:"sofort",EPS:"eps",MYBANK:"mybank",P24:"p24",VERKKOPANKKI:"verkkopankki",PAYU:"payu",BLIK:"blik",TRUSTLY:"trustly",ZIMPLER:"zimpler",MAXIMA:"maxima",OXXO:"oxxo",BOLETO:"boleto",WECHATPAY:"wechatpay",MERCADOPAGO:"mercadopago"};export{j as BraintreePayPalButtons,u as DISPATCH_ACTION,B as FUNDING,b as PayPalButtons,L as PayPalMarks,C as PayPalMessages,D as PayPalScriptProvider,c as SCRIPT_LOADING_STATE,m as ScriptContext,h as destroySDKScript,v as getScriptID,y as scriptReducer,P as usePayPalScriptReducer}; | ||
import e,{createContext as t,useContext as n,useRef as r,useState as o,useEffect as a,useReducer as i,Children as c}from"react";var s,u,l;!function(e){e.INITIAL="initial",e.PENDING="pending",e.REJECTED="rejected",e.RESOLVED="resolved"}(s||(s={})),function(e){e.LOADING_STATUS="setLoadingStatus",e.RESET_OPTIONS="resetOptions",e.SET_BRAINTREE_INSTANCE="braintreeInstance"}(u||(u={})),function(e){e.NUMBER="number",e.CVV="cvv",e.EXPIRATION_DATE="expirationDate",e.EXPIRATION_MONTH="expirationMonth",e.EXPIRATION_YEAR="expirationYear",e.POSTAL_CODE="postalCode"}(l||(l={}));var d="data-react-paypal-script-id",p=function(){return(p=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)};function f(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function v(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function h(e){return void 0===e&&(e="paypal"),window[e]}function m(e){return"react-paypal-js-"+function(e){for(var t="",n=0;n<e.length;n++){var r=e[n].charCodeAt(0)*n;e[n+1]&&(r+=e[n+1].charCodeAt(0)*(n-1)),t+=String.fromCharCode(97+Math.abs(r)%26)}return t}(JSON.stringify(e))}function E(e){var t=self.document.querySelector("script["+d+'="'+e+'"]');(null==t?void 0:t.parentNode)&&t.parentNode.removeChild(t)}function y(e,t){var n;switch(t.type){case u.LOADING_STATUS:return p(p({},e),{loadingStatus:t.value});case u.RESET_OPTIONS:return E(e.options[d]),delete t.value[d],p(p({},e),{loadingStatus:s.PENDING,options:p(p({},t.value),(n={},n[d]=""+m(t.value),n["data-sdk-integration-source"]="react-paypal-js",n))});case u.SET_BRAINTREE_INSTANCE:return p(p({},e),{braintreePayPalCheckoutInstance:t.value});default:return e}}var P=t(null);function b(e){if("function"==typeof(null==e?void 0:e.dispatch)&&0!==e.dispatch.length)return e;throw new Error("usePayPalScriptReducer must be used within a PayPalScriptProvider")}function w(){var e=b(n(P));return[p(p({},e),{isInitial:e.loadingStatus===s.INITIAL,isPending:e.loadingStatus===s.PENDING,isResolved:e.loadingStatus===s.RESOLVED,isRejected:e.loadingStatus===s.REJECTED}),e.dispatch]}function g(){var e=function(e){var t;if(!(null===(t=null==e?void 0:e.options)||void 0===t?void 0:t["data-client-token"]))throw new Error("A client token wasn't found in the provider parent component");return e}(b(n(P)));return[e,e.dispatch]}var A=t(null);function I(){return n(A)}var S=function(t){var n=t.className,i=void 0===n?"":n,c=t.disabled,s=void 0!==c&&c,u=t.children,l=t.forceReRender,d=void 0===l?[]:l,m=f(t,["className","disabled","children","forceReRender"]),E=s?{opacity:.38}:{},y=(i+" "+(s?"paypal-buttons-disabled":"")).trim(),P=r(null),b=r(null),g=w()[0],A=g.isResolved,I=g.options,S=o(null),T=S[0],O=S[1],N=o(!0),R=N[0],k=N[1],j=o(null)[1];function C(){null!==b.current&&b.current.close().catch((function(){}))}return a((function(){if(!1===A)return C;var e=h(I["data-namespace"]);if(void 0===e||void 0===e.Buttons)return j((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalButtons /> because window."+(void 0===r?"paypal":r)+".Buttons is undefined.";if(n.length&&!n.includes("buttons")){o+="\nTo fix the issue, add 'buttons' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n+",buttons")+"'}}>`."}return o}(I))})),C;try{b.current=e.Buttons(p(p({},m),{onInit:function(e,t){O(t),"function"==typeof m.onInit&&m.onInit(e,t)}}))}catch(e){return j((function(){throw new Error("Failed to render <PayPalButtons /> component. Failed to initialize: "+e)}))}return!1===b.current.isEligible()?(k(!1),C):P.current?(b.current.render(P.current).catch((function(e){null!==P.current&&0!==P.current.children.length&&j((function(){throw new Error("Failed to render <PayPalButtons /> component. "+e)}))})),C):C}),v(v([A],d,!0),[m.fundingSource],!1)),a((function(){null!==T&&(!0===s?T.disable().catch((function(){})):T.enable().catch((function(){})))}),[s,T]),e.createElement(e.Fragment,null,R?e.createElement("div",{ref:P,style:E,className:y}):u)};function T(e){var t="https://www.paypal.com/sdk/js";e.sdkBaseURL&&(t=e.sdkBaseURL,delete e.sdkBaseURL);var n=function(e,t){var n="",r="";Array.isArray(e)?e.length>1?(n="*",r=e.toString()):n=e.toString():"string"==typeof e&&e.length>0?n=e:"string"==typeof t&&t.length>0&&(n="*",r=t);return{"merchant-id":n,"data-merchant-id":r}}(e["merchant-id"],e["data-merchant-id"]),r=Object.assign({},e,n),o=Object.keys(r).filter((function(e){return void 0!==r[e]&&null!==r[e]&&""!==r[e]})).reduce((function(e,t){var n=r[t].toString();return"data-"===t.substring(0,5)?e.dataAttributes[t]=n:e.queryParams[t]=n,e}),{queryParams:{},dataAttributes:{}}),a=o.queryParams,i=o.dataAttributes;return{url:t+"?"+O(a),dataAttributes:i}}function O(e){var t="";return Object.keys(e).forEach((function(n){0!==t.length&&(t+="&"),t+=n+"="+e[n]})),t}function N(e,t){void 0===t&&(t={});var n=document.createElement("script");return n.src=e,Object.keys(t).forEach((function(e){n.setAttribute(e,t[e]),"data-csp-nonce"===e&&n.setAttribute("nonce",t["data-csp-nonce"])})),n}function R(e,t){if(void 0===t&&(t=j()),D(e,t),"undefined"==typeof window)return t.resolve(null);var n=T(e),r=n.url,o=n.dataAttributes,a=o["data-namespace"]||"paypal",i=C(a);return function(e,t){var n=document.querySelector('script[src="'+e+'"]');if(null===n)return null;var r=N(e,t),o=Object.assign({},n.dataset);if(delete o.uidAuto,Object.keys(o).length!==Object.keys(r.dataset).length)return null;var a=!0;return Object.keys(o).forEach((function(e){o[e]!==r.dataset[e]&&(a=!1)})),a?n:null}(r,o)&&i?t.resolve(i):k({url:r,attributes:o},t).then((function(){var e=C(a);if(e)return e;throw new Error("The window."+a+" global variable is not available.")}))}function k(e,t){void 0===t&&(t=j()),D(e,t);var n=e.url,r=e.attributes;if("string"!=typeof n||0===n.length)throw new Error("Invalid url.");if(void 0!==r&&"object"!=typeof r)throw new Error("Expected attributes to be an object.");return new t((function(e,t){if("undefined"==typeof window)return e();!function(e){var t=e.url,n=e.attributes,r=e.onSuccess,o=e.onError,a=N(t,n);a.onerror=o,a.onload=r,document.head.insertBefore(a,document.head.firstElementChild)}({url:n,attributes:r,onSuccess:function(){return e()},onError:function(){return t(new Error('The script "'+n+'" failed to load.'))}})}))}function j(){if("undefined"==typeof Promise)throw new Error("Promise is undefined. To resolve the issue, use a Promise polyfill.");return Promise}function C(e){return window[e]}function D(e,t){if("object"!=typeof e||null===e)throw new Error("Expected an options object.");if(void 0!==t&&"function"!=typeof t)throw new Error("Expected PromisePonyfill to be a function.")}var L=function(e,t){return function(e,t){if("function"==typeof e.createOrder){var n=e.createOrder;e.createOrder=function(e,r){return n(e,p(p({},r),{braintree:t}))}}}(e,t),function(e,t){if("function"==typeof e.onApprove){var n=e.onApprove;e.onApprove=function(e,r){return n(e,p(p({},r),{braintree:t}))}}}(e,t),p({},e)},M=function(t){var n=t.className,r=void 0===n?"":n,i=t.disabled,c=void 0!==i&&i,s=t.children,l=t.forceReRender,d=void 0===l?[]:l,v=f(t,["className","disabled","children","forceReRender"]),h=o(null)[1],m=g(),E=m[0],y=m[1];return a((function(){Promise.all([k({url:"https://js.braintreegateway.com/web/3.81.0/js/client.min.js"}),k({url:"https://js.braintreegateway.com/web/3.81.0/js/paypal-checkout.min.js"})]).then((function(){var e,t=E.options["data-client-token"],n=(void 0===e&&(e="braintree"),window[e]);return n.client.create({authorization:t}).then((function(e){return n.paypalCheckout.create({client:e})})).then((function(e){y({type:u.SET_BRAINTREE_INSTANCE,value:e})}))})).catch((function(e){h((function(){throw new Error("An error occurred when loading the Braintree scripts: "+e)}))}))}),[E.options,y]),e.createElement(e.Fragment,null,E.braintreePayPalCheckoutInstance&&e.createElement(S,p({className:r,disabled:c,forceReRender:d},L(v,E.braintreePayPalCheckoutInstance)),s))},F=function(t){var n=t.className,i=void 0===n?"":n,c=t.children,s=f(t,["className","children"]),u=w()[0],l=u.isResolved,d=u.options,v=r(null),m=o(!0),E=m[0],y=m[1],P=o(null)[1];return a((function(){if(!1!==l){var e=h(d["data-namespace"]);void 0!==e&&void 0!==e.Marks?function(e){var t=v.current;if(!t||!e.isEligible())return y(!1);t.firstChild&&t.removeChild(t.firstChild),e.render(t).catch((function(e){null!==t&&0!==t.children.length&&P((function(){throw new Error("Failed to render <PayPalMarks /> component. "+e)}))}))}(e.Marks(p({},s))):P((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalMarks /> because window."+(void 0===r?"paypal":r)+".Marks is undefined.";if(!n.includes("marks")){o+="\nTo fix the issue, add 'marks' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n?n+",marks":"marks")+"'}}>`."}return o}(d))}))}}),[l,s.fundingSource]),e.createElement(e.Fragment,null,E?e.createElement("div",{ref:v,className:i}):c)};var B=function(t){var n=t.className,i=void 0===n?"":n,c=t.forceReRender,s=void 0===c?[]:c,u=f(t,["className","forceReRender"]),l=w()[0],d=l.isResolved,m=l.options,E=r(null),y=r(null),P=o(null)[1];return a((function(){if(!1!==d){var e=h(m["data-namespace"]);void 0!==e&&void 0!==e.Messages?(y.current=e.Messages(p({},u)),null!==E.current&&y.current.render(E.current).catch((function(e){null!==E.current&&0!==E.current.children.length&&P((function(){throw new Error("Failed to render <PayPalMessages /> component. "+e)}))}))):P((function(){throw new Error(function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o="Unable to render <PayPalMessages /> because window."+(void 0===r?"paypal":r)+".Messages is undefined.";if(!n.includes("messages")){o+="\nTo fix the issue, add 'messages' to the list of components passed to the parent PayPalScriptProvider:\n`<PayPalScriptProvider options={{ components: '"+(n?n+",messages":"messages")+"'}}>`."}return o}(m))}))}}),v([d],s,!0)),e.createElement("div",{ref:E,className:i})};var _=function(t){var n,r=t.options,o=void 0===r?{"client-id":"test"}:r,c=t.children,l=t.deferLoading,f=void 0!==l&&l,v=i(y,{options:p(p({},o),(n={},n[d]=""+m(o),n["data-sdk-integration-source"]="react-paypal-js",n)),loadingStatus:f?s.INITIAL:s.PENDING}),h=v[0],E=v[1];return a((function(){if(!1===f&&h.loadingStatus===s.INITIAL)return E({type:u.LOADING_STATUS,value:s.PENDING});if(h.loadingStatus===s.PENDING){var e=!0;return R(h.options).then((function(){e&&E({type:u.LOADING_STATUS,value:s.RESOLVED})})).catch((function(){e&&E({type:u.LOADING_STATUS,value:s.REJECTED})})),function(){e=!1}}}),[h.options,f,h.loadingStatus]),e.createElement(P.Provider,{value:p(p({},h),{dispatch:E})},c)},x=function(e){return e.reduce((function(e,t){var n=t.props,r=n.hostedFieldType,o=n.options;return Object.values(l).includes(r)&&(e[r]={selector:o.selector,placeholder:o.placeholder,type:o.type,formatInput:o.formatInput,maskInput:o.maskInput,select:o.select,maxlength:o.maxlength,minlength:o.minlength,prefill:o.prefill,rejectUnsupportedCards:o.rejectUnsupportedCards}),e}),{})},U=function(e){if(!e.includes(l.NUMBER)||!e.includes(l.CVV)||function(e){return!e.includes(l.EXPIRATION_DATE)&&!e.includes(l.EXPIRATION_MONTH)&&!e.includes(l.EXPIRATION_YEAR)}(e))throw new Error("To use HostedFields you must use it with at least 3 children with types: [number, cvv, expirationDate] includes")},G=function(e){var t=function(e){return e.reduce((function(e,t){var n=t;return n.props.hostedFieldType&&e.push(n.props.hostedFieldType),e}),[])}(e);U(t),function(e){if(e.length!==new Set(e).size)throw new Error("Cannot use duplicate HostedFields as children")}(t)},Y=function(t){var n=t.styles,i=t.createOrder,u=t.notEligibleError,l=t.children,d=c.toArray(l),p=g()[0],f=p.options,v=p.loadingStatus,m=o(!0),E=m[0],y=m[1],P=o(null),b=P[0],w=P[1],I=r(null),S=r(),T=o(null)[1];return a((function(){G(d)}),[]),a((function(){var e,t;if(v===s.RESOLVED){if(S.current||(S.current=h(f["data-namespace"]).HostedFields,S.current||function(e){var t=e.components,n=void 0===t?"":t,r=e["data-namespace"],o=n?n+",hosted-fields":"hosted-fields",a="Unable to render <PayPalHostedFieldsProvider /> because window."+(void 0===r?"paypal":r)+".HostedFields is undefined.";throw n.includes("hosted-fields")||(a+="\nTo fix the issue, add 'hosted-fields' to the list of components passed to the parent PayPalScriptProvider: <PayPalScriptProvider options={{ components: '"+o+"'}}>"),new Error(a)}(((e={components:f.components})["data-namespace"]=f["data-namespace"],e))),!(null===(t=null==S?void 0:S.current)||void 0===t?void 0:t.isEligible()))return y(!1);b&&b.teardown(),S.current.render({createOrder:i,styles:n,fields:x(d)}).then((function(e){w(e)})).catch((function(e){T((function(){throw new Error("Failed to render <PayPalHostedFieldsProvider /> component. "+e)}))}))}}),[v,n]),e.createElement("div",{ref:I},E?e.createElement(A.Provider,{value:b},l):u)},V=function(t){t.hostedFieldType,t.options;var n=f(t,["hostedFieldType","options"]);return e.createElement("div",p({},n))},H={PAYPAL:"paypal",VENMO:"venmo",APPLEPAY:"applepay",ITAU:"itau",CREDIT:"credit",PAYLATER:"paylater",CARD:"card",IDEAL:"ideal",SEPA:"sepa",BANCONTACT:"bancontact",GIROPAY:"giropay",SOFORT:"sofort",EPS:"eps",MYBANK:"mybank",P24:"p24",VERKKOPANKKI:"verkkopankki",PAYU:"payu",BLIK:"blik",TRUSTLY:"trustly",ZIMPLER:"zimpler",MAXIMA:"maxima",OXXO:"oxxo",BOLETO:"boleto",WECHATPAY:"wechatpay",MERCADOPAGO:"mercadopago"};export{M as BraintreePayPalButtons,H as FUNDING,l as PAYPAL_HOSTED_FIELDS_TYPES,S as PayPalButtons,V as PayPalHostedField,Y as PayPalHostedFieldsProvider,F as PayPalMarks,B as PayPalMessages,_ as PayPalScriptProvider,s as SCRIPT_LOADING_STATE,u as SCRIPT_PROVIDER_DISPATCH_ACTION,P as ScriptContext,E as destroySDKScript,m as getScriptID,y as scriptReducer,I as usePayPalHostedFields,w as usePayPalScriptReducer,g as useScriptProviderContext}; |
@@ -30,3 +30,3 @@ import { FC } from "react"; | ||
} | ||
/>; | ||
/> | ||
</PayPalScriptProvider> | ||
@@ -33,0 +33,0 @@ ``` |
@@ -1,2 +0,2 @@ | ||
import { FunctionComponent } from "react"; | ||
import { FC, ReactNode } from "react"; | ||
import type { PayPalMarksComponentOptions } from "@paypal/paypal-js/types/components/marks"; | ||
@@ -8,2 +8,3 @@ export interface PayPalMarksComponentProps extends PayPalMarksComponentOptions { | ||
className?: string; | ||
children?: ReactNode; | ||
} | ||
@@ -14,13 +15,9 @@ /** | ||
It relies on the `<PayPalScriptProvider />` parent component for managing state related to loading the JS SDK script. | ||
```jsx | ||
<PayPalMarks /> | ||
``` | ||
This component can also be configured to use a single funding source similar to the [standalone buttons](https://developer.paypal.com/docs/business/checkout/configure-payments/standalone-buttons/) approach. | ||
A `FUNDING` object is exported by this library which has a key for every available funding source option. | ||
```jsx | ||
import { PayPalScriptProvider, PayPalMarks, FUNDING } from "@paypal/react-paypal-js"; | ||
<PayPalScriptProvider options={{ "client-id": "test", components: "buttons,marks" }}> | ||
@@ -31,2 +28,2 @@ <PayPalMarks fundingSource={FUNDING.PAYPAL}/> | ||
*/ | ||
export declare const PayPalMarks: FunctionComponent<PayPalMarksComponentProps>; | ||
export declare const PayPalMarks: FC<PayPalMarksComponentProps>; |
@@ -0,1 +1,4 @@ | ||
/********************************************* | ||
* Common reference to the script identifier * | ||
*********************************************/ | ||
export declare const SCRIPT_ID = "data-react-paypal-script-id"; | ||
@@ -5,7 +8,22 @@ export declare const DATA_CLIENT_TOKEN = "data-client-token"; | ||
export declare const DATA_SDK_INTEGRATION_SOURCE_VALUE = "react-paypal-js"; | ||
export declare const EMPTY_PROVIDER_CONTEXT_ERROR_MESSAGE = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; | ||
export declare const DATA_NAMESPACE = "data-namespace"; | ||
/**************************** | ||
* Braintree error messages * | ||
****************************/ | ||
export declare const EMPTY_PROVIDER_CONTEXT_CLIENT_TOKEN_ERROR_MESSAGE = "A client token wasn't found in the provider parent component"; | ||
export declare const BRAINTREE_SOURCE: string; | ||
export declare const BRAINTREE_PAYPAL_CHECKOUT_SOURCE: string; | ||
/********************* | ||
* PayPal namespaces * | ||
*********************/ | ||
export declare const DEFAULT_PAYPAL_NAMESPACE = "paypal"; | ||
export declare const DEFAULT_BRAINTREE_NAMESPACE = "braintree"; | ||
/***************** | ||
* Hosted Fields * | ||
*****************/ | ||
export declare const HOSTED_FIELDS_CHILDREN_ERROR = "To use HostedFields you must use it with at least 3 children with types: [number, cvv, expirationDate] includes"; | ||
export declare const HOSTED_FIELDS_DUPLICATE_CHILDREN_ERROR = "Cannot use duplicate HostedFields as children"; | ||
/******************* | ||
* Script Provider * | ||
*******************/ | ||
export declare const SCRIPT_PROVIDER_REDUCER_ERROR = "usePayPalScriptReducer must be used within a PayPalScriptProvider"; |
@@ -1,2 +0,2 @@ | ||
import type { ScriptContextState, StrictScriptContextState } from "../types"; | ||
import type { ScriptContextState } from "../types"; | ||
/** | ||
@@ -8,3 +8,3 @@ * Check if the context is valid and ready to dispatch actions. | ||
*/ | ||
export declare function contextNotEmptyValidator(scriptContext: ScriptContextState | null): StrictScriptContextState; | ||
export declare function contextNotEmptyValidator(scriptContext: ScriptContextState | null): ScriptContextState; | ||
/** | ||
@@ -17,2 +17,2 @@ * Check if the data-client-token is set in the options of the context | ||
*/ | ||
export declare const contextOptionClientTokenNotEmptyValidator: (scriptContext: ScriptContextState | null) => StrictScriptContextState; | ||
export declare const contextOptionClientTokenNotEmptyValidator: (scriptContext: ScriptContextState | null) => ScriptContextState; |
@@ -1,3 +0,3 @@ | ||
/// <reference types="react" /> | ||
import type { ScriptContextDerivedState, ScriptReducerAction } from "../types"; | ||
import React from "react"; | ||
import type { ScriptContextDerivedState, ScriptContextState, ScriptReducerAction } from "../types"; | ||
/** | ||
@@ -14,1 +14,10 @@ * Custom hook to get access to the Script context and | ||
]; | ||
/** | ||
* Custom hook to get access to the ScriptProvider context | ||
* | ||
* @returns the latest state of the context | ||
*/ | ||
export declare function useScriptProviderContext(): [ | ||
ScriptContextState, | ||
React.Dispatch<ScriptReducerAction> | ||
]; |
export * from "./types"; | ||
export * from "./context/scriptProviderContext"; | ||
export * from "./hooks/scriptProviderHooks"; | ||
export { usePayPalHostedFields } from "./hooks/payPalHostedFieldsHooks"; | ||
export * from "./components/PayPalButtons"; | ||
@@ -9,2 +10,4 @@ export * from "./components/braintree/BraintreePayPalButtons"; | ||
export * from "./components/PayPalScriptProvider"; | ||
export * from "./components/hostedFields/PayPalHostedFieldsProvider"; | ||
export * from "./components/hostedFields/PayPalHostedField"; | ||
export declare const FUNDING: Record<string, string>; |
@@ -0,1 +1,6 @@ | ||
/** | ||
* Enum for the SDK script resolve status, | ||
* | ||
* @enum {string} | ||
*/ | ||
export declare enum SCRIPT_LOADING_STATE { | ||
@@ -7,3 +12,8 @@ INITIAL = "initial", | ||
} | ||
export declare enum DISPATCH_ACTION { | ||
/** | ||
* Enum for the PayPalScriptProvider context dispatch actions | ||
* | ||
* @enum {string} | ||
*/ | ||
export declare enum SCRIPT_PROVIDER_DISPATCH_ACTION { | ||
LOADING_STATUS = "setLoadingStatus", | ||
@@ -13,1 +23,14 @@ RESET_OPTIONS = "resetOptions", | ||
} | ||
/** | ||
* Enum for all the available hosted fields | ||
* | ||
* @enum {string} | ||
*/ | ||
export declare enum PAYPAL_HOSTED_FIELDS_TYPES { | ||
NUMBER = "number", | ||
CVV = "cvv", | ||
EXPIRATION_DATE = "expirationDate", | ||
EXPIRATION_MONTH = "expirationMonth", | ||
EXPIRATION_YEAR = "expirationYear", | ||
POSTAL_CODE = "postalCode" | ||
} |
@@ -5,1 +5,2 @@ export * from "./braintreePayPalButtonTypes"; | ||
export * from "./scriptProviderTypes"; | ||
export * from "./payPalHostedFieldTypes"; |
@@ -1,2 +0,2 @@ | ||
import { ReactElement } from "react"; | ||
import type { ReactNode } from "react"; | ||
import type { PayPalButtonsComponentOptions } from "@paypal/paypal-js/types/components/buttons"; | ||
@@ -20,3 +20,3 @@ export interface PayPalButtonsComponentProps extends PayPalButtonsComponentOptions { | ||
*/ | ||
children?: ReactElement | null; | ||
children?: ReactNode; | ||
} |
@@ -1,6 +0,6 @@ | ||
/// <reference types="react" /> | ||
import type { PayPalScriptOptions } from "@paypal/paypal-js/types/script-options"; | ||
import { SCRIPT_ID } from "../constants"; | ||
import { BraintreePayPalCheckout } from "./braintree/paypalCheckout"; | ||
import { DISPATCH_ACTION, SCRIPT_LOADING_STATE } from "./enums"; | ||
import { SCRIPT_PROVIDER_DISPATCH_ACTION, SCRIPT_LOADING_STATE } from "./enums"; | ||
import type { ReactNode, Dispatch } from "react"; | ||
import type { PayPalScriptOptions } from "@paypal/paypal-js/types/script-options"; | ||
export interface ReactPayPalScriptOptions extends PayPalScriptOptions { | ||
@@ -10,4 +10,10 @@ [SCRIPT_ID]: string; | ||
export declare type ScriptReducerAction = { | ||
type: DISPATCH_ACTION; | ||
value: SCRIPT_LOADING_STATE | ReactPayPalScriptOptions | PayPalScriptOptions | BraintreePayPalCheckout; | ||
type: `${SCRIPT_PROVIDER_DISPATCH_ACTION.LOADING_STATUS}`; | ||
value: SCRIPT_LOADING_STATE; | ||
} | { | ||
type: `${SCRIPT_PROVIDER_DISPATCH_ACTION.RESET_OPTIONS}`; | ||
value: PayPalScriptOptions | ReactPayPalScriptOptions; | ||
} | { | ||
type: `${SCRIPT_PROVIDER_DISPATCH_ACTION.SET_BRAINTREE_INSTANCE}`; | ||
value: BraintreePayPalCheckout; | ||
}; | ||
@@ -22,9 +28,5 @@ export declare type InitialState = { | ||
braintreePayPalCheckoutInstance?: BraintreePayPalCheckout; | ||
dispatch: React.Dispatch<ScriptReducerAction> | null; | ||
dispatch?: Dispatch<ScriptReducerAction>; | ||
} | ||
export interface StrictScriptContextState extends ScriptContextState { | ||
dispatch: React.Dispatch<ScriptReducerAction>; | ||
} | ||
export interface ScriptContextDerivedState { | ||
options: ReactPayPalScriptOptions; | ||
export interface ScriptContextDerivedState extends Pick<ScriptContextState, "options"> { | ||
isInitial: boolean; | ||
@@ -37,4 +39,4 @@ isPending: boolean; | ||
options: PayPalScriptOptions; | ||
children?: React.ReactNode; | ||
children?: ReactNode; | ||
deferLoading?: boolean; | ||
} |
{ | ||
"name": "@paypal/react-paypal-js", | ||
"version": "7.3.3", | ||
"version": "7.4.0", | ||
"description": "React components for the PayPal JS SDK", | ||
@@ -20,2 +20,3 @@ "keywords": [ | ||
"build": "rollup --config", | ||
"check-node-version": "node scripts/check-node-version.js", | ||
"format": "prettier --write .", | ||
@@ -28,10 +29,12 @@ "lint": "eslint .", | ||
"test": "jest --env=jsdom", | ||
"start": "npm run storybook", | ||
"start": "npm run check-node-version && npm run storybook", | ||
"storybook": "start-storybook -p 6006", | ||
"build-storybook": "build-storybook", | ||
"deploy-storybook": "storybook-to-ghpages", | ||
"release": "node ./scripts/publish", | ||
"prerelease": "npm run validate", | ||
"release": "standard-version", | ||
"postrelease": "git push && git push --follow-tags && npm run build && npm publish", | ||
"typecheck": "tsc --noEmit", | ||
"type-declarations": "tsc --emitDeclarationOnly --outDir dist/types --project tsconfig.declarations.json", | ||
"validate": "npm run typecheck && npm run build && npm run lint && npm test -- --coverage" | ||
"validate": "npm run check-node-version && npm run typecheck && npm run build && npm run lint && npm test -- --coverage" | ||
}, | ||
@@ -48,36 +51,41 @@ "files": [ | ||
"dependencies": { | ||
"@paypal/paypal-js": "^4.0.8", | ||
"@paypal/sdk-constants": "^1.0.107" | ||
"@paypal/paypal-js": "^4.1.0", | ||
"@paypal/sdk-constants": "^1.0.110" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.14.8", | ||
"@babel/preset-env": "^7.14.8", | ||
"@babel/core": "^7.15.5", | ||
"@babel/preset-env": "^7.15.6", | ||
"@babel/preset-react": "^7.14.5", | ||
"@babel/preset-typescript": "^7.14.5", | ||
"@commitlint/cli": "^13.1.0", | ||
"@commitlint/config-conventional": "^13.1.0", | ||
"@babel/preset-typescript": "^7.15.0", | ||
"@commitlint/cli": "^13.2.0", | ||
"@commitlint/config-conventional": "^13.2.0", | ||
"@rollup/plugin-babel": "^5.3.0", | ||
"@rollup/plugin-node-resolve": "^13.0.4", | ||
"@rollup/plugin-node-resolve": "^13.0.5", | ||
"@rollup/plugin-replace": "^3.0.0", | ||
"@rollup/plugin-typescript": "^8.2.3", | ||
"@storybook/addon-actions": "^6.3.6", | ||
"@storybook/addon-essentials": "^6.3.6", | ||
"@storybook/addon-links": "^6.3.6", | ||
"@storybook/react": "^6.3.6", | ||
"@rollup/plugin-typescript": "^8.2.5", | ||
"@storybook/addon-actions": "^6.3.8", | ||
"@storybook/addon-essentials": "^6.3.8", | ||
"@storybook/addon-links": "^6.3.8", | ||
"@storybook/react": "^6.3.8", | ||
"@storybook/storybook-deployer": "^2.8.10", | ||
"@testing-library/react": "^12.0.0", | ||
"@types/react": "^17.0.15", | ||
"@typescript-eslint/eslint-plugin": "^4.28.5", | ||
"@typescript-eslint/parser": "^4.28.5", | ||
"babel-jest": "^27.0.6", | ||
"@testing-library/react": "^12.1.1", | ||
"@types/jest": "^27.0.2", | ||
"@types/react": "^17.0.25", | ||
"@types/react-dom": "^17.0.9", | ||
"@typescript-eslint/eslint-plugin": "^4.32.0", | ||
"@typescript-eslint/parser": "^4.32.0", | ||
"babel-jest": "^27.2.4", | ||
"babel-loader": "^8.2.2", | ||
"eslint": "^7.31.0", | ||
"chalk": "^4.1.2", | ||
"check-node-version": "^4.1.0", | ||
"eslint": "^7.32.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"eslint-plugin-react": "^7.24.0", | ||
"eslint-plugin-react": "^7.26.0", | ||
"eslint-plugin-react-hooks": "^4.2.0", | ||
"husky": "^7.0.1", | ||
"jest": "^27.0.6", | ||
"lint-staged": "^11.1.1", | ||
"husky": "^7.0.2", | ||
"jest": "^27.2.4", | ||
"jest-mock-extended": "^2.0.4", | ||
"lint-staged": "^11.1.2", | ||
"pinst": "^2.1.6", | ||
"prettier": "^2.3.2", | ||
"prettier": "^2.4.1", | ||
"react": "^16.14.0", | ||
@@ -88,3 +96,3 @@ "react-dom": "^16.14.0", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^2.55.0", | ||
"rollup": "^2.57.0", | ||
"rollup-plugin-cleanup": "^3.2.1", | ||
@@ -94,3 +102,3 @@ "rollup-plugin-terser": "^7.0.2", | ||
"standard-version": "^9.3.1", | ||
"typescript": "^4.3.5" | ||
"typescript": "^4.4.3" | ||
}, | ||
@@ -100,3 +108,8 @@ "peerDependencies": { | ||
"react-dom": ">=16.3.0" | ||
}, | ||
"jest": { | ||
"transformIgnorePatterns": [ | ||
"/!node_modules\\/@paypal\\/sdk-constants/" | ||
] | ||
} | ||
} |
@@ -210,4 +210,96 @@ # react-paypal-js | ||
### PayPal Hosted Fields | ||
The JS SDK hosted-fields component provides payment form functionality that you can customize. Read more about this integration in the [PayPal Advanced Card Payments documentation](https://developer.paypal.com/docs/business/checkout/advanced-card-payments/). | ||
There are 3 parts to the hosted-fields integration: | ||
1. The `<PayPalHostedFieldsProvider />` provider component wraps the form field elements and accepts props like `createOrder()`. | ||
2. The `<PayPalHostedField>` component is used for the credit card number, expiration, and cvv elements. These are customizable using props and must be children of the `<PayPalHostedFieldsProvider />` component. | ||
3. The `usePayPalHostedFields` hook exposes the `submit()` function for submitting the payment with your own custom button. | ||
```jsx | ||
import { | ||
PayPalScriptProvider, | ||
PayPalHostedFieldsProvider, | ||
PayPalHostedField, | ||
usePayPalHostedFields, | ||
} from "@paypal/react-paypal-js"; | ||
const SubmitPayment = () => { | ||
// Here declare the variable containing the hostedField instance | ||
const hostedFields = usePayPalHostedFields(); | ||
const submitHandler = () => { | ||
if (!typeof hostedFields.submit !== "function") return; // validate that `submit()` exists before using it | ||
hostedFields | ||
.submit({ | ||
// The full name as shown in the card and billing address | ||
cardholderName: "Jhon Wick", | ||
}) | ||
.then((order) => { | ||
fetch( | ||
"/your-server-side-integration-endpoint/capture-payment-info" | ||
) | ||
.then((response) => response.json()) | ||
.then((data) => { | ||
// Inside the data you can find all the information related to the payment | ||
}) | ||
.catch((err) => { | ||
// Handle any error | ||
}); | ||
}); | ||
}; | ||
return <button onClick={submitHandler}>Pay</button>; | ||
}; | ||
export default function App() { | ||
return ( | ||
<PayPalScriptProvider | ||
options={{ | ||
"client-id": "your-client-id", | ||
"data-client-token": "your-data-client-token", | ||
}} | ||
> | ||
<PayPalHostedFieldsProvider | ||
createOrder={() => { | ||
// Here define the call to create and order | ||
return fetch( | ||
"/your-server-side-integration-endpoint/orders" | ||
) | ||
.then((response) => response.json()) | ||
.then((order) => order.id) | ||
.catch((err) => { | ||
// Handle any error | ||
}); | ||
}} | ||
> | ||
<PayPalHostedField | ||
id="card-number" | ||
hostedFieldType="number" | ||
options={{ selector: "#card-number" }} | ||
/> | ||
<PayPalHostedField | ||
id="cvv" | ||
hostedFieldType="cvv" | ||
options={{ selector: "#cvv" }} | ||
/> | ||
<PayPalHostedField | ||
id="expiration-date" | ||
hostedFieldType="expirationDate" | ||
options={{ | ||
selector: "#expiration-date", | ||
placeholder: "MM/YY", | ||
}} | ||
/> | ||
<SubmitPayment /> | ||
</PayPalHostedFieldsProvider> | ||
</PayPalScriptProvider> | ||
); | ||
} | ||
``` | ||
### Browser Support | ||
This library supports all popular browsers, including IE 11. It provides the same browser support as the JS SDK. Here's the [full list of supported browsers](https://developer.paypal.com/docs/business/checkout/reference/browser-support/#supported-browsers-by-platform). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
213362
41
3599
305
46
1
Updated@paypal/paypal-js@^4.1.0