strapi-plugin-payone-provider 1.5.0 → 1.5.3

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.
@@ -25,7 +25,8 @@ const PreauthorizationForm = ({
25
25
  cardexpiredate,
26
26
  setCardexpiredate,
27
27
  cardcvc2,
28
- setCardcvc2
28
+ setCardcvc2,
29
+ isLiveMode = false
29
30
  }) => {
30
31
  const handleGooglePayToken = (token, paymentData) => {
31
32
  if (!token) {
@@ -41,12 +42,35 @@ const PreauthorizationForm = ({
41
42
  }
42
43
  };
43
44
 
44
- const handleApplePayToken = (token, paymentData) => {
45
+ const handleApplePayToken = async (token, paymentData) => {
45
46
  if (!token) {
46
- return;
47
+ console.error("[Apple Pay] Token is missing in handleApplePayToken");
48
+ return Promise.reject(new Error("Token is missing"));
47
49
  }
50
+
51
+ console.log("[Apple Pay] handleApplePayToken called with token:", {
52
+ hasToken: !!token,
53
+ tokenLength: token?.length,
54
+ paymentData: !!paymentData
55
+ });
56
+
57
+ // IMPORTANT: Set token in state immediately (synchronously)
58
+ // This ensures the token is saved before the dialog closes
48
59
  setApplePayToken(token);
49
- onPreauthorization(token);
60
+
61
+ console.log("[Apple Pay] Token saved to state successfully");
62
+
63
+ // Don't call onPreauthorization immediately
64
+ // Let the user manually trigger the payment using the button
65
+ // This prevents the dialog from closing prematurely if there's an error
66
+ // The dialog will close with success, and the user will see the "Process Preauthorization" button
67
+
68
+ // Return success immediately so the dialog closes properly
69
+ // The actual payment processing will happen when the user clicks the button
70
+ return Promise.resolve({
71
+ success: true,
72
+ message: "Token received successfully. Please click 'Process Preauthorization' to complete the payment."
73
+ });
50
74
  };
51
75
 
52
76
  const handleApplePayError = (error) => {
@@ -122,21 +146,31 @@ const PreauthorizationForm = ({
122
146
  onError={handleApplePayError}
123
147
  settings={settings}
124
148
  />
125
- <Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
126
- <Typography variant="pi" textColor="neutral600" style={{ marginBottom: "8px" }}>
127
- Apple Pay is not available on localhost. You can test the payment flow without Apple Pay token:
128
- </Typography>
129
- <Button
130
- variant="secondary"
131
- onClick={() => onPreauthorization(null)}
132
- loading={isProcessingPayment}
133
- startIcon={<Play />}
134
- style={{ maxWidth: '200px' }}
135
- disabled={!paymentAmount.trim() || !preauthReference.trim()}
136
- >
137
- Process Preauthorization
138
- </Button>
139
- </Box>
149
+ {applePayToken && (
150
+ <Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
151
+ <Typography variant="pi" textColor="success600" style={{ marginBottom: "8px", fontWeight: "bold" }}>
152
+ ✓ Apple Pay token received. You can now process the preauthorization:
153
+ </Typography>
154
+ <Button
155
+ variant="default"
156
+ onClick={() => onPreauthorization(applePayToken)}
157
+ loading={isProcessingPayment}
158
+ startIcon={<Play />}
159
+ style={{ maxWidth: '200px' }}
160
+ disabled={!paymentAmount.trim() || !preauthReference.trim() || isLiveMode}
161
+ className="payment-button payment-button-primary"
162
+ >
163
+ Process Preauthorization
164
+ </Button>
165
+ </Box>
166
+ )}
167
+ {!applePayToken && (
168
+ <Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
169
+ <Typography variant="pi" textColor="neutral600" style={{ marginBottom: "8px" }}>
170
+ Apple Pay is not available on localhost. You can test the payment flow without Apple Pay token:
171
+ </Typography>
172
+ </Box>
173
+ )}
140
174
  </Box>
141
175
  ) : (
142
176
  <Button
@@ -150,7 +184,8 @@ const PreauthorizationForm = ({
150
184
  !paymentAmount.trim() ||
151
185
  (paymentMethod === "cc" &&
152
186
  settings?.enable3DSecure !== false &&
153
- (!cardtype || !cardpan || !cardexpiredate || !cardcvc2))
187
+ (!cardtype || !cardpan || !cardexpiredate || !cardcvc2)) ||
188
+ isLiveMode
154
189
  }
155
190
  >
156
191
  Process Preauthorization
@@ -1,13 +1,19 @@
1
- import React, { useState } from "react";
1
+ import React, { useState, useEffect } from "react";
2
+ import { useLocation, useHistory } from "react-router-dom";
2
3
  import { Layout, ContentLayout, Box } from "@strapi/design-system";
3
4
  import useSettings from "../hooks/useSettings";
4
5
  import useTransactionHistory from "../hooks/useTransactionHistory";
5
6
  import usePaymentActions from "../hooks/usePaymentActions";
6
7
  import AppHeader from "./components/AppHeader";
7
8
  import AppTabs from "./components/AppTabs";
9
+ import ApplePayConfigPanel from "./components/ApplePayConfigPanel";
10
+ import GooglePayConfigPanel from "./components/GooglePayConfigPanel";
8
11
  import "./styles.css";
12
+ import pluginId from "../../pluginId";
9
13
 
10
14
  const App = () => {
15
+ const location = useLocation();
16
+ const history = useHistory();
11
17
  const [activeTab, setActiveTab] = useState(0);
12
18
 
13
19
  // Custom hooks
@@ -15,6 +21,68 @@ const App = () => {
15
21
  const transactionHistory = useTransactionHistory();
16
22
  const paymentActions = usePaymentActions();
17
23
 
24
+ useEffect(() => {
25
+ if (location.pathname.includes('/apple-pay-config') || location.pathname.includes('/google-pay-config')) {
26
+ } else {
27
+ const tabFromPath = location.pathname.includes('/history') ? 1 :
28
+ location.pathname.includes('/payment-actions') ? 2 :
29
+ location.pathname.includes('/documentation') ? 3 : 0;
30
+ setActiveTab(tabFromPath);
31
+ }
32
+ }, [location.pathname]);
33
+
34
+ const isApplePayConfigPage = location.pathname.includes('/apple-pay-config');
35
+ const isGooglePayConfigPage = location.pathname.includes('/google-pay-config');
36
+
37
+ if (isApplePayConfigPage) {
38
+ return (
39
+ <Layout>
40
+ <AppHeader
41
+ title="Apple Pay Configuration"
42
+ activeTab={null}
43
+ isSaving={settings.isSaving}
44
+ onSave={settings.handleSave}
45
+ onBack={() => history.push(`/plugins/${pluginId}`)}
46
+ />
47
+ <ContentLayout>
48
+ <Box padding={6}>
49
+ <ApplePayConfigPanel
50
+ settings={settings.settings}
51
+ onInputChange={settings.handleInputChange}
52
+ isSaving={settings.isSaving}
53
+ onSave={settings.handleSave}
54
+ />
55
+ </Box>
56
+ </ContentLayout>
57
+ </Layout>
58
+ );
59
+ }
60
+
61
+ if (isGooglePayConfigPage) {
62
+ return (
63
+ <Layout>
64
+ <AppHeader
65
+ title="Google Pay Configuration"
66
+ activeTab={null}
67
+ isSaving={settings.isSaving}
68
+ onSave={settings.handleSave}
69
+ onBack={() => history.push(`/plugins/${pluginId}`)}
70
+ />
71
+ <ContentLayout>
72
+ <Box padding={6}>
73
+ <GooglePayConfigPanel
74
+ settings={settings.settings}
75
+ onInputChange={settings.handleInputChange}
76
+ isSaving={settings.isSaving}
77
+ onSave={settings.handleSave}
78
+ onBack={() => history.push(`/plugins/${pluginId}`)}
79
+ />
80
+ </Box>
81
+ </ContentLayout>
82
+ </Layout>
83
+ );
84
+ }
85
+
18
86
  return (
19
87
  <Layout>
20
88
  <AppHeader
@@ -48,6 +116,7 @@ const App = () => {
48
116
  selectedTransaction={transactionHistory.selectedTransaction}
49
117
  onTransactionSelect={transactionHistory.handleTransactionSelect}
50
118
  paymentActions={paymentActions}
119
+ history={history}
51
120
  />
52
121
  </Box>
53
122
  </ContentLayout>
@@ -83,6 +83,12 @@ const usePaymentActions = () => {
83
83
  };
84
84
 
85
85
  const handlePreauthorization = async (tokenParam = null) => {
86
+ console.log("[Payment] handlePreauthorization called", {
87
+ hasToken: !!tokenParam,
88
+ paymentMethod,
89
+ amount: paymentAmount
90
+ });
91
+
86
92
  setIsProcessingPayment(true);
87
93
  setPaymentError(null);
88
94
  setPaymentResult(null);
@@ -211,16 +217,31 @@ const usePaymentActions = () => {
211
217
 
212
218
  setPaymentResult(responseData);
213
219
 
220
+ console.log("[Payment] Preauthorization result:", {
221
+ status,
222
+ hasError: !!errorCode,
223
+ errorCode,
224
+ errorMessage
225
+ });
226
+
214
227
  if (status === "APPROVED") {
215
228
  handlePaymentSuccess("Preauthorization completed successfully");
229
+ // Return success result for Apple Pay callback
230
+ return { success: true, data: responseData };
216
231
  } else {
232
+ const errorMsg = errorMessage || `Unexpected status: ${status}`;
217
233
  handlePaymentError(
218
- { message: `Unexpected status: ${status}` },
234
+ { message: errorMsg },
219
235
  `Preauthorization completed with status: ${status}`
220
236
  );
237
+ // Return error result for Apple Pay callback
238
+ throw new Error(errorMsg);
221
239
  }
222
240
  } catch (error) {
241
+ console.error("[Payment] Preauthorization error:", error);
223
242
  handlePaymentError(error, "Preauthorization failed");
243
+ // Re-throw error so Apple Pay callback knows it failed
244
+ throw error;
224
245
  } finally {
225
246
  setIsProcessingPayment(false);
226
247
  }
@@ -356,16 +377,31 @@ const usePaymentActions = () => {
356
377
 
357
378
  setPaymentResult(responseData);
358
379
 
380
+ console.log("[Payment] Authorization result:", {
381
+ status,
382
+ hasError: !!errorCode,
383
+ errorCode,
384
+ errorMessage
385
+ });
386
+
359
387
  if (status === "APPROVED") {
360
388
  handlePaymentSuccess("Authorization completed successfully");
389
+ // Return success result for Apple Pay callback
390
+ return { success: true, data: responseData };
361
391
  } else {
392
+ const errorMsg = errorMessage || `Unexpected status: ${status}`;
362
393
  handlePaymentError(
363
- { message: `Unexpected status: ${status}` },
394
+ { message: errorMsg },
364
395
  `Authorization completed with status: ${status}`
365
396
  );
397
+ // Return error result for Apple Pay callback
398
+ throw new Error(errorMsg);
366
399
  }
367
400
  } catch (error) {
401
+ console.error("[Payment] Authorization error:", error);
368
402
  handlePaymentError(error, "Authorization failed");
403
+ // Re-throw error so Apple Pay callback knows it failed
404
+ throw error;
369
405
  } finally {
370
406
  setIsProcessingPayment(false);
371
407
  }
@@ -49,6 +49,8 @@ const useSettings = () => {
49
49
  type: "success",
50
50
  message: "Settings saved successfully"
51
51
  });
52
+ // Reload settings after save to ensure consistency
53
+ await loadSettings();
52
54
  } catch (error) {
53
55
  toggleNotification({
54
56
  type: "warning",
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Google Pay Constants
3
+ * Based on Google Pay documentation and Payone requirements
4
+ * https://developers.google.com/pay/api/web/overview
5
+ * https://docs.payone.com/display/public/PLATFORM/Google+Pay
6
+ */
7
+
8
+ // Google Pay supported card networks
9
+ export const GOOGLE_PAY_SUPPORTED_NETWORKS = [
10
+ { code: "MASTERCARD", name: "Mastercard" },
11
+ { code: "VISA", name: "Visa" },
12
+ { code: "AMEX", name: "American Express" },
13
+ { code: "DISCOVER", name: "Discover" },
14
+ { code: "JCB", name: "JCB" }
15
+ ];
16
+
17
+ // Google Pay supported authentication methods
18
+ export const GOOGLE_PAY_AUTH_METHODS = [
19
+ { code: "PAN_ONLY", name: "PAN Only", description: "Basic card authentication" },
20
+ { code: "CRYPTOGRAM_3DS", name: "3D Secure", description: "3D Secure authentication" }
21
+ ];
22
+
23
+ // Google Pay supported countries
24
+ export const GOOGLE_PAY_SUPPORTED_COUNTRIES = [
25
+ { code: "US", name: "United States" },
26
+ { code: "GB", name: "United Kingdom" },
27
+ { code: "CA", name: "Canada" },
28
+ { code: "AU", name: "Australia" },
29
+ { code: "DE", name: "Germany" },
30
+ { code: "FR", name: "France" },
31
+ { code: "IT", name: "Italy" },
32
+ { code: "ES", name: "Spain" },
33
+ { code: "NL", name: "Netherlands" },
34
+ { code: "BE", name: "Belgium" },
35
+ { code: "CH", name: "Switzerland" },
36
+ { code: "AT", name: "Austria" },
37
+ { code: "IE", name: "Ireland" },
38
+ { code: "SE", name: "Sweden" },
39
+ { code: "NO", name: "Norway" },
40
+ { code: "DK", name: "Denmark" },
41
+ { code: "FI", name: "Finland" },
42
+ { code: "PL", name: "Poland" },
43
+ { code: "BR", name: "Brazil" },
44
+ { code: "MX", name: "Mexico" },
45
+ { code: "JP", name: "Japan" },
46
+ { code: "SG", name: "Singapore" },
47
+ { code: "NZ", name: "New Zealand" },
48
+ { code: "IN", name: "India" }
49
+ ];
50
+
51
+ // Google Pay supported currencies
52
+ export const GOOGLE_PAY_SUPPORTED_CURRENCIES = [
53
+ { code: "USD", name: "US Dollar", symbol: "$" },
54
+ { code: "EUR", name: "Euro", symbol: "€" },
55
+ { code: "GBP", name: "British Pound", symbol: "£" },
56
+ { code: "CAD", name: "Canadian Dollar", symbol: "C$" },
57
+ { code: "AUD", name: "Australian Dollar", symbol: "A$" },
58
+ { code: "JPY", name: "Japanese Yen", symbol: "¥" },
59
+ { code: "CHF", name: "Swiss Franc", symbol: "CHF" },
60
+ { code: "SEK", name: "Swedish Krona", symbol: "kr" },
61
+ { code: "NOK", name: "Norwegian Krone", symbol: "kr" },
62
+ { code: "DKK", name: "Danish Krone", symbol: "kr" },
63
+ { code: "PLN", name: "Polish Zloty", symbol: "zł" },
64
+ { code: "BRL", name: "Brazilian Real", symbol: "R$" },
65
+ { code: "MXN", name: "Mexican Peso", symbol: "$" },
66
+ { code: "SGD", name: "Singapore Dollar", symbol: "S$" },
67
+ { code: "NZD", name: "New Zealand Dollar", symbol: "NZ$" },
68
+ { code: "INR", name: "Indian Rupee", symbol: "₹" }
69
+ ];
70
+
71
+ // Default Google Pay configuration
72
+ export const DEFAULT_GOOGLE_PAY_CONFIG = {
73
+ countryCode: "US",
74
+ currencyCode: "USD",
75
+ allowedCardNetworks: ["MASTERCARD", "VISA"],
76
+ allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
77
+ merchantName: "Your Store Name"
78
+ };
79
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-payone-provider",
3
- "version": "1.5.0",
3
+ "version": "1.5.3",
4
4
  "description": "Strapi plugin for Payone payment gateway integration",
5
5
  "license": "MIT",
6
6
  "maintainers": [