strapi-plugin-payone-provider 1.5.8-beta.1 → 1.6.0
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/admin/src/index.js +3 -3
- package/admin/src/pages/App/components/ApplePayBtn.jsx +304 -0
- package/admin/src/pages/App/components/{ApplePayButton.js → ApplePayButton.jsx} +4 -46
- package/admin/src/pages/App/components/{ApplePayConfig.js → ApplePayConfig.jsx} +64 -130
- package/admin/src/pages/App/components/{PaymentActionsPanel.js → PaymentActionsPanel.jsx} +62 -14
- package/admin/src/pages/App/components/icons/index.jsx +11 -0
- package/admin/src/pages/App/components/paymentActions/{AuthorizationForm.js → AuthorizationForm.jsx} +45 -35
- package/admin/src/pages/App/components/paymentActions/{PaymentMethodSelector.js → PaymentMethodSelector.jsx} +111 -31
- package/admin/src/pages/App/components/paymentActions/{PreauthorizationForm.js → PreauthorizationForm.jsx} +3 -70
- package/admin/src/pages/constants/paymentConstants.js +1 -2
- package/admin/src/pages/hooks/usePaymentActions.js +1 -76
- package/package.json +49 -49
- package/server/bootstrap.js +59 -1
- package/server/controllers/payone.js +6 -77
- package/server/routes/index.js +1 -1
- package/server/services/applePayService.js +51 -509
- package/server/services/paymentService.js +0 -68
- package/server/services/payone.js +0 -3
- package/server/services/settingsService.js +0 -21
- package/server/services/testConnectionService.js +0 -14
- package/server/services/transactionService.js +2 -16
- package/server/utils/paymentMethodParams.js +60 -21
- package/server/utils/requestBuilder.js +0 -22
- package/admin/src/pages/App/components/icons/index.js +0 -11
- /package/admin/src/components/Initializer/{index.js → index.jsx} +0 -0
- /package/admin/src/components/PluginIcon/{index.js → index.jsx} +0 -0
- /package/admin/src/pages/App/components/{AppHeader.js → AppHeader.jsx} +0 -0
- /package/admin/src/pages/App/components/{AppTabs.js → AppTabs.jsx} +0 -0
- /package/admin/src/pages/App/components/{ApplePayConfigPanel.js → ApplePayConfigPanel.jsx} +0 -0
- /package/admin/src/pages/App/components/{ConfigurationPanel.js → ConfigurationPanel.jsx} +0 -0
- /package/admin/src/pages/App/components/{DocsPanel.js → DocsPanel.jsx} +0 -0
- /package/admin/src/pages/App/components/{GooglePayConfig.js → GooglePayConfig.jsx} +0 -0
- /package/admin/src/pages/App/components/{GooglePayConfigPanel.js → GooglePayConfigPanel.jsx} +0 -0
- /package/admin/src/pages/App/components/{GooglePaybutton.js → GooglePaybutton.jsx} +0 -0
- /package/admin/src/pages/App/components/{HistoryPanel.js → HistoryPanel.jsx} +0 -0
- /package/admin/src/pages/App/components/{StatusBadge.js → StatusBadge.jsx} +0 -0
- /package/admin/src/pages/App/components/{TransactionHistoryItem.js → TransactionHistoryItem.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{BankIcon.js → BankIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{ChevronDownIcon.js → ChevronDownIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{ChevronUpIcon.js → ChevronUpIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{CreditCardIcon.js → CreditCardIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{ErrorIcon.js → ErrorIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{InfoIcon.js → InfoIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{PaymentIcon.js → PaymentIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{PendingIcon.js → PendingIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{PersonIcon.js → PersonIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{SuccessIcon.js → SuccessIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/icons/{WalletIcon.js → WalletIcon.jsx} +0 -0
- /package/admin/src/pages/App/components/paymentActions/{CaptureForm.js → CaptureForm.jsx} +0 -0
- /package/admin/src/pages/App/components/paymentActions/{CardDetailsInput.js → CardDetailsInput.jsx} +0 -0
- /package/admin/src/pages/App/components/paymentActions/{PaymentResult.js → PaymentResult.jsx} +0 -0
- /package/admin/src/pages/App/components/paymentActions/{RefundForm.js → RefundForm.jsx} +0 -0
- /package/admin/src/pages/App/{index.js → index.jsx} +0 -0
|
@@ -6,183 +6,48 @@ const { getSettings, validateSettings } = require("./settingsService");
|
|
|
6
6
|
|
|
7
7
|
const POST_GATEWAY_URL = "https://api.pay1.de/post-gateway/";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
* - add_paydata[domain_name]="yourdomain.com"
|
|
22
|
-
*/
|
|
9
|
+
const parseResponse = (responseData) => {
|
|
10
|
+
if (typeof responseData === 'string') {
|
|
11
|
+
const params = new URLSearchParams(responseData);
|
|
12
|
+
const parsed = {};
|
|
13
|
+
for (const [key, value] of params.entries()) {
|
|
14
|
+
parsed[key] = value;
|
|
15
|
+
}
|
|
16
|
+
return parsed;
|
|
17
|
+
}
|
|
18
|
+
return responseData;
|
|
19
|
+
};
|
|
20
|
+
|
|
23
21
|
const initializeApplePaySession = async (strapi, params) => {
|
|
24
22
|
try {
|
|
25
|
-
strapi.log.info("[Apple Pay] Initializing Apple Pay session with Payone");
|
|
26
|
-
strapi.log.info("[Apple Pay] Request params:", JSON.stringify(params, null, 2));
|
|
27
|
-
|
|
28
23
|
const settings = await getSettings(strapi);
|
|
24
|
+
const { displayName, domainName } = params;
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new Error("Payone settings not configured");
|
|
33
|
-
}
|
|
26
|
+
const merchantName = displayName || "Store";
|
|
27
|
+
const domain = domainName;
|
|
34
28
|
|
|
35
|
-
|
|
36
|
-
mode: settings.mode,
|
|
37
|
-
mid: settings.mid,
|
|
38
|
-
portalid: settings.portalid,
|
|
39
|
-
hasKey: !!settings.key
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const {
|
|
43
|
-
displayName,
|
|
44
|
-
domainName,
|
|
45
|
-
mid,
|
|
46
|
-
portalid
|
|
47
|
-
} = params;
|
|
48
|
-
|
|
49
|
-
// Get merchant data from settings (test or live mode)
|
|
50
|
-
const merchantName = displayName || settings.merchantName || settings.displayName || "Test Store";
|
|
51
|
-
const merchantId = mid || settings.mid || settings.merchantIdentifier;
|
|
52
|
-
const portalId = portalid || settings.portalid;
|
|
53
|
-
const accountId = settings.aid;
|
|
54
|
-
const apiKey = settings.key;
|
|
55
|
-
const mode = settings.mode || "test"; // test or live
|
|
56
|
-
|
|
57
|
-
// Get domain from params or settings or server config
|
|
58
|
-
const domain = domainName || settings.domainName ||
|
|
59
|
-
(strapi.config.get("server.url") ? new URL(strapi.config.get("server.url")).hostname : null) ||
|
|
60
|
-
"localhost";
|
|
61
|
-
|
|
62
|
-
// Build request parameters for Apple Pay session initialization
|
|
63
|
-
// According to Payone documentation: request="genericpayment"
|
|
64
|
-
const requestParams = {
|
|
29
|
+
const baseParams = {
|
|
65
30
|
request: "genericpayment",
|
|
66
|
-
mid: merchantId,
|
|
67
|
-
aid: accountId,
|
|
68
|
-
portalid: portalId,
|
|
69
|
-
key: apiKey,
|
|
70
|
-
mode: mode, // Use test or live mode from settings
|
|
71
31
|
clearingtype: "wlt",
|
|
72
32
|
wallettype: "APL",
|
|
73
|
-
currency:
|
|
33
|
+
currency: params.currency,
|
|
74
34
|
"add_paydata[action]": "init_applepay_session",
|
|
75
35
|
"add_paydata[display_name]": merchantName,
|
|
76
36
|
"add_paydata[domain_name]": domain
|
|
77
37
|
};
|
|
78
38
|
|
|
79
|
-
|
|
80
|
-
url: POST_GATEWAY_URL,
|
|
81
|
-
mode: mode,
|
|
82
|
-
merchantName: merchantName,
|
|
83
|
-
domain: domain,
|
|
84
|
-
merchantId: merchantId,
|
|
85
|
-
portalId: portalId
|
|
86
|
-
});
|
|
39
|
+
const requestParams = buildClientRequestParams(settings, baseParams, strapi.log);
|
|
87
40
|
|
|
88
41
|
const formData = toFormData(requestParams);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
params: {
|
|
93
|
-
...requestParams,
|
|
94
|
-
key: "***HIDDEN***" // Hide API key in logs
|
|
95
|
-
}
|
|
42
|
+
const response = await axios.post(`${POST_GATEWAY_URL}Genericpayment`, formData, {
|
|
43
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
44
|
+
timeout: 30000
|
|
96
45
|
});
|
|
97
46
|
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
response = await axios.post(POST_GATEWAY_URL, formData, {
|
|
101
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
102
|
-
timeout: 30000
|
|
103
|
-
});
|
|
104
|
-
} catch (axiosError) {
|
|
105
|
-
strapi.log.error("[Apple Pay] Payone API request failed:", {
|
|
106
|
-
message: axiosError.message,
|
|
107
|
-
status: axiosError.response?.status,
|
|
108
|
-
statusText: axiosError.response?.statusText,
|
|
109
|
-
data: axiosError.response?.data,
|
|
110
|
-
config: {
|
|
111
|
-
url: axiosError.config?.url,
|
|
112
|
-
method: axiosError.config?.method
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
throw axiosError;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
strapi.log.info("[Apple Pay] ========== PAYONE RESPONSE START ==========");
|
|
119
|
-
strapi.log.info("[Apple Pay] HTTP Status:", response.status);
|
|
120
|
-
strapi.log.info("[Apple Pay] HTTP Status Text:", response.statusText);
|
|
121
|
-
strapi.log.info("[Apple Pay] Response Headers:", JSON.stringify(response.headers, null, 2));
|
|
122
|
-
strapi.log.info("[Apple Pay] Raw Response Data Type:", typeof response.data);
|
|
123
|
-
strapi.log.info("[Apple Pay] Raw Response Data:", response.data);
|
|
124
|
-
|
|
125
|
-
// Parse response
|
|
126
|
-
const responseData = parseResponse(response.data, strapi.log);
|
|
127
|
-
|
|
128
|
-
strapi.log.info("[Apple Pay] ========== PARSED RESPONSE ==========");
|
|
129
|
-
strapi.log.info("[Apple Pay] Full Parsed Response (JSON):", JSON.stringify(responseData, null, 2));
|
|
130
|
-
strapi.log.info("[Apple Pay] Response Type:", typeof responseData);
|
|
131
|
-
strapi.log.info("[Apple Pay] Is Object:", responseData instanceof Object);
|
|
132
|
-
strapi.log.info("[Apple Pay] All Response Keys:", Object.keys(responseData));
|
|
133
|
-
strapi.log.info("[Apple Pay] Response Keys Count:", Object.keys(responseData).length);
|
|
134
|
-
|
|
135
|
-
// Log each key-value pair
|
|
136
|
-
strapi.log.info("[Apple Pay] ========== RESPONSE KEY-VALUE PAIRS ==========");
|
|
137
|
-
for (const [key, value] of Object.entries(responseData)) {
|
|
138
|
-
if (typeof value === 'string' && value.length > 200) {
|
|
139
|
-
strapi.log.info(`[Apple Pay] ${key}:`, value.substring(0, 200) + "... (truncated, length: " + value.length + ")");
|
|
140
|
-
} else {
|
|
141
|
-
strapi.log.info(`[Apple Pay] ${key}:`, value);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
strapi.log.info("[Apple Pay] ========== IMPORTANT FIELDS ==========");
|
|
146
|
-
strapi.log.info("[Apple Pay] status:", responseData.status || responseData.Status || "NOT_SET");
|
|
147
|
-
strapi.log.info("[Apple Pay] Status (lowercase):", responseData.status || "NOT_SET");
|
|
148
|
-
strapi.log.info("[Apple Pay] Status (uppercase):", responseData.Status || "NOT_SET");
|
|
149
|
-
strapi.log.info("[Apple Pay] errorcode:", responseData.errorcode || responseData.ErrorCode || responseData.error_code || "none");
|
|
150
|
-
strapi.log.info("[Apple Pay] errormessage:", responseData.errormessage || responseData.ErrorMessage || responseData.errortxt || responseData.ErrorTxt || responseData.error_message || "none");
|
|
151
|
-
strapi.log.info("[Apple Pay] workorderid:", responseData.workorderid || responseData.workorderId || responseData.WorkorderId || "none");
|
|
152
|
-
strapi.log.info("[Apple Pay] txid:", responseData.txid || responseData.TxId || responseData.tx_id || "none");
|
|
153
|
-
|
|
154
|
-
// Check for Apple Pay session in various formats
|
|
155
|
-
strapi.log.info("[Apple Pay] ========== APPLE PAY SESSION CHECK ==========");
|
|
156
|
-
const applePaySessionKeys = [
|
|
157
|
-
"add_paydata[applepay_payment_session]",
|
|
158
|
-
"add_paydata_applepay_payment_session",
|
|
159
|
-
"addPaydata[applepay_payment_session]",
|
|
160
|
-
"addPaydata_applepay_payment_session",
|
|
161
|
-
"applepay_payment_session",
|
|
162
|
-
"applePayPaymentSession",
|
|
163
|
-
"payment_session",
|
|
164
|
-
"paymentSession"
|
|
165
|
-
];
|
|
166
|
-
|
|
167
|
-
for (const key of applePaySessionKeys) {
|
|
168
|
-
if (responseData[key]) {
|
|
169
|
-
strapi.log.info(`[Apple Pay] Found Apple Pay session in key: ${key}`);
|
|
170
|
-
strapi.log.info(`[Apple Pay] Session value length: ${responseData[key].length}`);
|
|
171
|
-
strapi.log.info(`[Apple Pay] Session value preview: ${responseData[key].substring(0, 100)}...`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Check add_paydata object if it exists
|
|
176
|
-
if (responseData.add_paydata) {
|
|
177
|
-
strapi.log.info("[Apple Pay] add_paydata object exists:", typeof responseData.add_paydata);
|
|
178
|
-
strapi.log.info("[Apple Pay] add_paydata keys:", Object.keys(responseData.add_paydata));
|
|
179
|
-
strapi.log.info("[Apple Pay] add_paydata content:", JSON.stringify(responseData.add_paydata, null, 2));
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
strapi.log.info("[Apple Pay] ========== PAYONE RESPONSE END ==========");
|
|
47
|
+
const responseData = parseResponse(response.data);
|
|
183
48
|
|
|
184
49
|
if (responseData.errorcode || responseData.ErrorCode) {
|
|
185
|
-
strapi.log.
|
|
50
|
+
strapi.log.error("[Apple Pay] Payone error:", {
|
|
186
51
|
errorcode: responseData.errorcode || responseData.ErrorCode,
|
|
187
52
|
errormessage: responseData.errormessage || responseData.ErrorMessage
|
|
188
53
|
});
|
|
@@ -199,374 +64,51 @@ const initializeApplePaySession = async (strapi, params) => {
|
|
|
199
64
|
}
|
|
200
65
|
};
|
|
201
66
|
|
|
202
|
-
/**
|
|
203
|
-
* Validate Apple Pay merchant with Payone
|
|
204
|
-
* This is called when Apple Pay requests merchant validation
|
|
205
|
-
*/
|
|
206
67
|
const validateApplePayMerchant = async (strapi, params) => {
|
|
207
|
-
|
|
208
|
-
strapi.log.info("[Apple Pay] Validating merchant with Payone");
|
|
209
|
-
strapi.log.info("[Apple Pay] Validation params:", JSON.stringify({
|
|
210
|
-
validationURL: params.validationURL,
|
|
211
|
-
domain: params.domain,
|
|
212
|
-
displayName: params.displayName,
|
|
213
|
-
mid: params.mid,
|
|
214
|
-
portalid: params.portalid
|
|
215
|
-
}, null, 2));
|
|
216
|
-
|
|
217
|
-
const settings = await getSettings(strapi);
|
|
218
|
-
|
|
219
|
-
if (!validateSettings(settings)) {
|
|
220
|
-
strapi.log.error("[Apple Pay] Payone settings not configured for merchant validation");
|
|
221
|
-
throw new Error("Payone settings not configured");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Log all settings to verify MerchantId is being read correctly
|
|
225
|
-
strapi.log.info("[Apple Pay] ========== SETTINGS FROM CONFIG ==========");
|
|
226
|
-
strapi.log.info("[Apple Pay] Full Settings Object:", JSON.stringify(settings, null, 2));
|
|
227
|
-
strapi.log.info("[Apple Pay] Settings Keys:", Object.keys(settings || {}));
|
|
228
|
-
strapi.log.info("[Apple Pay] MerchantId (mid) from config:", settings.mid || "NOT_SET");
|
|
229
|
-
strapi.log.info("[Apple Pay] MerchantId type:", typeof settings.mid);
|
|
230
|
-
strapi.log.info("[Apple Pay] MerchantId length:", settings.mid ? settings.mid.length : 0);
|
|
231
|
-
strapi.log.info("[Apple Pay] merchantIdentifier from config:", settings.merchantIdentifier || "NOT_SET");
|
|
232
|
-
strapi.log.info("[Apple Pay] portalid from config:", settings.portalid || "NOT_SET");
|
|
233
|
-
strapi.log.info("[Apple Pay] mode from config:", settings.mode || "NOT_SET");
|
|
234
|
-
strapi.log.info("[Apple Pay] ==========================================");
|
|
235
|
-
|
|
236
|
-
const {
|
|
237
|
-
validationURL,
|
|
238
|
-
mid,
|
|
239
|
-
portalid,
|
|
240
|
-
domain,
|
|
241
|
-
displayName
|
|
242
|
-
} = params;
|
|
243
|
-
|
|
244
|
-
// Get merchant data from settings (test or live mode)
|
|
245
|
-
const merchantName = displayName || settings.merchantName || settings.displayName || "Test Store";
|
|
68
|
+
const settings = await getSettings(strapi);
|
|
246
69
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
strapi.log.info("[Apple Pay] ========== MERCHANT ID SELECTION ==========");
|
|
253
|
-
strapi.log.info("[Apple Pay] mid from params:", mid || "NOT_PROVIDED");
|
|
254
|
-
strapi.log.info("[Apple Pay] settings.mid:", settings.mid || "NOT_SET");
|
|
255
|
-
strapi.log.info("[Apple Pay] settings.merchantIdentifier:", settings.merchantIdentifier || "NOT_SET");
|
|
256
|
-
strapi.log.info("[Apple Pay] Selected merchantId:", merchantId || "NOT_SET");
|
|
257
|
-
strapi.log.info("[Apple Pay] Selected merchantId type:", typeof merchantId);
|
|
258
|
-
strapi.log.info("[Apple Pay] Selected merchantId length:", merchantId ? merchantId.length : 0);
|
|
259
|
-
strapi.log.info("[Apple Pay] ==========================================");
|
|
260
|
-
|
|
261
|
-
// Get domain from params or settings or server config
|
|
262
|
-
const domainName = domain || settings.domainName ||
|
|
263
|
-
(strapi.config.get("server.url") ? new URL(strapi.config.get("server.url")).hostname : null) ||
|
|
264
|
-
"localhost";
|
|
70
|
+
if (!validateSettings(settings)) {
|
|
71
|
+
strapi.log.error("Payone settings not configured");
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
265
74
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const sessionParams = {
|
|
270
|
-
displayName: merchantName,
|
|
271
|
-
domainName: domainName,
|
|
272
|
-
mid: merchantId,
|
|
273
|
-
portalid: portalId
|
|
274
|
-
};
|
|
75
|
+
const sessionResponse = await initializeApplePaySession(strapi, params);
|
|
76
|
+
const applePaySessionBase64 = sessionResponse["add_paydata[applepay_payment_session]"] ||
|
|
77
|
+
sessionResponse.add_paydata?.applepay_payment_session;
|
|
275
78
|
|
|
276
|
-
|
|
79
|
+
if (sessionResponse.status === "OK" && applePaySessionBase64 && applePaySessionBase64.length > 0) {
|
|
80
|
+
const merchantSessionJson = Buffer.from(applePaySessionBase64, 'base64').toString('utf-8');
|
|
81
|
+
const merchantSession = JSON.parse(merchantSessionJson);
|
|
277
82
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
try {
|
|
281
|
-
sessionResponse = await initializeApplePaySession(strapi, sessionParams);
|
|
282
|
-
} catch (error) {
|
|
283
|
-
strapi.log.error("[Apple Pay] Failed to initialize session with Payone:", {
|
|
284
|
-
message: error.message,
|
|
285
|
-
status: error.response?.status,
|
|
286
|
-
data: error.response?.data,
|
|
287
|
-
stack: error.stack
|
|
288
|
-
});
|
|
289
|
-
// DO NOT return empty object - throw error instead
|
|
290
|
-
// Empty object causes Apple Pay to close dialog without proper error message
|
|
291
|
-
throw new Error(`Failed to initialize Apple Pay session with Payone: ${error.message}. Please check your Payone configuration and ensure Apple Pay is properly set up in PMI.`);
|
|
83
|
+
if (merchantSession.epochTimestamp && merchantSession.epochTimestamp > 1000000000000) {
|
|
84
|
+
merchantSession.epochTimestamp = Math.floor(merchantSession.epochTimestamp / 1000);
|
|
292
85
|
}
|
|
293
86
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
hasMerchantIdentifier: !!(sessionResponse.merchantIdentifier || sessionResponse.merchantSessionIdentifier),
|
|
297
|
-
hasApplePaySession: !!(sessionResponse["add_paydata[applepay_payment_session]"] ||
|
|
298
|
-
sessionResponse["add_paydata[applepay_payment_session]"] ||
|
|
299
|
-
sessionResponse.add_paydata?.applepay_payment_session),
|
|
300
|
-
fullResponse: JSON.stringify(sessionResponse, null, 2)
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// If session initialization is successful, extract merchant session from Payone response
|
|
304
|
-
// Payone returns: add_paydata[applepay_payment_session] = BASE64 encoded merchant session
|
|
305
|
-
// Check for both uppercase and lowercase status
|
|
306
|
-
const responseStatus = sessionResponse.status || sessionResponse.Status;
|
|
307
|
-
if (responseStatus === "APPROVED" || responseStatus === "OK" ||
|
|
308
|
-
responseStatus === "approved" || responseStatus === "ok") {
|
|
309
|
-
|
|
310
|
-
// Extract BASE64 encoded merchant session from Payone response
|
|
311
|
-
// Payone returns it in: add_paydata[applepay_payment_session]
|
|
312
|
-
// Try all possible variations of the field name
|
|
313
|
-
const applePaySessionBase64 =
|
|
314
|
-
sessionResponse["add_paydata[applepay_payment_session]"] ||
|
|
315
|
-
sessionResponse["add_paydata[applepay_payment_session]"] ||
|
|
316
|
-
sessionResponse["add_paydata_applepay_payment_session"] ||
|
|
317
|
-
sessionResponse.add_paydata?.applepay_payment_session ||
|
|
318
|
-
sessionResponse.add_paydata?.["applepay_payment_session"] ||
|
|
319
|
-
sessionResponse["addPaydata[applepay_payment_session]"] ||
|
|
320
|
-
sessionResponse["addPaydata_applepay_payment_session"] ||
|
|
321
|
-
null;
|
|
322
|
-
|
|
323
|
-
strapi.log.info("[Apple Pay] Checking for merchant session in response:", {
|
|
324
|
-
hasWorkorderid: !!sessionResponse.workorderid,
|
|
325
|
-
workorderid: sessionResponse.workorderid,
|
|
326
|
-
allKeys: Object.keys(sessionResponse).filter(k => k.includes('applepay') || k.includes('session') || k.includes('paydata')),
|
|
327
|
-
responseKeys: Object.keys(sessionResponse)
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
strapi.log.info("[Apple Pay] Extracted Apple Pay session data:", {
|
|
331
|
-
hasBase64Session: !!applePaySessionBase64,
|
|
332
|
-
sessionLength: applePaySessionBase64?.length,
|
|
333
|
-
workorderid: sessionResponse.workorderid,
|
|
334
|
-
allResponseKeys: Object.keys(sessionResponse),
|
|
335
|
-
responseSample: JSON.stringify(sessionResponse).substring(0, 500)
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
if (applePaySessionBase64 && applePaySessionBase64.length > 0) {
|
|
339
|
-
try {
|
|
340
|
-
// Decode BASE64 merchant session
|
|
341
|
-
const merchantSessionJson = Buffer.from(applePaySessionBase64, 'base64').toString('utf-8');
|
|
342
|
-
const merchantSession = JSON.parse(merchantSessionJson);
|
|
343
|
-
|
|
344
|
-
strapi.log.info("[Apple Pay] Decoded merchant session:", {
|
|
345
|
-
merchantIdentifier: merchantSession.merchantIdentifier,
|
|
346
|
-
domainName: merchantSession.domainName,
|
|
347
|
-
displayName: merchantSession.displayName,
|
|
348
|
-
hasEpochTimestamp: !!merchantSession.epochTimestamp,
|
|
349
|
-
hasExpiresAt: !!merchantSession.expiresAt,
|
|
350
|
-
fullSession: merchantSession
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
// Validate decoded merchant session
|
|
354
|
-
if (!merchantSession.merchantIdentifier) {
|
|
355
|
-
strapi.log.warn("[Apple Pay] Decoded merchant session missing merchantIdentifier, using MerchantId from config");
|
|
356
|
-
// Use MerchantId (mid) from config as merchantIdentifier
|
|
357
|
-
// Priority: settings.mid (MerchantId) > settings.merchantIdentifier > settings.portalid
|
|
358
|
-
strapi.log.info("[Apple Pay] Available MerchantId values from config:");
|
|
359
|
-
strapi.log.info("[Apple Pay] settings.mid:", settings.mid || "NOT_SET");
|
|
360
|
-
strapi.log.info("[Apple Pay] settings.merchantIdentifier:", settings.merchantIdentifier || "NOT_SET");
|
|
361
|
-
strapi.log.info("[Apple Pay] settings.portalid:", settings.portalid || "NOT_SET");
|
|
362
|
-
|
|
363
|
-
const fallbackMerchantId = settings.mid || settings.merchantIdentifier || settings.portalid;
|
|
364
|
-
merchantSession.merchantIdentifier = fallbackMerchantId || `merchant.${domainName}`;
|
|
365
|
-
|
|
366
|
-
strapi.log.info("[Apple Pay] Selected MerchantId from config:", fallbackMerchantId || "NOT_SET");
|
|
367
|
-
strapi.log.info("[Apple Pay] Final merchantIdentifier set to:", merchantSession.merchantIdentifier);
|
|
368
|
-
} else {
|
|
369
|
-
strapi.log.info("[Apple Pay] Using merchantIdentifier from decoded Payone session:", merchantSession.merchantIdentifier);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Ensure epochTimestamp and expiresAt are in seconds (not milliseconds)
|
|
373
|
-
if (merchantSession.epochTimestamp && merchantSession.epochTimestamp > 1000000000000) {
|
|
374
|
-
// If timestamp is in milliseconds, convert to seconds
|
|
375
|
-
merchantSession.epochTimestamp = Math.floor(merchantSession.epochTimestamp / 1000);
|
|
376
|
-
}
|
|
377
|
-
if (merchantSession.expiresAt && merchantSession.expiresAt > 1000000000000) {
|
|
378
|
-
// If timestamp is in milliseconds, convert to seconds
|
|
379
|
-
merchantSession.expiresAt = Math.floor(merchantSession.expiresAt / 1000);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
// Validate final merchant session
|
|
383
|
-
if (!merchantSession.merchantIdentifier || merchantSession.merchantIdentifier === 'undefined' || merchantSession.merchantIdentifier === 'null') {
|
|
384
|
-
throw new Error("Decoded merchant session has invalid merchantIdentifier");
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
strapi.log.info("[Apple Pay] Validated merchant session:", {
|
|
388
|
-
merchantIdentifier: merchantSession.merchantIdentifier,
|
|
389
|
-
domainName: merchantSession.domainName,
|
|
390
|
-
epochTimestamp: merchantSession.epochTimestamp,
|
|
391
|
-
expiresAt: merchantSession.expiresAt
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
return merchantSession;
|
|
395
|
-
} catch (decodeError) {
|
|
396
|
-
strapi.log.error("[Apple Pay] Failed to decode merchant session:", {
|
|
397
|
-
error: decodeError.message,
|
|
398
|
-
base64Length: applePaySessionBase64?.length,
|
|
399
|
-
base64Preview: applePaySessionBase64?.substring(0, 100)
|
|
400
|
-
});
|
|
401
|
-
|
|
402
|
-
// If decoding fails, we cannot proceed - merchant session is invalid
|
|
403
|
-
throw new Error(`Failed to decode Apple Pay merchant session: ${decodeError.message}`);
|
|
404
|
-
}
|
|
405
|
-
} else {
|
|
406
|
-
// CRITICAL: If Payone doesn't return merchant session, we cannot proceed
|
|
407
|
-
// Apple Pay requires the merchant session to be validated by Apple's servers
|
|
408
|
-
// Payone should return add_paydata[applepay_payment_session] after successful initialization
|
|
409
|
-
strapi.log.error("[Apple Pay] CRITICAL: No Apple Pay session data in Payone response!");
|
|
410
|
-
strapi.log.error("[Apple Pay] This means merchant validation will fail. Possible causes:");
|
|
411
|
-
strapi.log.error("[Apple Pay] 1. Apple Pay not properly configured in Payone PMI");
|
|
412
|
-
strapi.log.error("[Apple Pay] 2. Domain not verified in Payone PMI");
|
|
413
|
-
strapi.log.error("[Apple Pay] 3. Merchant identifier not configured in Payone PMI");
|
|
414
|
-
strapi.log.error("[Apple Pay] 4. Apple Pay onboarding not completed in Payone PMI");
|
|
415
|
-
strapi.log.error("[Apple Pay] Response status:", responseStatus);
|
|
416
|
-
strapi.log.error("[Apple Pay] Full response keys:", Object.keys(sessionResponse));
|
|
417
|
-
strapi.log.error("[Apple Pay] Response sample:", JSON.stringify(sessionResponse).substring(0, 1000));
|
|
418
|
-
|
|
419
|
-
// DO NOT create a fallback session - it will fail validation
|
|
420
|
-
// Instead, throw an error so the frontend knows validation failed
|
|
421
|
-
throw new Error("Payone did not return Apple Pay merchant session. Please ensure Apple Pay is properly configured in Payone Merchant Interface (PMI): CONFIGURATION → PAYMENT PORTALS → [Your Portal] → Apple Pay configuration. The merchant session must come from Payone after successful Apple Pay onboarding.");
|
|
422
|
-
|
|
423
|
-
// Get merchant identifier from settings
|
|
424
|
-
// Use MerchantId (mid) from config as merchantIdentifier
|
|
425
|
-
// According to Payone docs, merchant identifier should be visible in PMI after onboarding
|
|
426
|
-
// Path: CONFIGURATION/PAYMENT PORTALS - choose an onboarded Portal - Payment type configuration tab
|
|
427
|
-
strapi.log.info("[Apple Pay] ========== CREATING MERCHANT SESSION FROM CONFIG ==========");
|
|
428
|
-
strapi.log.info("[Apple Pay] Available MerchantId values from config:");
|
|
429
|
-
strapi.log.info("[Apple Pay] settings.mid:", settings.mid || "NOT_SET");
|
|
430
|
-
strapi.log.info("[Apple Pay] settings.merchantIdentifier:", settings.merchantIdentifier || "NOT_SET");
|
|
431
|
-
strapi.log.info("[Apple Pay] settings.portalid:", settings.portalid || "NOT_SET");
|
|
432
|
-
|
|
433
|
-
// Priority: settings.mid (MerchantId) > settings.merchantIdentifier > settings.portalid
|
|
434
|
-
let merchantIdentifier = settings.mid || settings.merchantIdentifier || settings.portalid;
|
|
435
|
-
|
|
436
|
-
strapi.log.info("[Apple Pay] Selected merchantIdentifier:", merchantIdentifier || "NOT_SET");
|
|
437
|
-
strapi.log.info("[Apple Pay] merchantIdentifier type:", typeof merchantIdentifier);
|
|
438
|
-
strapi.log.info("[Apple Pay] merchantIdentifier length:", merchantIdentifier ? merchantIdentifier.length : 0);
|
|
439
|
-
|
|
440
|
-
// If still no merchant identifier, try to construct one from domain
|
|
441
|
-
// But this is not ideal - merchant identifier should come from Payone PMI
|
|
442
|
-
if (!merchantIdentifier) {
|
|
443
|
-
strapi.log.warn("[Apple Pay] No merchant identifier found in settings, using domain-based fallback");
|
|
444
|
-
merchantIdentifier = `merchant.${domainName}`;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Ensure merchant identifier is a string and not empty
|
|
448
|
-
merchantIdentifier = merchantIdentifier.toString().trim();
|
|
449
|
-
if (!merchantIdentifier || merchantIdentifier === 'undefined' || merchantIdentifier === 'null') {
|
|
450
|
-
strapi.log.error("[Apple Pay] Invalid merchant identifier:", merchantIdentifier);
|
|
451
|
-
throw new Error("Merchant identifier is invalid. Please configure a valid merchant identifier in Payone Merchant Interface (PMI) after Apple Pay onboarding. Path: CONFIGURATION → PAYMENT PORTALS → [Your Portal] → Payment type configuration tab");
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
// Create a valid merchant session object
|
|
455
|
-
// This format is required by Apple Pay Payment Request API
|
|
456
|
-
// IMPORTANT: epochTimestamp and expiresAt must be in seconds (Unix timestamp), not milliseconds
|
|
457
|
-
// IMPORTANT: merchantIdentifier must be the MerchantId (mid) from Payone config
|
|
458
|
-
const merchantSession = {
|
|
459
|
-
epochTimestamp: Math.floor(Date.now() / 1000), // Unix timestamp in seconds
|
|
460
|
-
expiresAt: Math.floor((Date.now() + (5 * 60 * 1000)) / 1000), // 5 minutes from now, in seconds
|
|
461
|
-
merchantSessionIdentifier: `merchant.${domainName}`,
|
|
462
|
-
nonce: generateNonce(),
|
|
463
|
-
merchantIdentifier: merchantIdentifier, // MerchantId (mid) from config - already validated and converted to string
|
|
464
|
-
domainName: domainName,
|
|
465
|
-
displayName: merchantName
|
|
466
|
-
};
|
|
467
|
-
|
|
468
|
-
strapi.log.info("[Apple Pay] Created merchant session with MerchantId from config:");
|
|
469
|
-
strapi.log.info("[Apple Pay] merchantIdentifier:", merchantSession.merchantIdentifier);
|
|
470
|
-
strapi.log.info("[Apple Pay] domainName:", merchantSession.domainName);
|
|
471
|
-
strapi.log.info("[Apple Pay] displayName:", merchantSession.displayName);
|
|
472
|
-
strapi.log.info("[Apple Pay] epochTimestamp:", merchantSession.epochTimestamp);
|
|
473
|
-
strapi.log.info("[Apple Pay] expiresAt:", merchantSession.expiresAt);
|
|
474
|
-
strapi.log.info("[Apple Pay] ==========================================");
|
|
475
|
-
|
|
476
|
-
// Validate merchant session before returning
|
|
477
|
-
if (!merchantSession.merchantIdentifier || merchantSession.merchantIdentifier === 'undefined' || merchantSession.merchantIdentifier === 'null') {
|
|
478
|
-
strapi.log.error("[Apple Pay] Created merchant session is missing or invalid merchantIdentifier!", {
|
|
479
|
-
merchantIdentifier: merchantSession.merchantIdentifier,
|
|
480
|
-
settings: {
|
|
481
|
-
hasMerchantIdentifier: !!settings.merchantIdentifier,
|
|
482
|
-
hasMid: !!settings.mid,
|
|
483
|
-
hasPortalid: !!settings.portalid,
|
|
484
|
-
mid: settings.mid,
|
|
485
|
-
portalid: settings.portalid
|
|
486
|
-
}
|
|
487
|
-
});
|
|
488
|
-
throw new Error("Merchant identifier is required but not found in settings. Please configure merchant identifier in Payone Merchant Interface (PMI) after Apple Pay onboarding.");
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
strapi.log.info("[Apple Pay] Created merchant session from settings:", {
|
|
492
|
-
merchantIdentifier: merchantSession.merchantIdentifier,
|
|
493
|
-
domainName: merchantSession.domainName,
|
|
494
|
-
displayName: merchantSession.displayName,
|
|
495
|
-
epochTimestamp: merchantSession.epochTimestamp,
|
|
496
|
-
expiresAt: merchantSession.expiresAt
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
return merchantSession;
|
|
500
|
-
}
|
|
87
|
+
if (merchantSession.expiresAt && merchantSession.expiresAt > 1000000000000) {
|
|
88
|
+
merchantSession.expiresAt = Math.floor(merchantSession.expiresAt / 1000);
|
|
501
89
|
}
|
|
502
90
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
strapi.log.error("[Apple Pay] This means merchant validation will fail.");
|
|
508
|
-
strapi.log.error("[Apple Pay] Possible causes:");
|
|
509
|
-
strapi.log.error("[Apple Pay] 1. Payone returned ERROR status - check errorcode and errormessage in response");
|
|
510
|
-
strapi.log.error("[Apple Pay] 2. Apple Pay not configured in Payone PMI");
|
|
511
|
-
strapi.log.error("[Apple Pay] 3. Domain not verified in Payone PMI");
|
|
512
|
-
strapi.log.error("[Apple Pay] 4. Merchant identifier not configured correctly");
|
|
513
|
-
strapi.log.error("[Apple Pay] 5. Apple Pay onboarding not completed");
|
|
514
|
-
|
|
515
|
-
// Extract error details from Payone response
|
|
516
|
-
const errorCode = sessionResponse.errorcode || sessionResponse.ErrorCode;
|
|
517
|
-
const errorMessage = sessionResponse.errormessage || sessionResponse.ErrorMessage || sessionResponse.errortxt || sessionResponse.ErrorTxt;
|
|
518
|
-
|
|
519
|
-
if (errorCode || errorMessage) {
|
|
520
|
-
strapi.log.error("[Apple Pay] Payone error details:", {
|
|
521
|
-
errorCode: errorCode,
|
|
522
|
-
errorMessage: errorMessage
|
|
523
|
-
});
|
|
524
|
-
throw new Error(`Payone Apple Pay initialization failed: ${errorCode ? `Error ${errorCode}` : ''} ${errorMessage || 'Unknown error'}. Please check your Payone Apple Pay configuration in PMI (CONFIGURATION → PAYMENT PORTALS → [Your Portal] → Apple Pay).`);
|
|
525
|
-
} else {
|
|
526
|
-
throw new Error(`Apple Pay session initialization failed with status: ${responseStatus || 'UNKNOWN'}. Please check your Payone Apple Pay configuration in PMI (CONFIGURATION → PAYMENT PORTALS → [Your Portal] → Apple Pay).`);
|
|
91
|
+
if (!merchantSession.merchantIdentifier ||
|
|
92
|
+
merchantSession.merchantIdentifier === 'undefined' ||
|
|
93
|
+
merchantSession.merchantIdentifier === 'null') {
|
|
94
|
+
strapi.log.error("Decoded merchant session has invalid merchantIdentifier");
|
|
527
95
|
}
|
|
528
|
-
} catch (error) {
|
|
529
|
-
strapi.log.error("[Apple Pay] Merchant validation error:", {
|
|
530
|
-
message: error.message,
|
|
531
|
-
stack: error.stack,
|
|
532
|
-
response: error.response?.data,
|
|
533
|
-
status: error.response?.status
|
|
534
|
-
});
|
|
535
96
|
|
|
536
|
-
|
|
537
|
-
// Instead, re-throw the error so the frontend can handle it properly
|
|
538
|
-
// The error message will help the user understand what went wrong
|
|
539
|
-
throw error;
|
|
97
|
+
return merchantSession;
|
|
540
98
|
}
|
|
541
|
-
};
|
|
542
99
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const parseResponse = (responseData, logger) => {
|
|
547
|
-
if (typeof responseData === 'string') {
|
|
548
|
-
// Parse form-encoded response
|
|
549
|
-
const params = new URLSearchParams(responseData);
|
|
550
|
-
const parsed = {};
|
|
551
|
-
for (const [key, value] of params.entries()) {
|
|
552
|
-
parsed[key] = value;
|
|
553
|
-
}
|
|
554
|
-
return parsed;
|
|
555
|
-
}
|
|
556
|
-
return responseData;
|
|
557
|
-
};
|
|
100
|
+
const errorCode = sessionResponse.errorcode || sessionResponse.ErrorCode;
|
|
101
|
+
const errorMessage = sessionResponse.errormessage || sessionResponse.ErrorMessage ||
|
|
102
|
+
sessionResponse.errortxt || sessionResponse.ErrorTxt;
|
|
558
103
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
return
|
|
564
|
-
Math.random().toString(36).substring(2, 15);
|
|
104
|
+
strapi.log.error(
|
|
105
|
+
`Payone Apple Pay initialization failed: ${errorCode ? `Error ${errorCode}` : ''} ${errorMessage || 'Unknown error'}`
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
return null;
|
|
565
109
|
};
|
|
566
110
|
|
|
567
111
|
module.exports = {
|
|
568
112
|
initializeApplePaySession,
|
|
569
113
|
validateApplePayMerchant
|
|
570
114
|
};
|
|
571
|
-
|
|
572
|
-
|