@tagadapay/plugin-sdk 2.4.2 → 2.4.4
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.
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
export interface Address {
|
|
3
|
+
address1: string;
|
|
4
|
+
address2?: string;
|
|
5
|
+
lastName?: string;
|
|
6
|
+
firstName?: string;
|
|
7
|
+
city?: string;
|
|
8
|
+
state?: string;
|
|
9
|
+
country?: string;
|
|
10
|
+
postal?: string;
|
|
11
|
+
phone?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
}
|
|
14
|
+
type PaymentMethod = {
|
|
15
|
+
id: string;
|
|
16
|
+
type: string;
|
|
17
|
+
title: string;
|
|
18
|
+
iconUrl: string;
|
|
19
|
+
default: boolean;
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
};
|
|
22
|
+
type ExpressOrderLineItem = {
|
|
23
|
+
label: string;
|
|
24
|
+
amount: string;
|
|
25
|
+
};
|
|
26
|
+
type ExpressShippingMethod = {
|
|
27
|
+
label: string;
|
|
28
|
+
amount: string;
|
|
29
|
+
identifier: string;
|
|
30
|
+
detail: string;
|
|
31
|
+
};
|
|
32
|
+
export interface ExpressPaymentContextType {
|
|
33
|
+
applePayPaymentMethod?: PaymentMethod;
|
|
34
|
+
googlePayPaymentMethod?: PaymentMethod;
|
|
35
|
+
reComputeOrderSummary: () => Promise<{
|
|
36
|
+
lineItems: ExpressOrderLineItem[];
|
|
37
|
+
total: {
|
|
38
|
+
label: string;
|
|
39
|
+
amount: string;
|
|
40
|
+
};
|
|
41
|
+
shippingMethods: ExpressShippingMethod[];
|
|
42
|
+
} | undefined>;
|
|
43
|
+
loading?: boolean;
|
|
44
|
+
availableExpressPaymentMethodIds: string[];
|
|
45
|
+
setAvailableExpressPaymentMethodIds: (value: string[]) => void;
|
|
46
|
+
shippingMethods: ExpressShippingMethod[];
|
|
47
|
+
lineItems: ExpressOrderLineItem[];
|
|
48
|
+
handleAddExpressId: (id: string) => void;
|
|
49
|
+
updateCheckoutSessionValues: (input: {
|
|
50
|
+
data: {
|
|
51
|
+
shippingAddress: Address;
|
|
52
|
+
billingAddress?: Address | null;
|
|
53
|
+
};
|
|
54
|
+
}) => Promise<void>;
|
|
55
|
+
updateCustomerEmail: (input: {
|
|
56
|
+
data: {
|
|
57
|
+
email: string;
|
|
58
|
+
};
|
|
59
|
+
}) => Promise<void>;
|
|
60
|
+
error: string | null;
|
|
61
|
+
setError: (error: string | null) => void;
|
|
62
|
+
}
|
|
63
|
+
interface ExpressPaymentProviderProps {
|
|
64
|
+
children: ReactNode;
|
|
65
|
+
checkoutSessionId: string;
|
|
66
|
+
customerId?: string;
|
|
67
|
+
}
|
|
68
|
+
export declare const ExpressPaymentProvider: React.FC<ExpressPaymentProviderProps>;
|
|
69
|
+
export declare const useExpressPayment: () => ExpressPaymentContextType;
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
3
|
+
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
4
|
+
import { useOrderSummary } from './useOrderSummary';
|
|
5
|
+
import { useShippingRates } from './useShippingRates';
|
|
6
|
+
const ExpressPaymentContext = createContext(undefined);
|
|
7
|
+
export const ExpressPaymentProvider = ({ children, checkoutSessionId, customerId, }) => {
|
|
8
|
+
const { apiService } = useTagadaContext();
|
|
9
|
+
const [availableExpressPaymentMethodIds, setAvailableExpressPaymentMethodIds] = useState([]);
|
|
10
|
+
const [error, setError] = useState(null);
|
|
11
|
+
const [paymentMethods, setPaymentMethods] = useState(null);
|
|
12
|
+
const [isLoadingPaymentMethods, setIsLoadingPaymentMethods] = useState(false);
|
|
13
|
+
// Fetch enabled payment methods for this checkout session
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
let mounted = true;
|
|
16
|
+
const fetchPaymentMethods = async () => {
|
|
17
|
+
try {
|
|
18
|
+
setIsLoadingPaymentMethods(true);
|
|
19
|
+
const response = await apiService.fetch(`/api/v1/payment-methods?checkoutSessionId=${encodeURIComponent(checkoutSessionId)}`);
|
|
20
|
+
if (mounted)
|
|
21
|
+
setPaymentMethods(response);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
if (mounted)
|
|
25
|
+
setPaymentMethods([]);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
if (mounted)
|
|
29
|
+
setIsLoadingPaymentMethods(false);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
if (checkoutSessionId)
|
|
33
|
+
void fetchPaymentMethods();
|
|
34
|
+
return () => {
|
|
35
|
+
mounted = false;
|
|
36
|
+
};
|
|
37
|
+
}, [apiService, checkoutSessionId]);
|
|
38
|
+
const handleAddExpressId = (id) => {
|
|
39
|
+
setAvailableExpressPaymentMethodIds((prev) => (prev.includes(id) ? prev : [...prev, id]));
|
|
40
|
+
};
|
|
41
|
+
// Base data hooks
|
|
42
|
+
const { orderSummary, isLoading: isLoadingOrderSummary, isRefetching: isRefetchingOrderSummary, refetch: refetchOrderSummary, } = useOrderSummary({ sessionId: checkoutSessionId });
|
|
43
|
+
const { shippingRates, isLoading: isLoadingShippingRates, isFetching: isFetchingShippingRates, refetch: refetchRates, } = useShippingRates({ checkoutSessionId });
|
|
44
|
+
const minorUnitsToCurrencyString = (amountMinor, currency) => {
|
|
45
|
+
if (!amountMinor || !currency)
|
|
46
|
+
return '0.00';
|
|
47
|
+
return (amountMinor / 100).toFixed(2);
|
|
48
|
+
};
|
|
49
|
+
const shippingMethods = useMemo(() => (shippingRates || []).map((rate) => ({
|
|
50
|
+
label: rate.shippingRateName,
|
|
51
|
+
amount: minorUnitsToCurrencyString(rate.amount, rate.currency),
|
|
52
|
+
identifier: rate.id,
|
|
53
|
+
detail: rate.description || '',
|
|
54
|
+
})), [shippingRates]);
|
|
55
|
+
const lineItems = useMemo(() => [
|
|
56
|
+
{
|
|
57
|
+
label: 'Subtotal',
|
|
58
|
+
amount: minorUnitsToCurrencyString(orderSummary?.subtotalAdjustedAmount, orderSummary?.currency),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
label: 'Shipping',
|
|
62
|
+
amount: minorUnitsToCurrencyString(orderSummary?.shippingCost ?? 0, orderSummary?.currency),
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
label: 'Tax',
|
|
66
|
+
amount: minorUnitsToCurrencyString(orderSummary?.totalTaxAmount, orderSummary?.currency),
|
|
67
|
+
},
|
|
68
|
+
], [
|
|
69
|
+
orderSummary?.subtotalAdjustedAmount,
|
|
70
|
+
orderSummary?.shippingCost,
|
|
71
|
+
orderSummary?.totalTaxAmount,
|
|
72
|
+
orderSummary?.currency,
|
|
73
|
+
]);
|
|
74
|
+
const reComputeOrderSummary = useCallback(async () => {
|
|
75
|
+
try {
|
|
76
|
+
await refetchOrderSummary();
|
|
77
|
+
await refetchRates();
|
|
78
|
+
if (!orderSummary || !shippingRates)
|
|
79
|
+
return;
|
|
80
|
+
const recomputedLineItems = [
|
|
81
|
+
{
|
|
82
|
+
label: 'Subtotal',
|
|
83
|
+
amount: minorUnitsToCurrencyString(orderSummary.subtotalAdjustedAmount, orderSummary.currency),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
label: 'Shipping',
|
|
87
|
+
amount: minorUnitsToCurrencyString(orderSummary.shippingCost ?? 0, orderSummary.currency),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
label: 'Tax',
|
|
91
|
+
amount: minorUnitsToCurrencyString(orderSummary.totalTaxAmount, orderSummary.currency),
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
const total = {
|
|
95
|
+
label: 'Order Total',
|
|
96
|
+
amount: minorUnitsToCurrencyString(orderSummary.totalAdjustedAmount, orderSummary.currency),
|
|
97
|
+
};
|
|
98
|
+
const recomputedShippingMethods = (shippingRates || []).map((rate) => ({
|
|
99
|
+
label: rate.shippingRateName,
|
|
100
|
+
amount: minorUnitsToCurrencyString(rate.amount, rate.currency),
|
|
101
|
+
identifier: rate.id,
|
|
102
|
+
detail: rate.description || '',
|
|
103
|
+
}));
|
|
104
|
+
return {
|
|
105
|
+
lineItems: recomputedLineItems,
|
|
106
|
+
total,
|
|
107
|
+
shippingMethods: recomputedShippingMethods,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}, [orderSummary, shippingRates, refetchOrderSummary, refetchRates]);
|
|
114
|
+
const updateCheckoutSessionValues = useCallback(async (input) => {
|
|
115
|
+
await apiService.fetch(`/api/v1/checkout-sessions/${checkoutSessionId}/address`, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
body: input,
|
|
118
|
+
});
|
|
119
|
+
}, [apiService, checkoutSessionId]);
|
|
120
|
+
const updateCustomerEmail = useCallback(async (input) => {
|
|
121
|
+
if (!customerId)
|
|
122
|
+
return;
|
|
123
|
+
await apiService.fetch(`/api/v1/customers/${customerId}`, {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
body: input,
|
|
126
|
+
});
|
|
127
|
+
}, [apiService, customerId]);
|
|
128
|
+
const enabledApplePayPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'apple_pay'), [paymentMethods]);
|
|
129
|
+
const enabledGooglePayPaymentMethod = useMemo(() => paymentMethods?.find((p) => p.type === 'google_pay'), [paymentMethods]);
|
|
130
|
+
const loading = !paymentMethods || isLoadingPaymentMethods || isLoadingOrderSummary;
|
|
131
|
+
const contextValue = {
|
|
132
|
+
availableExpressPaymentMethodIds,
|
|
133
|
+
setAvailableExpressPaymentMethodIds,
|
|
134
|
+
applePayPaymentMethod: enabledApplePayPaymentMethod,
|
|
135
|
+
googlePayPaymentMethod: enabledGooglePayPaymentMethod,
|
|
136
|
+
shippingMethods,
|
|
137
|
+
lineItems,
|
|
138
|
+
reComputeOrderSummary,
|
|
139
|
+
loading,
|
|
140
|
+
handleAddExpressId,
|
|
141
|
+
updateCheckoutSessionValues,
|
|
142
|
+
updateCustomerEmail,
|
|
143
|
+
error,
|
|
144
|
+
setError,
|
|
145
|
+
};
|
|
146
|
+
const hasAnyEnabled = Boolean(enabledApplePayPaymentMethod || enabledGooglePayPaymentMethod);
|
|
147
|
+
return (_jsx(ExpressPaymentContext.Provider, { value: contextValue, children: hasAnyEnabled ? _jsx(_Fragment, { children: children }) : _jsx(_Fragment, {}) }));
|
|
148
|
+
};
|
|
149
|
+
export const useExpressPayment = () => {
|
|
150
|
+
const context = useContext(ExpressPaymentContext);
|
|
151
|
+
if (context === undefined) {
|
|
152
|
+
throw new Error('useExpressPayment must be used within an ExpressPaymentProvider');
|
|
153
|
+
}
|
|
154
|
+
return context;
|
|
155
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
2
2
|
import { useTagadaContext } from '../providers/TagadaProvider';
|
|
3
3
|
import { usePluginConfig } from './usePluginConfig';
|
|
4
4
|
export function useProducts(options = {}) {
|
|
@@ -42,6 +42,7 @@ export function useProducts(options = {}) {
|
|
|
42
42
|
productId,
|
|
43
43
|
storeId,
|
|
44
44
|
},
|
|
45
|
+
skipAuth: true,
|
|
45
46
|
});
|
|
46
47
|
});
|
|
47
48
|
const fetchedProducts = await Promise.all(fetchPromises);
|
|
@@ -56,6 +57,7 @@ export function useProducts(options = {}) {
|
|
|
56
57
|
includeVariants,
|
|
57
58
|
includePrices,
|
|
58
59
|
},
|
|
60
|
+
skipAuth: true,
|
|
59
61
|
});
|
|
60
62
|
setProducts(Array.isArray(data) ? data : (data.items ?? []));
|
|
61
63
|
}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export { usePaymentPolling } from './hooks/usePaymentPolling';
|
|
|
31
31
|
export { useThreeds } from './hooks/useThreeds';
|
|
32
32
|
export { useThreedsModal } from './hooks/useThreedsModal';
|
|
33
33
|
export { useApplePay } from './hooks/useApplePay';
|
|
34
|
+
export { ExpressPaymentProvider, useExpressPayment } from './hooks/useExpressPayment';
|
|
34
35
|
export type { AuthState, Currency, Customer, Environment, EnvironmentConfig, Locale, Order, OrderAddress, OrderItem, OrderSummary, PickupPoint, Session, Store } from './types';
|
|
35
36
|
export type { CheckoutData, CheckoutInitParams, CheckoutLineItem, CheckoutSession, CheckoutSessionPreview, Promotion, UseCheckoutOptions, UseCheckoutResult } from './hooks/useCheckout';
|
|
36
37
|
export type { Discount, DiscountCodeValidation, UseDiscountsOptions, UseDiscountsResult } from './hooks/useDiscounts';
|
|
@@ -41,5 +42,5 @@ export type { Payment, PaymentPollingHook, PollingOptions } from './hooks/usePay
|
|
|
41
42
|
export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession } from './hooks/useThreeds';
|
|
42
43
|
export type { ApplePayToken, CardPaymentMethod, PaymentHook, PaymentInstrumentResponse, PaymentOptions, PaymentResponse } from './hooks/usePayment';
|
|
43
44
|
export type { ApplePayAddress, ApplePayConfig, ApplePayLineItem, ApplePayPaymentAuthorizedEvent, ApplePayPaymentRequest, ApplePayPaymentToken, ApplePayValidateMerchantEvent, BasisTheorySessionRequest, BasisTheoryTokenizeRequest, PayToken, UseApplePayOptions, UseApplePayResult } from './types/apple-pay';
|
|
44
|
-
export {
|
|
45
|
+
export { ApplePayButton, Button } from './components';
|
|
45
46
|
export { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMoney, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits } from './utils/money';
|
package/dist/react/index.js
CHANGED
|
@@ -35,7 +35,9 @@ export { useThreeds } from './hooks/useThreeds';
|
|
|
35
35
|
export { useThreedsModal } from './hooks/useThreedsModal';
|
|
36
36
|
// Apple Pay hooks exports
|
|
37
37
|
export { useApplePay } from './hooks/useApplePay';
|
|
38
|
+
// Express Payment context exports
|
|
39
|
+
export { ExpressPaymentProvider, useExpressPayment } from './hooks/useExpressPayment';
|
|
38
40
|
// Component exports
|
|
39
|
-
export {
|
|
41
|
+
export { ApplePayButton, Button } from './components';
|
|
40
42
|
// Utility exports
|
|
41
43
|
export { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMoney, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits } from './utils/money';
|