strapi-plugin-payone-provider 5.7.24 → 5.7.26
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 +1191 -1191
- package/admin/src/components/Initializer/index.jsx +16 -16
- package/admin/src/components/PluginIcon/index.jsx +17 -17
- package/admin/src/index.js +57 -57
- package/admin/src/pages/App/components/AppHeader.jsx +45 -45
- package/admin/src/pages/App/components/AppTabs.jsx +105 -105
- package/admin/src/pages/App/components/ApplePayBtn.jsx +355 -355
- package/admin/src/pages/App/components/ApplePayConfig.jsx +357 -357
- package/admin/src/pages/App/components/DocsPanel.jsx +53 -53
- package/admin/src/pages/App/components/RenderInput.jsx +78 -78
- package/admin/src/pages/App/components/StatusBadge.jsx +87 -87
- package/admin/src/pages/App/components/icons/BankIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/ChevronDownIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/ChevronUpIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/CreditCardIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/ErrorIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/InfoIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/MarkCircle.jsx +19 -19
- package/admin/src/pages/App/components/icons/PaymentIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/PendingIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/PersonIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/SuccessIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/WalletIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/index.jsx +12 -12
- package/admin/src/pages/App/components/payment-actions/AuthorizationForm.jsx +334 -334
- package/admin/src/pages/App/components/payment-actions/CaptureForm.jsx +120 -120
- package/admin/src/pages/App/components/payment-actions/PaymentActionsPanel.jsx +183 -183
- package/admin/src/pages/App/components/payment-actions/PaymentMethodSelector.jsx +315 -315
- package/admin/src/pages/App/components/payment-actions/PaymentResult.jsx +129 -129
- package/admin/src/pages/App/components/payment-actions/PreauthorizationForm.jsx +273 -273
- package/admin/src/pages/App/components/payment-actions/RefundForm.jsx +114 -114
- package/admin/src/pages/App/components/transaction-history/ImportExportBar.jsx +153 -153
- package/admin/src/pages/App/components/transaction-history/details/TransactionHistoryItem.jsx +526 -526
- package/admin/src/pages/App/index.jsx +96 -96
- package/admin/src/pages/App/styles.css +176 -176
- package/admin/src/pages/constants/paymentConstants.js +71 -71
- package/admin/src/pages/hooks/use-system-theme.js +27 -27
- package/admin/src/pages/hooks/usePaymentActions.js +498 -498
- package/admin/src/pages/hooks/usePluginTranslations.js +12 -12
- package/admin/src/pages/hooks/useSettings.js +183 -183
- package/admin/src/pages/hooks/useTransactionHistory.js +148 -148
- package/admin/src/pages/utils/api.js +97 -97
- package/admin/src/pages/utils/applePayConstants.js +196 -196
- package/admin/src/pages/utils/formatTransactionData.js +15 -15
- package/admin/src/pages/utils/getInputComponent.jsx +200 -200
- package/admin/src/pages/utils/paymentUtils.js +661 -661
- package/admin/src/pages/utils/tooltipHelpers.js +18 -18
- package/admin/src/pages/utils/transactionTableUtils.js +71 -71
- package/admin/src/pluginId.js +9 -9
- package/admin/src/translations/de.json +235 -235
- package/admin/src/translations/en.json +235 -235
- package/admin/src/translations/fr.json +235 -235
- package/admin/src/translations/ru.json +235 -235
- package/admin/src/utils/prefixPluginTranslations.js +13 -13
- package/package.json +45 -45
- package/server/bootstrap.js +107 -107
- package/server/config/index.js +83 -83
- package/server/content-types/index.js +4 -4
- package/server/content-types/transactions/index.js +4 -4
- package/server/content-types/transactions/schema.json +86 -86
- package/server/controllers/index.js +7 -7
- package/server/controllers/payone.js +506 -451
- package/server/destroy.js +5 -5
- package/server/index.js +23 -23
- package/server/policies/index.js +7 -7
- package/server/policies/is-auth.js +29 -29
- package/server/policies/isSuperAdmin.js +20 -20
- package/server/register.js +5 -5
- package/server/routes/index.js +218 -218
- package/server/services/applePayService.js +295 -295
- package/server/services/index.js +9 -9
- package/server/services/paymentService.js +223 -223
- package/server/services/payone.js +78 -78
- package/server/services/settingsService.js +59 -59
- package/server/services/testConnectionService.js +115 -115
- package/server/services/transactionService.js +262 -262
- package/server/utils/csvTransactions.js +82 -82
- package/server/utils/normalize.js +39 -39
- package/server/utils/paymentMethodParams.js +288 -288
- package/server/utils/requestBuilder.js +100 -100
- package/server/utils/responseParser.js +141 -141
- package/strapi-admin.js +4 -4
- package/strapi-server.js +3 -3
|
@@ -1,661 +1,661 @@
|
|
|
1
|
-
export function getValidCardExpiryDate(cardexpiredate) {
|
|
2
|
-
const now = new Date();
|
|
3
|
-
const currentYear = now.getFullYear() % 100;
|
|
4
|
-
const currentMonth = now.getMonth() + 1;
|
|
5
|
-
|
|
6
|
-
if (!cardexpiredate || cardexpiredate.trim() === "") {
|
|
7
|
-
const nextYear = currentYear + 1;
|
|
8
|
-
const monthStr = String(currentMonth).padStart(2, '0');
|
|
9
|
-
return `${nextYear}${monthStr}`;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (!/^\d{4}$/.test(cardexpiredate)) {
|
|
13
|
-
const nextYear = currentYear + 1;
|
|
14
|
-
const monthStr = String(currentMonth).padStart(2, '0');
|
|
15
|
-
return `${nextYear}${monthStr}`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const year = parseInt(cardexpiredate.substring(0, 2), 10);
|
|
19
|
-
const month = parseInt(cardexpiredate.substring(2, 4), 10);
|
|
20
|
-
|
|
21
|
-
if (month < 1 || month > 12) {
|
|
22
|
-
const nextYear = currentYear + 1;
|
|
23
|
-
const monthStr = String(currentMonth).padStart(2, '0');
|
|
24
|
-
return `${nextYear}${monthStr}`;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const currentDate = new Date(2000 + currentYear, currentMonth - 1);
|
|
28
|
-
const expiryDate = new Date(2000 + year, month - 1);
|
|
29
|
-
|
|
30
|
-
if (expiryDate < currentDate) {
|
|
31
|
-
const nextYear = currentYear + 1;
|
|
32
|
-
const monthStr = String(currentMonth).padStart(2, '0');
|
|
33
|
-
return `${nextYear}${monthStr}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return cardexpiredate;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function generateLagOrderNumber(sequence = 1000) {
|
|
40
|
-
const paddedSequence = sequence.toString().padStart(5, '0');
|
|
41
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
42
|
-
let randomPart = '';
|
|
43
|
-
for (let i = 0; i < 4; i++) {
|
|
44
|
-
randomPart += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
45
|
-
}
|
|
46
|
-
return `ORD-${paddedSequence}-${randomPart}`;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export const getBaseParams = (options = {}) => {
|
|
51
|
-
const {
|
|
52
|
-
amount,
|
|
53
|
-
currency = "EUR",
|
|
54
|
-
reference,
|
|
55
|
-
customerid,
|
|
56
|
-
firstname = "John",
|
|
57
|
-
lastname = "Doe",
|
|
58
|
-
street = "Test Street 123",
|
|
59
|
-
zip = "12345",
|
|
60
|
-
city = "Test City",
|
|
61
|
-
country = "DE",
|
|
62
|
-
email = "test@example.com",
|
|
63
|
-
salutation = "Herr",
|
|
64
|
-
gender = "m",
|
|
65
|
-
telephonenumber = "01752345678",
|
|
66
|
-
ip = "127.0.0.1",
|
|
67
|
-
customer_is_present = "yes",
|
|
68
|
-
language = "de",
|
|
69
|
-
successurl = "https://www.example.com/success",
|
|
70
|
-
errorurl = "https://www.example.com/error",
|
|
71
|
-
backurl = "https://www.example.com/back"
|
|
72
|
-
} = options;
|
|
73
|
-
|
|
74
|
-
const generateCustomerId = () => {
|
|
75
|
-
const timestamp = Date.now().toString().slice(-10);
|
|
76
|
-
const random = Math.random().toString(36).substring(2, 6).toUpperCase();
|
|
77
|
-
const id = `${timestamp}${random}`.slice(0, 17);
|
|
78
|
-
return id;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
let finalCustomerId = customerid || generateCustomerId();
|
|
82
|
-
|
|
83
|
-
if (finalCustomerId && finalCustomerId.length > 17) {
|
|
84
|
-
finalCustomerId = finalCustomerId.slice(0, 17);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
amount: parseInt(amount),
|
|
89
|
-
currency: currency.toUpperCase(),
|
|
90
|
-
reference: reference || `REF-${Date.now()}`,
|
|
91
|
-
customerid: finalCustomerId,
|
|
92
|
-
firstname,
|
|
93
|
-
lastname,
|
|
94
|
-
street,
|
|
95
|
-
zip,
|
|
96
|
-
city,
|
|
97
|
-
country: country.toUpperCase(),
|
|
98
|
-
email,
|
|
99
|
-
salutation,
|
|
100
|
-
gender,
|
|
101
|
-
telephonenumber,
|
|
102
|
-
ip,
|
|
103
|
-
customer_is_present,
|
|
104
|
-
language,
|
|
105
|
-
successurl,
|
|
106
|
-
errorurl,
|
|
107
|
-
backurl
|
|
108
|
-
};
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
113
|
-
const {
|
|
114
|
-
cardType,
|
|
115
|
-
cardtype,
|
|
116
|
-
captureMode = "full",
|
|
117
|
-
cardpan,
|
|
118
|
-
cardexpiredate,
|
|
119
|
-
cardcvc2,
|
|
120
|
-
iban,
|
|
121
|
-
bic,
|
|
122
|
-
bankaccountholder,
|
|
123
|
-
shipping_firstname,
|
|
124
|
-
shipping_lastname,
|
|
125
|
-
shipping_street,
|
|
126
|
-
shipping_zip,
|
|
127
|
-
shipping_city,
|
|
128
|
-
shipping_country,
|
|
129
|
-
firstname,
|
|
130
|
-
lastname,
|
|
131
|
-
street,
|
|
132
|
-
zip,
|
|
133
|
-
city,
|
|
134
|
-
country
|
|
135
|
-
} = options;
|
|
136
|
-
|
|
137
|
-
const finalCardType = cardtype || cardType || "V";
|
|
138
|
-
|
|
139
|
-
const getShippingParams = () => ({
|
|
140
|
-
shipping_firstname: shipping_firstname || firstname || "John",
|
|
141
|
-
shipping_lastname: shipping_lastname || lastname || "Doe",
|
|
142
|
-
shipping_street: shipping_street || street || "Test Street 123",
|
|
143
|
-
shipping_zip: shipping_zip || zip || "12345",
|
|
144
|
-
shipping_city: shipping_city || city || "Test City",
|
|
145
|
-
shipping_country: (shipping_country || country || "DE").toUpperCase()
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
switch (paymentMethod) {
|
|
149
|
-
case "cc":
|
|
150
|
-
return {
|
|
151
|
-
clearingtype: "cc",
|
|
152
|
-
cardtype: finalCardType,
|
|
153
|
-
cardpan: cardpan || "4111111111111111",
|
|
154
|
-
cardexpiredate: getValidCardExpiryDate(cardexpiredate),
|
|
155
|
-
cardcvc2: cardcvc2 || "123"
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
case "wlt":
|
|
159
|
-
return {
|
|
160
|
-
clearingtype: "wlt",
|
|
161
|
-
wallettype: "PPE",
|
|
162
|
-
...getShippingParams()
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
case "gpp":
|
|
166
|
-
const googlePayParams = {
|
|
167
|
-
clearingtype: "wlt",
|
|
168
|
-
wallettype: "GGP",
|
|
169
|
-
...getShippingParams()
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
if (options.googlePayToken) {
|
|
173
|
-
const gatewayMerchantId = options.settings?.mid || options.settings?.portalid || '';
|
|
174
|
-
googlePayParams["add_paydata[paymentmethod_token_data]"] = options.googlePayToken;
|
|
175
|
-
googlePayParams["add_paydata[paymentmethod]"] = "GGP";
|
|
176
|
-
googlePayParams["add_paydata[paymentmethod_type]"] = "GOOGLEPAY";
|
|
177
|
-
googlePayParams["add_paydata[gatewayid]"] = "payonegmbh";
|
|
178
|
-
if (gatewayMerchantId) {
|
|
179
|
-
googlePayParams["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return googlePayParams;
|
|
184
|
-
|
|
185
|
-
case "apl":
|
|
186
|
-
const applePayParams = {
|
|
187
|
-
clearingtype: "wlt",
|
|
188
|
-
wallettype: "APL",
|
|
189
|
-
...getShippingParams()
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
if (options.applePayToken) {
|
|
193
|
-
const gatewayMerchantId = options.settings?.mid || options.settings?.portalid || '';
|
|
194
|
-
applePayParams["add_paydata[paymentmethod_token_data]"] = options.applePayToken;
|
|
195
|
-
applePayParams["add_paydata[paymentmethod]"] = "APL";
|
|
196
|
-
applePayParams["add_paydata[paymentmethod_type]"] = "APPLEPAY";
|
|
197
|
-
applePayParams["add_paydata[gatewayid]"] = "payonegmbh";
|
|
198
|
-
if (gatewayMerchantId) {
|
|
199
|
-
applePayParams["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return applePayParams;
|
|
204
|
-
|
|
205
|
-
case "sb":
|
|
206
|
-
return {
|
|
207
|
-
clearingtype: "sb",
|
|
208
|
-
bankcountry: "DE",
|
|
209
|
-
onlinebanktransfertype: "PNT"
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
case "elv":
|
|
213
|
-
return {
|
|
214
|
-
clearingtype: "elv",
|
|
215
|
-
bankcountry: "DE",
|
|
216
|
-
iban: iban || "DE89370400440532013000",
|
|
217
|
-
bic: bic || "COBADEFFXXX",
|
|
218
|
-
bankaccountholder: bankaccountholder || "John Doe"
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
default:
|
|
222
|
-
return {
|
|
223
|
-
clearingtype: "cc",
|
|
224
|
-
cardtype: "V",
|
|
225
|
-
cardpan: "4111111111111111",
|
|
226
|
-
cardexpiredate: "2512",
|
|
227
|
-
cardcvc2: "123"
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
export const getPreauthorizationParams = (paymentMethod, options = {}) => {
|
|
234
|
-
const baseParams = getBaseParams(options);
|
|
235
|
-
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
236
|
-
|
|
237
|
-
const {
|
|
238
|
-
amount,
|
|
239
|
-
currency,
|
|
240
|
-
reference,
|
|
241
|
-
customerid,
|
|
242
|
-
firstname,
|
|
243
|
-
lastname,
|
|
244
|
-
street,
|
|
245
|
-
zip,
|
|
246
|
-
city,
|
|
247
|
-
country,
|
|
248
|
-
email,
|
|
249
|
-
salutation,
|
|
250
|
-
gender,
|
|
251
|
-
telephonenumber,
|
|
252
|
-
ip,
|
|
253
|
-
customer_is_present,
|
|
254
|
-
language,
|
|
255
|
-
successurl,
|
|
256
|
-
errorurl,
|
|
257
|
-
backurl,
|
|
258
|
-
enable3DSecure,
|
|
259
|
-
ecommercemode,
|
|
260
|
-
cardtype,
|
|
261
|
-
cardpan,
|
|
262
|
-
cardexpiredate,
|
|
263
|
-
cardcvc2,
|
|
264
|
-
...additionalParams
|
|
265
|
-
} = options;
|
|
266
|
-
|
|
267
|
-
const params = {
|
|
268
|
-
...baseParams,
|
|
269
|
-
...methodParams,
|
|
270
|
-
...additionalParams,
|
|
271
|
-
request: "preauthorization"
|
|
272
|
-
};
|
|
273
|
-
|
|
274
|
-
if (paymentMethod === "cc" && options.enable3DSecure !== false) {
|
|
275
|
-
params["3dsecure"] = "yes";
|
|
276
|
-
params.ecommercemode = options.ecommercemode || "internet";
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
return params;
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
export const getAuthorizationParams = (paymentMethod, options = {}) => {
|
|
284
|
-
const baseParams = getBaseParams(options);
|
|
285
|
-
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
286
|
-
|
|
287
|
-
const {
|
|
288
|
-
amount,
|
|
289
|
-
currency,
|
|
290
|
-
reference,
|
|
291
|
-
customerid,
|
|
292
|
-
firstname,
|
|
293
|
-
lastname,
|
|
294
|
-
street,
|
|
295
|
-
zip,
|
|
296
|
-
city,
|
|
297
|
-
country,
|
|
298
|
-
email,
|
|
299
|
-
salutation,
|
|
300
|
-
gender,
|
|
301
|
-
telephonenumber,
|
|
302
|
-
ip,
|
|
303
|
-
customer_is_present,
|
|
304
|
-
language,
|
|
305
|
-
successurl,
|
|
306
|
-
errorurl,
|
|
307
|
-
backurl,
|
|
308
|
-
enable3DSecure,
|
|
309
|
-
ecommercemode,
|
|
310
|
-
cardtype,
|
|
311
|
-
cardpan,
|
|
312
|
-
cardexpiredate,
|
|
313
|
-
cardcvc2,
|
|
314
|
-
...additionalParams
|
|
315
|
-
} = options;
|
|
316
|
-
|
|
317
|
-
const params = {
|
|
318
|
-
...baseParams,
|
|
319
|
-
...methodParams,
|
|
320
|
-
...additionalParams,
|
|
321
|
-
request: "authorization"
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
if (paymentMethod === "cc" && options.enable3DSecure !== false) {
|
|
325
|
-
params["3dsecure"] = "yes";
|
|
326
|
-
params.ecommercemode = options.ecommercemode || "internet";
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
return params;
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
export const getCaptureParams = (paymentMethod, options = {}) => {
|
|
334
|
-
const {
|
|
335
|
-
txid,
|
|
336
|
-
amount,
|
|
337
|
-
currency = "EUR",
|
|
338
|
-
captureMode = "full",
|
|
339
|
-
sequencenumber = 1,
|
|
340
|
-
reference
|
|
341
|
-
} = options;
|
|
342
|
-
|
|
343
|
-
// Base parameters for all payment methods (Payone v1 documentation)
|
|
344
|
-
const baseParams = {
|
|
345
|
-
request: "capture", // Required for Payone API
|
|
346
|
-
txid,
|
|
347
|
-
sequencenumber: parseInt(sequencenumber),
|
|
348
|
-
amount: parseInt(amount),
|
|
349
|
-
currency: currency.toUpperCase(),
|
|
350
|
-
reference: reference || `CAPTURE-${Date.now()}`
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
// Payment method specific parameters
|
|
354
|
-
let methodParams = {};
|
|
355
|
-
|
|
356
|
-
switch (paymentMethod) {
|
|
357
|
-
case "cc": // Credit Card (Visa, Mastercard)
|
|
358
|
-
// Credit card capture only needs basic parameters
|
|
359
|
-
break;
|
|
360
|
-
|
|
361
|
-
case "wlt": // PayPal
|
|
362
|
-
case "gpp": // Google Pay
|
|
363
|
-
case "apl": // Apple Pay
|
|
364
|
-
methodParams = {
|
|
365
|
-
capturemode: captureMode // full or partial
|
|
366
|
-
};
|
|
367
|
-
break;
|
|
368
|
-
|
|
369
|
-
case "sb": // Sofort Banking
|
|
370
|
-
// Sofort capture parameters (if needed)
|
|
371
|
-
break;
|
|
372
|
-
|
|
373
|
-
case "elv": // SEPA Direct Debit
|
|
374
|
-
// SEPA capture parameters (if needed)
|
|
375
|
-
break;
|
|
376
|
-
|
|
377
|
-
default:
|
|
378
|
-
// Default to credit card behavior
|
|
379
|
-
break;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return {
|
|
383
|
-
...baseParams,
|
|
384
|
-
...methodParams
|
|
385
|
-
};
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
export const getRefundParams = (paymentMethod, options = {}) => {
|
|
390
|
-
const {
|
|
391
|
-
txid,
|
|
392
|
-
amount,
|
|
393
|
-
currency = "EUR",
|
|
394
|
-
reference,
|
|
395
|
-
sequencenumber = 2
|
|
396
|
-
} = options;
|
|
397
|
-
|
|
398
|
-
// Base parameters for all payment methods (Payone v1 documentation)
|
|
399
|
-
const baseParams = {
|
|
400
|
-
request: "refund", // Required for Payone API
|
|
401
|
-
txid,
|
|
402
|
-
sequencenumber: parseInt(sequencenumber),
|
|
403
|
-
amount: -Math.abs(parseInt(amount)), // Refund amount must be negative
|
|
404
|
-
currency: currency.toUpperCase(),
|
|
405
|
-
reference: reference || `REFUND-${Date.now()}`
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
// Payment method specific parameters
|
|
409
|
-
let methodParams = {};
|
|
410
|
-
|
|
411
|
-
switch (paymentMethod) {
|
|
412
|
-
case "cc": // Credit Card (Visa, Mastercard)
|
|
413
|
-
// Credit card refund only needs basic parameters
|
|
414
|
-
break;
|
|
415
|
-
|
|
416
|
-
case "wlt": // PayPal
|
|
417
|
-
case "gpp": // Google Pay
|
|
418
|
-
case "apl": // Apple Pay
|
|
419
|
-
// Wallet payment specific refund parameters (if needed)
|
|
420
|
-
break;
|
|
421
|
-
|
|
422
|
-
case "sb": // Sofort Banking
|
|
423
|
-
// Sofort specific refund parameters (if needed)
|
|
424
|
-
break;
|
|
425
|
-
|
|
426
|
-
case "elv": // SEPA Direct Debit
|
|
427
|
-
// SEPA specific refund parameters (if needed)
|
|
428
|
-
break;
|
|
429
|
-
|
|
430
|
-
default:
|
|
431
|
-
// Default to credit card behavior
|
|
432
|
-
break;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return {
|
|
436
|
-
...baseParams,
|
|
437
|
-
...methodParams
|
|
438
|
-
};
|
|
439
|
-
};
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
export const getPaymentMethodDisplayName = (paymentMethod) => {
|
|
443
|
-
const displayNames = {
|
|
444
|
-
cc: "Credit Card (Visa, Mastercard)",
|
|
445
|
-
wlt: "PayPal",
|
|
446
|
-
gpp: "Google Pay",
|
|
447
|
-
apl: "Apple Pay",
|
|
448
|
-
sb: "Sofort Banking",
|
|
449
|
-
elv: "SEPA Direct Debit"
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
return displayNames[paymentMethod] || "Unknown Payment Method";
|
|
453
|
-
};
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
export const getPaymentMethodOptions = (isLiveMode = false) => {
|
|
457
|
-
return isLiveMode ? [{ value: "apl", label: "Apple Pay" }] : [
|
|
458
|
-
{ value: "cc", label: "Credit Card (Visa, Mastercard)" },
|
|
459
|
-
{ value: "wlt", label: "PayPal" },
|
|
460
|
-
{ value: "gpp", label: "Google Pay" },
|
|
461
|
-
{ value: "apl", label: "Apple Pay" },
|
|
462
|
-
{ value: "elv", label: "SEPA Direct Debit" }
|
|
463
|
-
];
|
|
464
|
-
};
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
export const supportsCaptureMode = (paymentMethod) => {
|
|
468
|
-
return paymentMethod === "wlt" || paymentMethod === "gpp" || paymentMethod === "apl";
|
|
469
|
-
};
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
export const getCaptureModeOptions = () => {
|
|
473
|
-
return [
|
|
474
|
-
{ value: "full", label: "Full Capture" },
|
|
475
|
-
{ value: "partial", label: "Partial Capture" }
|
|
476
|
-
];
|
|
477
|
-
};
|
|
478
|
-
|
|
479
|
-
export const validatePaymentParams = (operation, paymentMethod, params) => {
|
|
480
|
-
const errors = [];
|
|
481
|
-
|
|
482
|
-
// Common validations for all operations
|
|
483
|
-
if (!params.amount || params.amount <= 0) {
|
|
484
|
-
errors.push("Amount is required and must be greater than 0");
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
if (!params.currency) {
|
|
488
|
-
errors.push("Currency is required");
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
if (params.currency && !/^[A-Z]{3}$/.test(params.currency)) {
|
|
492
|
-
errors.push("Currency must be in ISO 4217 format (e.g., EUR, USD)");
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
switch (operation) {
|
|
496
|
-
case "preauthorization":
|
|
497
|
-
if (!params.reference) {
|
|
498
|
-
errors.push("Reference is required for preauthorization");
|
|
499
|
-
}
|
|
500
|
-
if (!params.customerid) {
|
|
501
|
-
errors.push("Customer ID is required for preauthorization");
|
|
502
|
-
}
|
|
503
|
-
if (!params.firstname || !params.lastname) {
|
|
504
|
-
errors.push("First name and last name are required for preauthorization");
|
|
505
|
-
}
|
|
506
|
-
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
507
|
-
errors.push("Address details (street, zip, city, country) are required for preauthorization");
|
|
508
|
-
}
|
|
509
|
-
if (!params.email) {
|
|
510
|
-
errors.push("Email is required for preauthorization");
|
|
511
|
-
}
|
|
512
|
-
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
513
|
-
errors.push("Success, error, and back URLs are required for preauthorization");
|
|
514
|
-
}
|
|
515
|
-
// Validate email format
|
|
516
|
-
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
517
|
-
errors.push("Email format is invalid");
|
|
518
|
-
}
|
|
519
|
-
break;
|
|
520
|
-
|
|
521
|
-
case "authorization":
|
|
522
|
-
if (!params.reference) {
|
|
523
|
-
errors.push("Reference is required for authorization");
|
|
524
|
-
}
|
|
525
|
-
if (!params.customerid) {
|
|
526
|
-
errors.push("Customer ID is required for authorization");
|
|
527
|
-
}
|
|
528
|
-
if (!params.firstname || !params.lastname) {
|
|
529
|
-
errors.push("First name and last name are required for authorization");
|
|
530
|
-
}
|
|
531
|
-
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
532
|
-
errors.push("Address details (street, zip, city, country) are required for authorization");
|
|
533
|
-
}
|
|
534
|
-
if (!params.email) {
|
|
535
|
-
errors.push("Email is required for authorization");
|
|
536
|
-
}
|
|
537
|
-
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
538
|
-
errors.push("Success, error, and back URLs are required for authorization");
|
|
539
|
-
}
|
|
540
|
-
// Validate email format
|
|
541
|
-
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
542
|
-
errors.push("Email format is invalid");
|
|
543
|
-
}
|
|
544
|
-
break;
|
|
545
|
-
|
|
546
|
-
case "capture":
|
|
547
|
-
if (!params.txid) {
|
|
548
|
-
errors.push("Transaction ID (txid) is required for capture");
|
|
549
|
-
}
|
|
550
|
-
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
551
|
-
errors.push("Sequence number is required for capture and must be >= 1");
|
|
552
|
-
}
|
|
553
|
-
if (!params.reference) {
|
|
554
|
-
errors.push("Reference is required for capture");
|
|
555
|
-
}
|
|
556
|
-
break;
|
|
557
|
-
|
|
558
|
-
case "refund":
|
|
559
|
-
if (!params.txid) {
|
|
560
|
-
errors.push("Transaction ID (txid) is required for refund");
|
|
561
|
-
}
|
|
562
|
-
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
563
|
-
errors.push("Sequence number is required for refund and must be >= 1");
|
|
564
|
-
}
|
|
565
|
-
if (!params.reference) {
|
|
566
|
-
errors.push("Reference is required for refund");
|
|
567
|
-
}
|
|
568
|
-
if (params.amount > 0) {
|
|
569
|
-
errors.push("Refund amount must be negative");
|
|
570
|
-
}
|
|
571
|
-
break;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
switch (paymentMethod) {
|
|
575
|
-
case "cc":
|
|
576
|
-
if (!params.cardpan || !params.cardexpiredate || !params.cardcvc2) {
|
|
577
|
-
errors.push("Card details (cardpan, cardexpiredate, cardcvc2) are required for credit card payments");
|
|
578
|
-
}
|
|
579
|
-
if (!params.cardtype) {
|
|
580
|
-
errors.push("Card type is required for credit card payments");
|
|
581
|
-
}
|
|
582
|
-
// Validate card number format (basic check)
|
|
583
|
-
if (params.cardpan && !/^\d{13,19}$/.test(params.cardpan.replace(/\s/g, ''))) {
|
|
584
|
-
errors.push("Card number must be 13-19 digits");
|
|
585
|
-
}
|
|
586
|
-
// Validate expiry date format (YYMM)
|
|
587
|
-
if (params.cardexpiredate && !/^\d{4}$/.test(params.cardexpiredate)) {
|
|
588
|
-
errors.push("Card expiry date must be in YYMM format (e.g., 2512 = December 2025)");
|
|
589
|
-
}
|
|
590
|
-
// Validate CVC format (3-4 digits)
|
|
591
|
-
if (params.cardcvc2 && !/^\d{3,4}$/.test(params.cardcvc2)) {
|
|
592
|
-
errors.push("CVC must be 3-4 digits");
|
|
593
|
-
}
|
|
594
|
-
break;
|
|
595
|
-
|
|
596
|
-
case "wlt":
|
|
597
|
-
if (!params.wallettype) {
|
|
598
|
-
errors.push("Wallet type is required for PayPal payments");
|
|
599
|
-
}
|
|
600
|
-
if (params.wallettype && !["PPE", "PAP"].includes(params.wallettype)) {
|
|
601
|
-
errors.push("Wallet type must be PPE (PayPal Express) or PAP (PayPal Plus)");
|
|
602
|
-
}
|
|
603
|
-
break;
|
|
604
|
-
|
|
605
|
-
case "gpp":
|
|
606
|
-
if (!params.wallettype) {
|
|
607
|
-
errors.push("Wallet type is required for Google Pay payments");
|
|
608
|
-
}
|
|
609
|
-
if (params.wallettype && params.wallettype !== "GGP") {
|
|
610
|
-
errors.push("Wallet type must be GGP for Google Pay payments");
|
|
611
|
-
}
|
|
612
|
-
break;
|
|
613
|
-
|
|
614
|
-
case "apl":
|
|
615
|
-
if (!params.wallettype) {
|
|
616
|
-
errors.push("Wallet type is required for Apple Pay payments");
|
|
617
|
-
}
|
|
618
|
-
if (params.wallettype && params.wallettype !== "APL") {
|
|
619
|
-
errors.push("Wallet type must be APL for Apple Pay payments");
|
|
620
|
-
}
|
|
621
|
-
break;
|
|
622
|
-
|
|
623
|
-
case "sb":
|
|
624
|
-
if (!params.bankcountry) {
|
|
625
|
-
errors.push("Bank country is required for Sofort payments");
|
|
626
|
-
}
|
|
627
|
-
if (!params.onlinebanktransfertype) {
|
|
628
|
-
errors.push("Online bank transfer type is required for Sofort payments");
|
|
629
|
-
}
|
|
630
|
-
if (params.onlinebanktransfertype && params.onlinebanktransfertype !== "PNT") {
|
|
631
|
-
errors.push("Online bank transfer type must be PNT for Sofort payments");
|
|
632
|
-
}
|
|
633
|
-
break;
|
|
634
|
-
|
|
635
|
-
case "elv":
|
|
636
|
-
if (!params.iban || !params.bic) {
|
|
637
|
-
errors.push("IBAN and BIC are required for SEPA payments");
|
|
638
|
-
}
|
|
639
|
-
if (!params.bankaccountholder) {
|
|
640
|
-
errors.push("Bank account holder is required for SEPA payments");
|
|
641
|
-
}
|
|
642
|
-
if (!params.bankcountry) {
|
|
643
|
-
errors.push("Bank country is required for SEPA payments");
|
|
644
|
-
}
|
|
645
|
-
// Basic IBAN validation
|
|
646
|
-
if (params.iban && params.iban.length < 15) {
|
|
647
|
-
errors.push("IBAN must be at least 15 characters");
|
|
648
|
-
}
|
|
649
|
-
// Basic BIC validation
|
|
650
|
-
if (params.bic && params.bic.length < 8) {
|
|
651
|
-
errors.push("BIC must be at least 8 characters");
|
|
652
|
-
}
|
|
653
|
-
break;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
return {
|
|
657
|
-
isValid: errors.length === 0,
|
|
658
|
-
errors,
|
|
659
|
-
errorCount: errors.length
|
|
660
|
-
};
|
|
661
|
-
};
|
|
1
|
+
export function getValidCardExpiryDate(cardexpiredate) {
|
|
2
|
+
const now = new Date();
|
|
3
|
+
const currentYear = now.getFullYear() % 100;
|
|
4
|
+
const currentMonth = now.getMonth() + 1;
|
|
5
|
+
|
|
6
|
+
if (!cardexpiredate || cardexpiredate.trim() === "") {
|
|
7
|
+
const nextYear = currentYear + 1;
|
|
8
|
+
const monthStr = String(currentMonth).padStart(2, '0');
|
|
9
|
+
return `${nextYear}${monthStr}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
if (!/^\d{4}$/.test(cardexpiredate)) {
|
|
13
|
+
const nextYear = currentYear + 1;
|
|
14
|
+
const monthStr = String(currentMonth).padStart(2, '0');
|
|
15
|
+
return `${nextYear}${monthStr}`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const year = parseInt(cardexpiredate.substring(0, 2), 10);
|
|
19
|
+
const month = parseInt(cardexpiredate.substring(2, 4), 10);
|
|
20
|
+
|
|
21
|
+
if (month < 1 || month > 12) {
|
|
22
|
+
const nextYear = currentYear + 1;
|
|
23
|
+
const monthStr = String(currentMonth).padStart(2, '0');
|
|
24
|
+
return `${nextYear}${monthStr}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const currentDate = new Date(2000 + currentYear, currentMonth - 1);
|
|
28
|
+
const expiryDate = new Date(2000 + year, month - 1);
|
|
29
|
+
|
|
30
|
+
if (expiryDate < currentDate) {
|
|
31
|
+
const nextYear = currentYear + 1;
|
|
32
|
+
const monthStr = String(currentMonth).padStart(2, '0');
|
|
33
|
+
return `${nextYear}${monthStr}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return cardexpiredate;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function generateLagOrderNumber(sequence = 1000) {
|
|
40
|
+
const paddedSequence = sequence.toString().padStart(5, '0');
|
|
41
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
42
|
+
let randomPart = '';
|
|
43
|
+
for (let i = 0; i < 4; i++) {
|
|
44
|
+
randomPart += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
45
|
+
}
|
|
46
|
+
return `ORD-${paddedSequence}-${randomPart}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
export const getBaseParams = (options = {}) => {
|
|
51
|
+
const {
|
|
52
|
+
amount,
|
|
53
|
+
currency = "EUR",
|
|
54
|
+
reference,
|
|
55
|
+
customerid,
|
|
56
|
+
firstname = "John",
|
|
57
|
+
lastname = "Doe",
|
|
58
|
+
street = "Test Street 123",
|
|
59
|
+
zip = "12345",
|
|
60
|
+
city = "Test City",
|
|
61
|
+
country = "DE",
|
|
62
|
+
email = "test@example.com",
|
|
63
|
+
salutation = "Herr",
|
|
64
|
+
gender = "m",
|
|
65
|
+
telephonenumber = "01752345678",
|
|
66
|
+
ip = "127.0.0.1",
|
|
67
|
+
customer_is_present = "yes",
|
|
68
|
+
language = "de",
|
|
69
|
+
successurl = "https://www.example.com/success",
|
|
70
|
+
errorurl = "https://www.example.com/error",
|
|
71
|
+
backurl = "https://www.example.com/back"
|
|
72
|
+
} = options;
|
|
73
|
+
|
|
74
|
+
const generateCustomerId = () => {
|
|
75
|
+
const timestamp = Date.now().toString().slice(-10);
|
|
76
|
+
const random = Math.random().toString(36).substring(2, 6).toUpperCase();
|
|
77
|
+
const id = `${timestamp}${random}`.slice(0, 17);
|
|
78
|
+
return id;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let finalCustomerId = customerid || generateCustomerId();
|
|
82
|
+
|
|
83
|
+
if (finalCustomerId && finalCustomerId.length > 17) {
|
|
84
|
+
finalCustomerId = finalCustomerId.slice(0, 17);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
amount: parseInt(amount),
|
|
89
|
+
currency: currency.toUpperCase(),
|
|
90
|
+
reference: reference || `REF-${Date.now()}`,
|
|
91
|
+
customerid: finalCustomerId,
|
|
92
|
+
firstname,
|
|
93
|
+
lastname,
|
|
94
|
+
street,
|
|
95
|
+
zip,
|
|
96
|
+
city,
|
|
97
|
+
country: country.toUpperCase(),
|
|
98
|
+
email,
|
|
99
|
+
salutation,
|
|
100
|
+
gender,
|
|
101
|
+
telephonenumber,
|
|
102
|
+
ip,
|
|
103
|
+
customer_is_present,
|
|
104
|
+
language,
|
|
105
|
+
successurl,
|
|
106
|
+
errorurl,
|
|
107
|
+
backurl
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
113
|
+
const {
|
|
114
|
+
cardType,
|
|
115
|
+
cardtype,
|
|
116
|
+
captureMode = "full",
|
|
117
|
+
cardpan,
|
|
118
|
+
cardexpiredate,
|
|
119
|
+
cardcvc2,
|
|
120
|
+
iban,
|
|
121
|
+
bic,
|
|
122
|
+
bankaccountholder,
|
|
123
|
+
shipping_firstname,
|
|
124
|
+
shipping_lastname,
|
|
125
|
+
shipping_street,
|
|
126
|
+
shipping_zip,
|
|
127
|
+
shipping_city,
|
|
128
|
+
shipping_country,
|
|
129
|
+
firstname,
|
|
130
|
+
lastname,
|
|
131
|
+
street,
|
|
132
|
+
zip,
|
|
133
|
+
city,
|
|
134
|
+
country
|
|
135
|
+
} = options;
|
|
136
|
+
|
|
137
|
+
const finalCardType = cardtype || cardType || "V";
|
|
138
|
+
|
|
139
|
+
const getShippingParams = () => ({
|
|
140
|
+
shipping_firstname: shipping_firstname || firstname || "John",
|
|
141
|
+
shipping_lastname: shipping_lastname || lastname || "Doe",
|
|
142
|
+
shipping_street: shipping_street || street || "Test Street 123",
|
|
143
|
+
shipping_zip: shipping_zip || zip || "12345",
|
|
144
|
+
shipping_city: shipping_city || city || "Test City",
|
|
145
|
+
shipping_country: (shipping_country || country || "DE").toUpperCase()
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
switch (paymentMethod) {
|
|
149
|
+
case "cc":
|
|
150
|
+
return {
|
|
151
|
+
clearingtype: "cc",
|
|
152
|
+
cardtype: finalCardType,
|
|
153
|
+
cardpan: cardpan || "4111111111111111",
|
|
154
|
+
cardexpiredate: getValidCardExpiryDate(cardexpiredate),
|
|
155
|
+
cardcvc2: cardcvc2 || "123"
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
case "wlt":
|
|
159
|
+
return {
|
|
160
|
+
clearingtype: "wlt",
|
|
161
|
+
wallettype: "PPE",
|
|
162
|
+
...getShippingParams()
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
case "gpp":
|
|
166
|
+
const googlePayParams = {
|
|
167
|
+
clearingtype: "wlt",
|
|
168
|
+
wallettype: "GGP",
|
|
169
|
+
...getShippingParams()
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
if (options.googlePayToken) {
|
|
173
|
+
const gatewayMerchantId = options.settings?.mid || options.settings?.portalid || '';
|
|
174
|
+
googlePayParams["add_paydata[paymentmethod_token_data]"] = options.googlePayToken;
|
|
175
|
+
googlePayParams["add_paydata[paymentmethod]"] = "GGP";
|
|
176
|
+
googlePayParams["add_paydata[paymentmethod_type]"] = "GOOGLEPAY";
|
|
177
|
+
googlePayParams["add_paydata[gatewayid]"] = "payonegmbh";
|
|
178
|
+
if (gatewayMerchantId) {
|
|
179
|
+
googlePayParams["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return googlePayParams;
|
|
184
|
+
|
|
185
|
+
case "apl":
|
|
186
|
+
const applePayParams = {
|
|
187
|
+
clearingtype: "wlt",
|
|
188
|
+
wallettype: "APL",
|
|
189
|
+
...getShippingParams()
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
if (options.applePayToken) {
|
|
193
|
+
const gatewayMerchantId = options.settings?.mid || options.settings?.portalid || '';
|
|
194
|
+
applePayParams["add_paydata[paymentmethod_token_data]"] = options.applePayToken;
|
|
195
|
+
applePayParams["add_paydata[paymentmethod]"] = "APL";
|
|
196
|
+
applePayParams["add_paydata[paymentmethod_type]"] = "APPLEPAY";
|
|
197
|
+
applePayParams["add_paydata[gatewayid]"] = "payonegmbh";
|
|
198
|
+
if (gatewayMerchantId) {
|
|
199
|
+
applePayParams["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return applePayParams;
|
|
204
|
+
|
|
205
|
+
case "sb":
|
|
206
|
+
return {
|
|
207
|
+
clearingtype: "sb",
|
|
208
|
+
bankcountry: "DE",
|
|
209
|
+
onlinebanktransfertype: "PNT"
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
case "elv":
|
|
213
|
+
return {
|
|
214
|
+
clearingtype: "elv",
|
|
215
|
+
bankcountry: "DE",
|
|
216
|
+
iban: iban || "DE89370400440532013000",
|
|
217
|
+
bic: bic || "COBADEFFXXX",
|
|
218
|
+
bankaccountholder: bankaccountholder || "John Doe"
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
default:
|
|
222
|
+
return {
|
|
223
|
+
clearingtype: "cc",
|
|
224
|
+
cardtype: "V",
|
|
225
|
+
cardpan: "4111111111111111",
|
|
226
|
+
cardexpiredate: "2512",
|
|
227
|
+
cardcvc2: "123"
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
export const getPreauthorizationParams = (paymentMethod, options = {}) => {
|
|
234
|
+
const baseParams = getBaseParams(options);
|
|
235
|
+
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
236
|
+
|
|
237
|
+
const {
|
|
238
|
+
amount,
|
|
239
|
+
currency,
|
|
240
|
+
reference,
|
|
241
|
+
customerid,
|
|
242
|
+
firstname,
|
|
243
|
+
lastname,
|
|
244
|
+
street,
|
|
245
|
+
zip,
|
|
246
|
+
city,
|
|
247
|
+
country,
|
|
248
|
+
email,
|
|
249
|
+
salutation,
|
|
250
|
+
gender,
|
|
251
|
+
telephonenumber,
|
|
252
|
+
ip,
|
|
253
|
+
customer_is_present,
|
|
254
|
+
language,
|
|
255
|
+
successurl,
|
|
256
|
+
errorurl,
|
|
257
|
+
backurl,
|
|
258
|
+
enable3DSecure,
|
|
259
|
+
ecommercemode,
|
|
260
|
+
cardtype,
|
|
261
|
+
cardpan,
|
|
262
|
+
cardexpiredate,
|
|
263
|
+
cardcvc2,
|
|
264
|
+
...additionalParams
|
|
265
|
+
} = options;
|
|
266
|
+
|
|
267
|
+
const params = {
|
|
268
|
+
...baseParams,
|
|
269
|
+
...methodParams,
|
|
270
|
+
...additionalParams,
|
|
271
|
+
request: "preauthorization"
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
if (paymentMethod === "cc" && options.enable3DSecure !== false) {
|
|
275
|
+
params["3dsecure"] = "yes";
|
|
276
|
+
params.ecommercemode = options.ecommercemode || "internet";
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return params;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
export const getAuthorizationParams = (paymentMethod, options = {}) => {
|
|
284
|
+
const baseParams = getBaseParams(options);
|
|
285
|
+
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
286
|
+
|
|
287
|
+
const {
|
|
288
|
+
amount,
|
|
289
|
+
currency,
|
|
290
|
+
reference,
|
|
291
|
+
customerid,
|
|
292
|
+
firstname,
|
|
293
|
+
lastname,
|
|
294
|
+
street,
|
|
295
|
+
zip,
|
|
296
|
+
city,
|
|
297
|
+
country,
|
|
298
|
+
email,
|
|
299
|
+
salutation,
|
|
300
|
+
gender,
|
|
301
|
+
telephonenumber,
|
|
302
|
+
ip,
|
|
303
|
+
customer_is_present,
|
|
304
|
+
language,
|
|
305
|
+
successurl,
|
|
306
|
+
errorurl,
|
|
307
|
+
backurl,
|
|
308
|
+
enable3DSecure,
|
|
309
|
+
ecommercemode,
|
|
310
|
+
cardtype,
|
|
311
|
+
cardpan,
|
|
312
|
+
cardexpiredate,
|
|
313
|
+
cardcvc2,
|
|
314
|
+
...additionalParams
|
|
315
|
+
} = options;
|
|
316
|
+
|
|
317
|
+
const params = {
|
|
318
|
+
...baseParams,
|
|
319
|
+
...methodParams,
|
|
320
|
+
...additionalParams,
|
|
321
|
+
request: "authorization"
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
if (paymentMethod === "cc" && options.enable3DSecure !== false) {
|
|
325
|
+
params["3dsecure"] = "yes";
|
|
326
|
+
params.ecommercemode = options.ecommercemode || "internet";
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return params;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
export const getCaptureParams = (paymentMethod, options = {}) => {
|
|
334
|
+
const {
|
|
335
|
+
txid,
|
|
336
|
+
amount,
|
|
337
|
+
currency = "EUR",
|
|
338
|
+
captureMode = "full",
|
|
339
|
+
sequencenumber = 1,
|
|
340
|
+
reference
|
|
341
|
+
} = options;
|
|
342
|
+
|
|
343
|
+
// Base parameters for all payment methods (Payone v1 documentation)
|
|
344
|
+
const baseParams = {
|
|
345
|
+
request: "capture", // Required for Payone API
|
|
346
|
+
txid,
|
|
347
|
+
sequencenumber: parseInt(sequencenumber),
|
|
348
|
+
amount: parseInt(amount),
|
|
349
|
+
currency: currency.toUpperCase(),
|
|
350
|
+
reference: reference || `CAPTURE-${Date.now()}`
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// Payment method specific parameters
|
|
354
|
+
let methodParams = {};
|
|
355
|
+
|
|
356
|
+
switch (paymentMethod) {
|
|
357
|
+
case "cc": // Credit Card (Visa, Mastercard)
|
|
358
|
+
// Credit card capture only needs basic parameters
|
|
359
|
+
break;
|
|
360
|
+
|
|
361
|
+
case "wlt": // PayPal
|
|
362
|
+
case "gpp": // Google Pay
|
|
363
|
+
case "apl": // Apple Pay
|
|
364
|
+
methodParams = {
|
|
365
|
+
capturemode: captureMode // full or partial
|
|
366
|
+
};
|
|
367
|
+
break;
|
|
368
|
+
|
|
369
|
+
case "sb": // Sofort Banking
|
|
370
|
+
// Sofort capture parameters (if needed)
|
|
371
|
+
break;
|
|
372
|
+
|
|
373
|
+
case "elv": // SEPA Direct Debit
|
|
374
|
+
// SEPA capture parameters (if needed)
|
|
375
|
+
break;
|
|
376
|
+
|
|
377
|
+
default:
|
|
378
|
+
// Default to credit card behavior
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
...baseParams,
|
|
384
|
+
...methodParams
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
export const getRefundParams = (paymentMethod, options = {}) => {
|
|
390
|
+
const {
|
|
391
|
+
txid,
|
|
392
|
+
amount,
|
|
393
|
+
currency = "EUR",
|
|
394
|
+
reference,
|
|
395
|
+
sequencenumber = 2
|
|
396
|
+
} = options;
|
|
397
|
+
|
|
398
|
+
// Base parameters for all payment methods (Payone v1 documentation)
|
|
399
|
+
const baseParams = {
|
|
400
|
+
request: "refund", // Required for Payone API
|
|
401
|
+
txid,
|
|
402
|
+
sequencenumber: parseInt(sequencenumber),
|
|
403
|
+
amount: -Math.abs(parseInt(amount)), // Refund amount must be negative
|
|
404
|
+
currency: currency.toUpperCase(),
|
|
405
|
+
reference: reference || `REFUND-${Date.now()}`
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// Payment method specific parameters
|
|
409
|
+
let methodParams = {};
|
|
410
|
+
|
|
411
|
+
switch (paymentMethod) {
|
|
412
|
+
case "cc": // Credit Card (Visa, Mastercard)
|
|
413
|
+
// Credit card refund only needs basic parameters
|
|
414
|
+
break;
|
|
415
|
+
|
|
416
|
+
case "wlt": // PayPal
|
|
417
|
+
case "gpp": // Google Pay
|
|
418
|
+
case "apl": // Apple Pay
|
|
419
|
+
// Wallet payment specific refund parameters (if needed)
|
|
420
|
+
break;
|
|
421
|
+
|
|
422
|
+
case "sb": // Sofort Banking
|
|
423
|
+
// Sofort specific refund parameters (if needed)
|
|
424
|
+
break;
|
|
425
|
+
|
|
426
|
+
case "elv": // SEPA Direct Debit
|
|
427
|
+
// SEPA specific refund parameters (if needed)
|
|
428
|
+
break;
|
|
429
|
+
|
|
430
|
+
default:
|
|
431
|
+
// Default to credit card behavior
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return {
|
|
436
|
+
...baseParams,
|
|
437
|
+
...methodParams
|
|
438
|
+
};
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
export const getPaymentMethodDisplayName = (paymentMethod) => {
|
|
443
|
+
const displayNames = {
|
|
444
|
+
cc: "Credit Card (Visa, Mastercard)",
|
|
445
|
+
wlt: "PayPal",
|
|
446
|
+
gpp: "Google Pay",
|
|
447
|
+
apl: "Apple Pay",
|
|
448
|
+
sb: "Sofort Banking",
|
|
449
|
+
elv: "SEPA Direct Debit"
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
return displayNames[paymentMethod] || "Unknown Payment Method";
|
|
453
|
+
};
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
export const getPaymentMethodOptions = (isLiveMode = false) => {
|
|
457
|
+
return isLiveMode ? [{ value: "apl", label: "Apple Pay" }] : [
|
|
458
|
+
{ value: "cc", label: "Credit Card (Visa, Mastercard)" },
|
|
459
|
+
{ value: "wlt", label: "PayPal" },
|
|
460
|
+
{ value: "gpp", label: "Google Pay" },
|
|
461
|
+
{ value: "apl", label: "Apple Pay" },
|
|
462
|
+
{ value: "elv", label: "SEPA Direct Debit" }
|
|
463
|
+
];
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
export const supportsCaptureMode = (paymentMethod) => {
|
|
468
|
+
return paymentMethod === "wlt" || paymentMethod === "gpp" || paymentMethod === "apl";
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
export const getCaptureModeOptions = () => {
|
|
473
|
+
return [
|
|
474
|
+
{ value: "full", label: "Full Capture" },
|
|
475
|
+
{ value: "partial", label: "Partial Capture" }
|
|
476
|
+
];
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
export const validatePaymentParams = (operation, paymentMethod, params) => {
|
|
480
|
+
const errors = [];
|
|
481
|
+
|
|
482
|
+
// Common validations for all operations
|
|
483
|
+
if (!params.amount || params.amount <= 0) {
|
|
484
|
+
errors.push("Amount is required and must be greater than 0");
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (!params.currency) {
|
|
488
|
+
errors.push("Currency is required");
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (params.currency && !/^[A-Z]{3}$/.test(params.currency)) {
|
|
492
|
+
errors.push("Currency must be in ISO 4217 format (e.g., EUR, USD)");
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
switch (operation) {
|
|
496
|
+
case "preauthorization":
|
|
497
|
+
if (!params.reference) {
|
|
498
|
+
errors.push("Reference is required for preauthorization");
|
|
499
|
+
}
|
|
500
|
+
if (!params.customerid) {
|
|
501
|
+
errors.push("Customer ID is required for preauthorization");
|
|
502
|
+
}
|
|
503
|
+
if (!params.firstname || !params.lastname) {
|
|
504
|
+
errors.push("First name and last name are required for preauthorization");
|
|
505
|
+
}
|
|
506
|
+
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
507
|
+
errors.push("Address details (street, zip, city, country) are required for preauthorization");
|
|
508
|
+
}
|
|
509
|
+
if (!params.email) {
|
|
510
|
+
errors.push("Email is required for preauthorization");
|
|
511
|
+
}
|
|
512
|
+
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
513
|
+
errors.push("Success, error, and back URLs are required for preauthorization");
|
|
514
|
+
}
|
|
515
|
+
// Validate email format
|
|
516
|
+
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
517
|
+
errors.push("Email format is invalid");
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
520
|
+
|
|
521
|
+
case "authorization":
|
|
522
|
+
if (!params.reference) {
|
|
523
|
+
errors.push("Reference is required for authorization");
|
|
524
|
+
}
|
|
525
|
+
if (!params.customerid) {
|
|
526
|
+
errors.push("Customer ID is required for authorization");
|
|
527
|
+
}
|
|
528
|
+
if (!params.firstname || !params.lastname) {
|
|
529
|
+
errors.push("First name and last name are required for authorization");
|
|
530
|
+
}
|
|
531
|
+
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
532
|
+
errors.push("Address details (street, zip, city, country) are required for authorization");
|
|
533
|
+
}
|
|
534
|
+
if (!params.email) {
|
|
535
|
+
errors.push("Email is required for authorization");
|
|
536
|
+
}
|
|
537
|
+
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
538
|
+
errors.push("Success, error, and back URLs are required for authorization");
|
|
539
|
+
}
|
|
540
|
+
// Validate email format
|
|
541
|
+
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
542
|
+
errors.push("Email format is invalid");
|
|
543
|
+
}
|
|
544
|
+
break;
|
|
545
|
+
|
|
546
|
+
case "capture":
|
|
547
|
+
if (!params.txid) {
|
|
548
|
+
errors.push("Transaction ID (txid) is required for capture");
|
|
549
|
+
}
|
|
550
|
+
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
551
|
+
errors.push("Sequence number is required for capture and must be >= 1");
|
|
552
|
+
}
|
|
553
|
+
if (!params.reference) {
|
|
554
|
+
errors.push("Reference is required for capture");
|
|
555
|
+
}
|
|
556
|
+
break;
|
|
557
|
+
|
|
558
|
+
case "refund":
|
|
559
|
+
if (!params.txid) {
|
|
560
|
+
errors.push("Transaction ID (txid) is required for refund");
|
|
561
|
+
}
|
|
562
|
+
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
563
|
+
errors.push("Sequence number is required for refund and must be >= 1");
|
|
564
|
+
}
|
|
565
|
+
if (!params.reference) {
|
|
566
|
+
errors.push("Reference is required for refund");
|
|
567
|
+
}
|
|
568
|
+
if (params.amount > 0) {
|
|
569
|
+
errors.push("Refund amount must be negative");
|
|
570
|
+
}
|
|
571
|
+
break;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
switch (paymentMethod) {
|
|
575
|
+
case "cc":
|
|
576
|
+
if (!params.cardpan || !params.cardexpiredate || !params.cardcvc2) {
|
|
577
|
+
errors.push("Card details (cardpan, cardexpiredate, cardcvc2) are required for credit card payments");
|
|
578
|
+
}
|
|
579
|
+
if (!params.cardtype) {
|
|
580
|
+
errors.push("Card type is required for credit card payments");
|
|
581
|
+
}
|
|
582
|
+
// Validate card number format (basic check)
|
|
583
|
+
if (params.cardpan && !/^\d{13,19}$/.test(params.cardpan.replace(/\s/g, ''))) {
|
|
584
|
+
errors.push("Card number must be 13-19 digits");
|
|
585
|
+
}
|
|
586
|
+
// Validate expiry date format (YYMM)
|
|
587
|
+
if (params.cardexpiredate && !/^\d{4}$/.test(params.cardexpiredate)) {
|
|
588
|
+
errors.push("Card expiry date must be in YYMM format (e.g., 2512 = December 2025)");
|
|
589
|
+
}
|
|
590
|
+
// Validate CVC format (3-4 digits)
|
|
591
|
+
if (params.cardcvc2 && !/^\d{3,4}$/.test(params.cardcvc2)) {
|
|
592
|
+
errors.push("CVC must be 3-4 digits");
|
|
593
|
+
}
|
|
594
|
+
break;
|
|
595
|
+
|
|
596
|
+
case "wlt":
|
|
597
|
+
if (!params.wallettype) {
|
|
598
|
+
errors.push("Wallet type is required for PayPal payments");
|
|
599
|
+
}
|
|
600
|
+
if (params.wallettype && !["PPE", "PAP"].includes(params.wallettype)) {
|
|
601
|
+
errors.push("Wallet type must be PPE (PayPal Express) or PAP (PayPal Plus)");
|
|
602
|
+
}
|
|
603
|
+
break;
|
|
604
|
+
|
|
605
|
+
case "gpp":
|
|
606
|
+
if (!params.wallettype) {
|
|
607
|
+
errors.push("Wallet type is required for Google Pay payments");
|
|
608
|
+
}
|
|
609
|
+
if (params.wallettype && params.wallettype !== "GGP") {
|
|
610
|
+
errors.push("Wallet type must be GGP for Google Pay payments");
|
|
611
|
+
}
|
|
612
|
+
break;
|
|
613
|
+
|
|
614
|
+
case "apl":
|
|
615
|
+
if (!params.wallettype) {
|
|
616
|
+
errors.push("Wallet type is required for Apple Pay payments");
|
|
617
|
+
}
|
|
618
|
+
if (params.wallettype && params.wallettype !== "APL") {
|
|
619
|
+
errors.push("Wallet type must be APL for Apple Pay payments");
|
|
620
|
+
}
|
|
621
|
+
break;
|
|
622
|
+
|
|
623
|
+
case "sb":
|
|
624
|
+
if (!params.bankcountry) {
|
|
625
|
+
errors.push("Bank country is required for Sofort payments");
|
|
626
|
+
}
|
|
627
|
+
if (!params.onlinebanktransfertype) {
|
|
628
|
+
errors.push("Online bank transfer type is required for Sofort payments");
|
|
629
|
+
}
|
|
630
|
+
if (params.onlinebanktransfertype && params.onlinebanktransfertype !== "PNT") {
|
|
631
|
+
errors.push("Online bank transfer type must be PNT for Sofort payments");
|
|
632
|
+
}
|
|
633
|
+
break;
|
|
634
|
+
|
|
635
|
+
case "elv":
|
|
636
|
+
if (!params.iban || !params.bic) {
|
|
637
|
+
errors.push("IBAN and BIC are required for SEPA payments");
|
|
638
|
+
}
|
|
639
|
+
if (!params.bankaccountholder) {
|
|
640
|
+
errors.push("Bank account holder is required for SEPA payments");
|
|
641
|
+
}
|
|
642
|
+
if (!params.bankcountry) {
|
|
643
|
+
errors.push("Bank country is required for SEPA payments");
|
|
644
|
+
}
|
|
645
|
+
// Basic IBAN validation
|
|
646
|
+
if (params.iban && params.iban.length < 15) {
|
|
647
|
+
errors.push("IBAN must be at least 15 characters");
|
|
648
|
+
}
|
|
649
|
+
// Basic BIC validation
|
|
650
|
+
if (params.bic && params.bic.length < 8) {
|
|
651
|
+
errors.push("BIC must be at least 8 characters");
|
|
652
|
+
}
|
|
653
|
+
break;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
return {
|
|
657
|
+
isValid: errors.length === 0,
|
|
658
|
+
errors,
|
|
659
|
+
errorCount: errors.length
|
|
660
|
+
};
|
|
661
|
+
};
|