@payware/mcp-server 1.3.3 → 1.5.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 (89) hide show
  1. package/.env.example +4 -0
  2. package/README.md +18 -0
  3. package/package.json +7 -9
  4. package/src/auth/rsa-keys.js +12 -6
  5. package/src/auth/sandbox-setup.js +2 -0
  6. package/src/config/toolsets.js +104 -0
  7. package/src/core/auth/jwt-factory.js +4 -1
  8. package/src/core/auth/jwt-token.js +4 -0
  9. package/src/index.js +10 -6
  10. package/src/isv/data/index.js +15 -14
  11. package/src/isv/deep-links/delete-product-link.js +3 -2
  12. package/src/isv/deep-links/delete-transaction-link.js +3 -2
  13. package/src/isv/deep-links/get-product-link.js +8 -6
  14. package/src/isv/deep-links/get-transaction-link.js +8 -6
  15. package/src/isv/index.js +6 -0
  16. package/src/isv/invitations/index.js +5 -0
  17. package/src/isv/oauth2/get-token-info.js +3 -0
  18. package/src/isv/oauth2/obtain-token.js +3 -0
  19. package/src/isv/oauth2/token-helper.js +2 -0
  20. package/src/isv/poi/cancel-price.js +2 -0
  21. package/src/isv/poi/get-poi.js +2 -0
  22. package/src/isv/poi/get-qrcode.js +40 -9
  23. package/src/isv/poi/get-status.js +2 -0
  24. package/src/isv/poi/list-pois.js +2 -0
  25. package/src/isv/poi/set-price.js +2 -0
  26. package/src/isv/products/audios.js +8 -2
  27. package/src/isv/products/create-product.js +2 -0
  28. package/src/isv/products/delete-product.js +2 -0
  29. package/src/isv/products/get-product-image.js +2 -0
  30. package/src/isv/products/get-product.js +2 -0
  31. package/src/isv/products/list-products.js +2 -0
  32. package/src/isv/products/schedules.js +6 -0
  33. package/src/isv/products/update-product.js +2 -0
  34. package/src/isv/reference/index.js +2 -0
  35. package/src/isv/transactions/cancel-transaction.js +2 -0
  36. package/src/isv/transactions/create-transaction.js +14 -2
  37. package/src/isv/transactions/get-status.js +3 -1
  38. package/src/isv/transactions/process-transaction.js +14 -2
  39. package/src/isv/transactions/simulate-callback.js +2 -0
  40. package/src/isv/transactions/transaction-history.js +2 -0
  41. package/src/merchant/data/export-report.js +2 -0
  42. package/src/merchant/data/generate-report.js +2 -0
  43. package/src/merchant/data/get-export-list.js +2 -0
  44. package/src/merchant/data/get-report-requests.js +2 -0
  45. package/src/merchant/data/get-report-status.js +2 -0
  46. package/src/merchant/data/index.js +15 -10
  47. package/src/merchant/data/list-reports.js +2 -0
  48. package/src/merchant/deep-links/delete-product-link.js +3 -2
  49. package/src/merchant/deep-links/delete-transaction-link.js +3 -2
  50. package/src/merchant/deep-links/get-product-link.js +8 -6
  51. package/src/merchant/deep-links/get-transaction-link.js +8 -6
  52. package/src/merchant/index.js +7 -1
  53. package/src/merchant/logs/index.js +4 -0
  54. package/src/merchant/products/audios.js +15 -14
  55. package/src/merchant/products/create-product.js +3 -2
  56. package/src/merchant/products/delete-product.js +3 -2
  57. package/src/merchant/products/get-product-image.js +3 -2
  58. package/src/merchant/products/get-product.js +3 -2
  59. package/src/merchant/products/list-products.js +3 -2
  60. package/src/merchant/products/schedules.js +11 -10
  61. package/src/merchant/products/update-product.js +3 -2
  62. package/src/merchant/transactions/cancel-transaction.js +4 -3
  63. package/src/merchant/transactions/create-transaction.js +14 -2
  64. package/src/merchant/transactions/get-status.js +4 -3
  65. package/src/merchant/transactions/process-transaction.js +17 -6
  66. package/src/merchant/transactions/simulate-callback.js +3 -0
  67. package/src/merchant/transactions/transaction-history.js +5 -4
  68. package/src/payment-institution/data/index.js +15 -14
  69. package/src/payment-institution/deep-links/delete-transaction-link.js +3 -2
  70. package/src/payment-institution/deep-links/get-transaction-link.js +8 -6
  71. package/src/payment-institution/transactions/create-pi-transaction.js +15 -4
  72. package/src/payment-institution/transactions/finalize-transaction.js +7 -4
  73. package/src/payment-institution/transactions/get-transaction-history.js +7 -4
  74. package/src/payment-institution/transactions/get-transaction-status.js +15 -12
  75. package/src/payment-institution/transactions/process-pi-transaction.js +19 -8
  76. package/src/payment-institution/transactions/simulate-pi-callback.js +3 -0
  77. package/src/payment-institution/transactions/soundbite-transaction.js +5 -4
  78. package/src/proxy-server.js +25 -0
  79. package/src/shared/placements/api.js +51 -0
  80. package/src/shared/placements/tools.js +519 -0
  81. package/src/shared/poi/poi-create-api.js +3 -0
  82. package/src/shared/products/products-api.js +36 -25
  83. package/src/shared/shops/shops-api.js +2 -0
  84. package/src/shared/tool-annotations.js +53 -0
  85. package/src/tools/advanced-code-generator.js +3 -0
  86. package/src/utils/format-request.js +2 -0
  87. package/src/utils/json-formatter.js +2 -0
  88. package/src/utils/server-info.js +2 -0
  89. package/src/utils/code-examples.js +0 -646
@@ -1,11 +1,13 @@
1
1
  import { getProducts } from '../../shared/products/products-api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { READS } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * List products tool implementation for merchants
6
7
  */
7
8
  export const listProductsTool = {
8
9
  name: "payware_products_list_products",
10
+ annotations: READS,
9
11
  description: "Get a list of all products for the merchant account",
10
12
 
11
13
  inputSchema: {
@@ -18,8 +20,7 @@ export const listProductsTool = {
18
20
  },
19
21
  privateKey: {
20
22
  type: "string",
21
- description: "RSA private key for authentication (uses environment-specific private key as default)",
22
- default: getPrivateKeySafe()
23
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
23
24
  },
24
25
  useSandbox: {
25
26
  type: "boolean",
@@ -7,12 +7,14 @@ import {
7
7
  } from '../../shared/products/products-api.js';
8
8
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
9
9
  import { PRICE_CORRECTION_TYPES, CORRECTION_TYPES } from '../../shared/products/products-api.js';
10
+ import { CHANGES, CREATES, READS } from '../../shared/tool-annotations.js';
10
11
 
11
12
  /**
12
13
  * Create price schedule tool implementation for merchants
13
14
  */
14
15
  export const createScheduleTool = {
15
16
  name: "payware_products_create_schedule",
17
+ annotations: CREATES,
16
18
  description: "Create a price schedule for a product to manage time-based pricing",
17
19
 
18
20
  inputSchema: {
@@ -62,8 +64,7 @@ export const createScheduleTool = {
62
64
  },
63
65
  privateKey: {
64
66
  type: "string",
65
- description: "RSA private key for authentication (uses environment-specific private key as default)",
66
- default: getPrivateKeySafe()
67
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
67
68
  },
68
69
  useSandbox: {
69
70
  type: "boolean",
@@ -174,6 +175,7 @@ ${JSON.stringify(schedule, null, 2)}
174
175
  */
175
176
  export const getSchedulesTool = {
176
177
  name: "payware_products_get_schedules",
178
+ annotations: READS,
177
179
  description: "Get all price schedules for a product",
178
180
 
179
181
  inputSchema: {
@@ -191,8 +193,7 @@ export const getSchedulesTool = {
191
193
  },
192
194
  privateKey: {
193
195
  type: "string",
194
- description: "RSA private key for authentication (uses environment-specific private key as default)",
195
- default: getPrivateKeySafe()
196
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
196
197
  },
197
198
  useSandbox: {
198
199
  type: "boolean",
@@ -286,6 +287,7 @@ ${schedulesList}
286
287
  */
287
288
  export const getScheduleTool = {
288
289
  name: "payware_products_get_schedule",
290
+ annotations: READS,
289
291
  description: "Get detailed information about a specific price schedule",
290
292
 
291
293
  inputSchema: {
@@ -307,8 +309,7 @@ export const getScheduleTool = {
307
309
  },
308
310
  privateKey: {
309
311
  type: "string",
310
- description: "RSA private key for authentication (uses environment-specific private key as default)",
311
- default: getPrivateKeySafe()
312
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
312
313
  },
313
314
  useSandbox: {
314
315
  type: "boolean",
@@ -399,6 +400,7 @@ ${JSON.stringify(schedule, null, 2)}
399
400
  */
400
401
  export const updateScheduleTool = {
401
402
  name: "payware_products_update_schedule",
403
+ annotations: CHANGES,
402
404
  description: "Update an existing price schedule. Only provide fields you want to change.",
403
405
 
404
406
  inputSchema: {
@@ -449,8 +451,7 @@ export const updateScheduleTool = {
449
451
  },
450
452
  privateKey: {
451
453
  type: "string",
452
- description: "RSA private key for authentication (uses environment-specific private key as default)",
453
- default: getPrivateKeySafe()
454
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
454
455
  },
455
456
  useSandbox: {
456
457
  type: "boolean",
@@ -547,6 +548,7 @@ ${JSON.stringify(schedule, null, 2)}
547
548
  */
548
549
  export const deleteScheduleTool = {
549
550
  name: "payware_products_delete_schedule",
551
+ annotations: CHANGES,
550
552
  description: "Delete a price schedule. This action cannot be undone.",
551
553
 
552
554
  inputSchema: {
@@ -568,8 +570,7 @@ export const deleteScheduleTool = {
568
570
  },
569
571
  privateKey: {
570
572
  type: "string",
571
- description: "RSA private key for authentication (uses environment-specific private key as default)",
572
- default: getPrivateKeySafe()
573
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
573
574
  },
574
575
  useSandbox: {
575
576
  type: "boolean",
@@ -1,12 +1,14 @@
1
1
  import { updateProduct } from '../../shared/products/products-api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
3
  import { PRODUCT_TYPES, OVERLAP_PRIORITY } from '../../shared/products/products-api.js';
4
+ import { CHANGES } from '../../shared/tool-annotations.js';
4
5
 
5
6
  /**
6
7
  * Update product tool implementation for merchants
7
8
  */
8
9
  export const updateProductTool = {
9
10
  name: "payware_products_update_product",
11
+ annotations: CHANGES,
10
12
  description: `Update an existing product. Only provide the fields you want to change.
11
13
 
12
14
  **Product Structure:**
@@ -128,8 +130,7 @@ export const updateProductTool = {
128
130
  },
129
131
  privateKey: {
130
132
  type: "string",
131
- description: "RSA private key for authentication (uses environment-specific private key as default)",
132
- default: getPrivateKeySafe()
133
+ description: "RSA private key for authentication (uses environment-specific private key as default)"
133
134
  },
134
135
  useSandbox: {
135
136
  type: "boolean",
@@ -3,6 +3,7 @@ import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { createMinimizedJSON } from '../../core/utils/json-serializer.js';
4
4
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
5
5
  import { apiErrorResult } from '../../shared/api-errors.js';
6
+ import { CHANGES } from '../../shared/tool-annotations.js';
6
7
 
7
8
  /**
8
9
  * Cancel a transaction via payware API
@@ -76,6 +77,7 @@ export async function cancelTransaction({
76
77
  */
77
78
  export const cancelTransactionTool = {
78
79
  name: "payware_operations_cancel_transaction",
80
+ annotations: CHANGES,
79
81
  description: "Cancel an ACTIVE transaction created by this merchant. Only the merchant who created the transaction can cancel it, and only before it has been processed.",
80
82
  inputSchema: {
81
83
  type: "object",
@@ -104,8 +106,7 @@ export const cancelTransactionTool = {
104
106
  },
105
107
  privateKey: {
106
108
  type: "string",
107
- description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default.",
108
- default: getPrivateKeySafe()
109
+ description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default."
109
110
  },
110
111
  useSandbox: {
111
112
  type: "boolean",
@@ -213,7 +214,7 @@ ${JSON.stringify(result.error.details || result.error, null, 2)}
213
214
  **Timestamp:** ${result.timestamp}
214
215
 
215
216
  **Common Issues:**
216
- 1. **ERR_MISSING_TRANSACTION**: Transaction not found or expired
217
+ 1. **ERR_MISSING_TRANSACTION**: Transaction not found. **ERR_TRANSACTION_EXPIRED** (also 404): its time to live has run out and it is already closed as unpaid
217
218
  2. **ERR_ALREADY_PROCESSED**: Transaction already processed, cannot cancel
218
219
  3. **ERR_UNAUTHORIZED_OPERATION**: Only transaction creator can cancel
219
220
  4. **ERR_INVALID_STATUS_MESSAGE**: Status message invalid or too long
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { createMinimizedJSON } from '../../core/utils/json-serializer.js';
4
4
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
5
+ import { CREATES } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Create a transaction via payware API
@@ -39,6 +40,7 @@ export async function createTransaction({
39
40
  barBarHeight,
40
41
  barFontSize,
41
42
  barHumanReadableLocation,
43
+ idempotencyKey,
42
44
  useSandbox = true
43
45
  }) {
44
46
  if (!reasonL1) {
@@ -141,7 +143,8 @@ export async function createTransaction({
141
143
  const headers = {
142
144
  'Authorization': `Bearer ${tokenData.token}`,
143
145
  'Content-Type': 'application/json',
144
- 'Api-Version': '1' // Required: current API version
146
+ 'Api-Version': '1', // Required: current API version
147
+ ...(idempotencyKey && { 'Idempotency-Key': idempotencyKey })
145
148
  };
146
149
 
147
150
  try {
@@ -159,6 +162,7 @@ export async function createTransaction({
159
162
  success: true,
160
163
  transaction: response.data,
161
164
  requestId: response.headers['x-request-id'],
165
+ replayed: response.headers?.['idempotent-replayed'] === 'true',
162
166
  timestamp: new Date().toISOString()
163
167
  };
164
168
  } catch (error) {
@@ -196,6 +200,7 @@ Original error: ${enhancedMessage}`;
196
200
  */
197
201
  export const createTransactionTool = {
198
202
  name: "payware_operations_create_transaction",
203
+ annotations: CREATES,
199
204
  description: `Create a new payware transaction. Parameters map to the following API structure:
200
205
 
201
206
  📋 **ROOT LEVEL** (Transaction metadata):
@@ -267,6 +272,11 @@ ISV's software is running on that producer's hardware.`,
267
272
  inputSchema: {
268
273
  type: "object",
269
274
  properties: {
275
+ idempotencyKey: {
276
+ type: "string",
277
+ description: "Optional. Sent as the Idempotency-Key header. Use one value per payment (a UUID is typical) and the same value on every retry of it: a retry with the same key and body within 24 hours returns the transaction the first call created instead of a new one, and the result reports replayed: true. The same key with a different body is refused (422 ERR_IDEMPOTENCY_KEY_REUSED); a retry while the first call still runs gets 409 ERR_IDEMPOTENCY_KEY_IN_PROGRESS.",
278
+ pattern: "^[\\x21-\\x7E]{1,255}$"
279
+ },
270
280
  type: {
271
281
  type: "string",
272
282
  enum: ["PLAIN", "QR", "BARCODE"],
@@ -444,6 +454,7 @@ ISV's software is running on that producer's hardware.`,
444
454
  barBarHeight,
445
455
  barFontSize,
446
456
  barHumanReadableLocation,
457
+ idempotencyKey,
447
458
  useSandbox = true
448
459
  } = args;
449
460
 
@@ -488,6 +499,7 @@ ISV's software is running on that producer's hardware.`,
488
499
  barBarHeight,
489
500
  barFontSize,
490
501
  barHumanReadableLocation,
502
+ idempotencyKey,
491
503
  useSandbox
492
504
  });
493
505
 
@@ -524,7 +536,7 @@ ${JSON.stringify(result.transaction, null, 2)}
524
536
 
525
537
  **Next Steps:**
526
538
  1. Save the transaction ID: \`${result.transaction.transactionId || 'N/A'}\`
527
- 2. Use \`payware_transactions_get_transaction_status\` to check status
539
+ 2. Use \`payware_operations_get_transaction_status\` to check status
528
540
  3. Wait for callback notification (if callback URL provided)
529
541
  4. Process payment through payware interface`
530
542
  }]
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
4
  import { apiErrorResult } from '../../shared/api-errors.js';
5
+ import { READS } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Get transaction status from payware API
@@ -67,11 +68,12 @@ function formatTransactionStatus(transaction) {
67
68
  */
68
69
  export const getTransactionStatusTool = {
69
70
  name: "payware_operations_get_transaction_status",
71
+ annotations: READS,
70
72
  description: `Get status of an ACTIVE transaction by ID (for completed/expired transactions use transaction history tool).
71
73
 
72
74
  **Endpoint:** GET /transactions/{transactionId}
73
75
  **Use Case:** Check status of ACTIVE transactions only. This endpoint only returns transactions with ACTIVE status.
74
- **Note:** For transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use 'payware_transactions_get_history' instead.
76
+ **Note:** For transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use 'payware_operations_get_transaction_history' instead.
75
77
 
76
78
  🛍️ **Product-originated transactions carry a nested \`product\` object.** Since 2026-07-22 the
77
79
  presentation fields are grouped under \`product\` rather than sitting flat on the response - the old
@@ -123,8 +125,7 @@ with ERR_FEE_MISMATCH. Echo \`fee\` back unchanged instead.`,
123
125
  },
124
126
  privateKey: {
125
127
  type: "string",
126
- description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default.",
127
- default: getPrivateKeySafe()
128
+ description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default."
128
129
  },
129
130
  useSandbox: {
130
131
  type: "boolean",
@@ -3,6 +3,7 @@ import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { createMinimizedJSON } from '../../core/utils/json-serializer.js';
4
4
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
5
5
  import { apiErrorResult } from '../../shared/api-errors.js';
6
+ import { COMMITS } from '../../shared/tool-annotations.js';
6
7
 
7
8
  /**
8
9
  * Process a transaction via payware API (for merchants accepting payments)
@@ -24,6 +25,7 @@ export async function processTransaction({
24
25
  paymentMethod,
25
26
  partnerId,
26
27
  privateKey,
28
+ idempotencyKey,
27
29
  useSandbox = true
28
30
  }) {
29
31
  if (!transactionId) {
@@ -79,7 +81,8 @@ export async function processTransaction({
79
81
  const headers = {
80
82
  'Authorization': `Bearer ${tokenData.token}`,
81
83
  'Content-Type': 'application/json',
82
- 'Api-Version': '1' // Required: current API version
84
+ 'Api-Version': '1', // Required: current API version
85
+ ...(idempotencyKey && { 'Idempotency-Key': idempotencyKey })
83
86
  };
84
87
 
85
88
  try {
@@ -95,6 +98,7 @@ export async function processTransaction({
95
98
  success: true,
96
99
  transaction: response.data,
97
100
  requestId: response.headers['x-request-id'],
101
+ replayed: response.headers?.['idempotent-replayed'] === 'true',
98
102
  timestamp: new Date().toISOString()
99
103
  };
100
104
  } catch (error) {
@@ -107,6 +111,7 @@ export async function processTransaction({
107
111
  */
108
112
  export const processTransactionTool = {
109
113
  name: "payware_operations_process_transaction",
114
+ annotations: COMMITS,
110
115
  description: `Process a PEER transaction (for merchants accepting payments by scanning customer QR/barcode).
111
116
 
112
117
  **Use Case:** Merchant scans customer's payware QR code or barcode to accept payment.
@@ -136,10 +141,15 @@ export const processTransactionTool = {
136
141
  type: "object",
137
142
  additionalProperties: false,
138
143
  properties: {
144
+ idempotencyKey: {
145
+ type: "string",
146
+ description: "Optional. Sent as the Idempotency-Key header. Use one value per payment (a UUID is typical) and the same value on every retry of it: a retry with the same key and body within 24 hours returns the transaction the first call created instead of a new one, and the result reports replayed: true. The same key with a different body is refused (422 ERR_IDEMPOTENCY_KEY_REUSED); a retry while the first call still runs gets 409 ERR_IDEMPOTENCY_KEY_IN_PROGRESS.",
147
+ pattern: "^[\\x21-\\x7E]{1,255}$"
148
+ },
139
149
  transactionId: {
140
150
  type: "string",
141
- description: "Transaction ID to process. Format: 2-char prefix + 8-char ID. Supports: 'pw' (standard), 'pr' (product), 'ps' (soundbite)",
142
- pattern: "^(pw|pr|ps)[0-9A-Za-z]{8}$"
151
+ description: "Transaction ID to process. Format: 2-char prefix + 8-char ID. Supports: 'pw' (standard), 'pr' (product), 'pl' (placement: pays as its product, and the payment is attributed to the placement), 'ps' (soundbite)",
152
+ pattern: "^(pw|pr|pl|ps)[0-9A-Za-z]{8}$"
143
153
  },
144
154
  amount: {
145
155
  type: ["number", "string"],
@@ -207,8 +217,7 @@ export const processTransactionTool = {
207
217
  },
208
218
  privateKey: {
209
219
  type: "string",
210
- description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default.",
211
- default: getPrivateKeySafe()
220
+ description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default."
212
221
  },
213
222
  useSandbox: {
214
223
  type: "boolean",
@@ -235,6 +244,7 @@ export const processTransactionTool = {
235
244
  paymentMethod,
236
245
  partnerId = getPartnerIdSafe(),
237
246
  privateKey = getPrivateKeySafe(args.useSandbox ?? true),
247
+ idempotencyKey,
238
248
  useSandbox = true
239
249
  } = args;
240
250
 
@@ -273,6 +283,7 @@ export const processTransactionTool = {
273
283
  paymentMethod,
274
284
  partnerId,
275
285
  privateKey,
286
+ idempotencyKey,
276
287
  useSandbox
277
288
  });
278
289
 
@@ -333,7 +344,7 @@ ${JSON.stringify(result.error.details || result.error, null, 2)}
333
344
  **Timestamp:** ${result.timestamp}
334
345
 
335
346
  **Common Issues:**
336
- 1. **ERR_MISSING_TRANSACTION**: Transaction ID not found or expired
347
+ 1. **ERR_MISSING_TRANSACTION**: Transaction ID not found. **ERR_TRANSACTION_EXPIRED** (also 404): its time to live has run out and it is closed as unpaid
337
348
  2. **ERR_UNKNOWN_ROLE**: Transaction generated by payee (can't process own transaction)
338
349
  3. **ERR_ALREADY_PROCESSED**: Transaction already processed
339
350
  4. **ERR_SPECIFYING_AMOUNT_NOT_ALLOWED**: Amount exceeds transaction limit
@@ -9,6 +9,8 @@
9
9
  * @param {Object} options - Additional options
10
10
  * @returns {Object} Mock callback payload
11
11
  */
12
+ import { LOCAL } from '../../shared/tool-annotations.js';
13
+
12
14
  export function generateMockCallback(transactionId, status = 'CONFIRMED', options = {}) {
13
15
  const {
14
16
  amount = '57.60',
@@ -137,6 +139,7 @@ export async function simulateCallbackDelivery(callbackUrl, payload) {
137
139
  */
138
140
  export const simulateCallbackTool = {
139
141
  name: "payware_operations_simulate_callback",
142
+ annotations: LOCAL,
140
143
  description: `Simulate callback scenarios for testing webhook handling.
141
144
 
142
145
  Generates the payload a merchant's \`callbackUrl\` actually receives, so a handler can be built and
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
4
  import { apiErrorResult } from '../../shared/api-errors.js';
5
+ import { READS } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Get transaction history from payware API (for completed/expired transactions)
@@ -91,11 +92,12 @@ function formatTransactionHistory(transaction) {
91
92
  */
92
93
  export const getTransactionHistoryTool = {
93
94
  name: "payware_operations_get_transaction_history",
95
+ annotations: READS,
94
96
  description: `Get history of completed/finalized transactions with final statuses.
95
97
 
96
98
  **Endpoint:** GET /transactions-history/{transactionId}
97
99
  **Use Case:** Retrieve transactions with final statuses: CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED.
98
- **Note:** For ACTIVE transactions, use 'payware_transactions_get_transaction_status' instead.
100
+ **Note:** For ACTIVE transactions, use 'payware_operations_get_transaction_status' instead.
99
101
 
100
102
  📦 **This is where the delivery address lives.** For a SHIPPABLE transaction, \`deliveryAddress\`
101
103
  (fullName, streetAddressLine1/2, zipCode, city, region, country, phoneNumber, email) is returned
@@ -129,8 +131,7 @@ retry once the window passes. The failure result exposes this as \`error.throttl
129
131
  },
130
132
  privateKey: {
131
133
  type: "string",
132
- description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default.",
133
- default: getPrivateKeySafe()
134
+ description: "RSA private key for JWT token creation. Can use PAYWARE_PRIVATE_KEY_PATH env var as default."
134
135
  },
135
136
  useSandbox: {
136
137
  type: "boolean",
@@ -262,7 +263,7 @@ ${JSON.stringify(result.error.details || result.error, null, 2)}
262
263
  1. Verify transaction ID is correct: 10 characters total, starts with 'pw' (standard), 'pr' (product), or 'ps' (soundbite)
263
264
  2. Ensure transaction exists and you have access to it
264
265
  3. If getting rate limit errors, wait 60 seconds before retrying
265
- 4. For ACTIVE transactions, use 'payware_transactions_get_transaction_status' instead
266
+ 4. For ACTIVE transactions, use 'payware_operations_get_transaction_status' instead
266
267
  5. This endpoint only returns transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED)`;
267
268
 
268
269
  return {
@@ -19,10 +19,12 @@ import {
19
19
  LOCALES
20
20
  } from '../../shared/data/data-api.js';
21
21
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
22
+ import { CHANGES, CREATES, READS } from '../../shared/tool-annotations.js';
22
23
 
23
24
  // Create a payment institution tool factory
24
- const createPIDataTool = (toolName, apiFunction, description, additionalParams = {}) => ({
25
+ const createPIDataTool = (toolName, apiFunction, description, additionalParams = {}, annotations) => ({
25
26
  name: `payware_data_${toolName}`,
27
+ annotations,
26
28
  description: `${description} (Payment Institution data access)`,
27
29
  inputSchema: {
28
30
  type: "object",
@@ -35,8 +37,7 @@ const createPIDataTool = (toolName, apiFunction, description, additionalParams =
35
37
  },
36
38
  privateKey: {
37
39
  type: "string",
38
- description: "Payment Institution RSA private key for authentication. Uses environment-specific private key as default.",
39
- default: getPrivateKeySafe()
40
+ description: "Payment Institution RSA private key for authentication. Uses environment-specific private key as default."
40
41
  },
41
42
  ...additionalParams
42
43
  },
@@ -78,6 +79,7 @@ const createPIDataTool = (toolName, apiFunction, description, additionalParams =
78
79
  */
79
80
  export const generateReportTool = {
80
81
  name: "payware_data_generate_report",
82
+ annotations: CREATES,
81
83
  description: "Generate an asynchronous data report for Payment Institution analysis. Focuses on P2P transaction flows and cross-institution payments. Production only.",
82
84
  inputSchema: {
83
85
  type: "object",
@@ -122,8 +124,7 @@ export const generateReportTool = {
122
124
  },
123
125
  privateKey: {
124
126
  type: "string",
125
- description: "Payment Institution RSA private key for authentication. Uses environment-specific private key as default.",
126
- default: getPrivateKeySafe()
127
+ description: "Payment Institution RSA private key for authentication. Uses environment-specific private key as default."
127
128
  }
128
129
  },
129
130
  required: ["reportUnitId"]
@@ -221,7 +222,7 @@ This feature is only available in the production environment, not in sandbox.
221
222
  };
222
223
 
223
224
  // Create all other PI data tools
224
- export const listReportsTool = createPIDataTool('list_reports', listReports, 'List All Available Reports', {});
225
+ export const listReportsTool = createPIDataTool('list_reports', listReports, 'List All Available Reports', {}, READS);
225
226
 
226
227
  export const getReportRequestsTool = createPIDataTool('get_report_requests', getReportRequests, 'Get Report Request History', {
227
228
  reportId: {
@@ -229,21 +230,21 @@ export const getReportRequestsTool = createPIDataTool('get_report_requests', get
229
230
  description: "The report unit ID (path) to get execution history for (e.g., '/processedTransactions')",
230
231
  enum: Object.values(REPORT_TYPES)
231
232
  }
232
- });
233
+ }, READS);
233
234
 
234
235
  export const getExportListTool = createPIDataTool('get_export_list', getExportList, 'Get Export List for Request', {
235
236
  requestId: {
236
237
  type: "string",
237
238
  description: "The request ID (UUID) to get exports for"
238
239
  }
239
- });
240
+ }, READS);
240
241
 
241
242
  export const getReportStatusTool = createPIDataTool('get_report_status', getReportStatus, 'Get Report Status', {
242
243
  requestId: {
243
244
  type: "string",
244
245
  description: "The request ID returned from the report generation request (UUID format)"
245
246
  }
246
- });
247
+ }, READS);
247
248
 
248
249
  export const exportReportTool = createPIDataTool('export_report', exportReport, 'Export Report', {
249
250
  requestId: {
@@ -256,35 +257,35 @@ export const exportReportTool = createPIDataTool('export_report', exportReport,
256
257
  enum: Object.values(EXPORT_FORMATS),
257
258
  default: EXPORT_FORMATS.PDF
258
259
  }
259
- });
260
+ }, CREATES);
260
261
 
261
262
  export const getExportStatusTool = createPIDataTool('get_export_status', getExportStatus, 'Get Export Status', {
262
263
  exportId: {
263
264
  type: "string",
264
265
  description: "The export ID returned from the export request (UUID format)"
265
266
  }
266
- });
267
+ }, READS);
267
268
 
268
269
  export const downloadExportTool = createPIDataTool('download_export', downloadExport, 'Download Export', {
269
270
  exportId: {
270
271
  type: "string",
271
272
  description: "The export ID from the export request (UUID format)"
272
273
  }
273
- });
274
+ }, READS);
274
275
 
275
276
  export const cancelReportTool = createPIDataTool('cancel_report', cancelReport, 'Cancel Report', {
276
277
  requestId: {
277
278
  type: "string",
278
279
  description: "The request ID of the report to cancel (UUID format)"
279
280
  }
280
- });
281
+ }, CHANGES);
281
282
 
282
283
  export const cancelExportTool = createPIDataTool('cancel_export', cancelExport, 'Cancel Export', {
283
284
  exportId: {
284
285
  type: "string",
285
286
  description: "The export ID of the export to cancel (UUID format)"
286
287
  }
287
- });
288
+ }, CHANGES);
288
289
 
289
290
  /**
290
291
  * All Payment Institution data tools
@@ -1,11 +1,13 @@
1
1
  import { deleteTransactionDeepLink } from '../../shared/deep-links/api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { CHANGES } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * Delete deep link for a payment institution transaction
6
7
  */
7
8
  export const deleteTransactionLinkTool = {
8
9
  name: "payware_deep_links_delete_transaction_link",
10
+ annotations: CHANGES,
9
11
  description: `Delete an active deep link for a transaction where the payment institution acts as source (SRC) or destination (DST). Once deleted, the deep link URL will no longer redirect to the payware mobile app.
10
12
 
11
13
  **Use Cases:**
@@ -34,8 +36,7 @@ export const deleteTransactionLinkTool = {
34
36
  },
35
37
  privateKey: {
36
38
  type: "string",
37
- description: "RSA private key for JWT token creation. Uses environment-specific private key as default.",
38
- default: getPrivateKeySafe()
39
+ description: "RSA private key for JWT token creation. Uses environment-specific private key as default."
39
40
  }
40
41
  },
41
42
  required: ["transactionId"]
@@ -1,16 +1,18 @@
1
1
  import { getTransactionDeepLink } from '../../shared/deep-links/api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { ADDS } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * Get deep link for a payment institution transaction
6
7
  */
7
8
  export const getTransactionLinkTool = {
8
9
  name: "payware_deep_links_get_transaction_link",
10
+ annotations: ADDS,
9
11
  description: `Get an active deep link for a transaction where the payment institution acts as source (SRC) or destination (DST). Returns a clickable URL that redirects to the payware mobile app.
10
12
 
11
13
  **Deep Link Format:**
12
14
  - Web URL: https://go.payware.eu/{transactionId}
13
- - Mobile Redirect: payware://{transactionId}
15
+ - Mobile Redirect: payware:/{transactionId} (one slash: the identifier is case-sensitive, so it must not sit in the URI host, which redirect services lowercase)
14
16
 
15
17
  **Use Cases:**
16
18
  - P2P payments initiated via messaging services
@@ -19,6 +21,7 @@ export const getTransactionLinkTool = {
19
21
 
20
22
  **Important Notes:**
21
23
  - Deep links are only supported in production environment
24
+ - Apps that open payware links must accept \`payware:\` followed by one, two or three slashes (QR codes and NFC tags carry \`payware://{id}\`): read the identifier after the scheme and any slashes, up to \`/\`, \`?\` or \`#\`, and keep its case
22
25
  - Link expiration is synchronized with the referenced transaction
23
26
  - Payment institutions only manage transaction links (no product links)
24
27
  - Traditional deep links that route to app content when app is installed`,
@@ -38,8 +41,7 @@ export const getTransactionLinkTool = {
38
41
  },
39
42
  privateKey: {
40
43
  type: "string",
41
- description: "RSA private key for JWT token creation. Uses environment-specific private key as default.",
42
- default: getPrivateKeySafe()
44
+ description: "RSA private key for JWT token creation. Uses environment-specific private key as default."
43
45
  }
44
46
  },
45
47
  required: ["transactionId"]
@@ -83,7 +85,7 @@ export const getTransactionLinkTool = {
83
85
  **Deep Link Details:**
84
86
  - Transaction ID: ${transactionId}
85
87
  - Web URL: ${linkUrl}
86
- - Mobile Redirect: payware://${transactionId}
88
+ - Mobile Redirect: payware:/${transactionId}
87
89
 
88
90
  **Payment Institution Info:**
89
91
  - Partner ID: ${partnerId}
@@ -106,7 +108,7 @@ ${JSON.stringify(result.data, null, 2)}
106
108
 
107
109
  **Usage:**
108
110
  1. Share the web URL: \`${linkUrl}\`
109
- 2. On mobile devices, it will redirect to: \`payware://${transactionId}\`
111
+ 2. On mobile devices, it will redirect to: \`payware:/${transactionId}\`
110
112
  3. Link expires when the transaction expires
111
113
  4. Use for P2P transaction notifications and sharing`
112
114
  }]
@@ -129,7 +131,7 @@ ${JSON.stringify(result.data, null, 2)}
129
131
  5. **Invalid transaction ID**: Ensure transaction ID format is correct
130
132
 
131
133
  **Troubleshooting:**
132
- 1. Verify transaction exists using \`payware_transactions_get_transaction_status\`
134
+ 1. Verify transaction exists using \`payware_operations_get_transaction_status\`
133
135
  2. Check if running in production environment
134
136
  3. Ensure JWT authentication is working
135
137
  4. Confirm payment institution role in transaction