@payware/mcp-server 1.3.2 → 1.3.3
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/package.json +1 -1
- package/src/isv/oauth2/get-token-info.js +7 -5
- package/src/isv/oauth2/obtain-token.js +6 -4
- package/src/isv/oauth2/token-helper.js +26 -26
- package/src/isv/poi/cancel-price.js +7 -2
- package/src/isv/poi/get-poi.js +2 -3
- package/src/isv/poi/get-status.js +194 -168
- package/src/isv/poi/list-pois.js +4 -6
- package/src/isv/poi/set-price.js +38 -53
- package/src/isv/transactions/simulate-callback.js +19 -10
- package/src/merchant/transactions/simulate-callback.js +322 -313
- package/src/merchant/transactions/transaction-history.js +2 -2
- package/src/payment-institution/transactions/get-transaction-history.js +1 -1
- package/src/payment-institution/transactions/get-transaction-status.js +1 -1
- package/src/payment-institution/transactions/simulate-pi-callback.js +385 -375
- package/src/payment-institution/transactions/soundbite-transaction.js +1 -1
- package/src/shared/poi/poi-create-api.js +1 -1
- package/src/tools/advanced-code-generator.js +14 -265
- package/src/utils/code-examples/common/auth-examples.js +1 -1
- package/src/utils/code-examples/isv/products.js +1 -1
- package/src/utils/code-examples/isv/transactions.js +1 -1
- package/src/utils/code-examples/merchant/transactions.js +1 -1
- package/src/utils/code-examples.js +2 -2
|
@@ -1,376 +1,386 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simulate payment institution callback scenarios for testing
|
|
3
|
-
* Payment institutions receive TRANSACTION_PROCESSED and TRANSACTION_FINALIZED callbacks
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generate mock payment institution callback payload
|
|
8
|
-
* @param {string} transactionId - Transaction ID
|
|
9
|
-
* @param {string} callbackType - Callback type (TRANSACTION_PROCESSED, TRANSACTION_FINALIZED)
|
|
10
|
-
* @param {Object} options - Additional options
|
|
11
|
-
* @returns {Object} Mock callback payload
|
|
12
|
-
*/
|
|
13
|
-
export function generateMockPICallback(transactionId, callbackType = 'TRANSACTION_PROCESSED', options = {}) {
|
|
14
|
-
const {
|
|
15
|
-
amount = '57.00',
|
|
16
|
-
currency = 'EUR',
|
|
17
|
-
payerAmount = null,
|
|
18
|
-
payeeAmount = null,
|
|
19
|
-
payeeBIC = 'SBBICID1',
|
|
20
|
-
payeeAccount = 'M-1W-1account2',
|
|
21
|
-
payeeFriendlyName = 'payware',
|
|
22
|
-
payerBIC = 'SBBICID1',
|
|
23
|
-
payerAccount = 'payerAccount',
|
|
24
|
-
payerFriendlyName = 'Demo Financial Institution',
|
|
25
|
-
reasonL1 = '57',
|
|
26
|
-
reasonL2 = null,
|
|
27
|
-
timeToLive = 600,
|
|
28
|
-
initiatedBy = 'PEER',
|
|
29
|
-
transactionType = 'DEFAULT',
|
|
30
|
-
paymentMethod = null,
|
|
31
|
-
status = 'CONFIRMED',
|
|
32
|
-
statusMessage = null,
|
|
33
|
-
passbackParams = null,
|
|
34
|
-
// The
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
fee:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fee = Math.abs(parseFloat(
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// a
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
...(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
...
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
...
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
...(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
type: "string",
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
type: "
|
|
232
|
-
description: "
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
},
|
|
245
|
-
|
|
246
|
-
type: "string",
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
**
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
**
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
**
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Simulate payment institution callback scenarios for testing
|
|
3
|
+
* Payment institutions receive TRANSACTION_PROCESSED and TRANSACTION_FINALIZED callbacks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate mock payment institution callback payload
|
|
8
|
+
* @param {string} transactionId - Transaction ID
|
|
9
|
+
* @param {string} callbackType - Callback type (TRANSACTION_PROCESSED, TRANSACTION_FINALIZED)
|
|
10
|
+
* @param {Object} options - Additional options
|
|
11
|
+
* @returns {Object} Mock callback payload
|
|
12
|
+
*/
|
|
13
|
+
export function generateMockPICallback(transactionId, callbackType = 'TRANSACTION_PROCESSED', options = {}) {
|
|
14
|
+
const {
|
|
15
|
+
amount = '57.00',
|
|
16
|
+
currency = 'EUR',
|
|
17
|
+
payerAmount = null,
|
|
18
|
+
payeeAmount = null,
|
|
19
|
+
payeeBIC = 'SBBICID1',
|
|
20
|
+
payeeAccount = 'M-1W-1account2',
|
|
21
|
+
payeeFriendlyName = 'payware',
|
|
22
|
+
payerBIC = 'SBBICID1',
|
|
23
|
+
payerAccount = 'payerAccount',
|
|
24
|
+
payerFriendlyName = 'Demo Financial Institution',
|
|
25
|
+
reasonL1 = '57',
|
|
26
|
+
reasonL2 = null,
|
|
27
|
+
timeToLive = 600,
|
|
28
|
+
initiatedBy = 'PEER',
|
|
29
|
+
transactionType = 'DEFAULT',
|
|
30
|
+
paymentMethod = null,
|
|
31
|
+
status = 'CONFIRMED',
|
|
32
|
+
statusMessage = null,
|
|
33
|
+
passbackParams = null,
|
|
34
|
+
// The POI the payer scanned, on both payloads of a POI sale only (server S8, 2026-09-28).
|
|
35
|
+
poiId = null,
|
|
36
|
+
// The fee breakdown. Present on BOTH payloads whenever the transaction has a fee configuration -
|
|
37
|
+
// FINALIZED gained them on 2026-08-21, having previously carried the total without the two
|
|
38
|
+
// numbers that produced it. Both are INFORMATIONAL: recomputing the fee from them and submitting
|
|
39
|
+
// that at finalize is rejected with ERR_FEE_MISMATCH. Echo `fee` back unchanged instead.
|
|
40
|
+
feeFixed = '0.1000',
|
|
41
|
+
feeRate = '0.0150',
|
|
42
|
+
// Pass fee: null to model the anomaly the server reports by OMITTING the property - a
|
|
43
|
+
// transaction with no recorded fee. Deliberately distinguishable from a genuine '0.00'.
|
|
44
|
+
fee: feeOverride = undefined
|
|
45
|
+
} = options;
|
|
46
|
+
|
|
47
|
+
// Calculate fee like the server: |payerAmount - amount| or |payeeAmount - amount|.
|
|
48
|
+
const transactionAmount = parseFloat(amount);
|
|
49
|
+
let fee = '0.60'; // Default fee
|
|
50
|
+
if (payerAmount !== null) {
|
|
51
|
+
fee = Math.abs(parseFloat(payerAmount) - transactionAmount).toFixed(2);
|
|
52
|
+
} else if (payeeAmount !== null) {
|
|
53
|
+
fee = Math.abs(parseFloat(payeeAmount) - transactionAmount).toFixed(2);
|
|
54
|
+
}
|
|
55
|
+
if (feeOverride !== undefined) {
|
|
56
|
+
fee = feeOverride;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// The server's payloads are @JsonInclude(NON_NULL): a property with no value is ABSENT from the
|
|
60
|
+
// JSON rather than sent as null. Emitting "passbackParams": null here taught integrators to expect
|
|
61
|
+
// a shape the server never sends.
|
|
62
|
+
const feeFields = {
|
|
63
|
+
...(fee !== null && fee !== undefined && { fee }),
|
|
64
|
+
...(feeFixed !== null && feeFixed !== undefined && { feeFixed }),
|
|
65
|
+
...(feeRate !== null && feeRate !== undefined && { feeRate })
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Build payload based on callback type (matching Java implementation exactly)
|
|
69
|
+
if (callbackType === 'TRANSACTION_PROCESSED') {
|
|
70
|
+
return {
|
|
71
|
+
callbackType,
|
|
72
|
+
transactionId,
|
|
73
|
+
...(poiId && { poiId }),
|
|
74
|
+
...(passbackParams !== null && passbackParams !== undefined && { passbackParams }),
|
|
75
|
+
amount,
|
|
76
|
+
...feeFields,
|
|
77
|
+
currency,
|
|
78
|
+
payeeBIC,
|
|
79
|
+
payeeAccount,
|
|
80
|
+
payeeFriendlyName,
|
|
81
|
+
payerBIC,
|
|
82
|
+
payerAccount,
|
|
83
|
+
payerFriendlyName,
|
|
84
|
+
reasonL1,
|
|
85
|
+
...(reasonL2 && { reasonL2 }),
|
|
86
|
+
timeToLive,
|
|
87
|
+
transactionType,
|
|
88
|
+
initiatedBy,
|
|
89
|
+
...(paymentMethod && { paymentMethod })
|
|
90
|
+
};
|
|
91
|
+
} else {
|
|
92
|
+
// TRANSACTION_FINALIZED.
|
|
93
|
+
//
|
|
94
|
+
// transactionType and initiatedBy are deliberately NOT here: the server's finalized builder
|
|
95
|
+
// never sets them, so @JsonInclude(NON_NULL) drops them. An institution that needs either for a
|
|
96
|
+
// finalized transaction reads it from GET /transactions-history/{transactionId}.
|
|
97
|
+
return {
|
|
98
|
+
callbackType,
|
|
99
|
+
transactionId,
|
|
100
|
+
...(poiId && { poiId }),
|
|
101
|
+
...(passbackParams !== null && passbackParams !== undefined && { passbackParams }),
|
|
102
|
+
amount,
|
|
103
|
+
...feeFields,
|
|
104
|
+
currency,
|
|
105
|
+
status,
|
|
106
|
+
...(statusMessage && { statusMessage }),
|
|
107
|
+
...(paymentMethod && { paymentMethod }),
|
|
108
|
+
created: Date.now() - 300000, // Created 5 minutes ago (milliseconds)
|
|
109
|
+
// Absent on EXPIRED: the expiry sweep transitions status in bulk and sets no finalized moment.
|
|
110
|
+
...(status !== 'EXPIRED' && { finalized: Date.now() })
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Simulate callback delivery for payment institutions
|
|
117
|
+
* @param {string} callbackUrl - URL to send callback to
|
|
118
|
+
* @param {Object} payload - Callback payload
|
|
119
|
+
* @returns {Object} Simulation result
|
|
120
|
+
*/
|
|
121
|
+
export async function simulatePICallbackDelivery(callbackUrl, payload) {
|
|
122
|
+
if (!callbackUrl || !callbackUrl.startsWith('http')) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
error: 'Invalid callback URL provided'
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// In a real implementation, this would actually send HTTP POST
|
|
130
|
+
// For simulation, we just return what would be sent
|
|
131
|
+
return {
|
|
132
|
+
success: true,
|
|
133
|
+
url: callbackUrl,
|
|
134
|
+
payload,
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
'Authorization': 'Bearer mock-jwt-token-' + Date.now()
|
|
138
|
+
},
|
|
139
|
+
simulatedAt: new Date().toISOString(),
|
|
140
|
+
note: 'This is a simulation - no actual HTTP request was made. Real payware callbacks use JWT tokens in Authorization header.'
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Payment Institution callback simulation tool implementation
|
|
146
|
+
*/
|
|
147
|
+
export const simulatePICallbackTool = {
|
|
148
|
+
name: "payware_operations_simulate_callback",
|
|
149
|
+
description: "Simulate payment institution callback scenarios for testing webhook handling. Payment institutions receive TRANSACTION_PROCESSED when merchant processes their transaction, and TRANSACTION_FINALIZED when transaction is completed.",
|
|
150
|
+
inputSchema: {
|
|
151
|
+
type: "object",
|
|
152
|
+
additionalProperties: false,
|
|
153
|
+
properties: {
|
|
154
|
+
transactionId: {
|
|
155
|
+
type: "string",
|
|
156
|
+
description: "Transaction ID to simulate callback for"
|
|
157
|
+
},
|
|
158
|
+
callbackType: {
|
|
159
|
+
type: "string",
|
|
160
|
+
enum: ["TRANSACTION_PROCESSED", "TRANSACTION_FINALIZED"],
|
|
161
|
+
description: "Type of callback to simulate",
|
|
162
|
+
default: "TRANSACTION_PROCESSED"
|
|
163
|
+
},
|
|
164
|
+
callbackUrl: {
|
|
165
|
+
type: "string",
|
|
166
|
+
description: "URL where callback would be sent (for simulation only)",
|
|
167
|
+
format: "uri"
|
|
168
|
+
},
|
|
169
|
+
amount: {
|
|
170
|
+
type: "string",
|
|
171
|
+
description: "Transaction amount (e.g., '57.00')",
|
|
172
|
+
default: "57.00"
|
|
173
|
+
},
|
|
174
|
+
currency: {
|
|
175
|
+
type: "string",
|
|
176
|
+
enum: ["EUR", "USD", "GBP"],
|
|
177
|
+
description: "Transaction currency",
|
|
178
|
+
default: "EUR"
|
|
179
|
+
},
|
|
180
|
+
fee: {
|
|
181
|
+
type: "string",
|
|
182
|
+
description: "Fee amount charged by payment institution (e.g., '0.60')",
|
|
183
|
+
default: "0.60"
|
|
184
|
+
},
|
|
185
|
+
feeFixed: {
|
|
186
|
+
type: "string",
|
|
187
|
+
description: "Fixed fee component of the applicable fee configuration. Informational, for reconciliation - do not recompute the fee from it. Present on both callback types since 2026-08-21. Pass null to model a transaction with no fee configuration, where it is omitted.",
|
|
188
|
+
default: "0.1000"
|
|
189
|
+
},
|
|
190
|
+
feeRate: {
|
|
191
|
+
type: "string",
|
|
192
|
+
description: "Variable rate of the applicable fee configuration, e.g. '0.0150' = 1.5%. Informational, same as feeFixed.",
|
|
193
|
+
default: "0.0150"
|
|
194
|
+
},
|
|
195
|
+
payeeBIC: {
|
|
196
|
+
type: "string",
|
|
197
|
+
description: "Payee's BIC code",
|
|
198
|
+
default: "SBBICID1"
|
|
199
|
+
},
|
|
200
|
+
payeeAccount: {
|
|
201
|
+
type: "string",
|
|
202
|
+
description: "Payee account identifier",
|
|
203
|
+
default: "M-1W-1account2"
|
|
204
|
+
},
|
|
205
|
+
payeeFriendlyName: {
|
|
206
|
+
type: "string",
|
|
207
|
+
description: "Payee friendly name",
|
|
208
|
+
default: "payware"
|
|
209
|
+
},
|
|
210
|
+
payerBIC: {
|
|
211
|
+
type: "string",
|
|
212
|
+
description: "Payer's BIC code",
|
|
213
|
+
default: "SBBICID1"
|
|
214
|
+
},
|
|
215
|
+
payerAccount: {
|
|
216
|
+
type: "string",
|
|
217
|
+
description: "Payer account identifier",
|
|
218
|
+
default: "payerAccount"
|
|
219
|
+
},
|
|
220
|
+
payerFriendlyName: {
|
|
221
|
+
type: "string",
|
|
222
|
+
description: "Payer friendly name",
|
|
223
|
+
default: "Demo Financial Institution"
|
|
224
|
+
},
|
|
225
|
+
reasonL1: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Transaction reason line 1",
|
|
228
|
+
default: "57"
|
|
229
|
+
},
|
|
230
|
+
reasonL2: {
|
|
231
|
+
type: "string",
|
|
232
|
+
description: "Transaction reason line 2 (optional)"
|
|
233
|
+
},
|
|
234
|
+
timeToLive: {
|
|
235
|
+
type: "number",
|
|
236
|
+
description: "Remaining time to live in seconds",
|
|
237
|
+
default: 600
|
|
238
|
+
},
|
|
239
|
+
status: {
|
|
240
|
+
type: "string",
|
|
241
|
+
enum: ["CONFIRMED", "DECLINED", "FAILED", "CANCELLED"],
|
|
242
|
+
description: "Transaction status (only for TRANSACTION_FINALIZED callbacks)",
|
|
243
|
+
default: "CONFIRMED"
|
|
244
|
+
},
|
|
245
|
+
statusMessage: {
|
|
246
|
+
type: "string",
|
|
247
|
+
description: "Status message (only for TRANSACTION_FINALIZED callbacks)"
|
|
248
|
+
},
|
|
249
|
+
paymentMethod: {
|
|
250
|
+
type: "string",
|
|
251
|
+
enum: ["A2A", "CARD_FUNDED", "BNPL", "INSTANT_CREDIT"],
|
|
252
|
+
description: "Payment method chosen by customer. A2A = direct transfer. CARD_FUNDED = card-linked account. BNPL = buy now pay later. INSTANT_CREDIT = credit line."
|
|
253
|
+
},
|
|
254
|
+
poiId: {
|
|
255
|
+
type: "string",
|
|
256
|
+
description: "Set to simulate a POI sale: both payloads then carry the poiId the payer scanned"
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
required: ["transactionId"]
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
async handler(args) {
|
|
263
|
+
const {
|
|
264
|
+
transactionId,
|
|
265
|
+
callbackType = 'TRANSACTION_PROCESSED',
|
|
266
|
+
callbackUrl,
|
|
267
|
+
amount = '57.00',
|
|
268
|
+
currency = 'EUR',
|
|
269
|
+
fee,
|
|
270
|
+
feeFixed = '0.1000',
|
|
271
|
+
feeRate = '0.0150',
|
|
272
|
+
payeeBIC = 'SBBICID1',
|
|
273
|
+
payeeAccount = 'M-1W-1account2',
|
|
274
|
+
payeeFriendlyName = 'payware',
|
|
275
|
+
payerBIC = 'SBBICID1',
|
|
276
|
+
payerAccount = 'payerAccount',
|
|
277
|
+
payerFriendlyName = 'Demo Financial Institution',
|
|
278
|
+
reasonL1 = '57',
|
|
279
|
+
reasonL2,
|
|
280
|
+
timeToLive = 600,
|
|
281
|
+
status = 'CONFIRMED',
|
|
282
|
+
statusMessage,
|
|
283
|
+
paymentMethod,
|
|
284
|
+
poiId
|
|
285
|
+
} = args;
|
|
286
|
+
|
|
287
|
+
if (!transactionId) {
|
|
288
|
+
throw new Error("Transaction ID is required");
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Generate mock callback payload
|
|
292
|
+
const payload = generateMockPICallback(transactionId, callbackType, {
|
|
293
|
+
amount,
|
|
294
|
+
currency,
|
|
295
|
+
fee,
|
|
296
|
+
feeFixed,
|
|
297
|
+
feeRate,
|
|
298
|
+
payeeBIC,
|
|
299
|
+
payeeAccount,
|
|
300
|
+
payeeFriendlyName,
|
|
301
|
+
payerBIC,
|
|
302
|
+
payerAccount,
|
|
303
|
+
payerFriendlyName,
|
|
304
|
+
reasonL1,
|
|
305
|
+
reasonL2,
|
|
306
|
+
timeToLive,
|
|
307
|
+
initiatedBy: 'PEER',
|
|
308
|
+
transactionType: 'DEFAULT',
|
|
309
|
+
paymentMethod,
|
|
310
|
+
status,
|
|
311
|
+
statusMessage,
|
|
312
|
+
poiId
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// Simulate callback delivery if URL provided
|
|
316
|
+
let deliveryResult = null;
|
|
317
|
+
if (callbackUrl) {
|
|
318
|
+
deliveryResult = await simulatePICallbackDelivery(callbackUrl, payload);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const callbackEmojis = {
|
|
322
|
+
'TRANSACTION_PROCESSED': '🔄',
|
|
323
|
+
'TRANSACTION_FINALIZED': '✅'
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
const statusEmojis = {
|
|
327
|
+
'CONFIRMED': '✅',
|
|
328
|
+
'DECLINED': '❌',
|
|
329
|
+
'FAILED': '💥',
|
|
330
|
+
'CANCELLED': '🚫'
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
const callbackEmoji = callbackEmojis[callbackType] || '📨';
|
|
334
|
+
const statusEmoji = statusEmojis[status] || '❓';
|
|
335
|
+
|
|
336
|
+
return {
|
|
337
|
+
content: [{
|
|
338
|
+
type: "text",
|
|
339
|
+
text: `${callbackEmoji} **Payment Institution Callback Simulation Complete**
|
|
340
|
+
|
|
341
|
+
**Transaction:** ${transactionId}
|
|
342
|
+
**Callback Type:** ${callbackType}
|
|
343
|
+
${callbackType === 'TRANSACTION_FINALIZED' ? `**Status:** ${statusEmoji} ${status}` : ''}
|
|
344
|
+
|
|
345
|
+
**Mock Callback Payload:**
|
|
346
|
+
\`\`\`json
|
|
347
|
+
${JSON.stringify(payload, null, 2)}
|
|
348
|
+
\`\`\`
|
|
349
|
+
|
|
350
|
+
${deliveryResult ? `
|
|
351
|
+
**Callback Delivery Simulation:**
|
|
352
|
+
${deliveryResult.success ? '✅ Callback would be delivered successfully' : '❌ Callback delivery would fail'}
|
|
353
|
+
|
|
354
|
+
**Delivery Details:**
|
|
355
|
+
- URL: ${deliveryResult.url || 'N/A'}
|
|
356
|
+
- Headers: ${JSON.stringify(deliveryResult.headers || {}, null, 2)}
|
|
357
|
+
- Simulated At: ${deliveryResult.simulatedAt || 'N/A'}
|
|
358
|
+
|
|
359
|
+
**Note:** ${deliveryResult.note || 'No actual HTTP request was made'}
|
|
360
|
+
` : '**No callback URL provided** - only payload generated'}
|
|
361
|
+
|
|
362
|
+
**Payment Institution Callback Types:**
|
|
363
|
+
- 🔄 **TRANSACTION_PROCESSED**: Merchant has processed your transaction (ready for finalization)
|
|
364
|
+
- ✅ **TRANSACTION_FINALIZED**: Transaction completed with final status
|
|
365
|
+
|
|
366
|
+
**Transaction Flow:**
|
|
367
|
+
1. Payment Institution creates transaction as SRC (payer) or DST (payee)
|
|
368
|
+
2. Transaction can be processed by merchant OR payment institution → **TRANSACTION_PROCESSED** callback to PI
|
|
369
|
+
3. Transaction can be finalized ONLY by payment institution → **TRANSACTION_FINALIZED** callback to PI
|
|
370
|
+
4. Transaction can be cancelled ONLY by its issuer (creator)
|
|
371
|
+
|
|
372
|
+
**Integration Testing:**
|
|
373
|
+
1. Use this payload to test your payment institution callback handler
|
|
374
|
+
2. Verify handling of both TRANSACTION_PROCESSED and TRANSACTION_FINALIZED
|
|
375
|
+
3. Test different status scenarios for finalized transactions
|
|
376
|
+
4. Ensure proper BIC and account information processing
|
|
377
|
+
|
|
378
|
+
**Next Steps:**
|
|
379
|
+
1. Implement callback endpoint to receive this payload structure
|
|
380
|
+
2. Test with both callback types
|
|
381
|
+
3. Add signature verification in production
|
|
382
|
+
4. Set up proper error handling and retry logic`
|
|
383
|
+
}]
|
|
384
|
+
};
|
|
385
|
+
}
|
|
376
386
|
};
|