@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,288 @@
1
+ import { createProduct } from '../../shared/products/products-api.js';
2
+ import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { PRODUCT_TYPES, OVERLAP_PRIORITY } from '../../shared/products/products-api.js';
4
+
5
+ /**
6
+ * Create product tool implementation for merchants
7
+ */
8
+ export const createProductTool = {
9
+ name: "payware_products_create_product",
10
+ description: `Create a new product for inventory management and payment processing.
11
+
12
+ **Product Structure:**
13
+ 📦 **PRODUCT METADATA**: name, shortDescription, longDescription, sku, upc, shippable, active, shop
14
+ 💰 **PRODUCT DATA** (prData object): type, regularPrice, currency, overlapPriority, timeToLive, activeFrom, activeTo, timeZone
15
+ ⚙️ **PRODUCT OPTIONS** (prOptions object): imageUrl, termsUrl, termsText
16
+
17
+ **Required:** name
18
+ **Optional:** All other parameters have sensible defaults`,
19
+
20
+ inputSchema: {
21
+ type: "object",
22
+ properties: {
23
+ name: {
24
+ type: "string",
25
+ description: "Product recognizable name (required)",
26
+ maxLength: 50
27
+ },
28
+ shortDescription: {
29
+ type: "string",
30
+ description: "Short product description",
31
+ maxLength: 150
32
+ },
33
+ longDescription: {
34
+ type: "string",
35
+ description: "Long product description",
36
+ maxLength: 1500
37
+ },
38
+ sku: {
39
+ type: "string",
40
+ description: "Stock Keeping Unit (SKU)",
41
+ maxLength: 25
42
+ },
43
+ upc: {
44
+ type: "string",
45
+ description: "Universal Product Code (UPC)",
46
+ maxLength: 15
47
+ },
48
+ shippable: {
49
+ type: "string",
50
+ enum: ["TRUE", "FALSE"],
51
+ description: "Indicates if product requires delivery address",
52
+ default: "FALSE"
53
+ },
54
+ active: {
55
+ type: "string",
56
+ enum: ["TRUE", "FALSE"],
57
+ description: "Indicates if product can serve as payment source",
58
+ default: "FALSE"
59
+ },
60
+ shop: {
61
+ type: "string",
62
+ description: "Shop code (if not supplied, default shop is used)",
63
+ maxLength: 10
64
+ },
65
+ // Product Data Properties
66
+ productType: {
67
+ type: "string",
68
+ enum: Object.values(PRODUCT_TYPES),
69
+ description: "Type of product",
70
+ default: PRODUCT_TYPES.ITEM
71
+ },
72
+ regularPrice: {
73
+ type: "string",
74
+ description: "Product regular price (positive number with max 2 decimals)",
75
+ default: "0.00"
76
+ },
77
+ currency: {
78
+ type: "string",
79
+ pattern: "^[A-Z]{3}$",
80
+ description: "Price currency (3-character ISO code)",
81
+ default: "EUR"
82
+ },
83
+ overlapPriority: {
84
+ type: "string",
85
+ enum: Object.values(OVERLAP_PRIORITY),
86
+ description: "Priority when overlapping price schedules exist",
87
+ default: OVERLAP_PRIORITY.LOWEST
88
+ },
89
+ timeToLive: {
90
+ type: "number",
91
+ description: "Time allowed for product payment in seconds (60-2592000)",
92
+ minimum: 60,
93
+ maximum: 2592000,
94
+ default: 86400
95
+ },
96
+ activeFrom: {
97
+ type: "string",
98
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$",
99
+ description: "Product active state starting date (YYYY-MM-DD format)"
100
+ },
101
+ activeTo: {
102
+ type: "string",
103
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$",
104
+ description: "Product active state ending date (YYYY-MM-DD format)"
105
+ },
106
+ timeZone: {
107
+ type: "string",
108
+ description: "Product state scheduling timezone (IANA format, e.g., 'Europe/Sofia')",
109
+ default: "GMT"
110
+ },
111
+ // Product Options Properties
112
+ imageUrl: {
113
+ type: "string",
114
+ description: "URL pointing to external product image resource",
115
+ maxLength: 150,
116
+ format: "uri"
117
+ },
118
+ termsUrl: {
119
+ type: "string",
120
+ description: "URL pointing to external terms and conditions resource",
121
+ maxLength: 150,
122
+ format: "uri"
123
+ },
124
+ termsText: {
125
+ type: "string",
126
+ description: "Terms and conditions text",
127
+ maxLength: 3000
128
+ },
129
+ // Authentication
130
+ partnerId: {
131
+ type: "string",
132
+ description: "Merchant partner ID (uses PAYWARE_PARTNER_ID env var as default)",
133
+ default: getPartnerIdSafe()
134
+ },
135
+ privateKey: {
136
+ type: "string",
137
+ description: "RSA private key for authentication (uses environment-specific private key as default)",
138
+ default: getPrivateKeySafe(true)
139
+ },
140
+ useSandbox: {
141
+ type: "boolean",
142
+ description: "Use sandbox environment",
143
+ default: true
144
+ }
145
+ },
146
+ required: ["name"]
147
+ },
148
+
149
+ async handler(args) {
150
+ const {
151
+ name,
152
+ shortDescription,
153
+ longDescription,
154
+ sku,
155
+ upc,
156
+ shippable = "FALSE",
157
+ active = "FALSE",
158
+ shop,
159
+ productType = PRODUCT_TYPES.ITEM,
160
+ regularPrice = "0.00",
161
+ currency = "EUR",
162
+ overlapPriority = OVERLAP_PRIORITY.LOWEST,
163
+ timeToLive = 86400,
164
+ activeFrom,
165
+ activeTo,
166
+ timeZone = "GMT",
167
+ imageUrl,
168
+ termsUrl,
169
+ termsText,
170
+ partnerId = getPartnerIdSafe(),
171
+ privateKey = getPrivateKeySafe(args.useSandbox ?? true),
172
+ useSandbox = true
173
+ } = args;
174
+
175
+ if (!name) {
176
+ throw new Error("Product name is required");
177
+ }
178
+
179
+ if (!partnerId) {
180
+ throw new Error("Partner ID is required. Provide via 'partnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
181
+ }
182
+
183
+ if (!privateKey) {
184
+ throw new Error("Private key is required. Provide via 'privateKey' parameter or set environment-specific private key variable.");
185
+ }
186
+
187
+ // Build prData object
188
+ const prData = {
189
+ type: productType,
190
+ regularPrice,
191
+ currency,
192
+ overlapPriority,
193
+ timeToLive,
194
+ timeZone
195
+ };
196
+
197
+ if (activeFrom) prData.activeFrom = activeFrom;
198
+ if (activeTo) prData.activeTo = activeTo;
199
+
200
+ // Build prOptions object
201
+ const prOptions = {};
202
+ if (imageUrl) prOptions.imageUrl = imageUrl;
203
+ if (termsUrl) prOptions.termsUrl = termsUrl;
204
+ if (termsText) prOptions.termsText = termsText;
205
+
206
+ try {
207
+ const result = await createProduct({
208
+ name,
209
+ shortDescription,
210
+ longDescription,
211
+ sku,
212
+ upc,
213
+ shippable,
214
+ active,
215
+ shop,
216
+ prData,
217
+ prOptions,
218
+ partnerType: 'merchant',
219
+ partnerId,
220
+ privateKey,
221
+ useSandbox
222
+ });
223
+
224
+ const product = result.data;
225
+
226
+ return {
227
+ content: [{
228
+ type: "text",
229
+ text: `📦 **Product Created Successfully**
230
+
231
+ **Product Details:**
232
+ - ID: ${product.productId}
233
+ - Name: ${product.name}
234
+ - Type: ${product.type}
235
+ - Price: ${product.regularPrice} ${product.currencyCode}
236
+ - Status: ${product.active ? '✅ Active' : '⏸️ Inactive'}
237
+ - Shop: ${product.shopCode} (${product.shopName})
238
+ ${product.shortDescription ? `- Description: ${product.shortDescription}` : ''}
239
+ ${product.sku ? `- SKU: ${product.sku}` : ''}
240
+ ${product.upc ? `- UPC: ${product.upc}` : ''}
241
+
242
+ **Product Settings:**
243
+ - Shippable: ${product.shippable ? 'Yes' : 'No'}
244
+ - Time to Live: ${product.timeToLive} seconds
245
+ - Sale Price: ${product.salePrice} ${product.currencyCode}
246
+ - Overlap Priority: ${product.overlapPriority}
247
+
248
+ **Active Period:**
249
+ - From: ${product.activeFromZoned || product.activeFrom}
250
+ - To: ${product.activeToZoned || product.activeTo}
251
+ - Timezone: ${product.timeZone}
252
+
253
+ **API Response:**
254
+ \`\`\`json
255
+ ${JSON.stringify(product, null, 2)}
256
+ \`\`\`
257
+
258
+ **API Call Details:**
259
+ - Endpoint: ${result.requestInfo.method} ${result.requestInfo.url}
260
+ - Status: ${result.requestInfo.statusCode}
261
+
262
+ **Next Steps:**
263
+ 1. Save the product ID: \`${product.productId}\`
264
+ 2. Use \`payware_products_get_product\` to view product details
265
+ 3. Use \`payware_products_create_schedule\` to add price schedules
266
+ 4. Use \`payware_products_register_audio\` to add soundbites`
267
+ }]
268
+ };
269
+ } catch (error) {
270
+ return {
271
+ content: [{
272
+ type: "text",
273
+ text: `❌ **Product Creation Failed**
274
+
275
+ **Error Details:**
276
+ - Message: ${error.message}
277
+
278
+ **Troubleshooting:**
279
+ 1. Verify JWT token is valid and not expired
280
+ 2. Check product parameters (name, price format, dates)
281
+ 3. Ensure private key matches public key registered with payware
282
+ 4. Verify partner ID and API access
283
+ 5. Check sandbox API status`
284
+ }]
285
+ };
286
+ }
287
+ }
288
+ };
@@ -0,0 +1,111 @@
1
+ import { deleteProduct } from '../../shared/products/products-api.js';
2
+ import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+
4
+ /**
5
+ * Delete product tool implementation for merchants
6
+ */
7
+ export const deleteProductTool = {
8
+ name: "payware_products_delete_product",
9
+ description: "Delete a product from the merchant account. This action cannot be undone.",
10
+
11
+ inputSchema: {
12
+ type: "object",
13
+ properties: {
14
+ productId: {
15
+ type: "string",
16
+ description: "Product identifier to delete (starts with 'pr')",
17
+ pattern: "^pr[a-zA-Z0-9]+$"
18
+ },
19
+ partnerId: {
20
+ type: "string",
21
+ description: "Merchant partner ID (uses PAYWARE_PARTNER_ID env var as default)",
22
+ default: getPartnerIdSafe()
23
+ },
24
+ privateKey: {
25
+ type: "string",
26
+ description: "RSA private key for authentication (uses environment-specific private key as default)",
27
+ default: getPrivateKeySafe()
28
+ },
29
+ useSandbox: {
30
+ type: "boolean",
31
+ description: "Use sandbox environment",
32
+ default: true
33
+ }
34
+ },
35
+ required: ["productId"]
36
+ },
37
+
38
+ async handler(args) {
39
+ const {
40
+ productId,
41
+ partnerId = getPartnerIdSafe(),
42
+ privateKey = getPrivateKeySafe(),
43
+ useSandbox = true
44
+ } = args;
45
+
46
+ if (!productId) {
47
+ throw new Error("Product ID is required");
48
+ }
49
+
50
+ if (!partnerId) {
51
+ throw new Error("Partner ID is required. Provide via 'partnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
52
+ }
53
+
54
+ if (!privateKey) {
55
+ throw new Error("Private key is required. Provide via 'privateKey' parameter or set environment-specific private key variable.");
56
+ }
57
+
58
+ try {
59
+ const result = await deleteProduct({
60
+ productId,
61
+ partnerType: 'merchant',
62
+ partnerId,
63
+ privateKey,
64
+ useSandbox
65
+ });
66
+
67
+ return {
68
+ content: [{
69
+ type: "text",
70
+ text: `🗑️ **Product Deleted Successfully**
71
+
72
+ **Deleted Product:**
73
+ - ID: ${productId}
74
+ - Status: Successfully removed from account
75
+
76
+ **API Call Details:**
77
+ - Endpoint: ${result.requestInfo.method} ${result.requestInfo.url}
78
+ - Status: ${result.requestInfo.statusCode}
79
+
80
+ **Important Notes:**
81
+ ⚠️ This action cannot be undone
82
+ ⚠️ Any associated price schedules and audios have also been deleted
83
+ ⚠️ Active transactions using this product may be affected
84
+
85
+ **Next Steps:**
86
+ - Use \`payware_products_list_products\` to view remaining products
87
+ - Create new products with \`payware_products_create_product\`
88
+ - Check active transactions that may have used this product`
89
+ }]
90
+ };
91
+ } catch (error) {
92
+ return {
93
+ content: [{
94
+ type: "text",
95
+ text: `❌ **Product Deletion Failed**
96
+
97
+ **Error Details:**
98
+ - Message: ${error.message}
99
+ - Product ID: ${productId}
100
+
101
+ **Troubleshooting:**
102
+ 1. Verify the product ID is correct and exists
103
+ 2. Ensure the product belongs to your account
104
+ 3. Check if the product is currently in use by active transactions
105
+ 4. Verify JWT token is valid and not expired
106
+ 5. Ensure proper API access permissions`
107
+ }]
108
+ };
109
+ }
110
+ }
111
+ };
@@ -0,0 +1,252 @@
1
+ import { getProductImage } from '../../shared/products/products-api.js';
2
+ import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { IMAGE_TYPES, IMAGE_FORMATS, QR_ERROR_CORRECTION, BARCODE_LOCATIONS } from '../../shared/products/products-api.js';
4
+
5
+ /**
6
+ * Get product image tool implementation for merchants
7
+ */
8
+ export const getProductImageTool = {
9
+ name: "payware_products_get_product_image",
10
+ description: `Generate a QR code or barcode image for a product.
11
+
12
+ **QR Code Options:** Format, border, error correction, scale, version
13
+ **Barcode Options:** Format, module width, bar height, font size, text location`,
14
+
15
+ inputSchema: {
16
+ type: "object",
17
+ properties: {
18
+ productId: {
19
+ type: "string",
20
+ description: "Product identifier (starts with 'pr')",
21
+ pattern: "^pr[a-zA-Z0-9]+$"
22
+ },
23
+ type: {
24
+ type: "string",
25
+ enum: Object.values(IMAGE_TYPES),
26
+ description: "Type of image to generate",
27
+ default: IMAGE_TYPES.QR
28
+ },
29
+ // QR Code Options
30
+ qrFormat: {
31
+ type: "string",
32
+ enum: Object.values(IMAGE_FORMATS),
33
+ description: "QR code image format (applies when type=QR)",
34
+ default: IMAGE_FORMATS.SVG
35
+ },
36
+ qrBorder: {
37
+ type: "number",
38
+ minimum: 1,
39
+ maximum: 10,
40
+ description: "QR code border size in modules (applies when type=QR)",
41
+ default: 4
42
+ },
43
+ qrErrorCorrection: {
44
+ type: "string",
45
+ enum: Object.values(QR_ERROR_CORRECTION),
46
+ description: "QR code error correction level (applies when type=QR)",
47
+ default: QR_ERROR_CORRECTION.QUARTILE
48
+ },
49
+ qrScale: {
50
+ type: "number",
51
+ minimum: 1,
52
+ maximum: 100,
53
+ description: "QR code module size in pixels, irrelevant for SVG (applies when type=QR)",
54
+ default: 16
55
+ },
56
+ qrVersion: {
57
+ type: "number",
58
+ minimum: 1,
59
+ maximum: 40,
60
+ description: "QR code version, higher versions store more data (applies when type=QR)",
61
+ default: 10
62
+ },
63
+ // Barcode Options
64
+ barFormat: {
65
+ type: "string",
66
+ enum: Object.values(IMAGE_FORMATS),
67
+ description: "Barcode image format (applies when type=BARCODE)",
68
+ default: IMAGE_FORMATS.SVG
69
+ },
70
+ barModuleWidth: {
71
+ type: "number",
72
+ minimum: 1,
73
+ maximum: 10,
74
+ description: "Barcode module width in pixels (applies when type=BARCODE)",
75
+ default: 2
76
+ },
77
+ barBarHeight: {
78
+ type: "number",
79
+ minimum: 15,
80
+ maximum: 1000,
81
+ description: "Barcode height in pixels (applies when type=BARCODE)",
82
+ default: 100
83
+ },
84
+ barFontSize: {
85
+ type: "number",
86
+ minimum: 0,
87
+ maximum: 24,
88
+ description: "Barcode font size in pixels (applies when type=BARCODE)",
89
+ default: 12
90
+ },
91
+ barHumanReadableLocation: {
92
+ type: "string",
93
+ enum: Object.values(BARCODE_LOCATIONS),
94
+ description: "Barcode text position (applies when type=BARCODE)",
95
+ default: BARCODE_LOCATIONS.NONE
96
+ },
97
+ // Authentication
98
+ partnerId: {
99
+ type: "string",
100
+ description: "Merchant partner ID (uses PAYWARE_PARTNER_ID env var as default)",
101
+ default: getPartnerIdSafe()
102
+ },
103
+ privateKey: {
104
+ type: "string",
105
+ description: "RSA private key for authentication (uses environment-specific private key as default)",
106
+ default: getPrivateKeySafe()
107
+ },
108
+ useSandbox: {
109
+ type: "boolean",
110
+ description: "Use sandbox environment",
111
+ default: true
112
+ }
113
+ },
114
+ required: ["productId"]
115
+ },
116
+
117
+ async handler(args) {
118
+ const {
119
+ productId,
120
+ type = IMAGE_TYPES.QR,
121
+ qrFormat = IMAGE_FORMATS.SVG,
122
+ qrBorder = 4,
123
+ qrErrorCorrection = QR_ERROR_CORRECTION.QUARTILE,
124
+ qrScale = 16,
125
+ qrVersion = 10,
126
+ barFormat = IMAGE_FORMATS.SVG,
127
+ barModuleWidth = 2,
128
+ barBarHeight = 100,
129
+ barFontSize = 12,
130
+ barHumanReadableLocation = BARCODE_LOCATIONS.NONE,
131
+ partnerId = getPartnerIdSafe(),
132
+ privateKey = getPrivateKeySafe(),
133
+ useSandbox = true
134
+ } = args;
135
+
136
+ if (!productId) {
137
+ throw new Error("Product ID is required");
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 environment-specific private key variable.");
146
+ }
147
+
148
+ // Build options based on type
149
+ const qrOptions = type === IMAGE_TYPES.QR ? {
150
+ qrFormat,
151
+ qrBorder,
152
+ qrErrorCorrection,
153
+ qrScale,
154
+ qrVersion
155
+ } : {};
156
+
157
+ const barOptions = type === IMAGE_TYPES.BARCODE ? {
158
+ barFormat,
159
+ barModuleWidth,
160
+ barBarHeight,
161
+ barFontSize,
162
+ barHumanReadableLocation
163
+ } : {};
164
+
165
+ try {
166
+ const result = await getProductImage({
167
+ productId,
168
+ type,
169
+ qrOptions,
170
+ barOptions,
171
+ partnerType: 'merchant',
172
+ partnerId,
173
+ privateKey,
174
+ useSandbox
175
+ });
176
+
177
+ const imageData = result.data;
178
+ const format = imageData.format;
179
+ const imageType = imageData.type;
180
+
181
+ // Truncate image data for display (show first 100 chars + length info)
182
+ const truncatedData = imageData.imageData.length > 100
183
+ ? `${imageData.imageData.substring(0, 100)}... (${imageData.imageData.length} total characters)`
184
+ : imageData.imageData;
185
+
186
+ return {
187
+ content: [{
188
+ type: "text",
189
+ text: `🖼️ **Product Image Generated Successfully**
190
+
191
+ **Image Details:**
192
+ - Product ID: ${imageData.id}
193
+ - Type: ${imageType}
194
+ - Format: ${format}
195
+ - Data Length: ${imageData.imageData.length} characters
196
+
197
+ **Configuration Used:**
198
+ ${type === IMAGE_TYPES.QR ? `**QR Code Settings:**
199
+ - Format: ${qrFormat}
200
+ - Border: ${qrBorder} modules
201
+ - Error Correction: ${qrErrorCorrection}
202
+ - Scale: ${qrScale}px per module
203
+ - Version: ${qrVersion}` : ''}
204
+ ${type === IMAGE_TYPES.BARCODE ? `**Barcode Settings:**
205
+ - Format: ${barFormat}
206
+ - Module Width: ${barModuleWidth}px
207
+ - Height: ${barBarHeight}px
208
+ - Font Size: ${barFontSize}px
209
+ - Text Location: ${barHumanReadableLocation}` : ''}
210
+
211
+ **Image Data (Base64):**
212
+ \`\`\`
213
+ ${truncatedData}
214
+ \`\`\`
215
+
216
+ **API Response:**
217
+ \`\`\`json
218
+ ${JSON.stringify(imageData, null, 2)}
219
+ \`\`\`
220
+
221
+ **API Call Details:**
222
+ - Endpoint: ${result.requestInfo.method} ${result.requestInfo.url}
223
+ - Status: ${result.requestInfo.statusCode}
224
+
225
+ **Usage Notes:**
226
+ - For ${format === 'SVG' ? 'SVG' : 'raster'} images, decode the base64 data and save as .${format.toLowerCase()} file
227
+ - QR codes can be scanned by payment apps to initiate transactions
228
+ - Barcodes can be used for inventory and payment processing systems`
229
+ }]
230
+ };
231
+ } catch (error) {
232
+ return {
233
+ content: [{
234
+ type: "text",
235
+ text: `❌ **Image Generation Failed**
236
+
237
+ **Error Details:**
238
+ - Message: ${error.message}
239
+ - Product ID: ${productId}
240
+ - Image Type: ${type}
241
+
242
+ **Troubleshooting:**
243
+ 1. Verify the product ID is correct and exists
244
+ 2. Check image generation parameters (format, dimensions)
245
+ 3. Ensure the product belongs to your account
246
+ 4. Verify JWT token is valid and not expired
247
+ 5. Try different image settings if generation fails`
248
+ }]
249
+ };
250
+ }
251
+ }
252
+ };