strapi-plugin-payone-provider 1.6.6 → 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.
- package/.well-known/.gitkeep +3 -0
- package/.well-known/apple-developer-merchant-id-domain-association.txt +1 -0
- package/admin/src/pages/App/components/AppTabs.jsx +31 -16
- package/admin/src/pages/App/components/ApplePayBtn.jsx +63 -28
- package/admin/src/pages/App/components/ConfigurationPanel.jsx +163 -10
- package/admin/src/pages/App/components/DocsPanel.jsx +864 -194
- package/admin/src/pages/App/components/HistoryPanel.jsx +39 -34
- package/admin/src/pages/App/components/PaymentActionsPanel.jsx +8 -1
- package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +45 -1
- package/admin/src/pages/App/index.jsx +1 -0
- package/admin/src/pages/hooks/useSettings.js +26 -0
- package/admin/src/pages/hooks/useTransactionHistory.js +2 -3
- package/package.json +1 -1
- package/server/bootstrap.js +9 -3
- package/server/controllers/payone.js +8 -0
- package/server/services/applePayService.js +103 -93
- package/server/services/transactionService.js +35 -14
- package/server/utils/paymentMethodParams.js +67 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
7b2276657273696f6e223a312c227073704964223a2235393638344337413333424534333631304339333343413031384639393231333841394642453136413636363835333532463437413441414646363734333038222c22637265617465644f6e223a313735363238323636363439317d
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
151
|
-
|
|
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
|
-
|
|
155
|
-
|
|
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
|
-
|
|
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}>
|
|
@@ -228,8 +230,160 @@ const ConfigurationPanel = ({
|
|
|
228
230
|
</Stack>
|
|
229
231
|
</CardBody>
|
|
230
232
|
</Card>
|
|
231
|
-
</Box>
|
|
232
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>
|
|
233
387
|
<Box paddingTop={6}>
|
|
234
388
|
<Card className="payment-card">
|
|
235
389
|
<CardBody padding={6}>
|
|
@@ -349,7 +503,6 @@ const ConfigurationPanel = ({
|
|
|
349
503
|
</CardBody>
|
|
350
504
|
</Card>
|
|
351
505
|
</Box>
|
|
352
|
-
|
|
353
506
|
<Box paddingTop={4}>
|
|
354
507
|
<Typography variant="sigma" textColor="neutral600">
|
|
355
508
|
Note: These settings are used for all Payone API requests. Make sure
|