strapi-plugin-payone-provider 1.0.1
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 +571 -0
- package/admin/src/components/Initializer/index.js +16 -0
- package/admin/src/components/PluginIcon/index.js +6 -0
- package/admin/src/index.js +37 -0
- package/admin/src/pages/App/components/ConfigurationPanel.js +265 -0
- package/admin/src/pages/App/components/HistoryPanel.js +298 -0
- package/admin/src/pages/App/components/PaymentActionsPanel.js +333 -0
- package/admin/src/pages/App/components/StatusBadge.js +22 -0
- package/admin/src/pages/App/components/TransactionHistoryItem.js +374 -0
- package/admin/src/pages/App/components/icons/BankIcon.js +10 -0
- package/admin/src/pages/App/components/icons/ChevronDownIcon.js +9 -0
- package/admin/src/pages/App/components/icons/ChevronUpIcon.js +9 -0
- package/admin/src/pages/App/components/icons/CreditCardIcon.js +9 -0
- package/admin/src/pages/App/components/icons/ErrorIcon.js +10 -0
- package/admin/src/pages/App/components/icons/InfoIcon.js +9 -0
- package/admin/src/pages/App/components/icons/PaymentIcon.js +10 -0
- package/admin/src/pages/App/components/icons/PendingIcon.js +9 -0
- package/admin/src/pages/App/components/icons/PersonIcon.js +9 -0
- package/admin/src/pages/App/components/icons/SuccessIcon.js +9 -0
- package/admin/src/pages/App/components/icons/WalletIcon.js +9 -0
- package/admin/src/pages/App/components/icons/index.js +11 -0
- package/admin/src/pages/App/index.js +483 -0
- package/admin/src/pages/utils/api.js +75 -0
- package/admin/src/pages/utils/formatTransactionData.js +16 -0
- package/admin/src/pages/utils/paymentUtils.js +528 -0
- package/admin/src/pluginId.js +5 -0
- package/package.json +43 -0
- package/server/bootstrap.js +26 -0
- package/server/config/index.js +42 -0
- package/server/controllers/index.js +7 -0
- package/server/controllers/payone.js +134 -0
- package/server/destroy.js +5 -0
- package/server/index.js +21 -0
- package/server/policies/index.js +6 -0
- package/server/policies/isAuth.js +23 -0
- package/server/policies/isSuperAdmin.js +18 -0
- package/server/register.js +5 -0
- package/server/routes/index.js +124 -0
- package/server/services/index.js +7 -0
- package/server/services/payone.js +679 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +3 -0
|
@@ -0,0 +1,528 @@
|
|
|
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
|
+
* - Sofort Banking (sb)
|
|
15
|
+
* - SEPA Direct Debit (elv)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Get base parameters for all payment methods
|
|
20
|
+
* Based on Payone v1 API Documentation
|
|
21
|
+
* @param {Object} options - Base options
|
|
22
|
+
* @returns {Object} Base parameters with all required fields
|
|
23
|
+
*/
|
|
24
|
+
export const getBaseParams = (options = {}) => {
|
|
25
|
+
const {
|
|
26
|
+
amount,
|
|
27
|
+
currency = "EUR",
|
|
28
|
+
reference,
|
|
29
|
+
customerid,
|
|
30
|
+
firstname = "John",
|
|
31
|
+
lastname = "Doe",
|
|
32
|
+
street = "Test Street 123",
|
|
33
|
+
zip = "12345",
|
|
34
|
+
city = "Test City",
|
|
35
|
+
country = "DE",
|
|
36
|
+
email = "test@example.com",
|
|
37
|
+
salutation = "Herr",
|
|
38
|
+
gender = "m",
|
|
39
|
+
telephonenumber = "01752345678",
|
|
40
|
+
ip = "127.0.0.1",
|
|
41
|
+
customer_is_present = "yes",
|
|
42
|
+
language = "de",
|
|
43
|
+
successurl = "https://www.example.com/success",
|
|
44
|
+
errorurl = "https://www.example.com/error",
|
|
45
|
+
backurl = "https://www.example.com/back"
|
|
46
|
+
} = options;
|
|
47
|
+
|
|
48
|
+
// Generate unique customer ID if not provided
|
|
49
|
+
const finalCustomerId = customerid || `CUST-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
// Required core parameters (Payone v1)
|
|
53
|
+
amount: parseInt(amount),
|
|
54
|
+
currency: currency.toUpperCase(),
|
|
55
|
+
reference: reference || `REF-${Date.now()}`,
|
|
56
|
+
customerid: finalCustomerId,
|
|
57
|
+
|
|
58
|
+
// Customer information (required for preauthorization/authorization)
|
|
59
|
+
firstname,
|
|
60
|
+
lastname,
|
|
61
|
+
street,
|
|
62
|
+
zip,
|
|
63
|
+
city,
|
|
64
|
+
country: country.toUpperCase(),
|
|
65
|
+
email,
|
|
66
|
+
|
|
67
|
+
// Additional customer details
|
|
68
|
+
salutation,
|
|
69
|
+
gender,
|
|
70
|
+
telephonenumber,
|
|
71
|
+
ip,
|
|
72
|
+
customer_is_present,
|
|
73
|
+
language,
|
|
74
|
+
|
|
75
|
+
// URL parameters (required for redirect-based payments)
|
|
76
|
+
successurl,
|
|
77
|
+
errorurl,
|
|
78
|
+
backurl
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Get payment method specific parameters
|
|
84
|
+
* Based on Payone v1 API Documentation
|
|
85
|
+
* @param {string} paymentMethod - Payment method (cc, wlt, sb, elv)
|
|
86
|
+
* @param {Object} options - Additional options
|
|
87
|
+
* @returns {Object} Payment method specific parameters
|
|
88
|
+
*/
|
|
89
|
+
export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
90
|
+
const {
|
|
91
|
+
cardType = "V",
|
|
92
|
+
captureMode = "full",
|
|
93
|
+
cardpan,
|
|
94
|
+
cardexpiredate,
|
|
95
|
+
cardcvc2,
|
|
96
|
+
iban,
|
|
97
|
+
bic,
|
|
98
|
+
bankaccountholder
|
|
99
|
+
} = options;
|
|
100
|
+
|
|
101
|
+
switch (paymentMethod) {
|
|
102
|
+
case "cc": // Credit Card (Visa, Mastercard, Amex)
|
|
103
|
+
return {
|
|
104
|
+
clearingtype: "cc",
|
|
105
|
+
cardtype: cardType, // V = Visa, M = Mastercard, A = Amex
|
|
106
|
+
cardpan: cardpan || "4111111111111111", // Test Visa card
|
|
107
|
+
cardexpiredate: cardexpiredate || "2512", // MMYY format
|
|
108
|
+
cardcvc2: cardcvc2 || "123" // 3-digit security code
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
case "wlt": // PayPal
|
|
112
|
+
return {
|
|
113
|
+
clearingtype: "wlt",
|
|
114
|
+
wallettype: "PPE", // PayPal Express
|
|
115
|
+
shipping_firstname: "John",
|
|
116
|
+
shipping_lastname: "Doe",
|
|
117
|
+
shipping_street: "Test Street 123",
|
|
118
|
+
shipping_zip: "12345",
|
|
119
|
+
shipping_city: "Test City",
|
|
120
|
+
shipping_country: "DE"
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
case "sb": // Sofort Banking
|
|
124
|
+
return {
|
|
125
|
+
clearingtype: "sb",
|
|
126
|
+
bankcountry: "DE",
|
|
127
|
+
onlinebanktransfertype: "PNT" // Sofort Banking
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
case "elv": // SEPA Direct Debit
|
|
131
|
+
return {
|
|
132
|
+
clearingtype: "elv",
|
|
133
|
+
bankcountry: "DE",
|
|
134
|
+
iban: iban || "DE89370400440532013000", // Test IBAN
|
|
135
|
+
bic: bic || "COBADEFFXXX", // Test BIC
|
|
136
|
+
bankaccountholder: bankaccountholder || "John Doe"
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
default:
|
|
140
|
+
// Default to credit card for unknown payment methods
|
|
141
|
+
return {
|
|
142
|
+
clearingtype: "cc",
|
|
143
|
+
cardtype: "V",
|
|
144
|
+
cardpan: "4111111111111111",
|
|
145
|
+
cardexpiredate: "2512",
|
|
146
|
+
cardcvc2: "123"
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get preauthorization parameters for specific payment method
|
|
153
|
+
* Based on Payone v1 API Documentation
|
|
154
|
+
* @param {string} paymentMethod - Payment method
|
|
155
|
+
* @param {Object} options - Options including amount, reference, etc.
|
|
156
|
+
* @returns {Object} Complete preauthorization parameters
|
|
157
|
+
*/
|
|
158
|
+
export const getPreauthorizationParams = (paymentMethod, options = {}) => {
|
|
159
|
+
const baseParams = getBaseParams(options);
|
|
160
|
+
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
...baseParams,
|
|
164
|
+
...methodParams,
|
|
165
|
+
request: "preauthorization" // Required for Payone API
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get authorization parameters for specific payment method
|
|
171
|
+
* Based on Payone v1 API Documentation
|
|
172
|
+
* @param {string} paymentMethod - Payment method
|
|
173
|
+
* @param {Object} options - Options including amount, reference, etc.
|
|
174
|
+
* @returns {Object} Complete authorization parameters
|
|
175
|
+
*/
|
|
176
|
+
export const getAuthorizationParams = (paymentMethod, options = {}) => {
|
|
177
|
+
const baseParams = getBaseParams(options);
|
|
178
|
+
const methodParams = getPaymentMethodParams(paymentMethod, options);
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
...baseParams,
|
|
182
|
+
...methodParams,
|
|
183
|
+
request: "authorization" // Required for Payone API
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Get capture parameters for specific payment method
|
|
189
|
+
* Based on Payone v1 API Documentation
|
|
190
|
+
* @param {string} paymentMethod - Payment method
|
|
191
|
+
* @param {Object} options - Options including txid, amount, captureMode, etc.
|
|
192
|
+
* @returns {Object} Complete capture parameters
|
|
193
|
+
*/
|
|
194
|
+
export const getCaptureParams = (paymentMethod, options = {}) => {
|
|
195
|
+
const {
|
|
196
|
+
txid,
|
|
197
|
+
amount,
|
|
198
|
+
currency = "EUR",
|
|
199
|
+
captureMode = "full",
|
|
200
|
+
sequencenumber = 1,
|
|
201
|
+
reference
|
|
202
|
+
} = options;
|
|
203
|
+
|
|
204
|
+
// Base parameters for all payment methods (Payone v1 documentation)
|
|
205
|
+
const baseParams = {
|
|
206
|
+
request: "capture", // Required for Payone API
|
|
207
|
+
txid,
|
|
208
|
+
sequencenumber: parseInt(sequencenumber),
|
|
209
|
+
amount: parseInt(amount),
|
|
210
|
+
currency: currency.toUpperCase(),
|
|
211
|
+
reference: reference || `CAPTURE-${Date.now()}`
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// Payment method specific parameters
|
|
215
|
+
let methodParams = {};
|
|
216
|
+
|
|
217
|
+
switch (paymentMethod) {
|
|
218
|
+
case "cc": // Credit Card (Visa, Mastercard)
|
|
219
|
+
// Credit card capture only needs basic parameters
|
|
220
|
+
break;
|
|
221
|
+
|
|
222
|
+
case "wlt": // PayPal
|
|
223
|
+
methodParams = {
|
|
224
|
+
capturemode: captureMode // full or partial
|
|
225
|
+
};
|
|
226
|
+
break;
|
|
227
|
+
|
|
228
|
+
case "sb": // Sofort Banking
|
|
229
|
+
// Sofort capture parameters (if needed)
|
|
230
|
+
break;
|
|
231
|
+
|
|
232
|
+
case "elv": // SEPA Direct Debit
|
|
233
|
+
// SEPA capture parameters (if needed)
|
|
234
|
+
break;
|
|
235
|
+
|
|
236
|
+
default:
|
|
237
|
+
// Default to credit card behavior
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {
|
|
242
|
+
...baseParams,
|
|
243
|
+
...methodParams
|
|
244
|
+
};
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Get refund parameters for specific payment method
|
|
249
|
+
* Based on Payone v1 API Documentation
|
|
250
|
+
* @param {string} paymentMethod - Payment method
|
|
251
|
+
* @param {Object} options - Options including txid, amount, sequencenumber, etc.
|
|
252
|
+
* @returns {Object} Complete refund parameters
|
|
253
|
+
*/
|
|
254
|
+
export const getRefundParams = (paymentMethod, options = {}) => {
|
|
255
|
+
const {
|
|
256
|
+
txid,
|
|
257
|
+
amount,
|
|
258
|
+
currency = "EUR",
|
|
259
|
+
reference,
|
|
260
|
+
sequencenumber = 2
|
|
261
|
+
} = options;
|
|
262
|
+
|
|
263
|
+
// Base parameters for all payment methods (Payone v1 documentation)
|
|
264
|
+
const baseParams = {
|
|
265
|
+
request: "refund", // Required for Payone API
|
|
266
|
+
txid,
|
|
267
|
+
sequencenumber: parseInt(sequencenumber),
|
|
268
|
+
amount: -Math.abs(parseInt(amount)), // Refund amount must be negative
|
|
269
|
+
currency: currency.toUpperCase(),
|
|
270
|
+
reference: reference || `REFUND-${Date.now()}`
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// Payment method specific parameters
|
|
274
|
+
let methodParams = {};
|
|
275
|
+
|
|
276
|
+
switch (paymentMethod) {
|
|
277
|
+
case "cc": // Credit Card (Visa, Mastercard)
|
|
278
|
+
// Credit card refund only needs basic parameters
|
|
279
|
+
break;
|
|
280
|
+
|
|
281
|
+
case "wlt": // PayPal
|
|
282
|
+
// PayPal specific refund parameters (if needed)
|
|
283
|
+
break;
|
|
284
|
+
|
|
285
|
+
case "sb": // Sofort Banking
|
|
286
|
+
// Sofort specific refund parameters (if needed)
|
|
287
|
+
break;
|
|
288
|
+
|
|
289
|
+
case "elv": // SEPA Direct Debit
|
|
290
|
+
// SEPA specific refund parameters (if needed)
|
|
291
|
+
break;
|
|
292
|
+
|
|
293
|
+
default:
|
|
294
|
+
// Default to credit card behavior
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
...baseParams,
|
|
300
|
+
...methodParams
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get payment method display name
|
|
306
|
+
* @param {string} paymentMethod - Payment method code
|
|
307
|
+
* @returns {string} Display name
|
|
308
|
+
*/
|
|
309
|
+
export const getPaymentMethodDisplayName = (paymentMethod) => {
|
|
310
|
+
const displayNames = {
|
|
311
|
+
cc: "Credit Card (Visa, Mastercard)",
|
|
312
|
+
wlt: "PayPal",
|
|
313
|
+
sb: "Sofort Banking",
|
|
314
|
+
elv: "SEPA Direct Debit"
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
return displayNames[paymentMethod] || "Unknown Payment Method";
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Get payment method options for dropdown
|
|
322
|
+
* @returns {Array} Array of payment method options
|
|
323
|
+
*/
|
|
324
|
+
export const getPaymentMethodOptions = () => {
|
|
325
|
+
return [
|
|
326
|
+
{ value: "cc", label: "Credit Card (Visa, Mastercard)" },
|
|
327
|
+
{ value: "wlt", label: "PayPal" },
|
|
328
|
+
{ value: "sb", label: "Sofort Banking" },
|
|
329
|
+
{ value: "elv", label: "SEPA Direct Debit" }
|
|
330
|
+
];
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Check if payment method supports capture mode
|
|
335
|
+
* @param {string} paymentMethod - Payment method
|
|
336
|
+
* @returns {boolean} True if supports capture mode
|
|
337
|
+
*/
|
|
338
|
+
export const supportsCaptureMode = (paymentMethod) => {
|
|
339
|
+
return paymentMethod === "wlt"; // Only PayPal supports capture mode
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get capture mode options
|
|
344
|
+
* @returns {Array} Array of capture mode options
|
|
345
|
+
*/
|
|
346
|
+
export const getCaptureModeOptions = () => {
|
|
347
|
+
return [
|
|
348
|
+
{ value: "full", label: "Full Capture" },
|
|
349
|
+
{ value: "partial", label: "Partial Capture" }
|
|
350
|
+
];
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Validate payment parameters based on Payone v1 documentation
|
|
355
|
+
* Comprehensive validation for all operations and payment methods
|
|
356
|
+
* @param {string} operation - Operation type (preauthorization, authorization, capture, refund)
|
|
357
|
+
* @param {string} paymentMethod - Payment method
|
|
358
|
+
* @param {Object} params - Parameters to validate
|
|
359
|
+
* @returns {Object} Validation result with detailed error messages
|
|
360
|
+
*/
|
|
361
|
+
export const validatePaymentParams = (operation, paymentMethod, params) => {
|
|
362
|
+
const errors = [];
|
|
363
|
+
|
|
364
|
+
// Common validations for all operations
|
|
365
|
+
if (!params.amount || params.amount <= 0) {
|
|
366
|
+
errors.push("Amount is required and must be greater than 0");
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (!params.currency) {
|
|
370
|
+
errors.push("Currency is required");
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Validate currency format (ISO 4217)
|
|
374
|
+
if (params.currency && !/^[A-Z]{3}$/.test(params.currency)) {
|
|
375
|
+
errors.push("Currency must be in ISO 4217 format (e.g., EUR, USD)");
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Operation specific validations (Payone v1 documentation)
|
|
379
|
+
switch (operation) {
|
|
380
|
+
case "preauthorization":
|
|
381
|
+
if (!params.reference) {
|
|
382
|
+
errors.push("Reference is required for preauthorization");
|
|
383
|
+
}
|
|
384
|
+
if (!params.customerid) {
|
|
385
|
+
errors.push("Customer ID is required for preauthorization");
|
|
386
|
+
}
|
|
387
|
+
if (!params.firstname || !params.lastname) {
|
|
388
|
+
errors.push("First name and last name are required for preauthorization");
|
|
389
|
+
}
|
|
390
|
+
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
391
|
+
errors.push("Address details (street, zip, city, country) are required for preauthorization");
|
|
392
|
+
}
|
|
393
|
+
if (!params.email) {
|
|
394
|
+
errors.push("Email is required for preauthorization");
|
|
395
|
+
}
|
|
396
|
+
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
397
|
+
errors.push("Success, error, and back URLs are required for preauthorization");
|
|
398
|
+
}
|
|
399
|
+
// Validate email format
|
|
400
|
+
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
401
|
+
errors.push("Email format is invalid");
|
|
402
|
+
}
|
|
403
|
+
break;
|
|
404
|
+
|
|
405
|
+
case "authorization":
|
|
406
|
+
if (!params.reference) {
|
|
407
|
+
errors.push("Reference is required for authorization");
|
|
408
|
+
}
|
|
409
|
+
if (!params.customerid) {
|
|
410
|
+
errors.push("Customer ID is required for authorization");
|
|
411
|
+
}
|
|
412
|
+
if (!params.firstname || !params.lastname) {
|
|
413
|
+
errors.push("First name and last name are required for authorization");
|
|
414
|
+
}
|
|
415
|
+
if (!params.street || !params.zip || !params.city || !params.country) {
|
|
416
|
+
errors.push("Address details (street, zip, city, country) are required for authorization");
|
|
417
|
+
}
|
|
418
|
+
if (!params.email) {
|
|
419
|
+
errors.push("Email is required for authorization");
|
|
420
|
+
}
|
|
421
|
+
if (!params.successurl || !params.errorurl || !params.backurl) {
|
|
422
|
+
errors.push("Success, error, and back URLs are required for authorization");
|
|
423
|
+
}
|
|
424
|
+
// Validate email format
|
|
425
|
+
if (params.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(params.email)) {
|
|
426
|
+
errors.push("Email format is invalid");
|
|
427
|
+
}
|
|
428
|
+
break;
|
|
429
|
+
|
|
430
|
+
case "capture":
|
|
431
|
+
if (!params.txid) {
|
|
432
|
+
errors.push("Transaction ID (txid) is required for capture");
|
|
433
|
+
}
|
|
434
|
+
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
435
|
+
errors.push("Sequence number is required for capture and must be >= 1");
|
|
436
|
+
}
|
|
437
|
+
if (!params.reference) {
|
|
438
|
+
errors.push("Reference is required for capture");
|
|
439
|
+
}
|
|
440
|
+
break;
|
|
441
|
+
|
|
442
|
+
case "refund":
|
|
443
|
+
if (!params.txid) {
|
|
444
|
+
errors.push("Transaction ID (txid) is required for refund");
|
|
445
|
+
}
|
|
446
|
+
if (!params.sequencenumber || params.sequencenumber < 1) {
|
|
447
|
+
errors.push("Sequence number is required for refund and must be >= 1");
|
|
448
|
+
}
|
|
449
|
+
if (!params.reference) {
|
|
450
|
+
errors.push("Reference is required for refund");
|
|
451
|
+
}
|
|
452
|
+
if (params.amount > 0) {
|
|
453
|
+
errors.push("Refund amount must be negative");
|
|
454
|
+
}
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Payment method specific validations (Payone v1 documentation)
|
|
459
|
+
switch (paymentMethod) {
|
|
460
|
+
case "cc":
|
|
461
|
+
if (!params.cardpan || !params.cardexpiredate || !params.cardcvc2) {
|
|
462
|
+
errors.push("Card details (cardpan, cardexpiredate, cardcvc2) are required for credit card payments");
|
|
463
|
+
}
|
|
464
|
+
if (!params.cardtype) {
|
|
465
|
+
errors.push("Card type is required for credit card payments");
|
|
466
|
+
}
|
|
467
|
+
// Validate card number format (basic check)
|
|
468
|
+
if (params.cardpan && !/^\d{13,19}$/.test(params.cardpan.replace(/\s/g, ''))) {
|
|
469
|
+
errors.push("Card number must be 13-19 digits");
|
|
470
|
+
}
|
|
471
|
+
// Validate expiry date format (MMYY)
|
|
472
|
+
if (params.cardexpiredate && !/^\d{4}$/.test(params.cardexpiredate)) {
|
|
473
|
+
errors.push("Card expiry date must be in MMYY format");
|
|
474
|
+
}
|
|
475
|
+
// Validate CVC format (3-4 digits)
|
|
476
|
+
if (params.cardcvc2 && !/^\d{3,4}$/.test(params.cardcvc2)) {
|
|
477
|
+
errors.push("CVC must be 3-4 digits");
|
|
478
|
+
}
|
|
479
|
+
break;
|
|
480
|
+
|
|
481
|
+
case "wlt":
|
|
482
|
+
if (!params.wallettype) {
|
|
483
|
+
errors.push("Wallet type is required for PayPal payments");
|
|
484
|
+
}
|
|
485
|
+
if (params.wallettype && !["PPE", "PAP"].includes(params.wallettype)) {
|
|
486
|
+
errors.push("Wallet type must be PPE (PayPal Express) or PAP (PayPal Plus)");
|
|
487
|
+
}
|
|
488
|
+
break;
|
|
489
|
+
|
|
490
|
+
case "sb":
|
|
491
|
+
if (!params.bankcountry) {
|
|
492
|
+
errors.push("Bank country is required for Sofort payments");
|
|
493
|
+
}
|
|
494
|
+
if (!params.onlinebanktransfertype) {
|
|
495
|
+
errors.push("Online bank transfer type is required for Sofort payments");
|
|
496
|
+
}
|
|
497
|
+
if (params.onlinebanktransfertype && params.onlinebanktransfertype !== "PNT") {
|
|
498
|
+
errors.push("Online bank transfer type must be PNT for Sofort payments");
|
|
499
|
+
}
|
|
500
|
+
break;
|
|
501
|
+
|
|
502
|
+
case "elv":
|
|
503
|
+
if (!params.iban || !params.bic) {
|
|
504
|
+
errors.push("IBAN and BIC are required for SEPA payments");
|
|
505
|
+
}
|
|
506
|
+
if (!params.bankaccountholder) {
|
|
507
|
+
errors.push("Bank account holder is required for SEPA payments");
|
|
508
|
+
}
|
|
509
|
+
if (!params.bankcountry) {
|
|
510
|
+
errors.push("Bank country is required for SEPA payments");
|
|
511
|
+
}
|
|
512
|
+
// Basic IBAN validation
|
|
513
|
+
if (params.iban && params.iban.length < 15) {
|
|
514
|
+
errors.push("IBAN must be at least 15 characters");
|
|
515
|
+
}
|
|
516
|
+
// Basic BIC validation
|
|
517
|
+
if (params.bic && params.bic.length < 8) {
|
|
518
|
+
errors.push("BIC must be at least 8 characters");
|
|
519
|
+
}
|
|
520
|
+
break;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return {
|
|
524
|
+
isValid: errors.length === 0,
|
|
525
|
+
errors,
|
|
526
|
+
errorCount: errors.length
|
|
527
|
+
};
|
|
528
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "strapi-plugin-payone-provider",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Strapi plugin for Payone payment gateway integration",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Strapi Payone Provider Developer"
|
|
8
|
+
},
|
|
9
|
+
"maintainers": [
|
|
10
|
+
{
|
|
11
|
+
"name": "Strapi Payone Provider Developer"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@strapi/design-system": "^1.6.3",
|
|
16
|
+
"@strapi/helper-plugin": "^4.6.0",
|
|
17
|
+
"@strapi/icons": "^1.6.3",
|
|
18
|
+
"axios": "^1.6.2",
|
|
19
|
+
"prop-types": "^15.7.2"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"react": "^18.2.0",
|
|
23
|
+
"react-dom": "^18.2.0",
|
|
24
|
+
"react-router-dom": "^5.3.4",
|
|
25
|
+
"styled-components": "^5.3.6"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": "^17.0.0 || ^18.0.0",
|
|
29
|
+
"react-dom": "^17.0.0 || ^18.0.0",
|
|
30
|
+
"react-router-dom": "^5.2.0",
|
|
31
|
+
"styled-components": "^5.2.1"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=18.0.0 <=20.x.x",
|
|
35
|
+
"npm": ">=6.0.0"
|
|
36
|
+
},
|
|
37
|
+
"strapi": {
|
|
38
|
+
"name": "strapi-plugin-payone-provider",
|
|
39
|
+
"description": "Integrates Strapi Payone payment gateway with Strapi",
|
|
40
|
+
"kind": "plugin",
|
|
41
|
+
"displayName": "Strapi Payone Provider"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
module.exports = async ({ strapi }) => {
|
|
4
|
+
// Initialize plugin settings store
|
|
5
|
+
const pluginStore = strapi.store({
|
|
6
|
+
environment: "",
|
|
7
|
+
type: "plugin",
|
|
8
|
+
name: "payone-provider"
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
// Initialize default settings if not already set
|
|
12
|
+
const settings = await pluginStore.get({ key: "settings" });
|
|
13
|
+
if (!settings) {
|
|
14
|
+
await pluginStore.set({
|
|
15
|
+
key: "settings",
|
|
16
|
+
value: {
|
|
17
|
+
aid: "",
|
|
18
|
+
portalid: "",
|
|
19
|
+
mid: "",
|
|
20
|
+
key: "",
|
|
21
|
+
mode: "test",
|
|
22
|
+
api_version: "3.10"
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { yup } = require("@strapi/utils");
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
default: {
|
|
7
|
+
settings: {
|
|
8
|
+
aid: "",
|
|
9
|
+
portalid: "",
|
|
10
|
+
mid: "",
|
|
11
|
+
key: "",
|
|
12
|
+
mode: "test",
|
|
13
|
+
api_version: "3.10"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
validator(config) {
|
|
17
|
+
if (!config || !config.settings) {
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const schema = yup.object({
|
|
22
|
+
settings: yup
|
|
23
|
+
.object({
|
|
24
|
+
aid: yup.string().defined(),
|
|
25
|
+
portalid: yup.string().defined(),
|
|
26
|
+
mid: yup.string().defined(),
|
|
27
|
+
key: yup.string().defined(),
|
|
28
|
+
mode: yup.mixed().oneOf(["test", "live"]).defined(),
|
|
29
|
+
api_version: yup
|
|
30
|
+
.string()
|
|
31
|
+
.matches(/^\d+\.\d+$/)
|
|
32
|
+
.defined()
|
|
33
|
+
})
|
|
34
|
+
.defined()
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return schema.validateSync(config, {
|
|
38
|
+
abortEarly: false,
|
|
39
|
+
stripUnknown: true
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|