@bunnyapp/components 1.8.0-beta.8 → 1.8.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1015 -943
- package/dist/cjs/types/src/components/PaymentForm/DemoPay/DemoPayFormProvider.d.ts +10 -0
- package/dist/cjs/types/src/components/PaymentForm/DemoPay/hooks/usePay.d.ts +2 -4
- package/dist/cjs/types/src/components/PaymentForm/DemoPay/hooks/useSave.d.ts +1 -5
- package/dist/cjs/types/src/components/PaymentForm/PaymentForm.d.ts +40 -9
- package/dist/cjs/types/src/components/PaymentForm/Stripe/StripeFormProvider.d.ts +5 -0
- package/dist/cjs/types/src/components/PaymentForm/Stripe/hooks/usePay.d.ts +2 -4
- package/dist/cjs/types/src/components/PaymentForm/components/CheckoutNoPayment.d.ts +6 -0
- package/dist/cjs/types/src/components/PaymentForm/components/Pay.d.ts +5 -0
- package/dist/cjs/types/src/components/PaymentForm/components/PaymentMethodDetails/PaymentMethodDetails.d.ts +12 -0
- package/dist/cjs/types/src/components/PaymentForm/components/PaymentMethodDetails/components/Cancel.d.ts +1 -0
- package/dist/cjs/types/src/components/PaymentForm/components/PaymentMethodDetails/components/Save.d.ts +1 -0
- package/dist/cjs/types/src/components/PaymentForm/components/StoredPaymentMethods.d.ts +18 -0
- package/dist/cjs/types/src/components/PaymentForm/context/AccountIdContext.d.ts +5 -0
- package/dist/cjs/types/src/components/PaymentForm/context/CallbacksContext.d.ts +14 -0
- package/dist/cjs/types/src/components/PaymentForm/context/PaymentMethodFormVisibilityContext.d.ts +12 -0
- package/dist/cjs/types/src/components/PaymentForm/context/PaymentProvider.d.ts +46 -37
- package/dist/cjs/types/src/components/PaymentForm/hooks/usePay.d.ts +14 -0
- package/dist/cjs/types/src/components/PaymentForm/hooks/usePaymentButtonText.d.ts +7 -1
- package/dist/cjs/types/src/components/PaymentForm/hooks/usePaymentHold.d.ts +18 -0
- package/dist/cjs/types/src/components/PaymentForm/hooks/useSave.d.ts +16 -0
- package/dist/cjs/types/src/components/PaymentForm/types/PaymentType.d.ts +2 -1
- package/dist/cjs/types/src/hooks/usePaymentMethod.d.ts +4 -0
- package/dist/esm/index.js +1019 -947
- package/dist/esm/types/src/components/PaymentForm/DemoPay/DemoPayFormProvider.d.ts +10 -0
- package/dist/esm/types/src/components/PaymentForm/DemoPay/hooks/usePay.d.ts +2 -4
- package/dist/esm/types/src/components/PaymentForm/DemoPay/hooks/useSave.d.ts +1 -5
- package/dist/esm/types/src/components/PaymentForm/PaymentForm.d.ts +40 -9
- package/dist/esm/types/src/components/PaymentForm/Stripe/StripeFormProvider.d.ts +5 -0
- package/dist/esm/types/src/components/PaymentForm/Stripe/hooks/usePay.d.ts +2 -4
- package/dist/esm/types/src/components/PaymentForm/components/CheckoutNoPayment.d.ts +6 -0
- package/dist/esm/types/src/components/PaymentForm/components/Pay.d.ts +5 -0
- package/dist/esm/types/src/components/PaymentForm/components/PaymentMethodDetails/PaymentMethodDetails.d.ts +12 -0
- package/dist/esm/types/src/components/PaymentForm/components/PaymentMethodDetails/components/Cancel.d.ts +1 -0
- package/dist/esm/types/src/components/PaymentForm/components/PaymentMethodDetails/components/Save.d.ts +1 -0
- package/dist/esm/types/src/components/PaymentForm/components/StoredPaymentMethods.d.ts +18 -0
- package/dist/esm/types/src/components/PaymentForm/context/AccountIdContext.d.ts +5 -0
- package/dist/esm/types/src/components/PaymentForm/context/CallbacksContext.d.ts +14 -0
- package/dist/esm/types/src/components/PaymentForm/context/PaymentMethodFormVisibilityContext.d.ts +12 -0
- package/dist/esm/types/src/components/PaymentForm/context/PaymentProvider.d.ts +46 -37
- package/dist/esm/types/src/components/PaymentForm/hooks/usePay.d.ts +14 -0
- package/dist/esm/types/src/components/PaymentForm/hooks/usePaymentButtonText.d.ts +7 -1
- package/dist/esm/types/src/components/PaymentForm/hooks/usePaymentHold.d.ts +18 -0
- package/dist/esm/types/src/components/PaymentForm/hooks/useSave.d.ts +16 -0
- package/dist/esm/types/src/components/PaymentForm/types/PaymentType.d.ts +2 -1
- package/dist/esm/types/src/hooks/usePaymentMethod.d.ts +4 -0
- package/dist/index.d.ts +64 -9
- package/package.json +1 -1
- package/dist/cjs/types/src/components/PaymentForm/components/CheckoutFooter.d.ts +0 -2
- package/dist/cjs/types/src/components/PaymentForm/components/PaymentMethodDetails.d.ts +0 -2
- package/dist/cjs/types/src/components/PaymentForm/components/PaymentMethodFooter.d.ts +0 -4
- package/dist/cjs/types/src/components/PaymentForm/hooks/useHandlePayment.d.ts +0 -41
- package/dist/esm/types/src/components/PaymentForm/components/CheckoutFooter.d.ts +0 -2
- package/dist/esm/types/src/components/PaymentForm/components/PaymentMethodDetails.d.ts +0 -2
- package/dist/esm/types/src/components/PaymentForm/components/PaymentMethodFooter.d.ts +0 -4
- package/dist/esm/types/src/components/PaymentForm/hooks/useHandlePayment.d.ts +0 -41
- /package/dist/cjs/types/src/components/PaymentForm/components/{PaymentMethodSelector.d.ts → PaymentMethodDetails/components/PaymentMethodSelector.d.ts} +0 -0
- /package/dist/esm/types/src/components/PaymentForm/components/{PaymentMethodSelector.d.ts → PaymentMethodDetails/components/PaymentMethodSelector.d.ts} +0 -0
package/dist/cjs/index.js
CHANGED
|
@@ -1283,7 +1283,7 @@ const DEFAULT_CONFIG = {
|
|
|
1283
1283
|
};
|
|
1284
1284
|
|
|
1285
1285
|
// This will be replaced at build time by rollup-plugin-replace
|
|
1286
|
-
const PACKAGE_VERSION = '1.8.0-beta.
|
|
1286
|
+
const PACKAGE_VERSION = '1.8.0-beta.8';
|
|
1287
1287
|
const createRequestHeaders = (token) => {
|
|
1288
1288
|
const headers = createClientDevHeaders({ token });
|
|
1289
1289
|
// Add the components version header
|
|
@@ -19845,60 +19845,6 @@ const PaymentForm_PaymentMethodsFragment = t(`
|
|
|
19845
19845
|
}
|
|
19846
19846
|
`, [MiniCreditCard_PaymentMethodFragment]);
|
|
19847
19847
|
|
|
19848
|
-
const query$9 = t(`
|
|
19849
|
-
query PaymentMethods($accountId: ID) {
|
|
19850
|
-
paymentMethods(accountId: $accountId) {
|
|
19851
|
-
nodes {
|
|
19852
|
-
id
|
|
19853
|
-
pluginId
|
|
19854
|
-
accountId
|
|
19855
|
-
expirationDate
|
|
19856
|
-
plugin {
|
|
19857
|
-
guid
|
|
19858
|
-
id
|
|
19859
|
-
}
|
|
19860
|
-
state
|
|
19861
|
-
metadata {
|
|
19862
|
-
issuer
|
|
19863
|
-
identifier
|
|
19864
|
-
kind
|
|
19865
|
-
description
|
|
19866
|
-
icon
|
|
19867
|
-
type
|
|
19868
|
-
}
|
|
19869
|
-
isDefault
|
|
19870
|
-
...PaymentForm_PaymentMethodsFragment
|
|
19871
|
-
}
|
|
19872
|
-
}
|
|
19873
|
-
}
|
|
19874
|
-
`, [PaymentForm_PaymentMethodsFragment]);
|
|
19875
|
-
const getPaymentMethods = async ({ apiHost, token, accountId, }) => {
|
|
19876
|
-
var _a, _b, _c;
|
|
19877
|
-
const response = await execute(query$9, { apiHost, token }, { accountId });
|
|
19878
|
-
// Filter out null values that are technically possible due to api schema
|
|
19879
|
-
return (_c = (_b = (_a = response === null || response === void 0 ? void 0 : response.paymentMethods) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.filter(paymentMethod => paymentMethod !== null)) !== null && _c !== void 0 ? _c : [];
|
|
19880
|
-
};
|
|
19881
|
-
const usePaymentMethod = ({ accountId, enabled = true, }) => {
|
|
19882
|
-
// Context
|
|
19883
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
19884
|
-
const token = useToken();
|
|
19885
|
-
// Query
|
|
19886
|
-
const { data, isLoading } = reactQuery.useQuery({
|
|
19887
|
-
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
19888
|
-
accountId,
|
|
19889
|
-
token,
|
|
19890
|
-
}),
|
|
19891
|
-
queryFn: () => getPaymentMethods({ apiHost, token, accountId }),
|
|
19892
|
-
staleTime: 5 * 60 * 1000, // Consider data fresh for 5 minutes
|
|
19893
|
-
enabled,
|
|
19894
|
-
});
|
|
19895
|
-
return {
|
|
19896
|
-
paymentMethods: data,
|
|
19897
|
-
defaultPaymentMethod: data === null || data === void 0 ? void 0 : data.find(paymentMethod => paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.isDefault),
|
|
19898
|
-
isLoading,
|
|
19899
|
-
};
|
|
19900
|
-
};
|
|
19901
|
-
|
|
19902
19848
|
const mutation$i = t(`
|
|
19903
19849
|
query PaymentPlugins($accountId: ID) {
|
|
19904
19850
|
paymentPlugins(accountId: $accountId) {
|
|
@@ -19954,63 +19900,53 @@ const usePaymentPlugins = (accountId) => {
|
|
|
19954
19900
|
};
|
|
19955
19901
|
};
|
|
19956
19902
|
|
|
19957
|
-
|
|
19958
|
-
* Creates a context and provider for a state value
|
|
19959
|
-
* @param useValue - A function that returns the state value
|
|
19960
|
-
* @returns A tuple containing the provider and the context value
|
|
19961
|
-
* @example take a look at how this is used in the quoteIdContext in the QuantityDrawer
|
|
19962
|
-
*/
|
|
19963
|
-
const createStateContext = (useValue) => {
|
|
19964
|
-
const StateContext = react.createContext(null);
|
|
19965
|
-
const StateProvider = ({ initialValue, children, }) => jsxRuntime.jsxs(StateContext.Provider, { value: useValue(initialValue), children: [" ", children, " "] });
|
|
19966
|
-
const useContextState = () => {
|
|
19967
|
-
const value = react.useContext(StateContext);
|
|
19968
|
-
if (value === null) {
|
|
19969
|
-
throw new Error('Provider missing');
|
|
19970
|
-
}
|
|
19971
|
-
return value;
|
|
19972
|
-
};
|
|
19973
|
-
return [StateProvider, useContextState];
|
|
19974
|
-
};
|
|
19903
|
+
const [PaymentFormCallbacksProvider, usePaymentFormCallbacks] = createValueContext();
|
|
19975
19904
|
|
|
19976
|
-
//
|
|
19977
|
-
const
|
|
19978
|
-
|
|
19979
|
-
|
|
19980
|
-
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
function
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19993
|
-
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
19905
|
+
// Used for Signup component. Signup uses an apiClient token which api can't infer an account from, so accountId must be used
|
|
19906
|
+
const [AccountIdProvider, useAccountId] = createValueContext();
|
|
19907
|
+
|
|
19908
|
+
// Automatically sets the default payment method if there is none currently set
|
|
19909
|
+
const useAutoSetDefaultPaymentMethod = ({ handleSetDefault, setDefaultPaymentMethodLoading, enabled = true, }) => {
|
|
19910
|
+
const accountId = useAccountId();
|
|
19911
|
+
const token = useToken();
|
|
19912
|
+
const queryClient = reactQuery.useQueryClient();
|
|
19913
|
+
const { paymentMethods, defaultPaymentMethod } = usePaymentMethod({
|
|
19914
|
+
accountId,
|
|
19915
|
+
});
|
|
19916
|
+
// Set the default payment method on the cache. Prevents 'handleSetDefault' from being called too many times.
|
|
19917
|
+
function setDefaultPaymentMethodOnCache(targetPaymentMethod) {
|
|
19918
|
+
let cachedPaymentMethods = queryClient.getQueryData(QueryKeyFactory.accountPaymentMethodsKey({
|
|
19919
|
+
accountId,
|
|
19920
|
+
token,
|
|
19921
|
+
}));
|
|
19922
|
+
if (cachedPaymentMethods) {
|
|
19923
|
+
for (const paymentMethod of cachedPaymentMethods) {
|
|
19924
|
+
paymentMethod.isDefault = paymentMethod.id === targetPaymentMethod.id;
|
|
19925
|
+
}
|
|
19926
|
+
queryClient.setQueryData(QueryKeyFactory.accountPaymentMethodsKey({
|
|
19927
|
+
accountId,
|
|
19928
|
+
token,
|
|
19929
|
+
}), cachedPaymentMethods);
|
|
19930
|
+
}
|
|
19931
|
+
}
|
|
20000
19932
|
react.useEffect(() => {
|
|
20001
|
-
var _a
|
|
20002
|
-
if (
|
|
19933
|
+
var _a;
|
|
19934
|
+
if (setDefaultPaymentMethodLoading || !enabled)
|
|
20003
19935
|
return;
|
|
19936
|
+
if ((paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) && (paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) > 0 && !defaultPaymentMethod) {
|
|
19937
|
+
handleSetDefault((_a = paymentMethods[0]) === null || _a === void 0 ? void 0 : _a.id);
|
|
19938
|
+
setDefaultPaymentMethodOnCache(paymentMethods[0]);
|
|
20004
19939
|
}
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
|
|
20010
|
-
|
|
20011
|
-
|
|
20012
|
-
|
|
20013
|
-
|
|
19940
|
+
}, [
|
|
19941
|
+
paymentMethods,
|
|
19942
|
+
defaultPaymentMethod,
|
|
19943
|
+
handleSetDefault,
|
|
19944
|
+
setDefaultPaymentMethodLoading,
|
|
19945
|
+
queryClient,
|
|
19946
|
+
accountId,
|
|
19947
|
+
token,
|
|
19948
|
+
]);
|
|
19949
|
+
};
|
|
20014
19950
|
|
|
20015
19951
|
const request = ({ method = 'GET', apiHost, endpoint, body, headers, token, }) => {
|
|
20016
19952
|
const { apiEndpoint } = DEFAULT_CONFIG;
|
|
@@ -20055,222 +19991,232 @@ const invokePlugin = async ({ method, payload, plugin, token, apiHost, component
|
|
|
20055
19991
|
throw new Error(error.message);
|
|
20056
19992
|
};
|
|
20057
19993
|
|
|
20058
|
-
|
|
20059
|
-
|
|
20060
|
-
const
|
|
20061
|
-
const isNavigation = (char) => [9, 37, 38, 39, 40].includes(char); // Tab, Arrows
|
|
20062
|
-
const isModifier = (char) => [16, 17, 18].includes(char); // Shift, Ctrl, Alt
|
|
20063
|
-
const isValidKey = (code) => isDeletion(code) || isNavigation(code) || isModifier(code);
|
|
20064
|
-
const isValidExpiry = (expiry) => {
|
|
20065
|
-
const month = parseInt(expiry.substring(0, 2), 10);
|
|
20066
|
-
const year = parseInt(expiry.substring(2, 4), 10) + 2000;
|
|
20067
|
-
if (isNaN(month) || isNaN(year))
|
|
20068
|
-
return false;
|
|
20069
|
-
if (month < 1 || month > 12)
|
|
20070
|
-
return false;
|
|
20071
|
-
return true;
|
|
20072
|
-
};
|
|
20073
|
-
const isCardExpired = (expiry) => {
|
|
20074
|
-
const month = parseInt(expiry.substring(0, 2), 10);
|
|
20075
|
-
const year = parseInt(expiry.substring(2, 4), 10) + 2000;
|
|
20076
|
-
const expiryDate = new Date(year, month, 1);
|
|
20077
|
-
return expiryDate < new Date();
|
|
20078
|
-
};
|
|
20079
|
-
const formatCardExpiry = (cardExpiry) => {
|
|
20080
|
-
if (cardExpiry.length <= 2)
|
|
20081
|
-
return cardExpiry;
|
|
20082
|
-
return cardExpiry.substring(0, 2) + '/' + cardExpiry.substring(2);
|
|
20083
|
-
};
|
|
20084
|
-
// removes spaces from a credit card number
|
|
20085
|
-
const unformatCardNumber = (cardNumber) => {
|
|
20086
|
-
const cardNumberArray = cardNumber.split('');
|
|
20087
|
-
const unformattedCardNumberArray = cardNumberArray.filter(character => character !== ' ');
|
|
20088
|
-
return unformattedCardNumberArray.join('');
|
|
20089
|
-
};
|
|
20090
|
-
const storePayment = async (options, plugin, apiHost, accountId) => {
|
|
20091
|
-
const { testCreditCardNumber, testCreditCardCvc, testCreditCardExpirationDate, token } = options;
|
|
20092
|
-
const response = await invokePlugin({
|
|
20093
|
-
method: 'store_payment_method',
|
|
20094
|
-
plugin,
|
|
20095
|
-
payload: {
|
|
20096
|
-
test_credit_card_number: testCreditCardNumber,
|
|
20097
|
-
test_credit_card_cvc: testCreditCardCvc,
|
|
20098
|
-
test_credit_card_expiration_date: testCreditCardExpirationDate,
|
|
20099
|
-
account_id: accountId,
|
|
20100
|
-
},
|
|
20101
|
-
token,
|
|
20102
|
-
apiHost,
|
|
20103
|
-
});
|
|
20104
|
-
if ((response === null || response === void 0 ? void 0 : response.status) !== 'success')
|
|
20105
|
-
throw new Error(response === null || response === void 0 ? void 0 : response.message);
|
|
20106
|
-
return response;
|
|
20107
|
-
};
|
|
20108
|
-
|
|
20109
|
-
function useSave$1({ onSaveSuccess, onSaveError, accountId, }) {
|
|
20110
|
-
const [isSaving, setIsSaving] = react.useState(false);
|
|
20111
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
19994
|
+
function useSetDefaultPaymentMethod(onError, onSuccess) {
|
|
19995
|
+
// Context
|
|
19996
|
+
const accountId = useAccountId();
|
|
20112
19997
|
const token = useToken();
|
|
20113
|
-
const
|
|
20114
|
-
const
|
|
20115
|
-
|
|
20116
|
-
|
|
20117
|
-
|
|
20118
|
-
|
|
20119
|
-
|
|
20120
|
-
|
|
20121
|
-
|
|
20122
|
-
|
|
20123
|
-
|
|
20124
|
-
|
|
20125
|
-
|
|
20126
|
-
|
|
20127
|
-
pluginPaymentResponse: {
|
|
20128
|
-
plugin,
|
|
20129
|
-
token: response.token,
|
|
20130
|
-
savePaymentMethod: true,
|
|
20131
|
-
},
|
|
20132
|
-
savedPaymentMethodResponse: {
|
|
20133
|
-
paymentMethodId,
|
|
20134
|
-
},
|
|
20135
|
-
});
|
|
20136
|
-
return paymentMethodId;
|
|
20137
|
-
}
|
|
20138
|
-
catch (error) {
|
|
20139
|
-
onSaveError === null || onSaveError === void 0 ? void 0 : onSaveError(error);
|
|
20140
|
-
}
|
|
20141
|
-
finally {
|
|
20142
|
-
setIsSaving(false);
|
|
19998
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
19999
|
+
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
20000
|
+
const { paymentMethods } = usePaymentMethod({ accountId });
|
|
20001
|
+
// Hooks
|
|
20002
|
+
const showErrorNotification = useErrorNotification();
|
|
20003
|
+
const showSuccessNotification = useSuccessNotification();
|
|
20004
|
+
const queryClient = reactQuery.useQueryClient();
|
|
20005
|
+
// State
|
|
20006
|
+
const [loading, setLoading] = react.useState(false);
|
|
20007
|
+
const setDefaultPaymentMethod = react.useCallback(async (paymentMethodId) => {
|
|
20008
|
+
const paymentMethod = paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.find(paymentMethod => (paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id) === paymentMethodId);
|
|
20009
|
+
if (paymentMethod === undefined) {
|
|
20010
|
+
showErrorNotification('Payment method not found', 'Error setting default payment method');
|
|
20011
|
+
return;
|
|
20143
20012
|
}
|
|
20144
|
-
return
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20161
|
-
|
|
20162
|
-
|
|
20163
|
-
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
|
|
20174
|
-
|
|
20175
|
-
|
|
20176
|
-
|
|
20177
|
-
|
|
20178
|
-
|
|
20013
|
+
const plugin = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.find(paymentPlugin => { var _a; return String(paymentPlugin.id) === ((_a = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.plugin) === null || _a === void 0 ? void 0 : _a.id); }); // TODO: type the response to PluginData
|
|
20014
|
+
if (plugin) {
|
|
20015
|
+
setLoading(true);
|
|
20016
|
+
await invokePlugin({
|
|
20017
|
+
plugin: plugin,
|
|
20018
|
+
method: 'assign_default_payment_method',
|
|
20019
|
+
payload: {
|
|
20020
|
+
payment_method_id: paymentMethod.id,
|
|
20021
|
+
account_id: accountId,
|
|
20022
|
+
},
|
|
20023
|
+
token,
|
|
20024
|
+
apiHost,
|
|
20025
|
+
})
|
|
20026
|
+
.then(() => {
|
|
20027
|
+
var _a;
|
|
20028
|
+
showSuccessNotification(`Payment method ${(_a = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.metadata) === null || _a === void 0 ? void 0 : _a.identifier} was set as default`, 'Success');
|
|
20029
|
+
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
|
|
20030
|
+
queryClient.invalidateQueries({
|
|
20031
|
+
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
20032
|
+
token,
|
|
20033
|
+
accountId,
|
|
20034
|
+
}),
|
|
20035
|
+
});
|
|
20036
|
+
})
|
|
20037
|
+
.catch((error) => {
|
|
20038
|
+
setLoading(false);
|
|
20039
|
+
showErrorNotification(error.message, 'Error removing payment method');
|
|
20040
|
+
})
|
|
20041
|
+
.finally(() => {
|
|
20042
|
+
setLoading(false);
|
|
20043
|
+
});
|
|
20044
|
+
}
|
|
20045
|
+
else {
|
|
20046
|
+
const availablePlugins = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.map((plugin) => { var _a, _b, _c; return (_c = (_b = (_a = plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name; });
|
|
20047
|
+
onError === null || onError === void 0 ? void 0 : onError(`Either the payment method was not found or the plugin was not present. Available plugins: ${availablePlugins === null || availablePlugins === void 0 ? void 0 : availablePlugins.join(', ')}`);
|
|
20048
|
+
}
|
|
20049
|
+
}, [paymentPlugins, token, apiHost, queryClient]);
|
|
20050
|
+
return { setDefaultPaymentMethod, loading };
|
|
20051
|
+
}
|
|
20052
|
+
|
|
20053
|
+
function useRemovePaymentMethod(onPaymentMethodRemoved, onError) {
|
|
20054
|
+
const queryClient = reactQuery.useQueryClient();
|
|
20055
|
+
const showErrorNotification = useErrorNotification();
|
|
20056
|
+
const showSuccessNotification = useSuccessNotification();
|
|
20057
|
+
const accountId = useAccountId();
|
|
20058
|
+
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
20059
|
+
const token = useToken();
|
|
20060
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
20061
|
+
const removePaymentMethod = react.useCallback(async (data) => {
|
|
20062
|
+
const plugin = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.find(paymentPlugin => { var _a; return String(paymentPlugin.id) === String((_a = data === null || data === void 0 ? void 0 : data.plugin) === null || _a === void 0 ? void 0 : _a.id); });
|
|
20063
|
+
if (data && plugin) {
|
|
20064
|
+
await invokePlugin({
|
|
20065
|
+
plugin: plugin, // TODO: type the plugin
|
|
20066
|
+
method: 'remove_payment_method',
|
|
20067
|
+
payload: {
|
|
20068
|
+
payment_method_id: data.id,
|
|
20069
|
+
account_id: accountId,
|
|
20070
|
+
},
|
|
20071
|
+
token,
|
|
20072
|
+
apiHost,
|
|
20073
|
+
})
|
|
20074
|
+
.then(() => {
|
|
20075
|
+
showSuccessNotification('Payment method was removed', 'Success');
|
|
20076
|
+
queryClient.invalidateQueries({
|
|
20077
|
+
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
20078
|
+
token,
|
|
20079
|
+
accountId,
|
|
20080
|
+
}),
|
|
20081
|
+
});
|
|
20082
|
+
onPaymentMethodRemoved === null || onPaymentMethodRemoved === void 0 ? void 0 : onPaymentMethodRemoved(data);
|
|
20083
|
+
})
|
|
20084
|
+
.catch((error) => {
|
|
20085
|
+
showErrorNotification(error.message, 'Error removing payment method');
|
|
20086
|
+
});
|
|
20087
|
+
}
|
|
20088
|
+
else {
|
|
20089
|
+
const availablePlugins = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.map(plugin => {
|
|
20090
|
+
var _a, _b;
|
|
20091
|
+
const components = plugin.components;
|
|
20092
|
+
return (_b = (_a = components === null || components === void 0 ? void 0 : components.frontend) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.name;
|
|
20093
|
+
});
|
|
20094
|
+
onError === null || onError === void 0 ? void 0 : onError(`Either the payment method was not found or the plugin was not present. Available plugins: ${availablePlugins === null || availablePlugins === void 0 ? void 0 : availablePlugins.join(', ')}`);
|
|
20095
|
+
}
|
|
20096
|
+
}, [paymentPlugins, token, apiHost, queryClient, onPaymentMethodRemoved, accountId, onError]);
|
|
20097
|
+
return removePaymentMethod;
|
|
20098
|
+
}
|
|
20099
|
+
|
|
20100
|
+
const StoredPaymentMethods_PaymentMethodsFragment = t(`
|
|
20101
|
+
fragment StoredPaymentMethods_PaymentMethodsFragment on PaymentMethod {
|
|
20102
|
+
...MiniCreditCard_PaymentMethodFragment
|
|
20103
|
+
id
|
|
20104
|
+
plugin {
|
|
20179
20105
|
id
|
|
20180
|
-
amount
|
|
20181
20106
|
}
|
|
20182
20107
|
}
|
|
20183
|
-
|
|
20184
|
-
|
|
20185
|
-
|
|
20186
|
-
const
|
|
20187
|
-
|
|
20188
|
-
|
|
20189
|
-
|
|
20190
|
-
};
|
|
20191
|
-
|
|
20192
|
-
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20108
|
+
`, [MiniCreditCard_PaymentMethodFragment]);
|
|
20109
|
+
const showErrorNotification$d = useErrorNotification();
|
|
20110
|
+
function StoredPaymentMethods(props = {}) {
|
|
20111
|
+
const { className } = props;
|
|
20112
|
+
const accountId = useAccountId();
|
|
20113
|
+
const { paymentMethods, isLoading: isPaymentMethodLoading } = usePaymentMethod({ accountId });
|
|
20114
|
+
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
20115
|
+
const { onSetDefaultPaymentMethod, onPaymentMethodRemoved } = usePaymentFormCallbacks();
|
|
20116
|
+
// Custom hooks
|
|
20117
|
+
const { setDefaultPaymentMethod: handleSetDefault, loading: setDefaultPaymentMethodLoading } = useSetDefaultPaymentMethod(message => {
|
|
20118
|
+
showErrorNotification$d(message, 'Error setting default payment method');
|
|
20119
|
+
}, () => {
|
|
20120
|
+
onSetDefaultPaymentMethod === null || onSetDefaultPaymentMethod === void 0 ? void 0 : onSetDefaultPaymentMethod();
|
|
20121
|
+
});
|
|
20122
|
+
useAutoSetDefaultPaymentMethod({
|
|
20123
|
+
handleSetDefault,
|
|
20124
|
+
setDefaultPaymentMethodLoading,
|
|
20125
|
+
enabled: !!paymentPlugins,
|
|
20126
|
+
});
|
|
20127
|
+
const handleRemovePaymentMethod = useRemovePaymentMethod(onPaymentMethodRemoved, message => {
|
|
20128
|
+
showErrorNotification$d(message, 'Error removing payment method');
|
|
20129
|
+
});
|
|
20130
|
+
if (isPaymentMethodLoading) {
|
|
20131
|
+
return jsxRuntime.jsx(antd.Skeleton, { active: true, className: "bunny-p-4" });
|
|
20196
20132
|
}
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20133
|
+
return (jsxRuntime.jsxs("div", { className: `bunny-flex bunny-flex-col bunny-gap-2 ${className}`, children: [paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.map(maskedPaymentMethod => {
|
|
20134
|
+
const paymentMethod = readFragment(StoredPaymentMethods_PaymentMethodsFragment, maskedPaymentMethod);
|
|
20135
|
+
return (jsxRuntime.jsx(MiniCreditCard, { onClickRemove: () => handleRemovePaymentMethod(paymentMethod), onClickSetDefault: () => handleSetDefault(paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id), paymentMethod: paymentMethod, id: `payment-method-${paymentMethod.id}` }, paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id));
|
|
20136
|
+
}), (paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) === 0 && jsxRuntime.jsx(MiniCreditCard, {})] }));
|
|
20137
|
+
}
|
|
20138
|
+
|
|
20139
|
+
const query$9 = t(`
|
|
20140
|
+
query PaymentMethods($accountId: ID) {
|
|
20141
|
+
paymentMethods(accountId: $accountId) {
|
|
20142
|
+
nodes {
|
|
20143
|
+
id
|
|
20144
|
+
pluginId
|
|
20145
|
+
accountId
|
|
20146
|
+
expirationDate
|
|
20147
|
+
plugin {
|
|
20148
|
+
guid
|
|
20149
|
+
id
|
|
20150
|
+
}
|
|
20151
|
+
state
|
|
20152
|
+
metadata {
|
|
20153
|
+
issuer
|
|
20154
|
+
identifier
|
|
20155
|
+
kind
|
|
20156
|
+
description
|
|
20157
|
+
icon
|
|
20158
|
+
type
|
|
20159
|
+
}
|
|
20160
|
+
isDefault
|
|
20161
|
+
...PaymentForm_PaymentMethodsFragment
|
|
20162
|
+
...StoredPaymentMethods_PaymentMethodsFragment
|
|
20163
|
+
}
|
|
20164
|
+
}
|
|
20165
|
+
}
|
|
20166
|
+
`, [PaymentForm_PaymentMethodsFragment, StoredPaymentMethods_PaymentMethodsFragment]);
|
|
20167
|
+
const getPaymentMethods = async ({ apiHost, token, accountId, }) => {
|
|
20168
|
+
var _a, _b, _c;
|
|
20169
|
+
const response = await execute(query$9, { apiHost, token }, { accountId });
|
|
20170
|
+
// Filter out null values that are technically possible due to api schema
|
|
20171
|
+
return (_c = (_b = (_a = response === null || response === void 0 ? void 0 : response.paymentMethods) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b.filter(paymentMethod => paymentMethod !== null)) !== null && _c !== void 0 ? _c : [];
|
|
20172
|
+
};
|
|
20173
|
+
const usePaymentMethod = ({ accountId, enabled = true, }) => {
|
|
20174
|
+
// Context
|
|
20175
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
20176
|
+
const token = useToken();
|
|
20177
|
+
// Query
|
|
20178
|
+
const { data, isLoading } = reactQuery.useQuery({
|
|
20179
|
+
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
20180
|
+
accountId,
|
|
20181
|
+
token,
|
|
20182
|
+
}),
|
|
20183
|
+
queryFn: () => getPaymentMethods({ apiHost, token, accountId }),
|
|
20184
|
+
staleTime: 5 * 60 * 1000, // Consider data fresh for 5 minutes
|
|
20185
|
+
enabled,
|
|
20202
20186
|
});
|
|
20203
|
-
const { errors } = response === null || response === void 0 ? void 0 : response.checkout;
|
|
20204
|
-
if (errors)
|
|
20205
|
-
throw errors;
|
|
20206
20187
|
return {
|
|
20207
|
-
|
|
20188
|
+
paymentMethods: data,
|
|
20189
|
+
defaultPaymentMethod: data === null || data === void 0 ? void 0 : data.find(paymentMethod => paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.isDefault),
|
|
20190
|
+
isLoading,
|
|
20208
20191
|
};
|
|
20209
20192
|
};
|
|
20210
20193
|
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
}
|
|
20225
|
-
|
|
20226
|
-
var dayjs_minExports = requireDayjs_min();
|
|
20227
|
-
var dayjs = /*@__PURE__*/getDefaultExportFromCjs(dayjs_minExports);
|
|
20228
|
-
|
|
20229
|
-
var localizedFormat$2 = {exports: {}};
|
|
20230
|
-
|
|
20231
|
-
var localizedFormat$1 = localizedFormat$2.exports;
|
|
20232
|
-
|
|
20233
|
-
var hasRequiredLocalizedFormat;
|
|
20234
|
-
|
|
20235
|
-
function requireLocalizedFormat () {
|
|
20236
|
-
if (hasRequiredLocalizedFormat) return localizedFormat$2.exports;
|
|
20237
|
-
hasRequiredLocalizedFormat = 1;
|
|
20238
|
-
(function (module, exports) {
|
|
20239
|
-
!function(e,t){module.exports=t();}(localizedFormat$1,(function(){var e={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};return function(t,o,n){var r=o.prototype,i=r.format;n.en.formats=e,r.format=function(t){void 0===t&&(t="YYYY-MM-DDTHH:mm:ssZ");var o=this.$locale().formats,n=function(t,o){return t.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var i=r&&r.toUpperCase();return n||o[r]||e[r]||o[i].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,o){return t||o.slice(1)}))}))}(t,void 0===o?{}:o);return i.call(this,n)};}}));
|
|
20240
|
-
} (localizedFormat$2));
|
|
20241
|
-
return localizedFormat$2.exports;
|
|
20242
|
-
}
|
|
20243
|
-
|
|
20244
|
-
var localizedFormatExports = requireLocalizedFormat();
|
|
20245
|
-
var localizedFormat = /*@__PURE__*/getDefaultExportFromCjs(localizedFormatExports);
|
|
20246
|
-
|
|
20247
|
-
dayjs.extend(localizedFormat);
|
|
20248
|
-
const formatCurrency = (value, currencyIsoCode, decimals = 2) => {
|
|
20249
|
-
if (value !== 0 && !value)
|
|
20250
|
-
return '';
|
|
20251
|
-
const currencyValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
20252
|
-
if (isNaN(currencyValue))
|
|
20194
|
+
/**
|
|
20195
|
+
* Creates a context and provider for a state value
|
|
20196
|
+
* @param useValue - A function that returns the state value
|
|
20197
|
+
* @returns A tuple containing the provider and the context value
|
|
20198
|
+
* @example take a look at how this is used in the quoteIdContext in the QuantityDrawer
|
|
20199
|
+
*/
|
|
20200
|
+
const createStateContext = (useValue) => {
|
|
20201
|
+
const StateContext = react.createContext(null);
|
|
20202
|
+
const StateProvider = ({ initialValue, children, }) => jsxRuntime.jsxs(StateContext.Provider, { value: useValue(initialValue), children: [" ", children, " "] });
|
|
20203
|
+
const useContextState = () => {
|
|
20204
|
+
const value = react.useContext(StateContext);
|
|
20205
|
+
if (value === null) {
|
|
20206
|
+
throw new Error('Provider missing');
|
|
20207
|
+
}
|
|
20253
20208
|
return value;
|
|
20254
|
-
const localeOptions = {
|
|
20255
|
-
minimumFractionDigits: decimals,
|
|
20256
|
-
maximumFractionDigits: decimals,
|
|
20257
20209
|
};
|
|
20258
|
-
|
|
20259
|
-
localeOptions.currency = currencyIsoCode;
|
|
20260
|
-
return currencyValue.toLocaleString(navigator.language, localeOptions);
|
|
20210
|
+
return [StateProvider, useContextState];
|
|
20261
20211
|
};
|
|
20262
20212
|
|
|
20263
|
-
const
|
|
20264
|
-
|
|
20265
|
-
|
|
20266
|
-
|
|
20267
|
-
}
|
|
20268
|
-
`, []);
|
|
20269
|
-
const getQuoteAmountDue = (maskedQuote) => {
|
|
20270
|
-
var _a;
|
|
20271
|
-
const quote = readFragment(getQuoteAmountDue_QuoteFragment, maskedQuote);
|
|
20272
|
-
return (_a = quote.amountDue) !== null && _a !== void 0 ? _a : quote.amount;
|
|
20213
|
+
const defaultCardDetails = {
|
|
20214
|
+
number: '4242424242424242',
|
|
20215
|
+
expiry: '',
|
|
20216
|
+
cvc: '',
|
|
20273
20217
|
};
|
|
20218
|
+
const useDemoPayCardDetailsState = (initialValue) => react.useState(initialValue !== null && initialValue !== void 0 ? initialValue : defaultCardDetails);
|
|
20219
|
+
const [DemoPayFormProvider, useDemoPayCardDetails] = createStateContext(useDemoPayCardDetailsState);
|
|
20274
20220
|
|
|
20275
20221
|
const { useToken: useAntdToken$1 } = antd.theme;
|
|
20276
20222
|
const createPaymentMethod = async ({ paymentMethodId, plugin, token, apiHost, accountId, }) => {
|
|
@@ -20412,6 +20358,277 @@ const useStripePlugin = (plugin, currencyId, accountId) => {
|
|
|
20412
20358
|
return { stripe, options };
|
|
20413
20359
|
};
|
|
20414
20360
|
|
|
20361
|
+
// Contexts
|
|
20362
|
+
const useSelectedPluginIdState = (id) => react.useState(id);
|
|
20363
|
+
const [SelectedPluginIdProvider, useSelectedPluginId] = createStateContext(useSelectedPluginIdState);
|
|
20364
|
+
const [SelectedPluginDataProvider, useSelectedPlugin] = createValueContext(); // TODO: type the response to PluginData
|
|
20365
|
+
/**
|
|
20366
|
+
* SelectedPluginProvider manages the selected payment plugin state.
|
|
20367
|
+
*
|
|
20368
|
+
* Data Flow Pattern:
|
|
20369
|
+
* - Children components should set the plugin ID using `setSelectedPluginId` from `useSelectedPluginId`
|
|
20370
|
+
* - This provider then derives the `selectedPlugin` from that ID and provides it via `useSelectedPlugin`
|
|
20371
|
+
* - This ensures that data flows only downward: children control the ID, and the provider computes and provides the data
|
|
20372
|
+
*/
|
|
20373
|
+
function SelectedPluginProvider({ children, accountId, }) {
|
|
20374
|
+
return (jsxRuntime.jsx(SelectedPluginIdProvider, { initialValue: undefined, children: jsxRuntime.jsx(Content, { accountId: accountId, children: children }) }));
|
|
20375
|
+
}
|
|
20376
|
+
function Content({ children, accountId }) {
|
|
20377
|
+
// Context
|
|
20378
|
+
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
20379
|
+
const { defaultPaymentMethod } = usePaymentMethod({ accountId });
|
|
20380
|
+
const [selectedPluginId, setSelectedPluginId] = useSelectedPluginId();
|
|
20381
|
+
// Derived state
|
|
20382
|
+
const selectedPlugin = react.useMemo(() => {
|
|
20383
|
+
return paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.find(plugin => plugin.id === selectedPluginId);
|
|
20384
|
+
}, [paymentPlugins, selectedPluginId]);
|
|
20385
|
+
react.useEffect(() => {
|
|
20386
|
+
var _a, _b;
|
|
20387
|
+
if (selectedPluginId) {
|
|
20388
|
+
return;
|
|
20389
|
+
}
|
|
20390
|
+
if (defaultPaymentMethod) {
|
|
20391
|
+
setSelectedPluginId((_a = defaultPaymentMethod.plugin) === null || _a === void 0 ? void 0 : _a.id);
|
|
20392
|
+
}
|
|
20393
|
+
else {
|
|
20394
|
+
setSelectedPluginId((_b = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins[0]) === null || _b === void 0 ? void 0 : _b.id);
|
|
20395
|
+
}
|
|
20396
|
+
}, [defaultPaymentMethod, paymentPlugins]);
|
|
20397
|
+
return jsxRuntime.jsx(SelectedPluginDataProvider, { value: selectedPlugin, children: children });
|
|
20398
|
+
}
|
|
20399
|
+
|
|
20400
|
+
function StripeFormProvider({ children, currencyId, accountId, }) {
|
|
20401
|
+
const plugin = useSelectedPlugin();
|
|
20402
|
+
const { stripe, options } = useStripePlugin(plugin, currencyId, accountId);
|
|
20403
|
+
return (jsxRuntime.jsx(reactStripeJs.Elements, { options: options, stripe: stripe, children: children }));
|
|
20404
|
+
}
|
|
20405
|
+
|
|
20406
|
+
const MUTATION$4 = `
|
|
20407
|
+
mutation checkout(
|
|
20408
|
+
$invoiceId: ID,
|
|
20409
|
+
$quoteId: ID,
|
|
20410
|
+
$paymentMethodId: ID,
|
|
20411
|
+
$paymentMethodData: CheckoutPaymentMethodAttributes
|
|
20412
|
+
) {
|
|
20413
|
+
checkout(
|
|
20414
|
+
invoiceId: $invoiceId,
|
|
20415
|
+
quoteId: $quoteId,
|
|
20416
|
+
paymentMethodId: $paymentMethodId,
|
|
20417
|
+
paymentMethodData: $paymentMethodData
|
|
20418
|
+
) {
|
|
20419
|
+
invoice {
|
|
20420
|
+
id
|
|
20421
|
+
state
|
|
20422
|
+
amount
|
|
20423
|
+
amountDue
|
|
20424
|
+
}
|
|
20425
|
+
payment {
|
|
20426
|
+
id
|
|
20427
|
+
state
|
|
20428
|
+
amount
|
|
20429
|
+
}
|
|
20430
|
+
paymentApplication {
|
|
20431
|
+
id
|
|
20432
|
+
invoiceId
|
|
20433
|
+
paymentId
|
|
20434
|
+
}
|
|
20435
|
+
transaction {
|
|
20436
|
+
id
|
|
20437
|
+
amount
|
|
20438
|
+
}
|
|
20439
|
+
}
|
|
20440
|
+
}
|
|
20441
|
+
`;
|
|
20442
|
+
const checkout = async ({ quoteId, invoiceId, paymentMethodId, paymentMethodData, token, apiHost, }) => {
|
|
20443
|
+
const mutationVars = {
|
|
20444
|
+
quoteId,
|
|
20445
|
+
invoiceId,
|
|
20446
|
+
paymentMethodId,
|
|
20447
|
+
};
|
|
20448
|
+
if (paymentMethodData) {
|
|
20449
|
+
mutationVars.paymentMethodData = {
|
|
20450
|
+
...paymentMethodData,
|
|
20451
|
+
metadata: paymentMethodData.metadata,
|
|
20452
|
+
};
|
|
20453
|
+
}
|
|
20454
|
+
const response = await gqlRequest({
|
|
20455
|
+
query: MUTATION$4,
|
|
20456
|
+
token,
|
|
20457
|
+
vars: mutationVars,
|
|
20458
|
+
apiHost: apiHost,
|
|
20459
|
+
});
|
|
20460
|
+
const { errors } = response === null || response === void 0 ? void 0 : response.checkout;
|
|
20461
|
+
if (errors)
|
|
20462
|
+
throw errors;
|
|
20463
|
+
return {
|
|
20464
|
+
savePaymentMethod: paymentMethodData === null || paymentMethodData === void 0 ? void 0 : paymentMethodData.savePaymentMethod,
|
|
20465
|
+
};
|
|
20466
|
+
};
|
|
20467
|
+
|
|
20468
|
+
const getQuoteAmountDue_QuoteFragment = t(`
|
|
20469
|
+
fragment getQuoteAmountDue_QuoteFragment on Quote {
|
|
20470
|
+
amountDue
|
|
20471
|
+
amount
|
|
20472
|
+
}
|
|
20473
|
+
`, []);
|
|
20474
|
+
const getQuoteAmountDue = (maskedQuote) => {
|
|
20475
|
+
var _a;
|
|
20476
|
+
const quote = readFragment(getQuoteAmountDue_QuoteFragment, maskedQuote);
|
|
20477
|
+
return (_a = quote.amountDue) !== null && _a !== void 0 ? _a : quote.amount;
|
|
20478
|
+
};
|
|
20479
|
+
|
|
20480
|
+
var dayjs_min$1 = {exports: {}};
|
|
20481
|
+
|
|
20482
|
+
var dayjs_min = dayjs_min$1.exports;
|
|
20483
|
+
|
|
20484
|
+
var hasRequiredDayjs_min;
|
|
20485
|
+
|
|
20486
|
+
function requireDayjs_min () {
|
|
20487
|
+
if (hasRequiredDayjs_min) return dayjs_min$1.exports;
|
|
20488
|
+
hasRequiredDayjs_min = 1;
|
|
20489
|
+
(function (module, exports) {
|
|
20490
|
+
!function(t,e){module.exports=e();}(dayjs_min,(function(){var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return "["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return !r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return (e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()<n.date())return -t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,c),s=n-i<0,u=e.clone().add(r+(s?-1:1),c);return +(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return {M:c,y:h,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:f}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},g="en",D={};D[g]=M;var p="$isDayjsObject",S=function(t){return t instanceof _||!(!t||!t[p])},w=function t(e,n,r){var i;if(!e)return g;if("string"==typeof e){var s=e.toLowerCase();D[s]&&(i=s),n&&(D[s]=n,i=s);var u=e.split("-");if(!i&&u.length>1)return t(u[0])}else {var a=e.name;D[a]=e,i=a;}return !r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0;}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init();},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds();},m.$utils=function(){return b},m.isValid=function(){return !(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<O(t)},m.$g=function(t,e,n){return b.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!b.u(e)||e,f=b.p(t),l=function(t,e){var i=b.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},$=function(t,e){return b.w(n.toDate()[t].apply(n.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,v="set"+(this.$u?"UTC":"");switch(f){case h:return r?l(1,0):l(31,11);case c:return r?l(1,M):l(0,M+1);case o:var g=this.$locale().weekStart||0,D=(y<g?y+7:y)-g;return l(r?m-D:m+(6-D),M);case a:case d:return $(v+"Hours",0);case u:return $(v+"Minutes",1);case s:return $(v+"Seconds",2);case i:return $(v+"Milliseconds",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var n,o=b.p(t),f="set"+(this.$u?"UTC":""),l=(n={},n[a]=f+"Date",n[d]=f+"Date",n[c]=f+"Month",n[h]=f+"FullYear",n[u]=f+"Hours",n[s]=f+"Minutes",n[i]=f+"Seconds",n[r]=f+"Milliseconds",n)[o],$=o===a?this.$D+(e-this.$W):e;if(o===c||o===h){var y=this.clone().set(d,1);y.$d[l]($),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d;}else l&&this.$d[l]($);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[b.p(t)]()},m.add=function(r,f){var d,l=this;r=Number(r);var $=b.p(f),y=function(t){var e=O(l);return b.w(e.date(e.date()+Math.round(t*r)),l)};if($===c)return this.set(c,this.$M+r);if($===h)return this.set(h,this.$y+r);if($===a)return y(1);if($===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[$]||1,m=this.$d.getTime()+r*M;return b.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||l;var r=t||"YYYY-MM-DDTHH:mm:ssZ",i=b.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,c=n.months,f=n.meridiem,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].slice(0,s)},d=function(t){return b.s(s%12||12,t,"0")},$=f||function(t,e,n){var r=t<12?"AM":"PM";return n?r.toLowerCase():r};return r.replace(y,(function(t,r){return r||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return b.s(e.$y,4,"0");case"M":return a+1;case"MM":return b.s(a+1,2,"0");case"MMM":return h(n.monthsShort,a,c,3);case"MMMM":return h(c,a);case"D":return e.$D;case"DD":return b.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return h(n.weekdaysMin,e.$W,o,2);case"ddd":return h(n.weekdaysShort,e.$W,o,3);case"dddd":return o[e.$W];case"H":return String(s);case"HH":return b.s(s,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return $(s,u,!0);case"A":return $(s,u,!1);case"m":return String(u);case"mm":return b.s(u,2,"0");case"s":return String(e.$s);case"ss":return b.s(e.$s,2,"0");case"SSS":return b.s(e.$ms,3,"0");case"Z":return i}return null}(t)||i.replace(":","")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,l){var $,y=this,M=b.p(d),m=O(r),v=(m.utcOffset()-this.utcOffset())*e,g=this-m,D=function(){return b.m(y,m)};switch(M){case h:$=D()/12;break;case c:$=D();break;case f:$=D()/3;break;case o:$=(g-v)/6048e5;break;case a:$=(g-v)/864e5;break;case u:$=g/n;break;case s:$=g/e;break;case i:$=g/t;break;default:$=g;}return l?$:b.a($)},m.daysInMonth=function(){return this.endOf(c).$D},m.$locale=function(){return D[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=w(t,e,!0);return r&&(n.$L=r),n},m.clone=function(){return b.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),k=_.prototype;return O.prototype=k,[["$ms",r],["$s",i],["$m",s],["$H",u],["$W",a],["$M",c],["$y",h],["$D",d]].forEach((function(t){k[t[1]]=function(e){return this.$g(e,t[0],t[1])};})),O.extend=function(t,e){return t.$i||(t(e,_,O),t.$i=!0),O},O.locale=w,O.isDayjs=S,O.unix=function(t){return O(1e3*t)},O.en=D[g],O.Ls=D,O.p={},O}));
|
|
20491
|
+
} (dayjs_min$1));
|
|
20492
|
+
return dayjs_min$1.exports;
|
|
20493
|
+
}
|
|
20494
|
+
|
|
20495
|
+
var dayjs_minExports = requireDayjs_min();
|
|
20496
|
+
var dayjs = /*@__PURE__*/getDefaultExportFromCjs(dayjs_minExports);
|
|
20497
|
+
|
|
20498
|
+
var localizedFormat$2 = {exports: {}};
|
|
20499
|
+
|
|
20500
|
+
var localizedFormat$1 = localizedFormat$2.exports;
|
|
20501
|
+
|
|
20502
|
+
var hasRequiredLocalizedFormat;
|
|
20503
|
+
|
|
20504
|
+
function requireLocalizedFormat () {
|
|
20505
|
+
if (hasRequiredLocalizedFormat) return localizedFormat$2.exports;
|
|
20506
|
+
hasRequiredLocalizedFormat = 1;
|
|
20507
|
+
(function (module, exports) {
|
|
20508
|
+
!function(e,t){module.exports=t();}(localizedFormat$1,(function(){var e={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};return function(t,o,n){var r=o.prototype,i=r.format;n.en.formats=e,r.format=function(t){void 0===t&&(t="YYYY-MM-DDTHH:mm:ssZ");var o=this.$locale().formats,n=function(t,o){return t.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var i=r&&r.toUpperCase();return n||o[r]||e[r]||o[i].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,o){return t||o.slice(1)}))}))}(t,void 0===o?{}:o);return i.call(this,n)};}}));
|
|
20509
|
+
} (localizedFormat$2));
|
|
20510
|
+
return localizedFormat$2.exports;
|
|
20511
|
+
}
|
|
20512
|
+
|
|
20513
|
+
var localizedFormatExports = requireLocalizedFormat();
|
|
20514
|
+
var localizedFormat = /*@__PURE__*/getDefaultExportFromCjs(localizedFormatExports);
|
|
20515
|
+
|
|
20516
|
+
dayjs.extend(localizedFormat);
|
|
20517
|
+
const formatCurrency = (value, currencyIsoCode, decimals = 2) => {
|
|
20518
|
+
if (value !== 0 && !value)
|
|
20519
|
+
return '';
|
|
20520
|
+
const currencyValue = typeof value === 'string' ? parseFloat(value) : value;
|
|
20521
|
+
if (isNaN(currencyValue))
|
|
20522
|
+
return value;
|
|
20523
|
+
const localeOptions = {
|
|
20524
|
+
minimumFractionDigits: decimals,
|
|
20525
|
+
maximumFractionDigits: decimals,
|
|
20526
|
+
};
|
|
20527
|
+
localeOptions.style = 'currency';
|
|
20528
|
+
localeOptions.currency = currencyIsoCode;
|
|
20529
|
+
return currencyValue.toLocaleString(navigator.language, localeOptions);
|
|
20530
|
+
};
|
|
20531
|
+
|
|
20532
|
+
var PaymentType;
|
|
20533
|
+
(function (PaymentType) {
|
|
20534
|
+
PaymentType["PAY"] = "PAY";
|
|
20535
|
+
PaymentType["APPROVE_HOLD"] = "APPROVE_HOLD";
|
|
20536
|
+
PaymentType["CHECKOUT_NO_PAYMENT"] = "CHECKOUT_NO_PAYMENT";
|
|
20537
|
+
PaymentType["SAVE"] = "SAVE";
|
|
20538
|
+
})(PaymentType || (PaymentType = {}));
|
|
20539
|
+
|
|
20540
|
+
// Contexts
|
|
20541
|
+
// TODO: use useSelector to get the values from the context so we don't have unnecessary re-renders
|
|
20542
|
+
const [PayableProvider, usePayable] = createValueContext();
|
|
20543
|
+
const PaymentProvider_QuoteFragment = t(`
|
|
20544
|
+
fragment PaymentProvider_QuoteFragment on Quote {
|
|
20545
|
+
id
|
|
20546
|
+
currencyId
|
|
20547
|
+
...getQuoteAmountDue_QuoteFragment
|
|
20548
|
+
}
|
|
20549
|
+
`, [getQuoteAmountDue_QuoteFragment]);
|
|
20550
|
+
const PaymentProvider_InvoiceFragment = t(`
|
|
20551
|
+
fragment PaymentProvider_InvoiceFragment on Invoice {
|
|
20552
|
+
id
|
|
20553
|
+
currencyId
|
|
20554
|
+
amountDue
|
|
20555
|
+
}
|
|
20556
|
+
`);
|
|
20557
|
+
function PaymentProvider({ children, quote: maskedQuote, invoice: maskedInvoice, paymentHold, }) {
|
|
20558
|
+
var _a, _b;
|
|
20559
|
+
// Read fragments
|
|
20560
|
+
const quote = readFragment(PaymentProvider_QuoteFragment, maskedQuote);
|
|
20561
|
+
const invoice = readFragment(PaymentProvider_InvoiceFragment, maskedInvoice);
|
|
20562
|
+
// State
|
|
20563
|
+
const [isPaid, setIsPaid] = react.useState(false);
|
|
20564
|
+
const getAmountDue = () => {
|
|
20565
|
+
return quote ? getQuoteAmountDue(quote) : invoice === null || invoice === void 0 ? void 0 : invoice.amountDue;
|
|
20566
|
+
};
|
|
20567
|
+
const formattedAmountDue = () => {
|
|
20568
|
+
var _a;
|
|
20569
|
+
const amountDue = getAmountDue();
|
|
20570
|
+
const currencyId = (_a = quote === null || quote === void 0 ? void 0 : quote.currencyId) !== null && _a !== void 0 ? _a : invoice === null || invoice === void 0 ? void 0 : invoice.currencyId;
|
|
20571
|
+
return amountDue !== undefined && currencyId !== undefined
|
|
20572
|
+
? formatCurrency(amountDue, currencyId).toString()
|
|
20573
|
+
: undefined;
|
|
20574
|
+
};
|
|
20575
|
+
// Validation checks
|
|
20576
|
+
if (quote !== undefined && invoice !== undefined && paymentHold !== undefined) {
|
|
20577
|
+
throw new Error('Either quote or invoice or paymentHold must be provided, not all');
|
|
20578
|
+
}
|
|
20579
|
+
function getPaymentType() {
|
|
20580
|
+
if (getAmountDue() === undefined)
|
|
20581
|
+
return PaymentType.SAVE;
|
|
20582
|
+
if (getAmountDue() === 0)
|
|
20583
|
+
return PaymentType.CHECKOUT_NO_PAYMENT;
|
|
20584
|
+
return paymentHold
|
|
20585
|
+
? PaymentType.APPROVE_HOLD
|
|
20586
|
+
: PaymentType.PAY;
|
|
20587
|
+
}
|
|
20588
|
+
const paymentType = getPaymentType();
|
|
20589
|
+
const amountDue = getAmountDue();
|
|
20590
|
+
const formattedAmountDueValue = formattedAmountDue();
|
|
20591
|
+
return (jsxRuntime.jsx(PayableProvider, { value: {
|
|
20592
|
+
quoteId: (_a = quote === null || quote === void 0 ? void 0 : quote.id) !== null && _a !== void 0 ? _a : undefined,
|
|
20593
|
+
invoiceId: (_b = invoice === null || invoice === void 0 ? void 0 : invoice.id) !== null && _b !== void 0 ? _b : undefined,
|
|
20594
|
+
paymentHold,
|
|
20595
|
+
paymentType,
|
|
20596
|
+
amountDue: amountDue !== null && amountDue !== void 0 ? amountDue : undefined,
|
|
20597
|
+
formattedAmountDue: formattedAmountDueValue,
|
|
20598
|
+
isPaid,
|
|
20599
|
+
setIsPaid
|
|
20600
|
+
}, children: children }));
|
|
20601
|
+
}
|
|
20602
|
+
|
|
20603
|
+
function CheckoutNoPayment(props = {}) {
|
|
20604
|
+
const { className, disabled } = props;
|
|
20605
|
+
const { formattedAmountDue, quoteId } = usePayable();
|
|
20606
|
+
const token = useToken();
|
|
20607
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
20608
|
+
const handleAllErrorFormats = useAllErrorFormats$1();
|
|
20609
|
+
const { onPaymentSuccess } = usePaymentFormCallbacks();
|
|
20610
|
+
const { mutate: checkoutNoPayment, isPending } = reactQuery.useMutation({
|
|
20611
|
+
mutationFn: async () => {
|
|
20612
|
+
const paymentRequired = formattedAmountDue ? parseFloat(formattedAmountDue) > 0 : true;
|
|
20613
|
+
if (!quoteId)
|
|
20614
|
+
throw new Error('Quote ID is required');
|
|
20615
|
+
if (paymentRequired)
|
|
20616
|
+
throw new Error('Payment is required');
|
|
20617
|
+
return await checkout({ quoteId, token, apiHost });
|
|
20618
|
+
},
|
|
20619
|
+
onSuccess: () => {
|
|
20620
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess({});
|
|
20621
|
+
},
|
|
20622
|
+
onError: error => {
|
|
20623
|
+
handleAllErrorFormats(error);
|
|
20624
|
+
},
|
|
20625
|
+
});
|
|
20626
|
+
return (jsxRuntime.jsx("div", { className: className, children: jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", loading: isPending, disabled: isPending || disabled, onClick: () => checkoutNoPayment(), type: "primary", children: isPending ? 'Processing...' : 'Complete Order' }) }));
|
|
20627
|
+
}
|
|
20628
|
+
|
|
20629
|
+
const useShowPaymentDetailsState = (isOpen = false) => react.useState(isOpen);
|
|
20630
|
+
const [ShowPaymentDetailsProvider, useShowPaymentDetails] = createStateContext(useShowPaymentDetailsState);
|
|
20631
|
+
|
|
20415
20632
|
function useApproveHold$1({ onApproveHoldSuccess, onApproveHoldError, }) {
|
|
20416
20633
|
// Hooks
|
|
20417
20634
|
const [isApprovingHold, setIsApprovingHold] = react.useState(false);
|
|
@@ -20444,47 +20661,6 @@ function useApproveHold$1({ onApproveHoldSuccess, onApproveHoldError, }) {
|
|
|
20444
20661
|
return { approveHold, isApprovingHold };
|
|
20445
20662
|
}
|
|
20446
20663
|
|
|
20447
|
-
// Used for Signup component. Signup needs a custom checkout function
|
|
20448
|
-
const [CustomCheckoutFunctionProvider, useCustomCheckoutFunction] = createValueContext();
|
|
20449
|
-
|
|
20450
|
-
const showErrorNotification$a = useErrorNotification();
|
|
20451
|
-
function usePay$1({ onPaymentSuccess, onPaymentError, quoteId, invoice, plugin, }) {
|
|
20452
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
20453
|
-
const customCheckoutFunction = useCustomCheckoutFunction();
|
|
20454
|
-
const token = useToken();
|
|
20455
|
-
const [isPaying, setIsPaying] = react.useState(false);
|
|
20456
|
-
const pay = async (paymentMethodId) => {
|
|
20457
|
-
try {
|
|
20458
|
-
setIsPaying(true);
|
|
20459
|
-
if (customCheckoutFunction) {
|
|
20460
|
-
if (!(plugin === null || plugin === void 0 ? void 0 : plugin.id)) {
|
|
20461
|
-
showErrorNotification$a('Plugin ID is required');
|
|
20462
|
-
return;
|
|
20463
|
-
}
|
|
20464
|
-
const response = await customCheckoutFunction(plugin === null || plugin === void 0 ? void 0 : plugin.id.toString(), paymentMethodId.toString());
|
|
20465
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20466
|
-
}
|
|
20467
|
-
else {
|
|
20468
|
-
const response = await checkout({
|
|
20469
|
-
invoiceId: invoice === null || invoice === void 0 ? void 0 : invoice.id,
|
|
20470
|
-
quoteId,
|
|
20471
|
-
paymentMethodId,
|
|
20472
|
-
token,
|
|
20473
|
-
apiHost,
|
|
20474
|
-
});
|
|
20475
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20476
|
-
}
|
|
20477
|
-
}
|
|
20478
|
-
catch (error) {
|
|
20479
|
-
onPaymentError === null || onPaymentError === void 0 ? void 0 : onPaymentError(error);
|
|
20480
|
-
}
|
|
20481
|
-
finally {
|
|
20482
|
-
setIsPaying(false);
|
|
20483
|
-
}
|
|
20484
|
-
};
|
|
20485
|
-
return { pay, isPaying };
|
|
20486
|
-
}
|
|
20487
|
-
|
|
20488
20664
|
function useApproveHold({ onApproveHoldSuccess, onApproveHoldError, }) {
|
|
20489
20665
|
// Hooks
|
|
20490
20666
|
const [isApprovingHold, setIsApprovingHold] = react.useState(false);
|
|
@@ -20517,209 +20693,147 @@ function useApproveHold({ onApproveHoldSuccess, onApproveHoldError, }) {
|
|
|
20517
20693
|
return { approveHold, isApprovingHold };
|
|
20518
20694
|
}
|
|
20519
20695
|
|
|
20520
|
-
const showErrorNotification$
|
|
20521
|
-
function
|
|
20522
|
-
|
|
20523
|
-
const
|
|
20524
|
-
const customCheckoutFunction = useCustomCheckoutFunction();
|
|
20525
|
-
const token = useToken();
|
|
20526
|
-
const [isPaying, setIsPaying] = react.useState(false);
|
|
20527
|
-
const pay = async (paymentMethodId) => {
|
|
20528
|
-
try {
|
|
20529
|
-
setIsPaying(true);
|
|
20530
|
-
if (customCheckoutFunction) {
|
|
20531
|
-
if (!(plugin === null || plugin === void 0 ? void 0 : plugin.id)) {
|
|
20532
|
-
showErrorNotification$9('Plugin ID is required');
|
|
20533
|
-
return;
|
|
20534
|
-
}
|
|
20535
|
-
const response = await customCheckoutFunction(plugin === null || plugin === void 0 ? void 0 : plugin.id.toString(), paymentMethodId.toString());
|
|
20536
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20537
|
-
}
|
|
20538
|
-
else {
|
|
20539
|
-
if (!quoteId && !(invoice === null || invoice === void 0 ? void 0 : invoice.id)) {
|
|
20540
|
-
showErrorNotification$9('Quote ID or Invoice ID is required');
|
|
20541
|
-
return;
|
|
20542
|
-
}
|
|
20543
|
-
const response = await checkout({
|
|
20544
|
-
invoiceId: invoice === null || invoice === void 0 ? void 0 : invoice.id,
|
|
20545
|
-
quoteId,
|
|
20546
|
-
paymentMethodId,
|
|
20547
|
-
token,
|
|
20548
|
-
apiHost,
|
|
20549
|
-
});
|
|
20550
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20551
|
-
}
|
|
20552
|
-
}
|
|
20553
|
-
catch (error) {
|
|
20554
|
-
onPaymentError === null || onPaymentError === void 0 ? void 0 : onPaymentError(error);
|
|
20555
|
-
}
|
|
20556
|
-
finally {
|
|
20557
|
-
setIsPaying(false);
|
|
20558
|
-
}
|
|
20559
|
-
};
|
|
20560
|
-
return { pay, isPaying };
|
|
20561
|
-
}
|
|
20562
|
-
|
|
20563
|
-
var PaymentType;
|
|
20564
|
-
(function (PaymentType) {
|
|
20565
|
-
PaymentType["PAY"] = "PAY";
|
|
20566
|
-
PaymentType["APPROVE_HOLD"] = "APPROVE_HOLD";
|
|
20567
|
-
PaymentType["CHECKOUT_NO_PAYMENT"] = "CHECKOUT_NO_PAYMENT";
|
|
20568
|
-
})(PaymentType || (PaymentType = {}));
|
|
20569
|
-
|
|
20570
|
-
const handleAllErrorFormats$3 = useAllErrorFormats();
|
|
20571
|
-
const showErrorNotification$8 = useErrorNotification();
|
|
20572
|
-
const useHandlePayment_QuoteFragment = t(`
|
|
20573
|
-
fragment useHandlePayment_QuoteFragment on Quote {
|
|
20574
|
-
id
|
|
20575
|
-
amount
|
|
20576
|
-
currencyId
|
|
20577
|
-
...getQuoteAmountDue_QuoteFragment
|
|
20578
|
-
}
|
|
20579
|
-
`, [getQuoteAmountDue_QuoteFragment]);
|
|
20580
|
-
const useHandlePayment = ({ quote: maskedQuote, invoice, onPaymentSuccess, onPaymentHoldSuccess, paymentHoldPrecondition, plugin, paymentHoldOptions, accountId, }) => {
|
|
20581
|
-
// Read fragments
|
|
20582
|
-
const quote = readFragment(useHandlePayment_QuoteFragment, maskedQuote);
|
|
20583
|
-
// Context
|
|
20584
|
-
const { defaultPaymentMethod } = usePaymentMethod({ accountId });
|
|
20585
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
20586
|
-
const token = useToken();
|
|
20587
|
-
// State
|
|
20588
|
-
const [isPaid, setIsPaid] = react.useState(false);
|
|
20589
|
-
const getAmountDue = () => {
|
|
20590
|
-
return quote ? getQuoteAmountDue(quote) : invoice === null || invoice === void 0 ? void 0 : invoice.amountDue;
|
|
20591
|
-
};
|
|
20592
|
-
const formattedAmountDue = () => {
|
|
20593
|
-
var _a;
|
|
20594
|
-
const amountDue = getAmountDue();
|
|
20595
|
-
const currencyId = (_a = quote === null || quote === void 0 ? void 0 : quote.currencyId) !== null && _a !== void 0 ? _a : invoice === null || invoice === void 0 ? void 0 : invoice.currencyId;
|
|
20596
|
-
return amountDue !== undefined && currencyId !== undefined ? formatCurrency(amountDue, currencyId).toString() : undefined;
|
|
20597
|
-
};
|
|
20598
|
-
// Validation checks
|
|
20599
|
-
if (quote !== undefined && invoice !== undefined) {
|
|
20600
|
-
throw new Error('Either quote or invoice must be provided, not both');
|
|
20601
|
-
}
|
|
20602
|
-
// Payment hooks
|
|
20603
|
-
const { pay: payDemoPay, isPaying: isPayingDemoPay } = usePay$1({
|
|
20604
|
-
onPaymentSuccess: handlePaymentSuccess,
|
|
20605
|
-
onPaymentError: error => {
|
|
20606
|
-
handleAllErrorFormats$3(error);
|
|
20607
|
-
},
|
|
20608
|
-
quoteId: quote === null || quote === void 0 ? void 0 : quote.id,
|
|
20609
|
-
invoice: invoice,
|
|
20610
|
-
plugin,
|
|
20611
|
-
});
|
|
20612
|
-
const { pay: payStripe, isPaying: isPayingStripe } = usePay({
|
|
20613
|
-
onPaymentSuccess: handlePaymentSuccess,
|
|
20614
|
-
onPaymentError: error => {
|
|
20615
|
-
handleAllErrorFormats$3(error);
|
|
20616
|
-
},
|
|
20617
|
-
quoteId: quote === null || quote === void 0 ? void 0 : quote.id,
|
|
20618
|
-
invoice: invoice,
|
|
20619
|
-
plugin,
|
|
20620
|
-
});
|
|
20621
|
-
// Approve hold hooks
|
|
20696
|
+
const showErrorNotification$c = useErrorNotification();
|
|
20697
|
+
function usePaymentHold({ plugin, onPaymentHoldSuccess, onPaymentHoldError, }) {
|
|
20698
|
+
var _a, _b, _c;
|
|
20699
|
+
const pluginName = (_c = (_b = (_a = plugin === null || plugin === void 0 ? void 0 : plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name;
|
|
20622
20700
|
const { approveHold: approveHoldStripe, isApprovingHold: isApprovingHoldStripe } = useApproveHold({
|
|
20623
|
-
onApproveHoldSuccess:
|
|
20624
|
-
|
|
20625
|
-
},
|
|
20626
|
-
onApproveHoldError: error => {
|
|
20627
|
-
handleAllErrorFormats$3(error);
|
|
20628
|
-
},
|
|
20701
|
+
onApproveHoldSuccess: onPaymentHoldSuccess,
|
|
20702
|
+
onApproveHoldError: onPaymentHoldError,
|
|
20629
20703
|
});
|
|
20630
20704
|
const { approveHold: approveHoldDemoPay, isApprovingHold: isApprovingHoldDemoPay } = useApproveHold$1({
|
|
20631
|
-
onApproveHoldSuccess:
|
|
20632
|
-
|
|
20633
|
-
},
|
|
20634
|
-
onApproveHoldError: error => {
|
|
20635
|
-
handleAllErrorFormats$3(error);
|
|
20636
|
-
},
|
|
20637
|
-
});
|
|
20638
|
-
// Mutations
|
|
20639
|
-
const { mutate: checkoutNoPayment, isPending: isCheckingOutNoPayment } = reactQuery.useMutation({
|
|
20640
|
-
mutationFn: async () => {
|
|
20641
|
-
const amountDue = formattedAmountDue();
|
|
20642
|
-
const paymentRequired = amountDue ? parseFloat(amountDue) > 0 : true;
|
|
20643
|
-
if (!(quote === null || quote === void 0 ? void 0 : quote.id))
|
|
20644
|
-
throw new Error('Quote ID is required');
|
|
20645
|
-
if (paymentRequired)
|
|
20646
|
-
throw new Error('Payment is required');
|
|
20647
|
-
return await checkout({ quoteId: quote.id, token, apiHost });
|
|
20648
|
-
},
|
|
20649
|
-
onSuccess: () => {
|
|
20650
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess({});
|
|
20651
|
-
},
|
|
20652
|
-
onError: error => {
|
|
20653
|
-
handleAllErrorFormats$3(error);
|
|
20654
|
-
},
|
|
20705
|
+
onApproveHoldSuccess: onPaymentHoldSuccess,
|
|
20706
|
+
onApproveHoldError: onPaymentHoldError,
|
|
20655
20707
|
});
|
|
20656
|
-
const
|
|
20657
|
-
|
|
20658
|
-
|
|
20659
|
-
const allowed = await paymentHoldPrecondition();
|
|
20660
|
-
if (!allowed)
|
|
20661
|
-
return;
|
|
20662
|
-
}
|
|
20663
|
-
const paymentMethodId = overridePaymentMethodId !== null && overridePaymentMethodId !== void 0 ? overridePaymentMethodId : defaultPaymentMethod === null || defaultPaymentMethod === void 0 ? void 0 : defaultPaymentMethod.id;
|
|
20708
|
+
const approveHold = async ({ quote, paymentMethodId, }) => {
|
|
20709
|
+
if (!pluginName)
|
|
20710
|
+
return showErrorNotification$c('plugin name is required');
|
|
20664
20711
|
if (!plugin)
|
|
20665
|
-
return showErrorNotification$
|
|
20666
|
-
|
|
20667
|
-
return showErrorNotification$8('quote id and amount are required to approve hold');
|
|
20668
|
-
if (!paymentMethodId)
|
|
20669
|
-
return;
|
|
20670
|
-
switch ((_b = (_a = plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0].name) {
|
|
20712
|
+
return showErrorNotification$c('plugin is required');
|
|
20713
|
+
switch (pluginName) {
|
|
20671
20714
|
case 'StripePayment':
|
|
20672
|
-
await approveHoldStripe({
|
|
20673
|
-
|
|
20674
|
-
quote: { id: quote.id, amount: quote.amount },
|
|
20675
|
-
paymentMethodId,
|
|
20676
|
-
});
|
|
20677
|
-
break;
|
|
20715
|
+
await approveHoldStripe({ plugin, quote, paymentMethodId });
|
|
20716
|
+
return;
|
|
20678
20717
|
case 'DemoPayPayment':
|
|
20679
|
-
await approveHoldDemoPay({
|
|
20718
|
+
await approveHoldDemoPay({ plugin, quote, paymentMethodId });
|
|
20719
|
+
return;
|
|
20720
|
+
default:
|
|
20721
|
+
showErrorNotification$c(`Payment holds are not supported by ${pluginName}`);
|
|
20722
|
+
return;
|
|
20723
|
+
}
|
|
20724
|
+
};
|
|
20725
|
+
return {
|
|
20726
|
+
approveHold,
|
|
20727
|
+
isApprovingHold: isApprovingHoldStripe || isApprovingHoldDemoPay,
|
|
20728
|
+
};
|
|
20729
|
+
}
|
|
20730
|
+
|
|
20731
|
+
const DIGIT_REGEX = /\d/;
|
|
20732
|
+
const isDigit = (char) => DIGIT_REGEX.test(char);
|
|
20733
|
+
const isDeletion = (char) => [8, 46].includes(char); // Backspace or Delete
|
|
20734
|
+
const isNavigation = (char) => [9, 37, 38, 39, 40].includes(char); // Tab, Arrows
|
|
20735
|
+
const isModifier = (char) => [16, 17, 18].includes(char); // Shift, Ctrl, Alt
|
|
20736
|
+
const isValidKey = (code) => isDeletion(code) || isNavigation(code) || isModifier(code);
|
|
20737
|
+
const isValidExpiry = (expiry) => {
|
|
20738
|
+
const month = parseInt(expiry.substring(0, 2), 10);
|
|
20739
|
+
const year = parseInt(expiry.substring(2, 4), 10) + 2000;
|
|
20740
|
+
if (isNaN(month) || isNaN(year))
|
|
20741
|
+
return false;
|
|
20742
|
+
if (month < 1 || month > 12)
|
|
20743
|
+
return false;
|
|
20744
|
+
return true;
|
|
20745
|
+
};
|
|
20746
|
+
const isCardExpired = (expiry) => {
|
|
20747
|
+
const month = parseInt(expiry.substring(0, 2), 10);
|
|
20748
|
+
const year = parseInt(expiry.substring(2, 4), 10) + 2000;
|
|
20749
|
+
const expiryDate = new Date(year, month, 1);
|
|
20750
|
+
return expiryDate < new Date();
|
|
20751
|
+
};
|
|
20752
|
+
const formatCardExpiry = (cardExpiry) => {
|
|
20753
|
+
if (cardExpiry.length <= 2)
|
|
20754
|
+
return cardExpiry;
|
|
20755
|
+
return cardExpiry.substring(0, 2) + '/' + cardExpiry.substring(2);
|
|
20756
|
+
};
|
|
20757
|
+
// removes spaces from a credit card number
|
|
20758
|
+
const unformatCardNumber = (cardNumber) => {
|
|
20759
|
+
const cardNumberArray = cardNumber.split('');
|
|
20760
|
+
const unformattedCardNumberArray = cardNumberArray.filter(character => character !== ' ');
|
|
20761
|
+
return unformattedCardNumberArray.join('');
|
|
20762
|
+
};
|
|
20763
|
+
const storePayment = async (options, plugin, apiHost, accountId) => {
|
|
20764
|
+
const { testCreditCardNumber, testCreditCardCvc, testCreditCardExpirationDate, token } = options;
|
|
20765
|
+
const response = await invokePlugin({
|
|
20766
|
+
method: 'store_payment_method',
|
|
20767
|
+
plugin,
|
|
20768
|
+
payload: {
|
|
20769
|
+
test_credit_card_number: testCreditCardNumber,
|
|
20770
|
+
test_credit_card_cvc: testCreditCardCvc,
|
|
20771
|
+
test_credit_card_expiration_date: testCreditCardExpirationDate,
|
|
20772
|
+
account_id: accountId,
|
|
20773
|
+
},
|
|
20774
|
+
token,
|
|
20775
|
+
apiHost,
|
|
20776
|
+
});
|
|
20777
|
+
if ((response === null || response === void 0 ? void 0 : response.status) !== 'success')
|
|
20778
|
+
throw new Error(response === null || response === void 0 ? void 0 : response.message);
|
|
20779
|
+
return response;
|
|
20780
|
+
};
|
|
20781
|
+
|
|
20782
|
+
const TEST_CARD = '4242424242424242';
|
|
20783
|
+
function useSave$2({ onSaveSuccess, onSaveError, accountId, }) {
|
|
20784
|
+
const [isSaving, setIsSaving] = react.useState(false);
|
|
20785
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
20786
|
+
const token = useToken();
|
|
20787
|
+
const plugin = useSelectedPlugin();
|
|
20788
|
+
const [cardDetails, setCardDetails] = useDemoPayCardDetails();
|
|
20789
|
+
const save = async () => {
|
|
20790
|
+
try {
|
|
20791
|
+
validateCardDetails();
|
|
20792
|
+
setIsSaving(true);
|
|
20793
|
+
const response = await storePayment({
|
|
20794
|
+
testCreditCardNumber: unformatCardNumber(cardDetails.number),
|
|
20795
|
+
testCreditCardCvc: cardDetails.cvc.toString(),
|
|
20796
|
+
testCreditCardExpirationDate: cardDetails.expiry,
|
|
20797
|
+
token,
|
|
20798
|
+
}, plugin, apiHost, accountId);
|
|
20799
|
+
const paymentMethodId = response.payload[0].id;
|
|
20800
|
+
if (response.status !== 'success')
|
|
20801
|
+
throw new Error(response === null || response === void 0 ? void 0 : response.message);
|
|
20802
|
+
onSaveSuccess === null || onSaveSuccess === void 0 ? void 0 : onSaveSuccess({
|
|
20803
|
+
pluginPaymentResponse: {
|
|
20680
20804
|
plugin,
|
|
20681
|
-
|
|
20805
|
+
token: response.token,
|
|
20806
|
+
savePaymentMethod: true,
|
|
20807
|
+
},
|
|
20808
|
+
savedPaymentMethodResponse: {
|
|
20682
20809
|
paymentMethodId,
|
|
20683
|
-
}
|
|
20684
|
-
|
|
20685
|
-
|
|
20686
|
-
|
|
20687
|
-
break;
|
|
20810
|
+
},
|
|
20811
|
+
});
|
|
20812
|
+
setCardDetails({ number: cardDetails.number, expiry: '', cvc: '' });
|
|
20813
|
+
return paymentMethodId;
|
|
20688
20814
|
}
|
|
20689
|
-
|
|
20690
|
-
|
|
20691
|
-
setIsPaid(true);
|
|
20692
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20693
|
-
}
|
|
20694
|
-
const handlePayment = async (overridePaymentMethodId) => {
|
|
20695
|
-
var _a, _b;
|
|
20696
|
-
if (!plugin)
|
|
20697
|
-
return;
|
|
20698
|
-
switch ((_b = (_a = plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0].name) {
|
|
20699
|
-
case 'StripePayment':
|
|
20700
|
-
await payStripe(overridePaymentMethodId);
|
|
20701
|
-
break;
|
|
20702
|
-
case 'DemoPayPayment':
|
|
20703
|
-
await payDemoPay(overridePaymentMethodId);
|
|
20704
|
-
break;
|
|
20815
|
+
catch (error) {
|
|
20816
|
+
onSaveError === null || onSaveError === void 0 ? void 0 : onSaveError(error);
|
|
20705
20817
|
}
|
|
20818
|
+
finally {
|
|
20819
|
+
setIsSaving(false);
|
|
20820
|
+
}
|
|
20821
|
+
return undefined;
|
|
20706
20822
|
};
|
|
20707
|
-
|
|
20708
|
-
|
|
20709
|
-
|
|
20710
|
-
|
|
20711
|
-
|
|
20712
|
-
|
|
20713
|
-
|
|
20714
|
-
|
|
20715
|
-
|
|
20716
|
-
|
|
20717
|
-
|
|
20718
|
-
|
|
20719
|
-
};
|
|
20720
|
-
};
|
|
20823
|
+
function validateCardDetails() {
|
|
20824
|
+
if (cardDetails.number !== TEST_CARD)
|
|
20825
|
+
throw new Error('Only the card number 4242 4242 4242 4242 will be accepted.');
|
|
20826
|
+
if (!isValidExpiry(cardDetails.expiry))
|
|
20827
|
+
throw new Error('Invalid expiry date');
|
|
20828
|
+
if (isCardExpired(cardDetails.expiry))
|
|
20829
|
+
throw new Error('Card is expired');
|
|
20830
|
+
if (cardDetails.cvc.length !== 3)
|
|
20831
|
+
throw new Error('Invalid CVC');
|
|
20832
|
+
}
|
|
20833
|
+
return { save, isSaving };
|
|
20834
|
+
}
|
|
20721
20835
|
|
|
20722
|
-
function useSave({ onSaveSuccess, onSaveError, accountId, }) {
|
|
20836
|
+
function useSave$1({ onSaveSuccess, onSaveError, accountId, }) {
|
|
20723
20837
|
// Hooks
|
|
20724
20838
|
const [isSaving, setIsSaving] = react.useState(false);
|
|
20725
20839
|
const elements = reactStripeJs.useElements();
|
|
@@ -20795,169 +20909,176 @@ function useSave({ onSaveSuccess, onSaveError, accountId, }) {
|
|
|
20795
20909
|
return { save, createStripePaymentMethodId, isSaving };
|
|
20796
20910
|
}
|
|
20797
20911
|
|
|
20798
|
-
const
|
|
20799
|
-
const
|
|
20800
|
-
|
|
20801
|
-
const handleAllErrorFormats$2 = useAllErrorFormats();
|
|
20802
|
-
const showErrorNotification$7 = useErrorNotification();
|
|
20803
|
-
// Contexts
|
|
20804
|
-
const [FormattedAmountDueProvider, useFormattedAmountDue] = createValueContext();
|
|
20805
|
-
const [PaymentTypeProvider, usePaymentType] = createValueContext();
|
|
20806
|
-
const [IsPayingProvider, useIsPaying] = createValueContext();
|
|
20807
|
-
const [HandlePaymentFormSubmitProvider, useHandlePaymentFormSubmit] = createValueContext();
|
|
20808
|
-
const [IsSavingProvider, useIsSaving] = createValueContext();
|
|
20809
|
-
// Used for PaymentMethodFooter to disable pay button if payment is already successful
|
|
20810
|
-
const [IsPaidProvider, useIsPaid] = createValueContext();
|
|
20811
|
-
// Used for Signup component. Signup uses an apiClient token which api can't infer an account from, so accountId must be used
|
|
20812
|
-
const [AccountIdProvider, useAccountId] = createValueContext();
|
|
20813
|
-
// Optional external control to disable the pay button (e.g. while quote is updating)
|
|
20814
|
-
const [IsPayButtonDisabledProvider, useIsPayButtonDisabled] = createValueContext();
|
|
20815
|
-
const PaymentProvider_QuoteFragment = t(`
|
|
20816
|
-
fragment PaymentProvider_QuoteFragment on Quote {
|
|
20817
|
-
id
|
|
20818
|
-
...useHandlePayment_QuoteFragment
|
|
20819
|
-
}
|
|
20820
|
-
`, [useHandlePayment_QuoteFragment]);
|
|
20821
|
-
function PaymentProvider({ children, accountId, quote: maskedQuote, invoice, onPaymentSuccess, onPaymentHoldSuccess, paymentHoldPrecondition, paymentHoldOptions, onSavePaymentMethod, }) {
|
|
20912
|
+
const handleAllErrorFormats$3 = useAllErrorFormats();
|
|
20913
|
+
const showErrorNotification$b = useErrorNotification();
|
|
20914
|
+
function useSave({ accountId, onSaveSuccess, onSaveError, invalidatePaymentMethodsQuery = true, }) {
|
|
20822
20915
|
var _a, _b, _c;
|
|
20823
|
-
// Read fragments
|
|
20824
|
-
const quote = readFragment(PaymentProvider_QuoteFragment, maskedQuote);
|
|
20825
|
-
// Context
|
|
20826
|
-
const [showPaymentMethodForm, setShowPaymentMethodForm] = useShowPaymentDetails();
|
|
20827
20916
|
const selectedPlugin = useSelectedPlugin();
|
|
20828
|
-
// Hooks
|
|
20829
20917
|
const queryClient = reactQuery.useQueryClient();
|
|
20830
20918
|
const token = useToken();
|
|
20831
|
-
const
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
// TODO: type the response to PaymentSuccessResponse
|
|
20836
|
-
// Hide payment method selector and form
|
|
20837
|
-
setShowPaymentMethodForm(false);
|
|
20838
|
-
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20839
|
-
},
|
|
20840
|
-
onPaymentHoldSuccess,
|
|
20841
|
-
paymentHoldPrecondition,
|
|
20842
|
-
plugin: selectedPlugin, // TODO: type the response to PluginData
|
|
20843
|
-
paymentHoldOptions,
|
|
20919
|
+
const onSaveErrorFinal = onSaveError !== null && onSaveError !== void 0 ? onSaveError : handleAllErrorFormats$3;
|
|
20920
|
+
// Derived state
|
|
20921
|
+
const pluginName = (_c = (_b = (_a = selectedPlugin === null || selectedPlugin === void 0 ? void 0 : selectedPlugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name;
|
|
20922
|
+
const { save: saveDemoPay, isSaving: isSavingDemoPay } = useSave$2({
|
|
20844
20923
|
accountId,
|
|
20845
|
-
|
|
20846
|
-
|
|
20847
|
-
|
|
20848
|
-
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
|
|
20852
|
-
accountId,
|
|
20853
|
-
token,
|
|
20854
|
-
}),
|
|
20855
|
-
});
|
|
20856
|
-
setShowPaymentMethodForm(false);
|
|
20924
|
+
onSaveSuccess: response => {
|
|
20925
|
+
onSaveSuccess === null || onSaveSuccess === void 0 ? void 0 : onSaveSuccess(response);
|
|
20926
|
+
if (invalidatePaymentMethodsQuery) {
|
|
20927
|
+
queryClient.invalidateQueries({
|
|
20928
|
+
queryKey: QueryKeyFactory.accountPaymentMethodsKey({ accountId, token }),
|
|
20929
|
+
});
|
|
20930
|
+
}
|
|
20857
20931
|
},
|
|
20858
|
-
onSaveError:
|
|
20859
|
-
accountId,
|
|
20932
|
+
onSaveError: onSaveErrorFinal,
|
|
20860
20933
|
});
|
|
20861
|
-
const { save: saveStripe, isSaving: isSavingStripe } = useSave({
|
|
20862
|
-
onSaveSuccess: async (response) => {
|
|
20863
|
-
onSavePaymentMethod === null || onSavePaymentMethod === void 0 ? void 0 : onSavePaymentMethod(response);
|
|
20864
|
-
queryClient.invalidateQueries({
|
|
20865
|
-
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
20866
|
-
accountId,
|
|
20867
|
-
token,
|
|
20868
|
-
}),
|
|
20869
|
-
});
|
|
20870
|
-
setShowPaymentMethodForm(false);
|
|
20871
|
-
},
|
|
20872
|
-
onSaveError: handleAllErrorFormats$2,
|
|
20934
|
+
const { save: saveStripe, isSaving: isSavingStripe } = useSave$1({
|
|
20873
20935
|
accountId,
|
|
20936
|
+
onSaveSuccess: response => {
|
|
20937
|
+
onSaveSuccess === null || onSaveSuccess === void 0 ? void 0 : onSaveSuccess(response);
|
|
20938
|
+
if (invalidatePaymentMethodsQuery) {
|
|
20939
|
+
queryClient.invalidateQueries({
|
|
20940
|
+
queryKey: QueryKeyFactory.accountPaymentMethodsKey({ accountId, token }),
|
|
20941
|
+
});
|
|
20942
|
+
}
|
|
20943
|
+
},
|
|
20944
|
+
onSaveError: onSaveErrorFinal,
|
|
20874
20945
|
});
|
|
20875
|
-
const
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
if (pluginName === 'StripePayment') {
|
|
20946
|
+
const save = async () => {
|
|
20947
|
+
var _a, _b, _c;
|
|
20948
|
+
if (pluginName === 'StripePayment')
|
|
20879
20949
|
return await saveStripe();
|
|
20880
|
-
|
|
20881
|
-
|
|
20882
|
-
|
|
20883
|
-
|
|
20884
|
-
else {
|
|
20885
|
-
showErrorNotification$7(`Can not find form for plugin ${(_b = (_a = selectedPlugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0].name}`);
|
|
20886
|
-
return undefined;
|
|
20887
|
-
}
|
|
20950
|
+
if (pluginName === 'DemoPayPayment')
|
|
20951
|
+
return await saveDemoPay();
|
|
20952
|
+
showErrorNotification$b(`Can not find form for plugin ${(_c = (_b = (_a = selectedPlugin === null || selectedPlugin === void 0 ? void 0 : selectedPlugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name}`);
|
|
20953
|
+
return undefined;
|
|
20888
20954
|
};
|
|
20889
|
-
|
|
20890
|
-
|
|
20891
|
-
|
|
20892
|
-
|
|
20955
|
+
return { save, isSaving: isSavingDemoPay || isSavingStripe };
|
|
20956
|
+
}
|
|
20957
|
+
|
|
20958
|
+
// Used for Signup component. Signup needs a custom checkout function
|
|
20959
|
+
const [CustomCheckoutFunctionProvider, useCustomCheckoutFunction] = createValueContext();
|
|
20960
|
+
|
|
20961
|
+
const showErrorNotification$a = useErrorNotification();
|
|
20962
|
+
function usePay$2({ onPaymentSuccess, onPaymentError, quoteId, invoiceId, plugin, }) {
|
|
20963
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
20964
|
+
const customCheckoutFunction = useCustomCheckoutFunction();
|
|
20965
|
+
const token = useToken();
|
|
20966
|
+
const [isPaying, setIsPaying] = react.useState(false);
|
|
20967
|
+
const pay = async (paymentMethodId) => {
|
|
20968
|
+
try {
|
|
20969
|
+
setIsPaying(true);
|
|
20970
|
+
if (customCheckoutFunction) {
|
|
20971
|
+
if (!(plugin === null || plugin === void 0 ? void 0 : plugin.id)) {
|
|
20972
|
+
showErrorNotification$a('Plugin ID is required');
|
|
20973
|
+
return;
|
|
20974
|
+
}
|
|
20975
|
+
const response = await customCheckoutFunction(plugin === null || plugin === void 0 ? void 0 : plugin.id.toString(), paymentMethodId.toString());
|
|
20976
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20977
|
+
}
|
|
20978
|
+
else {
|
|
20979
|
+
const response = await checkout({
|
|
20980
|
+
invoiceId,
|
|
20981
|
+
quoteId,
|
|
20982
|
+
paymentMethodId,
|
|
20983
|
+
token,
|
|
20984
|
+
apiHost,
|
|
20985
|
+
});
|
|
20986
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20987
|
+
}
|
|
20893
20988
|
}
|
|
20894
|
-
|
|
20895
|
-
|
|
20989
|
+
catch (error) {
|
|
20990
|
+
onPaymentError === null || onPaymentError === void 0 ? void 0 : onPaymentError(error);
|
|
20896
20991
|
}
|
|
20897
|
-
|
|
20898
|
-
|
|
20992
|
+
finally {
|
|
20993
|
+
setIsPaying(false);
|
|
20899
20994
|
}
|
|
20900
20995
|
};
|
|
20901
|
-
|
|
20902
|
-
|
|
20903
|
-
|
|
20904
|
-
|
|
20905
|
-
|
|
20906
|
-
|
|
20907
|
-
|
|
20908
|
-
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
}
|
|
20919
|
-
if (paymentType === PaymentType.PAY) {
|
|
20920
|
-
if (showPaymentMethodForm) {
|
|
20921
|
-
// If paying and showing payment method form, save payment method first, then pay (1 click for user convenience)
|
|
20922
|
-
const savedPaymentMethodId = await handleSave(demoPayCardDetails);
|
|
20923
|
-
if (savedPaymentMethodId) {
|
|
20924
|
-
await handlePayment(savedPaymentMethodId);
|
|
20996
|
+
return { pay, isPaying };
|
|
20997
|
+
}
|
|
20998
|
+
|
|
20999
|
+
const showErrorNotification$9 = useErrorNotification();
|
|
21000
|
+
function usePay$1({ onPaymentSuccess, onPaymentError, quoteId, invoiceId, plugin, }) {
|
|
21001
|
+
// Hooks
|
|
21002
|
+
const { apiHost } = react.useContext(BunnyContext);
|
|
21003
|
+
const customCheckoutFunction = useCustomCheckoutFunction();
|
|
21004
|
+
const token = useToken();
|
|
21005
|
+
const [isPaying, setIsPaying] = react.useState(false);
|
|
21006
|
+
const pay = async (paymentMethodId) => {
|
|
21007
|
+
try {
|
|
21008
|
+
setIsPaying(true);
|
|
21009
|
+
if (customCheckoutFunction) {
|
|
21010
|
+
if (!(plugin === null || plugin === void 0 ? void 0 : plugin.id)) {
|
|
21011
|
+
showErrorNotification$9('Plugin ID is required');
|
|
21012
|
+
return;
|
|
20925
21013
|
}
|
|
21014
|
+
const response = await customCheckoutFunction(plugin === null || plugin === void 0 ? void 0 : plugin.id.toString(), paymentMethodId.toString());
|
|
21015
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20926
21016
|
}
|
|
20927
21017
|
else {
|
|
20928
|
-
if (!
|
|
20929
|
-
showErrorNotification$
|
|
21018
|
+
if (!quoteId && !invoiceId) {
|
|
21019
|
+
showErrorNotification$9('Quote ID or Invoice ID is required');
|
|
20930
21020
|
return;
|
|
20931
21021
|
}
|
|
20932
|
-
|
|
21022
|
+
const response = await checkout({
|
|
21023
|
+
invoiceId,
|
|
21024
|
+
quoteId,
|
|
21025
|
+
paymentMethodId,
|
|
21026
|
+
token,
|
|
21027
|
+
apiHost,
|
|
21028
|
+
});
|
|
21029
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
20933
21030
|
}
|
|
20934
|
-
|
|
21031
|
+
}
|
|
21032
|
+
catch (error) {
|
|
21033
|
+
onPaymentError === null || onPaymentError === void 0 ? void 0 : onPaymentError(error);
|
|
21034
|
+
}
|
|
21035
|
+
finally {
|
|
21036
|
+
setIsPaying(false);
|
|
20935
21037
|
}
|
|
20936
21038
|
};
|
|
20937
|
-
|
|
20938
|
-
[FormattedAmountDueProvider, { value: formattedAmountDue }],
|
|
20939
|
-
[PaymentTypeProvider, { value: paymentType }],
|
|
20940
|
-
[IsPayingProvider, { value: isPaying }],
|
|
20941
|
-
[HandlePaymentFormSubmitProvider, { value: handlePaymentFormSubmit }],
|
|
20942
|
-
[IsSavingProvider, { value: isSavingDemoPay || isSavingStripe }],
|
|
20943
|
-
[IsPaidProvider, { value: isPaid }],
|
|
20944
|
-
[AccountIdProvider, { value: accountId }],
|
|
20945
|
-
];
|
|
20946
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: providers.reduceRight((acc, [Provider, props]) => react.createElement(Provider, props, acc), children) }));
|
|
21039
|
+
return { pay, isPaying };
|
|
20947
21040
|
}
|
|
20948
|
-
|
|
20949
|
-
|
|
20950
|
-
|
|
20951
|
-
|
|
21041
|
+
|
|
21042
|
+
const showErrorNotification$8 = useErrorNotification();
|
|
21043
|
+
function usePay({ plugin, quoteId, invoiceId, onPaymentSuccess, onPaymentError, }) {
|
|
21044
|
+
var _a, _b, _c;
|
|
21045
|
+
const pluginName = (_c = (_b = (_a = plugin === null || plugin === void 0 ? void 0 : plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name;
|
|
21046
|
+
const { pay: payStripe, isPaying: isPayingStripe } = usePay$1({
|
|
21047
|
+
onPaymentSuccess,
|
|
21048
|
+
onPaymentError,
|
|
21049
|
+
quoteId,
|
|
21050
|
+
invoiceId,
|
|
21051
|
+
plugin,
|
|
21052
|
+
});
|
|
21053
|
+
const { pay: payDemoPay, isPaying: isPayingDemoPay } = usePay$2({
|
|
21054
|
+
onPaymentSuccess,
|
|
21055
|
+
onPaymentError,
|
|
21056
|
+
quoteId,
|
|
21057
|
+
invoiceId,
|
|
21058
|
+
plugin,
|
|
21059
|
+
});
|
|
21060
|
+
const pay = async (paymentMethodId) => {
|
|
21061
|
+
if (!pluginName)
|
|
21062
|
+
return showErrorNotification$8('plugin name is required');
|
|
21063
|
+
switch (pluginName) {
|
|
21064
|
+
case 'StripePayment':
|
|
21065
|
+
await payStripe(paymentMethodId);
|
|
21066
|
+
return;
|
|
21067
|
+
case 'DemoPayPayment':
|
|
21068
|
+
await payDemoPay(paymentMethodId);
|
|
21069
|
+
return;
|
|
21070
|
+
default:
|
|
21071
|
+
showErrorNotification$8(`Payments are not supported by ${pluginName}`);
|
|
21072
|
+
return;
|
|
21073
|
+
}
|
|
21074
|
+
};
|
|
21075
|
+
return { pay, isPaying: isPayingStripe || isPayingDemoPay };
|
|
20952
21076
|
}
|
|
20953
21077
|
|
|
20954
|
-
function usePaymentButtonText() {
|
|
20955
|
-
const
|
|
20956
|
-
const paymentType =
|
|
20957
|
-
const
|
|
20958
|
-
const isSaving = useIsSaving();
|
|
20959
|
-
const isPaying = useIsPaying();
|
|
20960
|
-
const isProcessing = isSaving || isPaying;
|
|
21078
|
+
function usePaymentButtonText(props = {}) {
|
|
21079
|
+
const { isSaving, isPaying, isApprovingHold } = props;
|
|
21080
|
+
const { formattedAmountDue, paymentType, isPaid } = usePayable();
|
|
21081
|
+
const isProcessing = isSaving || isPaying || isApprovingHold;
|
|
20961
21082
|
// If payment is already successful, show the amount paid
|
|
20962
21083
|
if (isPaid) {
|
|
20963
21084
|
return 'Paid ' + (formattedAmountDue !== null && formattedAmountDue !== void 0 ? formattedAmountDue : '');
|
|
@@ -20972,34 +21093,95 @@ function usePaymentButtonText() {
|
|
|
20972
21093
|
return paymentTypeText + ' ' + (formattedAmountDue !== null && formattedAmountDue !== void 0 ? formattedAmountDue : '');
|
|
20973
21094
|
}
|
|
20974
21095
|
|
|
20975
|
-
const
|
|
20976
|
-
|
|
20977
|
-
|
|
20978
|
-
const
|
|
20979
|
-
const
|
|
20980
|
-
const
|
|
20981
|
-
const
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
|
|
21096
|
+
const handleAllErrorFormats$2 = useAllErrorFormats();
|
|
21097
|
+
const showErrorNotification$7 = useErrorNotification();
|
|
21098
|
+
function Pay(props = {}) {
|
|
21099
|
+
const { disabled } = props;
|
|
21100
|
+
const isMobile = useIsMobile();
|
|
21101
|
+
const { onPaymentSuccess, onPaymentHoldSuccess, onSavePaymentMethod, paymentHoldPrecondition } = usePaymentFormCallbacks();
|
|
21102
|
+
const selectedPlugin = useSelectedPlugin();
|
|
21103
|
+
const { quoteId, invoiceId, paymentHold, paymentType, setIsPaid } = usePayable();
|
|
21104
|
+
const accountId = useAccountId();
|
|
21105
|
+
const { defaultPaymentMethod } = usePaymentMethod({ accountId });
|
|
21106
|
+
const [showPaymentDetailsForm, setShowPaymentDetailsForm] = useShowPaymentDetails();
|
|
21107
|
+
const { save, isSaving } = useSave({
|
|
21108
|
+
accountId,
|
|
21109
|
+
onSaveSuccess: (response) => {
|
|
21110
|
+
onSavePaymentMethod === null || onSavePaymentMethod === void 0 ? void 0 : onSavePaymentMethod(response);
|
|
21111
|
+
},
|
|
21112
|
+
onSaveError: handleAllErrorFormats$2,
|
|
21113
|
+
invalidatePaymentMethodsQuery: true,
|
|
21114
|
+
});
|
|
21115
|
+
const { pay, isPaying } = usePay({
|
|
21116
|
+
plugin: selectedPlugin,
|
|
21117
|
+
quoteId,
|
|
21118
|
+
invoiceId,
|
|
21119
|
+
onPaymentSuccess: (response) => {
|
|
21120
|
+
setIsPaid(true);
|
|
21121
|
+
setShowPaymentDetailsForm(false);
|
|
21122
|
+
onPaymentSuccess === null || onPaymentSuccess === void 0 ? void 0 : onPaymentSuccess(response);
|
|
21123
|
+
},
|
|
21124
|
+
onPaymentError: error => handleAllErrorFormats$2(error),
|
|
21125
|
+
});
|
|
21126
|
+
const { approveHold, isApprovingHold } = usePaymentHold({
|
|
21127
|
+
plugin: selectedPlugin,
|
|
21128
|
+
onPaymentHoldSuccess: onPaymentHoldSuccess,
|
|
21129
|
+
onPaymentHoldError: error => handleAllErrorFormats$2(error),
|
|
21130
|
+
});
|
|
21131
|
+
const paymentButtonText = usePaymentButtonText({ isSaving, isPaying, isApprovingHold });
|
|
21132
|
+
async function handlePayment() {
|
|
21133
|
+
if (paymentType === PaymentType.APPROVE_HOLD) {
|
|
21134
|
+
if (paymentHoldPrecondition) {
|
|
21135
|
+
const allowed = await paymentHoldPrecondition();
|
|
21136
|
+
if (!allowed)
|
|
21137
|
+
return;
|
|
21138
|
+
}
|
|
21139
|
+
if (!paymentHold) {
|
|
21140
|
+
showErrorNotification$7('Payment hold is undefined');
|
|
21141
|
+
return;
|
|
21142
|
+
}
|
|
21143
|
+
// If payment details form is shown, save payment method first, then approve hold
|
|
21144
|
+
if (showPaymentDetailsForm) {
|
|
21145
|
+
const savedPaymentMethodId = await save();
|
|
21146
|
+
if (!savedPaymentMethodId) {
|
|
21147
|
+
showErrorNotification$7('Saved payment method ID is undefined');
|
|
21148
|
+
return;
|
|
21149
|
+
}
|
|
21150
|
+
await approveHold({ quote: { id: paymentHold.quoteId, amount: paymentHold.amountToHold }, paymentMethodId: savedPaymentMethodId });
|
|
21151
|
+
return;
|
|
21152
|
+
}
|
|
21153
|
+
if (!(defaultPaymentMethod === null || defaultPaymentMethod === void 0 ? void 0 : defaultPaymentMethod.id)) {
|
|
21154
|
+
showErrorNotification$7('Default payment method ID is undefined');
|
|
21155
|
+
return;
|
|
21156
|
+
}
|
|
21157
|
+
await approveHold({ quote: { id: paymentHold.quoteId, amount: paymentHold.amountToHold }, paymentMethodId: defaultPaymentMethod.id });
|
|
21158
|
+
return;
|
|
21159
|
+
}
|
|
21160
|
+
if (paymentType === PaymentType.PAY) {
|
|
21161
|
+
if (showPaymentDetailsForm) {
|
|
21162
|
+
// If paying and showing payment method form, save payment method first, then pay (1 click for user convenience)
|
|
21163
|
+
const savedPaymentMethodId = await save();
|
|
21164
|
+
if (savedPaymentMethodId) {
|
|
21165
|
+
await pay(savedPaymentMethodId);
|
|
21166
|
+
}
|
|
21167
|
+
}
|
|
21168
|
+
else {
|
|
21169
|
+
if (!(defaultPaymentMethod === null || defaultPaymentMethod === void 0 ? void 0 : defaultPaymentMethod.id)) {
|
|
21170
|
+
showErrorNotification$7('Default payment method ID is undefined');
|
|
21171
|
+
return;
|
|
21172
|
+
}
|
|
21173
|
+
await pay(defaultPaymentMethod === null || defaultPaymentMethod === void 0 ? void 0 : defaultPaymentMethod.id);
|
|
21174
|
+
}
|
|
21175
|
+
return;
|
|
21176
|
+
}
|
|
21177
|
+
}
|
|
21178
|
+
return (jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", disabled: isPaying || isApprovingHold || isSaving || disabled, loading: isPaying || isApprovingHold || isSaving, onClick: handlePayment, size: isMobile ? 'large' : 'middle', type: "primary", children: paymentButtonText }));
|
|
21179
|
+
}
|
|
21180
|
+
|
|
20985
21181
|
const defaultStyled = typeof styled === "function" ? styled : styled.default;
|
|
20986
21182
|
// !!! This is a workaround to avoid the issue with styled-components not supporting ESM
|
|
20987
21183
|
// Workaround from https://github.com/styled-components/styled-components/issues/3437#issuecomment-1103085056
|
|
20988
21184
|
|
|
20989
|
-
function PaymentMethodFooter({ onSubmit, noPadding, }) {
|
|
20990
|
-
const isPaying = useIsPaying();
|
|
20991
|
-
const isSaving = useIsSaving();
|
|
20992
|
-
const formattedAmountDue = useFormattedAmountDue();
|
|
20993
|
-
const paymentButtonText = usePaymentButtonText();
|
|
20994
|
-
const isMobile = useIsMobile();
|
|
20995
|
-
const [, setShowPaymentMethodForm] = useShowPaymentDetails();
|
|
20996
|
-
// If amount due is undefined, show the save button
|
|
20997
|
-
const payableAvailable = formattedAmountDue !== undefined;
|
|
20998
|
-
const saveButtonText = isSaving ? 'Saving' : 'Save';
|
|
20999
|
-
const buttonText = payableAvailable ? paymentButtonText : saveButtonText;
|
|
21000
|
-
return (jsxRuntime.jsxs("div", { className: `bunny-flex bunny-justify-end bunny-gap-2 ${noPadding ? '' : 'pt-6'}`, children: [jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", size: isMobile ? 'large' : 'middle', onClick: () => setShowPaymentMethodForm(false), children: "Cancel" }), jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", disabled: isSaving || isPaying, loading: isSaving || isPaying, onClick: onSubmit, size: isMobile ? 'large' : 'middle', type: "primary", children: buttonText })] }));
|
|
21001
|
-
}
|
|
21002
|
-
|
|
21003
21185
|
const DemoPayCardCvc = ({ autoFocus, onChange, placeholder, value, }) => {
|
|
21004
21186
|
const onKeyPress = (event) => {
|
|
21005
21187
|
if (!isDigit(event.key) && !isValidKey(event.keyCode))
|
|
@@ -21039,46 +21221,19 @@ const DemoPayExpiry = ({ autoFocus, onChange, placeholder, value, }) => {
|
|
|
21039
21221
|
};
|
|
21040
21222
|
|
|
21041
21223
|
const { Text: Text$C } = antd.Typography;
|
|
21042
|
-
const handleAllErrorFormats$1 = useAllErrorFormats();
|
|
21043
|
-
const TEST_CARD = '4242424242424242';
|
|
21044
21224
|
const DemoPayForm = () => {
|
|
21045
|
-
// Context
|
|
21046
21225
|
const { darkMode } = react.useContext(BunnyContext);
|
|
21047
|
-
const
|
|
21048
|
-
const [cardDetails, setCardDetails] = react.useState({
|
|
21049
|
-
number: '4242424242424242',
|
|
21050
|
-
expiry: '',
|
|
21051
|
-
cvc: '',
|
|
21052
|
-
});
|
|
21053
|
-
function onSubmit() {
|
|
21054
|
-
try {
|
|
21055
|
-
validateCardDetails();
|
|
21056
|
-
onPaymentFormSubmit(cardDetails);
|
|
21057
|
-
}
|
|
21058
|
-
catch (error) {
|
|
21059
|
-
handleAllErrorFormats$1(error);
|
|
21060
|
-
}
|
|
21061
|
-
}
|
|
21062
|
-
function validateCardDetails() {
|
|
21063
|
-
if (cardDetails.number !== TEST_CARD)
|
|
21064
|
-
throw new Error('Only the card number 4242 4242 4242 4242 will be accepted.');
|
|
21065
|
-
if (!isValidExpiry(cardDetails.expiry))
|
|
21066
|
-
throw new Error('Invalid expiry date');
|
|
21067
|
-
if (isCardExpired(cardDetails.expiry))
|
|
21068
|
-
throw new Error('Card is expired');
|
|
21069
|
-
if (cardDetails.cvc.length !== 3)
|
|
21070
|
-
throw new Error('Invalid CVC');
|
|
21071
|
-
}
|
|
21226
|
+
const [cardDetails, setCardDetails] = useDemoPayCardDetails();
|
|
21072
21227
|
const onCardNumberChange = (number) => {
|
|
21073
|
-
setCardDetails({ ...
|
|
21228
|
+
setCardDetails(prev => ({ ...prev, number }));
|
|
21074
21229
|
};
|
|
21075
21230
|
const onCardExpiryChange = (expiry) => {
|
|
21076
|
-
setCardDetails({ ...
|
|
21231
|
+
setCardDetails(prev => ({ ...prev, expiry }));
|
|
21077
21232
|
};
|
|
21078
21233
|
const onCardCvcChange = (cvc) => {
|
|
21079
|
-
setCardDetails({ ...
|
|
21234
|
+
setCardDetails(prev => ({ ...prev, cvc }));
|
|
21080
21235
|
};
|
|
21081
|
-
return (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2", children: [jsxRuntime.jsxs(StyledInputs, { className: "bunny-flex bunny-flex-col bunny-gap-2", darkMode: darkMode !== null && darkMode !== void 0 ? darkMode : false, children: [jsxRuntime.jsx(DemoPayCardNumber, { onChange: onCardNumberChange, value: cardDetails.number }), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-gap-2", children: [jsxRuntime.jsx(DemoPayExpiry, { onChange: onCardExpiryChange, value: cardDetails.expiry }), jsxRuntime.jsx(DemoPayCardCvc, { onChange: onCardCvcChange, value: cardDetails.cvc })] })] }), jsxRuntime.jsx(Text$C, { children: "DemoPay is for testing only." })
|
|
21236
|
+
return (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2", children: [jsxRuntime.jsxs(StyledInputs, { className: "bunny-flex bunny-flex-col bunny-gap-2", darkMode: darkMode !== null && darkMode !== void 0 ? darkMode : false, children: [jsxRuntime.jsx(DemoPayCardNumber, { onChange: onCardNumberChange, value: cardDetails.number }), jsxRuntime.jsxs("div", { className: "bunny-flex bunny-gap-2", children: [jsxRuntime.jsx(DemoPayExpiry, { onChange: onCardExpiryChange, value: cardDetails.expiry }), jsxRuntime.jsx(DemoPayCardCvc, { onChange: onCardCvcChange, value: cardDetails.cvc })] })] }), jsxRuntime.jsx(Text$C, { children: "DemoPay is for testing only." })] }));
|
|
21082
21237
|
};
|
|
21083
21238
|
const StyledInputs = defaultStyled.div `
|
|
21084
21239
|
.ant-input {
|
|
@@ -21090,8 +21245,6 @@ const StyledInputs = defaultStyled.div `
|
|
|
21090
21245
|
`;
|
|
21091
21246
|
|
|
21092
21247
|
const StripeForm = () => {
|
|
21093
|
-
// Context
|
|
21094
|
-
const onPaymentFormSubmit = useHandlePaymentFormSubmit();
|
|
21095
21248
|
// State
|
|
21096
21249
|
const [isIdealWarningOpen, setIsIdealWarningOpen] = react.useState(false);
|
|
21097
21250
|
const idealWarningHasShown = react.useRef(false);
|
|
@@ -21103,25 +21256,19 @@ const StripeForm = () => {
|
|
|
21103
21256
|
};
|
|
21104
21257
|
return (jsxRuntime.jsxs("form", { children: [jsxRuntime.jsx(reactStripeJs.PaymentElement, { options: {
|
|
21105
21258
|
layout: { type: 'accordion' },
|
|
21106
|
-
}, onChange: onChange }), jsxRuntime.jsx(
|
|
21259
|
+
}, onChange: onChange }), jsxRuntime.jsx(IdealWarningModal, { isOpen: isIdealWarningOpen, onClose: () => setIsIdealWarningOpen(false) })] }));
|
|
21107
21260
|
};
|
|
21108
21261
|
function IdealWarningModal({ isOpen, onClose }) {
|
|
21109
21262
|
return (jsxRuntime.jsx(antd.Modal, { open: isOpen, onCancel: onClose, footer: jsxRuntime.jsx(antd.Button, { type: "primary", onClick: onClose, children: "Ok" }), children: jsxRuntime.jsx("div", { className: "bunny-p-4", children: "iDEAL will charge a 1 cent fee when storing this payment method. You will be refunded later." }) }));
|
|
21110
21263
|
}
|
|
21111
21264
|
|
|
21112
|
-
const
|
|
21113
|
-
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21117
|
-
|
|
21118
|
-
|
|
21119
|
-
return jsxRuntime.jsx(DemoPayForm, {});
|
|
21120
|
-
default:
|
|
21121
|
-
console.warn('Can not find form for plugin', selectedPlugin);
|
|
21122
|
-
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
21123
|
-
}
|
|
21124
|
-
};
|
|
21265
|
+
const [PaymentMethodFormVisibilityProvider, usePaymentMethodFormVisibility] = createValueContext();
|
|
21266
|
+
|
|
21267
|
+
function Cancel() {
|
|
21268
|
+
const isMobile = useIsMobile();
|
|
21269
|
+
const [, setShowPaymentMethodForm] = useShowPaymentDetails();
|
|
21270
|
+
return (jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", size: isMobile ? 'large' : 'middle', onClick: () => setShowPaymentMethodForm(false), children: "Cancel" }));
|
|
21271
|
+
}
|
|
21125
21272
|
|
|
21126
21273
|
const CardIcon = ({ className }) => {
|
|
21127
21274
|
return (jsxRuntime.jsxs("svg", { className: className, width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [jsxRuntime.jsx("path", { d: "M15 3.75H3C2.17157 3.75 1.5 4.42157 1.5 5.25V12.75C1.5 13.5784 2.17157 14.25 3 14.25H15C15.8284 14.25 16.5 13.5784 16.5 12.75V5.25C16.5 4.42157 15.8284 3.75 15 3.75Z", stroke: SLATE_400, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }), jsxRuntime.jsx("path", { d: "M1.5 7.5H16.5", stroke: SLATE_400, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }));
|
|
@@ -21156,48 +21303,72 @@ const PaymentOptionContainer = defaultStyled.div `
|
|
|
21156
21303
|
}
|
|
21157
21304
|
`;
|
|
21158
21305
|
|
|
21159
|
-
|
|
21160
|
-
|
|
21306
|
+
const handleAllErrorFormats$1 = useAllErrorFormats();
|
|
21307
|
+
function Save() {
|
|
21161
21308
|
const accountId = useAccountId();
|
|
21162
|
-
const
|
|
21163
|
-
const
|
|
21164
|
-
const
|
|
21309
|
+
const isMobile = useIsMobile();
|
|
21310
|
+
const { onSavePaymentMethod } = usePaymentFormCallbacks();
|
|
21311
|
+
const [_, setShowPaymentDetailsForm] = useShowPaymentDetails();
|
|
21312
|
+
const { save: handleSave, isSaving } = useSave({
|
|
21165
21313
|
accountId,
|
|
21314
|
+
onSaveSuccess: (response) => {
|
|
21315
|
+
onSavePaymentMethod === null || onSavePaymentMethod === void 0 ? void 0 : onSavePaymentMethod(response);
|
|
21316
|
+
setShowPaymentDetailsForm(false);
|
|
21317
|
+
},
|
|
21318
|
+
onSaveError: handleAllErrorFormats$1,
|
|
21319
|
+
invalidatePaymentMethodsQuery: true,
|
|
21166
21320
|
});
|
|
21167
|
-
|
|
21168
|
-
|
|
21169
|
-
|
|
21170
|
-
|
|
21171
|
-
|
|
21172
|
-
|
|
21173
|
-
|
|
21174
|
-
|
|
21175
|
-
|
|
21176
|
-
|
|
21177
|
-
|
|
21178
|
-
|
|
21179
|
-
|
|
21180
|
-
|
|
21321
|
+
const saveButtonText = isSaving ? 'Saving' : 'Save';
|
|
21322
|
+
return (jsxRuntime.jsx(antd.Button, { className: "bunny-w-full", disabled: isSaving, loading: isSaving, onClick: handleSave, size: isMobile ? 'large' : 'middle', type: "primary", children: saveButtonText }));
|
|
21323
|
+
}
|
|
21324
|
+
|
|
21325
|
+
const showErrorNotification$6 = useErrorNotification();
|
|
21326
|
+
function PaymentMethodDetailsRoot(props = {}) {
|
|
21327
|
+
var _a, _b;
|
|
21328
|
+
const { footer } = props;
|
|
21329
|
+
const { showPaymentMethodForm, setShowPaymentMethodForm } = usePaymentMethodFormVisibility();
|
|
21330
|
+
const selectedPlugin = useSelectedPlugin();
|
|
21331
|
+
const accountId = useAccountId();
|
|
21332
|
+
const { paymentMethods } = usePaymentMethod({ accountId });
|
|
21333
|
+
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
21334
|
+
function handleClickAddPaymentMethod() {
|
|
21335
|
+
if ((paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.length) === 0) {
|
|
21336
|
+
showErrorNotification$6('No payment plugins available', 'Error adding payment method');
|
|
21337
|
+
}
|
|
21338
|
+
else {
|
|
21339
|
+
setShowPaymentMethodForm(true);
|
|
21181
21340
|
}
|
|
21182
21341
|
}
|
|
21342
|
+
// Automatically show the payment method form if there are no payment methods
|
|
21183
21343
|
react.useEffect(() => {
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
return;
|
|
21187
|
-
if ((paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) && (paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) > 0 && !defaultPaymentMethod) {
|
|
21188
|
-
handleSetDefault((_a = paymentMethods[0]) === null || _a === void 0 ? void 0 : _a.id);
|
|
21189
|
-
setDefaultPaymentMethodOnCache(paymentMethods[0]);
|
|
21344
|
+
if ((paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) === 0) {
|
|
21345
|
+
setShowPaymentMethodForm(true);
|
|
21190
21346
|
}
|
|
21191
|
-
}, [
|
|
21192
|
-
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
21347
|
+
}, [paymentMethods]);
|
|
21348
|
+
return (jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col", children: jsxRuntime.jsx(antd.Collapse, { bordered: false, activeKey: showPaymentMethodForm ? '1' : undefined, ghost: true, collapsible: "disabled", destroyOnHidden: true, items: [
|
|
21349
|
+
{
|
|
21350
|
+
key: '1',
|
|
21351
|
+
showArrow: false,
|
|
21352
|
+
label: !showPaymentMethodForm ? (jsxRuntime.jsx("div", { className: "bunny-pt-2", children: jsxRuntime.jsx(antd.Button, { onClick: handleClickAddPaymentMethod, type: "default", className: "bunny-w-full", id: "addPaymentMethod", children: "Add payment method" }) })) : null,
|
|
21353
|
+
children: (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2 bunny-mt-2", children: [jsxRuntime.jsx(PaymentMethodSelector, {}), selectedPlugin && (jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col", children: getPaymentMethodForm((_b = (_a = selectedPlugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0].name) })), footer] })),
|
|
21354
|
+
},
|
|
21355
|
+
] }) }));
|
|
21356
|
+
}
|
|
21357
|
+
const getPaymentMethodForm = (pluginName) => {
|
|
21358
|
+
switch (pluginName) {
|
|
21359
|
+
case 'StripePayment':
|
|
21360
|
+
return jsxRuntime.jsx(StripeForm, {});
|
|
21361
|
+
case 'DemoPayPayment':
|
|
21362
|
+
return jsxRuntime.jsx(DemoPayForm, {});
|
|
21363
|
+
default:
|
|
21364
|
+
console.warn('Can not find form for plugin', pluginName);
|
|
21365
|
+
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
21366
|
+
}
|
|
21200
21367
|
};
|
|
21368
|
+
const PaymentMethodDetails = Object.assign(PaymentMethodDetailsRoot, {
|
|
21369
|
+
Cancel,
|
|
21370
|
+
Save
|
|
21371
|
+
});
|
|
21201
21372
|
|
|
21202
21373
|
const query$8 = t(`
|
|
21203
21374
|
query GetCurrentUserData {
|
|
@@ -21255,113 +21426,6 @@ function usePayableCurrency({ payableCurrencyId, accountCurrencyId }) {
|
|
|
21255
21426
|
return { currencyId, isCurrencyIdLoading: isCurrentUserDataLoading };
|
|
21256
21427
|
}
|
|
21257
21428
|
|
|
21258
|
-
function useRemovePaymentMethod(onPaymentMethodRemoved, onError) {
|
|
21259
|
-
const queryClient = reactQuery.useQueryClient();
|
|
21260
|
-
const showErrorNotification = useErrorNotification();
|
|
21261
|
-
const showSuccessNotification = useSuccessNotification();
|
|
21262
|
-
const accountId = useAccountId();
|
|
21263
|
-
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
21264
|
-
const token = useToken();
|
|
21265
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
21266
|
-
const removePaymentMethod = react.useCallback(async (data) => {
|
|
21267
|
-
const plugin = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.find(paymentPlugin => { var _a; return String(paymentPlugin.id) === String((_a = data === null || data === void 0 ? void 0 : data.plugin) === null || _a === void 0 ? void 0 : _a.id); });
|
|
21268
|
-
if (data && plugin) {
|
|
21269
|
-
await invokePlugin({
|
|
21270
|
-
plugin: plugin, // TODO: type the plugin
|
|
21271
|
-
method: 'remove_payment_method',
|
|
21272
|
-
payload: {
|
|
21273
|
-
payment_method_id: data.id,
|
|
21274
|
-
account_id: accountId,
|
|
21275
|
-
},
|
|
21276
|
-
token,
|
|
21277
|
-
apiHost,
|
|
21278
|
-
})
|
|
21279
|
-
.then(() => {
|
|
21280
|
-
showSuccessNotification('Payment method was removed', 'Success');
|
|
21281
|
-
queryClient.invalidateQueries({
|
|
21282
|
-
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
21283
|
-
token,
|
|
21284
|
-
accountId,
|
|
21285
|
-
}),
|
|
21286
|
-
});
|
|
21287
|
-
onPaymentMethodRemoved === null || onPaymentMethodRemoved === void 0 ? void 0 : onPaymentMethodRemoved(data);
|
|
21288
|
-
})
|
|
21289
|
-
.catch((error) => {
|
|
21290
|
-
showErrorNotification(error.message, 'Error removing payment method');
|
|
21291
|
-
});
|
|
21292
|
-
}
|
|
21293
|
-
else {
|
|
21294
|
-
const availablePlugins = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.map(plugin => {
|
|
21295
|
-
var _a, _b;
|
|
21296
|
-
const components = plugin.components;
|
|
21297
|
-
return (_b = (_a = components === null || components === void 0 ? void 0 : components.frontend) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.name;
|
|
21298
|
-
});
|
|
21299
|
-
onError === null || onError === void 0 ? void 0 : onError(`Either the payment method was not found or the plugin was not present. Available plugins: ${availablePlugins === null || availablePlugins === void 0 ? void 0 : availablePlugins.join(', ')}`);
|
|
21300
|
-
}
|
|
21301
|
-
}, [paymentPlugins, token, apiHost, queryClient, onPaymentMethodRemoved, accountId, onError]);
|
|
21302
|
-
return removePaymentMethod;
|
|
21303
|
-
}
|
|
21304
|
-
|
|
21305
|
-
function useSetDefaultPaymentMethod(onError, onSuccess) {
|
|
21306
|
-
// Context
|
|
21307
|
-
const accountId = useAccountId();
|
|
21308
|
-
const token = useToken();
|
|
21309
|
-
const { apiHost } = react.useContext(BunnyContext);
|
|
21310
|
-
const { paymentPlugins } = usePaymentPlugins(accountId);
|
|
21311
|
-
const { paymentMethods } = usePaymentMethod({ accountId });
|
|
21312
|
-
// Hooks
|
|
21313
|
-
const showErrorNotification = useErrorNotification();
|
|
21314
|
-
const showSuccessNotification = useSuccessNotification();
|
|
21315
|
-
const queryClient = reactQuery.useQueryClient();
|
|
21316
|
-
// State
|
|
21317
|
-
const [loading, setLoading] = react.useState(false);
|
|
21318
|
-
const setDefaultPaymentMethod = react.useCallback(async (paymentMethodId) => {
|
|
21319
|
-
const paymentMethod = paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.find(paymentMethod => (paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.id) === paymentMethodId);
|
|
21320
|
-
if (paymentMethod === undefined) {
|
|
21321
|
-
showErrorNotification('Payment method not found', 'Error setting default payment method');
|
|
21322
|
-
return;
|
|
21323
|
-
}
|
|
21324
|
-
const plugin = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.find(paymentPlugin => { var _a; return String(paymentPlugin.id) === ((_a = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.plugin) === null || _a === void 0 ? void 0 : _a.id); }); // TODO: type the response to PluginData
|
|
21325
|
-
if (plugin) {
|
|
21326
|
-
setLoading(true);
|
|
21327
|
-
await invokePlugin({
|
|
21328
|
-
plugin: plugin,
|
|
21329
|
-
method: 'assign_default_payment_method',
|
|
21330
|
-
payload: {
|
|
21331
|
-
payment_method_id: paymentMethod.id,
|
|
21332
|
-
account_id: accountId,
|
|
21333
|
-
},
|
|
21334
|
-
token,
|
|
21335
|
-
apiHost,
|
|
21336
|
-
})
|
|
21337
|
-
.then(() => {
|
|
21338
|
-
var _a;
|
|
21339
|
-
showSuccessNotification(`Payment method ${(_a = paymentMethod === null || paymentMethod === void 0 ? void 0 : paymentMethod.metadata) === null || _a === void 0 ? void 0 : _a.identifier} was set as default`, 'Success');
|
|
21340
|
-
onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess();
|
|
21341
|
-
queryClient.invalidateQueries({
|
|
21342
|
-
queryKey: QueryKeyFactory.accountPaymentMethodsKey({
|
|
21343
|
-
token,
|
|
21344
|
-
accountId,
|
|
21345
|
-
}),
|
|
21346
|
-
});
|
|
21347
|
-
})
|
|
21348
|
-
.catch((error) => {
|
|
21349
|
-
setLoading(false);
|
|
21350
|
-
showErrorNotification(error.message, 'Error removing payment method');
|
|
21351
|
-
})
|
|
21352
|
-
.finally(() => {
|
|
21353
|
-
setLoading(false);
|
|
21354
|
-
});
|
|
21355
|
-
}
|
|
21356
|
-
else {
|
|
21357
|
-
const availablePlugins = paymentPlugins === null || paymentPlugins === void 0 ? void 0 : paymentPlugins.map((plugin) => { var _a, _b, _c; return (_c = (_b = (_a = plugin.components) === null || _a === void 0 ? void 0 : _a.frontend) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.name; });
|
|
21358
|
-
onError === null || onError === void 0 ? void 0 : onError(`Either the payment method was not found or the plugin was not present. Available plugins: ${availablePlugins === null || availablePlugins === void 0 ? void 0 : availablePlugins.join(', ')}`);
|
|
21359
|
-
}
|
|
21360
|
-
}, [paymentPlugins, token, apiHost, queryClient]);
|
|
21361
|
-
return { setDefaultPaymentMethod, loading };
|
|
21362
|
-
}
|
|
21363
|
-
|
|
21364
|
-
const showErrorNotification$6 = useErrorNotification();
|
|
21365
21429
|
const PaymentForm_QuoteFragment = t(`
|
|
21366
21430
|
fragment PaymentForm_QuoteFragment on Quote {
|
|
21367
21431
|
id
|
|
@@ -21369,10 +21433,18 @@ const PaymentForm_QuoteFragment = t(`
|
|
|
21369
21433
|
...PaymentProvider_QuoteFragment
|
|
21370
21434
|
}
|
|
21371
21435
|
`, [PaymentProvider_QuoteFragment]);
|
|
21372
|
-
|
|
21436
|
+
const PaymentForm_InvoiceFragment = t(`
|
|
21437
|
+
fragment PaymentForm_InvoiceFragment on Invoice {
|
|
21438
|
+
id
|
|
21439
|
+
currencyId
|
|
21440
|
+
...PaymentProvider_InvoiceFragment
|
|
21441
|
+
}
|
|
21442
|
+
`, [PaymentProvider_InvoiceFragment]);
|
|
21443
|
+
function PaymentFormRoot({ currencyId: accountCurrencyId, invoice: maskedInvoice, quote: maskedQuote, paymentHold, onPaymentSuccess, onPaymentHoldSuccess, paymentHoldPrecondition, accountId, onSavePaymentMethod, onPaymentMethodRemoved, onSetDefaultPaymentMethod, overrideToken, customCheckoutFunction, children, }) {
|
|
21373
21444
|
var _a;
|
|
21374
21445
|
// Read fragments
|
|
21375
21446
|
const quote = readFragment(PaymentForm_QuoteFragment, maskedQuote);
|
|
21447
|
+
const invoice = readFragment(PaymentForm_InvoiceFragment, maskedInvoice);
|
|
21376
21448
|
const { currencyId, isCurrencyIdLoading } = usePayableCurrency({
|
|
21377
21449
|
payableCurrencyId: (_a = quote === null || quote === void 0 ? void 0 : quote.currencyId) !== null && _a !== void 0 ? _a : invoice === null || invoice === void 0 ? void 0 : invoice.currencyId,
|
|
21378
21450
|
accountCurrencyId,
|
|
@@ -21389,66 +21461,66 @@ function PaymentForm({ currencyId: accountCurrencyId, invoice, quote: maskedQuot
|
|
|
21389
21461
|
const providers = [
|
|
21390
21462
|
[ShowPaymentDetailsProvider, { value: undefined }],
|
|
21391
21463
|
[CustomCheckoutFunctionProvider, { value: customCheckoutFunction }],
|
|
21392
|
-
[
|
|
21464
|
+
[AccountIdProvider, { value: accountId }],
|
|
21393
21465
|
];
|
|
21394
|
-
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: providers.reduceRight((acc, [Provider, props]) => react.createElement(Provider, props, acc), jsxRuntime.jsx(OverrideTokenContext.Provider, { value: { overrideToken }, children: jsxRuntime.jsx(SelectedPluginProvider, { accountId: accountId, children: jsxRuntime.jsx(
|
|
21466
|
+
return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: providers.reduceRight((acc, [Provider, props]) => react.createElement(Provider, props, acc), jsxRuntime.jsx(OverrideTokenContext.Provider, { value: { overrideToken }, children: jsxRuntime.jsx(SelectedPluginProvider, { accountId: accountId, children: jsxRuntime.jsx(StripeFormProvider, { currencyId: currencyId, accountId: accountId, children: jsxRuntime.jsx(DemoPayFormProvider, { children: jsxRuntime.jsx(PaymentFormCallbacksProvider, { value: {
|
|
21467
|
+
onPaymentSuccess,
|
|
21468
|
+
onSetDefaultPaymentMethod,
|
|
21469
|
+
onPaymentMethodRemoved,
|
|
21470
|
+
onSavePaymentMethod,
|
|
21471
|
+
onPaymentHoldSuccess,
|
|
21472
|
+
paymentHoldPrecondition,
|
|
21473
|
+
}, children: jsxRuntime.jsx(PaymentProvider, { quote: quote, invoice: invoice, paymentHold: paymentHold, children: jsxRuntime.jsx(PaymentFormContent, { children: children }) }) }) }) }) }) })) }));
|
|
21474
|
+
}
|
|
21475
|
+
// Default layout that uses PaymentFormRoot under the hood when no children are provided.
|
|
21476
|
+
function PaymentFormDefault(props) {
|
|
21477
|
+
console.log('PaymentFormDefault', props);
|
|
21478
|
+
return jsxRuntime.jsx(PaymentFormRoot, { ...props, children: ({ hasPaymentMethods, isPaymentMethodDetailsOpen, isPayableAvailable, amountDue }) => {
|
|
21479
|
+
const showPayButton = amountDue !== undefined && amountDue > 0 && !isPaymentMethodDetailsOpen && hasPaymentMethods;
|
|
21480
|
+
const checkoutNoPaymentButton = amountDue !== undefined && amountDue === 0;
|
|
21481
|
+
console.log('props.disablePayButton', props.disablePayButton);
|
|
21482
|
+
if (checkoutNoPaymentButton) {
|
|
21483
|
+
return jsxRuntime.jsx(PaymentForm.CheckoutNoPayment, { className: "bunny-px-4", disabled: props.disablePayButton });
|
|
21484
|
+
}
|
|
21485
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PaymentForm.StoredPaymentMethods, { className: "bunny-px-4" }), jsxRuntime.jsx(PaymentForm.PaymentMethodDetails, { footer: jsxRuntime.jsxs("div", { className: "bunny-flex bunny-w-full bunny-gap-2", children: [jsxRuntime.jsx(PaymentForm.PaymentMethodDetails.Cancel, {}), isPayableAvailable && jsxRuntime.jsx(PaymentForm.Pay, { disabled: props.disablePayButton }), !isPayableAvailable && jsxRuntime.jsx(PaymentForm.PaymentMethodDetails.Save, {})] }) }), showPayButton && (jsxRuntime.jsx("div", { className: "bunny-px-4", children: jsxRuntime.jsx(PaymentForm.Pay, { disabled: props.disablePayButton }) }))] }));
|
|
21486
|
+
} });
|
|
21395
21487
|
}
|
|
21396
|
-
function PaymentFormContent({
|
|
21488
|
+
function PaymentFormContent({ children, }) {
|
|
21397
21489
|
// Context
|
|
21398
21490
|
const [showPaymentMethodForm, setShowPaymentMethodForm] = useShowPaymentDetails();
|
|
21399
|
-
const paymentType = usePaymentType();
|
|
21400
|
-
const isPaying = useIsPaying();
|
|
21401
|
-
const formattedAmountDue = useFormattedAmountDue();
|
|
21402
|
-
const selectedPlugin = useSelectedPlugin();
|
|
21403
|
-
const onPaymentFormSubmit = useHandlePaymentFormSubmit();
|
|
21404
21491
|
const accountId = useAccountId();
|
|
21492
|
+
const { quoteId, invoiceId, amountDue } = usePayable();
|
|
21405
21493
|
// Hooks
|
|
21406
|
-
const {
|
|
21407
|
-
const { paymentMethods: maskedPaymentMethods, isLoading: isPaymentMethodLoading } = usePaymentMethod({ accountId });
|
|
21408
|
-
// Read fragments
|
|
21409
|
-
const paymentMethods = react.useMemo(() => maskedPaymentMethods === null || maskedPaymentMethods === void 0 ? void 0 : maskedPaymentMethods.map(paymentMethod => readFragment(PaymentForm_PaymentMethodsFragment, paymentMethod)), [maskedPaymentMethods]);
|
|
21494
|
+
const { paymentMethods } = usePaymentMethod({ accountId });
|
|
21410
21495
|
// Derived state
|
|
21411
21496
|
const hasPaymentMethods = (paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) && (paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) > 0;
|
|
21412
|
-
|
|
21413
|
-
const
|
|
21414
|
-
|
|
21415
|
-
|
|
21416
|
-
|
|
21417
|
-
|
|
21418
|
-
|
|
21419
|
-
|
|
21420
|
-
|
|
21421
|
-
|
|
21422
|
-
|
|
21423
|
-
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
}
|
|
21430
|
-
else {
|
|
21431
|
-
setShowPaymentMethodForm(true);
|
|
21432
|
-
}
|
|
21433
|
-
}
|
|
21434
|
-
// Automatically show the payment method form if there are no payment methods
|
|
21435
|
-
react.useEffect(() => {
|
|
21436
|
-
if ((paymentMethods === null || paymentMethods === void 0 ? void 0 : paymentMethods.length) === 0) {
|
|
21437
|
-
setShowPaymentMethodForm(true);
|
|
21438
|
-
}
|
|
21439
|
-
}, [paymentMethods]);
|
|
21440
|
-
if (isPaymentMethodLoading) {
|
|
21441
|
-
return jsxRuntime.jsx(antd.Skeleton, { active: true, className: "bunny-p-4" });
|
|
21497
|
+
const isPayableAvailable = quoteId !== undefined || invoiceId !== undefined;
|
|
21498
|
+
const renderState = {
|
|
21499
|
+
hasPaymentMethods: !!hasPaymentMethods,
|
|
21500
|
+
isPaymentMethodDetailsOpen: showPaymentMethodForm,
|
|
21501
|
+
isPayableAvailable,
|
|
21502
|
+
amountDue,
|
|
21503
|
+
};
|
|
21504
|
+
const renderedChildren = typeof children === 'function' ? children(renderState) : children;
|
|
21505
|
+
return (jsxRuntime.jsx(PaymentMethodFormVisibilityProvider, { value: {
|
|
21506
|
+
showPaymentMethodForm,
|
|
21507
|
+
setShowPaymentMethodForm,
|
|
21508
|
+
}, children: jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col bunny-w-full", children: renderedChildren }) }));
|
|
21509
|
+
}
|
|
21510
|
+
// Public component: if children are passed, use PaymentFormRoot directly (render-prop / custom layout).
|
|
21511
|
+
// If no children are passed, fall back to PaymentFormDefault which uses PaymentFormRoot under the hood.
|
|
21512
|
+
function PaymentFormInternal(props) {
|
|
21513
|
+
if (props.children != null) {
|
|
21514
|
+
return jsxRuntime.jsx(PaymentFormRoot, { ...props });
|
|
21442
21515
|
}
|
|
21443
|
-
return
|
|
21444
|
-
{
|
|
21445
|
-
key: '1',
|
|
21446
|
-
showArrow: false,
|
|
21447
|
-
label: !showPaymentMethodForm ? (jsxRuntime.jsx("div", { className: "bunny-pt-2", children: jsxRuntime.jsx(antd.Button, { onClick: handleClickAddPaymentMethod, type: "default", className: "bunny-w-full", id: "addPaymentMethod", children: "Add payment method" }) })) : null,
|
|
21448
|
-
children: (jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-gap-2 bunny-mt-2", children: [jsxRuntime.jsx(PaymentMethodSelector, {}), selectedPlugin && (jsxRuntime.jsx("div", { className: "bunny-flex bunny-flex-col", children: jsxRuntime.jsx(PaymentMethodDetails, {}) }))] })),
|
|
21449
|
-
},
|
|
21450
|
-
] }), formattedAmountDue !== undefined && !showPaymentMethodForm && hasPaymentMethods ? (jsxRuntime.jsx("div", { className: "bunny-px-4", children: jsxRuntime.jsx(CheckoutFooter, {}) })) : null] })) : (jsxRuntime.jsx(antd.Button, { style: { margin: '0 16px' }, loading: isPaying, onClick: () => onPaymentFormSubmit(), type: "primary", children: isPaying ? 'Processing...' : 'Complete Order' })) }));
|
|
21516
|
+
return jsxRuntime.jsx(PaymentFormDefault, { ...props });
|
|
21451
21517
|
}
|
|
21518
|
+
const PaymentForm = Object.assign(PaymentFormInternal, {
|
|
21519
|
+
StoredPaymentMethods,
|
|
21520
|
+
Pay,
|
|
21521
|
+
CheckoutNoPayment,
|
|
21522
|
+
PaymentMethodDetails,
|
|
21523
|
+
});
|
|
21452
21524
|
|
|
21453
21525
|
const useAjax = (onError) => {
|
|
21454
21526
|
return async (url, method, callback, token, bodyData) => {
|
|
@@ -21942,8 +22014,8 @@ const PaymentHoldModal = ({ visible, setVisible, formattedQuote: maskedFormatted
|
|
|
21942
22014
|
const [form] = antd.Form.useForm();
|
|
21943
22015
|
return (jsxRuntime.jsx(StyledModal$2, { centered: true, onCancel: () => {
|
|
21944
22016
|
setVisible(false);
|
|
21945
|
-
}, footer: null, open: visible, width:
|
|
21946
|
-
|
|
22017
|
+
}, footer: null, open: visible, width: 900, className: 'bunny-flex bunny-flex-row bunny-gap-4', children: jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-row", children: [jsxRuntime.jsxs("div", { className: "bunny-flex bunny-flex-col bunny-w-1/2", children: [jsxRuntime.jsxs("div", { className: "bunny-mt-5 bunny-mx-4", children: [jsxRuntime.jsx(Title$2, { className: "bunny-mt-0", level: 5, children: "Pay and sign" }), jsxRuntime.jsxs(Text$z, { className: "bunny-bt-2 bunny-text-sm/5 bunny-text-gray-500", children: ["To accept this quote, approve a payment hold for", ' ', formatCurrency(formattedQuote.amount, formattedQuote.currency || 'null'), ". This amount will be charged to your payment method once the quote is signed."] })] }), jsxRuntime.jsx("div", { className: "bunny-p-4 bunny-pb-6", children: noSigningPlugins ? jsxRuntime.jsx(NoSigningPluginsForm, { isVisible: visible, formattedQuote: formattedQuote, form: form }) : null })] }), jsxRuntime.jsx(VerticalDivider, { className: "bunny-m-4" }), jsxRuntime.jsx("div", { className: "bunny-mb-3 bunny-w-1/2 bunny-pt-6", children: jsxRuntime.jsx(PaymentForm, { quote: formattedQuote.quote, paymentHold: {
|
|
22018
|
+
quoteId: formattedQuote.quote.id, // TODO: fix hack. We assume the quote id is always present, but may not be the case
|
|
21947
22019
|
amountToHold: formattedQuote.amount,
|
|
21948
22020
|
}, onPaymentSuccess: () => {
|
|
21949
22021
|
setVisible(false);
|
|
@@ -24134,7 +24206,7 @@ const QuoteCheckout = ({ account, onSuccess, onFail, quote: maskedQuote, taxatio
|
|
|
24134
24206
|
removeCoupon(couponCode);
|
|
24135
24207
|
}
|
|
24136
24208
|
});
|
|
24137
|
-
}, children: "Remove coupon(s)" }))] })) : (jsxRuntime.jsxs("div", { className: `bunny-flex bunny-flex-col bunny-gap-2 bunny-px-4 ${isMobile ? 'bunny-shadow-padding-x' : ''}`, children: [jsxRuntime.jsx(antd.Button, { onClick: handleCheckoutNoPayment, type: "primary", children: isSaving ? 'Processing...' : 'Complete order' }), jsxRuntime.jsx(Text$m, { className: "bunny-text-xs bunny-text-slate-500", children: "No payment is required" })] })) }));
|
|
24209
|
+
}, children: "Remove coupon(s)" }))] })) : (jsxRuntime.jsxs("div", { className: `bunny-flex bunny-flex-col bunny-gap-2 bunny-px-4 ${isMobile ? 'bunny-shadow-padding-x' : ''}`, children: [jsxRuntime.jsx(antd.Button, { onClick: handleCheckoutNoPayment, type: "primary", disabled: isFinalizingQuote, loading: isSaving || isFinalizingQuote, children: isSaving ? 'Processing...' : 'Complete order' }), jsxRuntime.jsx(Text$m, { className: "bunny-text-xs bunny-text-slate-500", children: "No payment is required" })] })) }));
|
|
24138
24210
|
};
|
|
24139
24211
|
const PaymentFormWrapper = ({ children, setMaxHeight, className, }) => {
|
|
24140
24212
|
const isMobile = useIsMobile();
|