@payware/mcp-server 1.0.0 → 1.1.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/package.json +1 -1
- package/src/isv/data/index.js +23 -0
- package/src/isv/deep-links/delete-product-link.js +1 -1
- package/src/isv/deep-links/delete-transaction-link.js +1 -1
- package/src/isv/deep-links/get-product-link.js +1 -1
- package/src/isv/deep-links/get-transaction-link.js +1 -1
- package/src/isv/index.js +11 -1
- package/src/isv/poi/cancel-price.js +149 -0
- package/src/isv/poi/get-poi.js +190 -0
- package/src/isv/poi/get-qrcode.js +151 -0
- package/src/isv/poi/get-status.js +176 -0
- package/src/isv/poi/index.js +32 -0
- package/src/isv/poi/list-pois.js +168 -0
- package/src/isv/poi/set-price.js +225 -0
- package/src/isv/transactions/get-status.js +1 -1
- package/src/isv/transactions/transaction-history.js +2 -1
- package/src/mcp-proxy.js +2 -2
- package/src/merchant/data/export-report.js +3 -4
- package/src/merchant/data/generate-report.js +3 -4
- package/src/merchant/data/get-export-list.js +140 -0
- package/src/merchant/data/get-report-requests.js +125 -0
- package/src/merchant/data/get-report-status.js +3 -4
- package/src/merchant/data/index.js +64 -25
- package/src/merchant/data/list-reports.js +107 -0
- package/src/merchant/deep-links/delete-product-link.js +1 -1
- package/src/merchant/deep-links/delete-transaction-link.js +1 -1
- package/src/merchant/deep-links/get-product-link.js +1 -1
- package/src/merchant/deep-links/get-transaction-link.js +1 -1
- package/src/merchant/transactions/create-transaction.js +4 -2
- package/src/merchant/transactions/get-status.js +1 -1
- package/src/merchant/transactions/process-transaction.js +10 -1
- package/src/merchant/transactions/simulate-callback.js +11 -2
- package/src/merchant/transactions/transaction-history.js +1 -1
- package/src/payment-institution/data/index.js +23 -0
- package/src/payment-institution/deep-links/delete-transaction-link.js +1 -1
- package/src/payment-institution/deep-links/get-transaction-link.js +1 -1
- package/src/payment-institution/transactions/create-pi-transaction.js +2 -0
- package/src/payment-institution/transactions/finalize-transaction.js +1 -0
- package/src/payment-institution/transactions/get-transaction-history.js +1 -1
- package/src/payment-institution/transactions/get-transaction-status.js +1 -1
- package/src/payment-institution/transactions/process-pi-transaction.js +12 -0
- package/src/payment-institution/transactions/simulate-pi-callback.js +12 -2
- package/src/payment-institution/transactions/soundbite-transaction.js +2 -0
- package/src/shared/data/data-api.js +97 -0
- package/src/utils/code-examples/merchant/transactions.js +2 -1
- package/src/utils/code-examples/payment-institution/transactions.js +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { getExportList } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get export list for request tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const getExportListTool = {
|
|
8
|
+
name: "payware_data_get_export_list",
|
|
9
|
+
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
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
requestId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The request ID (UUID) to get exports for"
|
|
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 production private key as default (Data API is production-only)."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
required: ["requestId"]
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
async handler(args) {
|
|
31
|
+
const {
|
|
32
|
+
requestId,
|
|
33
|
+
partnerId = getPartnerIdSafe(),
|
|
34
|
+
privateKey = getPrivateKeySafe(false) // false = production (Data API is production-only)
|
|
35
|
+
} = args;
|
|
36
|
+
|
|
37
|
+
if (!partnerId || !privateKey) {
|
|
38
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and PAYWARE_PRODUCTION_PRIVATE_KEY_PATH environment variables or provide them as parameters.");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (!requestId) {
|
|
42
|
+
throw new Error("requestId is required (UUID from report generation)");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const result = await getExportList({
|
|
47
|
+
requestId,
|
|
48
|
+
partnerType: 'merchant',
|
|
49
|
+
partnerId,
|
|
50
|
+
privateKey
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const exports = result.data;
|
|
54
|
+
|
|
55
|
+
// Group exports by status
|
|
56
|
+
const byStatus = {
|
|
57
|
+
READY: exports.filter(e => e.exportStatus === 'READY'),
|
|
58
|
+
QUEUED: exports.filter(e => e.exportStatus === 'QUEUED'),
|
|
59
|
+
CANCELLED: exports.filter(e => e.exportStatus === 'CANCELLED'),
|
|
60
|
+
FAILED: exports.filter(e => e.exportStatus === 'FAILED')
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Group by content type
|
|
64
|
+
const byFormat = {};
|
|
65
|
+
exports.forEach(e => {
|
|
66
|
+
const format = e.contentType || 'unknown';
|
|
67
|
+
if (!byFormat[format]) byFormat[format] = [];
|
|
68
|
+
byFormat[format].push(e);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Format export list
|
|
72
|
+
const formatExportList = (exportList) => {
|
|
73
|
+
if (exportList.length === 0) return ' *None*';
|
|
74
|
+
|
|
75
|
+
return exportList.map(e => {
|
|
76
|
+
// Handle both "application/pdf" and "pdf" formats
|
|
77
|
+
let format = 'UNKNOWN';
|
|
78
|
+
if (e.contentType) {
|
|
79
|
+
if (e.contentType.includes('/')) {
|
|
80
|
+
format = e.contentType.split('/')[1].toUpperCase();
|
|
81
|
+
} else {
|
|
82
|
+
format = e.contentType.toUpperCase();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const size = e.pages ? `${e.pages} pages` : 'N/A';
|
|
86
|
+
return ` • Export ID: \`${e.exportId}\`\n - Format: ${format}\n - Size: ${size}\n - File: ${e.fileName || 'N/A'}\n - Updated: ${e.updated}\n - Complete: ${e.outputFinal ? 'Yes' : 'No'}`;
|
|
87
|
+
}).join('\n\n');
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
content: [{
|
|
92
|
+
type: "text",
|
|
93
|
+
text: `📊 **Export List for Request**
|
|
94
|
+
|
|
95
|
+
**Request ID:** ${requestId}
|
|
96
|
+
**Total Exports:** ${exports.length}
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Status Summary
|
|
101
|
+
- ✅ **READY:** ${byStatus.READY.length} (available for download)
|
|
102
|
+
- 🟡 **QUEUED:** ${byStatus.QUEUED.length} (in progress)
|
|
103
|
+
- ❌ **CANCELLED:** ${byStatus.CANCELLED.length}
|
|
104
|
+
- 💥 **FAILED:** ${byStatus.FAILED.length}
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Format Summary
|
|
109
|
+
${Object.keys(byFormat).map(format => `- ${format}: ${byFormat[format].length}`).join('\n')}
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Ready Exports (${byStatus.READY.length})
|
|
114
|
+
${formatExportList(byStatus.READY)}
|
|
115
|
+
|
|
116
|
+
${byStatus.READY.length === 0 ? '\n*No exports ready for download yet. Create a new export with `payware_data_export_report`*' : ''}
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Queued Exports (${byStatus.QUEUED.length})
|
|
121
|
+
${formatExportList(byStatus.QUEUED)}
|
|
122
|
+
|
|
123
|
+
${byStatus.QUEUED.length === 0 ? '\n*No exports currently being processed*' : ''}
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
**Next Steps:**
|
|
128
|
+
- For READY exports, use \`payware_data_download_export\` with the export ID
|
|
129
|
+
- For QUEUED exports, use \`payware_data_get_export_status\` to check progress
|
|
130
|
+
- To create a new export, use \`payware_data_export_report\` with the request ID
|
|
131
|
+
|
|
132
|
+
**⚠️ Production Only:**
|
|
133
|
+
Data reports are only available in the production environment, not in sandbox.`
|
|
134
|
+
}]
|
|
135
|
+
};
|
|
136
|
+
} catch (error) {
|
|
137
|
+
throw new Error(`Failed to get export list: ${error.message}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getReportRequests, REPORT_TYPES } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get report request history tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const getReportRequestsTool = {
|
|
8
|
+
name: "payware_data_get_report_requests",
|
|
9
|
+
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
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
reportId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "The report unit ID (path) to get execution history for (e.g., '/processedTransactions')",
|
|
16
|
+
enum: Object.values(REPORT_TYPES)
|
|
17
|
+
},
|
|
18
|
+
partnerId: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
21
|
+
default: getPartnerIdSafe()
|
|
22
|
+
},
|
|
23
|
+
privateKey: {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "RSA private key for authentication. Uses production private key as default (Data API is production-only)."
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
required: ["reportId"]
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
async handler(args) {
|
|
32
|
+
const {
|
|
33
|
+
reportId,
|
|
34
|
+
partnerId = getPartnerIdSafe(),
|
|
35
|
+
privateKey = getPrivateKeySafe(false) // false = production (Data API is production-only)
|
|
36
|
+
} = args;
|
|
37
|
+
|
|
38
|
+
if (!partnerId || !privateKey) {
|
|
39
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and PAYWARE_PRODUCTION_PRIVATE_KEY_PATH environment variables or provide them as parameters.");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!reportId) {
|
|
43
|
+
throw new Error("reportId is required. Use one of the available report paths (e.g., '/processedTransactions')");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const result = await getReportRequests({
|
|
48
|
+
reportId,
|
|
49
|
+
partnerType: 'merchant',
|
|
50
|
+
partnerId,
|
|
51
|
+
privateKey
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const requests = result.data;
|
|
55
|
+
const reportTypeName = Object.keys(REPORT_TYPES).find(key => REPORT_TYPES[key] === reportId) || reportId;
|
|
56
|
+
|
|
57
|
+
// Group requests by status
|
|
58
|
+
const byStatus = {
|
|
59
|
+
READY: requests.filter(r => r.requestStatus === 'READY'),
|
|
60
|
+
QUEUED: requests.filter(r => r.requestStatus === 'QUEUED'),
|
|
61
|
+
CANCELLED: requests.filter(r => r.requestStatus === 'CANCELLED'),
|
|
62
|
+
FAILED: requests.filter(r => r.requestStatus === 'FAILED')
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Format request list
|
|
66
|
+
const formatRequestList = (requestList) => {
|
|
67
|
+
if (requestList.length === 0) return ' *None*';
|
|
68
|
+
|
|
69
|
+
return requestList.slice(0, 5).map(r => {
|
|
70
|
+
const dateRange = r.dateFrom && r.dateTo
|
|
71
|
+
? `${r.dateFrom} to ${r.dateTo}`
|
|
72
|
+
: 'Default range';
|
|
73
|
+
return ` • Request ID: \`${r.requestId}\`\n - Updated: ${r.updated}\n - Date Range: ${dateRange}\n - Pagination: ${r.ignorePagination ? 'Disabled' : 'Enabled'}`;
|
|
74
|
+
}).join('\n\n');
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const recentRequests = requests.slice(0, 10);
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
content: [{
|
|
81
|
+
type: "text",
|
|
82
|
+
text: `📊 **Report Request History**
|
|
83
|
+
|
|
84
|
+
**Report Type:** ${reportTypeName}
|
|
85
|
+
**Report ID:** ${reportId}
|
|
86
|
+
**Total Requests:** ${requests.length}
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Status Summary
|
|
91
|
+
- ✅ **READY:** ${byStatus.READY.length} (available for export)
|
|
92
|
+
- 🟡 **QUEUED:** ${byStatus.QUEUED.length} (in progress)
|
|
93
|
+
- ❌ **CANCELLED:** ${byStatus.CANCELLED.length}
|
|
94
|
+
- 💥 **FAILED:** ${byStatus.FAILED.length}
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Ready Reports (${byStatus.READY.length})
|
|
99
|
+
${formatRequestList(byStatus.READY)}
|
|
100
|
+
|
|
101
|
+
${byStatus.READY.length > 5 ? `\n*Showing 5 of ${byStatus.READY.length} ready reports*` : ''}
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Queued Reports (${byStatus.QUEUED.length})
|
|
106
|
+
${formatRequestList(byStatus.QUEUED)}
|
|
107
|
+
|
|
108
|
+
${byStatus.QUEUED.length > 5 ? `\n*Showing 5 of ${byStatus.QUEUED.length} queued reports*` : ''}
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
**Next Steps:**
|
|
113
|
+
- For READY reports, use \`payware_data_export_report\` with the request ID
|
|
114
|
+
- For QUEUED reports, use \`payware_data_get_report_status\` to check progress
|
|
115
|
+
- To see exports for a specific request, use \`payware_data_get_export_list\`
|
|
116
|
+
|
|
117
|
+
**⚠️ Production Only:**
|
|
118
|
+
Data reports are only available in the production environment, not in sandbox.`
|
|
119
|
+
}]
|
|
120
|
+
};
|
|
121
|
+
} catch (error) {
|
|
122
|
+
throw new Error(`Failed to get report requests: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
@@ -21,8 +21,7 @@ export const getReportStatusTool = {
|
|
|
21
21
|
},
|
|
22
22
|
privateKey: {
|
|
23
23
|
type: "string",
|
|
24
|
-
description: "RSA private key for authentication. Uses
|
|
25
|
-
default: getPrivateKeySafe()
|
|
24
|
+
description: "RSA private key for authentication. Uses production private key as default (Data API is production-only)."
|
|
26
25
|
}
|
|
27
26
|
},
|
|
28
27
|
required: ["requestId"]
|
|
@@ -32,11 +31,11 @@ export const getReportStatusTool = {
|
|
|
32
31
|
const {
|
|
33
32
|
requestId,
|
|
34
33
|
partnerId = getPartnerIdSafe(),
|
|
35
|
-
privateKey = getPrivateKeySafe()
|
|
34
|
+
privateKey = getPrivateKeySafe(false) // false = production (Data API is production-only)
|
|
36
35
|
} = args;
|
|
37
36
|
|
|
38
37
|
if (!partnerId || !privateKey) {
|
|
39
|
-
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and environment
|
|
38
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and PAYWARE_PRODUCTION_PRIVATE_KEY_PATH environment variables or provide them as parameters.");
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
try {
|
|
@@ -17,6 +17,9 @@ import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
|
17
17
|
import { generateReportTool } from './generate-report.js';
|
|
18
18
|
import { getReportStatusTool } from './get-report-status.js';
|
|
19
19
|
import { exportReportTool } from './export-report.js';
|
|
20
|
+
import { listReportsTool } from './list-reports.js';
|
|
21
|
+
import { getReportRequestsTool } from './get-report-requests.js';
|
|
22
|
+
import { getExportListTool } from './get-export-list.js';
|
|
20
23
|
|
|
21
24
|
/**
|
|
22
25
|
* Get export status tool for merchants
|
|
@@ -122,6 +125,11 @@ export const downloadExportTool = {
|
|
|
122
125
|
type: "string",
|
|
123
126
|
description: "The export ID from the export request (UUID format)"
|
|
124
127
|
},
|
|
128
|
+
saveToFile: {
|
|
129
|
+
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.",
|
|
131
|
+
default: false
|
|
132
|
+
},
|
|
125
133
|
partnerId: {
|
|
126
134
|
type: "string",
|
|
127
135
|
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
@@ -129,8 +137,7 @@ export const downloadExportTool = {
|
|
|
129
137
|
},
|
|
130
138
|
privateKey: {
|
|
131
139
|
type: "string",
|
|
132
|
-
description: "RSA private key for authentication. Uses
|
|
133
|
-
default: getPrivateKeySafe()
|
|
140
|
+
description: "RSA private key for authentication. Uses production private key as default (Data API is production-only)."
|
|
134
141
|
}
|
|
135
142
|
},
|
|
136
143
|
required: ["exportId"]
|
|
@@ -139,12 +146,13 @@ export const downloadExportTool = {
|
|
|
139
146
|
async handler(args) {
|
|
140
147
|
const {
|
|
141
148
|
exportId,
|
|
149
|
+
saveToFile = false,
|
|
142
150
|
partnerId = getPartnerIdSafe(),
|
|
143
|
-
privateKey = getPrivateKeySafe()
|
|
151
|
+
privateKey = getPrivateKeySafe(false) // false = production (Data API is production-only)
|
|
144
152
|
} = args;
|
|
145
153
|
|
|
146
154
|
if (!partnerId || !privateKey) {
|
|
147
|
-
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and environment
|
|
155
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and PAYWARE_PRODUCTION_PRIVATE_KEY_PATH environment variables or provide them as parameters.");
|
|
148
156
|
}
|
|
149
157
|
|
|
150
158
|
try {
|
|
@@ -155,38 +163,66 @@ export const downloadExportTool = {
|
|
|
155
163
|
privateKey
|
|
156
164
|
});
|
|
157
165
|
|
|
158
|
-
// Convert binary data to base64 for display
|
|
159
|
-
const base64Data = Buffer.from(result.data).toString('base64');
|
|
160
166
|
const sizeInKB = Math.round(result.data.length / 1024);
|
|
167
|
+
const contentType = result.contentType || 'unknown';
|
|
168
|
+
const isTextFormat = contentType.includes('csv') || contentType.includes('json') || contentType.includes('text');
|
|
169
|
+
|
|
170
|
+
let savedFileInfo = '';
|
|
171
|
+
let contentPreview = '';
|
|
172
|
+
|
|
173
|
+
if (saveToFile) {
|
|
174
|
+
// Determine file extension from content type
|
|
175
|
+
const extensionMap = {
|
|
176
|
+
'application/pdf': 'pdf',
|
|
177
|
+
'application/vnd.ms-excel': 'xls',
|
|
178
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'xlsx',
|
|
179
|
+
'text/csv': 'csv',
|
|
180
|
+
'application/json': 'json'
|
|
181
|
+
};
|
|
182
|
+
const extension = extensionMap[contentType] || 'bin';
|
|
183
|
+
const filename = `report_${exportId.substring(0, 8)}.${extension}`;
|
|
184
|
+
const filepath = `/mnt/d/git/payware/mcp/downloads/${filename}`;
|
|
185
|
+
|
|
186
|
+
// Save file to downloads directory
|
|
187
|
+
const fs = await import('fs');
|
|
188
|
+
const path = await import('path');
|
|
189
|
+
const downloadDir = path.dirname(filepath);
|
|
190
|
+
|
|
191
|
+
// Create downloads directory if it doesn't exist
|
|
192
|
+
if (!fs.existsSync(downloadDir)) {
|
|
193
|
+
fs.mkdirSync(downloadDir, { recursive: true });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
fs.writeFileSync(filepath, result.data);
|
|
197
|
+
savedFileInfo = `- Saved to: \`${filepath}\`\n- Filename: ${filename}\n`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (isTextFormat) {
|
|
201
|
+
// For text formats, show a preview
|
|
202
|
+
const textContent = Buffer.from(result.data).toString('utf-8');
|
|
203
|
+
const previewLength = saveToFile ? 500 : 2000; // Shorter preview if saved to file
|
|
204
|
+
const preview = textContent.length > previewLength ?
|
|
205
|
+
textContent.substring(0, previewLength) + '\n\n...[truncated' + (saveToFile ? ', see full file]' : ']') :
|
|
206
|
+
textContent;
|
|
207
|
+
contentPreview = `\n**Content Preview:**\n\`\`\`\n${preview}\n\`\`\`\n`;
|
|
208
|
+
} else if (!saveToFile) {
|
|
209
|
+
contentPreview = `\n**File Type:** Binary format (${contentType})\n**Note:** Binary files cannot be displayed as text. Use \`saveToFile: true\` to save the file to disk.\n`;
|
|
210
|
+
}
|
|
161
211
|
|
|
162
212
|
return {
|
|
163
213
|
content: [{
|
|
164
214
|
type: "text",
|
|
165
|
-
text: `📊 **Export
|
|
215
|
+
text: `📊 **Export Downloaded Successfully**
|
|
166
216
|
|
|
167
217
|
**File Information:**
|
|
168
218
|
- Export ID: ${exportId}
|
|
169
219
|
- Content Type: ${result.contentType}
|
|
170
220
|
- File Size: ${sizeInKB} KB (${result.contentLength} bytes)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
\`\`\`
|
|
175
|
-
${base64Data.substring(0, 200)}${base64Data.length > 200 ? '...[truncated]' : ''}
|
|
176
|
-
\`\`\`
|
|
177
|
-
|
|
178
|
-
**Usage Notes:**
|
|
179
|
-
- The file data is provided in Base64 encoding above
|
|
180
|
-
- For CSV/JSON files, you can decode and view the content
|
|
181
|
-
- For binary files (PDF, Excel), save the Base64 data and decode to get the original file
|
|
182
|
-
- Full file size: ${sizeInKB} KB
|
|
183
|
-
|
|
184
|
-
**Next Steps:**
|
|
185
|
-
1. Copy the Base64 data if you need to save the file
|
|
186
|
-
2. For text formats (CSV, JSON), decode Base64 to view content
|
|
187
|
-
3. For binary formats (PDF, Excel), decode and save as appropriate file type
|
|
221
|
+
${savedFileInfo}${contentPreview}
|
|
222
|
+
**Summary:**
|
|
223
|
+
✅ ${saveToFile ? 'File saved to disk and' : 'File'} downloaded successfully
|
|
188
224
|
|
|
189
|
-
**
|
|
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/`'}`
|
|
190
226
|
}]
|
|
191
227
|
};
|
|
192
228
|
} catch (error) {
|
|
@@ -341,9 +377,12 @@ Only exports in QUEUED status can be cancelled. Exports that are already READY,
|
|
|
341
377
|
* All merchant data tools
|
|
342
378
|
*/
|
|
343
379
|
export const merchantDataTools = [
|
|
380
|
+
listReportsTool,
|
|
344
381
|
generateReportTool,
|
|
382
|
+
getReportRequestsTool,
|
|
345
383
|
getReportStatusTool,
|
|
346
384
|
exportReportTool,
|
|
385
|
+
getExportListTool,
|
|
347
386
|
getExportStatusTool,
|
|
348
387
|
downloadExportTool,
|
|
349
388
|
cancelReportTool,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { listReports } from '../../shared/data/data-api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* List all available reports tool for merchants
|
|
6
|
+
*/
|
|
7
|
+
export const listReportsTool = {
|
|
8
|
+
name: "payware_data_list_reports",
|
|
9
|
+
description: "List all available report types with their configurations, descriptions, and visibility settings. Production only - not supported in sandbox.",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: "object",
|
|
12
|
+
properties: {
|
|
13
|
+
partnerId: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
16
|
+
default: getPartnerIdSafe()
|
|
17
|
+
},
|
|
18
|
+
privateKey: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "RSA private key for authentication. Uses production private key as default (Data API is production-only)."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
required: []
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
async handler(args) {
|
|
27
|
+
const {
|
|
28
|
+
partnerId = getPartnerIdSafe(),
|
|
29
|
+
privateKey = getPrivateKeySafe(false) // false = production (Data API is production-only)
|
|
30
|
+
} = args;
|
|
31
|
+
|
|
32
|
+
if (!partnerId || !privateKey) {
|
|
33
|
+
throw new Error("Partner ID and private key are required. Set PAYWARE_PARTNER_ID and PAYWARE_PRODUCTION_PRIVATE_KEY_PATH environment variables or provide them as parameters.");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const result = await listReports({
|
|
38
|
+
partnerType: 'merchant',
|
|
39
|
+
partnerId,
|
|
40
|
+
privateKey
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const reports = result.data;
|
|
44
|
+
const basicReports = reports.filter(r => r.plan === 'BSC');
|
|
45
|
+
const standardReports = reports.filter(r => r.plan === 'STD');
|
|
46
|
+
const premiumReports = reports.filter(r => r.plan === 'PRM');
|
|
47
|
+
const merchantReports = reports.filter(r => r.merchantVisible);
|
|
48
|
+
|
|
49
|
+
// Format report list
|
|
50
|
+
const formatReportList = (reportList) => {
|
|
51
|
+
if (!reportList || reportList.length === 0) {
|
|
52
|
+
return ' (No reports available)';
|
|
53
|
+
}
|
|
54
|
+
return reportList.map(r =>
|
|
55
|
+
` • **${r.name || 'Unnamed Report'}**\n - Path: \`${r.path || 'N/A'}\`\n - Format: ${r.defaultFormat?.toUpperCase() || 'N/A'}\n - Parameters: ${r.parameters ? 'Required' : 'Not required'}\n - Description: ${r.description || 'N/A'}`
|
|
56
|
+
).join('\n\n');
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
content: [{
|
|
61
|
+
type: "text",
|
|
62
|
+
text: `📊 **Available Data Reports**
|
|
63
|
+
|
|
64
|
+
**Total Reports:** ${reports.length}
|
|
65
|
+
**Merchant Accessible:** ${merchantReports.length}
|
|
66
|
+
**Basic Plan:** ${basicReports.length}
|
|
67
|
+
**Standard Plan:** ${standardReports.length}
|
|
68
|
+
**Premium Plan:** ${premiumReports.length}
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Basic Reports (${basicReports.length})
|
|
73
|
+
These reports are available on all plans (Basic, Standard, and Premium) and generally don't require date range parameters.
|
|
74
|
+
|
|
75
|
+
${formatReportList(basicReports)}
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Standard Reports (${standardReports.length})
|
|
80
|
+
These reports are available on Standard and Premium plans and may require date range parameters.
|
|
81
|
+
|
|
82
|
+
${formatReportList(standardReports)}
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Premium Reports (${premiumReports.length})
|
|
87
|
+
These reports require a Premium subscription and typically need date range parameters.
|
|
88
|
+
|
|
89
|
+
${formatReportList(premiumReports)}
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
**How to Use Reports:**
|
|
94
|
+
1. Choose a report from the list above
|
|
95
|
+
2. Use the \`payware_data_generate_report\` tool with the report path
|
|
96
|
+
3. Monitor progress with \`payware_data_get_report_status\`
|
|
97
|
+
4. Export the report with \`payware_data_export_report\`
|
|
98
|
+
|
|
99
|
+
**⚠️ Production Only:**
|
|
100
|
+
Data reports are only available in the production environment, not in sandbox.`
|
|
101
|
+
}]
|
|
102
|
+
};
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw new Error(`Failed to list reports: ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
@@ -75,7 +75,7 @@ export const deleteProductLinkTool = {
|
|
|
75
75
|
**Deletion Details:**
|
|
76
76
|
- Product ID: ${productId}
|
|
77
77
|
- Status: Successfully deleted
|
|
78
|
-
- Link URL: https://
|
|
78
|
+
- Link URL: https://go.payware.eu/${productId} (now inactive)
|
|
79
79
|
|
|
80
80
|
**API Call Details:**
|
|
81
81
|
- Endpoint: DELETE ${result.requestInfo.url}
|
|
@@ -75,7 +75,7 @@ export const deleteTransactionLinkTool = {
|
|
|
75
75
|
**Deletion Details:**
|
|
76
76
|
- Transaction ID: ${transactionId}
|
|
77
77
|
- Status: Successfully deleted
|
|
78
|
-
- Link URL: https://
|
|
78
|
+
- Link URL: https://go.payware.eu/${transactionId} (now inactive)
|
|
79
79
|
|
|
80
80
|
**API Call Details:**
|
|
81
81
|
- Endpoint: DELETE ${result.requestInfo.url}
|
|
@@ -9,7 +9,7 @@ export const getProductLinkTool = {
|
|
|
9
9
|
description: `Get an active deep link for a product. Returns a clickable URL that redirects to the payware mobile app.
|
|
10
10
|
|
|
11
11
|
**Deep Link Format:**
|
|
12
|
-
- Web URL: https://
|
|
12
|
+
- Web URL: https://go.payware.eu/{productId}
|
|
13
13
|
- Mobile Redirect: payware://{productId}
|
|
14
14
|
|
|
15
15
|
**Use Cases:**
|
|
@@ -9,7 +9,7 @@ export const getTransactionLinkTool = {
|
|
|
9
9
|
description: `Get an active deep link for a transaction. Returns a clickable URL that redirects to the payware mobile app.
|
|
10
10
|
|
|
11
11
|
**Deep Link Format:**
|
|
12
|
-
- Web URL: https://
|
|
12
|
+
- Web URL: https://go.payware.eu/{transactionId}
|
|
13
13
|
- Mobile Redirect: payware://{transactionId}
|
|
14
14
|
|
|
15
15
|
**Use Cases:**
|
|
@@ -411,11 +411,13 @@ export const createTransactionTool = {
|
|
|
411
411
|
useSandbox
|
|
412
412
|
});
|
|
413
413
|
|
|
414
|
+
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
415
|
+
|
|
414
416
|
if (result.success) {
|
|
415
417
|
// New transactions are always ACTIVE when created
|
|
416
418
|
const status = result.transaction.status || 'ACTIVE';
|
|
417
419
|
const statusEmoji = '⏳';
|
|
418
|
-
|
|
420
|
+
|
|
419
421
|
return {
|
|
420
422
|
content: [{
|
|
421
423
|
type: "text",
|
|
@@ -450,7 +452,7 @@ ${JSON.stringify(result.transaction, null, 2)}
|
|
|
450
452
|
} else {
|
|
451
453
|
return {
|
|
452
454
|
content: [{
|
|
453
|
-
type: "text",
|
|
455
|
+
type: "text",
|
|
454
456
|
text: `❌ **Transaction Creation Failed**
|
|
455
457
|
|
|
456
458
|
**Error Details:**
|
|
@@ -139,7 +139,7 @@ export const getTransactionStatusTool = {
|
|
|
139
139
|
- ID: ${result.transaction.id || 'N/A'}
|
|
140
140
|
- Type: ${result.transaction.type || 'N/A'}
|
|
141
141
|
- Amount: ${result.transaction.trData ? `${result.transaction.trData.amount} ${result.transaction.trData.currency}` : 'N/A'}
|
|
142
|
-
- Description: ${result.transaction.description || 'N/A'}
|
|
142
|
+
${result.transaction.paymentMethod ? `- Payment Method: ${result.transaction.paymentMethod}\n` : ''}- Description: ${result.transaction.description || 'N/A'}
|
|
143
143
|
- Created: ${result.transaction.createdAt || 'N/A'}
|
|
144
144
|
- Updated: ${result.transaction.updatedAt || 'N/A'}
|
|
145
145
|
|
|
@@ -20,6 +20,7 @@ export async function processTransaction({
|
|
|
20
20
|
callbackUrl,
|
|
21
21
|
passbackParams,
|
|
22
22
|
timeToLive = 120,
|
|
23
|
+
paymentMethod,
|
|
23
24
|
partnerId,
|
|
24
25
|
privateKey,
|
|
25
26
|
useSandbox = true
|
|
@@ -55,6 +56,7 @@ export async function processTransaction({
|
|
|
55
56
|
...(shop && { shop }),
|
|
56
57
|
...(callbackUrl && { callbackUrl }),
|
|
57
58
|
...(passbackParams && { passbackParams }),
|
|
59
|
+
...(paymentMethod && { paymentMethod }),
|
|
58
60
|
trData: {
|
|
59
61
|
amount: amount.toString(),
|
|
60
62
|
currency,
|
|
@@ -201,6 +203,11 @@ export const processTransactionTool = {
|
|
|
201
203
|
maximum: 600,
|
|
202
204
|
default: 120
|
|
203
205
|
},
|
|
206
|
+
paymentMethod: {
|
|
207
|
+
type: "string",
|
|
208
|
+
enum: ["A2A", "CARD_FUNDED", "BNPL", "INSTANT_CREDIT"],
|
|
209
|
+
description: "Payment method chosen by customer. A2A = direct transfer (lower fee, no rewards). CARD_FUNDED = card-linked account (higher fee, rewards eligible). BNPL = buy now pay later (installments). INSTANT_CREDIT = credit line approved at purchase."
|
|
210
|
+
},
|
|
204
211
|
partnerId: {
|
|
205
212
|
type: "string",
|
|
206
213
|
description: "Partner ID from payware dashboard. Can use PAYWARE_PARTNER_ID env var as default.",
|
|
@@ -233,6 +240,7 @@ export const processTransactionTool = {
|
|
|
233
240
|
callbackUrl,
|
|
234
241
|
passbackParams,
|
|
235
242
|
timeToLive = 120,
|
|
243
|
+
paymentMethod,
|
|
236
244
|
partnerId = getPartnerIdSafe(),
|
|
237
245
|
privateKey = getPrivateKeySafe(args.useSandbox ?? true),
|
|
238
246
|
useSandbox = true
|
|
@@ -270,6 +278,7 @@ export const processTransactionTool = {
|
|
|
270
278
|
callbackUrl,
|
|
271
279
|
passbackParams,
|
|
272
280
|
timeToLive,
|
|
281
|
+
paymentMethod,
|
|
273
282
|
partnerId,
|
|
274
283
|
privateKey,
|
|
275
284
|
useSandbox
|
|
@@ -287,7 +296,7 @@ export const processTransactionTool = {
|
|
|
287
296
|
**Transaction Details:**
|
|
288
297
|
- Amount: ${amount} ${currency}
|
|
289
298
|
- Reason: ${reasonL1}${reasonL2 ? ` (${reasonL2})` : ''}
|
|
290
|
-
- Time to Live: ${timeToLive} seconds
|
|
299
|
+
${paymentMethod ? `- Payment Method: ${paymentMethod}\n` : ''}- Time to Live: ${timeToLive} seconds
|
|
291
300
|
${callbackUrl ? `- Callback URL: ${callbackUrl}` : ''}
|
|
292
301
|
${passbackParams ? `- Passback Params: ${passbackParams}` : ''}
|
|
293
302
|
|