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.
Files changed (32) hide show
  1. package/README.md +179 -22
  2. package/admin/src/pages/App/components/AppHeader.js +22 -4
  3. package/admin/src/pages/App/components/AppTabs.js +25 -1
  4. package/admin/src/pages/App/components/ApplePayButton.js +737 -0
  5. package/admin/src/pages/App/components/ApplePayConfig.js +364 -0
  6. package/admin/src/pages/App/components/ApplePayConfigPanel.js +81 -0
  7. package/admin/src/pages/App/components/ConfigurationPanel.js +19 -3
  8. package/admin/src/pages/App/components/DocsPanel.js +1057 -0
  9. package/admin/src/pages/App/components/GooglePayConfig.js +217 -0
  10. package/admin/src/pages/App/components/GooglePayConfigPanel.js +82 -0
  11. package/admin/src/pages/App/components/GooglePaybutton.js +1 -1
  12. package/admin/src/pages/App/components/PaymentActionsPanel.js +24 -6
  13. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.js +60 -4
  14. package/admin/src/pages/App/components/paymentActions/CaptureForm.js +1 -0
  15. package/admin/src/pages/App/components/paymentActions/CardDetailsInput.js +18 -16
  16. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.js +106 -2
  17. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.js +64 -4
  18. package/admin/src/pages/App/components/paymentActions/RefundForm.js +1 -0
  19. package/admin/src/pages/App/index.js +70 -1
  20. package/admin/src/pages/hooks/usePaymentActions.js +13 -2
  21. package/admin/src/pages/hooks/useSettings.js +2 -0
  22. package/admin/src/pages/utils/applePayConstants.js +222 -0
  23. package/admin/src/pages/utils/googlePayConstants.js +79 -0
  24. package/admin/src/pages/utils/paymentUtils.js +22 -74
  25. package/package.json +1 -1
  26. package/server/bootstrap.js +5 -1
  27. package/server/config/index.js +5 -1
  28. package/server/controllers/payone.js +10 -0
  29. package/server/routes/index.js +17 -0
  30. package/server/services/applePayService.js +261 -0
  31. package/server/services/payone.js +10 -0
  32. package/server/utils/paymentMethodParams.js +19 -2
package/README.md CHANGED
@@ -85,6 +85,159 @@ After installation, you need to configure your Payone credentials:
85
85
  5. Click **"Test Connection"** to verify your credentials
86
86
  6. Click **"Save Configuration"** to store your settings
87
87
 
88
+ ### Apple Pay Configuration
89
+
90
+ To configure Apple Pay settings:
91
+
92
+ 1. Navigate to **Payone Provider** in the sidebar menu
93
+ 2. Go to **Payment Actions** tab
94
+ 3. Select **Apple Pay** as the payment method
95
+ 4. Click on the Apple Pay configuration link: `/plugins/strapi-plugin-payone-provider/apple-pay-config`
96
+ 5. Configure the following settings:
97
+ - **Country Code**: Select the country where your business operates
98
+ - **Currency Code**: Select the currency for transactions
99
+ - **Supported Networks**: Select payment card networks (Visa, Mastercard, Amex, etc.)
100
+ - **Merchant Capabilities**: Select payment capabilities (3D Secure is recommended)
101
+ - **Button Style & Type**: Customize the Apple Pay button appearance
102
+ 6. Click **"Save Apple Pay Configuration"** to store your settings
103
+
104
+ > ⚠️ **Important**: Apple Pay requires a registered domain with HTTPS. It does NOT work on localhost. For testing, use a production domain with HTTPS or test on a device with Safari (iOS/macOS).
105
+
106
+ #### Apple Pay Domain Verification File (.well-known)
107
+
108
+ Apple Pay requires a domain verification file to be placed on your server. This file must be accessible at:
109
+
110
+ ```
111
+ https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
112
+ ```
113
+
114
+ **Steps to set up the domain verification file:**
115
+
116
+ 1. **Download the file from Payone:**
117
+
118
+ - Download the domain verification file from Payone documentation: [https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev](https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev)
119
+ - Alternatively, log into your Payone Merchant Interface (PMI)
120
+ - Navigate to **Configuration** → **Payment Portals** → **Apple Pay**
121
+ - Download the `apple-developer-merchantid-domain-association` file
122
+
123
+ 2. **Place the file in Strapi:**
124
+
125
+ - Create the directory: `public/.well-known/` (if it doesn't exist)
126
+ - Place the file at: `public/.well-known/apple-developer-merchantid-domain-association`
127
+
128
+ 3. **Place the file in your Frontend (if separate):**
129
+
130
+ - Create the directory: `public/.well-known/` (if it doesn't exist)
131
+ - Place the file at: `public/.well-known/apple-developer-merchantid-domain-association`
132
+
133
+ 4. **Verify accessibility:**
134
+ - The file must be accessible via HTTPS at: `https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association`
135
+ - Test by visiting the URL in your browser - you should see the file content
136
+
137
+ > ⚠️ **Critical**: Without this file, Apple Pay will NOT work on your domain. The file must be accessible via HTTPS and must match exactly what Payone provides.
138
+
139
+ #### Middleware Configuration for Apple Pay
140
+
141
+ Apple Pay requires Content Security Policy (CSP) configuration in `config/middlewares.js` to allow Apple Pay scripts. Without this configuration, Apple Pay will NOT work.
142
+
143
+ **Required CSP directives:**
144
+
145
+ ```javascript
146
+ module.exports = [
147
+ "strapi::logger",
148
+ "strapi::errors",
149
+ {
150
+ name: "strapi::security",
151
+ config: {
152
+ contentSecurityPolicy: {
153
+ useDefaults: true,
154
+ directives: {
155
+ "script-src": [
156
+ "'self'",
157
+ "'unsafe-inline'",
158
+ "'unsafe-eval'",
159
+ "https://applepay.cdn-apple.com", // Apple Pay SDK
160
+ "https://www.apple.com", // Apple Pay manifest
161
+ ],
162
+ "connect-src": [
163
+ "'self'",
164
+ "https:",
165
+ "https://applepay.cdn-apple.com", // Apple Pay API
166
+ "https://www.apple.com", // Apple Pay manifest
167
+ ],
168
+ "frame-src": [
169
+ "'self'",
170
+ "https://applepay.cdn-apple.com", // Apple Pay iframe
171
+ ],
172
+ },
173
+ },
174
+ },
175
+ },
176
+ // ... other middlewares
177
+ ];
178
+ ```
179
+
180
+ > ⚠️ **Important**: Without this middleware configuration, Apple Pay scripts will be blocked and Apple Pay will NOT work!
181
+
182
+ ### Google Pay Configuration
183
+
184
+ To configure Google Pay settings:
185
+
186
+ 1. Navigate to **Payone Provider** in the sidebar menu
187
+ 2. Go to **Payment Actions** tab
188
+ 3. Select **Google Pay** as the payment method
189
+ 4. Click on the Google Pay configuration link: `/plugins/strapi-plugin-payone-provider/google-pay-config`
190
+ 5. Configure the following settings:
191
+ - **Country Code**: Select the country where your business operates
192
+ - **Currency Code**: Select the currency for transactions
193
+ - **Merchant Name**: Enter your business name as it will appear in Google Pay
194
+ - **Allowed Card Networks**: Select payment card networks (Mastercard, Visa, Amex, etc.)
195
+ - **Allowed Authentication Methods**: Select authentication methods (PAN Only, 3D Secure)
196
+ 6. Click **"Save Google Pay Configuration"** to store your settings
197
+
198
+ > ℹ️ **Note**: The Gateway Merchant ID will be automatically obtained from your Payone Merchant ID (MID) or Portal ID configured in the main Configuration tab.
199
+
200
+ #### Middleware Configuration for Google Pay
201
+
202
+ Google Pay requires Content Security Policy (CSP) configuration in `config/middlewares.js` to allow Google Pay scripts. Without this configuration, Google Pay will NOT work.
203
+
204
+ **Required CSP directives:**
205
+
206
+ ```javascript
207
+ module.exports = [
208
+ "strapi::logger",
209
+ "strapi::errors",
210
+ {
211
+ name: "strapi::security",
212
+ config: {
213
+ contentSecurityPolicy: {
214
+ useDefaults: true,
215
+ directives: {
216
+ "script-src": [
217
+ "'self'",
218
+ "'unsafe-inline'",
219
+ "'unsafe-eval'",
220
+ "https://pay.google.com", // Google Pay SDK
221
+ ],
222
+ "connect-src": [
223
+ "'self'",
224
+ "https:",
225
+ "https://pay.google.com", // Google Pay API
226
+ ],
227
+ "frame-src": [
228
+ "'self'",
229
+ "https://pay.google.com", // Google Pay iframe
230
+ ],
231
+ },
232
+ },
233
+ },
234
+ },
235
+ // ... other middlewares
236
+ ];
237
+ ```
238
+
239
+ > ⚠️ **Important**: Without this middleware configuration, Google Pay scripts will be blocked and Google Pay will NOT work!
240
+
88
241
  ## 🚀 Getting Started
89
242
 
90
243
  ### 1. Test Your Connection
@@ -590,7 +743,7 @@ Google Pay integration requires obtaining an encrypted payment token from Google
590
743
 
591
744
  ```javascript
592
745
  const paymentsClient = new google.payments.api.PaymentsClient({
593
- environment: 'TEST', // or "PRODUCTION" for live
746
+ environment: "TEST", // or "PRODUCTION" for live
594
747
  });
595
748
 
596
749
  const baseRequest = {
@@ -598,19 +751,19 @@ const baseRequest = {
598
751
  apiVersionMinor: 0,
599
752
  };
600
753
 
601
- const allowedCardNetworks = ['MASTERCARD', 'VISA'];
602
- const allowedAuthMethods = ['PAN_ONLY', 'CRYPTOGRAM_3DS'];
754
+ const allowedCardNetworks = ["MASTERCARD", "VISA"];
755
+ const allowedAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
603
756
 
604
757
  const tokenizationSpecification = {
605
- type: 'PAYMENT_GATEWAY',
758
+ type: "PAYMENT_GATEWAY",
606
759
  parameters: {
607
- gateway: 'payonegmbh',
608
- gatewayMerchantId: 'YOUR_PAYONE_MERCHANT_ID', // Use your Payone MID or Portal ID
760
+ gateway: "payonegmbh",
761
+ gatewayMerchantId: "YOUR_PAYONE_MERCHANT_ID", // Use your Payone MID or Portal ID
609
762
  },
610
763
  };
611
764
 
612
765
  const cardPaymentMethod = {
613
- type: 'CARD',
766
+ type: "CARD",
614
767
  parameters: {
615
768
  allowedCardNetworks,
616
769
  allowedAuthMethods,
@@ -634,45 +787,47 @@ paymentsClient.isReadyToPay(isReadyToPayRequest).then(function (response) {
634
787
  const paymentDataRequest = Object.assign({}, baseRequest);
635
788
  paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod];
636
789
  paymentDataRequest.transactionInfo = {
637
- totalPriceStatus: 'FINAL',
638
- totalPrice: '10.00',
639
- currencyCode: 'EUR',
790
+ totalPriceStatus: "FINAL",
791
+ totalPrice: "10.00",
792
+ currencyCode: "EUR",
640
793
  };
641
794
  paymentDataRequest.merchantInfo = {
642
- merchantId: 'YOUR_GOOGLE_MERCHANT_ID', // Optional: from Google Console
643
- merchantName: 'Your Merchant Name',
795
+ merchantId: "YOUR_GOOGLE_MERCHANT_ID", // Optional: from Google Console
796
+ merchantName: "Your Merchant Name",
644
797
  };
645
798
 
646
799
  const button = paymentsClient.createButton({
647
800
  onClick: async () => {
648
801
  try {
649
- const paymentData = await paymentsClient.loadPaymentData(paymentDataRequest);
802
+ const paymentData = await paymentsClient.loadPaymentData(
803
+ paymentDataRequest
804
+ );
650
805
  const token = paymentData.paymentMethodData.tokenizationData.token;
651
806
 
652
807
  // Token is a JSON string, encode it to Base64 for Payone
653
808
  const base64Token = btoa(unescape(encodeURIComponent(token)));
654
809
 
655
810
  // Send to your backend
656
- await fetch('/api/strapi-plugin-payone-provider/preauthorization', {
657
- method: 'POST',
811
+ await fetch("/api/strapi-plugin-payone-provider/preauthorization", {
812
+ method: "POST",
658
813
  headers: {
659
- 'Content-Type': 'application/json',
660
- Authorization: 'Bearer YOUR_TOKEN',
814
+ "Content-Type": "application/json",
815
+ Authorization: "Bearer YOUR_TOKEN",
661
816
  },
662
817
  body: JSON.stringify({
663
818
  amount: 1000,
664
- currency: 'EUR',
665
- reference: 'PAY1234567890ABCDEF',
819
+ currency: "EUR",
820
+ reference: "PAY1234567890ABCDEF",
666
821
  googlePayToken: base64Token,
667
822
  }),
668
823
  });
669
824
  } catch (error) {
670
- console.error('Google Pay error:', error);
825
+ console.error("Google Pay error:", error);
671
826
  }
672
827
  },
673
828
  });
674
829
 
675
- document.getElementById('google-pay-button').appendChild(button);
830
+ document.getElementById("google-pay-button").appendChild(button);
676
831
  ```
677
832
 
678
833
  **Token Format**
@@ -684,7 +839,9 @@ The token from Google Pay is a JSON string with the following structure:
684
839
  "signature": "MEUCIFr4ETGzv0uLZX3sR+i1ScARXnRBrncyYFDX/TI/VSLCAiEAvC/Q4dqXMQhwcSdg/ZvXj8+up0wXsfHja3V/6z48/vk=",
685
840
  "intermediateSigningKey": {
686
841
  "signedKey": "{\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7PWUi+e6WPUhNmTSQ2WN006oWlcWy0FtBWizw9sph1wvX9XcXUNRLcfcsmCBfI5IsKQkjAmYxpCSB+L5sIudLw\\u003d\\u003d\",\"keyExpiration\":\"1722393105282\"}",
687
- "signatures": ["MEUCIQCpU30A3g2pP93IBE5NxgO9ZcJlGF9YPzCZS7H4/IR1CQIgF6+I5t8olT8YsRDUcj7w3R1bvX4ZCcyFXE2+YXa+3H0="]
842
+ "signatures": [
843
+ "MEUCIQCpU30A3g2pP93IBE5NxgO9ZcJlGF9YPzCZS7H4/IR1CQIgF6+I5t8olT8YsRDUcj7w3R1bvX4ZCcyFXE2+YXa+3H0="
844
+ ]
688
845
  },
689
846
  "protocolVersion": "ECv2",
690
847
  "signedMessage": "{\"encryptedMessage\":\"...\",\"ephemeralPublicKey\":\"...\",\"tag\":\"...\"}"
@@ -1,22 +1,40 @@
1
1
  import React from "react";
2
2
  import { HeaderLayout, Box, Typography, Button } from "@strapi/design-system";
3
- import { Check } from "@strapi/icons";
3
+ import { Check, ArrowLeft } from "@strapi/icons";
4
+ import { useHistory, useLocation } from "react-router-dom";
5
+ import pluginId from "../../../pluginId";
4
6
 
5
7
  const AppHeader = ({ activeTab, isSaving, onSave }) => {
8
+ const history = useHistory();
9
+ const location = useLocation();
10
+ const isApplePayConfigPage = location.pathname.includes('/apple-pay-config');
11
+
6
12
  return (
7
13
  <HeaderLayout
8
14
  title={
9
15
  <Box>
10
16
  <Typography variant="alpha" as="h1" fontWeight="bold" className="payment-title">
11
- Payone Provider
17
+ {isApplePayConfigPage ? "Apple Pay Configuration" : "Payone Provider"}
12
18
  </Typography>
13
19
  <Typography variant="pi" marginTop={2} className="payment-subtitle">
14
- Configure your Payone integration and manage payment transactions
20
+ {isApplePayConfigPage
21
+ ? "Configure Apple Pay settings for your payment gateway"
22
+ : "Configure your Payone integration and manage payment transactions"
23
+ }
15
24
  </Typography>
16
25
  </Box>
17
26
  }
18
27
  primaryAction={
19
- activeTab === 0 ? (
28
+ isApplePayConfigPage ? (
29
+ <Button
30
+ onClick={() => history.push(`/plugins/${pluginId}`)}
31
+ startIcon={<ArrowLeft />}
32
+ size="L"
33
+ variant="secondary"
34
+ >
35
+ Back to Main
36
+ </Button>
37
+ ) : activeTab === 0 ? (
20
38
  <Button
21
39
  loading={isSaving}
22
40
  onClick={onSave}
@@ -1,8 +1,10 @@
1
1
  import React from "react";
2
2
  import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from "@strapi/design-system";
3
+ import pluginId from "../../../pluginId";
3
4
  import ConfigurationPanel from "./ConfigurationPanel";
4
5
  import HistoryPanel from "./HistoryPanel";
5
6
  import PaymentActionsPanel from "./PaymentActionsPanel";
7
+ import DocsPanel from "./DocsPanel";
6
8
 
7
9
  const AppTabs = ({
8
10
  activeTab,
@@ -30,8 +32,18 @@ const AppTabs = ({
30
32
  selectedTransaction,
31
33
  onTransactionSelect,
32
34
  // Payment actions props
33
- paymentActions
35
+ paymentActions,
36
+ history
34
37
  }) => {
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
+ };
35
47
  return (
36
48
  <TabGroup
37
49
  label="Payone Provider Tabs"
@@ -53,6 +65,11 @@ const AppTabs = ({
53
65
  >
54
66
  Payment Actions
55
67
  </Tab>
68
+ <Tab
69
+ className={`payment-tab ${activeTab === 3 ? 'payment-tab-active' : ''}`}
70
+ >
71
+ Documentation
72
+ </Tab>
56
73
  </Tabs>
57
74
  <TabPanels>
58
75
  <TabPanel>
@@ -115,6 +132,8 @@ const AppTabs = ({
115
132
  settings={settings}
116
133
  googlePayToken={paymentActions.googlePayToken}
117
134
  setGooglePayToken={paymentActions.setGooglePayToken}
135
+ applePayToken={paymentActions.applePayToken}
136
+ setApplePayToken={paymentActions.setApplePayToken}
118
137
  cardtype={paymentActions.cardtype}
119
138
  setCardtype={paymentActions.setCardtype}
120
139
  cardpan={paymentActions.cardpan}
@@ -123,8 +142,13 @@ const AppTabs = ({
123
142
  setCardexpiredate={paymentActions.setCardexpiredate}
124
143
  cardcvc2={paymentActions.cardcvc2}
125
144
  setCardcvc2={paymentActions.setCardcvc2}
145
+ onNavigateToConfig={handleNavigateToConfig}
126
146
  />
127
147
  </TabPanel>
148
+
149
+ <TabPanel>
150
+ <DocsPanel />
151
+ </TabPanel>
128
152
  </TabPanels>
129
153
  </TabGroup>
130
154
  );