@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.
- package/.env.example +92 -0
- package/MCP-SETUP.md +190 -0
- package/README.md +483 -0
- package/check-keys.js +52 -0
- package/keys/README.md +112 -0
- package/mcp-config.json +9 -0
- package/package.json +66 -0
- package/payware-mcp-config.json +12 -0
- package/src/auth/rsa-keys.js +82 -0
- package/src/auth/sandbox-setup.js +187 -0
- package/src/config/env.js +229 -0
- package/src/config/partner-types.js +143 -0
- package/src/core/auth/jwt-factory.js +182 -0
- package/src/core/auth/jwt-token.js +735 -0
- package/src/core/utils/json-serializer.js +100 -0
- package/src/core/utils/key-utils.js +133 -0
- package/src/index.js +237 -0
- package/src/isv/data/index.js +291 -0
- package/src/isv/deep-links/delete-product-link.js +154 -0
- package/src/isv/deep-links/delete-transaction-link.js +154 -0
- package/src/isv/deep-links/get-product-link.js +167 -0
- package/src/isv/deep-links/get-transaction-link.js +167 -0
- package/src/isv/deep-links/index.js +23 -0
- package/src/isv/index.js +103 -0
- package/src/isv/oauth2/create-token-simple.js +46 -0
- package/src/isv/oauth2/get-token-info.js +157 -0
- package/src/isv/oauth2/obtain-token.js +189 -0
- package/src/isv/oauth2/token-helper.js +151 -0
- package/src/isv/products/audios.js +470 -0
- package/src/isv/products/create-product.js +314 -0
- package/src/isv/products/delete-product.js +119 -0
- package/src/isv/products/get-product-image.js +247 -0
- package/src/isv/products/get-product.js +168 -0
- package/src/isv/products/index.js +65 -0
- package/src/isv/products/list-products.js +136 -0
- package/src/isv/products/schedules.js +522 -0
- package/src/isv/products/update-product.js +265 -0
- package/src/isv/transactions/cancel-transaction.js +129 -0
- package/src/isv/transactions/create-transaction.js +361 -0
- package/src/isv/transactions/get-status.js +217 -0
- package/src/isv/transactions/process-transaction.js +145 -0
- package/src/isv/transactions/simulate-callback.js +146 -0
- package/src/isv/transactions/transaction-history.js +186 -0
- package/src/isv/utils/auth.js +159 -0
- package/src/mcp-proxy.js +150 -0
- package/src/merchant/data/export-report.js +108 -0
- package/src/merchant/data/generate-report.js +151 -0
- package/src/merchant/data/get-report-status.js +120 -0
- package/src/merchant/data/index.js +351 -0
- package/src/merchant/deep-links/delete-product-link.js +121 -0
- package/src/merchant/deep-links/delete-transaction-link.js +121 -0
- package/src/merchant/deep-links/get-product-link.js +134 -0
- package/src/merchant/deep-links/get-transaction-link.js +134 -0
- package/src/merchant/deep-links/index.js +23 -0
- package/src/merchant/index.js +92 -0
- package/src/merchant/products/audios.js +606 -0
- package/src/merchant/products/create-product.js +288 -0
- package/src/merchant/products/delete-product.js +111 -0
- package/src/merchant/products/get-product-image.js +252 -0
- package/src/merchant/products/get-product.js +144 -0
- package/src/merchant/products/index.js +65 -0
- package/src/merchant/products/list-products.js +112 -0
- package/src/merchant/products/schedules.js +646 -0
- package/src/merchant/products/update-product.js +282 -0
- package/src/merchant/transactions/cancel-transaction.js +241 -0
- package/src/merchant/transactions/create-transaction.js +482 -0
- package/src/merchant/transactions/get-status.js +196 -0
- package/src/merchant/transactions/process-transaction.js +349 -0
- package/src/merchant/transactions/simulate-callback.js +246 -0
- package/src/merchant/transactions/transaction-history.js +258 -0
- package/src/payment-institution/data/index.js +280 -0
- package/src/payment-institution/deep-links/delete-transaction-link.js +128 -0
- package/src/payment-institution/deep-links/get-transaction-link.js +141 -0
- package/src/payment-institution/deep-links/index.js +17 -0
- package/src/payment-institution/index.js +92 -0
- package/src/payment-institution/transactions/create-pi-transaction.js +484 -0
- package/src/payment-institution/transactions/finalize-transaction.js +340 -0
- package/src/payment-institution/transactions/get-transaction-history.js +269 -0
- package/src/payment-institution/transactions/get-transaction-status.js +234 -0
- package/src/payment-institution/transactions/process-pi-transaction.js +421 -0
- package/src/payment-institution/transactions/simulate-pi-callback.js +326 -0
- package/src/payment-institution/transactions/soundbite-transaction.js +269 -0
- package/src/proxy-server.js +205 -0
- package/src/shared/data/data-api.js +372 -0
- package/src/shared/deep-links/api.js +214 -0
- package/src/shared/index.js +44 -0
- package/src/shared/products/products-api.js +872 -0
- package/src/tools/advanced-code-generator.js +2247 -0
- package/src/utils/code-examples/common/auth-examples.js +1482 -0
- package/src/utils/code-examples/common/helpers.js +416 -0
- package/src/utils/code-examples/common/utils-examples.js +591 -0
- package/src/utils/code-examples/frameworks/examples.js +859 -0
- package/src/utils/code-examples/index.js +441 -0
- package/src/utils/code-examples/isv/oauth2.js +600 -0
- package/src/utils/code-examples/isv/products.js +666 -0
- package/src/utils/code-examples/isv/transactions.js +813 -0
- package/src/utils/code-examples/merchant/products.js +497 -0
- package/src/utils/code-examples/merchant/transactions.js +623 -0
- package/src/utils/code-examples/payment-institution/transactions.js +388 -0
- package/src/utils/code-examples/shared/data.js +607 -0
- package/src/utils/code-examples/shared/deep-links.js +662 -0
- package/src/utils/code-examples/shared/soundbites.js +808 -0
- package/src/utils/code-examples.js +646 -0
- package/src/utils/format-request.js +363 -0
- package/src/utils/json-formatter.js +249 -0
- 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
|
+
};
|