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
|
@@ -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
|
-
|
|
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
package/server/bootstrap.js
CHANGED
package/server/config/index.js
CHANGED
|
@@ -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
|
});
|
package/server/routes/index.js
CHANGED
|
@@ -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[
|
|
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";
|