@payware/mcp-server 1.5.1 → 2.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 (30) hide show
  1. package/.env.example +1 -1
  2. package/README.md +1 -5
  3. package/package.json +1 -1
  4. package/src/config/toolsets.js +0 -2
  5. package/src/isv/index.js +0 -6
  6. package/src/isv/products/get-product.js +0 -1
  7. package/src/isv/transactions/create-transaction.js +1 -1
  8. package/src/merchant/index.js +0 -6
  9. package/src/merchant/products/get-product.js +0 -1
  10. package/src/payment-institution/index.js +1 -9
  11. package/src/shared/auth-headers.js +7 -6
  12. package/src/shared/placements/tools.js +4 -17
  13. package/src/tools/advanced-code-generator.js +2 -28
  14. package/src/utils/code-examples/common/helpers.js +1 -11
  15. package/src/utils/code-examples/index.js +1 -18
  16. package/src/isv/deep-links/delete-product-link.js +0 -155
  17. package/src/isv/deep-links/delete-transaction-link.js +0 -155
  18. package/src/isv/deep-links/get-product-link.js +0 -169
  19. package/src/isv/deep-links/get-transaction-link.js +0 -169
  20. package/src/isv/deep-links/index.js +0 -23
  21. package/src/merchant/deep-links/delete-product-link.js +0 -122
  22. package/src/merchant/deep-links/delete-transaction-link.js +0 -122
  23. package/src/merchant/deep-links/get-product-link.js +0 -136
  24. package/src/merchant/deep-links/get-transaction-link.js +0 -136
  25. package/src/merchant/deep-links/index.js +0 -23
  26. package/src/payment-institution/deep-links/delete-transaction-link.js +0 -129
  27. package/src/payment-institution/deep-links/get-transaction-link.js +0 -143
  28. package/src/payment-institution/deep-links/index.js +0 -17
  29. package/src/shared/deep-links/api.js +0 -215
  30. package/src/utils/code-examples/shared/deep-links.js +0 -662
@@ -1,662 +0,0 @@
1
- /**
2
- * Deep links examples (shared across all partner types)
3
- */
4
-
5
- import { ExampleGenerator, CommonTemplates } from '../common/helpers.js';
6
-
7
- /**
8
- * Deep link operations available to all partner types
9
- */
10
- export const DeepLinkOperations = {
11
- get_transaction_link: {
12
- description: 'Get deep link for transaction',
13
- endpoint: '/deeplinks/transactions/{id}',
14
- method: 'GET',
15
- sampleBody: null,
16
- queryParams: {
17
- type: 'QR_CODE',
18
- format: 'PNG',
19
- size: '256x256',
20
- theme: 'light'
21
- }
22
- },
23
-
24
- get_product_link: {
25
- description: 'Get deep link for product',
26
- endpoint: '/deeplinks/products/{id}',
27
- method: 'GET',
28
- sampleBody: null,
29
- queryParams: {
30
- type: 'URL',
31
- includeMetadata: true,
32
- expiry: '24h'
33
- }
34
- },
35
-
36
- create_custom_link: {
37
- description: 'Create custom deep link',
38
- endpoint: '/deeplinks/custom',
39
- method: 'POST',
40
- sampleBody: {
41
- targetType: 'TRANSACTION',
42
- targetId: 'tr_example_123',
43
- linkOptions: {
44
- type: 'QR_CODE',
45
- format: 'SVG',
46
- size: '512x512',
47
- theme: 'dark',
48
- logoUrl: 'https://example.com/logo.png'
49
- },
50
- metadata: {
51
- source: 'mobile_app',
52
- campaign: 'summer_sale_2024',
53
- customData: {
54
- userId: 'user_456',
55
- referralCode: 'REF123'
56
- }
57
- },
58
- expiry: {
59
- type: 'DURATION',
60
- value: '7d'
61
- }
62
- }
63
- },
64
-
65
- delete_transaction_link: {
66
- description: 'Delete transaction deep link',
67
- endpoint: '/deeplinks/transactions/{id}',
68
- method: 'DELETE',
69
- sampleBody: {
70
- reason: 'Transaction cancelled'
71
- }
72
- },
73
-
74
- delete_product_link: {
75
- description: 'Delete product deep link',
76
- endpoint: '/deeplinks/products/{id}',
77
- method: 'DELETE',
78
- sampleBody: {
79
- reason: 'Product discontinued'
80
- }
81
- },
82
-
83
- list_active_links: {
84
- description: 'List all active deep links',
85
- endpoint: '/deeplinks',
86
- method: 'GET',
87
- sampleBody: null,
88
- queryParams: {
89
- type: 'QR_CODE',
90
- status: 'ACTIVE',
91
- limit: 50,
92
- offset: 0
93
- }
94
- },
95
-
96
- get_link_analytics: {
97
- description: 'Get analytics for deep links',
98
- endpoint: '/deeplinks/analytics',
99
- method: 'GET',
100
- sampleBody: null,
101
- queryParams: {
102
- linkId: 'dl_example_123',
103
- startDate: '2024-01-01',
104
- endDate: '2024-12-31',
105
- metrics: 'scans,conversions,locations'
106
- }
107
- },
108
-
109
- create_batch_links: {
110
- description: 'Create multiple deep links in batch',
111
- endpoint: '/deeplinks/batch',
112
- method: 'POST',
113
- sampleBody: {
114
- links: [
115
- {
116
- targetType: 'TRANSACTION',
117
- targetId: 'tr_example_001',
118
- linkOptions: { type: 'QR_CODE', format: 'PNG' }
119
- },
120
- {
121
- targetType: 'PRODUCT',
122
- targetId: 'pr_example_001',
123
- linkOptions: { type: 'URL' }
124
- }
125
- ],
126
- batchOptions: {
127
- batchId: 'batch_001',
128
- description: 'Marketing campaign links',
129
- defaultExpiry: '30d'
130
- }
131
- }
132
- }
133
- };
134
-
135
- /**
136
- * Python Deep Links Generator
137
- */
138
- export class PythonDeepLinksGenerator extends ExampleGenerator {
139
- constructor() {
140
- super('python');
141
- }
142
-
143
- getOperationTemplate(operation, partnerType, params = {}) {
144
- const opConfig = DeepLinkOperations[operation];
145
- if (!opConfig) {
146
- throw new Error(`Unknown operation: ${operation}`);
147
- }
148
-
149
- const {
150
- transactionId = 'tr_example_123',
151
- productId = 'pr_example_456',
152
- linkId = 'dl_example_789',
153
- ...otherParams
154
- } = params;
155
-
156
- let endpoint = opConfig.endpoint;
157
- if (endpoint.includes('{id}')) {
158
- const id = operation.includes('product') ? productId :
159
- operation.includes('transaction') ? transactionId : linkId;
160
- endpoint = endpoint.replace('{id}', id);
161
- }
162
-
163
- const functionName = `${operation}_example`;
164
-
165
- return `def ${functionName}(${this.getFunctionParams(operation, transactionId, productId, linkId)}, use_sandbox=True):
166
- """${opConfig.description}"""
167
-
168
- try:
169
- # Get API configuration
170
- base_url = get_api_base_url(use_sandbox)
171
- endpoint = '${endpoint}'
172
- url = f"{base_url}{endpoint}"
173
-
174
- ${this.getQueryParamsSection(operation, opConfig)}
175
- ${this.getRequestBodySection(operation, opConfig)}
176
-
177
- # Create JWT token
178
- token, body_string = create_jwt_token(request_body, use_sandbox)
179
- headers = get_api_headers(token)
180
-
181
- ${this.getSpecialHandling(operation, opConfig)}
182
-
183
- ${this.getRequestSection(opConfig.method)}
184
-
185
- ${this.getResponseHandling(operation, opConfig)}
186
-
187
- except requests.exceptions.RequestException as e:
188
- print(f"Request error: {str(e)}")
189
- return None
190
- except Exception as e:
191
- print(f"Unexpected error: {str(e)}")
192
- return None
193
-
194
- # Deep link utility functions
195
- def save_qr_code(qr_data, filename='qr_code.png'):
196
- """Save QR code data to file"""
197
- import base64
198
-
199
- if isinstance(qr_data, str):
200
- # Base64 encoded data
201
- image_data = base64.b64decode(qr_data)
202
- with open(filename, 'wb') as f:
203
- f.write(image_data)
204
- print(f"QR code saved as: {filename}")
205
- return filename
206
- else:
207
- print("Invalid QR code data format")
208
- return None
209
-
210
- def display_link_info(link_result):
211
- """Display deep link information"""
212
- if not link_result:
213
- return
214
-
215
- print("Deep Link Information:")
216
- print(f"- Link ID: {link_result.get('linkId', 'N/A')}")
217
- print(f"- Type: {link_result.get('type', 'N/A')}")
218
- print(f"- URL: {link_result.get('url', 'N/A')}")
219
-
220
- if 'qrCode' in link_result:
221
- print(f"- QR Code: Available ({link_result.get('format', 'PNG')})")
222
-
223
- if 'expiry' in link_result:
224
- print(f"- Expires: {link_result.get('expiry', 'N/A')}")
225
-
226
- # Example usage
227
- if __name__ == "__main__":
228
- print("Deep Links Example")
229
-
230
- # ${opConfig.description}
231
- result = ${functionName}()
232
-
233
- if result:
234
- print("Deep link operation completed successfully")
235
- ${this.getUsageExample(operation)}
236
- else:
237
- print("Deep link operation failed")`;
238
- }
239
-
240
- getFunctionParams(operation, transactionId, productId, linkId) {
241
- const params = [];
242
-
243
- if (operation.includes('transaction')) {
244
- params.push(`transaction_id='${transactionId}'`);
245
- } else if (operation.includes('product')) {
246
- params.push(`product_id='${productId}'`);
247
- } else if (operation.includes('link') && !operation.includes('batch') && !operation.includes('list')) {
248
- params.push(`link_id='${linkId}'`);
249
- }
250
-
251
- return params.join(', ');
252
- }
253
-
254
- getQueryParamsSection(operation, opConfig) {
255
- if (!opConfig.queryParams) {
256
- return '';
257
- }
258
-
259
- const paramsStr = Object.entries(opConfig.queryParams)
260
- .map(([key, value]) => ` '${key}': ${typeof value === 'string' ? `'${value}'` : value}`)
261
- .join(',\n');
262
-
263
- return `# Add query parameters
264
- params = {
265
- ${paramsStr}
266
- }
267
- if params:
268
- url += '?' + '&'.join([f"{k}={v}" for k, v in params.items()])`;
269
- }
270
-
271
- getRequestBodySection(operation, opConfig) {
272
- if (!opConfig.sampleBody) {
273
- return '# No request body needed for this operation\n request_body = None';
274
- }
275
-
276
- const bodyStr = JSON.stringify(opConfig.sampleBody, null, 8).replace(/^/gm, ' ');
277
- return `# Prepare request body
278
- request_body = ${bodyStr}`;
279
- }
280
-
281
- getSpecialHandling(operation, opConfig) {
282
- if (operation.includes('get_') && opConfig.queryParams?.type === 'QR_CODE') {
283
- return `# Handle QR code response
284
- if params.get('type') == 'QR_CODE':
285
- headers['Accept'] = 'application/json' # QR code will be base64 encoded`;
286
- }
287
- return '';
288
- }
289
-
290
- getRequestSection(method) {
291
- if (method === 'GET') {
292
- return 'response = requests.get(url, headers=headers)';
293
- } else if (method === 'DELETE') {
294
- return 'response = requests.delete(url, headers=headers, data=body_string if request_body else None)';
295
- } else {
296
- return `response = requests.${method.toLowerCase()}(
297
- url,
298
- headers=headers,
299
- data=body_string if request_body else None
300
- )`;
301
- }
302
- }
303
-
304
- getResponseHandling(operation, opConfig) {
305
- if (operation.includes('get_') && opConfig.queryParams?.type === 'QR_CODE') {
306
- return `if response.status_code == 200:
307
- result = response.json()
308
- print(f"${opConfig.description} successful:")
309
-
310
- # Handle QR code data
311
- if 'qrCode' in result:
312
- qr_filename = f"{operation}_{transaction_id if 'transaction' in operation else product_id}.png"
313
- saved_file = save_qr_code(result['qrCode'], qr_filename)
314
- result['qrCodeFile'] = saved_file
315
-
316
- display_link_info(result)
317
- return result
318
- else:
319
- error_msg = f"Request failed with status {response.status_code}: {response.text}"
320
- print(error_msg)
321
- return None`;
322
- } else {
323
- return `if response.status_code == 200:
324
- result = response.json()
325
- print(f"${opConfig.description} successful:")
326
- print(json.dumps(result, indent=2))
327
- return result
328
- else:
329
- error_msg = f"Request failed with status {response.status_code}: {response.text}"
330
- print(error_msg)
331
- return None`;
332
- }
333
- }
334
-
335
- getUsageExample(operation) {
336
- const examples = {
337
- get_transaction_link: `# Display link information and save QR code
338
- display_link_info(result)
339
- if 'qrCodeFile' in result:
340
- print(f"QR code saved: {result['qrCodeFile']}")`,
341
-
342
- create_custom_link: `# Store custom link details
343
- if 'linkId' in result:
344
- link_id = result['linkId']
345
- print(f"Custom link created: {link_id}")
346
- print(f"Share URL: {result.get('url', 'N/A')}")`,
347
-
348
- create_batch_links: `# Process batch results
349
- batch_id = result.get('batchId')
350
- created_links = result.get('createdLinks', [])
351
- failed_links = result.get('failedLinks', [])
352
-
353
- print(f"Batch {batch_id}: {len(created_links)} created, {len(failed_links)} failed")
354
- for link in created_links[:3]: # Show first 3
355
- print(f"- {link.get('targetId')}: {link.get('url')}")`,
356
-
357
- get_link_analytics: `# Display analytics data
358
- analytics = result.get('analytics', {})
359
-
360
- print("Link Analytics:")
361
- for metric, value in analytics.items():
362
- if isinstance(value, dict):
363
- print(f"- {metric}:")
364
- for sub_metric, sub_value in value.items():
365
- print(f" - {sub_metric}: {sub_value}")
366
- else:
367
- print(f"- {metric}: {value}")`
368
- };
369
-
370
- return examples[operation] || '# Process deep link result as needed';
371
- }
372
- }
373
-
374
- /**
375
- * Node.js Deep Links Generator
376
- */
377
- export class NodeJSDeepLinksGenerator extends ExampleGenerator {
378
- constructor() {
379
- super('nodejs');
380
- }
381
-
382
- getOperationTemplate(operation, partnerType, params = {}) {
383
- const opConfig = DeepLinkOperations[operation];
384
- if (!opConfig) {
385
- throw new Error(`Unknown operation: ${operation}`);
386
- }
387
-
388
- const {
389
- transactionId = 'tr_example_123',
390
- productId = 'pr_example_456',
391
- linkId = 'dl_example_789',
392
- ...otherParams
393
- } = params;
394
-
395
- let endpoint = opConfig.endpoint;
396
- if (endpoint.includes('{id}')) {
397
- const id = operation.includes('product') ? productId :
398
- operation.includes('transaction') ? transactionId : linkId;
399
- endpoint = endpoint.replace('{id}', id);
400
- }
401
-
402
- const functionName = `${operation}Example`;
403
-
404
- return `async function ${functionName}(${this.getFunctionParams(operation, transactionId, productId, linkId)}, useSandbox = true) {
405
- /**
406
- * ${opConfig.description}
407
- */
408
-
409
- try {
410
- // Get API configuration
411
- const baseUrl = getAPIBaseURL(useSandbox);
412
- const endpoint = '${endpoint}';
413
- let url = \`\${baseUrl}\${endpoint}\`;
414
-
415
- ${this.getQueryParamsSection(operation, opConfig)}
416
- ${this.getRequestBodySection(operation, opConfig)}
417
-
418
- // Create JWT token
419
- const { token, bodyString } = createJWTToken(requestBody, useSandbox);
420
- const headers = getAPIHeaders(token);
421
-
422
- ${this.getSpecialHandling(operation, opConfig)}
423
-
424
- ${this.getRequestSection(opConfig.method)}
425
-
426
- ${this.getResponseHandling(operation, opConfig)}
427
-
428
- } catch (error) {
429
- if (error.response) {
430
- console.error(\`API Error: \${error.response.status} - \${error.response.data}\`);
431
- } else {
432
- console.error('Request Error:', error.message);
433
- }
434
- return null;
435
- }
436
- }
437
-
438
- // Deep link utility functions
439
- function saveQRCode(qrData, filename = 'qr_code.png') {
440
- /**
441
- * Save QR code data to file
442
- */
443
- const fs = require('fs');
444
-
445
- if (typeof qrData === 'string') {
446
- // Base64 encoded data
447
- const imageData = Buffer.from(qrData, 'base64');
448
- fs.writeFileSync(filename, imageData);
449
- console.log(\`QR code saved as: \${filename}\`);
450
- return filename;
451
- } else {
452
- console.log('Invalid QR code data format');
453
- return null;
454
- }
455
- }
456
-
457
- function displayLinkInfo(linkResult) {
458
- /**
459
- * Display deep link information
460
- */
461
- if (!linkResult) return;
462
-
463
- console.log('Deep Link Information:');
464
- console.log(\`- Link ID: \${linkResult.linkId || 'N/A'}\`);
465
- console.log(\`- Type: \${linkResult.type || 'N/A'}\`);
466
- console.log(\`- URL: \${linkResult.url || 'N/A'}\`);
467
-
468
- if (linkResult.qrCode) {
469
- console.log(\`- QR Code: Available (\${linkResult.format || 'PNG'})\`);
470
- }
471
-
472
- if (linkResult.expiry) {
473
- console.log(\`- Expires: \${linkResult.expiry}\`);
474
- }
475
- }
476
-
477
- // Example usage
478
- async function main() {
479
- console.log('Deep Links Example');
480
-
481
- try {
482
- const result = await ${functionName}();
483
-
484
- if (result) {
485
- console.log('Deep link operation completed successfully');
486
- ${this.getUsageExample(operation)}
487
- } else {
488
- console.log('Deep link operation failed');
489
- }
490
-
491
- } catch (error) {
492
- console.error('Deep link operation error:', error.message);
493
- }
494
- }
495
-
496
- // Run example if this file is executed directly
497
- if (require.main === module) {
498
- main().catch(console.error);
499
- }`;
500
- }
501
-
502
- getFunctionParams(operation, transactionId, productId, linkId) {
503
- const params = [];
504
-
505
- if (operation.includes('transaction')) {
506
- params.push(`transactionId = '${transactionId}'`);
507
- } else if (operation.includes('product')) {
508
- params.push(`productId = '${productId}'`);
509
- } else if (operation.includes('link') && !operation.includes('batch') && !operation.includes('list')) {
510
- params.push(`linkId = '${linkId}'`);
511
- }
512
-
513
- return params.join(', ');
514
- }
515
-
516
- getQueryParamsSection(operation, opConfig) {
517
- if (!opConfig.queryParams) {
518
- return '';
519
- }
520
-
521
- const paramsStr = JSON.stringify(opConfig.queryParams, null, 4).replace(/^/gm, ' ');
522
- return `// Add query parameters
523
- const queryParams = ${paramsStr};
524
- const searchParams = new URLSearchParams(queryParams);
525
- url += \`?\${searchParams.toString()}\`;`;
526
- }
527
-
528
- getRequestBodySection(operation, opConfig) {
529
- if (!opConfig.sampleBody) {
530
- return '// No request body needed for this operation\n const requestBody = null;';
531
- }
532
-
533
- const bodyStr = JSON.stringify(opConfig.sampleBody, null, 4).replace(/^/gm, ' ');
534
- return `// Prepare request body
535
- const requestBody = ${bodyStr};`;
536
- }
537
-
538
- getSpecialHandling(operation, opConfig) {
539
- if (operation.includes('get_') && opConfig.queryParams?.type === 'QR_CODE') {
540
- return `// Handle QR code response
541
- if (queryParams.type === 'QR_CODE') {
542
- headers['Accept'] = 'application/json'; // QR code will be base64 encoded
543
- }`;
544
- }
545
- return '';
546
- }
547
-
548
- getRequestSection(method) {
549
- if (method === 'GET') {
550
- return 'const response = await axios.get(url, { headers });';
551
- } else if (method === 'DELETE') {
552
- return `const response = await axios.delete(url, {
553
- headers,
554
- data: bodyString || undefined
555
- });`;
556
- } else {
557
- return `const response = await axios.${method.toLowerCase()}(
558
- url,
559
- bodyString || undefined,
560
- { headers }
561
- );`;
562
- }
563
- }
564
-
565
- getResponseHandling(operation, opConfig) {
566
- if (operation.includes('get_') && opConfig.queryParams?.type === 'QR_CODE') {
567
- return `if (response.status === 200) {
568
- const result = response.data;
569
- console.log('${opConfig.description} successful:');
570
-
571
- // Handle QR code data
572
- if (result.qrCode) {
573
- const qrFilename = \`\${operation}_\${${operation.includes('transaction') ? 'transactionId' : 'productId'}}.png\`;
574
- const savedFile = saveQRCode(result.qrCode, qrFilename);
575
- result.qrCodeFile = savedFile;
576
- }
577
-
578
- displayLinkInfo(result);
579
- return result;
580
- } else {
581
- console.error(\`Request failed with status \${response.status}: \${response.statusText}\`);
582
- return null;
583
- }`;
584
- } else {
585
- return `if (response.status === 200) {
586
- const result = response.data;
587
- console.log('${opConfig.description} successful:');
588
- console.log(JSON.stringify(result, null, 2));
589
- return result;
590
- } else {
591
- console.error(\`Request failed with status \${response.status}: \${response.statusText}\`);
592
- return null;
593
- }`;
594
- }
595
- }
596
-
597
- getUsageExample(operation) {
598
- const examples = {
599
- get_transaction_link: `// Display link information and save QR code
600
- displayLinkInfo(result);
601
- if (result.qrCodeFile) {
602
- console.log(\`QR code saved: \${result.qrCodeFile}\`);
603
- }`,
604
-
605
- create_custom_link: `// Store custom link details
606
- if (result.linkId) {
607
- const linkId = result.linkId;
608
- console.log(\`Custom link created: \${linkId}\`);
609
- console.log(\`Share URL: \${result.url || 'N/A'}\`);
610
- }`,
611
-
612
- create_batch_links: `// Process batch results
613
- const batchId = result.batchId;
614
- const createdLinks = result.createdLinks || [];
615
- const failedLinks = result.failedLinks || [];
616
-
617
- console.log(\`Batch \${batchId}: \${createdLinks.length} created, \${failedLinks.length} failed\`);
618
- createdLinks.slice(0, 3).forEach(link => {
619
- console.log(\`- \${link.targetId}: \${link.url}\`);
620
- });`,
621
-
622
- get_link_analytics: `// Display analytics data
623
- const analytics = result.analytics || {};
624
-
625
- console.log('Link Analytics:');
626
- Object.entries(analytics).forEach(([metric, value]) => {
627
- if (typeof value === 'object' && value !== null) {
628
- console.log(\`- \${metric}:\`);
629
- Object.entries(value).forEach(([subMetric, subValue]) => {
630
- console.log(\` - \${subMetric}: \${subValue}\`);
631
- });
632
- } else {
633
- console.log(\`- \${metric}: \${value}\`);
634
- }
635
- });`
636
- };
637
-
638
- return examples[operation] || '// Process deep link result as needed';
639
- }
640
- }
641
-
642
- /**
643
- * Export all generators
644
- */
645
- export const DeepLinksGenerators = {
646
- python: PythonDeepLinksGenerator,
647
- nodejs: NodeJSDeepLinksGenerator,
648
- javascript: NodeJSDeepLinksGenerator
649
- };
650
-
651
- /**
652
- * Generate deep links example
653
- */
654
- export function generateDeepLinksExample(operation, language = 'python', partnerType = 'merchant', options = {}) {
655
- const GeneratorClass = DeepLinksGenerators[language];
656
- if (!GeneratorClass) {
657
- throw new Error(`Unsupported language: ${language}`);
658
- }
659
-
660
- const generator = new GeneratorClass();
661
- return generator.generateExample(operation, partnerType, options);
662
- }