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.
Files changed (42) hide show
  1. package/README.md +571 -0
  2. package/admin/src/components/Initializer/index.js +16 -0
  3. package/admin/src/components/PluginIcon/index.js +6 -0
  4. package/admin/src/index.js +37 -0
  5. package/admin/src/pages/App/components/ConfigurationPanel.js +265 -0
  6. package/admin/src/pages/App/components/HistoryPanel.js +298 -0
  7. package/admin/src/pages/App/components/PaymentActionsPanel.js +333 -0
  8. package/admin/src/pages/App/components/StatusBadge.js +22 -0
  9. package/admin/src/pages/App/components/TransactionHistoryItem.js +374 -0
  10. package/admin/src/pages/App/components/icons/BankIcon.js +10 -0
  11. package/admin/src/pages/App/components/icons/ChevronDownIcon.js +9 -0
  12. package/admin/src/pages/App/components/icons/ChevronUpIcon.js +9 -0
  13. package/admin/src/pages/App/components/icons/CreditCardIcon.js +9 -0
  14. package/admin/src/pages/App/components/icons/ErrorIcon.js +10 -0
  15. package/admin/src/pages/App/components/icons/InfoIcon.js +9 -0
  16. package/admin/src/pages/App/components/icons/PaymentIcon.js +10 -0
  17. package/admin/src/pages/App/components/icons/PendingIcon.js +9 -0
  18. package/admin/src/pages/App/components/icons/PersonIcon.js +9 -0
  19. package/admin/src/pages/App/components/icons/SuccessIcon.js +9 -0
  20. package/admin/src/pages/App/components/icons/WalletIcon.js +9 -0
  21. package/admin/src/pages/App/components/icons/index.js +11 -0
  22. package/admin/src/pages/App/index.js +483 -0
  23. package/admin/src/pages/utils/api.js +75 -0
  24. package/admin/src/pages/utils/formatTransactionData.js +16 -0
  25. package/admin/src/pages/utils/paymentUtils.js +528 -0
  26. package/admin/src/pluginId.js +5 -0
  27. package/package.json +43 -0
  28. package/server/bootstrap.js +26 -0
  29. package/server/config/index.js +42 -0
  30. package/server/controllers/index.js +7 -0
  31. package/server/controllers/payone.js +134 -0
  32. package/server/destroy.js +5 -0
  33. package/server/index.js +21 -0
  34. package/server/policies/index.js +6 -0
  35. package/server/policies/isAuth.js +23 -0
  36. package/server/policies/isSuperAdmin.js +18 -0
  37. package/server/register.js +5 -0
  38. package/server/routes/index.js +124 -0
  39. package/server/services/index.js +7 -0
  40. package/server/services/payone.js +679 -0
  41. package/strapi-admin.js +3 -0
  42. package/strapi-server.js +3 -0
@@ -0,0 +1,679 @@
1
+ "use strict";
2
+
3
+ const axios = require("axios");
4
+ const crypto = require("crypto");
5
+
6
+ const POST_GATEWAY_URL = "https://api.pay1.de/post-gateway/";
7
+
8
+ const normalizeReference = (input, fallbackPrefix = "REF") => {
9
+ try {
10
+ const raw = (input == null ? "" : String(input));
11
+ // Keep only alphanumeric characters
12
+ let normalized = raw.replace(/[^A-Za-z0-9]/g, "");
13
+ if (!normalized) {
14
+ normalized = `${fallbackPrefix}${Date.now()}`;
15
+ }
16
+ // Limit length to 20 chars (safe for PAYONE)
17
+ if (normalized.length > 20) normalized = normalized.slice(0, 20);
18
+ return normalized;
19
+ } catch (_) {
20
+ const fallback = `${fallbackPrefix}${Date.now()}`;
21
+ return fallback.slice(0, 20);
22
+ }
23
+ };
24
+
25
+ const buildClientRequestParams = (settings, params) => {
26
+ const requestParams = {
27
+ request: params.request,
28
+ aid: settings.aid,
29
+ mid: settings.mid,
30
+ portalid: settings.portalid,
31
+ mode: settings.mode || "test",
32
+ encoding: "UTF-8",
33
+ ...params
34
+ };
35
+
36
+ requestParams.key = crypto
37
+ .createHash("md5")
38
+ .update(settings.portalKey || settings.key)
39
+ .digest("hex");
40
+
41
+ if (!requestParams.salutation) requestParams.salutation = "Herr";
42
+ if (!requestParams.gender) requestParams.gender = "m";
43
+ if (!requestParams.telephonenumber)
44
+ requestParams.telephonenumber = "01752345678";
45
+ if (!requestParams.ip) requestParams.ip = "127.0.0.1";
46
+ if (!requestParams.language) requestParams.language = "de";
47
+ if (!requestParams.customer_is_present)
48
+ requestParams.customer_is_present = "yes";
49
+
50
+ return requestParams;
51
+ };
52
+
53
+
54
+ const toFormData = (requestParams) => {
55
+ const formData = new URLSearchParams();
56
+ for (const [key, value] of Object.entries(requestParams)) {
57
+ if (value !== undefined && value !== null) {
58
+ formData.append(key, value);
59
+ }
60
+ }
61
+ return formData;
62
+ };
63
+
64
+ module.exports = ({ strapi }) => ({
65
+ async getSettings() {
66
+ const pluginStore = strapi.store({
67
+ environment: "",
68
+ type: "plugin",
69
+ name: "payone-provider"
70
+ });
71
+ return await pluginStore.get({ key: "settings" });
72
+ },
73
+
74
+ async updateSettings(settings) {
75
+ const pluginStore = strapi.store({
76
+ environment: "",
77
+ type: "plugin",
78
+ name: "payone-provider"
79
+ });
80
+ await pluginStore.set({
81
+ key: "settings",
82
+ value: settings
83
+ });
84
+ return settings;
85
+ },
86
+
87
+ async sendRequest(params) {
88
+ try {
89
+ strapi.log.info("Payone sendRequest called with params:", params);
90
+
91
+ const settings = await this.getSettings();
92
+
93
+ if (!settings || !settings.aid || !settings.portalid || !settings.key) {
94
+ throw new Error("Payone settings not configured");
95
+ }
96
+
97
+ const reqType = params.request;
98
+ if (reqType === "authorization" || reqType === "preauthorization" || reqType === "refund") {
99
+ const prefix = reqType === "refund" ? "REF" : reqType === "preauthorization" ? "PRE" : "AUTH";
100
+ params.reference = normalizeReference(params.reference, prefix);
101
+ }
102
+
103
+ const requestParams = buildClientRequestParams(settings, params);
104
+ const debugParams = { ...requestParams };
105
+ if (debugParams.key) debugParams.key = "***HIDDEN***";
106
+ strapi.log.info("Payone Client API request params:", debugParams);
107
+ const formData = toFormData(requestParams);
108
+
109
+ strapi.log.info("Payone form data being sent:", formData.toString());
110
+ strapi.log.info("Payone form data reference:", formData.get("reference"));
111
+
112
+ const response = await axios.post(POST_GATEWAY_URL, formData, {
113
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
114
+ timeout: 30000
115
+ });
116
+
117
+ let dataSample = "null";
118
+ if (response.data) {
119
+ if (typeof response.data === "string") {
120
+ dataSample = response.data.substring(0, 200);
121
+ } else {
122
+ dataSample = JSON.stringify(response.data).substring(0, 200);
123
+ }
124
+ }
125
+ strapi.log.info("Payone raw response:", {
126
+ status: response.status,
127
+ statusText: response.statusText,
128
+ dataType: typeof response.data,
129
+ dataSample,
130
+ fullData:
131
+ typeof response.data === "string"
132
+ ? response.data
133
+ : JSON.stringify(response.data)
134
+ });
135
+
136
+ const responseData = this.parseResponse(response.data);
137
+ const extractTxId = (data) => {
138
+ return (
139
+ data.txid ||
140
+ data.TxId ||
141
+ data.tx_id ||
142
+ data.transactionid ||
143
+ data.transaction_id ||
144
+ data.id ||
145
+ null
146
+ );
147
+ };
148
+
149
+ await this.logTransaction({
150
+ txid: extractTxId(responseData) || params.txid || null,
151
+ reference: params.reference || null,
152
+ status: responseData.status || responseData.Status || "unknown",
153
+ request_type: params.request,
154
+ amount: params.amount || null,
155
+ currency: params.currency || "EUR",
156
+ raw_request: requestParams,
157
+ raw_response: responseData,
158
+ error_code: responseData.Error?.ErrorCode || null,
159
+ error_message: responseData.Error?.ErrorMessage || null,
160
+ customer_message: responseData.Error?.CustomerMessage || null
161
+ });
162
+
163
+ return responseData;
164
+ } catch (error) {
165
+ strapi.log.error("Payone sendRequest error:", error);
166
+ throw error;
167
+ }
168
+ },
169
+
170
+ parseResponse(responseText) {
171
+ try {
172
+ if (typeof responseText === "object") {
173
+ return responseText;
174
+ }
175
+ if (responseText.trim().startsWith("{")) {
176
+ return JSON.parse(responseText);
177
+ }
178
+ } catch (e) {
179
+ strapi.log.error("Payone parseResponse error:", e);
180
+ }
181
+
182
+ const params = new URLSearchParams(responseText);
183
+ const response = {};
184
+ for (const [key, value] of params) {
185
+ response[key.toLowerCase()] = value;
186
+ response[key] = value;
187
+ }
188
+ return response;
189
+ },
190
+
191
+ addPaymentMethodParams(params) {
192
+ const updated = { ...params };
193
+ const clearingtype = updated.clearingtype || "cc";
194
+
195
+ switch (clearingtype) {
196
+ case "cc":
197
+ if (!updated.cardpan) updated.cardpan = "4111111111111111";
198
+ if (!updated.cardexpiredate) updated.cardexpiredate = "2512";
199
+ if (!updated.cardcvc2) updated.cardcvc2 = "123";
200
+ if (!updated.cardtype) updated.cardtype = "V";
201
+ break;
202
+
203
+ case "wlt":
204
+ if (!updated.wallettype) updated.wallettype = "PPE";
205
+ break;
206
+
207
+ case "elv":
208
+ if (!updated.bankcountry) updated.bankcountry = "DE";
209
+ if (!updated.iban) updated.iban = "DE89370400440532013000";
210
+ if (!updated.bic) updated.bic = "COBADEFFXXX";
211
+ if (!updated.bankaccountholder)
212
+ updated.bankaccountholder = `${updated.firstname || "Test"} ${updated.lastname || "User"}`;
213
+ break;
214
+
215
+ case "sb":
216
+ if (!updated.bankcountry) updated.bankcountry = "DE";
217
+ if (!updated.onlinebanktransfertype) updated.onlinebanktransfertype = "PNT";
218
+ break;
219
+
220
+ case "gp":
221
+ if (!updated.bankcountry) updated.bankcountry = "DE";
222
+ if (!updated.onlinebanktransfertype) updated.onlinebanktransfertype = "GPY";
223
+ break;
224
+
225
+ case "idl":
226
+ if (!updated.bankcountry) updated.bankcountry = "NL";
227
+ if (!updated.onlinebanktransfertype) updated.onlinebanktransfertype = "IDL";
228
+ break;
229
+
230
+ case "bct":
231
+ if (!updated.bankcountry) updated.bankcountry = "BE";
232
+ if (!updated.onlinebanktransfertype) updated.onlinebanktransfertype = "BCT";
233
+ break;
234
+
235
+ case "rec":
236
+ if (!updated.recurrence) updated.recurrence = "recurring";
237
+ break;
238
+
239
+ case "fnc":
240
+ if (!updated.financingtype) updated.financingtype = "fnc";
241
+ break;
242
+
243
+ case "iv":
244
+ if (!updated.invoicetype) updated.invoicetype = "invoice";
245
+ break;
246
+
247
+ default:
248
+ strapi.log.warn(`Unknown clearingtype: ${clearingtype}, using credit card defaults`);
249
+ if (!updated.cardpan) updated.cardpan = "4111111111111111";
250
+ if (!updated.cardexpiredate) updated.cardexpiredate = "2512";
251
+ if (!updated.cardcvc2) updated.cardcvc2 = "123";
252
+ if (!updated.cardtype) updated.cardtype = "V";
253
+ break;
254
+ }
255
+
256
+ if (!updated.salutation) updated.salutation = "Herr";
257
+ if (!updated.gender) updated.gender = "m";
258
+ if (!updated.telephonenumber) updated.telephonenumber = "01752345678";
259
+ if (!updated.ip) updated.ip = "127.0.0.1";
260
+ if (!updated.language) updated.language = "de";
261
+ if (!updated.customer_is_present) updated.customer_is_present = "yes";
262
+
263
+ return updated;
264
+ },
265
+
266
+ async preauthorization(params) {
267
+ strapi.log.info("Payone preauthorization called with params:", params);
268
+
269
+ const requiredParams = {
270
+ request: "preauthorization",
271
+ clearingtype: params.clearingtype || "cc",
272
+ ...params
273
+ };
274
+
275
+ if (!requiredParams.amount) requiredParams.amount = 1000;
276
+ if (!requiredParams.currency) requiredParams.currency = "EUR";
277
+ if (!requiredParams.reference)
278
+ requiredParams.reference = `PREAUTH-${Date.now()}`;
279
+ if (!requiredParams.firstname) requiredParams.firstname = "Test";
280
+ if (!requiredParams.lastname) requiredParams.lastname = "User";
281
+ if (!requiredParams.street) requiredParams.street = "Test Street 1";
282
+ if (!requiredParams.zip) requiredParams.zip = "12345";
283
+ if (!requiredParams.city) requiredParams.city = "Test City";
284
+ if (!requiredParams.country) requiredParams.country = "DE";
285
+ if (!requiredParams.email) requiredParams.email = "test@example.com";
286
+
287
+ const updatedParams = this.addPaymentMethodParams(requiredParams);
288
+
289
+ return await this.sendRequest(updatedParams);
290
+ },
291
+
292
+ async authorization(params) {
293
+ strapi.log.info("Payone authorization called with params:", params);
294
+
295
+ const requiredParams = {
296
+ request: "authorization",
297
+ clearingtype: params.clearingtype || "cc",
298
+ ...params
299
+ };
300
+
301
+ const updatedParams = this.addPaymentMethodParams(requiredParams);
302
+
303
+ return await this.sendRequest(updatedParams);
304
+ },
305
+
306
+ async capture(params) {
307
+ strapi.log.info("Payone capture called with params:", params);
308
+
309
+ if (!params.txid) {
310
+ throw new Error("Transaction ID (txid) is required for capture");
311
+ }
312
+
313
+ const requiredParams = {
314
+ request: "capture",
315
+ txid: params.txid,
316
+ amount: params.amount || 1000,
317
+ currency: params.currency || "EUR",
318
+ ...params
319
+ };
320
+
321
+ delete requiredParams.reference;
322
+
323
+ strapi.log.info("Payone capture required params:", requiredParams);
324
+
325
+ return await this.sendRequest(requiredParams);
326
+ },
327
+
328
+ async refund(params) {
329
+ strapi.log.info("Payone refund called with params:", params);
330
+
331
+ if (!params.txid) {
332
+ throw new Error("Transaction ID (txid) is required for refund");
333
+ }
334
+
335
+ const requiredParams = {
336
+ request: "refund",
337
+ txid: params.txid,
338
+ ...params
339
+ };
340
+
341
+ if (!requiredParams.amount) requiredParams.amount = 1000; // 10.00 EUR in cents
342
+ if (!requiredParams.currency) requiredParams.currency = "EUR";
343
+ if (!requiredParams.reference)
344
+ requiredParams.reference = `REFUND-${Date.now()}`;
345
+
346
+ return await this.sendRequest(requiredParams);
347
+ },
348
+
349
+ async logTransaction(transactionData) {
350
+ const pluginStore = strapi.store({
351
+ environment: "",
352
+ type: "plugin",
353
+ name: "payone-provider"
354
+ });
355
+
356
+ let transactionHistory =
357
+ (await pluginStore.get({ key: "transactionHistory" })) || [];
358
+
359
+ const logEntry = {
360
+ id: Date.now().toString(),
361
+ timestamp: new Date().toISOString(),
362
+ txid: transactionData.txid || null,
363
+ reference: transactionData.reference || null,
364
+ request_type:
365
+ transactionData.request_type || transactionData.request || "unknown",
366
+ amount: transactionData.amount || null,
367
+ currency: transactionData.currency || "EUR",
368
+ status: transactionData.status || transactionData.Status || "unknown",
369
+ error_code:
370
+ transactionData.error_code || transactionData.Error?.ErrorCode || null,
371
+ error_message:
372
+ transactionData.error_message ||
373
+ transactionData.Error?.ErrorMessage ||
374
+ null,
375
+ customer_message:
376
+ transactionData.customer_message ||
377
+ transactionData.Error?.CustomerMessage ||
378
+ null,
379
+ raw_request: transactionData.raw_request || null,
380
+ raw_response: transactionData.raw_response || transactionData,
381
+ created_at: new Date().toISOString(),
382
+ updated_at: new Date().toISOString()
383
+ };
384
+
385
+ transactionHistory.unshift(logEntry);
386
+
387
+ if (transactionHistory.length > 1000) {
388
+ transactionHistory = transactionHistory.slice(0, 1000);
389
+ }
390
+
391
+ await pluginStore.set({
392
+ key: "transactionHistory",
393
+ value: transactionHistory
394
+ });
395
+
396
+ strapi.log.info("Transaction logged:", logEntry);
397
+ },
398
+
399
+ async getTransactionHistory(filters = {}) {
400
+ const pluginStore = strapi.store({
401
+ environment: "",
402
+ type: "plugin",
403
+ name: "payone-provider"
404
+ });
405
+
406
+ let transactionHistory =
407
+ (await pluginStore.get({ key: "transactionHistory" })) || [];
408
+
409
+ if (filters.status) {
410
+ transactionHistory = transactionHistory.filter(
411
+ (transaction) => transaction.status === filters.status
412
+ );
413
+ }
414
+
415
+ if (filters.request_type) {
416
+ transactionHistory = transactionHistory.filter(
417
+ (transaction) => transaction.request_type === filters.request_type
418
+ );
419
+ }
420
+
421
+ if (filters.txid) {
422
+ transactionHistory = transactionHistory.filter(
423
+ (transaction) => transaction.txid === filters.txid
424
+ );
425
+ }
426
+
427
+ if (filters.reference) {
428
+ transactionHistory = transactionHistory.filter(
429
+ (transaction) => transaction.reference === filters.reference
430
+ );
431
+ }
432
+
433
+ if (filters.date_from) {
434
+ transactionHistory = transactionHistory.filter(
435
+ (transaction) =>
436
+ new Date(transaction.timestamp) >= new Date(filters.date_from)
437
+ );
438
+ }
439
+
440
+ if (filters.date_to) {
441
+ transactionHistory = transactionHistory.filter(
442
+ (transaction) =>
443
+ new Date(transaction.timestamp) <= new Date(filters.date_to)
444
+ );
445
+ }
446
+ return transactionHistory;
447
+ },
448
+
449
+ async testConnection() {
450
+ try {
451
+ const settings = await this.getSettings();
452
+
453
+ if (!settings || !settings.aid || !settings.portalid || !settings.key) {
454
+ return {
455
+ success: false,
456
+ message:
457
+ "Payone settings not configured. Please fill in all required fields."
458
+ };
459
+ }
460
+
461
+ const timestamp = Date.now();
462
+ const testParams = {
463
+ request: "authorization",
464
+ amount: 100,
465
+ currency: "EUR",
466
+ reference: `TEST-${timestamp}`, // Unique reference for each test
467
+ clearingtype: "cc",
468
+ cardtype: "V",
469
+ cardpan: "4111111111111111",
470
+ cardexpiredate: "2512",
471
+ cardcvc2: "123",
472
+ firstname: "Test",
473
+ lastname: "User",
474
+ street: "Test Street 1",
475
+ zip: "12345",
476
+ city: "Test City",
477
+ country: "DE",
478
+ email: "test@example.com",
479
+ salutation: "Herr",
480
+ gender: "m",
481
+ telephonenumber: "01752345678",
482
+ ip: "127.0.0.1",
483
+ customer_is_present: "yes",
484
+ language: "de"
485
+ };
486
+
487
+ const originalSendRequest = this.sendRequest.bind(this);
488
+ this.sendRequest = async (params) => {
489
+ try {
490
+ const settings = await this.getSettings();
491
+
492
+ if (
493
+ !settings ||
494
+ !settings.aid ||
495
+ !settings.portalid ||
496
+ !settings.key
497
+ ) {
498
+ throw new Error("Payone settings not configured");
499
+ }
500
+
501
+ const requestParams = buildClientRequestParams(settings, params);
502
+ const formData = toFormData(requestParams);
503
+
504
+ // Send request to Payone
505
+ const response = await axios.post(POST_GATEWAY_URL, formData, {
506
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
507
+ timeout: 30000
508
+ });
509
+ const responseData = this.parseResponse(response.data);
510
+
511
+ return responseData;
512
+ } catch (error) {
513
+ strapi.log.error("Payone API request failed:", error.message);
514
+
515
+ if (error.response) {
516
+ strapi.log.error("Response error:", {
517
+ status: error.response.status,
518
+ data: error.response.data
519
+ });
520
+ }
521
+
522
+ throw error;
523
+ }
524
+ };
525
+
526
+ const result = await this.sendRequest(testParams);
527
+
528
+ this.sendRequest = originalSendRequest;
529
+
530
+ const status = result.status || result.Status || result.STATUS;
531
+ const errorMessage =
532
+ result.errormessage ||
533
+ result.Errormessage ||
534
+ result.ERRORMESSAGE ||
535
+ result.error ||
536
+ result.Error ||
537
+ result.ERROR ||
538
+ "";
539
+ const errorCode =
540
+ result.errorcode ||
541
+ result.Errorcode ||
542
+ result.ERRORCODE ||
543
+ (result.Error && result.Error.ErrorCode) ||
544
+ "";
545
+ const customErrorMessage =
546
+ result.customerrormessage ||
547
+ result.Customerrormessage ||
548
+ result.CUSTOMERRORMESSAGE ||
549
+ (result.Error && result.Error.CustomerMessage) ||
550
+ "";
551
+
552
+ strapi.log.info("Payone test connection response:", {
553
+ status,
554
+ errorCode,
555
+ keys: Object.keys(result)
556
+ });
557
+
558
+ if (status === "ERROR" || status === "error") {
559
+ // First check for authentication errors (including "Key incorrect")
560
+ if (
561
+ errorCode === "2006" ||
562
+ errorCode === "920" ||
563
+ errorCode === "921" ||
564
+ errorCode === "922" ||
565
+ errorCode === "401" || // common unauthorized style codes
566
+ errorCode === "403"
567
+ ) {
568
+ const errorMsg =
569
+ customErrorMessage ||
570
+ (typeof errorMessage === "string"
571
+ ? errorMessage
572
+ : JSON.stringify(errorMessage)) ||
573
+ "Invalid credentials";
574
+ return {
575
+ success: false,
576
+ message: `Authentication failed: ${errorMsg}`,
577
+ errorcode: errorCode
578
+ };
579
+ }
580
+
581
+ // Additional heuristic for invalid credentials based on message content
582
+ const errorMessageStr =
583
+ typeof errorMessage === "string"
584
+ ? errorMessage
585
+ : JSON.stringify(errorMessage);
586
+ const errorMessageLower = (errorMessageStr || "").toLowerCase();
587
+ if (
588
+ errorMessageLower.includes("key incorrect") ||
589
+ errorMessageLower.includes("invalid key") ||
590
+ errorMessageLower.includes("portal key") ||
591
+ errorMessageLower.includes("unauthorized") ||
592
+ errorMessageLower.includes("not authorized") ||
593
+ errorMessageLower.includes("unknown aid") ||
594
+ errorMessageLower.includes("unknown account") ||
595
+ errorMessageLower.includes("unknown portal") ||
596
+ errorMessageLower.includes("unknown merchant") ||
597
+ errorMessageLower.includes("invalid aid") ||
598
+ errorMessageLower.includes("invalid mid") ||
599
+ errorMessageLower.includes("invalid portalid")
600
+ ) {
601
+ return {
602
+ success: false,
603
+ message: `Authentication failed: ${errorMessageStr}`,
604
+ errorcode: errorCode || "AUTH"
605
+ };
606
+ }
607
+
608
+ // Check for reference already exists (911) - this means credentials are working
609
+ if (errorCode === "911") {
610
+ return {
611
+ success: true,
612
+ message:
613
+ "Connection successful! Your Payone credentials are valid.",
614
+ details: {
615
+ mode: settings.mode,
616
+ aid: settings.aid,
617
+ portalid: settings.portalid,
618
+ mid: settings.mid
619
+ }
620
+ };
621
+ }
622
+
623
+ // Otherwise, for any ERROR status treat as failure
624
+ const errorMsg =
625
+ customErrorMessage ||
626
+ (typeof errorMessage === "string"
627
+ ? errorMessage
628
+ : JSON.stringify(errorMessage)) ||
629
+ "Unknown error";
630
+ return {
631
+ success: false,
632
+ message: `Connection failed: ${errorMsg}`,
633
+ errorcode: errorCode,
634
+ details: {
635
+ status,
636
+ errorCode,
637
+ rawResponse: JSON.stringify(result).substring(0, 200) // Include partial raw response for debugging
638
+ }
639
+ };
640
+ }
641
+
642
+ // APPROVED status shouldn't happen with dummy txid, but if it does, connection is OK
643
+ if (status === "APPROVED" || status === "approved") {
644
+ return {
645
+ success: true,
646
+ message: "Connection successful! Your Payone credentials are valid.",
647
+ details: {
648
+ mode: settings.mode,
649
+ aid: settings.aid,
650
+ portalid: settings.portalid,
651
+ mid: settings.mid
652
+ }
653
+ };
654
+ }
655
+
656
+ return {
657
+ success: false,
658
+ message: "Unexpected response format from Payone API",
659
+ response: result,
660
+ details: {
661
+ status,
662
+ keys: Object.keys(result),
663
+ rawResponse: JSON.stringify(result).substring(0, 200)
664
+ }
665
+ };
666
+ } catch (error) {
667
+ strapi.log.error("Payone test connection error:", error);
668
+ return {
669
+ success: false,
670
+ message: `Connection error: ${error.message || "Unknown error"}`,
671
+ error: error.toString(),
672
+ details: {
673
+ errorType: error.constructor.name,
674
+ stack: error.stack ? error.stack.substring(0, 200) : "No stack trace"
675
+ }
676
+ };
677
+ }
678
+ }
679
+ });
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ module.exports = require("./admin/src");
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ module.exports = require("./server");