@akinon/pz-apple-pay 2.0.0-beta.13 → 2.0.0-beta.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @akinon/pz-apple-pay
2
2
 
3
+ ## 2.0.0-beta.15
4
+
5
+ ## 2.0.0-beta.14
6
+
7
+ ### Minor Changes
8
+
9
+ - 6ad72e8d: ZERO-4032: Add loading state management for payment submissions across multiple components and add safe guarding
10
+
3
11
  ## 2.0.0-beta.13
4
12
 
5
13
  ## 1.118.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/pz-apple-pay",
3
- "version": "2.0.0-beta.13",
3
+ "version": "2.0.0-beta.15",
4
4
  "license": "MIT",
5
5
  "main": "src/index.tsx",
6
6
  "peerDependencies": {
@@ -3,6 +3,7 @@ import { useAppSelector, useAppDispatch } from '@akinon/next/redux/hooks';
3
3
  import { getCookie } from '@akinon/next/utils';
4
4
  import { getUrlPathWithLocale } from '@akinon/next/utils/localization';
5
5
  import { RootState } from '@theme/redux/store';
6
+ import { useLocalization } from '@akinon/next/hooks';
6
7
  import { useState, useMemo } from 'react';
7
8
 
8
9
  export default function useApplePay() {
@@ -10,7 +11,9 @@ export default function useApplePay() {
10
11
  (state: RootState) => state.checkout
11
12
  );
12
13
  const dispatch = useAppDispatch();
14
+ const { t } = useLocalization();
13
15
  const [errors, setErrors] = useState(null);
16
+ const [isProcessing, setIsProcessing] = useState(false);
14
17
 
15
18
  const paymentErrors = useMemo(() => {
16
19
  if (typeof errors === 'string') {
@@ -79,60 +82,70 @@ export default function useApplePay() {
79
82
  }, [walletPaymentData]);
80
83
 
81
84
  const initPaymentRequest = async () => {
82
- setErrors(null);
83
-
84
- const request = paymentRequest;
85
- const paymentRequestResponse = await request.show();
85
+ if (isProcessing) return;
86
86
 
87
- if (paymentRequestResponse.details?.token?.paymentData) {
88
- const paymentData = paymentRequestResponse.details.token.paymentData;
87
+ setIsProcessing(true);
88
+ setErrors(null);
89
89
 
90
- const walletPaymentPageResponse = await dispatch(
91
- checkoutApi.endpoints.setWalletPaymentPage.initiate({
92
- payment_token: JSON.stringify(paymentData)
93
- })
94
- ).unwrap();
90
+ try {
91
+ const request = paymentRequest;
92
+ const paymentRequestResponse = await request.show();
95
93
 
96
- if (walletPaymentPageResponse.errors) {
97
- setErrors(walletPaymentPageResponse.errors);
98
- }
94
+ if (paymentRequestResponse.details?.token?.paymentData) {
95
+ const paymentData = paymentRequestResponse.details.token.paymentData;
99
96
 
100
- if (
101
- walletPaymentPageResponse.context_list.find(
102
- (c) => c.page_name === 'WalletCompletePage'
103
- )
104
- ) {
105
- const paymentCompleteResponse = await dispatch(
106
- checkoutApi.endpoints.setWalletCompletePage.initiate({
107
- success: true
97
+ const walletPaymentPageResponse = await dispatch(
98
+ checkoutApi.endpoints.setWalletPaymentPage.initiate({
99
+ payment_token: JSON.stringify(paymentData)
108
100
  })
109
101
  ).unwrap();
110
102
 
111
- if (paymentCompleteResponse.errors) {
112
- setErrors(paymentCompleteResponse.errors);
103
+ if (walletPaymentPageResponse.errors) {
104
+ setErrors(walletPaymentPageResponse.errors);
113
105
  }
114
106
 
115
107
  if (
116
- paymentCompleteResponse.context_list.find(
117
- (c) => c.page_name === 'ThankYouPage'
108
+ walletPaymentPageResponse.context_list.find(
109
+ (c) => c.page_name === 'WalletCompletePage'
118
110
  )
119
111
  ) {
120
- const redirectUrl = paymentCompleteResponse.context_list.find(
121
- (c) => c.page_name === 'ThankYouPage'
122
- )?.page_context.context_data.redirect_url;
123
-
124
- const redirectUrlWithLocale = `${
125
- window.location.origin
126
- }${getUrlPathWithLocale(redirectUrl, getCookie('pz-locale'))}`;
127
-
128
- await paymentRequestResponse.complete('success');
129
- window.location.href = redirectUrlWithLocale;
112
+ const paymentCompleteResponse = await dispatch(
113
+ checkoutApi.endpoints.setWalletCompletePage.initiate({
114
+ success: true
115
+ })
116
+ ).unwrap();
117
+
118
+ if (paymentCompleteResponse.errors) {
119
+ setErrors(paymentCompleteResponse.errors);
120
+ }
121
+
122
+ if (
123
+ paymentCompleteResponse.context_list.find(
124
+ (c) => c.page_name === 'ThankYouPage'
125
+ )
126
+ ) {
127
+ const redirectUrl = paymentCompleteResponse.context_list.find(
128
+ (c) => c.page_name === 'ThankYouPage'
129
+ )?.page_context.context_data.redirect_url;
130
+
131
+ const redirectUrlWithLocale = `${
132
+ window.location.origin
133
+ }${getUrlPathWithLocale(redirectUrl, getCookie('pz-locale'))}`;
134
+
135
+ await paymentRequestResponse.complete('success');
136
+ window.location.href = redirectUrlWithLocale;
137
+ } else {
138
+ await paymentRequestResponse.complete('fail');
139
+ }
130
140
  } else {
131
141
  await paymentRequestResponse.complete('fail');
132
142
  }
133
- } else {
134
- await paymentRequestResponse.complete('fail');
135
143
  }
144
+ } catch (error) {
145
+ console.error('Apple Pay error:', error);
146
+ setErrors(error?.message || t('checkout.apple_pay.payment_failed'));
147
+ } finally {
148
+ setIsProcessing(false);
136
149
  }
137
150
  };
138
151
 
@@ -141,6 +154,7 @@ export default function useApplePay() {
141
154
  paymentErrors,
142
155
  setPaymentErrors: setErrors,
143
156
  onMerchantValidation,
144
- initPaymentRequest
157
+ initPaymentRequest,
158
+ isProcessing
145
159
  };
146
160
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { JSX } from 'react';
4
4
  import { useAppSelector } from '@akinon/next/redux/hooks';
5
+ import { useLocalization } from '@akinon/next/hooks';
5
6
  import { RootState } from '@theme/redux/store';
6
7
  import useApplePay from '../hooks/use-apple-pay';
7
8
 
@@ -16,7 +17,8 @@ export default function ApplePay({ customUIRender }: ApplePayProps) {
16
17
  const { walletPaymentData } = useAppSelector(
17
18
  (state: RootState) => state.checkout
18
19
  );
19
- const { paymentErrors, initPaymentRequest } = useApplePay();
20
+ const { t } = useLocalization();
21
+ const { paymentErrors, initPaymentRequest, isProcessing } = useApplePay();
20
22
 
21
23
  if (!walletPaymentData) {
22
24
  return null;
@@ -31,7 +33,9 @@ export default function ApplePay({ customUIRender }: ApplePayProps) {
31
33
 
32
34
  return (
33
35
  <div>
34
- <button onClick={initPaymentRequest}>Pay with Apple Pay</button>
36
+ <button onClick={initPaymentRequest} disabled={isProcessing}>
37
+ {isProcessing ? t('checkout.apple_pay.processing') : t('checkout.apple_pay.pay_button')}
38
+ </button>
35
39
 
36
40
  {paymentErrors?.length > 0 && (
37
41
  <div className="text-error-100 text-xs mt-5">{paymentErrors}</div>