@payware/mcp-server 1.3.2 → 1.4.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 (93) 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 +10 -5
  18. package/src/isv/oauth2/obtain-token.js +9 -4
  19. package/src/isv/oauth2/token-helper.js +28 -26
  20. package/src/isv/poi/cancel-price.js +9 -2
  21. package/src/isv/poi/get-poi.js +4 -3
  22. package/src/isv/poi/get-qrcode.js +40 -9
  23. package/src/isv/poi/get-status.js +196 -168
  24. package/src/isv/poi/list-pois.js +6 -6
  25. package/src/isv/poi/set-price.js +40 -53
  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 +2 -0
  37. package/src/isv/transactions/get-status.js +3 -1
  38. package/src/isv/transactions/process-transaction.js +2 -0
  39. package/src/isv/transactions/simulate-callback.js +21 -10
  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 +3 -2
  63. package/src/merchant/transactions/create-transaction.js +3 -1
  64. package/src/merchant/transactions/get-status.js +4 -3
  65. package/src/merchant/transactions/process-transaction.js +5 -4
  66. package/src/merchant/transactions/simulate-callback.js +325 -313
  67. package/src/merchant/transactions/transaction-history.js +7 -6
  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 +4 -3
  72. package/src/payment-institution/transactions/finalize-transaction.js +6 -3
  73. package/src/payment-institution/transactions/get-transaction-history.js +8 -5
  74. package/src/payment-institution/transactions/get-transaction-status.js +16 -13
  75. package/src/payment-institution/transactions/process-pi-transaction.js +7 -6
  76. package/src/payment-institution/transactions/simulate-pi-callback.js +388 -375
  77. package/src/payment-institution/transactions/soundbite-transaction.js +6 -5
  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 +4 -1
  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 +17 -265
  86. package/src/utils/code-examples/common/auth-examples.js +1 -1
  87. package/src/utils/code-examples/isv/products.js +1 -1
  88. package/src/utils/code-examples/isv/transactions.js +1 -1
  89. package/src/utils/code-examples/merchant/transactions.js +1 -1
  90. package/src/utils/format-request.js +2 -0
  91. package/src/utils/json-formatter.js +2 -0
  92. package/src/utils/server-info.js +2 -0
  93. package/src/utils/code-examples.js +0 -646
@@ -6,6 +6,7 @@ import {
6
6
  deleteAudio
7
7
  } from '../../shared/products/products-api.js';
8
8
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
9
+ import { CHANGES, CREATES, READS } from '../../shared/tool-annotations.js';
9
10
 
10
11
  // Common ISV authentication properties
11
12
  const ISV_AUTH_PROPS = {
@@ -46,9 +47,10 @@ function validateISVAuth(args) {
46
47
  */
47
48
  export const registerAudioTool = {
48
49
  name: "payware_products_register_audio",
50
+ annotations: CREATES,
49
51
  description: `Register an audio file (soundbite) for a merchant's product (ISV operation).
50
52
 
51
- **Supported formats:** Most audio/video formats (up to 200MB)
53
+ **Supported formats:** MP3, WAV, OGG, M4A, FLAC, AAC, WMA, MP4, MOV, up to 100 MB, holding 2 to 120 seconds of audio
52
54
  **Note:** For video files, only the audio channel is registered`,
53
55
 
54
56
  inputSchema: {
@@ -139,6 +141,7 @@ ${audio.status === '1' ? '✅ Audio is ready for use in soundbite transactions'
139
141
  */
140
142
  export const getAudiosTool = {
141
143
  name: "payware_products_get_audios",
144
+ annotations: READS,
142
145
  description: "Get all registered audio files for a merchant's product (ISV operation)",
143
146
 
144
147
  inputSchema: {
@@ -225,6 +228,7 @@ ${audiosList}`
225
228
  */
226
229
  export const getAudioTool = {
227
230
  name: "payware_products_get_audio",
231
+ annotations: READS,
228
232
  description: "Get detailed information about a specific audio file (ISV operation)",
229
233
 
230
234
  inputSchema: {
@@ -305,6 +309,7 @@ ${audio.status === '1' ? '✅ **Ready:** Audio is processed and ready for soundb
305
309
  */
306
310
  export const updateAudioTool = {
307
311
  name: "payware_products_update_audio",
312
+ annotations: CHANGES,
308
313
  description: "Update audio information (title) or reassign audio to another product (ISV operation)",
309
314
 
310
315
  inputSchema: {
@@ -327,7 +332,7 @@ export const updateAudioTool = {
327
332
  },
328
333
  newProductId: {
329
334
  type: "string",
330
- description: "New product ID to reassign audio to (starts with 'pr')",
335
+ description: "Product to move the audio to (starts with 'pr'). Sent as a transfer, which keeps the fingerprint; the target must be in the same shop",
331
336
  pattern: "^pr[a-zA-Z0-9]+$"
332
337
  },
333
338
  useSandbox: {
@@ -400,6 +405,7 @@ ${newProductId ? `- Reassigned from product ${productId} to ${newProductId}` : '
400
405
  */
401
406
  export const deleteAudioTool = {
402
407
  name: "payware_products_delete_audio",
408
+ annotations: CHANGES,
403
409
  description: "Delete an audio file from a merchant's product (ISV operation). This action cannot be undone.",
404
410
 
405
411
  inputSchema: {
@@ -1,12 +1,14 @@
1
1
  import { createProduct } 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 { CREATES } from '../../shared/tool-annotations.js';
4
5
 
5
6
  /**
6
7
  * Create product tool implementation for ISVs
7
8
  */
8
9
  export const createProductTool = {
9
10
  name: "payware_products_create_product",
11
+ annotations: CREATES,
10
12
  description: `Create a new product for inventory management and payment processing on behalf of a merchant (ISV operation).
11
13
 
12
14
  **ISV Authentication**: Requires ISV credentials and OAuth2 token from target merchant.
@@ -1,11 +1,13 @@
1
1
  import { deleteProduct } from '../../shared/products/products-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 product tool implementation for ISVs
6
7
  */
7
8
  export const deleteProductTool = {
8
9
  name: "payware_products_delete_product",
10
+ annotations: CHANGES,
9
11
  description: "Delete a product from a merchant account (ISV operation). This action cannot be undone.",
10
12
 
11
13
  inputSchema: {
@@ -1,12 +1,14 @@
1
1
  import { getProductImage } from '../../shared/products/products-api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
3
  import { IMAGE_TYPES, IMAGE_FORMATS, QR_ERROR_CORRECTION, BARCODE_LOCATIONS } from '../../shared/products/products-api.js';
4
+ import { READS } from '../../shared/tool-annotations.js';
4
5
 
5
6
  /**
6
7
  * Get product image tool implementation for ISVs
7
8
  */
8
9
  export const getProductImageTool = {
9
10
  name: "payware_products_get_product_image",
11
+ annotations: READS,
10
12
  description: `Generate a QR code or barcode image for a merchant's product (ISV operation).`,
11
13
 
12
14
  inputSchema: {
@@ -1,11 +1,13 @@
1
1
  import { getProduct } 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
  * Get product tool implementation for ISVs
6
7
  */
7
8
  export const getProductTool = {
8
9
  name: "payware_products_get_product",
10
+ annotations: READS,
9
11
  description: "Get detailed information about a specific product by ID (ISV operation)",
10
12
 
11
13
  inputSchema: {
@@ -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 ISVs
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 a merchant account (ISV operation)",
10
12
 
11
13
  inputSchema: {
@@ -7,6 +7,7 @@ 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
  // Common ISV authentication properties
12
13
  const ISV_AUTH_PROPS = {
@@ -47,6 +48,7 @@ function validateISVAuth(args) {
47
48
  */
48
49
  export const createScheduleTool = {
49
50
  name: "payware_products_create_schedule",
51
+ annotations: CREATES,
50
52
  description: "Create a price schedule for a merchant's product (ISV operation)",
51
53
 
52
54
  inputSchema: {
@@ -172,6 +174,7 @@ export const createScheduleTool = {
172
174
  */
173
175
  export const getSchedulesTool = {
174
176
  name: "payware_products_get_schedules",
177
+ annotations: READS,
175
178
  description: "Get all price schedules for a merchant's product (ISV operation)",
176
179
 
177
180
  inputSchema: {
@@ -258,6 +261,7 @@ ${schedulesList}`
258
261
  */
259
262
  export const getScheduleTool = {
260
263
  name: "payware_products_get_schedule",
264
+ annotations: READS,
261
265
  description: "Get detailed information about a specific price schedule (ISV operation)",
262
266
 
263
267
  inputSchema: {
@@ -341,6 +345,7 @@ export const getScheduleTool = {
341
345
  */
342
346
  export const updateScheduleTool = {
343
347
  name: "payware_products_update_schedule",
348
+ annotations: CHANGES,
344
349
  description: "Update an existing price schedule (ISV operation)",
345
350
 
346
351
  inputSchema: {
@@ -452,6 +457,7 @@ export const updateScheduleTool = {
452
457
  */
453
458
  export const deleteScheduleTool = {
454
459
  name: "payware_products_delete_schedule",
460
+ annotations: CHANGES,
455
461
  description: "Delete a price schedule (ISV operation). This action cannot be undone.",
456
462
 
457
463
  inputSchema: {
@@ -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 ISVs
7
8
  */
8
9
  export const updateProductTool = {
9
10
  name: "payware_products_update_product",
11
+ annotations: CHANGES,
10
12
  description: `Update an existing product on behalf of a merchant (ISV operation). Only provide the fields you want to change.`,
11
13
 
12
14
  inputSchema: {
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTToken } from '../../core/auth/jwt-token.js';
3
3
  import { apiErrorResult } from '../../shared/api-errors.js';
4
4
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
5
+ import { READS } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Reference data - the enumerations a merchant registration form has to be filled in with.
@@ -129,6 +130,7 @@ const DATASET_DOCS = Object.entries(DATASETS)
129
130
 
130
131
  export const referenceDataTool = {
131
132
  name: 'payware_reference_lookup',
133
+ annotations: READS,
132
134
  description: `Look up payware reference data - the enumerations a merchant registration form needs.
133
135
 
134
136
  **Endpoints:** GET /isv/reference/{legal-forms, business-activities, currencies, languages, jurisdictions}
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
3
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
4
  import { describeApiError } from '../../shared/api-errors.js';
5
+ import { CHANGES } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Cancel a transaction via payware API as an ISV
@@ -77,6 +78,7 @@ export async function cancelTransaction({ transactionId, statusMessage, merchant
77
78
 
78
79
  export const cancelTransactionTool = {
79
80
  name: 'payware_operations_cancel_transaction',
81
+ annotations: CHANGES,
80
82
  description: `Cancel an active transaction as an ISV on behalf of a merchant.
81
83
 
82
84
  **Endpoint:** PATCH /transactions/{transactionId} with \`{"status":"CANCELLED","statusMessage":"..."}\`
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
3
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
4
  import { describeApiError } from '../../shared/api-errors.js';
5
+ import { CREATES } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Create a transaction via payware API on behalf of a merchant (ISV)
@@ -145,6 +146,7 @@ export async function createTransaction({
145
146
 
146
147
  export const createTransactionTool = {
147
148
  name: 'payware_operations_create_transaction',
149
+ annotations: CREATES,
148
150
  description: `Create a new transaction through payware as an ISV on behalf of a merchant.
149
151
 
150
152
  ISV partners can create transactions for merchants they have authorization for via OAuth2.
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTForPartner } from '../../core/auth/jwt-factory.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 as an ISV
@@ -81,12 +82,13 @@ function formatTransactionStatus(transaction) {
81
82
  */
82
83
  export const getTransactionStatusTool = {
83
84
  name: "payware_operations_get_transaction_status",
85
+ annotations: READS,
84
86
  description: `Get status of an ACTIVE transaction by ID as an ISV on behalf of a merchant.
85
87
 
86
88
  **ISV Authentication:** Uses ISV JWT with merchant partner ID in 'aud' claim and OAuth2 token in 'sub' claim.
87
89
  **Endpoint:** GET /transactions/{transactionId}
88
90
  **Use Case:** Check status of ACTIVE transactions only. This endpoint only returns transactions with ACTIVE status.
89
- **Note:** For transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use 'payware_transactions_get_history' instead.
91
+ **Note:** For transactions with final statuses (CONFIRMED, DECLINED, FAILED, EXPIRED, CANCELLED), use 'payware_operations_get_transaction_history' instead.
90
92
 
91
93
  **Required:** Merchant Partner ID and OAuth2 token for ISV authentication.
92
94
 
@@ -3,6 +3,7 @@ import { createJWTForPartner } from '../../core/auth/jwt-factory.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 { describeApiError } from '../../shared/api-errors.js';
6
+ import { COMMITS } from '../../shared/tool-annotations.js';
6
7
 
7
8
  /**
8
9
  * Process a PEER transaction as an ISV on behalf of a merchant.
@@ -122,6 +123,7 @@ export async function processTransaction({
122
123
 
123
124
  export const processTransactionTool = {
124
125
  name: 'payware_operations_process_transaction',
126
+ annotations: COMMITS,
125
127
  description: `Process a PEER transaction as an ISV on behalf of a merchant - the merchant scanning a customer's QR or barcode to collect payment.
126
128
 
127
129
  **Endpoint:** POST /transactions/{transactionId}
@@ -1,5 +1,6 @@
1
1
  import { getPartnerIdSafe } from '../../config/env.js';
2
2
  import { generateMockCallback, simulateCallbackDelivery } from '../../merchant/transactions/simulate-callback.js';
3
+ import { LOCAL } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * Simulate the callback a merchant's endpoint receives, for an ISV building that handler.
@@ -17,16 +18,19 @@ import { generateMockCallback, simulateCallbackDelivery } from '../../merchant/t
17
18
  */
18
19
  export const simulateCallbackTool = {
19
20
  name: 'payware_operations_simulate_callback',
21
+ annotations: LOCAL,
20
22
  description: `Simulate the callback payload payware sends to a merchant's callbackUrl, for building and testing a webhook handler as an ISV.
21
23
 
22
24
  **Local only - this makes no API call.** payware has no endpoint that triggers a callback on demand,
23
25
  so nothing here reaches the network. What you get back is the exact payload shape a real
24
26
  TRANSACTION_FINALIZED callback carries, which is what a handler needs in order to be written.
25
27
 
26
- **Callbacks go to the MERCHANT's callbackUrl, not to yours.** An ISV that needs to know a transaction
27
- finished either has the merchant forward it, or polls
28
- \`payware_operations_get_transaction_history\` for the ids it created. Simulating the payload here
29
- tells you what the merchant's endpoint will receive; it does not route anything to you.
28
+ **Where the callback goes.** A transaction you create on a merchant's behalf calls back to the
29
+ \`callbackUrl\` you give when creating it; a POI sale calls back to the POI's \`callbackUrl\`. Both are
30
+ signed with your ISV callback key, so verify them with your own payware public key. Give no callbackUrl
31
+ and that transaction sends no callbacks at all - the merchant's default URL is not used. Without a backend, follow the
32
+ transaction with \`payware_operations_get_transaction_status\` while it is ACTIVE and then
33
+ \`payware_operations_get_transaction_history\` once, or a POI sale with \`payware_poi_get_status\`.
30
34
 
31
35
  Four properties of the real payload that are easy to get wrong:
32
36
 
@@ -38,9 +42,11 @@ Four properties of the real payload that are easy to get wrong:
38
42
  **3. \`EXPIRED\` is a non-payment, not a failure.** The payer never paid within \`timeToLive\`. Release
39
43
  the order or the stock; do not treat it as an error to retry.
40
44
 
41
- **4. Deduplicate on \`(transactionId, callbackType)\`.** payware retries once a second, up to 15
42
- times, until the endpoint answers 200. That pair is stable across retries and is the key payware
43
- guarantees.
45
+ **4. Deduplicate on \`(transactionId, callbackType)\`.** payware retries up to 15 times, backing off
46
+ from about a second to at most 5 minutes between attempts, until the endpoint answers any 2xx. That
47
+ pair is stable across retries and is the key payware guarantees.
48
+
49
+ A POI sale's callback also carries \`poiId\`, the POI that created the transaction.
44
50
 
45
51
  **Not on this payload:** \`deliveryAddress\` (removed 2026-08-07 - fetch it from
46
52
  \`payware_operations_get_transaction_history\`), \`producerPartnerId\`, \`transactionType\` and
@@ -99,6 +105,10 @@ guarantees.
99
105
  enum: ['A2A', 'CARD_FUNDED', 'BNPL', 'INSTANT_CREDIT'],
100
106
  description: 'Payment method chosen by the customer. A2A = direct transfer. CARD_FUNDED = card-linked account. BNPL = buy now pay later. INSTANT_CREDIT = credit line.'
101
107
  },
108
+ poiId: {
109
+ type: 'string',
110
+ description: 'Set to simulate a POI sale: the callback then carries the poiId of the POI that created the transaction'
111
+ },
102
112
  merchantPartnerId: {
103
113
  type: 'string',
104
114
  description: 'Partner ID of the merchant whose callback this simulates. Used for labelling only - no call is made on their behalf.'
@@ -123,6 +133,7 @@ guarantees.
123
133
  feeRate = '0.0150',
124
134
  statusMessage,
125
135
  paymentMethod,
136
+ poiId,
126
137
  merchantPartnerId
127
138
  } = args;
128
139
 
@@ -131,7 +142,7 @@ guarantees.
131
142
  }
132
143
 
133
144
  const payload = generateMockCallback(transactionId, status, {
134
- amount, currency, fee, feeFixed, feeRate, statusMessage, paymentMethod
145
+ amount, currency, fee, feeFixed, feeRate, statusMessage, paymentMethod, poiId
135
146
  });
136
147
 
137
148
  const delivery = callbackUrl ? await simulateCallbackDelivery(callbackUrl, payload) : null;
@@ -141,7 +152,7 @@ guarantees.
141
152
  type: 'text',
142
153
  text: `🔔 **Simulated Callback Payload**${merchantPartnerId ? ` (ISV ${getPartnerIdSafe()} -> Merchant ${merchantPartnerId})` : ''}
143
154
 
144
- This is what payware would POST to the **merchant's** \`callbackUrl\`. No request was made.
155
+ This is what payware would POST to the transaction's (or POI's) \`callbackUrl\`. No request was made.
145
156
 
146
157
  \`\`\`json
147
158
  ${JSON.stringify(payload, null, 2)}
@@ -153,7 +164,7 @@ ${delivery.note}
153
164
  ` : '**No callbackUrl given** - payload only.'}
154
165
 
155
166
  **Building the handler:**
156
- 1. Answer **200** or payware retries - once a second, 15 times.
167
+ 1. Answer any **2xx** or payware retries - up to 15 times, backing off from about a second to 5 minutes.
157
168
  2. Deduplicate on \`(transactionId, callbackType)\`; retries repeat the same pair.
158
169
  3. Read properties defensively: absent means absent, never zero.
159
170
  4. Treat \`EXPIRED\` as a non-payment, not an error to retry.
@@ -2,6 +2,7 @@ import axios from 'axios';
2
2
  import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
3
  import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
4
  import { describeApiError } from '../../shared/api-errors.js';
5
+ import { READS } from '../../shared/tool-annotations.js';
5
6
 
6
7
  /**
7
8
  * Get one completed transaction as an ISV acting on behalf of a merchant.
@@ -68,6 +69,7 @@ export async function getTransactionHistory({
68
69
 
69
70
  export const getTransactionHistoryTool = {
70
71
  name: 'payware_operations_get_transaction_history',
72
+ annotations: READS,
71
73
  description: `Get one completed or expired transaction as an ISV on behalf of a merchant.
72
74
 
73
75
  **Endpoint:** GET /transactions-history/{transactionId}
@@ -1,11 +1,13 @@
1
1
  import { exportReport, EXPORT_FORMATS } from '../../shared/data/data-api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { CREATES } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * Export report tool for merchants
6
7
  */
7
8
  export const exportReportTool = {
8
9
  name: "payware_data_export_report",
10
+ annotations: CREATES,
9
11
  description: "Export a READY report in a specific format (PDF, CSV, Excel, JSON). The report must be in READY status first.",
10
12
  inputSchema: {
11
13
  type: "object",
@@ -1,11 +1,13 @@
1
1
  import { generateReport, REPORT_TYPES, LOCALES } from '../../shared/data/data-api.js';
2
2
  import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
3
+ import { CREATES } from '../../shared/tool-annotations.js';
3
4
 
4
5
  /**
5
6
  * Generate report tool for merchants
6
7
  */
7
8
  export const generateReportTool = {
8
9
  name: "payware_data_generate_report",
10
+ annotations: CREATES,
9
11
  description: `Generate an asynchronous data report for merchant data analysis and reporting. Production only - not supported in sandbox.
10
12
 
11
13
  ⚠️ **Running a report is entitlement-checked as of 2026-08-22.** Naming a report answers **403
@@ -1,11 +1,13 @@
1
1
  import { getExportList } from '../../shared/data/data-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
  * Get export list for request tool for merchants
6
7
  */
7
8
  export const getExportListTool = {
8
9
  name: "payware_data_get_export_list",
10
+ annotations: READS,
9
11
  description: "Get all export attempts for a specific report request. Returns list of exports in various formats with their status and download information. Production only - not supported in sandbox.",
10
12
  inputSchema: {
11
13
  type: "object",
@@ -1,11 +1,13 @@
1
1
  import { getReportRequests, REPORT_TYPES } from '../../shared/data/data-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
  * Get report request history tool for merchants
6
7
  */
7
8
  export const getReportRequestsTool = {
8
9
  name: "payware_data_get_report_requests",
10
+ annotations: READS,
9
11
  description: "Get all execution requests for a specific report type. Returns historical execution records with status and parameters. Production only - not supported in sandbox.",
10
12
  inputSchema: {
11
13
  type: "object",
@@ -1,11 +1,13 @@
1
1
  import { getReportStatus } from '../../shared/data/data-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
  * Get report status tool for merchants
6
7
  */
7
8
  export const getReportStatusTool = {
8
9
  name: "payware_data_get_report_status",
10
+ annotations: READS,
9
11
  description: "Get the status of an asynchronous report generation request. Use this to monitor report progress.",
10
12
  inputSchema: {
11
13
  type: "object",
@@ -20,12 +20,14 @@ import { exportReportTool } from './export-report.js';
20
20
  import { listReportsTool } from './list-reports.js';
21
21
  import { getReportRequestsTool } from './get-report-requests.js';
22
22
  import { getExportListTool } from './get-export-list.js';
23
+ import { ADDS, CHANGES, READS } from '../../shared/tool-annotations.js';
23
24
 
24
25
  /**
25
26
  * Get export status tool for merchants
26
27
  */
27
28
  export const getExportStatusTool = {
28
29
  name: "payware_data_get_export_status",
30
+ annotations: READS,
29
31
  description: "Get the status of a report export request. Use this to monitor export progress.",
30
32
  inputSchema: {
31
33
  type: "object",
@@ -41,8 +43,7 @@ export const getExportStatusTool = {
41
43
  },
42
44
  privateKey: {
43
45
  type: "string",
44
- description: "RSA private key for authentication. Uses environment-specific private key as default.",
45
- default: getPrivateKeySafe()
46
+ description: "RSA private key for authentication. Uses environment-specific private key as default."
46
47
  }
47
48
  },
48
49
  required: ["exportId"]
@@ -117,6 +118,7 @@ ${downloadInfo}
117
118
  */
118
119
  export const downloadExportTool = {
119
120
  name: "payware_data_download_export",
121
+ annotations: ADDS,
120
122
  description: "Download a READY export file. The export must be in READY status. Returns binary data for the file.",
121
123
  inputSchema: {
122
124
  type: "object",
@@ -127,7 +129,7 @@ export const downloadExportTool = {
127
129
  },
128
130
  saveToFile: {
129
131
  type: "boolean",
130
- description: "Whether to save the downloaded file to disk. If true, saves to /mnt/d/git/payware/mcp/downloads/. If false, only shows metadata/preview.",
132
+ description: "Whether to save the downloaded file to disk. If true, saves it to a payware-mcp-downloads folder in the system temp directory and returns the path. If false, only shows metadata/preview.",
131
133
  default: false
132
134
  },
133
135
  partnerId: {
@@ -181,11 +183,14 @@ export const downloadExportTool = {
181
183
  };
182
184
  const extension = extensionMap[contentType] || 'bin';
183
185
  const filename = `report_${exportId.substring(0, 8)}.${extension}`;
184
- const filepath = `/mnt/d/git/payware/mcp/downloads/${filename}`;
186
+ // The temp directory is writable wherever the server runs; its working directory, set by the
187
+ // MCP client, often is not. This was a fixed developer path, which no other machine has.
188
+ const os = await import('os');
189
+ const path = await import('path');
190
+ const filepath = path.join(os.tmpdir(), 'payware-mcp-downloads', filename);
185
191
 
186
192
  // Save file to downloads directory
187
193
  const fs = await import('fs');
188
- const path = await import('path');
189
194
  const downloadDir = path.dirname(filepath);
190
195
 
191
196
  // Create downloads directory if it doesn't exist
@@ -222,7 +227,7 @@ ${savedFileInfo}${contentPreview}
222
227
  **Summary:**
223
228
  ✅ ${saveToFile ? 'File saved to disk and' : 'File'} downloaded successfully
224
229
 
225
- ${saveToFile ? '**Tip:** The file has been saved and can be opened with the appropriate application.' : '**Tip:** Use `saveToFile: true` parameter to save the file to disk at `/mnt/d/git/payware/mcp/downloads/`'}`
230
+ ${saveToFile ? '**Tip:** The file has been saved and can be opened with the appropriate application.' : '**Tip:** Use `saveToFile: true` parameter to save the file to disk'}`
226
231
  }]
227
232
  };
228
233
  } catch (error) {
@@ -236,6 +241,7 @@ ${saveToFile ? '**Tip:** The file has been saved and can be opened with the appr
236
241
  */
237
242
  export const cancelReportTool = {
238
243
  name: "payware_data_cancel_report",
244
+ annotations: CHANGES,
239
245
  description: "Cancel a running report generation. Only reports in QUEUED status can be cancelled.",
240
246
  inputSchema: {
241
247
  type: "object",
@@ -251,8 +257,7 @@ export const cancelReportTool = {
251
257
  },
252
258
  privateKey: {
253
259
  type: "string",
254
- description: "RSA private key for authentication. Uses environment-specific private key as default.",
255
- default: getPrivateKeySafe()
260
+ description: "RSA private key for authentication. Uses environment-specific private key as default."
256
261
  }
257
262
  },
258
263
  required: ["requestId"]
@@ -307,6 +312,7 @@ Only reports in QUEUED status can be cancelled. Reports that are already READY,
307
312
  */
308
313
  export const cancelExportTool = {
309
314
  name: "payware_data_cancel_export",
315
+ annotations: CHANGES,
310
316
  description: "Cancel a running export process. Only exports in QUEUED status can be cancelled.",
311
317
  inputSchema: {
312
318
  type: "object",
@@ -322,8 +328,7 @@ export const cancelExportTool = {
322
328
  },
323
329
  privateKey: {
324
330
  type: "string",
325
- description: "RSA private key for authentication. Uses environment-specific private key as default.",
326
- default: getPrivateKeySafe()
331
+ description: "RSA private key for authentication. Uses environment-specific private key as default."
327
332
  }
328
333
  },
329
334
  required: ["exportId"]
@@ -1,11 +1,13 @@
1
1
  import { listReports } from '../../shared/data/data-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 all available reports tool for merchants
6
7
  */
7
8
  export const listReportsTool = {
8
9
  name: "payware_data_list_reports",
10
+ annotations: READS,
9
11
  description: "List all available report types with their configurations, descriptions, and visibility settings. Production only - not supported in sandbox.",
10
12
  inputSchema: {
11
13
  type: "object",
@@ -1,11 +1,13 @@
1
1
  import { deleteProductDeepLink } 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 merchant product
6
7
  */
7
8
  export const deleteProductLinkTool = {
8
9
  name: "payware_deep_links_delete_product_link",
10
+ annotations: CHANGES,
9
11
  description: `Delete an active deep link for a product. Once deleted, the deep link URL will no longer redirect to the payware mobile app.
10
12
 
11
13
  **Use Cases:**
@@ -33,8 +35,7 @@ export const deleteProductLinkTool = {
33
35
  },
34
36
  privateKey: {
35
37
  type: "string",
36
- description: "RSA private key for JWT token creation. Uses environment-specific private key as default.",
37
- default: getPrivateKeySafe()
38
+ description: "RSA private key for JWT token creation. Uses environment-specific private key as default."
38
39
  }
39
40
  },
40
41
  required: ["productId"]
@@ -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 merchant 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. Once deleted, the deep link URL will no longer redirect to the payware mobile app.
10
12
 
11
13
  **Use Cases:**
@@ -33,8 +35,7 @@ export const deleteTransactionLinkTool = {
33
35
  },
34
36
  privateKey: {
35
37
  type: "string",
36
- description: "RSA private key for JWT token creation. Uses environment-specific private key as default.",
37
- default: getPrivateKeySafe()
38
+ description: "RSA private key for JWT token creation. Uses environment-specific private key as default."
38
39
  }
39
40
  },
40
41
  required: ["transactionId"]