strapi-plugin-payone-provider 1.6.5 → 1.6.7

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,3 @@
1
+ # This file ensures the .well-known directory is tracked by git
2
+ # Place your apple-developer-merchantid-domain-association file here
3
+
@@ -0,0 +1 @@
1
+ 7b2276657273696f6e223a312c227073704964223a2235393638344337413333424534333631304339333343413031384639393231333841394642453136413636363835333532463437413441414646363734333038222c22637265617465644f6e223a313735363238323636363439317d
@@ -1,5 +1,11 @@
1
1
  import React from "react";
2
- import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from "@strapi/design-system";
2
+ import {
3
+ Tabs,
4
+ Tab,
5
+ TabGroup,
6
+ TabPanels,
7
+ TabPanel,
8
+ } from "@strapi/design-system";
3
9
  import pluginId from "../../../pluginId";
4
10
  import ConfigurationPanel from "./ConfigurationPanel";
5
11
  import HistoryPanel from "./HistoryPanel";
@@ -17,6 +23,7 @@ const AppTabs = ({
17
23
  onSave,
18
24
  onTestConnection,
19
25
  onInputChange,
26
+ onPaymentMethodToggle,
20
27
  // Transaction history props
21
28
  filters,
22
29
  onFilterChange,
@@ -33,17 +40,17 @@ const AppTabs = ({
33
40
  onTransactionSelect,
34
41
  // Payment actions props
35
42
  paymentActions,
36
- history
43
+ history,
37
44
  }) => {
38
- const handleNavigateToConfig = (configType = "apple-pay") => {
39
- if (history) {
40
- if (configType === "google-pay") {
41
- history.push(`/plugins/${pluginId}/google-pay-config`);
42
- } else {
43
- history.push(`/plugins/${pluginId}/apple-pay-config`);
44
- }
45
- }
46
- };
45
+ const handleNavigateToConfig = (configType = "apple-pay") => {
46
+ if (history) {
47
+ if (configType === "google-pay") {
48
+ history.push(`/plugins/${pluginId}/google-pay-config`);
49
+ } else {
50
+ history.push(`/plugins/${pluginId}/apple-pay-config`);
51
+ }
52
+ }
53
+ };
47
54
  return (
48
55
  <TabGroup
49
56
  label="Payone Provider Tabs"
@@ -51,22 +58,30 @@ const AppTabs = ({
51
58
  >
52
59
  <Tabs style={{ borderBottom: "2px solid #e8e8ea" }}>
53
60
  <Tab
54
- className={`payment-tab ${activeTab === 0 ? 'payment-tab-active' : ''}`}
61
+ className={`payment-tab ${
62
+ activeTab === 0 ? "payment-tab-active" : ""
63
+ }`}
55
64
  >
56
65
  Configuration
57
66
  </Tab>
58
67
  <Tab
59
- className={`payment-tab ${activeTab === 1 ? 'payment-tab-active' : ''}`}
68
+ className={`payment-tab ${
69
+ activeTab === 1 ? "payment-tab-active" : ""
70
+ }`}
60
71
  >
61
72
  Transaction History
62
73
  </Tab>
63
74
  <Tab
64
- className={`payment-tab ${activeTab === 2 ? 'payment-tab-active' : ''}`}
75
+ className={`payment-tab ${
76
+ activeTab === 2 ? "payment-tab-active" : ""
77
+ }`}
65
78
  >
66
79
  Payment Actions
67
80
  </Tab>
68
81
  <Tab
69
- className={`payment-tab ${activeTab === 3 ? 'payment-tab-active' : ''}`}
82
+ className={`payment-tab ${
83
+ activeTab === 3 ? "payment-tab-active" : ""
84
+ }`}
70
85
  >
71
86
  Documentation
72
87
  </Tab>
@@ -81,6 +96,7 @@ const AppTabs = ({
81
96
  onSave={onSave}
82
97
  onTestConnection={onTestConnection}
83
98
  onInputChange={onInputChange}
99
+ onPaymentMethodToggle={onPaymentMethodToggle}
84
100
  />
85
101
  </TabPanel>
86
102
 
@@ -155,4 +171,3 @@ const AppTabs = ({
155
171
  };
156
172
 
157
173
  export default AppTabs;
158
-
@@ -25,31 +25,22 @@ const ApplePayBtn = ({
25
25
  {
26
26
  method: "POST",
27
27
  body: {
28
- domain: window.location.hostname,
29
- domainName: window.location.hostname,
30
- displayName: settings?.merchantName || "Store",
28
+ domainName: settings?.domainName || window.location.hostname,
29
+ displayName: settings?.displayName || "Store",
31
30
  currency: requestCurrency,
32
31
  countryCode: requestCountryCode,
32
+ mode: (settings?.mode || "test").toLowerCase() || "test",
33
33
  },
34
34
  }
35
35
  );
36
-
37
36
  if (merchantSession.error) {
38
37
  const errorMessage =
39
38
  merchantSession.error.message || "Merchant validation failed";
40
39
  const errorDetails = merchantSession.error.details || "";
41
40
 
42
- // If it's a 403 error, provide more specific guidance
43
- if (merchantSession.error.status === 403) {
44
- throw new Error(
45
- `403 Forbidden: Authentication failed with Payone. ` +
46
- `Please check your Payone credentials (aid, portalid, mid, key) in plugin settings. ` +
47
- `Also ensure that: 1) Mode is set to "live" (Apple Pay only works in live mode), ` +
48
- `2) Your domain is registered with Payone Merchant Services, ` +
49
- `3) Merchant ID (mid) matches your merchantIdentifier in PMI. ` +
50
- `Details: ${errorDetails || errorMessage}`
51
- );
52
- }
41
+ console.log(
42
+ `[Apple Pay] Merchant validation failed: ${errorMessage} ${errorDetails}`
43
+ );
53
44
 
54
45
  throw new Error(
55
46
  errorMessage + (errorDetails ? ` - ${errorDetails}` : "")
@@ -67,18 +58,14 @@ const ApplePayBtn = ({
67
58
 
68
59
  session.completeMerchantValidation(sessionData);
69
60
  } catch (error) {
70
-
71
- // Don't call completeMerchantValidation with empty object - this causes user cancellation
72
- // Instead, let the error propagate so user can see what went wrong
73
61
  if (onError) {
74
62
  onError(error);
75
63
  }
76
64
 
77
- // Complete with failure status to show error to user
78
65
  try {
79
66
  session.completeMerchantValidation({});
80
67
  } catch (completeError) {
81
- // Silent fail
68
+ console.error(completeError);
82
69
  }
83
70
  }
84
71
  };
@@ -133,27 +120,75 @@ const ApplePayBtn = ({
133
120
 
134
121
  const tokenObject = paymentData.token;
135
122
 
123
+ if (!tokenObject) {
124
+ const result = {
125
+ status: window.ApplePaySession.STATUS_FAILURE,
126
+ };
127
+ session.completePayment(result);
128
+ if (onError) {
129
+ onError(new Error("Payment token is missing"));
130
+ }
131
+ return;
132
+ }
133
+
136
134
  if (!tokenObject.paymentData) {
135
+ console.error(
136
+ "[Apple Pay] Invalid token structure: missing paymentData",
137
+ {
138
+ tokenKeys: Object.keys(tokenObject),
139
+ tokenStructure: JSON.stringify(tokenObject).substring(0, 500),
140
+ }
141
+ );
137
142
  const result = {
138
143
  status: window.ApplePaySession.STATUS_FAILURE,
139
144
  };
140
145
  session.completePayment(result);
141
146
  if (onError) {
142
- onError(new Error("Invalid Apple Pay token structure"));
147
+ onError(
148
+ new Error(
149
+ "Invalid Apple Pay token structure: missing paymentData field"
150
+ )
151
+ );
143
152
  }
144
153
  return;
145
154
  }
146
155
 
147
- // Encode token as Base64 for transmission
156
+ const paymentDataObj = tokenObject.paymentData;
157
+ const header = paymentDataObj.header || {};
158
+
159
+ console.log("[Apple Pay] Token structure validation:", {
160
+ hasVersion: !!paymentDataObj.version,
161
+ hasData: !!paymentDataObj.data,
162
+ hasSignature: !!paymentDataObj.signature,
163
+ hasHeader: !!paymentDataObj.header,
164
+ hasEphemeralPublicKey: !!header.ephemeralPublicKey,
165
+ hasPublicKeyHash: !!header.publicKeyHash,
166
+ hasTransactionId:
167
+ !!paymentDataObj.transactionId || !!header.transactionId,
168
+ dataLength: paymentDataObj.data ? paymentDataObj.data.length : 0,
169
+ signatureLength: paymentDataObj.signature
170
+ ? paymentDataObj.signature.length
171
+ : 0,
172
+ });
173
+
148
174
  let tokenString;
149
175
  try {
150
- tokenString = btoa(
151
- unescape(encodeURIComponent(JSON.stringify(tokenObject)))
152
- );
176
+ const tokenJson = JSON.stringify(tokenObject);
177
+ tokenString = btoa(unescape(encodeURIComponent(tokenJson)));
178
+ console.log("[Apple Pay] Token encoded successfully:", {
179
+ tokenLength: tokenJson.length,
180
+ encodedLength: tokenString.length,
181
+ });
153
182
  } catch (e) {
154
- tokenString = btoa(
155
- unescape(encodeURIComponent(JSON.stringify(tokenObject)))
156
- );
183
+ console.error("[Apple Pay] Error encoding token:", e);
184
+ const result = {
185
+ status: window.ApplePaySession.STATUS_FAILURE,
186
+ };
187
+ session.completePayment(result);
188
+ if (onError) {
189
+ onError(new Error(`Failed to encode token: ${e.message}`));
190
+ }
191
+ return;
157
192
  }
158
193
 
159
194
  if (onTokenReceived) {
@@ -11,6 +11,7 @@ import {
11
11
  Select,
12
12
  Option,
13
13
  Alert,
14
+ Switch,
14
15
  } from "@strapi/design-system";
15
16
  import { Play, Cog } from "@strapi/icons";
16
17
  import { useHistory } from "react-router-dom";
@@ -18,20 +19,15 @@ import pluginId from "../../../pluginId";
18
19
 
19
20
  const ConfigurationPanel = ({
20
21
  settings,
21
- isSaving,
22
22
  isTesting,
23
23
  testResult,
24
- onSave,
25
24
  onTestConnection,
26
25
  onInputChange,
26
+ onPaymentMethodToggle,
27
27
  }) => {
28
28
  const history = useHistory();
29
29
  const mode = (settings?.mode || "test").toLowerCase();
30
30
 
31
- useEffect(() => {
32
- // Mode updated
33
- }, [settings?.mode]);
34
-
35
31
  const handleNavigateToApplePayConfig = () => {
36
32
  history.push(`/plugins/${pluginId}/apple-pay-config`);
37
33
  };
@@ -69,8 +65,14 @@ const ConfigurationPanel = ({
69
65
  Configure your Payone payment gateway settings
70
66
  </Typography>
71
67
  </Box>
72
-
73
- <Box>
68
+ <Box
69
+ style={{
70
+ display: "flex",
71
+ flexDirection: "row",
72
+ gap: "16px",
73
+ flexWrap: "wrap",
74
+ }}
75
+ >
74
76
  <Card className="payment-card">
75
77
  <CardBody padding={6}>
76
78
  <Stack spacing={6}>
@@ -123,6 +125,32 @@ const ConfigurationPanel = ({
123
125
  />
124
126
  </Flex>
125
127
 
128
+ <Flex gap={4} wrap="wrap">
129
+ <TextInput
130
+ label="Domain Name"
131
+ name="domainName"
132
+ value={settings.domainName || ""}
133
+ onChange={(e) =>
134
+ onInputChange("domainName", e.target.value)
135
+ }
136
+ hint="Your domain name (optional)"
137
+ className="payment-input"
138
+ style={{ flex: 1, minWidth: "300px" }}
139
+ />
140
+
141
+ <TextInput
142
+ label="Display Name"
143
+ name="displayName"
144
+ value={settings.displayName || ""}
145
+ onChange={(e) =>
146
+ onInputChange("displayName", e.target.value)
147
+ }
148
+ hint="Display name for payment methods (optional)"
149
+ className="payment-input"
150
+ style={{ flex: 1, minWidth: "300px" }}
151
+ />
152
+ </Flex>
153
+
126
154
  <Flex gap={4} wrap="wrap">
127
155
  <Select
128
156
  label="Mode"
@@ -202,8 +230,160 @@ const ConfigurationPanel = ({
202
230
  </Stack>
203
231
  </CardBody>
204
232
  </Card>
205
- </Box>
206
233
 
234
+ <Card className="payment-card">
235
+ <CardBody padding={6}>
236
+ <Stack spacing={6}>
237
+ <Box>
238
+ <Typography
239
+ variant="delta"
240
+ as="h3"
241
+ fontWeight="bold"
242
+ marginBottom={4}
243
+ >
244
+ Payment Methods
245
+ </Typography>
246
+ <Typography
247
+ variant="pi"
248
+ textColor="neutral600"
249
+ marginBottom={4}
250
+ >
251
+ Enable or disable payment methods for your Payone
252
+ integration
253
+ </Typography>
254
+ </Box>
255
+
256
+ <Stack spacing={4}>
257
+ <Flex
258
+ direction="row"
259
+ justifyContent="space-between"
260
+ alignItems="center"
261
+ gap={4}
262
+ >
263
+ <Typography variant="omega" fontWeight="semiBold">
264
+ Credit Card (Visa, Mastercard)
265
+ </Typography>
266
+ <Switch
267
+ label="Credit Card"
268
+ selected={settings.enableCreditCard !== false}
269
+ onChange={() =>
270
+ onPaymentMethodToggle(
271
+ "enableCreditCard",
272
+ !settings.enableCreditCard
273
+ )
274
+ }
275
+ />
276
+ </Flex>
277
+
278
+ <Flex
279
+ direction="row"
280
+ justifyContent="space-between"
281
+ alignItems="center"
282
+ gap={4}
283
+ >
284
+ <Typography variant="omega" fontWeight="semiBold">
285
+ PayPal
286
+ </Typography>
287
+ <Switch
288
+ label="PayPal"
289
+ selected={settings.enablePayPal !== false}
290
+ onChange={() =>
291
+ onPaymentMethodToggle(
292
+ "enablePayPal",
293
+ !settings.enablePayPal
294
+ )
295
+ }
296
+ />
297
+ </Flex>
298
+
299
+ <Flex
300
+ direction="row"
301
+ justifyContent="space-between"
302
+ alignItems="center"
303
+ gap={4}
304
+ >
305
+ <Typography variant="omega" fontWeight="semiBold">
306
+ Google Pay
307
+ </Typography>
308
+ <Switch
309
+ label="Google Pay"
310
+ selected={settings.enableGooglePay !== false}
311
+ onChange={() =>
312
+ onPaymentMethodToggle(
313
+ "enableGooglePay",
314
+ !settings.enableGooglePay
315
+ )
316
+ }
317
+ />
318
+ </Flex>
319
+
320
+ <Flex
321
+ direction="row"
322
+ justifyContent="space-between"
323
+ alignItems="center"
324
+ gap={4}
325
+ >
326
+ <Typography variant="omega" fontWeight="semiBold">
327
+ Apple Pay
328
+ </Typography>
329
+ <Switch
330
+ label="Apple Pay"
331
+ selected={settings.enableApplePay !== false}
332
+ onChange={() =>
333
+ onPaymentMethodToggle(
334
+ "enableApplePay",
335
+ !settings.enableApplePay
336
+ )
337
+ }
338
+ />
339
+ </Flex>
340
+
341
+ <Flex
342
+ direction="row"
343
+ justifyContent="space-between"
344
+ alignItems="center"
345
+ gap={4}
346
+ >
347
+ <Typography variant="omega" fontWeight="semiBold">
348
+ Sofort Banking
349
+ </Typography>
350
+ <Switch
351
+ label="Sofort Banking"
352
+ selected={settings.enableSofort !== false}
353
+ onChange={() =>
354
+ onPaymentMethodToggle(
355
+ "enableSofort",
356
+ !settings.enableSofort
357
+ )
358
+ }
359
+ />
360
+ </Flex>
361
+
362
+ <Flex
363
+ direction="row"
364
+ justifyContent="space-between"
365
+ alignItems="center"
366
+ gap={4}
367
+ >
368
+ <Typography variant="omega" fontWeight="semiBold">
369
+ SEPA Direct Debit
370
+ </Typography>
371
+ <Switch
372
+ label="SEPA Direct Debit"
373
+ selected={settings.enableSepaDirectDebit !== false}
374
+ onChange={() =>
375
+ onPaymentMethodToggle(
376
+ "enableSepaDirectDebit",
377
+ !settings.enableSepaDirectDebit
378
+ )
379
+ }
380
+ />
381
+ </Flex>
382
+ </Stack>
383
+ </Stack>
384
+ </CardBody>
385
+ </Card>
386
+ </Box>
207
387
  <Box paddingTop={6}>
208
388
  <Card className="payment-card">
209
389
  <CardBody padding={6}>
@@ -323,7 +503,6 @@ const ConfigurationPanel = ({
323
503
  </CardBody>
324
504
  </Card>
325
505
  </Box>
326
-
327
506
  <Box paddingTop={4}>
328
507
  <Typography variant="sigma" textColor="neutral600">
329
508
  Note: These settings are used for all Payone API requests. Make sure