@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
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HTTP Proxy Server for payware MCP
|
|
5
|
+
* Provides HTTP/REST interface to the MCP server for external access
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import express from 'express';
|
|
9
|
+
import cors from 'cors';
|
|
10
|
+
import { spawn } from 'child_process';
|
|
11
|
+
import './config/env.js'; // Load environment variables
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import { dirname, join } from 'path';
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = dirname(__filename);
|
|
17
|
+
|
|
18
|
+
class PaywareMCPProxy {
|
|
19
|
+
constructor(port = 3001) {
|
|
20
|
+
this.app = express();
|
|
21
|
+
this.port = port;
|
|
22
|
+
this.mcpProcess = null;
|
|
23
|
+
this.setupMiddleware();
|
|
24
|
+
this.setupRoutes();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setupMiddleware() {
|
|
28
|
+
// Enable CORS for all routes
|
|
29
|
+
this.app.use(cors({
|
|
30
|
+
origin: true,
|
|
31
|
+
credentials: true
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
// Parse JSON requests
|
|
35
|
+
this.app.use(express.json());
|
|
36
|
+
|
|
37
|
+
// Add request logging
|
|
38
|
+
this.app.use((req, res, next) => {
|
|
39
|
+
console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
|
|
40
|
+
next();
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setupRoutes() {
|
|
45
|
+
// Health check endpoint
|
|
46
|
+
this.app.get('/health', (req, res) => {
|
|
47
|
+
res.json({
|
|
48
|
+
status: 'healthy',
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
service: 'payware-mcp-proxy',
|
|
51
|
+
version: '1.0.0'
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// List available tools
|
|
56
|
+
this.app.get('/tools', async (req, res) => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await this.callMCPTool('tools/list', {});
|
|
59
|
+
res.json(result);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
res.status(500).json({
|
|
62
|
+
error: 'Failed to list tools',
|
|
63
|
+
message: error.message
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Call a specific tool
|
|
69
|
+
this.app.post('/tools/:toolName', async (req, res) => {
|
|
70
|
+
try {
|
|
71
|
+
const { toolName } = req.params;
|
|
72
|
+
const args = req.body || {};
|
|
73
|
+
|
|
74
|
+
const result = await this.callMCPTool('tools/call', {
|
|
75
|
+
name: toolName,
|
|
76
|
+
arguments: args
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
res.json(result);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
res.status(500).json({
|
|
82
|
+
error: `Failed to call tool ${req.params.toolName}`,
|
|
83
|
+
message: error.message
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Generic MCP endpoint
|
|
89
|
+
this.app.post('/mcp', async (req, res) => {
|
|
90
|
+
try {
|
|
91
|
+
const { method, params } = req.body;
|
|
92
|
+
const result = await this.callMCPTool(method, params);
|
|
93
|
+
res.json(result);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
res.status(500).json({
|
|
96
|
+
error: 'MCP call failed',
|
|
97
|
+
message: error.message
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Serve API documentation
|
|
103
|
+
this.app.get('/', (req, res) => {
|
|
104
|
+
res.json({
|
|
105
|
+
name: 'payware MCP Proxy',
|
|
106
|
+
version: '1.0.0',
|
|
107
|
+
endpoints: {
|
|
108
|
+
'GET /health': 'Health check',
|
|
109
|
+
'GET /tools': 'List available MCP tools',
|
|
110
|
+
'POST /tools/:toolName': 'Call a specific tool',
|
|
111
|
+
'POST /mcp': 'Generic MCP method call'
|
|
112
|
+
},
|
|
113
|
+
examples: {
|
|
114
|
+
listTools: 'GET /tools',
|
|
115
|
+
generateKeys: 'POST /tools/generate_rsa_keys',
|
|
116
|
+
createJWT: 'POST /tools/create_jwt_token'
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async callMCPTool(method, params = {}) {
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
const mcpServerPath = join(__dirname, 'index.js');
|
|
125
|
+
const mcpProcess = spawn('node', [mcpServerPath], {
|
|
126
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
127
|
+
env: process.env // Pass environment variables to spawned process
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
let responseData = '';
|
|
131
|
+
let errorData = '';
|
|
132
|
+
|
|
133
|
+
const request = {
|
|
134
|
+
jsonrpc: '2.0',
|
|
135
|
+
id: Date.now(),
|
|
136
|
+
method,
|
|
137
|
+
params
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
mcpProcess.stdout.on('data', (data) => {
|
|
141
|
+
responseData += data.toString();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
mcpProcess.stderr.on('data', (data) => {
|
|
145
|
+
errorData += data.toString();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
mcpProcess.on('close', (code) => {
|
|
149
|
+
if (code === 0) {
|
|
150
|
+
try {
|
|
151
|
+
// Parse the last valid JSON response
|
|
152
|
+
const lines = responseData.trim().split('\n');
|
|
153
|
+
const lastLine = lines[lines.length - 1];
|
|
154
|
+
const result = JSON.parse(lastLine);
|
|
155
|
+
resolve(result);
|
|
156
|
+
} catch (parseError) {
|
|
157
|
+
reject(new Error(`Failed to parse MCP response: ${parseError.message}`));
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
reject(new Error(`MCP process failed with code ${code}: ${errorData}`));
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Send the request to the MCP server
|
|
165
|
+
mcpProcess.stdin.write(JSON.stringify(request) + '\n');
|
|
166
|
+
mcpProcess.stdin.end();
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async start() {
|
|
171
|
+
this.app.listen(this.port, '0.0.0.0', () => {
|
|
172
|
+
console.log(`🚀 payware MCP Proxy Server running on http://0.0.0.0:${this.port}`);
|
|
173
|
+
console.log(`📚 API Documentation: http://localhost:${this.port}`);
|
|
174
|
+
console.log(`🔧 Health Check: http://localhost:${this.port}/health`);
|
|
175
|
+
console.log(`🛠️ Tools List: http://localhost:${this.port}/tools`);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async stop() {
|
|
180
|
+
if (this.mcpProcess) {
|
|
181
|
+
this.mcpProcess.kill();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Handle graceful shutdown
|
|
187
|
+
process.on('SIGINT', async () => {
|
|
188
|
+
console.log('\n🛑 Shutting down proxy server...');
|
|
189
|
+
process.exit(0);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
process.on('SIGTERM', async () => {
|
|
193
|
+
console.log('\n🛑 Shutting down proxy server...');
|
|
194
|
+
process.exit(0);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Start the proxy server
|
|
198
|
+
const port = process.env.PROXY_PORT || 3001;
|
|
199
|
+
const proxy = new PaywareMCPProxy(port);
|
|
200
|
+
proxy.start().catch(error => {
|
|
201
|
+
console.error('❌ Failed to start proxy server:', error);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
export default PaywareMCPProxy;
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { createJWTToken } from '../../core/auth/jwt-token.js';
|
|
3
|
+
import { createJWTForPartner } from '../../core/auth/jwt-factory.js';
|
|
4
|
+
import { createMinimizedJSON } from '../../core/utils/json-serializer.js';
|
|
5
|
+
import { getSandboxUrl, getProductionUrl, getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Available report types from the Data API documentation
|
|
9
|
+
*/
|
|
10
|
+
export const REPORT_TYPES = {
|
|
11
|
+
// Standard reports
|
|
12
|
+
CURRENT_WEEK_TRANSACTIONS: '/processedTransactionsWTD',
|
|
13
|
+
CURRENT_MONTH_TRANSACTIONS: '/processedTransactionsMTD',
|
|
14
|
+
CURRENT_YEAR_TRANSACTIONS: '/processedTransactionsYTD',
|
|
15
|
+
PRODUCTS_LIST: '/productsList',
|
|
16
|
+
SHOPS_LIST: '/shopsList',
|
|
17
|
+
SALES_PER_PRODUCT: '/salesPerProduct',
|
|
18
|
+
PAYMENT_PROFILES: '/paymentProfiles',
|
|
19
|
+
TRANSACTIONS_PER_WEBPOS: '/transactionsPerWebPOS',
|
|
20
|
+
PARTNER_PROFILE: '/partnerProfile',
|
|
21
|
+
|
|
22
|
+
// Premium reports
|
|
23
|
+
PROCESSED_TRANSACTIONS: '/processedTransactions',
|
|
24
|
+
SCHEDULES_LIST: '/schedulesList',
|
|
25
|
+
TRANSACTIONS_PER_PRODUCT: '/processedTransactionsPerProduct'
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Supported export formats
|
|
30
|
+
*/
|
|
31
|
+
export const EXPORT_FORMATS = {
|
|
32
|
+
PDF: 'pdf',
|
|
33
|
+
CSV: 'csv',
|
|
34
|
+
EXCEL: 'xlsx',
|
|
35
|
+
JSON: 'json'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Supported locales
|
|
40
|
+
*/
|
|
41
|
+
export const LOCALES = {
|
|
42
|
+
ENGLISH_US: 'en_US',
|
|
43
|
+
SPANISH: 'es_ES',
|
|
44
|
+
BULGARIAN: 'bg_BG'
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Create authentication headers based on partner type
|
|
49
|
+
* @param {string} partnerType - merchant, isv, or payment_institution
|
|
50
|
+
* @param {Object} authParams - Authentication parameters
|
|
51
|
+
* @returns {Object} Headers for API request
|
|
52
|
+
*/
|
|
53
|
+
async function createAuthHeaders(partnerType, authParams) {
|
|
54
|
+
const baseHeaders = {
|
|
55
|
+
'Content-Type': 'application/json',
|
|
56
|
+
'Api-Version': '1'
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
let tokenData;
|
|
60
|
+
|
|
61
|
+
switch (partnerType) {
|
|
62
|
+
case 'merchant':
|
|
63
|
+
case 'payment_institution':
|
|
64
|
+
// Standard JWT authentication
|
|
65
|
+
tokenData = createJWTToken(
|
|
66
|
+
authParams.partnerId,
|
|
67
|
+
authParams.privateKey,
|
|
68
|
+
authParams.requestBody
|
|
69
|
+
);
|
|
70
|
+
break;
|
|
71
|
+
|
|
72
|
+
case 'isv':
|
|
73
|
+
// ISV JWT with OAuth2 - note the parameter mapping
|
|
74
|
+
tokenData = await createJWTForPartner({
|
|
75
|
+
partnerId: authParams.isvPartnerId,
|
|
76
|
+
privateKey: authParams.privateKey,
|
|
77
|
+
merchantId: authParams.merchantPartnerId, // Map merchantPartnerId to merchantId
|
|
78
|
+
oauth2Token: authParams.oauth2Token,
|
|
79
|
+
requestBody: authParams.requestBody
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`Unknown partner type: ${partnerType}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
...baseHeaders,
|
|
89
|
+
'Authorization': `Bearer ${tokenData.token}`
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Generate a report asynchronously
|
|
95
|
+
*/
|
|
96
|
+
export async function generateReport({
|
|
97
|
+
reportUnitId,
|
|
98
|
+
ignorePagination = false,
|
|
99
|
+
locale = LOCALES.ENGLISH_US,
|
|
100
|
+
dateFrom,
|
|
101
|
+
dateTo,
|
|
102
|
+
timeZone = 'GMT',
|
|
103
|
+
partnerType,
|
|
104
|
+
...authParams
|
|
105
|
+
}) {
|
|
106
|
+
if (!reportUnitId) {
|
|
107
|
+
throw new Error('reportUnitId is required (e.g., "/processedTransactions")');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!Object.values(REPORT_TYPES).includes(reportUnitId)) {
|
|
111
|
+
console.warn(`Warning: reportUnitId "${reportUnitId}" is not in the known report types list`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!Object.values(LOCALES).includes(locale)) {
|
|
115
|
+
throw new Error(`Invalid locale. Supported: ${Object.values(LOCALES).join(', ')}`);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const requestBody = {
|
|
119
|
+
reportUnitId,
|
|
120
|
+
ignorePagination,
|
|
121
|
+
locale,
|
|
122
|
+
timeZone
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Add date range if provided
|
|
126
|
+
if (dateFrom) requestBody.dateFrom = dateFrom;
|
|
127
|
+
if (dateTo) requestBody.dateTo = dateTo;
|
|
128
|
+
|
|
129
|
+
const minimizedBody = createMinimizedJSON(requestBody);
|
|
130
|
+
const headers = await createAuthHeaders(partnerType, { ...authParams, requestBody: minimizedBody });
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const response = await axios.post(
|
|
134
|
+
`${getProductionUrl()}/data-retrieval`,
|
|
135
|
+
minimizedBody,
|
|
136
|
+
{ headers }
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
success: true,
|
|
141
|
+
data: response.data,
|
|
142
|
+
requestInfo: {
|
|
143
|
+
url: `${getProductionUrl()}/data-retrieval`,
|
|
144
|
+
method: 'POST',
|
|
145
|
+
requestBody: minimizedBody,
|
|
146
|
+
statusCode: response.status
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
throw new Error(`Failed to generate report: ${error.response?.data?.message || error.message}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get report generation status
|
|
156
|
+
*/
|
|
157
|
+
export async function getReportStatus({
|
|
158
|
+
requestId,
|
|
159
|
+
partnerType,
|
|
160
|
+
...authParams
|
|
161
|
+
}) {
|
|
162
|
+
if (!requestId) {
|
|
163
|
+
throw new Error('requestId is required (UUID from report generation)');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const headers = await createAuthHeaders(partnerType, authParams);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
const response = await axios.get(
|
|
170
|
+
`${getProductionUrl()}/data-retrieval/request/${requestId}/status`,
|
|
171
|
+
{ headers }
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
success: true,
|
|
176
|
+
data: response.data,
|
|
177
|
+
requestInfo: {
|
|
178
|
+
url: `${getProductionUrl()}/data-retrieval/request/${requestId}/status`,
|
|
179
|
+
method: 'GET',
|
|
180
|
+
statusCode: response.status
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
} catch (error) {
|
|
184
|
+
throw new Error(`Failed to get report status: ${error.response?.data?.message || error.message}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Export report in specific format
|
|
190
|
+
*/
|
|
191
|
+
export async function exportReport({
|
|
192
|
+
requestId,
|
|
193
|
+
outputFormat = EXPORT_FORMATS.PDF,
|
|
194
|
+
partnerType,
|
|
195
|
+
...authParams
|
|
196
|
+
}) {
|
|
197
|
+
if (!requestId) {
|
|
198
|
+
throw new Error('requestId is required (UUID from report generation)');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!Object.values(EXPORT_FORMATS).includes(outputFormat)) {
|
|
202
|
+
throw new Error(`Invalid output format. Supported: ${Object.values(EXPORT_FORMATS).join(', ')}`);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const requestBody = {};
|
|
206
|
+
const headers = await createAuthHeaders(partnerType, { ...authParams, requestBody });
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const response = await axios.post(
|
|
210
|
+
`${getProductionUrl()}/data-retrieval/request/${requestId}/export/${outputFormat}`,
|
|
211
|
+
requestBody,
|
|
212
|
+
{ headers }
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
success: true,
|
|
217
|
+
data: response.data,
|
|
218
|
+
requestInfo: {
|
|
219
|
+
url: `${getProductionUrl()}/data-retrieval/request/${requestId}/export/${outputFormat}`,
|
|
220
|
+
method: 'POST',
|
|
221
|
+
statusCode: response.status
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
} catch (error) {
|
|
225
|
+
throw new Error(`Failed to export report: ${error.response?.data?.message || error.message}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Get export status
|
|
231
|
+
*/
|
|
232
|
+
export async function getExportStatus({
|
|
233
|
+
exportId,
|
|
234
|
+
partnerType,
|
|
235
|
+
...authParams
|
|
236
|
+
}) {
|
|
237
|
+
if (!exportId) {
|
|
238
|
+
throw new Error('exportId is required (UUID from export request)');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const headers = await createAuthHeaders(partnerType, authParams);
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const response = await axios.get(
|
|
245
|
+
`${getProductionUrl()}/data-retrieval/export/${exportId}/status`,
|
|
246
|
+
{ headers }
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
success: true,
|
|
251
|
+
data: response.data,
|
|
252
|
+
requestInfo: {
|
|
253
|
+
url: `${getProductionUrl()}/data-retrieval/export/${exportId}/status`,
|
|
254
|
+
method: 'GET',
|
|
255
|
+
statusCode: response.status
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
} catch (error) {
|
|
259
|
+
throw new Error(`Failed to get export status: ${error.response?.data?.message || error.message}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Download exported report
|
|
265
|
+
*/
|
|
266
|
+
export async function downloadExport({
|
|
267
|
+
exportId,
|
|
268
|
+
partnerType,
|
|
269
|
+
...authParams
|
|
270
|
+
}) {
|
|
271
|
+
if (!exportId) {
|
|
272
|
+
throw new Error('exportId is required (UUID from export request)');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const headers = await createAuthHeaders(partnerType, authParams);
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
const response = await axios.get(
|
|
279
|
+
`${getProductionUrl()}/data-retrieval/export/${exportId}/download`,
|
|
280
|
+
{
|
|
281
|
+
headers,
|
|
282
|
+
responseType: 'arraybuffer' // For binary data (PDF, Excel, etc.)
|
|
283
|
+
}
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
success: true,
|
|
288
|
+
data: response.data,
|
|
289
|
+
contentType: response.headers['content-type'],
|
|
290
|
+
contentLength: response.headers['content-length'],
|
|
291
|
+
requestInfo: {
|
|
292
|
+
url: `${getProductionUrl()}/data-retrieval/export/${exportId}/download`,
|
|
293
|
+
method: 'GET',
|
|
294
|
+
statusCode: response.status
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
} catch (error) {
|
|
298
|
+
throw new Error(`Failed to download export: ${error.response?.data?.message || error.message}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Cancel report generation
|
|
304
|
+
*/
|
|
305
|
+
export async function cancelReport({
|
|
306
|
+
requestId,
|
|
307
|
+
partnerType,
|
|
308
|
+
...authParams
|
|
309
|
+
}) {
|
|
310
|
+
if (!requestId) {
|
|
311
|
+
throw new Error('requestId is required (UUID from report generation)');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const requestBody = {};
|
|
315
|
+
const headers = await createAuthHeaders(partnerType, { ...authParams, requestBody });
|
|
316
|
+
|
|
317
|
+
try {
|
|
318
|
+
const response = await axios.put(
|
|
319
|
+
`${getProductionUrl()}/data-retrieval/${requestId}/cancel`,
|
|
320
|
+
requestBody,
|
|
321
|
+
{ headers }
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
return {
|
|
325
|
+
success: true,
|
|
326
|
+
data: response.data,
|
|
327
|
+
requestInfo: {
|
|
328
|
+
url: `${getProductionUrl()}/data-retrieval/${requestId}/cancel`,
|
|
329
|
+
method: 'PUT',
|
|
330
|
+
statusCode: response.status
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
throw new Error(`Failed to cancel report: ${error.response?.data?.message || error.message}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Cancel export
|
|
340
|
+
*/
|
|
341
|
+
export async function cancelExport({
|
|
342
|
+
exportId,
|
|
343
|
+
partnerType,
|
|
344
|
+
...authParams
|
|
345
|
+
}) {
|
|
346
|
+
if (!exportId) {
|
|
347
|
+
throw new Error('exportId is required (UUID from export request)');
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const requestBody = {};
|
|
351
|
+
const headers = await createAuthHeaders(partnerType, { ...authParams, requestBody });
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
const response = await axios.put(
|
|
355
|
+
`${getProductionUrl()}/data-retrieval/${exportId}/cancel`,
|
|
356
|
+
requestBody,
|
|
357
|
+
{ headers }
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
return {
|
|
361
|
+
success: true,
|
|
362
|
+
data: response.data,
|
|
363
|
+
requestInfo: {
|
|
364
|
+
url: `${getProductionUrl()}/data-retrieval/${exportId}/cancel`,
|
|
365
|
+
method: 'PUT',
|
|
366
|
+
statusCode: response.status
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
} catch (error) {
|
|
370
|
+
throw new Error(`Failed to cancel export: ${error.response?.data?.message || error.message}`);
|
|
371
|
+
}
|
|
372
|
+
}
|