@payware/mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +92 -0
- package/MCP-SETUP.md +190 -0
- package/README.md +483 -0
- package/check-keys.js +52 -0
- package/keys/README.md +112 -0
- package/mcp-config.json +9 -0
- package/package.json +66 -0
- package/payware-mcp-config.json +12 -0
- package/src/auth/rsa-keys.js +82 -0
- package/src/auth/sandbox-setup.js +187 -0
- package/src/config/env.js +229 -0
- package/src/config/partner-types.js +143 -0
- package/src/core/auth/jwt-factory.js +182 -0
- package/src/core/auth/jwt-token.js +735 -0
- package/src/core/utils/json-serializer.js +100 -0
- package/src/core/utils/key-utils.js +133 -0
- package/src/index.js +237 -0
- package/src/isv/data/index.js +291 -0
- package/src/isv/deep-links/delete-product-link.js +154 -0
- package/src/isv/deep-links/delete-transaction-link.js +154 -0
- package/src/isv/deep-links/get-product-link.js +167 -0
- package/src/isv/deep-links/get-transaction-link.js +167 -0
- package/src/isv/deep-links/index.js +23 -0
- package/src/isv/index.js +103 -0
- package/src/isv/oauth2/create-token-simple.js +46 -0
- package/src/isv/oauth2/get-token-info.js +157 -0
- package/src/isv/oauth2/obtain-token.js +189 -0
- package/src/isv/oauth2/token-helper.js +151 -0
- package/src/isv/products/audios.js +470 -0
- package/src/isv/products/create-product.js +314 -0
- package/src/isv/products/delete-product.js +119 -0
- package/src/isv/products/get-product-image.js +247 -0
- package/src/isv/products/get-product.js +168 -0
- package/src/isv/products/index.js +65 -0
- package/src/isv/products/list-products.js +136 -0
- package/src/isv/products/schedules.js +522 -0
- package/src/isv/products/update-product.js +265 -0
- package/src/isv/transactions/cancel-transaction.js +129 -0
- package/src/isv/transactions/create-transaction.js +361 -0
- package/src/isv/transactions/get-status.js +217 -0
- package/src/isv/transactions/process-transaction.js +145 -0
- package/src/isv/transactions/simulate-callback.js +146 -0
- package/src/isv/transactions/transaction-history.js +186 -0
- package/src/isv/utils/auth.js +159 -0
- package/src/mcp-proxy.js +150 -0
- package/src/merchant/data/export-report.js +108 -0
- package/src/merchant/data/generate-report.js +151 -0
- package/src/merchant/data/get-report-status.js +120 -0
- package/src/merchant/data/index.js +351 -0
- package/src/merchant/deep-links/delete-product-link.js +121 -0
- package/src/merchant/deep-links/delete-transaction-link.js +121 -0
- package/src/merchant/deep-links/get-product-link.js +134 -0
- package/src/merchant/deep-links/get-transaction-link.js +134 -0
- package/src/merchant/deep-links/index.js +23 -0
- package/src/merchant/index.js +92 -0
- package/src/merchant/products/audios.js +606 -0
- package/src/merchant/products/create-product.js +288 -0
- package/src/merchant/products/delete-product.js +111 -0
- package/src/merchant/products/get-product-image.js +252 -0
- package/src/merchant/products/get-product.js +144 -0
- package/src/merchant/products/index.js +65 -0
- package/src/merchant/products/list-products.js +112 -0
- package/src/merchant/products/schedules.js +646 -0
- package/src/merchant/products/update-product.js +282 -0
- package/src/merchant/transactions/cancel-transaction.js +241 -0
- package/src/merchant/transactions/create-transaction.js +482 -0
- package/src/merchant/transactions/get-status.js +196 -0
- package/src/merchant/transactions/process-transaction.js +349 -0
- package/src/merchant/transactions/simulate-callback.js +246 -0
- package/src/merchant/transactions/transaction-history.js +258 -0
- package/src/payment-institution/data/index.js +280 -0
- package/src/payment-institution/deep-links/delete-transaction-link.js +128 -0
- package/src/payment-institution/deep-links/get-transaction-link.js +141 -0
- package/src/payment-institution/deep-links/index.js +17 -0
- package/src/payment-institution/index.js +92 -0
- package/src/payment-institution/transactions/create-pi-transaction.js +484 -0
- package/src/payment-institution/transactions/finalize-transaction.js +340 -0
- package/src/payment-institution/transactions/get-transaction-history.js +269 -0
- package/src/payment-institution/transactions/get-transaction-status.js +234 -0
- package/src/payment-institution/transactions/process-pi-transaction.js +421 -0
- package/src/payment-institution/transactions/simulate-pi-callback.js +326 -0
- package/src/payment-institution/transactions/soundbite-transaction.js +269 -0
- package/src/proxy-server.js +205 -0
- package/src/shared/data/data-api.js +372 -0
- package/src/shared/deep-links/api.js +214 -0
- package/src/shared/index.js +44 -0
- package/src/shared/products/products-api.js +872 -0
- package/src/tools/advanced-code-generator.js +2247 -0
- package/src/utils/code-examples/common/auth-examples.js +1482 -0
- package/src/utils/code-examples/common/helpers.js +416 -0
- package/src/utils/code-examples/common/utils-examples.js +591 -0
- package/src/utils/code-examples/frameworks/examples.js +859 -0
- package/src/utils/code-examples/index.js +441 -0
- package/src/utils/code-examples/isv/oauth2.js +600 -0
- package/src/utils/code-examples/isv/products.js +666 -0
- package/src/utils/code-examples/isv/transactions.js +813 -0
- package/src/utils/code-examples/merchant/products.js +497 -0
- package/src/utils/code-examples/merchant/transactions.js +623 -0
- package/src/utils/code-examples/payment-institution/transactions.js +388 -0
- package/src/utils/code-examples/shared/data.js +607 -0
- package/src/utils/code-examples/shared/deep-links.js +662 -0
- package/src/utils/code-examples/shared/soundbites.js +808 -0
- package/src/utils/code-examples.js +646 -0
- package/src/utils/format-request.js +363 -0
- package/src/utils/json-formatter.js +249 -0
- package/src/utils/server-info.js +132 -0
package/src/mcp-proxy.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP-to-HTTP Bridge for payware MCP Server
|
|
5
|
+
* Provides proper MCP transport (stdio) that bridges to HTTP endpoints
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
9
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
10
|
+
import './config/env.js'; // Load environment variables
|
|
11
|
+
import {
|
|
12
|
+
CallToolRequestSchema,
|
|
13
|
+
ListToolsRequestSchema,
|
|
14
|
+
ErrorCode,
|
|
15
|
+
McpError
|
|
16
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
17
|
+
import axios from 'axios';
|
|
18
|
+
|
|
19
|
+
class PaywareMCPBridge {
|
|
20
|
+
constructor(httpServerUrl = 'http://localhost:3001') {
|
|
21
|
+
this.httpServerUrl = httpServerUrl;
|
|
22
|
+
this.server = new Server(
|
|
23
|
+
{
|
|
24
|
+
name: 'payware-mcp-bridge',
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
capabilities: {
|
|
29
|
+
tools: {},
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
this.setupToolHandlers();
|
|
35
|
+
this.setupErrorHandling();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setupToolHandlers() {
|
|
39
|
+
// List tools handler - proxy to HTTP server
|
|
40
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
41
|
+
try {
|
|
42
|
+
const response = await axios.get(`${this.httpServerUrl}/tools`, {
|
|
43
|
+
timeout: 5000
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (response.data && response.data.result && response.data.result.tools) {
|
|
47
|
+
return { tools: response.data.result.tools };
|
|
48
|
+
} else {
|
|
49
|
+
throw new Error('Invalid response format from HTTP server');
|
|
50
|
+
}
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw new McpError(
|
|
53
|
+
ErrorCode.InternalError,
|
|
54
|
+
`Failed to list tools from HTTP server: ${error.message}`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Call tool handler - proxy to HTTP server
|
|
60
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
61
|
+
const { name, arguments: args } = request.params;
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
const response = await axios.post(`${this.httpServerUrl}/tools/${name}`, args || {}, {
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
timeout: 30000
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Handle both direct result and JSON-RPC wrapped responses
|
|
70
|
+
if (response.data && response.data.result) {
|
|
71
|
+
return response.data.result;
|
|
72
|
+
} else if (response.data && !response.data.error) {
|
|
73
|
+
// Direct response without JSON-RPC wrapper
|
|
74
|
+
return response.data;
|
|
75
|
+
} else if (response.data && response.data.error) {
|
|
76
|
+
// JSON-RPC error response - preserve the original error message
|
|
77
|
+
const errorMessage = response.data.error.message || 'Tool execution failed';
|
|
78
|
+
console.error(`[Bridge] HTTP proxy returned error: ${errorMessage}`);
|
|
79
|
+
throw new Error(errorMessage);
|
|
80
|
+
} else {
|
|
81
|
+
throw new Error('Invalid response format from HTTP server');
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error.response) {
|
|
85
|
+
// HTTP error response
|
|
86
|
+
const errorMsg = error.response.data?.message || error.response.statusText || 'HTTP request failed';
|
|
87
|
+
throw new McpError(
|
|
88
|
+
ErrorCode.InternalError,
|
|
89
|
+
`Tool execution failed: ${errorMsg}`
|
|
90
|
+
);
|
|
91
|
+
} else if (error.request) {
|
|
92
|
+
// Network error
|
|
93
|
+
throw new McpError(
|
|
94
|
+
ErrorCode.InternalError,
|
|
95
|
+
`Network error: Failed to connect to HTTP server at ${this.httpServerUrl}`
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
// Other error
|
|
99
|
+
throw new McpError(
|
|
100
|
+
ErrorCode.InternalError,
|
|
101
|
+
`Unexpected error: ${error.message}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
setupErrorHandling() {
|
|
109
|
+
this.server.onerror = (error) => {
|
|
110
|
+
console.error('MCP Bridge error:', error);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
process.on('SIGINT', async () => {
|
|
114
|
+
console.log('\nShutting down MCP Bridge...');
|
|
115
|
+
await this.server.close();
|
|
116
|
+
process.exit(0);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
process.on('SIGTERM', async () => {
|
|
120
|
+
console.log('\nShutting down MCP Bridge...');
|
|
121
|
+
await this.server.close();
|
|
122
|
+
process.exit(0);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async run() {
|
|
127
|
+
// Test connection to HTTP server first
|
|
128
|
+
try {
|
|
129
|
+
const response = await axios.get(`${this.httpServerUrl}/health`, { timeout: 5000 });
|
|
130
|
+
console.error(`✅ Connected to HTTP server: ${response.data.service} v${response.data.version}`);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error(`❌ Failed to connect to HTTP server at ${this.httpServerUrl}`);
|
|
133
|
+
console.error('Make sure the HTTP proxy server is running with: npm run proxy');
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const transport = new StdioServerTransport();
|
|
138
|
+
await this.server.connect(transport);
|
|
139
|
+
console.error('🔗 MCP Bridge ready - connected to payware HTTP proxy');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Start the bridge
|
|
144
|
+
const httpServerUrl = process.env.HTTP_SERVER_URL || 'http://localhost:3001';
|
|
145
|
+
const bridge = new PaywareMCPBridge(httpServerUrl);
|
|
146
|
+
|
|
147
|
+
bridge.run().catch(error => {
|
|
148
|
+
console.error('❌ Failed to start MCP Bridge:', error.message);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { exportReport, EXPORT_FORMATS } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Export report tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const exportReportTool = {
|
|
8
|
+
name: "payware_data_export_report",
|
|
9
|
+
description: "Export a READY report in a specific format (PDF, CSV, Excel, JSON). The report must be in READY status first.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
requestId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The request ID from the report generation (UUID format)"
|
|
16
|
+
},
|
|
17
|
+
outputFormat: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Export format",
|
|
20
|
+
enum: Object.values(EXPORT_FORMATS),
|
|
21
|
+
default: EXPORT_FORMATS.PDF
|
|
22
|
+
},
|
|
23
|
+
partnerId: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
26
|
+
default: getPartnerIdSafe()
|
|
27
|
+
},
|
|
28
|
+
privateKey: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "RSA private key for authentication. Uses environment-specific private key as default.",
|
|
31
|
+
default: getPrivateKeySafe()
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
required: ["requestId"]
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
async handler(args) {
|
|
38
|
+
const {
|
|
39
|
+
requestId,
|
|
40
|
+
outputFormat = EXPORT_FORMATS.PDF,
|
|
41
|
+
partnerId = getPartnerIdSafe(),
|
|
42
|
+
privateKey = getPrivateKeySafe()
|
|
43
|
+
} = args;
|
|
44
|
+
|
|
45
|
+
if (!partnerId || !privateKey) {
|
|
46
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and environment-specific private key variables or provide them as parameters.");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const result = await exportReport({
|
|
51
|
+
requestId,
|
|
52
|
+
outputFormat,
|
|
53
|
+
partnerType: 'merchant',
|
|
54
|
+
partnerId,
|
|
55
|
+
privateKey
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const data = result.data;
|
|
59
|
+
|
|
60
|
+
// The export API returns export details in an outputResource object
|
|
61
|
+
if (!data.outputResource || !data.outputResource.exportId) {
|
|
62
|
+
throw new Error(`Export ID not found in response. Response: ${JSON.stringify(data)}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const exportResource = data.outputResource;
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
content: [{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `📊 **Report Export Started**
|
|
71
|
+
|
|
72
|
+
**Export Details:**
|
|
73
|
+
- Request ID: ${data.requestId || requestId}
|
|
74
|
+
- Export ID: ${exportResource.exportId}
|
|
75
|
+
- Format: ${outputFormat.toUpperCase()}
|
|
76
|
+
- Status: ${exportResource.status || 'QUEUED'}
|
|
77
|
+
- Export Started: ${exportResource.exportedAt || 'Just now'}
|
|
78
|
+
|
|
79
|
+
**Report Information:**
|
|
80
|
+
- Report Type: ${data.reportUnitId || 'N/A'}
|
|
81
|
+
- Date Range: ${data.dateFrom || 'Default'} to ${data.dateTo || 'Default'}
|
|
82
|
+
- Timezone: ${data.timeZone || 'N/A'}
|
|
83
|
+
|
|
84
|
+
**Next Steps:**
|
|
85
|
+
1. Save the Export ID: \`${exportResource.exportId}\`
|
|
86
|
+
2. Use "Get Export Status" tool to monitor export progress
|
|
87
|
+
3. When export status is "READY", use "Download Export" tool to get the file
|
|
88
|
+
|
|
89
|
+
**Available Export Formats:**
|
|
90
|
+
- **PDF**: ${EXPORT_FORMATS.PDF} - Formatted reports with charts and styling
|
|
91
|
+
- **CSV**: ${EXPORT_FORMATS.CSV} - Comma-separated values for data analysis
|
|
92
|
+
- **Excel**: ${EXPORT_FORMATS.EXCEL} - Microsoft Excel format
|
|
93
|
+
- **JSON**: ${EXPORT_FORMATS.JSON} - Structured data format
|
|
94
|
+
|
|
95
|
+
**Export Status Meanings:**
|
|
96
|
+
- 🟡 **QUEUED**: Export is waiting to be processed
|
|
97
|
+
- ✅ **READY**: Export completed and ready for download
|
|
98
|
+
- ❌ **CANCELLED**: Export was cancelled
|
|
99
|
+
- 💥 **FAILED**: Error occurred during export
|
|
100
|
+
|
|
101
|
+
Monitor the export progress using Export ID: \`${exportResource.exportId}\``
|
|
102
|
+
}]
|
|
103
|
+
};
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error(`Failed to export report: ${error.message}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { generateReport, REPORT_TYPES, LOCALES } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate report tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const generateReportTool = {
|
|
8
|
+
name: "payware_data_generate_report",
|
|
9
|
+
description: "Generate an asynchronous data report for merchant data analysis and reporting. Production only - not supported in sandbox.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
reportUnitId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The ID of the report to generate",
|
|
16
|
+
enum: Object.values(REPORT_TYPES),
|
|
17
|
+
default: REPORT_TYPES.PROCESSED_TRANSACTIONS
|
|
18
|
+
},
|
|
19
|
+
dateFrom: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "Start date for the reporting period (YYYY-MM-DD format). Required for premium reports.",
|
|
22
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
23
|
+
},
|
|
24
|
+
dateTo: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "End date for the reporting period (YYYY-MM-DD format). Required for premium reports.",
|
|
27
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
|
|
28
|
+
},
|
|
29
|
+
ignorePagination: {
|
|
30
|
+
type: "boolean",
|
|
31
|
+
description: "If true, return report as single continuous document. If false, paginate results.",
|
|
32
|
+
default: false
|
|
33
|
+
},
|
|
34
|
+
locale: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Locale for the report",
|
|
37
|
+
enum: Object.values(LOCALES),
|
|
38
|
+
default: LOCALES.ENGLISH_US
|
|
39
|
+
},
|
|
40
|
+
timeZone: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "Timezone for date calculations (e.g., 'Europe/Sofia', 'America/New_York')",
|
|
43
|
+
default: "GMT"
|
|
44
|
+
},
|
|
45
|
+
partnerId: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
48
|
+
default: getPartnerIdSafe()
|
|
49
|
+
},
|
|
50
|
+
privateKey: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "RSA private key for authentication. Uses environment-specific private key as default.",
|
|
53
|
+
default: getPrivateKeySafe()
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
required: ["reportUnitId"]
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async handler(args) {
|
|
60
|
+
const {
|
|
61
|
+
reportUnitId,
|
|
62
|
+
dateFrom,
|
|
63
|
+
dateTo,
|
|
64
|
+
ignorePagination = false,
|
|
65
|
+
locale = LOCALES.ENGLISH_US,
|
|
66
|
+
timeZone = 'GMT',
|
|
67
|
+
partnerId = getPartnerIdSafe(),
|
|
68
|
+
privateKey = getPrivateKeySafe()
|
|
69
|
+
} = args;
|
|
70
|
+
|
|
71
|
+
if (!partnerId || !privateKey) {
|
|
72
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and environment-specific private key variables or provide them as parameters.");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Check for required date range on premium reports
|
|
76
|
+
const premiumReports = [
|
|
77
|
+
REPORT_TYPES.PROCESSED_TRANSACTIONS,
|
|
78
|
+
REPORT_TYPES.SCHEDULES_LIST,
|
|
79
|
+
REPORT_TYPES.TRANSACTIONS_PER_PRODUCT,
|
|
80
|
+
REPORT_TYPES.SALES_PER_PRODUCT,
|
|
81
|
+
REPORT_TYPES.TRANSACTIONS_PER_WEBPOS
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
if (premiumReports.includes(reportUnitId) && (!dateFrom || !dateTo)) {
|
|
85
|
+
throw new Error(`Report "${reportUnitId}" requires dateFrom and dateTo parameters (YYYY-MM-DD format)`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await generateReport({
|
|
90
|
+
reportUnitId,
|
|
91
|
+
dateFrom,
|
|
92
|
+
dateTo,
|
|
93
|
+
ignorePagination,
|
|
94
|
+
locale,
|
|
95
|
+
timeZone,
|
|
96
|
+
partnerType: 'merchant',
|
|
97
|
+
partnerId,
|
|
98
|
+
privateKey
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const reportType = Object.keys(REPORT_TYPES).find(key => REPORT_TYPES[key] === reportUnitId) || reportUnitId;
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
content: [{
|
|
105
|
+
type: "text",
|
|
106
|
+
text: `📊 **Data Report Generation Started**
|
|
107
|
+
|
|
108
|
+
**Report Details:**
|
|
109
|
+
- Type: ${reportType}
|
|
110
|
+
- Report Unit ID: ${reportUnitId}
|
|
111
|
+
- Request ID: ${result.data.requestId}
|
|
112
|
+
- Status: ${result.data.status}
|
|
113
|
+
- Generated: ${result.data.generatedAt}
|
|
114
|
+
|
|
115
|
+
**Report Parameters:**
|
|
116
|
+
- Date Range: ${dateFrom || 'Default'} to ${dateTo || 'Default'}
|
|
117
|
+
- Timezone: ${timeZone}
|
|
118
|
+
- Locale: ${locale}
|
|
119
|
+
- Pagination: ${ignorePagination ? 'Disabled (single document)' : 'Enabled'}
|
|
120
|
+
|
|
121
|
+
**Next Steps:**
|
|
122
|
+
1. Save the Request ID: \`${result.data.requestId}\`
|
|
123
|
+
2. Use "Get Report Status" tool to monitor progress
|
|
124
|
+
3. When status is "READY", use "Export Report" tool to get the data
|
|
125
|
+
|
|
126
|
+
**Available Report Types:**
|
|
127
|
+
- **Standard Reports** (no date range required):
|
|
128
|
+
- Current Week Transactions: ${REPORT_TYPES.CURRENT_WEEK_TRANSACTIONS}
|
|
129
|
+
- Current Month Transactions: ${REPORT_TYPES.CURRENT_MONTH_TRANSACTIONS}
|
|
130
|
+
- Current Year Transactions: ${REPORT_TYPES.CURRENT_YEAR_TRANSACTIONS}
|
|
131
|
+
- Products List: ${REPORT_TYPES.PRODUCTS_LIST}
|
|
132
|
+
- Shops List: ${REPORT_TYPES.SHOPS_LIST}
|
|
133
|
+
- Payment Profiles: ${REPORT_TYPES.PAYMENT_PROFILES}
|
|
134
|
+
- Partner Profile: ${REPORT_TYPES.PARTNER_PROFILE}
|
|
135
|
+
|
|
136
|
+
- **Premium Reports** (date range required):
|
|
137
|
+
- Processed Transactions: ${REPORT_TYPES.PROCESSED_TRANSACTIONS}
|
|
138
|
+
- Schedules List: ${REPORT_TYPES.SCHEDULES_LIST}
|
|
139
|
+
- Transactions per Product: ${REPORT_TYPES.TRANSACTIONS_PER_PRODUCT}
|
|
140
|
+
- Sales per Product: ${REPORT_TYPES.SALES_PER_PRODUCT}
|
|
141
|
+
- Transactions per WebPOS: ${REPORT_TYPES.TRANSACTIONS_PER_WEBPOS}
|
|
142
|
+
|
|
143
|
+
**⚠️ Production Only:**
|
|
144
|
+
This feature is only available in the production environment, not in sandbox.`
|
|
145
|
+
}]
|
|
146
|
+
};
|
|
147
|
+
} catch (error) {
|
|
148
|
+
throw new Error(`Failed to generate report: ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { getReportStatus } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get report status tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const getReportStatusTool = {
|
|
8
|
+
name: "payware_data_get_report_status",
|
|
9
|
+
description: "Get the status of an asynchronous report generation request. Use this to monitor report progress.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
requestId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The request ID returned from the report generation request (UUID format)"
|
|
16
|
+
},
|
|
17
|
+
partnerId: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
20
|
+
default: getPartnerIdSafe()
|
|
21
|
+
},
|
|
22
|
+
privateKey: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "RSA private key for authentication. Uses environment-specific private key as default.",
|
|
25
|
+
default: getPrivateKeySafe()
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
required: ["requestId"]
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
async handler(args) {
|
|
32
|
+
const {
|
|
33
|
+
requestId,
|
|
34
|
+
partnerId = getPartnerIdSafe(),
|
|
35
|
+
privateKey = getPrivateKeySafe()
|
|
36
|
+
} = args;
|
|
37
|
+
|
|
38
|
+
if (!partnerId || !privateKey) {
|
|
39
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and environment-specific private key variables or provide them as parameters.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const result = await getReportStatus({
|
|
44
|
+
requestId,
|
|
45
|
+
partnerType: 'merchant',
|
|
46
|
+
partnerId,
|
|
47
|
+
privateKey
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const data = result.data;
|
|
51
|
+
const statusEmoji = {
|
|
52
|
+
'QUEUED': '⏳',
|
|
53
|
+
'READY': '✅',
|
|
54
|
+
'CANCELLED': '❌',
|
|
55
|
+
'FAILED': '💥'
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let nextSteps = '';
|
|
59
|
+
if (data.status === 'READY') {
|
|
60
|
+
nextSteps = `
|
|
61
|
+
**🎉 Report is Ready!**
|
|
62
|
+
Use the "Export Report" tool with request ID: \`${requestId}\`
|
|
63
|
+
Available formats: PDF, CSV, Excel, JSON`;
|
|
64
|
+
} else if (data.status === 'QUEUED') {
|
|
65
|
+
nextSteps = `
|
|
66
|
+
**⏳ Report is Processing**
|
|
67
|
+
Check status again in a few moments using the same request ID.`;
|
|
68
|
+
} else if (data.status === 'FAILED') {
|
|
69
|
+
nextSteps = `
|
|
70
|
+
**💥 Report Failed**
|
|
71
|
+
You may need to generate a new report with different parameters.`;
|
|
72
|
+
} else if (data.status === 'CANCELLED') {
|
|
73
|
+
nextSteps = `
|
|
74
|
+
**❌ Report was Cancelled**
|
|
75
|
+
Generate a new report if needed.`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let outputResourcesInfo = '';
|
|
79
|
+
if (data.outputResources && data.outputResources.length > 0) {
|
|
80
|
+
outputResourcesInfo = `
|
|
81
|
+
**Export Resources:**
|
|
82
|
+
${data.outputResources.map(resource =>
|
|
83
|
+
`- Export ID: ${resource.exportId}
|
|
84
|
+
- Format: ${resource.contentType}
|
|
85
|
+
- Status: ${statusEmoji[resource.status] || '❓'} ${resource.status}
|
|
86
|
+
- Pages: ${resource.pages || 'N/A'}
|
|
87
|
+
- Completed: ${resource.outputFinal ? 'Yes' : 'No'}`
|
|
88
|
+
).join('\n')}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
content: [{
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `📊 **Report Status Check**
|
|
95
|
+
|
|
96
|
+
**Report Information:**
|
|
97
|
+
- Request ID: ${data.requestId}
|
|
98
|
+
- Report Type: ${data.reportUnitId}
|
|
99
|
+
- Status: ${statusEmoji[data.status] || '❓'} ${data.status}
|
|
100
|
+
- Generated: ${data.generatedAt}
|
|
101
|
+
|
|
102
|
+
**Report Parameters:**
|
|
103
|
+
- Date Range: ${data.dateFrom || 'Default'} to ${data.dateTo || 'Default'}
|
|
104
|
+
- Timezone: ${data.timeZone}
|
|
105
|
+
- Pagination: ${data.ignorePagination ? 'Disabled' : 'Enabled'}
|
|
106
|
+
${outputResourcesInfo}
|
|
107
|
+
${nextSteps}
|
|
108
|
+
|
|
109
|
+
**Status Meanings:**
|
|
110
|
+
- 🟡 **QUEUED**: Report is waiting to be processed
|
|
111
|
+
- ✅ **READY**: Report completed and available for export
|
|
112
|
+
- ❌ **CANCELLED**: Report was cancelled by user
|
|
113
|
+
- 💥 **FAILED**: Error occurred during report generation`
|
|
114
|
+
}]
|
|
115
|
+
};
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw new Error(`Failed to get report status: ${error.message}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
};
|