@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,470 @@
1
+ import {
2
+ registerAudio,
3
+ getProductAudios,
4
+ getAudio,
5
+ updateAudio,
6
+ deleteAudio
7
+ } from '../../shared/products/products-api.js';
8
+ import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
9
+
10
+ // Common ISV authentication properties
11
+ const ISV_AUTH_PROPS = {
12
+ merchantPartnerId: {
13
+ type: "string",
14
+ description: "Target merchant partner ID (8 alphanumeric characters, e.g., 'PZAYNMVE')"
15
+ },
16
+ oauth2Token: {
17
+ type: "string",
18
+ description: "OAuth2 access token obtained from the merchant"
19
+ }
20
+ };
21
+
22
+ // Common ISV validation and credential setup
23
+ function validateISVAuth(args) {
24
+ const { merchantPartnerId, oauth2Token } = args;
25
+
26
+ if (!merchantPartnerId) {
27
+ throw new Error("Merchant Partner ID is required for ISV operations");
28
+ }
29
+
30
+ if (!oauth2Token) {
31
+ throw new Error("OAuth2 token is required for ISV operations");
32
+ }
33
+
34
+ const isvPartnerId = getPartnerIdSafe();
35
+ const privateKey = getPrivateKeySafe();
36
+
37
+ if (!isvPartnerId || !privateKey) {
38
+ throw new Error("ISV credentials are required");
39
+ }
40
+
41
+ return { isvPartnerId, privateKey, merchantPartnerId, oauth2Token };
42
+ }
43
+
44
+ /**
45
+ * Register audio tool implementation for ISVs
46
+ */
47
+ export const registerAudioTool = {
48
+ name: "payware_products_register_audio",
49
+ description: `Register an audio file (soundbite) for a merchant's product (ISV operation).
50
+
51
+ **Supported formats:** Most audio/video formats (up to 200MB)
52
+ **Note:** For video files, only the audio channel is registered`,
53
+
54
+ inputSchema: {
55
+ type: "object",
56
+ properties: {
57
+ ...ISV_AUTH_PROPS,
58
+ productId: {
59
+ type: "string",
60
+ description: "Product identifier (starts with 'pr')",
61
+ pattern: "^pr[a-zA-Z0-9]+$"
62
+ },
63
+ audioPath: {
64
+ type: "string",
65
+ description: "Path to the audio file to upload (e.g., '/path/to/audio.mp3')"
66
+ },
67
+ useSandbox: {
68
+ type: "boolean",
69
+ description: "Use sandbox environment",
70
+ default: true
71
+ }
72
+ },
73
+ required: ["merchantPartnerId", "oauth2Token", "productId", "audioPath"]
74
+ },
75
+
76
+ async handler(args) {
77
+ const { productId, audioPath, useSandbox = true } = args;
78
+ const { isvPartnerId, privateKey, merchantPartnerId, oauth2Token } = validateISVAuth(args);
79
+
80
+ if (!productId || !audioPath) {
81
+ throw new Error("Product ID and audio file path are required");
82
+ }
83
+
84
+ try {
85
+ const result = await registerAudio({
86
+ productId,
87
+ audioPath,
88
+ partnerType: 'isv',
89
+ isvPartnerId,
90
+ privateKey,
91
+ merchantPartnerId,
92
+ oauth2Token,
93
+ useSandbox
94
+ });
95
+
96
+ const audio = result.data;
97
+
98
+ return {
99
+ content: [{
100
+ type: "text",
101
+ text: `🎵 **Audio Registered Successfully (ISV -> Merchant: ${merchantPartnerId})**
102
+
103
+ **Audio Details:**
104
+ - ID: ${audio.id}
105
+ - Product ID: ${audio.productId}
106
+ - Title: ${audio.title}
107
+ - Status: ${audio.status === '1' ? '✅ Ready' : '⏳ Processing'}
108
+ - Duration: ${audio.duration} seconds
109
+ - Uploaded: ${audio.uploadedAt}
110
+
111
+ **ISV Integration Details:**
112
+ - ISV Partner: ${isvPartnerId}
113
+ - Target Merchant: ${merchantPartnerId}
114
+ - OAuth2 Token: ${oauth2Token.substring(0, 8)}...
115
+
116
+ **Important Notes:**
117
+ ${audio.status === '0' ? '⏳ Audio is being processed. Check status with `payware_products_get_audio`' : ''}
118
+ ${audio.status === '1' ? '✅ Audio is ready for use in soundbite transactions' : ''}`
119
+ }]
120
+ };
121
+ } catch (error) {
122
+ return {
123
+ content: [{
124
+ type: "text",
125
+ text: `❌ **Audio Registration Failed**
126
+
127
+ **Error:** ${error.message}
128
+ **Product ID:** ${productId}
129
+ **Audio Path:** ${audioPath}
130
+ **ISV -> Merchant:** ${isvPartnerId} -> ${merchantPartnerId}`
131
+ }]
132
+ };
133
+ }
134
+ }
135
+ };
136
+
137
+ /**
138
+ * Get product audios tool implementation for ISVs
139
+ */
140
+ export const getAudiosTool = {
141
+ name: "payware_products_get_audios",
142
+ description: "Get all registered audio files for a merchant's product (ISV operation)",
143
+
144
+ inputSchema: {
145
+ type: "object",
146
+ properties: {
147
+ ...ISV_AUTH_PROPS,
148
+ productId: {
149
+ type: "string",
150
+ description: "Product identifier (starts with 'pr')",
151
+ pattern: "^pr[a-zA-Z0-9]+$"
152
+ },
153
+ useSandbox: {
154
+ type: "boolean",
155
+ description: "Use sandbox environment",
156
+ default: true
157
+ }
158
+ },
159
+ required: ["merchantPartnerId", "oauth2Token", "productId"]
160
+ },
161
+
162
+ async handler(args) {
163
+ const { productId, useSandbox = true } = args;
164
+ const { isvPartnerId, privateKey, merchantPartnerId, oauth2Token } = validateISVAuth(args);
165
+
166
+ try {
167
+ const result = await getProductAudios({
168
+ productId,
169
+ partnerType: 'isv',
170
+ isvPartnerId,
171
+ privateKey,
172
+ merchantPartnerId,
173
+ oauth2Token,
174
+ useSandbox
175
+ });
176
+
177
+ const audios = result.data;
178
+ const audioCount = Array.isArray(audios) ? audios.length : 0;
179
+
180
+ let audiosList = '';
181
+ if (Array.isArray(audios) && audios.length > 0) {
182
+ audiosList = audios.map(audio =>
183
+ `**Audio ${audio.id}:**
184
+ - Title: ${audio.title}
185
+ - Status: ${audio.status === '1' ? '✅ Ready' : '⏳ Processing'}
186
+ - Duration: ${audio.duration} seconds
187
+ - Uploaded: ${audio.uploadedAt}`
188
+ ).join('\n\n');
189
+ } else {
190
+ audiosList = 'No audio files found for this product.';
191
+ }
192
+
193
+ return {
194
+ content: [{
195
+ type: "text",
196
+ text: `🎵 **Product Audio Files (ISV -> Merchant: ${merchantPartnerId})**
197
+
198
+ **Product ID:** ${productId}
199
+ **Total Audio Files:** ${audioCount}
200
+
201
+ **ISV Integration Details:**
202
+ - ISV Partner: ${isvPartnerId}
203
+ - Target Merchant: ${merchantPartnerId}
204
+
205
+ **Audio Files:**
206
+ ${audiosList}`
207
+ }]
208
+ };
209
+ } catch (error) {
210
+ return {
211
+ content: [{
212
+ type: "text",
213
+ text: `❌ **Failed to Get Audio Files**
214
+
215
+ **Error:** ${error.message}
216
+ **Product ID:** ${productId}`
217
+ }]
218
+ };
219
+ }
220
+ }
221
+ };
222
+
223
+ /**
224
+ * Get audio tool implementation for ISVs
225
+ */
226
+ export const getAudioTool = {
227
+ name: "payware_products_get_audio",
228
+ description: "Get detailed information about a specific audio file (ISV operation)",
229
+
230
+ inputSchema: {
231
+ type: "object",
232
+ properties: {
233
+ ...ISV_AUTH_PROPS,
234
+ productId: {
235
+ type: "string",
236
+ description: "Product identifier (starts with 'pr')",
237
+ pattern: "^pr[a-zA-Z0-9]+$"
238
+ },
239
+ audioId: {
240
+ type: "number",
241
+ description: "Audio identifier"
242
+ },
243
+ useSandbox: {
244
+ type: "boolean",
245
+ description: "Use sandbox environment",
246
+ default: true
247
+ }
248
+ },
249
+ required: ["merchantPartnerId", "oauth2Token", "productId", "audioId"]
250
+ },
251
+
252
+ async handler(args) {
253
+ const { productId, audioId, useSandbox = true } = args;
254
+ const { isvPartnerId, privateKey, merchantPartnerId, oauth2Token } = validateISVAuth(args);
255
+
256
+ try {
257
+ const result = await getAudio({
258
+ productId,
259
+ audioId,
260
+ partnerType: 'isv',
261
+ isvPartnerId,
262
+ privateKey,
263
+ merchantPartnerId,
264
+ oauth2Token,
265
+ useSandbox
266
+ });
267
+
268
+ const audio = result.data;
269
+
270
+ return {
271
+ content: [{
272
+ type: "text",
273
+ text: `🎵 **Audio Details (ISV -> Merchant: ${merchantPartnerId})**
274
+
275
+ **Audio Information:**
276
+ - ID: ${audio.id}
277
+ - Product ID: ${audio.productId}
278
+ - Title: ${audio.title}
279
+ - Status: ${audio.status === '1' ? '✅ Ready for use' : '⏳ Processing'}
280
+ - Duration: ${audio.duration} seconds
281
+ - Uploaded: ${audio.uploadedAt}
282
+
283
+ **Status Information:**
284
+ ${audio.status === '0' ? '⏳ **Processing:** Audio is being processed and will be available soon' : ''}
285
+ ${audio.status === '1' ? '✅ **Ready:** Audio is processed and ready for soundbite transactions' : ''}`
286
+ }]
287
+ };
288
+ } catch (error) {
289
+ return {
290
+ content: [{
291
+ type: "text",
292
+ text: `❌ **Failed to Get Audio**
293
+
294
+ **Error:** ${error.message}
295
+ **Product ID:** ${productId}
296
+ **Audio ID:** ${audioId}`
297
+ }]
298
+ };
299
+ }
300
+ }
301
+ };
302
+
303
+ /**
304
+ * Update audio tool implementation for ISVs
305
+ */
306
+ export const updateAudioTool = {
307
+ name: "payware_products_update_audio",
308
+ description: "Update audio information (title) or reassign audio to another product (ISV operation)",
309
+
310
+ inputSchema: {
311
+ type: "object",
312
+ properties: {
313
+ ...ISV_AUTH_PROPS,
314
+ productId: {
315
+ type: "string",
316
+ description: "Current product identifier (starts with 'pr')",
317
+ pattern: "^pr[a-zA-Z0-9]+$"
318
+ },
319
+ audioId: {
320
+ type: "number",
321
+ description: "Audio identifier"
322
+ },
323
+ title: {
324
+ type: "string",
325
+ description: "New audio title",
326
+ maxLength: 150
327
+ },
328
+ newProductId: {
329
+ type: "string",
330
+ description: "New product ID to reassign audio to (starts with 'pr')",
331
+ pattern: "^pr[a-zA-Z0-9]+$"
332
+ },
333
+ useSandbox: {
334
+ type: "boolean",
335
+ description: "Use sandbox environment",
336
+ default: true
337
+ }
338
+ },
339
+ required: ["merchantPartnerId", "oauth2Token", "productId", "audioId"]
340
+ },
341
+
342
+ async handler(args) {
343
+ const { productId, audioId, title, newProductId, useSandbox = true } = args;
344
+ const { isvPartnerId, privateKey, merchantPartnerId, oauth2Token } = validateISVAuth(args);
345
+
346
+ if (!title && !newProductId) {
347
+ throw new Error("Either title or newProductId must be provided to update");
348
+ }
349
+
350
+ try {
351
+ const result = await updateAudio({
352
+ productId,
353
+ audioId,
354
+ title,
355
+ newProductId,
356
+ partnerType: 'isv',
357
+ isvPartnerId,
358
+ privateKey,
359
+ merchantPartnerId,
360
+ oauth2Token,
361
+ useSandbox
362
+ });
363
+
364
+ const audio = result.data;
365
+
366
+ return {
367
+ content: [{
368
+ type: "text",
369
+ text: `✅ **Audio Updated Successfully (ISV -> Merchant: ${merchantPartnerId})**
370
+
371
+ **Updated Audio:**
372
+ - ID: ${audio.id}
373
+ - Product ID: ${audio.productId}${newProductId ? ` (reassigned from ${productId})` : ''}
374
+ - Title: ${audio.title}
375
+ - Status: ${audio.status === '1' ? '✅ Ready' : '⏳ Processing'}
376
+ - Duration: ${audio.duration} seconds
377
+
378
+ **Changes Made:**
379
+ ${title ? `- Title updated to: "${title}"` : ''}
380
+ ${newProductId ? `- Reassigned from product ${productId} to ${newProductId}` : ''}`
381
+ }]
382
+ };
383
+ } catch (error) {
384
+ return {
385
+ content: [{
386
+ type: "text",
387
+ text: `❌ **Audio Update Failed**
388
+
389
+ **Error:** ${error.message}
390
+ **Product ID:** ${productId}
391
+ **Audio ID:** ${audioId}`
392
+ }]
393
+ };
394
+ }
395
+ }
396
+ };
397
+
398
+ /**
399
+ * Delete audio tool implementation for ISVs
400
+ */
401
+ export const deleteAudioTool = {
402
+ name: "payware_products_delete_audio",
403
+ description: "Delete an audio file from a merchant's product (ISV operation). This action cannot be undone.",
404
+
405
+ inputSchema: {
406
+ type: "object",
407
+ properties: {
408
+ ...ISV_AUTH_PROPS,
409
+ productId: {
410
+ type: "string",
411
+ description: "Product identifier (starts with 'pr')",
412
+ pattern: "^pr[a-zA-Z0-9]+$"
413
+ },
414
+ audioId: {
415
+ type: "number",
416
+ description: "Audio identifier"
417
+ },
418
+ useSandbox: {
419
+ type: "boolean",
420
+ description: "Use sandbox environment",
421
+ default: true
422
+ }
423
+ },
424
+ required: ["merchantPartnerId", "oauth2Token", "productId", "audioId"]
425
+ },
426
+
427
+ async handler(args) {
428
+ const { productId, audioId, useSandbox = true } = args;
429
+ const { isvPartnerId, privateKey, merchantPartnerId, oauth2Token } = validateISVAuth(args);
430
+
431
+ try {
432
+ const result = await deleteAudio({
433
+ productId,
434
+ audioId,
435
+ partnerType: 'isv',
436
+ isvPartnerId,
437
+ privateKey,
438
+ merchantPartnerId,
439
+ oauth2Token,
440
+ useSandbox
441
+ });
442
+
443
+ return {
444
+ content: [{
445
+ type: "text",
446
+ text: `🗑️ **Audio Deleted Successfully (ISV -> Merchant: ${merchantPartnerId})**
447
+
448
+ **Deleted Audio:**
449
+ - Product ID: ${productId}
450
+ - Audio ID: ${audioId}
451
+
452
+ **Important Notes:**
453
+ ⚠️ This action cannot be undone
454
+ ⚠️ Any soundbite transactions using this audio may be affected`
455
+ }]
456
+ };
457
+ } catch (error) {
458
+ return {
459
+ content: [{
460
+ type: "text",
461
+ text: `❌ **Audio Deletion Failed**
462
+
463
+ **Error:** ${error.message}
464
+ **Product ID:** ${productId}
465
+ **Audio ID:** ${audioId}`
466
+ }]
467
+ };
468
+ }
469
+ }
470
+ };