strapi-plugin-payone-provider 1.4.2 → 1.5.2
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/README.md +179 -22
- package/admin/src/pages/App/components/AppHeader.js +22 -4
- package/admin/src/pages/App/components/AppTabs.js +25 -1
- package/admin/src/pages/App/components/ApplePayButton.js +737 -0
- package/admin/src/pages/App/components/ApplePayConfig.js +364 -0
- package/admin/src/pages/App/components/ApplePayConfigPanel.js +81 -0
- package/admin/src/pages/App/components/ConfigurationPanel.js +19 -3
- package/admin/src/pages/App/components/DocsPanel.js +1057 -0
- package/admin/src/pages/App/components/GooglePayConfig.js +217 -0
- package/admin/src/pages/App/components/GooglePayConfigPanel.js +82 -0
- package/admin/src/pages/App/components/GooglePaybutton.js +1 -1
- package/admin/src/pages/App/components/PaymentActionsPanel.js +24 -6
- package/admin/src/pages/App/components/paymentActions/AuthorizationForm.js +60 -4
- package/admin/src/pages/App/components/paymentActions/CaptureForm.js +1 -0
- package/admin/src/pages/App/components/paymentActions/CardDetailsInput.js +18 -16
- package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.js +106 -2
- package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.js +64 -4
- package/admin/src/pages/App/components/paymentActions/RefundForm.js +1 -0
- package/admin/src/pages/App/index.js +70 -1
- package/admin/src/pages/hooks/usePaymentActions.js +13 -2
- package/admin/src/pages/hooks/useSettings.js +2 -0
- package/admin/src/pages/utils/applePayConstants.js +222 -0
- package/admin/src/pages/utils/googlePayConstants.js +79 -0
- package/admin/src/pages/utils/paymentUtils.js +22 -74
- package/package.json +1 -1
- package/server/bootstrap.js +5 -1
- package/server/config/index.js +5 -1
- package/server/controllers/payone.js +10 -0
- package/server/routes/index.js +17 -0
- package/server/services/applePayService.js +261 -0
- package/server/services/payone.js +10 -0
- package/server/utils/paymentMethodParams.js +19 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Box, Flex, Select, Option } from "@strapi/design-system";
|
|
2
|
+
import { Box, Flex, Select, Option, Typography, Link, Alert } from "@strapi/design-system";
|
|
3
|
+
import pluginId from "../../../../pluginId";
|
|
3
4
|
import {
|
|
4
5
|
getPaymentMethodOptions,
|
|
5
6
|
supportsCaptureMode,
|
|
@@ -11,7 +12,8 @@ const PaymentMethodSelector = ({
|
|
|
11
12
|
paymentMethod,
|
|
12
13
|
setPaymentMethod,
|
|
13
14
|
captureMode,
|
|
14
|
-
setCaptureMode
|
|
15
|
+
setCaptureMode,
|
|
16
|
+
onNavigateToConfig
|
|
15
17
|
}) => {
|
|
16
18
|
return (
|
|
17
19
|
<Box>
|
|
@@ -29,6 +31,108 @@ const PaymentMethodSelector = ({
|
|
|
29
31
|
</Option>
|
|
30
32
|
))}
|
|
31
33
|
</Select>
|
|
34
|
+
{paymentMethod === "apl" && onNavigateToConfig && (
|
|
35
|
+
<>
|
|
36
|
+
<Alert closeLabel="Close" title="⚠️ Important: Middleware Configuration Required" variant="warning">
|
|
37
|
+
<Typography variant="pi" marginTop={2}>
|
|
38
|
+
<strong>Apple Pay requires middleware configuration</strong> to work properly. You must configure Content Security Policy (CSP) in <code>config/middlewares.js</code> to allow Apple Pay scripts, otherwise Apple Pay will NOT work.
|
|
39
|
+
</Typography>
|
|
40
|
+
<Typography variant="pi" marginTop={2}>
|
|
41
|
+
Required CSP directives for Apple Pay:
|
|
42
|
+
</Typography>
|
|
43
|
+
<Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
|
|
44
|
+
<Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
|
|
45
|
+
'script-src': ['https://applepay.cdn-apple.com', 'https://www.apple.com']<br/>
|
|
46
|
+
'connect-src': ['https://applepay.cdn-apple.com', 'https://www.apple.com']<br/>
|
|
47
|
+
'frame-src': ['https://applepay.cdn-apple.com']
|
|
48
|
+
</Typography>
|
|
49
|
+
</Box>
|
|
50
|
+
<Typography variant="pi" marginTop={2} fontWeight="bold">
|
|
51
|
+
⚠️ Without this configuration, Apple Pay will NOT work!
|
|
52
|
+
</Typography>
|
|
53
|
+
</Alert>
|
|
54
|
+
<Alert closeLabel="Close" title="📥 Apple Pay Domain Verification File Required" variant="default">
|
|
55
|
+
<Typography variant="pi" marginTop={2}>
|
|
56
|
+
<strong>Download the Apple Pay domain verification file</strong> from your Payone merchant portal and place it in:
|
|
57
|
+
</Typography>
|
|
58
|
+
<Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
|
|
59
|
+
<Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
|
|
60
|
+
<strong>Strapi:</strong> <code>public/.well-known/apple-developer-merchantid-domain-association</code><br/>
|
|
61
|
+
<strong>Frontend:</strong> <code>public/.well-known/apple-developer-merchantid-domain-association</code>
|
|
62
|
+
</Typography>
|
|
63
|
+
</Box>
|
|
64
|
+
<Typography variant="pi" marginTop={2}>
|
|
65
|
+
<strong>Download URL:</strong> Download the domain verification file from Payone documentation:{" "}
|
|
66
|
+
<Link
|
|
67
|
+
href="https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev"
|
|
68
|
+
target="_blank"
|
|
69
|
+
rel="noopener noreferrer"
|
|
70
|
+
style={{ color: "#0066ff", textDecoration: "underline" }}
|
|
71
|
+
>
|
|
72
|
+
https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
|
|
73
|
+
</Link>
|
|
74
|
+
</Typography>
|
|
75
|
+
<Typography variant="pi" marginTop={2}>
|
|
76
|
+
<strong>Alternative:</strong> Log into your Payone Merchant Interface (PMI) → Configuration → Payment Portals → Apple Pay → Download domain verification file
|
|
77
|
+
</Typography>
|
|
78
|
+
<Typography variant="pi" marginTop={2} fontWeight="bold" textColor="danger600">
|
|
79
|
+
⚠️ Without this file, Apple Pay will NOT work on your domain!
|
|
80
|
+
</Typography>
|
|
81
|
+
</Alert>
|
|
82
|
+
<Box padding={3} background="neutral100" borderRadius="4px">
|
|
83
|
+
<Typography variant="pi" textColor="neutral600">
|
|
84
|
+
Configure Apple Pay settings:{" "}
|
|
85
|
+
<Link
|
|
86
|
+
href={`/plugins/${pluginId}/apple-pay-config`}
|
|
87
|
+
onClick={(e) => {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
onNavigateToConfig("apple-pay");
|
|
90
|
+
}}
|
|
91
|
+
style={{ cursor: "pointer", textDecoration: "underline", color: "#0066ff" }}
|
|
92
|
+
>
|
|
93
|
+
/plugins/{pluginId}/apple-pay-config
|
|
94
|
+
</Link>
|
|
95
|
+
</Typography>
|
|
96
|
+
</Box>
|
|
97
|
+
</>
|
|
98
|
+
)}
|
|
99
|
+
{paymentMethod === "gpp" && onNavigateToConfig && (
|
|
100
|
+
<>
|
|
101
|
+
<Alert closeLabel="Close" title="⚠️ Important: Middleware Configuration Required" variant="warning">
|
|
102
|
+
<Typography variant="pi" marginTop={2}>
|
|
103
|
+
<strong>Google Pay requires middleware configuration</strong> to work properly. You must configure Content Security Policy (CSP) in <code>config/middlewares.js</code> to allow Google Pay scripts, otherwise Google Pay will NOT work.
|
|
104
|
+
</Typography>
|
|
105
|
+
<Typography variant="pi" marginTop={2}>
|
|
106
|
+
Required CSP directives for Google Pay:
|
|
107
|
+
</Typography>
|
|
108
|
+
<Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
|
|
109
|
+
<Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
|
|
110
|
+
'script-src': ['https://pay.google.com']<br/>
|
|
111
|
+
'connect-src': ['https://pay.google.com']<br/>
|
|
112
|
+
'frame-src': ['https://pay.google.com']
|
|
113
|
+
</Typography>
|
|
114
|
+
</Box>
|
|
115
|
+
<Typography variant="pi" marginTop={2} fontWeight="bold">
|
|
116
|
+
⚠️ Without this configuration, Google Pay will NOT work!
|
|
117
|
+
</Typography>
|
|
118
|
+
</Alert>
|
|
119
|
+
<Box padding={3} background="neutral100" borderRadius="4px">
|
|
120
|
+
<Typography variant="pi" textColor="neutral600">
|
|
121
|
+
Configure Google Pay settings:{" "}
|
|
122
|
+
<Link
|
|
123
|
+
href={`/plugins/${pluginId}/google-pay-config`}
|
|
124
|
+
onClick={(e) => {
|
|
125
|
+
e.preventDefault();
|
|
126
|
+
onNavigateToConfig("google-pay");
|
|
127
|
+
}}
|
|
128
|
+
style={{ cursor: "pointer", textDecoration: "underline", color: "#0066ff" }}
|
|
129
|
+
>
|
|
130
|
+
/plugins/{pluginId}/google-pay-config
|
|
131
|
+
</Link>
|
|
132
|
+
</Typography>
|
|
133
|
+
</Box>
|
|
134
|
+
</>
|
|
135
|
+
)}
|
|
32
136
|
{supportsCaptureMode(paymentMethod) && (
|
|
33
137
|
<Select
|
|
34
138
|
label="Capture Mode"
|
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { Box, Flex, Typography, TextInput, Button } from "@strapi/design-system";
|
|
3
3
|
import { Play } from "@strapi/icons";
|
|
4
4
|
import GooglePayButton from "../GooglePaybutton";
|
|
5
|
+
import ApplePayButton from "../ApplePayButton";
|
|
5
6
|
import CardDetailsInput from "./CardDetailsInput";
|
|
6
7
|
|
|
7
8
|
const PreauthorizationForm = ({
|
|
@@ -15,6 +16,8 @@ const PreauthorizationForm = ({
|
|
|
15
16
|
settings,
|
|
16
17
|
googlePayToken,
|
|
17
18
|
setGooglePayToken,
|
|
19
|
+
applePayToken,
|
|
20
|
+
setApplePayToken,
|
|
18
21
|
cardtype,
|
|
19
22
|
setCardtype,
|
|
20
23
|
cardpan,
|
|
@@ -22,7 +25,8 @@ const PreauthorizationForm = ({
|
|
|
22
25
|
cardexpiredate,
|
|
23
26
|
setCardexpiredate,
|
|
24
27
|
cardcvc2,
|
|
25
|
-
setCardcvc2
|
|
28
|
+
setCardcvc2,
|
|
29
|
+
isLiveMode = false
|
|
26
30
|
}) => {
|
|
27
31
|
const handleGooglePayToken = (token, paymentData) => {
|
|
28
32
|
if (!token) {
|
|
@@ -37,6 +41,26 @@ const PreauthorizationForm = ({
|
|
|
37
41
|
onError(error);
|
|
38
42
|
}
|
|
39
43
|
};
|
|
44
|
+
|
|
45
|
+
const handleApplePayToken = async (token, paymentData) => {
|
|
46
|
+
if (!token) {
|
|
47
|
+
return Promise.reject(new Error("Token is missing"));
|
|
48
|
+
}
|
|
49
|
+
setApplePayToken(token);
|
|
50
|
+
try {
|
|
51
|
+
await onPreauthorization(token);
|
|
52
|
+
return Promise.resolve();
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error("[Apple Pay] Error in preauthorization:", error);
|
|
55
|
+
return Promise.reject(error);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const handleApplePayError = (error) => {
|
|
60
|
+
if (onError) {
|
|
61
|
+
onError(error);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
40
64
|
return (
|
|
41
65
|
<Flex direction="column" alignItems="stretch" gap={4}>
|
|
42
66
|
<Flex direction="row" gap={2}>
|
|
@@ -73,8 +97,7 @@ const PreauthorizationForm = ({
|
|
|
73
97
|
/>
|
|
74
98
|
</Flex>
|
|
75
99
|
|
|
76
|
-
{
|
|
77
|
-
{paymentMethod === "cc" && settings?.enable3DSecure !== false && (
|
|
100
|
+
{paymentMethod === "cc" && settings?.enable3DSecure && (
|
|
78
101
|
<Box marginTop={4}>
|
|
79
102
|
<CardDetailsInput
|
|
80
103
|
cardtype={cardtype}
|
|
@@ -97,18 +120,55 @@ const PreauthorizationForm = ({
|
|
|
97
120
|
onError={handleGooglePayError}
|
|
98
121
|
settings={settings}
|
|
99
122
|
/>
|
|
123
|
+
) : paymentMethod === "apl" ? (
|
|
124
|
+
<Box>
|
|
125
|
+
<ApplePayButton
|
|
126
|
+
amount={paymentAmount}
|
|
127
|
+
currency="EUR"
|
|
128
|
+
onTokenReceived={handleApplePayToken}
|
|
129
|
+
onError={handleApplePayError}
|
|
130
|
+
settings={settings}
|
|
131
|
+
/>
|
|
132
|
+
{applePayToken && (
|
|
133
|
+
<Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
|
|
134
|
+
<Typography variant="pi" textColor="success600" style={{ marginBottom: "8px", fontWeight: "bold" }}>
|
|
135
|
+
✓ Apple Pay token received. You can now process the preauthorization:
|
|
136
|
+
</Typography>
|
|
137
|
+
<Button
|
|
138
|
+
variant="default"
|
|
139
|
+
onClick={() => onPreauthorization(applePayToken)}
|
|
140
|
+
loading={isProcessingPayment}
|
|
141
|
+
startIcon={<Play />}
|
|
142
|
+
style={{ maxWidth: '200px' }}
|
|
143
|
+
disabled={!paymentAmount.trim() || !preauthReference.trim() || isLiveMode}
|
|
144
|
+
className="payment-button payment-button-primary"
|
|
145
|
+
>
|
|
146
|
+
Process Preauthorization
|
|
147
|
+
</Button>
|
|
148
|
+
</Box>
|
|
149
|
+
)}
|
|
150
|
+
{!applePayToken && (
|
|
151
|
+
<Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
|
|
152
|
+
<Typography variant="pi" textColor="neutral600" style={{ marginBottom: "8px" }}>
|
|
153
|
+
Apple Pay is not available on localhost. You can test the payment flow without Apple Pay token:
|
|
154
|
+
</Typography>
|
|
155
|
+
</Box>
|
|
156
|
+
)}
|
|
157
|
+
</Box>
|
|
100
158
|
) : (
|
|
101
159
|
<Button
|
|
102
160
|
variant="default"
|
|
103
161
|
onClick={onPreauthorization}
|
|
104
162
|
loading={isProcessingPayment}
|
|
105
163
|
startIcon={<Play />}
|
|
164
|
+
style={{ maxWidth: '200px' }}
|
|
106
165
|
className="payment-button payment-button-primary"
|
|
107
166
|
disabled={
|
|
108
167
|
!paymentAmount.trim() ||
|
|
109
168
|
(paymentMethod === "cc" &&
|
|
110
169
|
settings?.enable3DSecure !== false &&
|
|
111
|
-
(!cardtype || !cardpan || !cardexpiredate || !cardcvc2))
|
|
170
|
+
(!cardtype || !cardpan || !cardexpiredate || !cardcvc2)) ||
|
|
171
|
+
isLiveMode
|
|
112
172
|
}
|
|
113
173
|
>
|
|
114
174
|
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>
|
|
@@ -50,6 +50,7 @@ const usePaymentActions = () => {
|
|
|
50
50
|
const [paymentMethod, setPaymentMethod] = useState("cc");
|
|
51
51
|
const [captureMode, setCaptureMode] = useState("full");
|
|
52
52
|
const [googlePayToken, setGooglePayToken] = useState(null);
|
|
53
|
+
const [applePayToken, setApplePayToken] = useState(null);
|
|
53
54
|
|
|
54
55
|
// Card details for 3DS testing
|
|
55
56
|
const [cardtype, setCardtype] = useState("");
|
|
@@ -129,10 +130,13 @@ const usePaymentActions = () => {
|
|
|
129
130
|
baseParams.backurl = `${baseUrl}${basePath}${pluginPath}/back`;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
const tokenToUse = tokenParam || googlePayToken;
|
|
133
|
+
const tokenToUse = tokenParam || googlePayToken || applePayToken;
|
|
133
134
|
if (paymentMethod === "gpp" && tokenToUse) {
|
|
134
135
|
baseParams.googlePayToken = tokenToUse;
|
|
135
136
|
baseParams.settings = settings;
|
|
137
|
+
} else if (paymentMethod === "apl" && tokenToUse) {
|
|
138
|
+
baseParams.applePayToken = tokenToUse;
|
|
139
|
+
baseParams.settings = settings;
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
const params = getPreauthorizationParams(paymentMethod, baseParams);
|
|
@@ -271,10 +275,13 @@ const usePaymentActions = () => {
|
|
|
271
275
|
baseParams.backurl = `${baseUrl}${basePath}${pluginPath}/back`;
|
|
272
276
|
}
|
|
273
277
|
|
|
274
|
-
const tokenToUse = tokenParam || googlePayToken;
|
|
278
|
+
const tokenToUse = tokenParam || googlePayToken || applePayToken;
|
|
275
279
|
if (paymentMethod === "gpp" && tokenToUse) {
|
|
276
280
|
baseParams.googlePayToken = tokenToUse;
|
|
277
281
|
baseParams.settings = settings;
|
|
282
|
+
} else if (paymentMethod === "apl" && tokenToUse) {
|
|
283
|
+
baseParams.applePayToken = tokenToUse;
|
|
284
|
+
baseParams.settings = settings;
|
|
278
285
|
}
|
|
279
286
|
|
|
280
287
|
const params = getAuthorizationParams(paymentMethod, baseParams);
|
|
@@ -454,6 +461,10 @@ const usePaymentActions = () => {
|
|
|
454
461
|
googlePayToken,
|
|
455
462
|
setGooglePayToken,
|
|
456
463
|
|
|
464
|
+
// Apple Pay
|
|
465
|
+
applePayToken,
|
|
466
|
+
setApplePayToken,
|
|
467
|
+
|
|
457
468
|
// Card details for 3DS
|
|
458
469
|
cardtype,
|
|
459
470
|
setCardtype,
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apple Pay Constants
|
|
3
|
+
* Based on Apple Pay documentation and Payone requirements
|
|
4
|
+
* https://developer.apple.com/documentation/applepayontheweb
|
|
5
|
+
* https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Apple Pay supported countries
|
|
9
|
+
// Note: Apple Pay availability varies by country
|
|
10
|
+
export const APPLE_PAY_SUPPORTED_COUNTRIES = [
|
|
11
|
+
{ code: "US", name: "United States" },
|
|
12
|
+
{ code: "GB", name: "United Kingdom" },
|
|
13
|
+
{ code: "CA", name: "Canada" },
|
|
14
|
+
{ code: "AU", name: "Australia" },
|
|
15
|
+
{ code: "DE", name: "Germany" },
|
|
16
|
+
{ code: "FR", name: "France" },
|
|
17
|
+
{ code: "IT", name: "Italy" },
|
|
18
|
+
{ code: "ES", name: "Spain" },
|
|
19
|
+
{ code: "NL", name: "Netherlands" },
|
|
20
|
+
{ code: "BE", name: "Belgium" },
|
|
21
|
+
{ code: "CH", name: "Switzerland" },
|
|
22
|
+
{ code: "AT", name: "Austria" },
|
|
23
|
+
{ code: "IE", name: "Ireland" },
|
|
24
|
+
{ code: "SE", name: "Sweden" },
|
|
25
|
+
{ code: "NO", name: "Norway" },
|
|
26
|
+
{ code: "DK", name: "Denmark" },
|
|
27
|
+
{ code: "FI", name: "Finland" },
|
|
28
|
+
{ code: "PL", name: "Poland" },
|
|
29
|
+
{ code: "CZ", name: "Czech Republic" },
|
|
30
|
+
{ code: "HU", name: "Hungary" },
|
|
31
|
+
{ code: "PT", name: "Portugal" },
|
|
32
|
+
{ code: "GR", name: "Greece" },
|
|
33
|
+
{ code: "JP", name: "Japan" },
|
|
34
|
+
{ code: "CN", name: "China" },
|
|
35
|
+
{ code: "HK", name: "Hong Kong" },
|
|
36
|
+
{ code: "TW", name: "Taiwan" },
|
|
37
|
+
{ code: "SG", name: "Singapore" },
|
|
38
|
+
{ code: "NZ", name: "New Zealand" },
|
|
39
|
+
{ code: "BR", name: "Brazil" },
|
|
40
|
+
{ code: "MX", name: "Mexico" },
|
|
41
|
+
{ code: "AE", name: "United Arab Emirates" },
|
|
42
|
+
{ code: "SA", name: "Saudi Arabia" },
|
|
43
|
+
{ code: "RU", name: "Russia" },
|
|
44
|
+
{ code: "UA", name: "Ukraine" },
|
|
45
|
+
{ code: "TR", name: "Turkey" },
|
|
46
|
+
{ code: "ZA", name: "South Africa" }
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
// Apple Pay supported currencies
|
|
50
|
+
// Note: Some currencies may be restricted in certain countries
|
|
51
|
+
export const APPLE_PAY_SUPPORTED_CURRENCIES = [
|
|
52
|
+
{ code: "USD", name: "US Dollar", symbol: "$" },
|
|
53
|
+
{ code: "EUR", name: "Euro", symbol: "€" },
|
|
54
|
+
{ code: "GBP", name: "British Pound", symbol: "£" },
|
|
55
|
+
{ code: "CAD", name: "Canadian Dollar", symbol: "C$" },
|
|
56
|
+
{ code: "AUD", name: "Australian Dollar", symbol: "A$" },
|
|
57
|
+
{ code: "JPY", name: "Japanese Yen", symbol: "¥" },
|
|
58
|
+
{ code: "CNY", name: "Chinese Yuan", symbol: "¥" },
|
|
59
|
+
{ code: "HKD", name: "Hong Kong Dollar", symbol: "HK$" },
|
|
60
|
+
{ code: "TWD", name: "Taiwan Dollar", symbol: "NT$" },
|
|
61
|
+
{ code: "SGD", name: "Singapore Dollar", symbol: "S$" },
|
|
62
|
+
{ code: "NZD", name: "New Zealand Dollar", symbol: "NZ$" },
|
|
63
|
+
{ code: "BRL", name: "Brazilian Real", symbol: "R$" },
|
|
64
|
+
{ code: "MXN", name: "Mexican Peso", symbol: "Mex$" },
|
|
65
|
+
{ code: "AED", name: "UAE Dirham", symbol: "د.إ" },
|
|
66
|
+
{ code: "SAR", name: "Saudi Riyal", symbol: "﷼" },
|
|
67
|
+
{ code: "RUB", name: "Russian Ruble", symbol: "₽" },
|
|
68
|
+
{ code: "UAH", name: "Ukrainian Hryvnia", symbol: "₴" },
|
|
69
|
+
{ code: "TRY", name: "Turkish Lira", symbol: "₺" },
|
|
70
|
+
{ code: "ZAR", name: "South African Rand", symbol: "R" },
|
|
71
|
+
{ code: "CHF", name: "Swiss Franc", symbol: "CHF" },
|
|
72
|
+
{ code: "SEK", name: "Swedish Krona", symbol: "kr" },
|
|
73
|
+
{ code: "NOK", name: "Norwegian Krone", symbol: "kr" },
|
|
74
|
+
{ code: "DKK", name: "Danish Krone", symbol: "kr" },
|
|
75
|
+
{ code: "PLN", name: "Polish Zloty", symbol: "zł" },
|
|
76
|
+
{ code: "CZK", name: "Czech Koruna", symbol: "Kč" },
|
|
77
|
+
{ code: "HUF", name: "Hungarian Forint", symbol: "Ft" }
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
// Apple Pay supported payment networks
|
|
81
|
+
export const APPLE_PAY_SUPPORTED_NETWORKS = [
|
|
82
|
+
{ code: "amex", name: "American Express" },
|
|
83
|
+
{ code: "discover", name: "Discover" },
|
|
84
|
+
{ code: "masterCard", name: "Mastercard" },
|
|
85
|
+
{ code: "visa", name: "Visa" },
|
|
86
|
+
{ code: "maestro", name: "Maestro" },
|
|
87
|
+
{ code: "girocard", name: "Girocard" },
|
|
88
|
+
{ code: "cartesBancaires", name: "Cartes Bancaires" },
|
|
89
|
+
{ code: "chinaUnionPay", name: "China UnionPay" },
|
|
90
|
+
{ code: "jcb", name: "JCB" },
|
|
91
|
+
{ code: "interac", name: "Interac" },
|
|
92
|
+
{ code: "privateLabel", name: "Private Label" }
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
// Merchant capabilities
|
|
96
|
+
export const APPLE_PAY_MERCHANT_CAPABILITIES = [
|
|
97
|
+
{ code: "supports3DS", name: "3D Secure", description: "Required for most payment methods" },
|
|
98
|
+
{ code: "supportsCredit", name: "Credit Cards", description: "Support credit card payments" },
|
|
99
|
+
{ code: "supportsDebit", name: "Debit Cards", description: "Support debit card payments" }
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
// Country-currency restrictions
|
|
103
|
+
// Some currencies are not available in certain countries
|
|
104
|
+
export const COUNTRY_CURRENCY_RESTRICTIONS = {
|
|
105
|
+
US: ["USD"],
|
|
106
|
+
GB: ["GBP", "EUR"],
|
|
107
|
+
CA: ["CAD", "USD"],
|
|
108
|
+
AU: ["AUD"],
|
|
109
|
+
DE: ["EUR"],
|
|
110
|
+
FR: ["EUR"],
|
|
111
|
+
IT: ["EUR"],
|
|
112
|
+
ES: ["EUR"],
|
|
113
|
+
JP: ["JPY"],
|
|
114
|
+
CN: ["CNY"],
|
|
115
|
+
HK: ["HKD"],
|
|
116
|
+
TW: ["TWD"],
|
|
117
|
+
SG: ["SGD"],
|
|
118
|
+
NZ: ["NZD"],
|
|
119
|
+
BR: ["BRL"],
|
|
120
|
+
MX: ["MXN"],
|
|
121
|
+
AE: ["AED"],
|
|
122
|
+
SA: ["SAR"],
|
|
123
|
+
RU: ["RUB", "USD", "EUR"],
|
|
124
|
+
UA: ["UAH", "USD", "EUR"],
|
|
125
|
+
TR: ["TRY", "USD", "EUR"],
|
|
126
|
+
ZA: ["ZAR"]
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Get supported currencies for a country
|
|
130
|
+
export const getSupportedCurrenciesForCountry = (countryCode) => {
|
|
131
|
+
const restrictions = COUNTRY_CURRENCY_RESTRICTIONS[countryCode];
|
|
132
|
+
if (restrictions) {
|
|
133
|
+
return APPLE_PAY_SUPPORTED_CURRENCIES.filter(currency =>
|
|
134
|
+
restrictions.includes(currency.code)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
// Default: return all currencies if no restrictions
|
|
138
|
+
return APPLE_PAY_SUPPORTED_CURRENCIES;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Get supported networks for a country
|
|
142
|
+
// Some networks are country-specific
|
|
143
|
+
export const getSupportedNetworksForCountry = (countryCode) => {
|
|
144
|
+
const countryNetworks = {
|
|
145
|
+
US: ["amex", "discover", "masterCard", "visa"],
|
|
146
|
+
GB: ["amex", "masterCard", "visa", "maestro"],
|
|
147
|
+
DE: ["masterCard", "visa", "girocard", "maestro"],
|
|
148
|
+
FR: ["masterCard", "visa", "cartesBancaires"],
|
|
149
|
+
CN: ["chinaUnionPay", "visa", "masterCard"],
|
|
150
|
+
JP: ["jcb", "visa", "masterCard", "amex"],
|
|
151
|
+
CA: ["visa", "masterCard", "amex", "interac"],
|
|
152
|
+
AU: ["visa", "masterCard", "amex"],
|
|
153
|
+
// Default networks for other countries
|
|
154
|
+
default: ["visa", "masterCard", "amex"]
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
return countryNetworks[countryCode] || countryNetworks.default;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Test data for Apple Pay
|
|
161
|
+
// Based on Apple Pay sandbox testing documentation
|
|
162
|
+
export const APPLE_PAY_TEST_DATA = {
|
|
163
|
+
// Test card numbers (for sandbox testing)
|
|
164
|
+
testCards: {
|
|
165
|
+
visa: "4111111111111111",
|
|
166
|
+
mastercard: "5555555555554444",
|
|
167
|
+
amex: "378282246310005",
|
|
168
|
+
discover: "6011111111111117"
|
|
169
|
+
},
|
|
170
|
+
// Test merchant identifiers (for development)
|
|
171
|
+
testMerchantIdentifier: "merchant.com.payone.test",
|
|
172
|
+
// Test domain
|
|
173
|
+
testDomain: "test.payone.com"
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// Apple Pay button styles
|
|
177
|
+
export const APPLE_PAY_BUTTON_STYLES = [
|
|
178
|
+
{ code: "black", name: "Black" },
|
|
179
|
+
{ code: "white", name: "White with outline" },
|
|
180
|
+
{ code: "white-outline", name: "White" }
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
// Apple Pay button types
|
|
184
|
+
export const APPLE_PAY_BUTTON_TYPES = [
|
|
185
|
+
{ code: "plain", name: "Plain" },
|
|
186
|
+
{ code: "buy", name: "Buy" },
|
|
187
|
+
{ code: "donate", name: "Donate" },
|
|
188
|
+
{ code: "check-out", name: "Check Out" },
|
|
189
|
+
{ code: "book", name: "Book" },
|
|
190
|
+
{ code: "subscribe", name: "Subscribe" },
|
|
191
|
+
{ code: "reload", name: "Reload" },
|
|
192
|
+
{ code: "add-money", name: "Add Money" },
|
|
193
|
+
{ code: "top-up", name: "Top Up" },
|
|
194
|
+
{ code: "order", name: "Order" },
|
|
195
|
+
{ code: "rent", name: "Rent" },
|
|
196
|
+
{ code: "support", name: "Support" },
|
|
197
|
+
{ code: "contribute", name: "Contribute" },
|
|
198
|
+
{ code: "tip", name: "Tip" },
|
|
199
|
+
{ code: "continue", name: "Continue" },
|
|
200
|
+
{ code: "pay", name: "Pay" },
|
|
201
|
+
{ code: "set-up", name: "Set Up" }
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
// Default Apple Pay configuration
|
|
205
|
+
export const DEFAULT_APPLE_PAY_CONFIG = {
|
|
206
|
+
countryCode: "DE",
|
|
207
|
+
currencyCode: "EUR",
|
|
208
|
+
merchantCapabilities: ["supports3DS"],
|
|
209
|
+
supportedNetworks: ["visa", "masterCard", "girocard"],
|
|
210
|
+
buttonStyle: "black",
|
|
211
|
+
buttonType: "pay",
|
|
212
|
+
requestPayerName: false,
|
|
213
|
+
requestBillingAddress: false,
|
|
214
|
+
requestPayerEmail: false,
|
|
215
|
+
requestPayerPhone: false,
|
|
216
|
+
requestShipping: false,
|
|
217
|
+
shippingType: "shipping"
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|