@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,623 @@
1
+ /**
2
+ * Merchant transaction examples for all operations
3
+ */
4
+
5
+ import { PythonGenerator, NodeJSGenerator } from '../common/utils-examples.js';
6
+ import { CommonTemplates } from '../common/helpers.js';
7
+
8
+ /**
9
+ * Merchant transaction operations
10
+ */
11
+ export const MerchantTransactionOperations = {
12
+ create_transaction: {
13
+ description: 'Create a new payment transaction',
14
+ endpoint: '/transactions',
15
+ method: 'POST',
16
+ sampleBody: {
17
+ trData: {
18
+ amount: '25.50',
19
+ currency: 'EUR',
20
+ reasonL1: 'Product purchase',
21
+ reasonL2: 'Online store order #12345'
22
+ },
23
+ trOptions: {
24
+ type: 'QR',
25
+ timeToLive: 300
26
+ }
27
+ }
28
+ },
29
+
30
+ get_transaction_status: {
31
+ description: 'Get the current status of a transaction',
32
+ endpoint: '/transactions/{id}',
33
+ method: 'GET',
34
+ sampleBody: {}
35
+ },
36
+
37
+ cancel_transaction: {
38
+ description: 'Cancel an active transaction',
39
+ endpoint: '/transactions/{id}',
40
+ method: 'PATCH',
41
+ sampleBody: {
42
+ status: 'CANCELLED',
43
+ statusMessage: 'Customer requested cancellation'
44
+ }
45
+ },
46
+
47
+ process_transaction: {
48
+ description: 'Process a transaction as merchant',
49
+ endpoint: '/transactions/{id}',
50
+ method: 'POST',
51
+ sampleBody: {
52
+ account: 'MERCHANT_ACCOUNT_123',
53
+ friendlyName: 'My Store'
54
+ }
55
+ },
56
+
57
+ get_transaction_history: {
58
+ description: 'Get transaction history',
59
+ endpoint: '/transactions/{id}/history',
60
+ method: 'GET',
61
+ sampleBody: {}
62
+ },
63
+
64
+ simulate_callback: {
65
+ description: 'Simulate a transaction callback for testing',
66
+ endpoint: '/transactions/{id}/callback',
67
+ method: 'POST',
68
+ sampleBody: {
69
+ status: 'PROCESSED',
70
+ timestamp: new Date().toISOString()
71
+ }
72
+ }
73
+ };
74
+
75
+ /**
76
+ * Generate Python examples for merchant transactions
77
+ */
78
+ export function generateMerchantTransactionPython(operation, params = {}) {
79
+ const generator = new PythonGenerator(params.framework);
80
+ const operationConfig = MerchantTransactionOperations[operation];
81
+
82
+ if (!operationConfig) {
83
+ throw new Error(`Unknown operation: ${operation}`);
84
+ }
85
+
86
+ // Customize request body with parameters
87
+ const customBody = { ...operationConfig.sampleBody };
88
+ if (params.amount) customBody.trData = { ...customBody.trData, amount: params.amount };
89
+ if (params.currency) customBody.trData = { ...customBody.trData, currency: params.currency };
90
+ if (params.reasonL1) customBody.trData = { ...customBody.trData, reasonL1: params.reasonL1 };
91
+
92
+ const sections = [];
93
+
94
+ // Header and description
95
+ sections.push(`"""
96
+ ${operationConfig.description}
97
+
98
+ This example demonstrates how to ${operationConfig.description.toLowerCase()} using the payware API.
99
+ Partner Type: Merchant
100
+ Operation: ${operation}
101
+ Method: ${operationConfig.method}
102
+ Endpoint: ${operationConfig.endpoint}
103
+ """
104
+
105
+ # Required dependencies:
106
+ # pip install requests pyjwt cryptography python-dotenv
107
+
108
+ import requests
109
+ import jwt
110
+ import json
111
+ import hashlib
112
+ import base64
113
+ import os
114
+ from datetime import datetime
115
+ from dotenv import load_dotenv
116
+
117
+ # Load environment variables
118
+ load_dotenv()`);
119
+
120
+ // Environment setup
121
+ sections.push(`# Environment Configuration
122
+ def load_merchant_config():
123
+ """Load merchant configuration from environment"""
124
+ config = {
125
+ 'partner_id': os.getenv('PAYWARE_PARTNER_ID'),
126
+ 'sandbox_key_path': os.getenv('PAYWARE_SANDBOX_PRIVATE_KEY_PATH'),
127
+ 'production_key_path': os.getenv('PAYWARE_PRODUCTION_PRIVATE_KEY_PATH'),
128
+ 'sandbox_url': os.getenv('PAYWARE_SANDBOX_URL', 'https://sandbox.payware.eu/api'),
129
+ 'production_url': os.getenv('PAYWARE_PRODUCTION_URL', 'https://api.payware.eu/api')
130
+ }
131
+
132
+ # Validate required configuration
133
+ if not config['partner_id']:
134
+ raise ValueError("PAYWARE_PARTNER_ID environment variable is required")
135
+
136
+ return config`);
137
+
138
+ // Authentication functions
139
+ sections.push(`# Authentication Functions
140
+ def create_jwt_token(request_body=None, use_sandbox=True):
141
+ """Create JWT token for payware API authentication"""
142
+ config = load_merchant_config()
143
+
144
+ # Get private key path based on environment
145
+ private_key_path = config['sandbox_key_path'] if use_sandbox else config['production_key_path']
146
+ if not private_key_path:
147
+ env_var = 'PAYWARE_SANDBOX_PRIVATE_KEY_PATH' if use_sandbox else 'PAYWARE_PRODUCTION_PRIVATE_KEY_PATH'
148
+ raise ValueError(f"{env_var} environment variable is required")
149
+
150
+ # Load private key
151
+ with open(private_key_path, 'r') as f:
152
+ private_key = f.read()
153
+
154
+ # Create JWT header
155
+ header = {
156
+ 'alg': 'RS256',
157
+ 'typ': 'JWT'
158
+ }
159
+
160
+ # Add content MD5 for requests with body
161
+ body_string = None
162
+ if request_body:
163
+ body_string = create_minimized_json(request_body)
164
+ content_md5 = base64.b64encode(
165
+ hashlib.md5(body_string.encode('utf-8')).digest()
166
+ ).decode('utf-8')
167
+ header['contentMd5'] = content_md5
168
+
169
+ # Create JWT payload
170
+ payload = {
171
+ 'iss': config['partner_id'],
172
+ 'aud': 'https://payware.eu',
173
+ 'iat': int(datetime.utcnow().timestamp())
174
+ }
175
+
176
+ # Create token
177
+ token = jwt.encode(payload, private_key, algorithm='RS256', headers=header)
178
+ return token, body_string
179
+
180
+ def create_minimized_json(data):
181
+ """Create deterministic minimized JSON for MD5 calculation"""
182
+ def sort_dict(obj):
183
+ if isinstance(obj, dict):
184
+ return {k: sort_dict(v) for k, v in sorted(obj.items())}
185
+ elif isinstance(obj, list):
186
+ return [sort_dict(item) for item in obj]
187
+ else:
188
+ return obj
189
+
190
+ sorted_data = sort_dict(data)
191
+ return json.dumps(sorted_data, separators=(',', ':'))
192
+
193
+ def get_api_headers(token):
194
+ """Get standard API headers"""
195
+ return {
196
+ 'Authorization': f'Bearer {token}',
197
+ 'Content-Type': 'application/json',
198
+ 'Api-Version': '1'
199
+ }`);
200
+
201
+ // Main operation function
202
+ const needsId = operationConfig.endpoint.includes('{id}');
203
+ const hasBody = operationConfig.method !== 'GET' && Object.keys(operationConfig.sampleBody).length > 0;
204
+
205
+ const paramList = ['use_sandbox=True'];
206
+ if (needsId) {
207
+ paramList.unshift('transaction_id');
208
+ }
209
+
210
+ // Add custom parameters for specific operations
211
+ if (operation === 'create_transaction') {
212
+ paramList.splice(-1, 0, 'amount="25.50"', 'currency="EUR"', 'reason_l1="Product purchase"', 'reason_l2=None');
213
+ }
214
+
215
+ const functionName = operation;
216
+ const endpoint = operationConfig.endpoint.replace('{id}', '{transaction_id}');
217
+
218
+ sections.push(`# Main Operation
219
+ def ${functionName}(${paramList.join(', ')}):
220
+ """${operationConfig.description}"""
221
+
222
+ try:
223
+ config = load_merchant_config()
224
+ base_url = config['sandbox_url'] if use_sandbox else config['production_url']
225
+
226
+ ${hasBody ? `# Prepare request body
227
+ request_body = ${JSON.stringify(customBody, null, 8).replace(/"/g, "'")}
228
+
229
+ ${operation === 'create_transaction' ? `# Customize with parameters
230
+ if amount:
231
+ request_body['trData']['amount'] = amount
232
+ if currency:
233
+ request_body['trData']['currency'] = currency
234
+ if reason_l1:
235
+ request_body['trData']['reasonL1'] = reason_l1
236
+ if reason_l2:
237
+ request_body['trData']['reasonL2'] = reason_l2` : ''}
238
+
239
+ # Create JWT token with body hash
240
+ token, body_string = create_jwt_token(request_body, use_sandbox)
241
+ headers = get_api_headers(token)
242
+
243
+ # Make API request
244
+ url = f"{base_url}${endpoint}"${needsId ? `.format(transaction_id=transaction_id)` : ''}
245
+ response = requests.${operationConfig.method.toLowerCase()}(
246
+ url,
247
+ data=body_string,
248
+ headers=headers
249
+ )` : `# Create JWT token for GET request
250
+ token, _ = create_jwt_token(None, use_sandbox)
251
+ headers = get_api_headers(token)
252
+
253
+ # Make API request
254
+ url = f"{base_url}${endpoint}"${needsId ? `.format(transaction_id=transaction_id)` : ''}
255
+ response = requests.${operationConfig.method.toLowerCase()}(
256
+ url,
257
+ headers=headers
258
+ )`}
259
+
260
+ # Handle response
261
+ if response.status_code in [200, 201]:
262
+ result = response.json()
263
+ return {
264
+ 'success': True,
265
+ 'data': result,
266
+ 'request_id': response.headers.get('x-request-id'),
267
+ 'timestamp': datetime.utcnow().isoformat()
268
+ }
269
+ else:
270
+ return {
271
+ 'success': False,
272
+ 'error': {
273
+ 'status': response.status_code,
274
+ 'message': response.text,
275
+ 'details': response.json() if response.headers.get('content-type', '').startswith('application/json') else None
276
+ },
277
+ 'timestamp': datetime.utcnow().isoformat()
278
+ }
279
+
280
+ except Exception as e:
281
+ return {
282
+ 'success': False,
283
+ 'error': {
284
+ 'message': str(e),
285
+ 'type': type(e).__name__
286
+ },
287
+ 'timestamp': datetime.utcnow().isoformat()
288
+ }`);
289
+
290
+ // Error handling
291
+ sections.push(`# Error Handling
292
+ def handle_payware_error(error_response):
293
+ """Handle common payware API errors"""
294
+ status = error_response.get('status', 0)
295
+ message = error_response.get('message', 'Unknown error')
296
+
297
+ error_messages = {
298
+ 400: f"Bad Request: {message}",
299
+ 401: "Authentication failed - check your partner ID and private key",
300
+ 403: "Forbidden - insufficient permissions",
301
+ 404: "Resource not found",
302
+ 409: "Conflict - resource already exists or invalid state",
303
+ 429: "Rate limit exceeded - please retry later",
304
+ 500: "Internal server error - please try again",
305
+ 502: "Bad gateway - service temporarily unavailable",
306
+ 503: "Service unavailable - please retry later"
307
+ }
308
+
309
+ return error_messages.get(status, f"API Error {status}: {message}")`);
310
+
311
+ // Example usage
312
+ const exampleParams = needsId ? "'pw12345678'" : '';
313
+ sections.push(`# Example Usage
314
+ if __name__ == "__main__":
315
+ print("=== Merchant ${operation.replace('_', ' ').title()} Example ===\\n")
316
+
317
+ try:
318
+ # Execute the operation
319
+ result = ${functionName}(${exampleParams})
320
+
321
+ if result['success']:
322
+ print("✅ Operation successful!")
323
+ print(f"Request ID: {result.get('request_id', 'N/A')}")
324
+ print("Response Data:")
325
+ print(json.dumps(result['data'], indent=2))
326
+ else:
327
+ print("❌ Operation failed!")
328
+ error_message = handle_payware_error(result['error'])
329
+ print(f"Error: {error_message}")
330
+
331
+ if result['error'].get('details'):
332
+ print("Error Details:")
333
+ print(json.dumps(result['error']['details'], indent=2))
334
+
335
+ except Exception as e:
336
+ print(f"❌ Unexpected error: {e}")
337
+
338
+ print(f"\\nTimestamp: {datetime.utcnow().isoformat()}")
339
+ print("\\n" + "="*50)`);
340
+
341
+ return sections.join('\n\n');
342
+ }
343
+
344
+ /**
345
+ * Generate Node.js examples for merchant transactions
346
+ */
347
+ export function generateMerchantTransactionNodeJS(operation, params = {}) {
348
+ const generator = new NodeJSGenerator(params.framework);
349
+ const operationConfig = MerchantTransactionOperations[operation];
350
+
351
+ if (!operationConfig) {
352
+ throw new Error(`Unknown operation: ${operation}`);
353
+ }
354
+
355
+ const sections = [];
356
+
357
+ // Header and description
358
+ sections.push(`/**
359
+ * ${operationConfig.description}
360
+ *
361
+ * This example demonstrates how to ${operationConfig.description.toLowerCase()} using the payware API.
362
+ * Partner Type: Merchant
363
+ * Operation: ${operation}
364
+ * Method: ${operationConfig.method}
365
+ * Endpoint: ${operationConfig.endpoint}
366
+ */
367
+
368
+ // Required dependencies:
369
+ // npm install axios jsonwebtoken crypto fs dotenv
370
+
371
+ const axios = require('axios');
372
+ const jwt = require('jsonwebtoken');
373
+ const crypto = require('crypto');
374
+ const fs = require('fs');
375
+ require('dotenv').config();`);
376
+
377
+ // Configuration
378
+ sections.push(`// Configuration
379
+ function loadMerchantConfig() {
380
+ const config = {
381
+ partnerId: process.env.PAYWARE_PARTNER_ID,
382
+ sandboxKeyPath: process.env.PAYWARE_SANDBOX_PRIVATE_KEY_PATH,
383
+ productionKeyPath: process.env.PAYWARE_PRODUCTION_PRIVATE_KEY_PATH,
384
+ sandboxUrl: process.env.PAYWARE_SANDBOX_URL || 'https://sandbox.payware.eu/api',
385
+ productionUrl: process.env.PAYWARE_PRODUCTION_URL || 'https://api.payware.eu/api'
386
+ };
387
+
388
+ // Validate required configuration
389
+ if (!config.partnerId) {
390
+ throw new Error('PAYWARE_PARTNER_ID environment variable is required');
391
+ }
392
+
393
+ return config;
394
+ }`);
395
+
396
+ // Authentication functions
397
+ sections.push(`// Authentication Functions
398
+ function createJWTToken(requestBody = null, useSandbox = true) {
399
+ const config = loadMerchantConfig();
400
+
401
+ // Get private key path based on environment
402
+ const privateKeyPath = useSandbox ? config.sandboxKeyPath : config.productionKeyPath;
403
+ if (!privateKeyPath) {
404
+ const envVar = useSandbox ? 'PAYWARE_SANDBOX_PRIVATE_KEY_PATH' : 'PAYWARE_PRODUCTION_PRIVATE_KEY_PATH';
405
+ throw new Error(\`\${envVar} environment variable is required\`);
406
+ }
407
+
408
+ // Load private key
409
+ const privateKey = fs.readFileSync(privateKeyPath, 'utf8');
410
+
411
+ // Create JWT header
412
+ const header = {
413
+ alg: 'RS256',
414
+ typ: 'JWT'
415
+ };
416
+
417
+ // Add content MD5 for requests with body
418
+ let bodyString = null;
419
+ if (requestBody) {
420
+ bodyString = createMinimizedJSON(requestBody);
421
+ const contentMd5 = crypto
422
+ .createHash('md5')
423
+ .update(bodyString, 'utf8')
424
+ .digest('base64');
425
+ header.contentMd5 = contentMd5;
426
+ }
427
+
428
+ // Create JWT payload
429
+ const payload = {
430
+ iss: config.partnerId,
431
+ aud: 'https://payware.eu',
432
+ iat: Math.floor(Date.now() / 1000)
433
+ };
434
+
435
+ // Create token
436
+ const token = jwt.sign(payload, privateKey, {
437
+ algorithm: 'RS256',
438
+ header
439
+ });
440
+
441
+ return { token, bodyString };
442
+ }
443
+
444
+ function createMinimizedJSON(data) {
445
+ // Sort object keys recursively for deterministic output
446
+ function sortObject(obj) {
447
+ if (Array.isArray(obj)) {
448
+ return obj.map(item => sortObject(item));
449
+ } else if (obj !== null && typeof obj === 'object') {
450
+ const sorted = {};
451
+ Object.keys(obj).sort().forEach(key => {
452
+ sorted[key] = sortObject(obj[key]);
453
+ });
454
+ return sorted;
455
+ }
456
+ return obj;
457
+ }
458
+
459
+ const sortedData = sortObject(data);
460
+ return JSON.stringify(sortedData);
461
+ }
462
+
463
+ function getAPIHeaders(token) {
464
+ return {
465
+ 'Authorization': \`Bearer \${token}\`,
466
+ 'Content-Type': 'application/json',
467
+ 'Api-Version': '1'
468
+ };
469
+ }`);
470
+
471
+ // Main operation function
472
+ const needsId = operationConfig.endpoint.includes('{id}');
473
+ const hasBody = operationConfig.method !== 'GET' && Object.keys(operationConfig.sampleBody).length > 0;
474
+
475
+ const paramList = ['useSandbox = true'];
476
+ if (needsId) {
477
+ paramList.unshift('transactionId');
478
+ }
479
+
480
+ // Add custom parameters for specific operations
481
+ if (operation === 'create_transaction') {
482
+ paramList.splice(-1, 0, 'amount = "25.50"', 'currency = "EUR"', 'reasonL1 = "Product purchase"', 'reasonL2 = null');
483
+ }
484
+
485
+ const endpoint = operationConfig.endpoint.replace('{id}', '${transactionId}');
486
+
487
+ sections.push(`// Main Operation
488
+ async function ${operation}(${paramList.join(', ')}) {
489
+ /**
490
+ * ${operationConfig.description}
491
+ */
492
+
493
+ try {
494
+ const config = loadMerchantConfig();
495
+ const baseUrl = useSandbox ? config.sandboxUrl : config.productionUrl;
496
+
497
+ ${hasBody ? `// Prepare request body
498
+ const requestBody = ${JSON.stringify(operationConfig.sampleBody, null, 4)};
499
+
500
+ ${operation === 'create_transaction' ? `// Customize with parameters
501
+ if (amount) requestBody.trData.amount = amount;
502
+ if (currency) requestBody.trData.currency = currency;
503
+ if (reasonL1) requestBody.trData.reasonL1 = reasonL1;
504
+ if (reasonL2) requestBody.trData.reasonL2 = reasonL2;` : ''}
505
+
506
+ // Create JWT token with body hash
507
+ const { token, bodyString } = createJWTToken(requestBody, useSandbox);
508
+ const headers = getAPIHeaders(token);
509
+
510
+ // Make API request
511
+ const url = \`\${baseUrl}${endpoint}\`;
512
+ const response = await axios.${operationConfig.method.toLowerCase()}(
513
+ url,
514
+ bodyString,
515
+ {
516
+ headers,
517
+ transformRequest: [(data) => data]
518
+ }
519
+ );` : `// Create JWT token for GET request
520
+ const { token } = createJWTToken(null, useSandbox);
521
+ const headers = getAPIHeaders(token);
522
+
523
+ // Make API request
524
+ const url = \`\${baseUrl}${endpoint}\`;
525
+ const response = await axios.${operationConfig.method.toLowerCase()}(
526
+ url,
527
+ { headers }
528
+ );`}
529
+
530
+ // Handle successful response
531
+ return {
532
+ success: true,
533
+ data: response.data,
534
+ requestId: response.headers['x-request-id'],
535
+ timestamp: new Date().toISOString()
536
+ };
537
+
538
+ } catch (error) {
539
+ // Handle errors
540
+ return {
541
+ success: false,
542
+ error: {
543
+ message: error.response?.data?.message || error.message,
544
+ status: error.response?.status,
545
+ details: error.response?.data
546
+ },
547
+ timestamp: new Date().toISOString()
548
+ };
549
+ }
550
+ }`);
551
+
552
+ // Error handling
553
+ sections.push(`// Error Handling
554
+ function handlePaywareError(errorResponse) {
555
+ const status = errorResponse.status || 0;
556
+ const message = errorResponse.message || 'Unknown error';
557
+
558
+ const errorMessages = {
559
+ 400: \`Bad Request: \${message}\`,
560
+ 401: 'Authentication failed - check your partner ID and private key',
561
+ 403: 'Forbidden - insufficient permissions',
562
+ 404: 'Resource not found',
563
+ 409: 'Conflict - resource already exists or invalid state',
564
+ 429: 'Rate limit exceeded - please retry later',
565
+ 500: 'Internal server error - please try again',
566
+ 502: 'Bad gateway - service temporarily unavailable',
567
+ 503: 'Service unavailable - please retry later'
568
+ };
569
+
570
+ return errorMessages[status] || \`API Error \${status}: \${message}\`;
571
+ }`);
572
+
573
+ // Example usage
574
+ const exampleParams = needsId ? "'pw12345678'" : '';
575
+ sections.push(`// Example Usage
576
+ async function main() {
577
+ console.log('=== Merchant ${operation.replace(/_/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase())} Example ===\\n');
578
+
579
+ try {
580
+ // Execute the operation
581
+ const result = await ${operation}(${exampleParams});
582
+
583
+ if (result.success) {
584
+ console.log('✅ Operation successful!');
585
+ console.log(\`Request ID: \${result.requestId || 'N/A'}\`);
586
+ console.log('Response Data:');
587
+ console.log(JSON.stringify(result.data, null, 2));
588
+ } else {
589
+ console.log('❌ Operation failed!');
590
+ const errorMessage = handlePaywareError(result.error);
591
+ console.log(\`Error: \${errorMessage}\`);
592
+
593
+ if (result.error.details) {
594
+ console.log('Error Details:');
595
+ console.log(JSON.stringify(result.error.details, null, 2));
596
+ }
597
+ }
598
+
599
+ } catch (error) {
600
+ console.error(\`❌ Unexpected error: \${error.message}\`);
601
+ }
602
+
603
+ console.log(\`\\nTimestamp: \${new Date().toISOString()}\`);
604
+ console.log('\\n' + '='.repeat(50));
605
+ }
606
+
607
+ // Run the example
608
+ main();`);
609
+
610
+ return sections.join('\n\n');
611
+ }
612
+
613
+ /**
614
+ * Export all merchant transaction examples
615
+ */
616
+ export const MerchantTransactionExamples = {
617
+ operations: MerchantTransactionOperations,
618
+ generators: {
619
+ python: generateMerchantTransactionPython,
620
+ nodejs: generateMerchantTransactionNodeJS,
621
+ javascript: generateMerchantTransactionNodeJS
622
+ }
623
+ };