@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,326 @@
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
+ status = 'CONFIRMED',
31
+ statusMessage = null,
32
+ passbackParams = null
33
+ } = options;
34
+
35
+ // Calculate fee like Java implementation: |payerAmount - amount| or |payeeAmount - amount|
36
+ const transactionAmount = parseFloat(amount);
37
+ let fee = '0.60'; // Default fee
38
+ if (payerAmount !== null) {
39
+ fee = Math.abs(parseFloat(payerAmount) - transactionAmount).toFixed(2);
40
+ } else if (payeeAmount !== null) {
41
+ fee = Math.abs(parseFloat(payeeAmount) - transactionAmount).toFixed(2);
42
+ }
43
+
44
+ // Build payload based on callback type (matching Java implementation exactly)
45
+ if (callbackType === 'TRANSACTION_PROCESSED') {
46
+ return {
47
+ callbackType,
48
+ transactionId,
49
+ passbackParams,
50
+ amount,
51
+ fee,
52
+ currency,
53
+ payeeBIC,
54
+ payeeAccount,
55
+ payeeFriendlyName,
56
+ payerBIC,
57
+ payerAccount,
58
+ payerFriendlyName,
59
+ reasonL1,
60
+ ...(reasonL2 && { reasonL2 }),
61
+ timeToLive,
62
+ transactionType,
63
+ initiatedBy
64
+ };
65
+ } else {
66
+ // TRANSACTION_FINALIZED
67
+ return {
68
+ callbackType,
69
+ transactionId,
70
+ passbackParams,
71
+ amount,
72
+ fee,
73
+ currency,
74
+ status,
75
+ ...(statusMessage && { statusMessage }),
76
+ created: Date.now() - 300000, // Created 5 minutes ago (milliseconds)
77
+ finalized: Date.now()
78
+ };
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Simulate callback delivery for payment institutions
84
+ * @param {string} callbackUrl - URL to send callback to
85
+ * @param {Object} payload - Callback payload
86
+ * @returns {Object} Simulation result
87
+ */
88
+ export async function simulatePICallbackDelivery(callbackUrl, payload) {
89
+ if (!callbackUrl || !callbackUrl.startsWith('http')) {
90
+ return {
91
+ success: false,
92
+ error: 'Invalid callback URL provided'
93
+ };
94
+ }
95
+
96
+ // In a real implementation, this would actually send HTTP POST
97
+ // For simulation, we just return what would be sent
98
+ return {
99
+ success: true,
100
+ url: callbackUrl,
101
+ payload,
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ 'Authorization': 'Bearer mock-jwt-token-' + Date.now()
105
+ },
106
+ simulatedAt: new Date().toISOString(),
107
+ note: 'This is a simulation - no actual HTTP request was made. Real payware callbacks use JWT tokens in Authorization header.'
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Payment Institution callback simulation tool implementation
113
+ */
114
+ export const simulatePICallbackTool = {
115
+ name: "payware_operations_simulate_callback",
116
+ 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.",
117
+ inputSchema: {
118
+ type: "object",
119
+ additionalProperties: false,
120
+ properties: {
121
+ transactionId: {
122
+ type: "string",
123
+ description: "Transaction ID to simulate callback for"
124
+ },
125
+ callbackType: {
126
+ type: "string",
127
+ enum: ["TRANSACTION_PROCESSED", "TRANSACTION_FINALIZED"],
128
+ description: "Type of callback to simulate",
129
+ default: "TRANSACTION_PROCESSED"
130
+ },
131
+ callbackUrl: {
132
+ type: "string",
133
+ description: "URL where callback would be sent (for simulation only)",
134
+ format: "uri"
135
+ },
136
+ amount: {
137
+ type: "string",
138
+ description: "Transaction amount (e.g., '57.00')",
139
+ default: "57.00"
140
+ },
141
+ currency: {
142
+ type: "string",
143
+ enum: ["EUR", "USD", "GBP"],
144
+ description: "Transaction currency",
145
+ default: "EUR"
146
+ },
147
+ fee: {
148
+ type: "string",
149
+ description: "Fee amount charged by payment institution (e.g., '0.60')",
150
+ default: "0.60"
151
+ },
152
+ payeeBIC: {
153
+ type: "string",
154
+ description: "Payee's BIC code",
155
+ default: "SBBICID1"
156
+ },
157
+ payeeAccount: {
158
+ type: "string",
159
+ description: "Payee account identifier",
160
+ default: "M-1W-1account2"
161
+ },
162
+ payeeFriendlyName: {
163
+ type: "string",
164
+ description: "Payee friendly name",
165
+ default: "payware"
166
+ },
167
+ payerBIC: {
168
+ type: "string",
169
+ description: "Payer's BIC code",
170
+ default: "SBBICID1"
171
+ },
172
+ payerAccount: {
173
+ type: "string",
174
+ description: "Payer account identifier",
175
+ default: "payerAccount"
176
+ },
177
+ payerFriendlyName: {
178
+ type: "string",
179
+ description: "Payer friendly name",
180
+ default: "Demo Financial Institution"
181
+ },
182
+ reasonL1: {
183
+ type: "string",
184
+ description: "Transaction reason line 1",
185
+ default: "57"
186
+ },
187
+ reasonL2: {
188
+ type: "string",
189
+ description: "Transaction reason line 2 (optional)"
190
+ },
191
+ timeToLive: {
192
+ type: "number",
193
+ description: "Remaining time to live in seconds",
194
+ default: 600
195
+ },
196
+ status: {
197
+ type: "string",
198
+ enum: ["CONFIRMED", "DECLINED", "FAILED", "CANCELLED"],
199
+ description: "Transaction status (only for TRANSACTION_FINALIZED callbacks)",
200
+ default: "CONFIRMED"
201
+ },
202
+ statusMessage: {
203
+ type: "string",
204
+ description: "Status message (only for TRANSACTION_FINALIZED callbacks)"
205
+ }
206
+ },
207
+ required: ["transactionId"]
208
+ },
209
+
210
+ async handler(args) {
211
+ const {
212
+ transactionId,
213
+ callbackType = 'TRANSACTION_PROCESSED',
214
+ callbackUrl,
215
+ amount = '57.00',
216
+ currency = 'EUR',
217
+ fee = '0.60',
218
+ payeeBIC = 'SBBICID1',
219
+ payeeAccount = 'M-1W-1account2',
220
+ payeeFriendlyName = 'payware',
221
+ payerBIC = 'SBBICID1',
222
+ payerAccount = 'payerAccount',
223
+ payerFriendlyName = 'Demo Financial Institution',
224
+ reasonL1 = '57',
225
+ reasonL2,
226
+ timeToLive = 600,
227
+ status = 'CONFIRMED',
228
+ statusMessage
229
+ } = args;
230
+
231
+ if (!transactionId) {
232
+ throw new Error("Transaction ID is required");
233
+ }
234
+
235
+ // Generate mock callback payload
236
+ const payload = generateMockPICallback(transactionId, callbackType, {
237
+ amount,
238
+ currency,
239
+ fee,
240
+ payeeBIC,
241
+ payeeAccount,
242
+ payeeFriendlyName,
243
+ payerBIC,
244
+ payerAccount,
245
+ payerFriendlyName,
246
+ reasonL1,
247
+ reasonL2,
248
+ timeToLive,
249
+ initiatedBy: 'PEER',
250
+ transactionType: 'DEFAULT',
251
+ status,
252
+ statusMessage
253
+ });
254
+
255
+ // Simulate callback delivery if URL provided
256
+ let deliveryResult = null;
257
+ if (callbackUrl) {
258
+ deliveryResult = await simulatePICallbackDelivery(callbackUrl, payload);
259
+ }
260
+
261
+ const callbackEmojis = {
262
+ 'TRANSACTION_PROCESSED': '🔄',
263
+ 'TRANSACTION_FINALIZED': '✅'
264
+ };
265
+
266
+ const statusEmojis = {
267
+ 'CONFIRMED': '✅',
268
+ 'DECLINED': '❌',
269
+ 'FAILED': '💥',
270
+ 'CANCELLED': '🚫'
271
+ };
272
+
273
+ const callbackEmoji = callbackEmojis[callbackType] || '📨';
274
+ const statusEmoji = statusEmojis[status] || '❓';
275
+
276
+ return {
277
+ content: [{
278
+ type: "text",
279
+ text: `${callbackEmoji} **Payment Institution Callback Simulation Complete**
280
+
281
+ **Transaction:** ${transactionId}
282
+ **Callback Type:** ${callbackType}
283
+ ${callbackType === 'TRANSACTION_FINALIZED' ? `**Status:** ${statusEmoji} ${status}` : ''}
284
+
285
+ **Mock Callback Payload:**
286
+ \`\`\`json
287
+ ${JSON.stringify(payload, null, 2)}
288
+ \`\`\`
289
+
290
+ ${deliveryResult ? `
291
+ **Callback Delivery Simulation:**
292
+ ${deliveryResult.success ? '✅ Callback would be delivered successfully' : '❌ Callback delivery would fail'}
293
+
294
+ **Delivery Details:**
295
+ - URL: ${deliveryResult.url || 'N/A'}
296
+ - Headers: ${JSON.stringify(deliveryResult.headers || {}, null, 2)}
297
+ - Simulated At: ${deliveryResult.simulatedAt || 'N/A'}
298
+
299
+ **Note:** ${deliveryResult.note || 'No actual HTTP request was made'}
300
+ ` : '**No callback URL provided** - only payload generated'}
301
+
302
+ **Payment Institution Callback Types:**
303
+ - 🔄 **TRANSACTION_PROCESSED**: Merchant has processed your transaction (ready for finalization)
304
+ - ✅ **TRANSACTION_FINALIZED**: Transaction completed with final status
305
+
306
+ **Transaction Flow:**
307
+ 1. Payment Institution creates transaction as SRC (payer) or DST (payee)
308
+ 2. Transaction can be processed by merchant OR payment institution → **TRANSACTION_PROCESSED** callback to PI
309
+ 3. Transaction can be finalized ONLY by payment institution → **TRANSACTION_FINALIZED** callback to PI
310
+ 4. Transaction can be cancelled ONLY by its issuer (creator)
311
+
312
+ **Integration Testing:**
313
+ 1. Use this payload to test your payment institution callback handler
314
+ 2. Verify handling of both TRANSACTION_PROCESSED and TRANSACTION_FINALIZED
315
+ 3. Test different status scenarios for finalized transactions
316
+ 4. Ensure proper BIC and account information processing
317
+
318
+ **Next Steps:**
319
+ 1. Implement callback endpoint to receive this payload structure
320
+ 2. Test with both callback types
321
+ 3. Add signature verification in production
322
+ 4. Set up proper error handling and retry logic`
323
+ }]
324
+ };
325
+ }
326
+ };
@@ -0,0 +1,269 @@
1
+ import axios from 'axios';
2
+ import FormData from 'form-data';
3
+ import { createJWTToken } from '../../core/auth/jwt-token.js';
4
+ import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
5
+ import { readFileSync } from 'fs';
6
+
7
+ /**
8
+ * Get transaction information using Soundbite file via payware API
9
+ * @param {Object} params - Soundbite transaction parameters
10
+ * @returns {Object} Transaction response
11
+ */
12
+ export async function getSoundbiteTransaction({
13
+ filePath,
14
+ partnerId,
15
+ privateKey,
16
+ useSandbox = true
17
+ }) {
18
+ if (!filePath) {
19
+ throw new Error('filePath is required for soundbite transaction');
20
+ }
21
+
22
+ if (!partnerId || !privateKey) {
23
+ throw new Error('Partner ID and private key are required for proper JWT creation');
24
+ }
25
+
26
+ let fileBuffer;
27
+ try {
28
+ fileBuffer = readFileSync(filePath);
29
+ } catch (error) {
30
+ throw new Error(`Failed to read soundbite file: ${error.message}`);
31
+ }
32
+
33
+ // Create form data
34
+ const formData = new FormData();
35
+ formData.append('file', fileBuffer, {
36
+ filename: filePath.split('/').pop() || 'soundbite.lo',
37
+ contentType: 'application/octet-stream'
38
+ });
39
+
40
+ // For multipart/form-data requests, we don't calculate contentMd5 the same way
41
+ // The JWT token is created without content MD5 for multipart uploads
42
+ const tokenData = createJWTToken(partnerId, privateKey, null);
43
+
44
+ // Required headers as per payware API documentation
45
+ const headers = {
46
+ 'Authorization': `Bearer ${tokenData.token}`,
47
+ 'Api-Version': '1', // Required: current API version
48
+ ...formData.getHeaders()
49
+ };
50
+
51
+ try {
52
+ const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
53
+ const response = await axios.post(`${baseUrl}/transactions`, formData, {
54
+ headers,
55
+ maxContentLength: Infinity,
56
+ maxBodyLength: Infinity
57
+ });
58
+
59
+ return {
60
+ success: true,
61
+ transaction: response.data,
62
+ requestId: response.headers['x-request-id'],
63
+ timestamp: new Date().toISOString()
64
+ };
65
+ } catch (error) {
66
+ return {
67
+ success: false,
68
+ error: {
69
+ message: error.response?.data?.message || error.message,
70
+ status: error.response?.status,
71
+ code: error.response?.data?.code,
72
+ details: error.response?.data
73
+ },
74
+ timestamp: new Date().toISOString()
75
+ };
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Soundbite transaction tool implementation
81
+ */
82
+ export const soundbiteTransactionTool = {
83
+ name: "payware_operations_soundbite_transaction",
84
+ description: `Get transaction information using a Soundbite SDK output file. This allows payment institutions to process transactions using audio-based identifiers.
85
+
86
+ **Soundbite Integration:**
87
+ - Upload Soundbite SDK output file (.lo extension)
88
+ - File contains audio-encoded transaction identifier
89
+ - Alternative to QR/barcode scanning for accessibility
90
+ - Returns same transaction information as regular transaction lookup
91
+
92
+ **File Requirements:**
93
+ - File must be output from Soundbite SDK
94
+ - Supported file format: .lo (Soundbite format)
95
+ - File must contain valid transaction identifier
96
+ - Maximum file size limits apply
97
+
98
+ **API Request:**
99
+ - Uses multipart/form-data content type
100
+ - File uploaded as form field named 'file'
101
+ - JWT authentication without contentMd5 (multipart upload)`,
102
+ inputSchema: {
103
+ type: "object",
104
+ properties: {
105
+ filePath: {
106
+ type: "string",
107
+ description: "Absolute path to the Soundbite SDK output file (typically with .lo extension)"
108
+ },
109
+ partnerId: {
110
+ type: "string",
111
+ description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
112
+ default: getPartnerIdSafe()
113
+ },
114
+ privateKey: {
115
+ type: "string",
116
+ description: "RSA private key for JWT token creation. Uses environment-specific private key as default.",
117
+ default: getPrivateKeySafe()
118
+ },
119
+ useSandbox: {
120
+ type: "boolean",
121
+ description: "Use sandbox environment for testing",
122
+ default: true
123
+ }
124
+ },
125
+ required: ["filePath"]
126
+ },
127
+
128
+ async handler(args) {
129
+ const {
130
+ filePath,
131
+ partnerId = getPartnerIdSafe(),
132
+ privateKey = getPrivateKeySafe(args.useSandbox ?? true),
133
+ useSandbox = true
134
+ } = args;
135
+
136
+ if (!filePath) {
137
+ throw new Error("filePath is required for soundbite transaction");
138
+ }
139
+
140
+ if (!partnerId) {
141
+ throw new Error("Partner ID is required. Provide via 'partnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
142
+ }
143
+
144
+ if (!privateKey) {
145
+ throw new Error("Private key is required. Provide via 'privateKey' parameter or set PAYWARE_PRIVATE_KEY environment variable.");
146
+ }
147
+
148
+ const result = await getSoundbiteTransaction({
149
+ filePath,
150
+ partnerId,
151
+ privateKey,
152
+ useSandbox
153
+ });
154
+
155
+ if (result.success) {
156
+ const tx = result.transaction;
157
+ const createdDate = tx.created ? new Date(tx.created * 1000).toISOString() : 'N/A';
158
+ const typeDisplay = tx.transactionType || 'DEFAULT';
159
+ const initiatorDisplay = tx.initiatedBy || 'UNKNOWN';
160
+
161
+ return {
162
+ content: [{
163
+ type: "text",
164
+ text: `🔊 **Soundbite Transaction Retrieved Successfully**
165
+
166
+ **Transaction Information:**
167
+ - ID: ${tx.transactionId || 'N/A'}
168
+ - Type: ${typeDisplay}
169
+ - Initiated By: ${initiatorDisplay}
170
+ - Status: ⏳ ACTIVE
171
+ - Created: ${createdDate}
172
+ - Remaining TTL: ${tx.timeToLive || 'N/A'} seconds
173
+
174
+ **Transaction Details:**
175
+ - Amount: ${tx.amount || 'N/A'} ${tx.currency || 'N/A'}
176
+ - Reason L1: ${tx.reasonL1 || 'N/A'}
177
+ ${tx.reasonL2 ? `- Reason L2: ${tx.reasonL2}` : ''}
178
+
179
+ **Payee Information:**
180
+ - Account: ${tx.payeeAccount || 'N/A'}
181
+ - Friendly Name: ${tx.payeeFriendlyName || 'N/A'}
182
+ - BIC: ${tx.payeeBIC || 'N/A'}
183
+
184
+ **Payer Information:**
185
+ - Account: ${tx.payerAccount || 'N/A'}
186
+ - Friendly Name: ${tx.payerFriendlyName || 'N/A'}
187
+ - BIC: ${tx.payerBIC || 'N/A'}
188
+
189
+ **Soundbite Details:**
190
+ - File Path: ${filePath}
191
+ - File Name: ${filePath.split('/').pop()}
192
+ - Processing Method: Audio-based transaction identifier
193
+
194
+ **Full API Response:**
195
+ \`\`\`json
196
+ ${JSON.stringify(result.transaction, null, 2)}
197
+ \`\`\`
198
+
199
+ **API Call Details:**
200
+ - Endpoint: POST ${baseUrl}/transactions (multipart/form-data)
201
+ - Request ID: ${result.requestId || 'N/A'}
202
+ - Timestamp: ${result.timestamp}
203
+
204
+ **Next Steps:**
205
+ 1. Transaction successfully identified from soundbite file
206
+ 2. Use transaction ID: \`${tx.transactionId || 'N/A'}\` for further operations
207
+ 3. ${!tx.payerAccount ? 'Process this transaction if you are the payer' : 'Transaction ready for finalization'}
208
+ 4. Use \`payware_pi_process_transaction\` to process payment
209
+ 5. Use \`payware_pi_finalize_transaction\` to confirm/decline
210
+
211
+ **♿ Accessibility Note:**
212
+ - Soundbite provides audio-based alternative to QR/barcode scanning
213
+ - Enables accessible payment processing for visually impaired users
214
+ - Same functionality as visual transaction identifiers`
215
+ }]
216
+ };
217
+ } else {
218
+ return {
219
+ content: [{
220
+ type: "text",
221
+ text: `❌ **Soundbite Transaction Processing Failed**
222
+
223
+ **File Path:** ${filePath}
224
+
225
+ **Error Details:**
226
+ - Message: ${result.error.message}
227
+ - Status: ${result.error.status || 'N/A'}
228
+ - Code: ${result.error.code || 'N/A'}
229
+
230
+ **Full Error Response:**
231
+ \`\`\`json
232
+ ${JSON.stringify(result.error.details || result.error, null, 2)}
233
+ \`\`\`
234
+
235
+ **Timestamp:** ${result.timestamp}
236
+
237
+ **Common Soundbite Issues:**
238
+ 1. **File Not Found**: Verify the file path is correct and accessible
239
+ 2. **Invalid File Format**: Ensure file is a valid Soundbite SDK output (.lo format)
240
+ 3. **Corrupted Audio Data**: File may be corrupted or invalid
241
+ 4. **Transaction Not Found**: Audio may not contain valid transaction identifier
242
+ 5. **File Size Limits**: File may exceed maximum upload size
243
+ 6. **Authentication Issues**: Verify JWT token and partner credentials
244
+
245
+ **Troubleshooting:**
246
+ 1. **File Path**: Ensure file path is absolute and file exists
247
+ 2. **File Format**: Verify file is output from Soundbite SDK (usually .lo extension)
248
+ 3. **File Integrity**: Check file is not corrupted or modified
249
+ 4. **Audio Quality**: Ensure soundbite was captured with sufficient quality
250
+ 5. **Transaction Validity**: Verify the original transaction hasn't expired
251
+ 6. **Permissions**: Check file read permissions
252
+
253
+ **File Requirements:**
254
+ - ✅ Valid Soundbite SDK output file
255
+ - ✅ Readable file permissions
256
+ - ✅ File size within limits
257
+ - ✅ Contains valid transaction identifier
258
+ - ✅ Transaction still active/valid
259
+
260
+ **Alternative Actions:**
261
+ - Try capturing soundbite again if audio quality was poor
262
+ - Use QR/barcode scanning as alternative
263
+ - Verify original transaction is still active
264
+ - Check Soundbite SDK integration and file generation`
265
+ }]
266
+ };
267
+ }
268
+ }
269
+ };