@tagadapay/plugin-sdk 2.3.9 → 2.3.11

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.
@@ -1,15 +1,49 @@
1
- import { useCallback, useState } from 'react';
1
+ import { useCallback, useEffect, useState } from 'react';
2
2
  import { getBasisTheoryApiKey } from '../config/payment';
3
3
  import { useTagadaContext } from '../providers/TagadaProvider';
4
4
  import { usePayment } from './usePayment';
5
5
  export function useApplePay(options = {}) {
6
6
  const [processingPayment, setProcessingPayment] = useState(false);
7
7
  const [error, setError] = useState(null);
8
- const [qrCodeData, setQrCodeData] = useState(null);
8
+ const [isApplePayAvailable, setIsApplePayAvailable] = useState(false);
9
9
  const { createApplePayPaymentInstrument, processApplePayPayment } = usePayment();
10
10
  const { environment, apiService } = useTagadaContext();
11
11
  // Get API key from environment
12
12
  const apiKey = getBasisTheoryApiKey(environment?.environment || 'local');
13
+ // Check Apple Pay availability on mount
14
+ useEffect(() => {
15
+ const checkApplePayAvailability = () => {
16
+ if (typeof window === 'undefined') {
17
+ setIsApplePayAvailable(false);
18
+ return;
19
+ }
20
+ // Check if ApplePaySession is available
21
+ const hasApplePaySession = !!window.ApplePaySession;
22
+ if (!hasApplePaySession) {
23
+ // In development, simulate Apple Pay availability for UI testing
24
+ const isDevelopment = process.env.NODE_ENV === 'development' ||
25
+ window.location.hostname === 'localhost' ||
26
+ window.location.hostname.includes('127.0.0.1');
27
+ if (isDevelopment) {
28
+ setIsApplePayAvailable(true);
29
+ return;
30
+ }
31
+ setIsApplePayAvailable(false);
32
+ return;
33
+ }
34
+ try {
35
+ // Check basic Apple Pay support
36
+ const canMakePayments = window.ApplePaySession.canMakePayments();
37
+ setIsApplePayAvailable(canMakePayments);
38
+ }
39
+ catch (error) {
40
+ console.warn('Apple Pay availability check failed:', error);
41
+ setIsApplePayAvailable(false);
42
+ }
43
+ };
44
+ checkApplePayAvailability();
45
+ // Debug logging
46
+ }, []);
13
47
  // Utility function to convert Apple Pay contact to address
14
48
  const appleContactToAddress = useCallback((contact) => {
15
49
  return {
@@ -25,68 +59,85 @@ export function useApplePay(options = {}) {
25
59
  email: contact?.emailAddress || '',
26
60
  };
27
61
  }, []);
28
- // Generate QR code URL for Apple Pay fallback
29
- const generateQRCode = useCallback((data) => {
30
- const qrData = {
31
- type: 'apple_pay_fallback',
32
- checkoutSessionId: data.checkoutSessionId,
33
- total: data.total,
34
- lineItems: data.lineItems,
35
- config: data.config,
36
- timestamp: Date.now(),
37
- };
38
- // Encode data as base64 for QR code
39
- const encodedData = btoa(JSON.stringify(qrData));
40
- return `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(encodedData)}`;
41
- }, []);
42
- // Check if Apple Pay is available with enhanced cross-browser support
43
- const isApplePayAvailable = (() => {
44
- if (typeof window === 'undefined')
45
- return false;
46
- // Check if ApplePaySession is available
47
- const hasApplePaySession = !!window.ApplePaySession;
48
- if (!hasApplePaySession) {
49
- // In development, simulate Apple Pay availability for UI testing
50
- const isDevelopment = process.env.NODE_ENV === 'development' ||
51
- window.location.hostname === 'localhost' ||
52
- window.location.hostname.includes('127.0.0.1');
53
- if (isDevelopment) {
54
- console.log('Development mode: Simulating Apple Pay availability for UI testing');
55
- return true;
56
- }
57
- return false;
62
+ // Update checkout session with addresses and customer info
63
+ const updateCheckoutSessionValues = useCallback(async (data) => {
64
+ try {
65
+ await apiService.fetch(`/api/v1/checkout-sessions/${options.checkoutSessionId}/address`, {
66
+ method: 'POST',
67
+ body: {
68
+ data: {
69
+ shippingAddress: data.shippingAddress,
70
+ billingAddress: data.billingAddress,
71
+ },
72
+ },
73
+ });
58
74
  }
75
+ catch (error) {
76
+ console.error('Failed to update checkout session addresses:', error);
77
+ throw error;
78
+ }
79
+ }, [apiService, options.checkoutSessionId]);
80
+ // Update customer email
81
+ const updateCustomerEmail = useCallback(async (email) => {
82
+ try {
83
+ await apiService.fetch(`/api/v1/customers/${options.customerId}`, {
84
+ method: 'POST',
85
+ body: {
86
+ data: {
87
+ email,
88
+ },
89
+ },
90
+ });
91
+ }
92
+ catch (error) {
93
+ console.error('Failed to update customer email:', error);
94
+ throw error;
95
+ }
96
+ }, [apiService, options.customerId]);
97
+ // Recompute order summary after address/shipping changes
98
+ const reComputeOrderSummary = useCallback(async () => {
59
99
  try {
60
- // Check basic Apple Pay support
61
- return window.ApplePaySession.canMakePayments();
100
+ const response = await apiService.fetch(`/api/v1/checkout-sessions/${options.checkoutSessionId}/order-summary`, {
101
+ method: 'POST',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ },
105
+ body: { checkoutSessionId: options.checkoutSessionId }
106
+ });
107
+ return response;
62
108
  }
63
109
  catch (error) {
64
- console.warn('Apple Pay availability check failed:', error);
65
- return false;
110
+ console.error('Failed to recompute order summary:', error);
111
+ throw error;
66
112
  }
67
- })();
68
- // Check if we should show QR code fallback
69
- const shouldShowQRCode = (() => {
70
- if (typeof window === 'undefined')
71
- return false;
72
- // Show QR code if Apple Pay is not available but we're in a supported environment
73
- const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
74
- const isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
75
- const isChrome = /Chrome/.test(navigator.userAgent);
76
- // Show QR code for mobile devices or when Apple Pay is not natively supported
77
- return !isApplePayAvailable && (isMobile || isSafari || isChrome);
78
- })();
79
- // Debug logging
80
- console.log('Apple Pay availability check:', {
81
- hasWindow: typeof window !== 'undefined',
82
- hasApplePaySession: typeof window !== 'undefined' && !!window.ApplePaySession,
83
- canMakePayments: typeof window !== 'undefined' && window.ApplePaySession && window.ApplePaySession.canMakePayments(),
84
- isDevelopment: process.env.NODE_ENV === 'development' ||
85
- (typeof window !== 'undefined' && (window.location.hostname === 'localhost' || window.location.hostname.includes('127.0.0.1'))),
86
- isAvailable: isApplePayAvailable,
87
- note: !window.ApplePaySession ? 'Apple Pay not available in this browser. Use Safari on iOS/macOS for real Apple Pay support.' : 'Apple Pay API detected'
88
- });
89
- const validateMerchant = useCallback(async () => {
113
+ }, [apiService, options.checkoutSessionId]);
114
+ // Get shipping rates for the checkout session
115
+ const getShippingRates = useCallback(async () => {
116
+ try {
117
+ const response = await apiService.fetch(`/api/v1/checkout-sessions/${options.checkoutSessionId}/shipping-rates`);
118
+ return response;
119
+ }
120
+ catch (error) {
121
+ console.error('Failed to get shipping rates:', error);
122
+ throw error;
123
+ }
124
+ }, [apiService, options.checkoutSessionId]);
125
+ // Set shipping rate
126
+ const setShippingRate = useCallback(async (shippingRateId) => {
127
+ try {
128
+ await apiService.fetch(`/api/v1/checkout-sessions/${options.checkoutSessionId}/shipping-rate`, {
129
+ method: 'POST',
130
+ body: {
131
+ shippingRateId,
132
+ },
133
+ });
134
+ }
135
+ catch (error) {
136
+ console.error('Failed to set shipping rate:', error);
137
+ throw error;
138
+ }
139
+ }, [apiService, options.checkoutSessionId]);
140
+ const validateMerchant = useCallback(async (storeName) => {
90
141
  try {
91
142
  const response = await fetch('https://api.basistheory.com/apple-pay/session', {
92
143
  method: 'POST',
@@ -95,7 +146,7 @@ export function useApplePay(options = {}) {
95
146
  'BT-API-KEY': apiKey,
96
147
  },
97
148
  body: JSON.stringify({
98
- display_name: 'Tagada Pay Store',
149
+ display_name: storeName || 'Tagada Pay Store',
99
150
  domain: typeof window !== 'undefined' ? window.location.host : 'localhost',
100
151
  }),
101
152
  });
@@ -133,21 +184,8 @@ export function useApplePay(options = {}) {
133
184
  throw error;
134
185
  }
135
186
  }, [apiKey]);
136
- const handleApplePayClick = useCallback((checkoutSessionId, lineItems, total, config = {}) => {
187
+ const handleApplePayClick = useCallback((checkoutSessionId, lineItems, total, config = {}, storeName, currencyCode, shippingMethods) => {
137
188
  if (!isApplePayAvailable) {
138
- if (shouldShowQRCode) {
139
- // Generate QR code data for fallback
140
- const qrData = {
141
- checkoutSessionId,
142
- lineItems,
143
- total,
144
- config,
145
- qrCodeUrl: generateQRCode({ checkoutSessionId, lineItems, total, config }),
146
- };
147
- setQrCodeData(qrData);
148
- options.onError?.('Apple Pay not available - QR code generated');
149
- return;
150
- }
151
189
  const errorMsg = 'Apple Pay is not available on this device';
152
190
  setError(errorMsg);
153
191
  options.onError?.(errorMsg);
@@ -155,11 +193,12 @@ export function useApplePay(options = {}) {
155
193
  }
156
194
  const request = {
157
195
  countryCode: config.countryCode || 'US',
158
- currencyCode: 'USD', // This should be passed as a parameter
196
+ currencyCode: currencyCode || 'USD',
159
197
  supportedNetworks: config.supportedNetworks || ['visa', 'masterCard', 'amex', 'discover'],
160
198
  merchantCapabilities: config.merchantCapabilities || ['supports3DS'],
161
199
  total,
162
200
  lineItems,
201
+ shippingMethods: shippingMethods || [],
163
202
  requiredShippingContactFields: ['name', 'phone', 'email', 'postalAddress'],
164
203
  requiredBillingContactFields: ['postalAddress'],
165
204
  };
@@ -168,8 +207,7 @@ export function useApplePay(options = {}) {
168
207
  session.onvalidatemerchant = (event) => {
169
208
  void (async () => {
170
209
  try {
171
- console.log('Merchant validation requested for:', event.validationURL);
172
- const merchantSession = await validateMerchant();
210
+ const merchantSession = await validateMerchant(storeName);
173
211
  session.completeMerchantValidation(merchantSession);
174
212
  }
175
213
  catch (error) {
@@ -191,10 +229,17 @@ export function useApplePay(options = {}) {
191
229
  const billingContact = event.payment.billingContact;
192
230
  const shippingAddress = shippingContact ? appleContactToAddress(shippingContact) : null;
193
231
  const billingAddress = billingContact ? appleContactToAddress(billingContact) : null;
194
- console.log('Apple Pay payment authorized with addresses:', {
195
- shipping: shippingAddress,
196
- billing: billingAddress,
197
- });
232
+ // Update checkout session with addresses
233
+ if (shippingAddress || billingAddress) {
234
+ await updateCheckoutSessionValues({
235
+ shippingAddress: shippingAddress || undefined,
236
+ billingAddress: billingAddress || undefined,
237
+ });
238
+ }
239
+ // Update customer email if available
240
+ if (shippingContact?.emailAddress) {
241
+ await updateCustomerEmail(shippingContact.emailAddress);
242
+ }
198
243
  // Tokenize the Apple Pay payment
199
244
  const applePayToken = await tokenizeApplePay(event);
200
245
  // Complete the Apple Pay session
@@ -222,6 +267,48 @@ export function useApplePay(options = {}) {
222
267
  }
223
268
  })();
224
269
  };
270
+ // Handle shipping method selection
271
+ session.onshippingmethodselected = (event) => {
272
+ void (async () => {
273
+ try {
274
+ await setShippingRate(event.shippingMethod.identifier);
275
+ const newOrderSummary = await reComputeOrderSummary();
276
+ if (!newOrderSummary) {
277
+ session.abort();
278
+ return;
279
+ }
280
+ const { lineItems: newLineItems, total: newTotal } = newOrderSummary;
281
+ session.completeShippingMethodSelection(window.ApplePaySession.STATUS_SUCCESS, newTotal, newLineItems);
282
+ }
283
+ catch (error) {
284
+ console.error('Shipping method selection failed:', error);
285
+ session.abort();
286
+ }
287
+ })();
288
+ };
289
+ // Handle shipping contact selection
290
+ session.onshippingcontactselected = (event) => {
291
+ void (async () => {
292
+ try {
293
+ const shippingContact = event.shippingContact;
294
+ await updateCheckoutSessionValues({
295
+ shippingAddress: appleContactToAddress(shippingContact),
296
+ });
297
+ const newOrderSummary = await reComputeOrderSummary();
298
+ if (!newOrderSummary) {
299
+ session.abort();
300
+ setError('Payment Failed');
301
+ return;
302
+ }
303
+ const { lineItems: newLineItems, total: newTotal, shippingMethods: newShippingMethods, } = newOrderSummary;
304
+ session.completeShippingContactSelection(window.ApplePaySession.STATUS_SUCCESS, newShippingMethods, newTotal, newLineItems);
305
+ }
306
+ catch (error) {
307
+ console.error('Shipping contact selection failed:', error);
308
+ session.abort();
309
+ }
310
+ })();
311
+ };
225
312
  session.onerror = (event) => {
226
313
  console.error('Apple Pay Session Error:', event);
227
314
  const errorMsg = 'Apple Pay session error';
@@ -233,6 +320,7 @@ export function useApplePay(options = {}) {
233
320
  setProcessingPayment(false);
234
321
  options.onCancel?.();
235
322
  };
323
+ // Begin the Apple Pay session - this opens the modal
236
324
  session.begin();
237
325
  }
238
326
  catch (error) {
@@ -246,6 +334,10 @@ export function useApplePay(options = {}) {
246
334
  validateMerchant,
247
335
  tokenizeApplePay,
248
336
  processApplePayPayment,
337
+ updateCheckoutSessionValues,
338
+ updateCustomerEmail,
339
+ setShippingRate,
340
+ reComputeOrderSummary,
249
341
  options,
250
342
  ]);
251
343
  return {
@@ -253,8 +345,8 @@ export function useApplePay(options = {}) {
253
345
  processingPayment,
254
346
  applePayError: error,
255
347
  isApplePayAvailable,
256
- shouldShowQRCode,
257
- qrCodeData,
258
- generateQRCode,
348
+ updateCheckoutSessionValues,
349
+ updateCustomerEmail,
350
+ setShippingRate,
259
351
  };
260
352
  }
@@ -19,6 +19,7 @@ const loadLocalDevConfig = async (configVariant = 'default') => {
19
19
  // Use hostname-based detection for better Vite compatibility
20
20
  const isLocalDev = typeof window !== 'undefined' &&
21
21
  (window.location.hostname === 'localhost' ||
22
+ window.location.hostname.includes('ngrok-free.app') ||
22
23
  window.location.hostname.includes('.localhost') ||
23
24
  window.location.hostname.includes('127.0.0.1'));
24
25
  if (!isLocalDev) {
@@ -184,6 +185,7 @@ export const debugPluginConfig = async (configVariant = 'default') => {
184
185
  // Use hostname-based detection for better Vite compatibility
185
186
  const isLocalDev = typeof window !== 'undefined' &&
186
187
  (window.location.hostname === 'localhost' ||
188
+ window.location.hostname.includes('ngrok-free.app') ||
187
189
  window.location.hostname.includes('.localhost') ||
188
190
  window.location.hostname.includes('127.0.0.1'));
189
191
  if (!isLocalDev) {
@@ -40,6 +40,5 @@ export type { PostPurchaseOffer, PostPurchaseOfferItem, PostPurchaseOfferLineIte
40
40
  export type { Payment, PaymentPollingHook, PollingOptions } from './hooks/usePaymentPolling';
41
41
  export type { PaymentInstrument, ThreedsChallenge, ThreedsHook, ThreedsOptions, ThreedsProvider, ThreedsSession } from './hooks/useThreeds';
42
42
  export type { ApplePayToken, CardPaymentMethod, PaymentHook, PaymentInstrumentResponse, PaymentOptions, PaymentResponse } from './hooks/usePayment';
43
- export type { ApplePayConfig, ApplePayLineItem, ApplePayPaymentAuthorizedEvent, ApplePayPaymentRequest, ApplePayPaymentToken, ApplePayValidateMerchantEvent, BasisTheorySessionRequest, BasisTheoryTokenizeRequest, PayToken, UseApplePayOptions, UseApplePayResult, ApplePayAddress, ApplePayQRCodeData } from './types/apple-pay';
44
- export { ApplePayUniversalButton } from './components/ApplePayUniversalButton';
43
+ export type { ApplePayAddress, ApplePayConfig, ApplePayLineItem, ApplePayPaymentAuthorizedEvent, ApplePayPaymentRequest, ApplePayPaymentToken, ApplePayValidateMerchantEvent, BasisTheorySessionRequest, BasisTheoryTokenizeRequest, PayToken, UseApplePayOptions, UseApplePayResult } from './types/apple-pay';
45
44
  export { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMoney, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits } from './utils/money';
@@ -36,6 +36,6 @@ export { useThreedsModal } from './hooks/useThreedsModal';
36
36
  // Apple Pay hooks exports
37
37
  export { useApplePay } from './hooks/useApplePay';
38
38
  // Component exports
39
- export { ApplePayUniversalButton } from './components/ApplePayUniversalButton';
39
+ // Apple Pay components removed - use useApplePay hook directly
40
40
  // Utility exports
41
41
  export { convertCurrency, formatMoney, formatMoneyWithoutSymbol, formatSimpleMoney, getCurrencyInfo, minorUnitsToMajorUnits, moneyStringOrNumberToMinorUnits } from './utils/money';
@@ -64,6 +64,8 @@ export interface UseApplePayOptions {
64
64
  onError?: (error: string) => void;
65
65
  onCancel?: () => void;
66
66
  config?: ApplePayConfig;
67
+ checkoutSessionId?: string;
68
+ customerId?: string;
67
69
  }
68
70
  export interface ApplePayAddress {
69
71
  address1: string;
@@ -77,21 +79,17 @@ export interface ApplePayAddress {
77
79
  phone?: string;
78
80
  email?: string;
79
81
  }
80
- export interface ApplePayQRCodeData {
81
- checkoutSessionId: string;
82
- lineItems: ApplePayLineItem[];
83
- total: ApplePayLineItem;
84
- config?: ApplePayConfig;
85
- qrCodeUrl?: string;
86
- }
87
82
  export interface UseApplePayResult {
88
- handleApplePayClick: (checkoutSessionId: string, lineItems: ApplePayLineItem[], total: ApplePayLineItem, config?: ApplePayConfig) => void;
83
+ handleApplePayClick: (checkoutSessionId: string, lineItems: ApplePayLineItem[], total: ApplePayLineItem, config?: ApplePayConfig, storeName?: string, currencyCode?: string, shippingMethods?: any[]) => void;
89
84
  processingPayment: boolean;
90
85
  applePayError: string | null;
91
86
  isApplePayAvailable: boolean;
92
- shouldShowQRCode: boolean;
93
- qrCodeData: ApplePayQRCodeData | null;
94
- generateQRCode: (data: ApplePayQRCodeData) => string;
87
+ updateCheckoutSessionValues: (data: {
88
+ shippingAddress?: ApplePayAddress;
89
+ billingAddress?: ApplePayAddress;
90
+ }) => Promise<void>;
91
+ updateCustomerEmail: (email: string) => Promise<void>;
92
+ setShippingRate: (shippingRateId: string) => Promise<void>;
95
93
  }
96
94
  declare global {
97
95
  interface Window {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tagadapay/plugin-sdk",
3
- "version": "2.3.9",
3
+ "version": "2.3.11",
4
4
  "description": "Modern React SDK for building Tagada Pay plugins",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,16 +0,0 @@
1
- import React from 'react';
2
- import { ApplePayLineItem, ApplePayConfig } from '../types/apple-pay';
3
- interface ApplePayUniversalButtonProps {
4
- checkoutSessionId: string;
5
- lineItems: ApplePayLineItem[];
6
- total: ApplePayLineItem;
7
- config?: ApplePayConfig;
8
- onSuccess?: (payment: any) => void;
9
- onError?: (error: string) => void;
10
- onCancel?: () => void;
11
- className?: string;
12
- children?: React.ReactNode;
13
- disabled?: boolean;
14
- }
15
- export declare const ApplePayUniversalButton: React.FC<ApplePayUniversalButtonProps>;
16
- export default ApplePayUniversalButton;
@@ -1,3 +0,0 @@
1
- import React from 'react';
2
- export declare const ApplePayUniversalButtonExample: React.FC;
3
- export default ApplePayUniversalButtonExample;
@@ -1,39 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ApplePayUniversalButton } from './ApplePayUniversalButton';
3
- // Example usage of ApplePayUniversalButton
4
- export const ApplePayUniversalButtonExample = () => {
5
- const checkoutSessionId = 'example-session-123';
6
- const lineItems = [
7
- {
8
- label: 'Product 1',
9
- amount: '29.99',
10
- type: 'final',
11
- },
12
- {
13
- label: 'Shipping',
14
- amount: '5.99',
15
- type: 'final',
16
- },
17
- ];
18
- const total = {
19
- label: 'Total',
20
- amount: '35.98',
21
- type: 'final',
22
- };
23
- const config = {
24
- countryCode: 'US',
25
- supportedNetworks: ['visa', 'masterCard', 'amex', 'discover'],
26
- merchantCapabilities: ['supports3DS'],
27
- };
28
- const handleSuccess = (payment) => {
29
- console.log('Payment successful:', payment);
30
- };
31
- const handleError = (error) => {
32
- console.error('Payment error:', error);
33
- };
34
- const handleCancel = () => {
35
- console.log('Payment cancelled');
36
- };
37
- return (_jsxs("div", { className: "max-w-md mx-auto p-6 bg-white rounded-lg shadow-lg", children: [_jsx("h2", { className: "text-2xl font-bold mb-4", children: "Apple Pay Universal Button Example" }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("h3", { className: "font-semibold mb-2", children: "Order Summary:" }), lineItems.map((item, index) => (_jsxs("div", { className: "flex justify-between text-sm", children: [_jsx("span", { children: item.label }), _jsxs("span", { children: ["$", item.amount] })] }, index))), _jsxs("div", { className: "flex justify-between font-bold border-t pt-2 mt-2", children: [_jsx("span", { children: total.label }), _jsxs("span", { children: ["$", total.amount] })] })] }), _jsx(ApplePayUniversalButton, { checkoutSessionId: checkoutSessionId, lineItems: lineItems, total: total, config: config, onSuccess: handleSuccess, onError: handleError, onCancel: handleCancel, className: "w-full" }), _jsxs("div", { className: "text-xs text-gray-500 mt-4", children: [_jsx("p", { children: "This button will:" }), _jsxs("ul", { className: "list-disc list-inside space-y-1", children: [_jsx("li", { children: "Show Apple Pay on supported devices (Safari iOS/macOS)" }), _jsx("li", { children: "Show QR code on other mobile browsers" }), _jsx("li", { children: "Show \"Unavailable\" on unsupported browsers" })] })] })] })] }));
38
- };
39
- export default ApplePayUniversalButtonExample;
@@ -1,62 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
3
- import { useApplePay } from '../hooks/useApplePay';
4
- export const ApplePayUniversalButton = ({ checkoutSessionId, lineItems, total, config = {}, onSuccess, onError, onCancel, className = '', children, disabled = false, }) => {
5
- const [showQRCode, setShowQRCode] = useState(false);
6
- const { handleApplePayClick, processingPayment, applePayError, isApplePayAvailable, shouldShowQRCode, qrCodeData, generateQRCode, } = useApplePay({
7
- onSuccess,
8
- onError,
9
- onCancel,
10
- config,
11
- });
12
- const handleClick = () => {
13
- if (isApplePayAvailable) {
14
- handleApplePayClick(checkoutSessionId, lineItems, total, config);
15
- }
16
- else if (shouldShowQRCode) {
17
- setShowQRCode(true);
18
- // Generate QR code data
19
- const qrData = {
20
- checkoutSessionId,
21
- lineItems,
22
- total,
23
- config,
24
- qrCodeUrl: generateQRCode({ checkoutSessionId, lineItems, total, config }),
25
- };
26
- handleApplePayClick(checkoutSessionId, lineItems, total, config);
27
- }
28
- else {
29
- onError?.('Apple Pay is not available on this device');
30
- }
31
- };
32
- const getButtonText = () => {
33
- if (processingPayment)
34
- return 'Processing...';
35
- if (isApplePayAvailable)
36
- return 'Pay with Apple Pay';
37
- if (shouldShowQRCode)
38
- return 'Show QR Code';
39
- return 'Apple Pay Unavailable';
40
- };
41
- const getButtonIcon = () => {
42
- if (isApplePayAvailable) {
43
- return (_jsx("svg", { className: "h-6 w-6", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z" }) }));
44
- }
45
- if (shouldShowQRCode) {
46
- return (_jsx("svg", { className: "h-6 w-6", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M3 3h7v7H3V3zm2 2v3h3V5H5zm8-2h7v7h-7V3zm2 2v3h3V5h-3zM3 13h7v7H3v-7zm2 2v3h3v-3H5zm8-2h7v7h-7v-7zm2 2v3h3v-3h-3z" }) }));
47
- }
48
- return (_jsx("svg", { className: "h-6 w-6", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" }) }));
49
- };
50
- const getButtonStyle = () => {
51
- const baseStyle = "h-10 w-full text-base shadow-sm transition-colors duration-200 flex items-center justify-center gap-2";
52
- if (isApplePayAvailable) {
53
- return `${baseStyle} bg-black text-white hover:bg-black/80 ${className}`;
54
- }
55
- if (shouldShowQRCode) {
56
- return `${baseStyle} bg-blue-600 text-white hover:bg-blue-700 ${className}`;
57
- }
58
- return `${baseStyle} bg-gray-400 text-gray-600 cursor-not-allowed ${className}`;
59
- };
60
- return (_jsxs("div", { className: "w-full", children: [_jsxs("button", { onClick: handleClick, disabled: disabled || processingPayment || (!isApplePayAvailable && !shouldShowQRCode), className: getButtonStyle(), style: { margin: 0 }, children: [getButtonIcon(), children || getButtonText()] }), showQRCode && qrCodeData && (_jsx("div", { className: "mt-4 p-4 bg-white border border-gray-200 rounded-lg shadow-sm", children: _jsxs("div", { className: "text-center", children: [_jsx("h3", { className: "text-lg font-medium text-gray-900 mb-2", children: "Scan QR Code to Pay" }), _jsx("p", { className: "text-sm text-gray-600 mb-4", children: "Use your mobile device to scan this QR code and complete your Apple Pay payment" }), _jsx("div", { className: "flex justify-center", children: _jsx("img", { src: qrCodeData.qrCodeUrl, alt: "Apple Pay QR Code", className: "w-48 h-48 border border-gray-200 rounded" }) }), _jsxs("div", { className: "mt-4 text-xs text-gray-500", children: [_jsxs("p", { children: ["Total: ", total.amount, " ", total.label] }), _jsxs("p", { children: ["Session: ", checkoutSessionId.slice(0, 8), "..."] })] }), _jsx("button", { onClick: () => setShowQRCode(false), className: "mt-3 px-4 py-2 text-sm text-gray-600 hover:text-gray-800 underline", children: "Close QR Code" })] }) })), applePayError && (_jsx("div", { className: "mt-2 p-2 bg-red-50 border border-red-200 rounded text-sm text-red-600", children: applePayError }))] }));
61
- };
62
- export default ApplePayUniversalButton;