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
@@ -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
+
@@ -1,27 +1,4 @@
1
- /**
2
- * Payment Utils - Universal functions for different payment methods and operations
3
- * Based on Payone v1 API Documentation
4
- *
5
- * This file contains all necessary parameters and validations for:
6
- * - Preauthorization
7
- * - Authorization
8
- * - Capture
9
- * - Refund
10
- *
11
- * Supported Payment Methods:
12
- * - Credit Card (cc)
13
- * - PayPal (wlt)
14
- * - Google Pay (gpp)
15
- * - Apple Pay (apl)
16
- * - Sofort Banking (sb)
17
- * - SEPA Direct Debit (elv)
18
- */
19
1
 
20
- /**
21
- * Generate order reference number
22
- * @param {number} sequence - Sequence number (default: 1000)
23
- * @returns {string} Generated order reference (format: ORD-XXXXX-XXXX)
24
- */
25
2
  export function generateLagOrderNumber(sequence = 1000) {
26
3
  const paddedSequence = sequence.toString().padStart(5, '0');
27
4
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
@@ -32,12 +9,7 @@ export function generateLagOrderNumber(sequence = 1000) {
32
9
  return `ORD-${paddedSequence}-${randomPart}`;
33
10
  }
34
11
 
35
- /**
36
- * Get base parameters for all payment methods
37
- * Based on Payone v1 API Documentation
38
- * @param {Object} options - Base options
39
- * @returns {Object} Base parameters with all required fields
40
- */
12
+
41
13
  export const getBaseParams = (options = {}) => {
42
14
  const {
43
15
  amount,
@@ -106,13 +78,7 @@ export const getBaseParams = (options = {}) => {
106
78
  };
107
79
  };
108
80
 
109
- /**
110
- * Get payment method specific parameters
111
- * Based on Payone v1 API Documentation
112
- * @param {string} paymentMethod - Payment method (cc, wlt, sb, elv)
113
- * @param {Object} options - Additional options
114
- * @returns {Object} Payment method specific parameters
115
- */
81
+
116
82
  export const getPaymentMethodParams = (paymentMethod, options = {}) => {
117
83
  const {
118
84
  cardType,
@@ -191,12 +157,25 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
191
157
  return googlePayParams;
192
158
 
193
159
  case "apl": // Apple Pay
194
- return {
160
+ const applePayParams = {
195
161
  clearingtype: "wlt",
196
162
  wallettype: "APL", // Apple Pay
197
163
  ...getShippingParams()
198
164
  };
199
165
 
166
+ if (options.applePayToken) {
167
+ const gatewayMerchantId = options.settings?.mid || options.settings?.portalid || '';
168
+ applePayParams["add_paydata[paymentmethod_token_data]"] = options.applePayToken;
169
+ applePayParams["add_paydata[paymentmethod]"] = "APL";
170
+ applePayParams["add_paydata[paymentmethod_type]"] = "APPLEPAY";
171
+ applePayParams["add_paydata[gatewayid]"] = "payonegmbh";
172
+ if (gatewayMerchantId) {
173
+ applePayParams["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
174
+ }
175
+ }
176
+
177
+ return applePayParams;
178
+
200
179
  case "sb": // Sofort Banking
201
180
  return {
202
181
  clearingtype: "sb",
@@ -225,13 +204,7 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
225
204
  }
226
205
  };
227
206
 
228
- /**
229
- * Get preauthorization parameters for specific payment method
230
- * Based on Payone v1 API Documentation
231
- * @param {string} paymentMethod - Payment method
232
- * @param {Object} options - Options including amount, reference, etc.
233
- * @returns {Object} Complete preauthorization parameters
234
- */
207
+
235
208
  export const getPreauthorizationParams = (paymentMethod, options = {}) => {
236
209
  const baseParams = getBaseParams(options);
237
210
  const methodParams = getPaymentMethodParams(paymentMethod, options);
@@ -251,13 +224,7 @@ export const getPreauthorizationParams = (paymentMethod, options = {}) => {
251
224
  return params;
252
225
  };
253
226
 
254
- /**
255
- * Get authorization parameters for specific payment method
256
- * Based on Payone v1 API Documentation
257
- * @param {string} paymentMethod - Payment method
258
- * @param {Object} options - Options including amount, reference, etc.
259
- * @returns {Object} Complete authorization parameters
260
- */
227
+
261
228
  export const getAuthorizationParams = (paymentMethod, options = {}) => {
262
229
  const baseParams = getBaseParams(options);
263
230
  const methodParams = getPaymentMethodParams(paymentMethod, options);
@@ -277,13 +244,7 @@ export const getAuthorizationParams = (paymentMethod, options = {}) => {
277
244
  return params;
278
245
  };
279
246
 
280
- /**
281
- * Get capture parameters for specific payment method
282
- * Based on Payone v1 API Documentation
283
- * @param {string} paymentMethod - Payment method
284
- * @param {Object} options - Options including txid, amount, captureMode, etc.
285
- * @returns {Object} Complete capture parameters
286
- */
247
+
287
248
  export const getCaptureParams = (paymentMethod, options = {}) => {
288
249
  const {
289
250
  txid,
@@ -339,13 +300,7 @@ export const getCaptureParams = (paymentMethod, options = {}) => {
339
300
  };
340
301
  };
341
302
 
342
- /**
343
- * Get refund parameters for specific payment method
344
- * Based on Payone v1 API Documentation
345
- * @param {string} paymentMethod - Payment method
346
- * @param {Object} options - Options including txid, amount, sequencenumber, etc.
347
- * @returns {Object} Complete refund parameters
348
- */
303
+
349
304
  export const getRefundParams = (paymentMethod, options = {}) => {
350
305
  const {
351
306
  txid,
@@ -398,11 +353,7 @@ export const getRefundParams = (paymentMethod, options = {}) => {
398
353
  };
399
354
  };
400
355
 
401
- /**
402
- * Get payment method display name
403
- * @param {string} paymentMethod - Payment method code
404
- * @returns {string} Display name
405
- */
356
+
406
357
  export const getPaymentMethodDisplayName = (paymentMethod) => {
407
358
  const displayNames = {
408
359
  cc: "Credit Card (Visa, Mastercard)",
@@ -416,10 +367,7 @@ export const getPaymentMethodDisplayName = (paymentMethod) => {
416
367
  return displayNames[paymentMethod] || "Unknown Payment Method";
417
368
  };
418
369
 
419
- /**
420
- * Get payment method options for dropdown
421
- * @returns {Array} Array of payment method options
422
- */
370
+
423
371
  export const getPaymentMethodOptions = () => {
424
372
  return [
425
373
  { value: "cc", label: "Credit Card (Visa, Mastercard)" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-payone-provider",
3
- "version": "1.4.2",
3
+ "version": "1.5.2",
4
4
  "description": "Strapi plugin for Payone payment gateway integration",
5
5
  "license": "MIT",
6
6
  "maintainers": [
@@ -19,7 +19,11 @@ module.exports = async ({ strapi }) => {
19
19
  mid: "",
20
20
  key: "",
21
21
  mode: "test",
22
- api_version: "3.10"
22
+ api_version: "3.10",
23
+ merchantName: "",
24
+ displayName: "",
25
+ domainName: "",
26
+ merchantIdentifier: ""
23
27
  }
24
28
  });
25
29
  }
@@ -10,7 +10,11 @@ module.exports = {
10
10
  mid: "",
11
11
  key: "",
12
12
  mode: "test",
13
- api_version: "3.10"
13
+ api_version: "3.10",
14
+ merchantName: "",
15
+ displayName: "",
16
+ domainName: "",
17
+ merchantIdentifier: ""
14
18
  }
15
19
  },
16
20
  validator(config) {
@@ -176,5 +176,15 @@ module.exports = ({ strapi }) => ({
176
176
  strapi.log.error("3DS callback error:", error);
177
177
  handleError(ctx, error);
178
178
  }
179
+ },
180
+
181
+ async validateApplePayMerchant(ctx) {
182
+ try {
183
+ const params = ctx.request.body;
184
+ const result = await getPayoneService(strapi).validateApplePayMerchant(params);
185
+ ctx.body = { data: result };
186
+ } catch (error) {
187
+ handleError(ctx, error);
188
+ }
179
189
  }
180
190
  });
@@ -75,6 +75,14 @@ module.exports = {
75
75
  config: {
76
76
  policies: ["admin::isAuthenticatedAdmin"]
77
77
  }
78
+ },
79
+ {
80
+ method: "POST",
81
+ path: "/validate-apple-pay-merchant",
82
+ handler: "payone.validateApplePayMerchant",
83
+ config: {
84
+ policies: ["admin::isAuthenticatedAdmin"]
85
+ }
78
86
  }
79
87
  ]
80
88
  },
@@ -144,6 +152,15 @@ module.exports = {
144
152
  policies: ["plugin::strapi-plugin-payone-provider.is-auth"],
145
153
  auth: false
146
154
  }
155
+ },
156
+ {
157
+ method: "POST",
158
+ path: "/validate-apple-pay-merchant",
159
+ handler: "payone.validateApplePayMerchant",
160
+ config: {
161
+ policies: ["plugin::strapi-plugin-payone-provider.is-auth"],
162
+ auth: false
163
+ }
147
164
  }
148
165
  ]
149
166
  }
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+
3
+ const axios = require("axios");
4
+ const { buildClientRequestParams, toFormData } = require("../utils/requestBuilder");
5
+ const { getSettings, validateSettings } = require("./settingsService");
6
+
7
+ const POST_GATEWAY_URL = "https://api.pay1.de/post-gateway/";
8
+
9
+ /**
10
+ * Initialize Apple Pay session with Payone
11
+ * According to Payone documentation:
12
+ * https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
13
+ *
14
+ * Request: genericpayment
15
+ * Required parameters:
16
+ * - request="genericpayment"
17
+ * - clearingtype="wlt"
18
+ * - wallettype="APL"
19
+ * - add_paydata[action]="init_applepay_session"
20
+ * - add_paydata[display_name]="Store Name"
21
+ * - add_paydata[domain_name]="yourdomain.com"
22
+ */
23
+ const initializeApplePaySession = async (strapi, params) => {
24
+ try {
25
+ strapi.log.info("[Apple Pay] Initializing Apple Pay session with Payone");
26
+ strapi.log.info("[Apple Pay] Request params:", JSON.stringify(params, null, 2));
27
+
28
+ const settings = await getSettings(strapi);
29
+
30
+ if (!validateSettings(settings)) {
31
+ strapi.log.error("[Apple Pay] Payone settings not configured");
32
+ throw new Error("Payone settings not configured");
33
+ }
34
+
35
+ strapi.log.info("[Apple Pay] Settings loaded:", {
36
+ mode: settings.mode,
37
+ mid: settings.mid,
38
+ portalid: settings.portalid,
39
+ hasKey: !!settings.key
40
+ });
41
+
42
+ const {
43
+ displayName,
44
+ domainName,
45
+ mid,
46
+ portalid
47
+ } = params;
48
+
49
+ // Get merchant data from settings (test or live mode)
50
+ const merchantName = displayName || settings.merchantName || settings.displayName || "Test Store";
51
+ const merchantId = mid || settings.mid || settings.merchantIdentifier;
52
+ const portalId = portalid || settings.portalid;
53
+ const accountId = settings.aid;
54
+ const apiKey = settings.key;
55
+ const mode = settings.mode || "test"; // test or live
56
+
57
+ // Get domain from params or settings or server config
58
+ const domain = domainName || settings.domainName ||
59
+ (strapi.config.get("server.url") ? new URL(strapi.config.get("server.url")).hostname : null) ||
60
+ "localhost";
61
+
62
+ // Build request parameters for Apple Pay session initialization
63
+ // According to Payone documentation: request="genericpayment"
64
+ const requestParams = {
65
+ request: "genericpayment",
66
+ mid: merchantId,
67
+ aid: accountId,
68
+ portalid: portalId,
69
+ key: apiKey,
70
+ mode: mode, // Use test or live mode from settings
71
+ clearingtype: "wlt",
72
+ wallettype: "APL",
73
+ currency: "EUR", // Default, can be overridden
74
+ "add_paydata[action]": "init_applepay_session",
75
+ "add_paydata[display_name]": merchantName,
76
+ "add_paydata[domain_name]": domain
77
+ };
78
+
79
+ strapi.log.info("[Apple Pay] Sending request to Payone:", {
80
+ url: POST_GATEWAY_URL,
81
+ mode: mode,
82
+ merchantName: merchantName,
83
+ domain: domain,
84
+ merchantId: merchantId,
85
+ portalId: portalId
86
+ });
87
+
88
+ const formData = toFormData(requestParams);
89
+
90
+ const response = await axios.post(POST_GATEWAY_URL, formData, {
91
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
92
+ timeout: 30000
93
+ });
94
+
95
+ strapi.log.info("[Apple Pay] Payone response received:", {
96
+ status: response.status,
97
+ statusText: response.statusText
98
+ });
99
+
100
+ // Parse response
101
+ const responseData = parseResponse(response.data, strapi.log);
102
+
103
+ strapi.log.info("[Apple Pay] Session initialization response:", JSON.stringify(responseData, null, 2));
104
+ strapi.log.info("[Apple Pay] Response status:", responseData.status || responseData.Status);
105
+
106
+ if (responseData.errorcode || responseData.ErrorCode) {
107
+ strapi.log.warn("[Apple Pay] Response contains error:", {
108
+ errorcode: responseData.errorcode || responseData.ErrorCode,
109
+ errormessage: responseData.errormessage || responseData.ErrorMessage
110
+ });
111
+ }
112
+
113
+ return responseData;
114
+ } catch (error) {
115
+ strapi.log.error("[Apple Pay] Session initialization error:", {
116
+ message: error.message,
117
+ stack: error.stack,
118
+ response: error.response?.data
119
+ });
120
+ throw error;
121
+ }
122
+ };
123
+
124
+ /**
125
+ * Validate Apple Pay merchant with Payone
126
+ * This is called when Apple Pay requests merchant validation
127
+ */
128
+ const validateApplePayMerchant = async (strapi, params) => {
129
+ try {
130
+ strapi.log.info("[Apple Pay] Validating merchant with Payone");
131
+ strapi.log.info("[Apple Pay] Validation params:", JSON.stringify({
132
+ validationURL: params.validationURL,
133
+ domain: params.domain,
134
+ displayName: params.displayName,
135
+ mid: params.mid,
136
+ portalid: params.portalid
137
+ }, null, 2));
138
+
139
+ const settings = await getSettings(strapi);
140
+
141
+ if (!validateSettings(settings)) {
142
+ strapi.log.error("[Apple Pay] Payone settings not configured for merchant validation");
143
+ throw new Error("Payone settings not configured");
144
+ }
145
+
146
+ const {
147
+ validationURL,
148
+ mid,
149
+ portalid,
150
+ domain,
151
+ displayName
152
+ } = params;
153
+
154
+ // Get merchant data from settings (test or live mode)
155
+ const merchantName = displayName || settings.merchantName || settings.displayName || "Test Store";
156
+ const merchantId = mid || settings.mid || settings.merchantIdentifier;
157
+ const portalId = portalid || settings.portalid;
158
+
159
+ // Get domain from params or settings or server config
160
+ const domainName = domain || settings.domainName ||
161
+ (strapi.config.get("server.url") ? new URL(strapi.config.get("server.url")).hostname : null) ||
162
+ "localhost";
163
+
164
+ // For Payone integration without developer account,
165
+ // Payone handles merchant validation
166
+ // We need to initialize the session first
167
+ const sessionParams = {
168
+ displayName: merchantName,
169
+ domainName: domainName,
170
+ mid: merchantId,
171
+ portalid: portalId
172
+ };
173
+
174
+ strapi.log.info("[Apple Pay] Initializing session with params:", JSON.stringify(sessionParams, null, 2));
175
+
176
+ // Initialize Apple Pay session with Payone
177
+ const sessionResponse = await initializeApplePaySession(strapi, sessionParams);
178
+
179
+ strapi.log.info("[Apple Pay] Session initialization result:", {
180
+ status: sessionResponse.status || sessionResponse.Status,
181
+ hasMerchantIdentifier: !!(sessionResponse.merchantIdentifier || sessionResponse.merchantSessionIdentifier)
182
+ });
183
+
184
+ // If session initialization is successful, return merchant session
185
+ // Payone will provide the merchant identifier and validation data
186
+ if (sessionResponse.status === "APPROVED" || sessionResponse.status === "REDIRECT") {
187
+ strapi.log.info("[Apple Pay] Session approved, creating merchant session object");
188
+ // Get merchant identifier from Payone response or settings
189
+ const merchantIdentifier = sessionResponse.merchantIdentifier ||
190
+ sessionResponse.merchantSessionIdentifier ||
191
+ settings.merchantIdentifier ||
192
+ settings.mid ||
193
+ settings.portalid ||
194
+ `merchant.${domainName}`;
195
+
196
+ // Return merchant session object
197
+ // In a real implementation, you would get this from Payone's response
198
+ const merchantSession = {
199
+ epochTimestamp: Date.now(),
200
+ expiresAt: Date.now() + (5 * 60 * 1000), // 5 minutes
201
+ merchantSessionIdentifier: sessionResponse.merchantSessionIdentifier || `merchant.${domainName}`,
202
+ nonce: sessionResponse.nonce || generateNonce(),
203
+ merchantIdentifier: merchantIdentifier,
204
+ domainName: domainName,
205
+ displayName: merchantName
206
+ };
207
+
208
+ strapi.log.info("[Apple Pay] Merchant session created:", {
209
+ merchantIdentifier: merchantSession.merchantIdentifier,
210
+ domainName: merchantSession.domainName,
211
+ expiresAt: new Date(merchantSession.expiresAt).toISOString()
212
+ });
213
+
214
+ return merchantSession;
215
+ }
216
+
217
+ // If initialization failed, return empty object
218
+ // Payment Request API will handle it
219
+ strapi.log.warn("[Apple Pay] Session initialization failed, returning empty object");
220
+ return {};
221
+ } catch (error) {
222
+ strapi.log.error("[Apple Pay] Merchant validation error:", {
223
+ message: error.message,
224
+ stack: error.stack,
225
+ response: error.response?.data
226
+ });
227
+ // Return empty object on error - Payone will handle validation
228
+ return {};
229
+ }
230
+ };
231
+
232
+ /**
233
+ * Parse Payone response
234
+ */
235
+ const parseResponse = (responseData, logger) => {
236
+ if (typeof responseData === 'string') {
237
+ // Parse form-encoded response
238
+ const params = new URLSearchParams(responseData);
239
+ const parsed = {};
240
+ for (const [key, value] of params.entries()) {
241
+ parsed[key] = value;
242
+ }
243
+ return parsed;
244
+ }
245
+ return responseData;
246
+ };
247
+
248
+ /**
249
+ * Generate nonce for merchant session
250
+ */
251
+ const generateNonce = () => {
252
+ return Math.random().toString(36).substring(2, 15) +
253
+ Math.random().toString(36).substring(2, 15);
254
+ };
255
+
256
+ module.exports = {
257
+ initializeApplePaySession,
258
+ validateApplePayMerchant
259
+ };
260
+
261
+
@@ -4,6 +4,7 @@ const settingsService = require("./settingsService");
4
4
  const transactionService = require("./transactionService");
5
5
  const paymentService = require("./paymentService");
6
6
  const testConnectionService = require("./testConnectionService");
7
+ const applePayService = require("./applePayService");
7
8
 
8
9
  /**
9
10
  * Main Payone service - aggregates all sub-services
@@ -52,5 +53,14 @@ module.exports = ({ strapi }) => ({
52
53
  // 3D Secure callback handler
53
54
  async handle3DSCallback(callbackData, resultType) {
54
55
  return await paymentService.handle3DSCallback(strapi, callbackData, resultType);
56
+ },
57
+
58
+ // Apple Pay
59
+ async validateApplePayMerchant(params) {
60
+ return await applePayService.validateApplePayMerchant(strapi, params);
61
+ },
62
+
63
+ async initializeApplePaySession(params) {
64
+ return await applePayService.initializeApplePaySession(strapi, params);
55
65
  }
56
66
  });
@@ -84,11 +84,28 @@ const addPaymentMethodParams = (params, logger) => {
84
84
  }
85
85
  });
86
86
 
87
+ // Handle Apple Pay token if present
88
+ if (updated.applePayToken || updated["add_paydata[paymentmethod_token_data]"]) {
89
+ const token = updated.applePayToken || updated["add_paydata[paymentmethod_token_data]"];
90
+ const gatewayMerchantId = updated.mid || updated.portalid || '';
91
+
92
+ updated["add_paydata[paymentmethod_token_data]"] = token;
93
+ updated["add_paydata[paymentmethod]"] = "APL";
94
+ updated["add_paydata[paymentmethod_type]"] = "APPLEPAY";
95
+ updated["add_paydata[gatewayid]"] = "payonegmbh";
96
+ if (gatewayMerchantId) {
97
+ updated["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
98
+ }
99
+
100
+ // Remove applePayToken from params as it's now in add_paydata
101
+ delete updated.applePayToken;
102
+ }
103
+
87
104
  // Ensure wallettype is set for wallet payments
88
105
  if (updated.clearingtype === "wlt" && !updated.wallettype) {
89
- if (clearingtype === "gpp" || updated.paymentMethod === "gpp" || updated["add_paydata[paymentmethod_token_data]"]) {
106
+ if (clearingtype === "gpp" || updated.paymentMethod === "gpp" || (updated["add_paydata[paymentmethod]"] === "GGP")) {
90
107
  updated.wallettype = "GGP";
91
- } else if (clearingtype === "apl" || updated.paymentMethod === "apl") {
108
+ } else if (clearingtype === "apl" || updated.paymentMethod === "apl" || (updated["add_paydata[paymentmethod]"] === "APL")) {
92
109
  updated.wallettype = "APL";
93
110
  } else {
94
111
  updated.wallettype = "PPE";