strapi-plugin-payone-provider 1.1.2 → 1.2.4

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 (36) hide show
  1. package/README.md +1045 -330
  2. package/admin/src/index.js +4 -1
  3. package/admin/src/pages/App/components/AppHeader.js +37 -0
  4. package/admin/src/pages/App/components/AppTabs.js +126 -0
  5. package/admin/src/pages/App/components/ConfigurationPanel.js +34 -35
  6. package/admin/src/pages/App/components/GooglePaybutton.js +300 -0
  7. package/admin/src/pages/App/components/HistoryPanel.js +25 -38
  8. package/admin/src/pages/App/components/PaymentActionsPanel.js +95 -280
  9. package/admin/src/pages/App/components/TransactionHistoryItem.js +4 -1
  10. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.js +93 -0
  11. package/admin/src/pages/App/components/paymentActions/CaptureForm.js +64 -0
  12. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.js +52 -0
  13. package/admin/src/pages/App/components/paymentActions/PaymentResult.js +85 -0
  14. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.js +93 -0
  15. package/admin/src/pages/App/components/paymentActions/RefundForm.js +89 -0
  16. package/admin/src/pages/App/index.js +41 -465
  17. package/admin/src/pages/App/styles.css +294 -0
  18. package/admin/src/pages/constants/paymentConstants.js +37 -0
  19. package/admin/src/pages/hooks/usePaymentActions.js +271 -0
  20. package/admin/src/pages/hooks/useSettings.js +111 -0
  21. package/admin/src/pages/hooks/useTransactionHistory.js +87 -0
  22. package/admin/src/pages/utils/api.js +10 -0
  23. package/admin/src/pages/utils/injectGooglePayScript.js +31 -0
  24. package/admin/src/pages/utils/paymentUtils.js +113 -13
  25. package/package.json +1 -1
  26. package/server/controllers/payone.js +71 -64
  27. package/server/routes/index.js +17 -0
  28. package/server/services/paymentService.js +214 -0
  29. package/server/services/payone.js +25 -648
  30. package/server/services/settingsService.js +59 -0
  31. package/server/services/testConnectionService.js +190 -0
  32. package/server/services/transactionService.js +114 -0
  33. package/server/utils/normalize.js +51 -0
  34. package/server/utils/paymentMethodParams.js +126 -0
  35. package/server/utils/requestBuilder.js +110 -0
  36. package/server/utils/responseParser.js +80 -0
@@ -1,679 +1,56 @@
1
1
  "use strict";
2
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
-
3
+ const settingsService = require("./settingsService");
4
+ const transactionService = require("./transactionService");
5
+ const paymentService = require("./paymentService");
6
+ const testConnectionService = require("./testConnectionService");
7
+
8
+ /**
9
+ * Main Payone service - aggregates all sub-services
10
+ */
64
11
  module.exports = ({ strapi }) => ({
12
+ // Settings
65
13
  async getSettings() {
66
- const pluginStore = strapi.store({
67
- environment: "",
68
- type: "plugin",
69
- name: "strapi-plugin-payone-provider"
70
- });
71
- return await pluginStore.get({ key: "settings" });
14
+ return await settingsService.getSettings(strapi);
72
15
  },
73
16
 
74
17
  async updateSettings(settings) {
75
- const pluginStore = strapi.store({
76
- environment: "",
77
- type: "plugin",
78
- name: "strapi-plugin-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;
18
+ return await settingsService.updateSettings(strapi, settings);
264
19
  },
265
20
 
21
+ // Payment operations
266
22
  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);
23
+ return await paymentService.preauthorization(strapi, params);
290
24
  },
291
25
 
292
26
  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);
27
+ return await paymentService.authorization(strapi, params);
304
28
  },
305
29
 
306
30
  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);
31
+ return await paymentService.capture(strapi, params);
326
32
  },
327
33
 
328
34
  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);
35
+ return await paymentService.refund(strapi, params);
347
36
  },
348
37
 
38
+ // Transaction history
349
39
  async logTransaction(transactionData) {
350
- const pluginStore = strapi.store({
351
- environment: "",
352
- type: "plugin",
353
- name: "strapi-plugin-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);
40
+ return await transactionService.logTransaction(strapi, transactionData);
397
41
  },
398
42
 
399
43
  async getTransactionHistory(filters = {}) {
400
- const pluginStore = strapi.store({
401
- environment: "",
402
- type: "plugin",
403
- name: "strapi-plugin-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;
44
+ return await transactionService.getTransactionHistory(strapi, filters);
447
45
  },
448
46
 
47
+ // Test connection
449
48
  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
- }
49
+ return await testConnectionService.testConnection(strapi);
50
+ },
655
51
 
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
- }
52
+ // 3D Secure callback handler
53
+ async handle3DSCallback(callbackData) {
54
+ return await paymentService.handle3DSCallback(strapi, callbackData);
678
55
  }
679
56
  });