@payware/mcp-server 1.1.1 → 1.3.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 (127) hide show
  1. package/.env.example +0 -0
  2. package/README.md +22 -16
  3. package/check-keys.js +0 -0
  4. package/keys/README.md +0 -0
  5. package/mcp-config.json +0 -0
  6. package/package.json +69 -66
  7. package/payware-mcp-config.json +0 -0
  8. package/src/auth/rsa-keys.js +0 -0
  9. package/src/auth/sandbox-setup.js +186 -186
  10. package/src/config/env.js +0 -0
  11. package/src/config/partner-types.js +0 -0
  12. package/src/core/auth/jwt-factory.js +4 -4
  13. package/src/core/auth/jwt-token.js +107 -66
  14. package/src/core/utils/json-serializer.js +5 -5
  15. package/src/core/utils/key-utils.js +0 -0
  16. package/src/index.js +0 -0
  17. package/src/isv/data/index.js +0 -0
  18. package/src/isv/deep-links/delete-product-link.js +0 -0
  19. package/src/isv/deep-links/delete-transaction-link.js +0 -0
  20. package/src/isv/deep-links/get-product-link.js +0 -0
  21. package/src/isv/deep-links/get-transaction-link.js +0 -0
  22. package/src/isv/deep-links/index.js +0 -0
  23. package/src/isv/index.js +29 -1
  24. package/src/isv/invitations/index.js +471 -0
  25. package/src/isv/oauth2/create-token-simple.js +0 -0
  26. package/src/isv/oauth2/get-token-info.js +0 -0
  27. package/src/isv/oauth2/obtain-token.js +19 -8
  28. package/src/isv/oauth2/token-helper.js +5 -2
  29. package/src/isv/poi/cancel-price.js +2 -10
  30. package/src/isv/poi/create.js +19 -0
  31. package/src/isv/poi/get-poi.js +2 -10
  32. package/src/isv/poi/get-qrcode.js +2 -10
  33. package/src/isv/poi/get-status.js +2 -10
  34. package/src/isv/poi/index.js +5 -0
  35. package/src/isv/poi/list-pois.js +2 -10
  36. package/src/isv/poi/set-price.js +217 -225
  37. package/src/isv/products/audios.js +0 -0
  38. package/src/isv/products/create-product.js +313 -313
  39. package/src/isv/products/delete-product.js +0 -0
  40. package/src/isv/products/get-product-image.js +0 -0
  41. package/src/isv/products/get-product.js +0 -0
  42. package/src/isv/products/index.js +0 -0
  43. package/src/isv/products/list-products.js +0 -0
  44. package/src/isv/products/schedules.js +0 -0
  45. package/src/isv/products/update-product.js +264 -264
  46. package/src/isv/reference/index.js +249 -0
  47. package/src/isv/shops/index.js +22 -0
  48. package/src/isv/transactions/cancel-transaction.js +43 -12
  49. package/src/isv/transactions/create-transaction.js +22 -6
  50. package/src/isv/transactions/get-status.js +18 -11
  51. package/src/isv/transactions/process-transaction.js +160 -42
  52. package/src/isv/transactions/simulate-callback.js +128 -109
  53. package/src/isv/transactions/transaction-history.js +86 -90
  54. package/src/isv/utils/auth.js +2 -2
  55. package/src/mcp-proxy.js +0 -0
  56. package/src/merchant/data/export-report.js +0 -0
  57. package/src/merchant/data/generate-report.js +19 -1
  58. package/src/merchant/data/get-export-list.js +0 -0
  59. package/src/merchant/data/get-report-requests.js +0 -0
  60. package/src/merchant/data/get-report-status.js +0 -0
  61. package/src/merchant/data/index.js +0 -0
  62. package/src/merchant/data/list-reports.js +0 -0
  63. package/src/merchant/deep-links/delete-product-link.js +0 -0
  64. package/src/merchant/deep-links/delete-transaction-link.js +0 -0
  65. package/src/merchant/deep-links/get-product-link.js +0 -0
  66. package/src/merchant/deep-links/get-transaction-link.js +0 -0
  67. package/src/merchant/deep-links/index.js +0 -0
  68. package/src/merchant/index.js +21 -1
  69. package/src/merchant/logs/index.js +366 -0
  70. package/src/merchant/products/audios.js +0 -0
  71. package/src/merchant/products/create-product.js +287 -287
  72. package/src/merchant/products/delete-product.js +0 -0
  73. package/src/merchant/products/get-product-image.js +0 -0
  74. package/src/merchant/products/get-product.js +0 -0
  75. package/src/merchant/products/index.js +0 -0
  76. package/src/merchant/products/list-products.js +0 -0
  77. package/src/merchant/products/schedules.js +0 -0
  78. package/src/merchant/products/update-product.js +281 -281
  79. package/src/merchant/shops/index.js +18 -0
  80. package/src/merchant/transactions/cancel-transaction.js +16 -19
  81. package/src/merchant/transactions/create-transaction.js +99 -19
  82. package/src/merchant/transactions/get-status.js +41 -12
  83. package/src/merchant/transactions/process-transaction.js +8 -16
  84. package/src/merchant/transactions/simulate-callback.js +68 -9
  85. package/src/merchant/transactions/transaction-history.js +275 -257
  86. package/src/payment-institution/data/index.js +0 -0
  87. package/src/payment-institution/deep-links/delete-transaction-link.js +0 -0
  88. package/src/payment-institution/deep-links/get-transaction-link.js +0 -0
  89. package/src/payment-institution/deep-links/index.js +0 -0
  90. package/src/payment-institution/index.js +0 -0
  91. package/src/payment-institution/transactions/create-pi-transaction.js +6 -14
  92. package/src/payment-institution/transactions/finalize-transaction.js +333 -340
  93. package/src/payment-institution/transactions/get-transaction-history.js +3 -11
  94. package/src/payment-institution/transactions/get-transaction-status.js +39 -12
  95. package/src/payment-institution/transactions/process-pi-transaction.js +5 -13
  96. package/src/payment-institution/transactions/simulate-pi-callback.js +49 -9
  97. package/src/payment-institution/transactions/soundbite-transaction.js +5 -13
  98. package/src/proxy-server.js +0 -0
  99. package/src/shared/api-errors.js +188 -0
  100. package/src/shared/auth-headers.js +62 -0
  101. package/src/shared/data/data-api.js +11 -10
  102. package/src/shared/deep-links/api.js +5 -4
  103. package/src/shared/index.js +0 -0
  104. package/src/shared/logs/logs-api.js +242 -0
  105. package/src/shared/poi/poi-create-api.js +419 -0
  106. package/src/shared/products/products-api.js +17 -16
  107. package/src/shared/shops/shops-api.js +155 -0
  108. package/src/tools/advanced-code-generator.js +2255 -2246
  109. package/src/utils/code-examples/common/auth-examples.js +1484 -1481
  110. package/src/utils/code-examples/common/helpers.js +7 -4
  111. package/src/utils/code-examples/common/utils-examples.js +0 -0
  112. package/src/utils/code-examples/frameworks/examples.js +4 -4
  113. package/src/utils/code-examples/index.js +0 -0
  114. package/src/utils/code-examples/isv/oauth2.js +458 -600
  115. package/src/utils/code-examples/isv/products.js +8 -8
  116. package/src/utils/code-examples/isv/transactions.js +815 -812
  117. package/src/utils/code-examples/merchant/products.js +0 -0
  118. package/src/utils/code-examples/merchant/transactions.js +9 -9
  119. package/src/utils/code-examples/payment-institution/transactions.js +0 -0
  120. package/src/utils/code-examples/shared/data.js +0 -0
  121. package/src/utils/code-examples/shared/deep-links.js +0 -0
  122. package/src/utils/code-examples/shared/soundbites.js +0 -0
  123. package/src/utils/code-examples.js +24 -24
  124. package/src/utils/format-request.js +3 -3
  125. package/src/utils/json-formatter.js +20 -20
  126. package/src/utils/server-info.js +0 -0
  127. package/MCP-SETUP.md +0 -190
@@ -9,11 +9,14 @@ import { getPOIStatusTool } from './get-status.js';
9
9
  import { setPOIPriceTool } from './set-price.js';
10
10
  import { cancelPOIPriceTool } from './cancel-price.js';
11
11
  import { getPOIQRCodeTool } from './get-qrcode.js';
12
+ import { createPOITool, createPOIBatchTool } from './create.js';
12
13
 
13
14
  /**
14
15
  * All POI tools for ISV
15
16
  */
16
17
  export const isvPOITools = [
18
+ createPOITool,
19
+ createPOIBatchTool,
17
20
  listPOIsTool,
18
21
  getPOITool,
19
22
  getPOIStatusTool,
@@ -23,6 +26,8 @@ export const isvPOITools = [
23
26
  ];
24
27
 
25
28
  export {
29
+ createPOITool,
30
+ createPOIBatchTool,
26
31
  listPOIsTool,
27
32
  getPOITool,
28
33
  getPOIStatusTool,
@@ -1,6 +1,7 @@
1
1
  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
+ import { apiErrorResult } from '../../shared/api-errors.js';
4
5
 
5
6
  /**
6
7
  * List all POIs for a merchant via ISV authentication
@@ -48,16 +49,7 @@ export async function listPOIs({ merchantPartnerId, oauth2Token, useSandbox = tr
48
49
  timestamp: new Date().toISOString()
49
50
  };
50
51
  } catch (error) {
51
- return {
52
- success: false,
53
- error: {
54
- message: error.response?.data?.message || error.message,
55
- status: error.response?.status,
56
- code: error.response?.data?.code,
57
- details: error.response?.data
58
- },
59
- timestamp: new Date().toISOString()
60
- };
52
+ return apiErrorResult(error);
61
53
  }
62
54
  }
63
55
 
@@ -1,225 +1,217 @@
1
- import axios from 'axios';
2
- import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
- import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
-
5
- /**
6
- * Set price on a POI via ISV authentication
7
- * @param {Object} params - Parameters for set price request
8
- * @returns {Object} Set price response
9
- */
10
- export async function setPOIPrice({ poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams, merchantPartnerId, oauth2Token, useSandbox = true }) {
11
- if (!poiId) {
12
- throw new Error('POI ID is required');
13
- }
14
-
15
- if (!amount) {
16
- throw new Error('Amount is required');
17
- }
18
-
19
- if (!currency) {
20
- throw new Error('Currency is required');
21
- }
22
-
23
- if (!reasonL1) {
24
- throw new Error('Reason (reasonL1) is required');
25
- }
26
-
27
- if (!merchantPartnerId) {
28
- throw new Error('Merchant Partner ID is required for ISV operations');
29
- }
30
-
31
- if (!oauth2Token) {
32
- throw new Error('OAuth2 token is required for ISV operations');
33
- }
34
-
35
- const isvPartnerId = getPartnerIdSafe();
36
- const privateKey = getPrivateKeySafe(useSandbox);
37
-
38
- // Build request body
39
- const requestBody = {
40
- amount: String(amount),
41
- currency: currency.toUpperCase(),
42
- reasonL1
43
- };
44
-
45
- if (reasonL2) requestBody.reasonL2 = reasonL2;
46
- if (timeToLive) requestBody.timeToLive = timeToLive;
47
- if (callbackUrl) requestBody.callbackUrl = callbackUrl;
48
- if (passbackParams) requestBody.passbackParams = passbackParams;
49
-
50
- const jwtData = await createJWTForPartner({
51
- partnerId: isvPartnerId,
52
- privateKey,
53
- requestBody,
54
- merchantId: merchantPartnerId,
55
- oauth2Token
56
- });
57
-
58
- const headers = {
59
- 'Authorization': `Bearer ${jwtData.token}`,
60
- 'Content-Type': 'application/json',
61
- 'Api-Version': '1'
62
- };
63
-
64
- try {
65
- const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
66
- const response = await axios.put(`${baseUrl}/poi/${poiId}/price`, requestBody, { headers });
67
-
68
- return {
69
- success: true,
70
- result: response.data,
71
- requestId: response.headers['x-request-id'],
72
- timestamp: new Date().toISOString()
73
- };
74
- } catch (error) {
75
- return {
76
- success: false,
77
- error: {
78
- message: error.response?.data?.message || error.message,
79
- status: error.response?.status,
80
- code: error.response?.data?.code,
81
- details: error.response?.data
82
- },
83
- timestamp: new Date().toISOString()
84
- };
85
- }
86
- }
87
-
88
- /**
89
- * Set POI price tool implementation for ISV
90
- */
91
- export const setPOIPriceTool = {
92
- name: "payware_poi_set_price",
93
- description: `Set a pending price on a POI for customer payment.
94
-
95
- **ISV Authentication:** Uses ISV JWT with merchant partner ID and OAuth2 token.
96
- **Endpoint:** PUT /poi/{poiId}/price
97
- **Use Case:** Set the amount a customer should pay when they scan the POI.
98
-
99
- The POI will transition to READY state and wait for a customer scan until the TTL expires.
100
-
101
- **Required:** POI ID, amount, currency, reason, Merchant Partner ID, and OAuth2 token.`,
102
-
103
- inputSchema: {
104
- type: "object",
105
- required: ["poiId", "amount", "currency", "reasonL1", "merchantPartnerId", "oauth2Token"],
106
- properties: {
107
- poiId: {
108
- type: "string",
109
- description: "The POI identifier (format: pi + 8 alphanumeric chars, e.g., piABC12345)"
110
- },
111
- amount: {
112
- type: "string",
113
- description: "Payment amount (e.g., '25.50')"
114
- },
115
- currency: {
116
- type: "string",
117
- description: "ISO 4217 currency code (e.g., 'EUR', 'USD', 'BGN')"
118
- },
119
- reasonL1: {
120
- type: "string",
121
- description: "Payment description (e.g., 'Table 5', 'Order #123')"
122
- },
123
- reasonL2: {
124
- type: "string",
125
- description: "Additional description (optional)"
126
- },
127
- timeToLive: {
128
- type: "integer",
129
- description: "Seconds until price expires (60-600, default: 120)"
130
- },
131
- callbackUrl: {
132
- type: "string",
133
- description: "Override callback URL for this payment (optional)"
134
- },
135
- passbackParams: {
136
- type: "string",
137
- description: "Data to pass back in callback (optional, max 200 chars)"
138
- },
139
- merchantPartnerId: {
140
- type: "string",
141
- description: "Partner ID of the target merchant (8 alphanumeric characters)"
142
- },
143
- oauth2Token: {
144
- type: "string",
145
- description: "OAuth2 access token obtained from the merchant"
146
- },
147
- useSandbox: {
148
- type: "boolean",
149
- description: "Use sandbox environment for testing",
150
- default: true
151
- }
152
- }
153
- },
154
-
155
- async handler(args) {
156
- const { poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams, merchantPartnerId, oauth2Token, useSandbox = true } = args;
157
-
158
- if (!poiId) throw new Error("POI ID is required");
159
- if (!amount) throw new Error("Amount is required");
160
- if (!currency) throw new Error("Currency is required");
161
- if (!reasonL1) throw new Error("Reason (reasonL1) is required");
162
- if (!merchantPartnerId) throw new Error("Merchant Partner ID is required");
163
- if (!oauth2Token) throw new Error("OAuth2 token is required");
164
-
165
- const result = await setPOIPrice({
166
- poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams,
167
- merchantPartnerId, oauth2Token, useSandbox
168
- });
169
-
170
- if (result.success) {
171
- const data = result.result;
172
-
173
- return {
174
- content: [{
175
- type: "text",
176
- text: `✅ **Price Set Successfully**
177
-
178
- **POI ID:** ${data.poiId || poiId}
179
- **Status:** 🟡 ${data.status || 'READY'}
180
-
181
- **Payment Details:**
182
- - Amount: **${data.amount || amount} ${data.currency || currency}**
183
- - Reason: ${reasonL1}${reasonL2 ? ` - ${reasonL2}` : ''}
184
-
185
- **Session:**
186
- - Token: ${data.sessionToken || 'N/A'}
187
- - Expires: ${data.sessionExpiresAt || 'N/A'}
188
-
189
- **Next Steps:**
190
- 1. Customer scans the POI (QR code, NFC tag, or barcode)
191
- 2. Customer sees the amount and confirms payment
192
- 3. You receive a callback when payment completes
193
-
194
- **ISV -> Merchant:** ${getPartnerIdSafe()} -> ${merchantPartnerId}
195
- **Request ID:** ${result.requestId || 'N/A'}
196
- **Timestamp:** ${result.timestamp}`
197
- }]
198
- };
199
- } else {
200
- return {
201
- content: [{
202
- type: "text",
203
- text: `❌ **Failed to Set Price**
204
-
205
- **POI ID:** ${poiId}
206
- **Attempted:** ${amount} ${currency}
207
-
208
- **Error:** ${result.error.message}
209
- **Code:** ${result.error.code || 'N/A'}
210
- **Status:** ${result.error.status || 'N/A'}
211
-
212
- **Common Issues:**
213
- - INVALID_POI_ID (400): POI ID format invalid (must be pi + 8 alphanumeric chars)
214
- - POI_NOT_FOUND (404): POI doesn't exist or doesn't belong to merchant
215
- - POI_DISABLED (409): POI is disabled
216
- - POI_NOT_IDLE (409): POI already has a pending price (cancel it first)
217
- - INVALID_AMOUNT (400): Check amount format (e.g., '25.50')
218
- - UNKNOWN_CURRENCY (400): Invalid currency code
219
-
220
- **Timestamp:** ${result.timestamp}`
221
- }]
222
- };
223
- }
224
- }
225
- };
1
+ import axios from 'axios';
2
+ import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
3
+ import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
4
+ import { apiErrorResult } from '../../shared/api-errors.js';
5
+
6
+ /**
7
+ * Set price on a POI via ISV authentication
8
+ * @param {Object} params - Parameters for set price request
9
+ * @returns {Object} Set price response
10
+ */
11
+ export async function setPOIPrice({ poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams, merchantPartnerId, oauth2Token, useSandbox = true }) {
12
+ if (!poiId) {
13
+ throw new Error('POI ID is required');
14
+ }
15
+
16
+ if (!amount) {
17
+ throw new Error('Amount is required');
18
+ }
19
+
20
+ if (!currency) {
21
+ throw new Error('Currency is required');
22
+ }
23
+
24
+ if (!reasonL1) {
25
+ throw new Error('Reason (reasonL1) is required');
26
+ }
27
+
28
+ if (!merchantPartnerId) {
29
+ throw new Error('Merchant Partner ID is required for ISV operations');
30
+ }
31
+
32
+ if (!oauth2Token) {
33
+ throw new Error('OAuth2 token is required for ISV operations');
34
+ }
35
+
36
+ const isvPartnerId = getPartnerIdSafe();
37
+ const privateKey = getPrivateKeySafe(useSandbox);
38
+
39
+ // Build request body
40
+ const requestBody = {
41
+ amount: String(amount),
42
+ currency: currency.toUpperCase(),
43
+ reasonL1
44
+ };
45
+
46
+ if (reasonL2) requestBody.reasonL2 = reasonL2;
47
+ if (timeToLive) requestBody.timeToLive = timeToLive;
48
+ if (callbackUrl) requestBody.callbackUrl = callbackUrl;
49
+ if (passbackParams) requestBody.passbackParams = passbackParams;
50
+
51
+ const jwtData = await createJWTForPartner({
52
+ partnerId: isvPartnerId,
53
+ privateKey,
54
+ requestBody,
55
+ merchantId: merchantPartnerId,
56
+ oauth2Token
57
+ });
58
+
59
+ const headers = {
60
+ 'Authorization': `Bearer ${jwtData.token}`,
61
+ 'Content-Type': 'application/json',
62
+ 'Api-Version': '1'
63
+ };
64
+
65
+ try {
66
+ const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
67
+ const response = await axios.put(`${baseUrl}/poi/${poiId}/price`, requestBody, { headers });
68
+
69
+ return {
70
+ success: true,
71
+ result: response.data,
72
+ requestId: response.headers['x-request-id'],
73
+ timestamp: new Date().toISOString()
74
+ };
75
+ } catch (error) {
76
+ return apiErrorResult(error);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Set POI price tool implementation for ISV
82
+ */
83
+ export const setPOIPriceTool = {
84
+ name: "payware_poi_set_price",
85
+ description: `Set a pending price on a POI for customer payment.
86
+
87
+ **ISV Authentication:** Uses ISV JWT with merchant partner ID and OAuth2 token.
88
+ **Endpoint:** PUT /poi/{poiId}/price
89
+ **Use Case:** Set the amount a customer should pay when they scan the POI.
90
+
91
+ The POI will transition to READY state and wait for a customer scan until the TTL expires.
92
+
93
+ **Required:** POI ID, amount, currency, reason, Merchant Partner ID, and OAuth2 token.`,
94
+
95
+ inputSchema: {
96
+ type: "object",
97
+ required: ["poiId", "amount", "currency", "reasonL1", "merchantPartnerId", "oauth2Token"],
98
+ properties: {
99
+ poiId: {
100
+ type: "string",
101
+ description: "The POI identifier (format: pi + 8 alphanumeric chars, e.g., piABC12345)"
102
+ },
103
+ amount: {
104
+ type: "string",
105
+ description: "Payment amount (e.g., '25.50')"
106
+ },
107
+ currency: {
108
+ type: "string",
109
+ description: "ISO 4217 currency code (e.g., 'EUR', 'USD', 'GBP')"
110
+ },
111
+ reasonL1: {
112
+ type: "string",
113
+ description: "Payment description (e.g., 'Table 5', 'Order #123')"
114
+ },
115
+ reasonL2: {
116
+ type: "string",
117
+ description: "Additional description (optional)"
118
+ },
119
+ timeToLive: {
120
+ type: "integer",
121
+ description: "Seconds until price expires (60-600, default: 120)"
122
+ },
123
+ callbackUrl: {
124
+ type: "string",
125
+ description: "Override callback URL for this payment (optional)"
126
+ },
127
+ passbackParams: {
128
+ type: "string",
129
+ description: "Data to pass back in callback (optional, max 200 chars)"
130
+ },
131
+ merchantPartnerId: {
132
+ type: "string",
133
+ description: "Partner ID of the target merchant (8 alphanumeric characters)"
134
+ },
135
+ oauth2Token: {
136
+ type: "string",
137
+ description: "OAuth2 access token obtained from the merchant"
138
+ },
139
+ useSandbox: {
140
+ type: "boolean",
141
+ description: "Use sandbox environment for testing",
142
+ default: true
143
+ }
144
+ }
145
+ },
146
+
147
+ async handler(args) {
148
+ const { poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams, merchantPartnerId, oauth2Token, useSandbox = true } = args;
149
+
150
+ if (!poiId) throw new Error("POI ID is required");
151
+ if (!amount) throw new Error("Amount is required");
152
+ if (!currency) throw new Error("Currency is required");
153
+ if (!reasonL1) throw new Error("Reason (reasonL1) is required");
154
+ if (!merchantPartnerId) throw new Error("Merchant Partner ID is required");
155
+ if (!oauth2Token) throw new Error("OAuth2 token is required");
156
+
157
+ const result = await setPOIPrice({
158
+ poiId, amount, currency, reasonL1, reasonL2, timeToLive, callbackUrl, passbackParams,
159
+ merchantPartnerId, oauth2Token, useSandbox
160
+ });
161
+
162
+ if (result.success) {
163
+ const data = result.result;
164
+
165
+ return {
166
+ content: [{
167
+ type: "text",
168
+ text: `✅ **Price Set Successfully**
169
+
170
+ **POI ID:** ${data.poiId || poiId}
171
+ **Status:** 🟡 ${data.status || 'READY'}
172
+
173
+ **Payment Details:**
174
+ - Amount: **${data.amount || amount} ${data.currency || currency}**
175
+ - Reason: ${reasonL1}${reasonL2 ? ` - ${reasonL2}` : ''}
176
+
177
+ **Session:**
178
+ - Token: ${data.sessionToken || 'N/A'}
179
+ - Expires: ${data.sessionExpiresAt || 'N/A'}
180
+
181
+ **Next Steps:**
182
+ 1. Customer scans the POI (QR code, NFC tag, or barcode)
183
+ 2. Customer sees the amount and confirms payment
184
+ 3. You receive a callback when payment completes
185
+
186
+ **ISV -> Merchant:** ${getPartnerIdSafe()} -> ${merchantPartnerId}
187
+ **Request ID:** ${result.requestId || 'N/A'}
188
+ **Timestamp:** ${result.timestamp}`
189
+ }]
190
+ };
191
+ } else {
192
+ return {
193
+ content: [{
194
+ type: "text",
195
+ text: `❌ **Failed to Set Price**
196
+
197
+ **POI ID:** ${poiId}
198
+ **Attempted:** ${amount} ${currency}
199
+
200
+ **Error:** ${result.error.message}
201
+ **Code:** ${result.error.code || 'N/A'}
202
+ **Status:** ${result.error.status || 'N/A'}
203
+
204
+ **Common Issues:**
205
+ - INVALID_POI_ID (400): POI ID format invalid (must be pi + 8 alphanumeric chars)
206
+ - POI_NOT_FOUND (404): POI doesn't exist or doesn't belong to merchant
207
+ - POI_DISABLED (409): POI is disabled
208
+ - POI_NOT_IDLE (409): POI already has a pending price (cancel it first)
209
+ - INVALID_AMOUNT (400): Check amount format (e.g., '25.50')
210
+ - UNKNOWN_CURRENCY (400): Invalid currency code
211
+
212
+ **Timestamp:** ${result.timestamp}`
213
+ }]
214
+ };
215
+ }
216
+ }
217
+ };
File without changes