@payware/mcp-server 1.0.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.
Files changed (106) hide show
  1. package/.env.example +92 -0
  2. package/MCP-SETUP.md +190 -0
  3. package/README.md +483 -0
  4. package/check-keys.js +52 -0
  5. package/keys/README.md +112 -0
  6. package/mcp-config.json +9 -0
  7. package/package.json +66 -0
  8. package/payware-mcp-config.json +12 -0
  9. package/src/auth/rsa-keys.js +82 -0
  10. package/src/auth/sandbox-setup.js +187 -0
  11. package/src/config/env.js +229 -0
  12. package/src/config/partner-types.js +143 -0
  13. package/src/core/auth/jwt-factory.js +182 -0
  14. package/src/core/auth/jwt-token.js +735 -0
  15. package/src/core/utils/json-serializer.js +100 -0
  16. package/src/core/utils/key-utils.js +133 -0
  17. package/src/index.js +237 -0
  18. package/src/isv/data/index.js +291 -0
  19. package/src/isv/deep-links/delete-product-link.js +154 -0
  20. package/src/isv/deep-links/delete-transaction-link.js +154 -0
  21. package/src/isv/deep-links/get-product-link.js +167 -0
  22. package/src/isv/deep-links/get-transaction-link.js +167 -0
  23. package/src/isv/deep-links/index.js +23 -0
  24. package/src/isv/index.js +103 -0
  25. package/src/isv/oauth2/create-token-simple.js +46 -0
  26. package/src/isv/oauth2/get-token-info.js +157 -0
  27. package/src/isv/oauth2/obtain-token.js +189 -0
  28. package/src/isv/oauth2/token-helper.js +151 -0
  29. package/src/isv/products/audios.js +470 -0
  30. package/src/isv/products/create-product.js +314 -0
  31. package/src/isv/products/delete-product.js +119 -0
  32. package/src/isv/products/get-product-image.js +247 -0
  33. package/src/isv/products/get-product.js +168 -0
  34. package/src/isv/products/index.js +65 -0
  35. package/src/isv/products/list-products.js +136 -0
  36. package/src/isv/products/schedules.js +522 -0
  37. package/src/isv/products/update-product.js +265 -0
  38. package/src/isv/transactions/cancel-transaction.js +129 -0
  39. package/src/isv/transactions/create-transaction.js +361 -0
  40. package/src/isv/transactions/get-status.js +217 -0
  41. package/src/isv/transactions/process-transaction.js +145 -0
  42. package/src/isv/transactions/simulate-callback.js +146 -0
  43. package/src/isv/transactions/transaction-history.js +186 -0
  44. package/src/isv/utils/auth.js +159 -0
  45. package/src/mcp-proxy.js +150 -0
  46. package/src/merchant/data/export-report.js +108 -0
  47. package/src/merchant/data/generate-report.js +151 -0
  48. package/src/merchant/data/get-report-status.js +120 -0
  49. package/src/merchant/data/index.js +351 -0
  50. package/src/merchant/deep-links/delete-product-link.js +121 -0
  51. package/src/merchant/deep-links/delete-transaction-link.js +121 -0
  52. package/src/merchant/deep-links/get-product-link.js +134 -0
  53. package/src/merchant/deep-links/get-transaction-link.js +134 -0
  54. package/src/merchant/deep-links/index.js +23 -0
  55. package/src/merchant/index.js +92 -0
  56. package/src/merchant/products/audios.js +606 -0
  57. package/src/merchant/products/create-product.js +288 -0
  58. package/src/merchant/products/delete-product.js +111 -0
  59. package/src/merchant/products/get-product-image.js +252 -0
  60. package/src/merchant/products/get-product.js +144 -0
  61. package/src/merchant/products/index.js +65 -0
  62. package/src/merchant/products/list-products.js +112 -0
  63. package/src/merchant/products/schedules.js +646 -0
  64. package/src/merchant/products/update-product.js +282 -0
  65. package/src/merchant/transactions/cancel-transaction.js +241 -0
  66. package/src/merchant/transactions/create-transaction.js +482 -0
  67. package/src/merchant/transactions/get-status.js +196 -0
  68. package/src/merchant/transactions/process-transaction.js +349 -0
  69. package/src/merchant/transactions/simulate-callback.js +246 -0
  70. package/src/merchant/transactions/transaction-history.js +258 -0
  71. package/src/payment-institution/data/index.js +280 -0
  72. package/src/payment-institution/deep-links/delete-transaction-link.js +128 -0
  73. package/src/payment-institution/deep-links/get-transaction-link.js +141 -0
  74. package/src/payment-institution/deep-links/index.js +17 -0
  75. package/src/payment-institution/index.js +92 -0
  76. package/src/payment-institution/transactions/create-pi-transaction.js +484 -0
  77. package/src/payment-institution/transactions/finalize-transaction.js +340 -0
  78. package/src/payment-institution/transactions/get-transaction-history.js +269 -0
  79. package/src/payment-institution/transactions/get-transaction-status.js +234 -0
  80. package/src/payment-institution/transactions/process-pi-transaction.js +421 -0
  81. package/src/payment-institution/transactions/simulate-pi-callback.js +326 -0
  82. package/src/payment-institution/transactions/soundbite-transaction.js +269 -0
  83. package/src/proxy-server.js +205 -0
  84. package/src/shared/data/data-api.js +372 -0
  85. package/src/shared/deep-links/api.js +214 -0
  86. package/src/shared/index.js +44 -0
  87. package/src/shared/products/products-api.js +872 -0
  88. package/src/tools/advanced-code-generator.js +2247 -0
  89. package/src/utils/code-examples/common/auth-examples.js +1482 -0
  90. package/src/utils/code-examples/common/helpers.js +416 -0
  91. package/src/utils/code-examples/common/utils-examples.js +591 -0
  92. package/src/utils/code-examples/frameworks/examples.js +859 -0
  93. package/src/utils/code-examples/index.js +441 -0
  94. package/src/utils/code-examples/isv/oauth2.js +600 -0
  95. package/src/utils/code-examples/isv/products.js +666 -0
  96. package/src/utils/code-examples/isv/transactions.js +813 -0
  97. package/src/utils/code-examples/merchant/products.js +497 -0
  98. package/src/utils/code-examples/merchant/transactions.js +623 -0
  99. package/src/utils/code-examples/payment-institution/transactions.js +388 -0
  100. package/src/utils/code-examples/shared/data.js +607 -0
  101. package/src/utils/code-examples/shared/deep-links.js +662 -0
  102. package/src/utils/code-examples/shared/soundbites.js +808 -0
  103. package/src/utils/code-examples.js +646 -0
  104. package/src/utils/format-request.js +363 -0
  105. package/src/utils/json-formatter.js +249 -0
  106. package/src/utils/server-info.js +132 -0
@@ -0,0 +1,361 @@
1
+ import axios from 'axios';
2
+ import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
+ import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
+
5
+ /**
6
+ * Create a transaction via payware API on behalf of a merchant (ISV)
7
+ * @param {Object} params - Transaction parameters including ISV authentication
8
+ * @returns {Object} Transaction response
9
+ */
10
+ export async function createTransaction({
11
+ // ISV Authentication
12
+ merchantPartnerId,
13
+ oauth2Token,
14
+ // Transaction parameters
15
+ type = 'PLAIN',
16
+ amount,
17
+ currency = 'EUR',
18
+ reasonL1,
19
+ reasonL2,
20
+ callbackUrl,
21
+ account,
22
+ friendlyName,
23
+ shop,
24
+ timeToLive = 120,
25
+ passbackParams,
26
+ // QR Options
27
+ qrFormat,
28
+ qrBorder,
29
+ qrErrorCorrection,
30
+ qrScale,
31
+ qrVersion,
32
+ // Barcode Options
33
+ barFormat,
34
+ barModuleWidth,
35
+ barBarHeight,
36
+ barFontSize,
37
+ barHumanReadableLocation,
38
+ useSandbox = true
39
+ }) {
40
+ // ISV-specific validation
41
+ if (!merchantPartnerId) {
42
+ throw new Error('Merchant Partner ID is required for ISV operations');
43
+ }
44
+
45
+ if (!oauth2Token) {
46
+ throw new Error('OAuth2 token is required for ISV operations');
47
+ }
48
+
49
+ // Standard validation
50
+ if (!reasonL1) {
51
+ throw new Error('reasonL1 is required (transaction grounds description)');
52
+ }
53
+
54
+ if (amount !== undefined && (typeof amount !== 'string' && typeof amount !== 'number')) {
55
+ throw new Error('Amount must be a string or number representing currency value (e.g., "25.50" or 25.50)');
56
+ }
57
+
58
+ if (amount !== undefined && parseFloat(amount) < 0) {
59
+ throw new Error('Amount must be non-negative');
60
+ }
61
+
62
+ if (!['PLAIN', 'QR', 'BARCODE'].includes(type)) {
63
+ throw new Error('Transaction type must be PLAIN, QR, or BARCODE');
64
+ }
65
+
66
+ // Build QR options if applicable
67
+ const qrOptions = {};
68
+ if (type === 'QR') {
69
+ if (qrFormat) qrOptions.qrFormat = qrFormat;
70
+ if (qrBorder !== undefined) qrOptions.qrBorder = qrBorder;
71
+ if (qrErrorCorrection) qrOptions.qrErrorCorrection = qrErrorCorrection;
72
+ if (qrScale) qrOptions.qrScale = qrScale;
73
+ if (qrVersion) qrOptions.qrVersion = qrVersion;
74
+ }
75
+
76
+ // Build barcode options if applicable
77
+ const barOptions = {};
78
+ if (type === 'BARCODE') {
79
+ if (barFormat) barOptions.barFormat = barFormat;
80
+ if (barModuleWidth) barOptions.barModuleWidth = barModuleWidth;
81
+ if (barBarHeight) barOptions.barBarHeight = barBarHeight;
82
+ if (barFontSize) barOptions.barFontSize = barFontSize;
83
+ if (barHumanReadableLocation) barOptions.barHumanReadableLocation = barHumanReadableLocation;
84
+ }
85
+
86
+ // Build request body according to documentation structure
87
+ const requestBody = {
88
+ ...(account && { account }),
89
+ ...(friendlyName && { friendlyName }),
90
+ ...(shop && { shop }),
91
+ ...(callbackUrl && { callbackUrl }),
92
+ ...(passbackParams && {
93
+ passbackParams: typeof passbackParams === 'string' ? passbackParams : JSON.stringify(passbackParams)
94
+ }),
95
+ trData: {
96
+ amount: amount !== undefined ? amount.toString() : '0.00',
97
+ currency,
98
+ reasonL1,
99
+ ...(reasonL2 && { reasonL2 })
100
+ },
101
+ trOptions: {
102
+ type,
103
+ timeToLive
104
+ },
105
+ ...(type === 'QR' && Object.keys(qrOptions).length > 0 && { qrOptions }),
106
+ ...(type === 'BARCODE' && Object.keys(barOptions).length > 0 && { barOptions })
107
+ };
108
+
109
+ // Get ISV credentials
110
+ const isvPartnerId = getPartnerIdSafe();
111
+ const privateKey = getPrivateKeySafe(useSandbox);
112
+
113
+ // Create ISV JWT token
114
+ const jwtData = await createJWTForPartner({
115
+ partnerId: isvPartnerId,
116
+ privateKey,
117
+ requestBody,
118
+ merchantId: merchantPartnerId,
119
+ oauth2Token
120
+ });
121
+
122
+ // Use the same JSON serialization method as the JWT factory for MD5 calculation
123
+ const { createMinimizedJSON } = await import('../../core/utils/json-serializer.js');
124
+ const minimizedBodyString = createMinimizedJSON(requestBody);
125
+
126
+ try {
127
+ const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
128
+ // Send the exact minimized JSON string that was used for MD5 calculation
129
+ const response = await axios.post(`${baseUrl}/transactions`, minimizedBodyString, {
130
+ headers: {
131
+ 'Authorization': `Bearer ${jwtData.token}`,
132
+ 'Content-Type': 'application/json',
133
+ 'Api-Version': '1'
134
+ },
135
+ // Tell axios to send the string as-is, don't serialize it again
136
+ transformRequest: [(data) => data]
137
+ });
138
+
139
+ return response.data;
140
+ } catch (error) {
141
+ if (error.response) {
142
+ throw new Error(`payware API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
143
+ }
144
+ throw error;
145
+ }
146
+ }
147
+
148
+ export const createTransactionTool = {
149
+ name: 'payware_operations_create_transaction',
150
+ description: `Create a new transaction through payware as an ISV on behalf of a merchant.
151
+
152
+ ISV partners can create transactions for merchants they have authorization for via OAuth2.
153
+ Requires valid OAuth2 token obtained from the merchant.
154
+
155
+ **Authentication**: Uses ISV JWT with merchant partner ID in 'aud' claim and OAuth2 token in 'sub' claim.
156
+
157
+ **Transaction Types:**
158
+ - PLAIN: Basic transaction without visual codes
159
+ - QR: Transaction with QR code for mobile payments
160
+ - BARCODE: Transaction with barcode for scanning
161
+
162
+ **Required for all transactions:**
163
+ - Merchant Partner ID and OAuth2 token (ISV authentication)
164
+ - reasonL1 (transaction description)
165
+ - amount (transaction value)
166
+
167
+ **QR Code Options** (when type='QR'):
168
+ - qrFormat: PNG, SVG (default: PNG)
169
+ - qrBorder: Border width in modules (0-10, default: 4)
170
+ - qrErrorCorrection: L, M, Q, H (default: M)
171
+ - qrScale: Scale factor (1-10, default: 4)
172
+ - qrVersion: QR version (1-40, auto if not specified)
173
+
174
+ **Barcode Options** (when type='BARCODE'):
175
+ - barFormat: CODE128, EAN13, etc.
176
+ - barModuleWidth: Width of bars in pixels
177
+ - barBarHeight: Height of bars in pixels
178
+ - barFontSize: Font size for human readable text
179
+ - barHumanReadableLocation: TOP, BOTTOM, NONE`,
180
+
181
+ inputSchema: {
182
+ type: 'object',
183
+ required: ['merchantPartnerId', 'oauth2Token', 'reasonL1'],
184
+ properties: {
185
+ // ISV Authentication
186
+ merchantPartnerId: {
187
+ type: 'string',
188
+ description: 'Partner ID of the target merchant (8 alphanumeric characters, e.g., "PZAYNMVE")'
189
+ },
190
+ oauth2Token: {
191
+ type: 'string',
192
+ description: 'OAuth2 access token obtained from the merchant'
193
+ },
194
+
195
+ // Core transaction data
196
+ type: {
197
+ type: 'string',
198
+ enum: ['PLAIN', 'QR', 'BARCODE'],
199
+ default: 'PLAIN',
200
+ description: 'Transaction type'
201
+ },
202
+ amount: {
203
+ type: ['string', 'number'],
204
+ description: 'Transaction amount (e.g., "25.50" or 25.50)'
205
+ },
206
+ currency: {
207
+ type: 'string',
208
+ default: 'EUR',
209
+ description: 'Currency code (ISO 4217, e.g., EUR, USD, GBP)'
210
+ },
211
+ reasonL1: {
212
+ type: 'string',
213
+ description: 'Primary transaction reason/description (required)'
214
+ },
215
+ reasonL2: {
216
+ type: 'string',
217
+ description: 'Secondary transaction reason/description (optional)'
218
+ },
219
+
220
+ // Optional transaction metadata
221
+ callbackUrl: {
222
+ type: 'string',
223
+ description: 'URL to receive transaction status updates'
224
+ },
225
+ account: {
226
+ type: 'string',
227
+ description: 'Account identifier'
228
+ },
229
+ friendlyName: {
230
+ type: 'string',
231
+ description: 'Human-readable transaction identifier'
232
+ },
233
+ shop: {
234
+ type: 'string',
235
+ description: 'Shop/location identifier'
236
+ },
237
+ timeToLive: {
238
+ type: 'number',
239
+ default: 120,
240
+ description: 'Transaction validity in minutes'
241
+ },
242
+ passbackParams: {
243
+ type: ['string', 'object'],
244
+ description: 'Additional parameters to pass back in callbacks'
245
+ },
246
+
247
+ // QR Code options (when type='QR')
248
+ qrFormat: {
249
+ type: 'string',
250
+ enum: ['PNG', 'SVG'],
251
+ description: 'QR code image format'
252
+ },
253
+ qrBorder: {
254
+ type: 'number',
255
+ minimum: 0,
256
+ maximum: 10,
257
+ description: 'QR code border width in modules'
258
+ },
259
+ qrErrorCorrection: {
260
+ type: 'string',
261
+ enum: ['L', 'M', 'Q', 'H'],
262
+ description: 'QR error correction level'
263
+ },
264
+ qrScale: {
265
+ type: 'number',
266
+ minimum: 1,
267
+ maximum: 10,
268
+ description: 'QR code scale factor'
269
+ },
270
+ qrVersion: {
271
+ type: 'number',
272
+ minimum: 1,
273
+ maximum: 40,
274
+ description: 'QR code version (size)'
275
+ },
276
+
277
+ // Barcode options (when type='BARCODE')
278
+ barFormat: {
279
+ type: 'string',
280
+ description: 'Barcode format (e.g., CODE128, EAN13)'
281
+ },
282
+ barModuleWidth: {
283
+ type: 'number',
284
+ description: 'Barcode module width in pixels'
285
+ },
286
+ barBarHeight: {
287
+ type: 'number',
288
+ description: 'Barcode height in pixels'
289
+ },
290
+ barFontSize: {
291
+ type: 'number',
292
+ description: 'Font size for human readable text'
293
+ },
294
+ barHumanReadableLocation: {
295
+ type: 'string',
296
+ enum: ['TOP', 'BOTTOM', 'NONE'],
297
+ description: 'Location of human readable text'
298
+ },
299
+ useSandbox: {
300
+ type: 'boolean',
301
+ description: 'Use sandbox environment for testing',
302
+ default: true
303
+ }
304
+ }
305
+ },
306
+
307
+ async handler(params) {
308
+ try {
309
+ const result = await createTransaction(params);
310
+
311
+ return {
312
+ content: [{
313
+ type: 'text',
314
+ text: `✅ Transaction Created Successfully (ISV -> Merchant: ${params.merchantPartnerId})
315
+
316
+ 📋 **Transaction Details:**
317
+ - **Transaction ID**: ${result.transactionId || 'N/A'}
318
+ - **Status**: ${result.status || 'CREATED'}
319
+ - **Type**: ${params.type}
320
+ - **Amount**: ${params.amount || 'N/A'} ${params.currency || 'EUR'}
321
+ - **Reason**: ${params.reasonL1}
322
+ - **TTL**: ${params.timeToLive || 120} minutes
323
+
324
+ 🔗 **Integration Details:**
325
+ - **ISV Partner**: ${getPartnerIdSafe()}
326
+ - **Target Merchant**: ${params.merchantPartnerId}
327
+ - **OAuth2 Token**: ${params.oauth2Token.substring(0, 8)}...
328
+
329
+ ${result.qrCodeUrl ? `🔲 **QR Code**: ${result.qrCodeUrl}` : ''}
330
+ ${result.barcodeUrl ? `📊 **Barcode**: ${result.barcodeUrl}` : ''}
331
+ ${result.paymentUrl ? `💳 **Payment URL**: ${result.paymentUrl}` : ''}
332
+
333
+ **Raw Response:**
334
+ \`\`\`json
335
+ ${JSON.stringify(result, null, 2)}
336
+ \`\`\``
337
+ }]
338
+ };
339
+ } catch (error) {
340
+ return {
341
+ content: [{
342
+ type: 'text',
343
+ text: `❌ Transaction Creation Failed
344
+
345
+ **Error**: ${error.message}
346
+
347
+ **ISV Authentication Check:**
348
+ - Merchant Partner ID: ${params.merchantPartnerId || 'Missing'}
349
+ - OAuth2 Token: ${params.oauth2Token ? 'Provided' : 'Missing'}
350
+ - ISV Partner ID: ${getPartnerIdSafe()}
351
+
352
+ **Troubleshooting:**
353
+ - Verify OAuth2 token is valid and granted
354
+ - Ensure merchant partner ID is correct (8 characters)
355
+ - Check transaction parameters meet payware requirements
356
+ - Confirm ISV has authorization to act on behalf of merchant`
357
+ }]
358
+ };
359
+ }
360
+ }
361
+ };
@@ -0,0 +1,217 @@
1
+ import axios from 'axios';
2
+ import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
+ import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
+
5
+ /**
6
+ * Get transaction status from payware API as an ISV
7
+ * @param {Object} params - Parameters for status request
8
+ * @returns {Object} Transaction status response
9
+ */
10
+ export async function getTransactionStatus({ transactionId, merchantPartnerId, oauth2Token, useSandbox = true }) {
11
+ if (!transactionId) {
12
+ throw new Error('Transaction ID is required');
13
+ }
14
+
15
+ if (!merchantPartnerId) {
16
+ throw new Error('Merchant Partner ID is required for ISV operations');
17
+ }
18
+
19
+ if (!oauth2Token) {
20
+ throw new Error('OAuth2 token is required for ISV operations');
21
+ }
22
+
23
+ // Get ISV credentials
24
+ const isvPartnerId = getPartnerIdSafe();
25
+ const privateKey = getPrivateKeySafe(useSandbox);
26
+
27
+ // Create ISV JWT token (GET request - no body)
28
+ const jwtData = await createJWTForPartner({
29
+ partnerId: isvPartnerId,
30
+ privateKey,
31
+ requestBody: null,
32
+ merchantId: merchantPartnerId,
33
+ oauth2Token
34
+ });
35
+
36
+ // Required headers as per payware API documentation
37
+ const headers = {
38
+ 'Authorization': `Bearer ${jwtData.token}`,
39
+ 'Content-Type': 'application/json',
40
+ 'Api-Version': '1' // Required: current API version
41
+ };
42
+
43
+ try {
44
+ const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
45
+ const response = await axios.get(`${baseUrl}/transactions/${transactionId}`, { headers });
46
+
47
+ return {
48
+ success: true,
49
+ transaction: response.data,
50
+ requestId: response.headers['x-request-id'],
51
+ timestamp: new Date().toISOString()
52
+ };
53
+ } catch (error) {
54
+ return {
55
+ success: false,
56
+ error: {
57
+ message: error.response?.data?.message || error.message,
58
+ status: error.response?.status,
59
+ code: error.response?.data?.code,
60
+ details: error.response?.data
61
+ },
62
+ timestamp: new Date().toISOString()
63
+ };
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Format transaction status for display
69
+ */
70
+ function formatTransactionStatus(transaction) {
71
+ const statusEmojis = {
72
+ 'ACTIVE': '⏳'
73
+ };
74
+
75
+ // If a transaction is returned from GET /transactions/{id}, it's always ACTIVE
76
+ // (transactions with final statuses are only available via /transactions-history)
77
+ const status = transaction.status || 'ACTIVE';
78
+ const emoji = statusEmojis[status] || '⏳';
79
+
80
+ return {
81
+ emoji,
82
+ status,
83
+ formatted: `${emoji} ${status}`
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Get transaction status tool implementation for ISV
89
+ */
90
+ export const getTransactionStatusTool = {
91
+ name: "payware_operations_get_transaction_status",
92
+ description: `Get status of an ACTIVE transaction by ID as an ISV on behalf of a merchant.
93
+
94
+ **ISV Authentication:** Uses ISV JWT with merchant partner ID in 'aud' claim and OAuth2 token in 'sub' claim.
95
+ **Endpoint:** GET /transactions/{transactionId}
96
+ **Use Case:** Check status of ACTIVE transactions only. This endpoint only returns transactions with ACTIVE status.
97
+ **Note:** For transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use 'payware_transactions_get_history' instead.
98
+
99
+ **Required:** Merchant Partner ID and OAuth2 token for ISV authentication.`,
100
+
101
+ inputSchema: {
102
+ type: "object",
103
+ required: ["transactionId", "merchantPartnerId", "oauth2Token"],
104
+ properties: {
105
+ transactionId: {
106
+ type: "string",
107
+ description: "Transaction ID to check status for"
108
+ },
109
+ merchantPartnerId: {
110
+ type: "string",
111
+ description: "Partner ID of the target merchant (8 alphanumeric characters, e.g., 'PZAYNMVE')"
112
+ },
113
+ oauth2Token: {
114
+ type: "string",
115
+ description: "OAuth2 access token obtained from the merchant"
116
+ },
117
+ useSandbox: {
118
+ type: "boolean",
119
+ description: "Use sandbox environment for testing",
120
+ default: true
121
+ }
122
+ }
123
+ },
124
+
125
+ async handler(args) {
126
+ const { transactionId, merchantPartnerId, oauth2Token, useSandbox = true } = args;
127
+
128
+ if (!transactionId) {
129
+ throw new Error("Transaction ID is required");
130
+ }
131
+
132
+ if (!merchantPartnerId) {
133
+ throw new Error("Merchant Partner ID is required for ISV operations");
134
+ }
135
+
136
+ if (!oauth2Token) {
137
+ throw new Error("OAuth2 token is required for ISV operations");
138
+ }
139
+
140
+ const result = await getTransactionStatus({ transactionId, merchantPartnerId, oauth2Token, useSandbox });
141
+
142
+ if (result.success) {
143
+ const statusInfo = formatTransactionStatus(result.transaction);
144
+
145
+ return {
146
+ content: [{
147
+ type: "text",
148
+ text: `📊 **Transaction Status Retrieved (ISV -> Merchant: ${merchantPartnerId})**
149
+
150
+ **Transaction:** ${transactionId}
151
+ **Status:** ${statusInfo.formatted}
152
+
153
+ **ISV Integration:**
154
+ - ISV Partner: ${getPartnerIdSafe()}
155
+ - Target Merchant: ${merchantPartnerId}
156
+ - OAuth2 Token: ${oauth2Token.substring(0, 8)}...
157
+
158
+ **Transaction Details:**
159
+ - ID: ${result.transaction.id || 'N/A'}
160
+ - Type: ${result.transaction.type || 'N/A'}
161
+ - Amount: ${result.transaction.trData ? `${result.transaction.trData.amount} ${result.transaction.trData.currency}` : 'N/A'}
162
+ - Description: ${result.transaction.description || 'N/A'}
163
+ - Created: ${result.transaction.createdAt || 'N/A'}
164
+ - Updated: ${result.transaction.updatedAt || 'N/A'}
165
+
166
+ **Full Response:**
167
+ \`\`\`json
168
+ ${JSON.stringify(result.transaction, null, 2)}
169
+ \`\`\`
170
+
171
+ **Request ID:** ${result.requestId || 'N/A'}
172
+ **Timestamp:** ${result.timestamp}
173
+
174
+ **Status Meanings:**
175
+ - ⏳ ACTIVE: Active transaction pending processing or finalizing
176
+
177
+ **Note:** Only ACTIVE transactions are returned by this endpoint. For final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use the transaction history tool.`
178
+ }]
179
+ };
180
+ } else {
181
+ return {
182
+ content: [{
183
+ type: "text",
184
+ text: `❌ **Failed to Get Transaction Status**
185
+
186
+ **Transaction ID:** ${transactionId}
187
+ **ISV -> Merchant:** ${getPartnerIdSafe()} -> ${merchantPartnerId}
188
+
189
+ **Error Details:**
190
+ - Message: ${result.error.message}
191
+ - Status: ${result.error.status || 'N/A'}
192
+ - Code: ${result.error.code || 'N/A'}
193
+
194
+ **Full Error Response:**
195
+ \`\`\`json
196
+ ${JSON.stringify(result.error.details || result.error, null, 2)}
197
+ \`\`\`
198
+
199
+ **Timestamp:** ${result.timestamp}
200
+
201
+ **ISV-Specific Troubleshooting:**
202
+ 1. Verify OAuth2 token is valid and granted for merchant
203
+ 2. Ensure merchant partner ID is correct (8 characters)
204
+ 3. Check if ISV has authorization to access merchant transactions
205
+ 4. Verify transaction belongs to the specified merchant
206
+ 5. Confirm JWT token is properly signed for ISV requests
207
+
208
+ **General Troubleshooting:**
209
+ 1. Verify the transaction ID is correct
210
+ 2. Check if transaction exists and is accessible
211
+ 3. Ensure transaction is still ACTIVE (not finalized)
212
+ 4. Try using transaction history tool for completed transactions`
213
+ }]
214
+ };
215
+ }
216
+ }
217
+ };