@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,497 @@
1
+ /**
2
+ * Merchant product management examples
3
+ */
4
+
5
+ import { ExampleGenerator, CommonTemplates } from '../common/helpers.js';
6
+
7
+ /**
8
+ * Merchant product operations
9
+ */
10
+ export const MerchantProductOperations = {
11
+ create_product: {
12
+ description: 'Create a new product for merchant',
13
+ endpoint: '/products',
14
+ method: 'POST',
15
+ sampleBody: {
16
+ name: 'Premium Coffee Blend',
17
+ shortDescription: 'Our signature premium coffee blend with rich flavor',
18
+ prData: {
19
+ type: 'ITEM',
20
+ regularPrice: '25.99',
21
+ currency: 'EUR',
22
+ timeToLive: 86400
23
+ },
24
+ prOptions: {
25
+ imageUrl: 'https://example.com/coffee-image.jpg',
26
+ category: 'beverages',
27
+ tags: ['coffee', 'premium', 'organic']
28
+ }
29
+ }
30
+ },
31
+
32
+ get_product: {
33
+ description: 'Get product details',
34
+ endpoint: '/products/{id}',
35
+ method: 'GET',
36
+ sampleBody: null
37
+ },
38
+
39
+ update_product: {
40
+ description: 'Update existing product',
41
+ endpoint: '/products/{id}',
42
+ method: 'PATCH',
43
+ sampleBody: {
44
+ name: 'Premium Coffee Blend - Updated',
45
+ prData: {
46
+ regularPrice: '24.99',
47
+ currency: 'EUR'
48
+ },
49
+ prOptions: {
50
+ imageUrl: 'https://example.com/coffee-new-image.jpg'
51
+ }
52
+ }
53
+ },
54
+
55
+ delete_product: {
56
+ description: 'Delete a product',
57
+ endpoint: '/products/{id}',
58
+ method: 'DELETE',
59
+ sampleBody: null
60
+ },
61
+
62
+ list_products: {
63
+ description: 'List all merchant products',
64
+ endpoint: '/products',
65
+ method: 'GET',
66
+ sampleBody: null,
67
+ queryParams: {
68
+ limit: 20,
69
+ offset: 0,
70
+ category: 'beverages',
71
+ status: 'active'
72
+ }
73
+ },
74
+
75
+ get_product_image: {
76
+ description: 'Get product image',
77
+ endpoint: '/products/{id}/image',
78
+ method: 'GET',
79
+ sampleBody: null
80
+ },
81
+
82
+ create_schedule: {
83
+ description: 'Create product schedule',
84
+ endpoint: '/products/{id}/schedules',
85
+ method: 'POST',
86
+ sampleBody: {
87
+ name: 'Weekend Special',
88
+ scheduleType: 'DISCOUNT',
89
+ startDate: '2024-01-01T00:00:00Z',
90
+ endDate: '2024-12-31T23:59:59Z',
91
+ conditions: {
92
+ dayOfWeek: ['SATURDAY', 'SUNDAY'],
93
+ timeRange: {
94
+ start: '10:00',
95
+ end: '18:00'
96
+ }
97
+ },
98
+ action: {
99
+ discountPercent: 15
100
+ }
101
+ }
102
+ },
103
+
104
+ update_schedule: {
105
+ description: 'Update product schedule',
106
+ endpoint: '/products/{id}/schedules/{scheduleId}',
107
+ method: 'PATCH',
108
+ sampleBody: {
109
+ action: {
110
+ discountPercent: 20
111
+ },
112
+ conditions: {
113
+ dayOfWeek: ['FRIDAY', 'SATURDAY', 'SUNDAY']
114
+ }
115
+ }
116
+ },
117
+
118
+ delete_schedule: {
119
+ description: 'Delete product schedule',
120
+ endpoint: '/products/{id}/schedules/{scheduleId}',
121
+ method: 'DELETE',
122
+ sampleBody: null
123
+ },
124
+
125
+ list_schedules: {
126
+ description: 'List product schedules',
127
+ endpoint: '/products/{id}/schedules',
128
+ method: 'GET',
129
+ sampleBody: null
130
+ },
131
+
132
+ // Audio/Soundbite Operations
133
+ register_audio: {
134
+ description: 'Register audio file for a product',
135
+ endpoint: '/products/{id}/audios/upload',
136
+ method: 'POST',
137
+ contentType: 'multipart/form-data',
138
+ sampleBody: {
139
+ file: '@/path/to/audio.mp3'
140
+ }
141
+ },
142
+
143
+ get_audios: {
144
+ description: 'Get all audio files for a product',
145
+ endpoint: '/products/{id}/audios',
146
+ method: 'GET',
147
+ sampleBody: null
148
+ },
149
+
150
+ get_audio: {
151
+ description: 'Get specific audio file details',
152
+ endpoint: '/products/{id}/audios/{audioId}',
153
+ method: 'GET',
154
+ sampleBody: null
155
+ },
156
+
157
+ update_audio: {
158
+ description: 'Update audio file information',
159
+ endpoint: '/products/{id}/audios/{audioId}',
160
+ method: 'PATCH',
161
+ sampleBody: {
162
+ title: 'Updated Audio Title',
163
+ productId: 'pr_new_product_789'
164
+ }
165
+ },
166
+
167
+ delete_audio: {
168
+ description: 'Delete audio file',
169
+ endpoint: '/products/{id}/audios/{audioId}',
170
+ method: 'DELETE',
171
+ sampleBody: null
172
+ }
173
+ };
174
+
175
+ /**
176
+ * Python Merchant Product Generator
177
+ */
178
+ export class PythonMerchantProductGenerator extends ExampleGenerator {
179
+ constructor() {
180
+ super('python');
181
+ }
182
+
183
+ getOperationTemplate(operation, partnerType, params = {}) {
184
+ const opConfig = MerchantProductOperations[operation];
185
+ if (!opConfig) {
186
+ throw new Error(`Unknown operation: ${operation}`);
187
+ }
188
+
189
+ const { productId = 'pr_example_123', scheduleId = 'sch_example_456', audioId = 'aud_example_789', ...otherParams } = params;
190
+ let endpoint = opConfig.endpoint.replace('{id}', productId);
191
+ if (endpoint.includes('{scheduleId}')) {
192
+ endpoint = endpoint.replace('{scheduleId}', scheduleId);
193
+ }
194
+ if (endpoint.includes('{audioId}')) {
195
+ endpoint = endpoint.replace('{audioId}', audioId);
196
+ }
197
+ const functionName = `${operation}_example`;
198
+
199
+ return `def ${functionName}(product_id='${productId}'${scheduleId && operation.includes('schedule') ? `, schedule_id='${scheduleId}'` : ''}${audioId && operation.includes('audio') && !operation.includes('get_audios') && !operation.includes('register') ? `, audio_id='${audioId}'` : ''}, use_sandbox=True):
200
+ """${opConfig.description}"""
201
+
202
+ # Get API configuration
203
+ base_url = get_api_base_url(use_sandbox)
204
+ endpoint = '${endpoint}'
205
+ url = f"{base_url}{endpoint}"
206
+
207
+ ${this.getQueryParamsSection(operation, opConfig)}
208
+ ${this.getRequestBodySection(operation, opConfig)}
209
+
210
+ # Create JWT token
211
+ token, body_string = create_jwt_token(request_body, use_sandbox)
212
+ headers = get_api_headers(token)
213
+
214
+ try:
215
+ ${this.getRequestSection(opConfig.method)}
216
+
217
+ if response.status_code == 200:
218
+ result = response.json()
219
+ print(f"${opConfig.description} successful:")
220
+ print(json.dumps(result, indent=2))
221
+ return result
222
+ else:
223
+ error_msg = f"Request failed with status {response.status_code}: {response.text}"
224
+ print(error_msg)
225
+ return None
226
+
227
+ except requests.exceptions.RequestException as e:
228
+ print(f"Request error: {str(e)}")
229
+ return None
230
+ except Exception as e:
231
+ print(f"Unexpected error: {str(e)}")
232
+ return None
233
+
234
+ # Example usage
235
+ if __name__ == "__main__":
236
+ # ${opConfig.description}
237
+ result = ${functionName}()
238
+
239
+ if result:
240
+ print("Operation completed successfully")
241
+ ${this.getResultProcessingSection(operation)}
242
+ else:
243
+ print("Operation failed")`;
244
+ }
245
+
246
+ getQueryParamsSection(operation, opConfig) {
247
+ if (!opConfig.queryParams) {
248
+ return '';
249
+ }
250
+
251
+ const paramsStr = Object.entries(opConfig.queryParams)
252
+ .map(([key, value]) => ` '${key}': ${typeof value === 'string' ? `'${value}'` : value}`)
253
+ .join(',\n');
254
+
255
+ return `# Add query parameters
256
+ params = {
257
+ ${paramsStr}
258
+ }
259
+ if params:
260
+ url += '?' + '&'.join([f"{k}={v}" for k, v in params.items()])`;
261
+ }
262
+
263
+ getRequestBodySection(operation, opConfig) {
264
+ if (!opConfig.sampleBody) {
265
+ return '# No request body needed for this operation\n request_body = None';
266
+ }
267
+
268
+ const bodyStr = JSON.stringify(opConfig.sampleBody, null, 8).replace(/^/gm, ' ');
269
+ return `# Prepare request body
270
+ request_body = ${bodyStr}`;
271
+ }
272
+
273
+ getRequestSection(method) {
274
+ if (method === 'GET') {
275
+ return 'response = requests.get(url, headers=headers)';
276
+ } else if (method === 'DELETE') {
277
+ return 'response = requests.delete(url, headers=headers)';
278
+ } else {
279
+ return `response = requests.${method.toLowerCase()}(
280
+ url,
281
+ headers=headers,
282
+ data=body_string if request_body else None
283
+ )`;
284
+ }
285
+ }
286
+
287
+ getResultProcessingSection(operation) {
288
+ const processing = {
289
+ create_product: `# Store product ID for later use
290
+ product_id = result.get('productId')
291
+ print(f"Product created with ID: {product_id}")`,
292
+
293
+ get_product: `# Display product details
294
+ name = result.get('name')
295
+ price = result.get('prData', {}).get('regularPrice')
296
+ print(f"Product: {name}, Price: {price}")`,
297
+
298
+ list_products: `# Display products list
299
+ products = result.get('products', [])
300
+ print(f"Found {len(products)} products:")
301
+ for product in products[:5]: # Show first 5
302
+ print(f"- {product.get('name')}: {product.get('prData', {}).get('regularPrice')}")`,
303
+
304
+ create_schedule: `# Store schedule ID
305
+ schedule_id = result.get('scheduleId')
306
+ print(f"Schedule created with ID: {schedule_id}")`,
307
+
308
+ list_schedules: `# Display schedules
309
+ schedules = result.get('schedules', [])
310
+ print(f"Found {len(schedules)} schedules:")
311
+ for schedule in schedules:
312
+ print(f"- {schedule.get('name')}: {schedule.get('scheduleType')}")`
313
+ };
314
+
315
+ return processing[operation] || '# Process result as needed';
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Node.js Merchant Product Generator
321
+ */
322
+ export class NodeJSMerchantProductGenerator extends ExampleGenerator {
323
+ constructor() {
324
+ super('nodejs');
325
+ }
326
+
327
+ getOperationTemplate(operation, partnerType, params = {}) {
328
+ const opConfig = MerchantProductOperations[operation];
329
+ if (!opConfig) {
330
+ throw new Error(`Unknown operation: ${operation}`);
331
+ }
332
+
333
+ const { productId = 'pr_example_123', scheduleId = 'sch_example_456', audioId = 'aud_example_789', ...otherParams } = params;
334
+ let endpoint = opConfig.endpoint.replace('{id}', productId);
335
+ if (endpoint.includes('{scheduleId}')) {
336
+ endpoint = endpoint.replace('{scheduleId}', scheduleId);
337
+ }
338
+ if (endpoint.includes('{audioId}')) {
339
+ endpoint = endpoint.replace('{audioId}', audioId);
340
+ }
341
+ const functionName = `${operation}Example`;
342
+
343
+ return `async function ${functionName}(productId = '${productId}'${scheduleId && operation.includes('schedule') ? `, scheduleId = '${scheduleId}'` : ''}${audioId && operation.includes('audio') && !operation.includes('get_audios') && !operation.includes('register') ? `, audioId = '${audioId}'` : ''}, useSandbox = true) {
344
+ /**
345
+ * ${opConfig.description}
346
+ */
347
+
348
+ try {
349
+ // Get API configuration
350
+ const baseUrl = getAPIBaseURL(useSandbox);
351
+ let endpoint = '${endpoint}';
352
+ let url = \`\${baseUrl}\${endpoint}\`;
353
+
354
+ ${this.getQueryParamsSection(operation, opConfig)}
355
+ ${this.getRequestBodySection(operation, opConfig)}
356
+
357
+ // Create JWT token
358
+ const { token, bodyString } = createJWTToken(requestBody, useSandbox);
359
+ const headers = getAPIHeaders(token);
360
+
361
+ ${this.getRequestSection(opConfig.method)}
362
+
363
+ if (response.status === 200) {
364
+ const result = response.data;
365
+ console.log('${opConfig.description} successful:');
366
+ console.log(JSON.stringify(result, null, 2));
367
+
368
+ ${this.getResultProcessingSection(operation)}
369
+
370
+ return result;
371
+ } else {
372
+ console.error(\`Request failed with status \${response.status}: \${response.statusText}\`);
373
+ return null;
374
+ }
375
+
376
+ } catch (error) {
377
+ if (error.response) {
378
+ console.error(\`API Error: \${error.response.status} - \${error.response.data}\`);
379
+ } else if (error.request) {
380
+ console.error('Network Error:', error.message);
381
+ } else {
382
+ console.error('Request Error:', error.message);
383
+ }
384
+ return null;
385
+ }
386
+ }
387
+
388
+ // Example usage
389
+ async function main() {
390
+ console.log('Merchant Product Management Example');
391
+
392
+ const result = await ${functionName}();
393
+
394
+ if (result) {
395
+ console.log('Operation completed successfully');
396
+ } else {
397
+ console.log('Operation failed');
398
+ }
399
+ }
400
+
401
+ // Run example if this file is executed directly
402
+ if (require.main === module) {
403
+ main().catch(console.error);
404
+ }`;
405
+ }
406
+
407
+ getQueryParamsSection(operation, opConfig) {
408
+ if (!opConfig.queryParams) {
409
+ return '';
410
+ }
411
+
412
+ const paramsStr = JSON.stringify(opConfig.queryParams, null, 4).replace(/^/gm, ' ');
413
+ return `// Add query parameters
414
+ const queryParams = ${paramsStr};
415
+ const searchParams = new URLSearchParams(queryParams);
416
+ url += \`?\${searchParams.toString()}\`;`;
417
+ }
418
+
419
+ getRequestBodySection(operation, opConfig) {
420
+ if (!opConfig.sampleBody) {
421
+ return '// No request body needed for this operation\n const requestBody = null;';
422
+ }
423
+
424
+ const bodyStr = JSON.stringify(opConfig.sampleBody, null, 4).replace(/^/gm, ' ');
425
+ return `// Prepare request body
426
+ const requestBody = ${bodyStr};`;
427
+ }
428
+
429
+ getRequestSection(method) {
430
+ if (method === 'GET') {
431
+ return 'const response = await axios.get(url, { headers });';
432
+ } else if (method === 'DELETE') {
433
+ return 'const response = await axios.delete(url, { headers });';
434
+ } else {
435
+ return `const response = await axios.${method.toLowerCase()}(
436
+ url,
437
+ bodyString || undefined,
438
+ { headers }
439
+ );`;
440
+ }
441
+ }
442
+
443
+ getResultProcessingSection(operation) {
444
+ const processing = {
445
+ create_product: `// Store product ID for later use
446
+ const productId = result.productId;
447
+ console.log(\`Product created with ID: \${productId}\`);`,
448
+
449
+ get_product: `// Display product details
450
+ const name = result.name;
451
+ const price = result.prData?.regularPrice;
452
+ console.log(\`Product: \${name}, Price: \${price}\`);`,
453
+
454
+ list_products: `// Display products list
455
+ const products = result.products || [];
456
+ console.log(\`Found \${products.length} products:\`);
457
+ products.slice(0, 5).forEach(product => {
458
+ console.log(\`- \${product.name}: \${product.prData?.regularPrice}\`);
459
+ });`,
460
+
461
+ create_schedule: `// Store schedule ID
462
+ const scheduleId = result.scheduleId;
463
+ console.log(\`Schedule created with ID: \${scheduleId}\`);`,
464
+
465
+ list_schedules: `// Display schedules
466
+ const schedules = result.schedules || [];
467
+ console.log(\`Found \${schedules.length} schedules:\`);
468
+ schedules.forEach(schedule => {
469
+ console.log(\`- \${schedule.name}: \${schedule.scheduleType}\`);
470
+ });`
471
+ };
472
+
473
+ return processing[operation] || '// Process result as needed';
474
+ }
475
+ }
476
+
477
+ /**
478
+ * Export all generators
479
+ */
480
+ export const MerchantProductGenerators = {
481
+ python: PythonMerchantProductGenerator,
482
+ nodejs: NodeJSMerchantProductGenerator,
483
+ javascript: NodeJSMerchantProductGenerator
484
+ };
485
+
486
+ /**
487
+ * Generate merchant product example
488
+ */
489
+ export function generateMerchantProductExample(operation, language = 'python', options = {}) {
490
+ const GeneratorClass = MerchantProductGenerators[language];
491
+ if (!GeneratorClass) {
492
+ throw new Error(`Unsupported language: ${language}`);
493
+ }
494
+
495
+ const generator = new GeneratorClass();
496
+ return generator.generateExample(operation, 'merchant', options);
497
+ }