@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/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@payware/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official MCP server for payware payment API integration",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"payware-mcp": "./src/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/index.js",
|
|
12
|
+
"dev": "node --watch src/index.js",
|
|
13
|
+
"proxy": "node src/proxy-server.js",
|
|
14
|
+
"proxy:dev": "node --watch src/proxy-server.js",
|
|
15
|
+
"bridge": "node src/mcp-proxy.js",
|
|
16
|
+
"inspector": "npx @modelcontextprotocol/inspector node src/mcp-proxy.js"
|
|
17
|
+
},
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@modelcontextprotocol/sdk": "^0.5.0",
|
|
20
|
+
"axios": "^1.6.0",
|
|
21
|
+
"cors": "^2.8.5",
|
|
22
|
+
"dotenv": "^17.2.2",
|
|
23
|
+
"express": "^5.1.0",
|
|
24
|
+
"http-proxy-middleware": "^3.0.5",
|
|
25
|
+
"jsonwebtoken": "^9.0.0",
|
|
26
|
+
"node-forge": "^1.3.1"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"mcp",
|
|
33
|
+
"model-context-protocol",
|
|
34
|
+
"payware",
|
|
35
|
+
"payments",
|
|
36
|
+
"payment-gateway",
|
|
37
|
+
"payment-processing",
|
|
38
|
+
"api",
|
|
39
|
+
"fintech",
|
|
40
|
+
"pos",
|
|
41
|
+
"terminal",
|
|
42
|
+
"merchant",
|
|
43
|
+
"isv",
|
|
44
|
+
"oauth2"
|
|
45
|
+
],
|
|
46
|
+
"author": "payware <support@payware.com>",
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/payware/mcp-server.git"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/payware/mcp-server/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/payware/mcp-server#readme",
|
|
56
|
+
"files": [
|
|
57
|
+
"src/",
|
|
58
|
+
"keys/README.md",
|
|
59
|
+
"README.md",
|
|
60
|
+
"check-keys.js",
|
|
61
|
+
"mcp-config.json",
|
|
62
|
+
"payware-mcp-config.json",
|
|
63
|
+
".env.example",
|
|
64
|
+
"MCP-SETUP.md"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import forge from 'node-forge';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate RSA key pair for payware API authentication
|
|
5
|
+
* @param {number} keySize - RSA key size in bits (default: 2048)
|
|
6
|
+
* @returns {Object} Object containing publicKey and privateKey in PEM format
|
|
7
|
+
*/
|
|
8
|
+
export function generateRSAKeyPair(keySize = 2048) {
|
|
9
|
+
const keyPair = forge.pki.rsa.generateKeyPair({ bits: keySize });
|
|
10
|
+
|
|
11
|
+
const privateKeyPem = forge.pki.privateKeyToPem(keyPair.privateKey);
|
|
12
|
+
const publicKeyPem = forge.pki.publicKeyToPem(keyPair.publicKey);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
privateKey: privateKeyPem,
|
|
16
|
+
publicKey: publicKeyPem,
|
|
17
|
+
keySize,
|
|
18
|
+
generated: new Date().toISOString()
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Generate RSA keys tool implementation
|
|
24
|
+
*/
|
|
25
|
+
export const generateRSAKeysTool = {
|
|
26
|
+
name: "payware_authentication_generate_rsa_keys",
|
|
27
|
+
description: "Generate RSA key pair for payware API authentication",
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
keySize: {
|
|
32
|
+
type: "number",
|
|
33
|
+
description: "RSA key size in bits",
|
|
34
|
+
minimum: 2048,
|
|
35
|
+
maximum: 8192
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
async handler(args) {
|
|
42
|
+
const keySize = args.keySize || 2048;
|
|
43
|
+
|
|
44
|
+
if (keySize < 2048) {
|
|
45
|
+
throw new Error("Key size must be at least 2048 bits for security");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const keyPair = generateRSAKeyPair(keySize);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
content: [{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `🔐 **RSA Key Pair Generated Successfully**
|
|
54
|
+
|
|
55
|
+
**⚠️ SECURITY WARNING ⚠️**
|
|
56
|
+
- Store private key securely and never share it
|
|
57
|
+
- Use different keys for production environment
|
|
58
|
+
- Sandbox keys should not be used in production
|
|
59
|
+
|
|
60
|
+
**Private Key:**
|
|
61
|
+
\`\`\`
|
|
62
|
+
${keyPair.privateKey}
|
|
63
|
+
\`\`\`
|
|
64
|
+
|
|
65
|
+
**Public Key:**
|
|
66
|
+
\`\`\`
|
|
67
|
+
${keyPair.publicKey}
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
**Key Details:**
|
|
71
|
+
- Size: ${keyPair.keySize} bits
|
|
72
|
+
- Generated: ${keyPair.generated}
|
|
73
|
+
- Purpose: payware API authentication (sandbox only)
|
|
74
|
+
|
|
75
|
+
**Next Steps:**
|
|
76
|
+
1. Save private key to secure location
|
|
77
|
+
2. Register public key with payware sandbox
|
|
78
|
+
3. Use private key to create JWT tokens`
|
|
79
|
+
}]
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Setup sandbox authentication configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../config/env.js';
|
|
6
|
+
|
|
7
|
+
const SANDBOX_CONFIG = {
|
|
8
|
+
baseUrl: 'https://sandbox.payware.eu/api',
|
|
9
|
+
apiVersion: '1',
|
|
10
|
+
environment: 'sandbox',
|
|
11
|
+
supportedCurrencies: [
|
|
12
|
+
// Major currencies
|
|
13
|
+
'EUR', 'USD', 'GBP', 'JPY', 'CHF', 'CAD', 'AUD', 'CNY', 'SEK', 'NOK', 'DKK',
|
|
14
|
+
// All other supported currencies (100+ total)
|
|
15
|
+
'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AWG', 'AZN',
|
|
16
|
+
'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTC', 'BTN', 'BWP', 'BYN', 'BZD',
|
|
17
|
+
'CDF', 'CLP', 'COP', 'CRC', 'CUP', 'CVE', 'CZK',
|
|
18
|
+
'DJF', 'DOP', 'DZD',
|
|
19
|
+
'EGP', 'ERN', 'ETB',
|
|
20
|
+
'FJD', 'FKP',
|
|
21
|
+
'GEL', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD',
|
|
22
|
+
'HKD', 'HNL', 'HRK', 'HTG', 'HUF',
|
|
23
|
+
'IDR', 'ILS', 'INR', 'IQD', 'IRR', 'ISK',
|
|
24
|
+
'JMD', 'JOD',
|
|
25
|
+
'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT',
|
|
26
|
+
'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD',
|
|
27
|
+
'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN',
|
|
28
|
+
'NAD', 'NGN', 'NIO', 'NPR', 'NZD',
|
|
29
|
+
'OMR',
|
|
30
|
+
'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG',
|
|
31
|
+
'QAR',
|
|
32
|
+
'RON', 'RSD', 'RUB', 'RWF',
|
|
33
|
+
'SAR', 'SBD', 'SCR', 'SDG', 'SGD', 'SHP', 'SLL', 'SOS', 'SRD', 'STD', 'SVC', 'SYP', 'SZL',
|
|
34
|
+
'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TWD', 'TZS',
|
|
35
|
+
'UAH', 'UGX', 'UYU', 'UZS',
|
|
36
|
+
'VND', 'VUV',
|
|
37
|
+
'WST',
|
|
38
|
+
'XAF', 'XCD', 'XOF', 'XPF',
|
|
39
|
+
'YER',
|
|
40
|
+
'ZAR', 'ZMW', 'ZWL'
|
|
41
|
+
], // ISO 3-character codes
|
|
42
|
+
supportedTransactionTypes: ['PLAIN', 'QR', 'BARCODE'], // trOptions.type values
|
|
43
|
+
transactionTypes: ['DEFAULT', 'SHIPPABLE'], // transactionType values
|
|
44
|
+
maxAmount: 'Unlimited', // Limited by Java type implementation
|
|
45
|
+
minAmount: '0.00', // Zero allowed for flexible amounts
|
|
46
|
+
maxTTL: 600, // seconds
|
|
47
|
+
minTTL: 60, // seconds
|
|
48
|
+
defaultTTL: 120, // seconds
|
|
49
|
+
audience: 'https://payware.eu', // Required JWT audience
|
|
50
|
+
transactionIdPrefix: 'pw' // All transaction IDs start with 'pw'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generate sandbox configuration
|
|
55
|
+
* @param {string} partnerId - Partner ID
|
|
56
|
+
* @param {string} privateKey - Private key (optional, for validation)
|
|
57
|
+
* @returns {Object} Sandbox configuration object
|
|
58
|
+
*/
|
|
59
|
+
export function generateSandboxConfig(partnerId, privateKey = null) {
|
|
60
|
+
const config = {
|
|
61
|
+
...SANDBOX_CONFIG,
|
|
62
|
+
partnerId,
|
|
63
|
+
endpoints: {
|
|
64
|
+
createTransaction: `${SANDBOX_CONFIG.baseUrl}/transactions`,
|
|
65
|
+
getTransactionStatus: `${SANDBOX_CONFIG.baseUrl}/transactions/{id}`,
|
|
66
|
+
processTransaction: `${SANDBOX_CONFIG.baseUrl}/transactions/{id}`,
|
|
67
|
+
cancelTransaction: `${SANDBOX_CONFIG.baseUrl}/transactions/{id}`,
|
|
68
|
+
getTransactionHistory: `${SANDBOX_CONFIG.baseUrl}/transactions-history/{id}`,
|
|
69
|
+
callback: 'https://your-callback-url' // Provided by merchant
|
|
70
|
+
},
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'Api-Version': '1'
|
|
74
|
+
},
|
|
75
|
+
authentication: {
|
|
76
|
+
type: 'JWT',
|
|
77
|
+
algorithm: 'RS256',
|
|
78
|
+
audience: 'https://payware.eu',
|
|
79
|
+
requiresContentMd5: 'For POST/PUT/PATCH requests',
|
|
80
|
+
hasPrivateKey: !!privateKey
|
|
81
|
+
},
|
|
82
|
+
generatedAt: new Date().toISOString()
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Setup sandbox auth tool implementation
|
|
90
|
+
*/
|
|
91
|
+
export const setupSandboxAuthTool = {
|
|
92
|
+
name: "payware_authentication_setup_sandbox_auth",
|
|
93
|
+
description: "Setup sandbox authentication configuration for payware API",
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: "object",
|
|
96
|
+
properties: {
|
|
97
|
+
partnerId: {
|
|
98
|
+
type: "string",
|
|
99
|
+
description: "Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default."
|
|
100
|
+
},
|
|
101
|
+
privateKey: {
|
|
102
|
+
type: "string",
|
|
103
|
+
description: "RSA private key in PEM format (optional, for validation). Uses environment-specific private key as default."
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
additionalProperties: false
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
async handler(args) {
|
|
110
|
+
const {
|
|
111
|
+
partnerId = getPartnerIdSafe(),
|
|
112
|
+
privateKey = getPrivateKeySafe()
|
|
113
|
+
} = args;
|
|
114
|
+
|
|
115
|
+
if (!partnerId) {
|
|
116
|
+
throw new Error("Partner ID is required. Provide via 'partnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const config = generateSandboxConfig(partnerId, privateKey);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
content: [{
|
|
123
|
+
type: "text",
|
|
124
|
+
text: `🔧 **Sandbox Authentication Setup Complete**
|
|
125
|
+
|
|
126
|
+
**Configuration:**
|
|
127
|
+
\`\`\`json
|
|
128
|
+
${JSON.stringify(config, null, 2)}
|
|
129
|
+
\`\`\`
|
|
130
|
+
|
|
131
|
+
**Environment Details:**
|
|
132
|
+
- Base URL: ${config.baseUrl}
|
|
133
|
+
- API Version: ${config.apiVersion}
|
|
134
|
+
- Environment: ${config.environment}
|
|
135
|
+
- Partner ID: ${config.partnerId}
|
|
136
|
+
|
|
137
|
+
**Supported Features:**
|
|
138
|
+
- Request Types (trOptions.type): ${config.supportedTransactionTypes.join(', ')}
|
|
139
|
+
- Transaction Types: ${config.transactionTypes.join(', ')}
|
|
140
|
+
- Currencies: ${config.supportedCurrencies.join(', ')} (ISO 3-char codes)
|
|
141
|
+
- Amount Range: €${config.minAmount} - ${config.maxAmount} (currency values)
|
|
142
|
+
- TTL Range: ${config.minTTL}-${config.maxTTL} seconds (default: ${config.defaultTTL})
|
|
143
|
+
- Transaction ID Format: Starts with '${config.transactionIdPrefix}'
|
|
144
|
+
- QR Options: Format (PNG/JPEG/SVG), Border, Error Correction (L/M/Q/H), Scale, Version
|
|
145
|
+
- Barcode Options: Format (CODE128/CODE39/EAN13), Width, Height, Font Size, Text Location
|
|
146
|
+
- Additional: passbackParams for custom callback data
|
|
147
|
+
|
|
148
|
+
**API Endpoints:**
|
|
149
|
+
- Create Transaction: \`POST ${config.endpoints.createTransaction}\`
|
|
150
|
+
- Get Transaction Status: \`GET ${config.endpoints.getTransactionStatus}\`
|
|
151
|
+
- Process Transaction: \`POST ${config.endpoints.processTransaction}\` (merchants only)
|
|
152
|
+
- Cancel Transaction: \`PATCH ${config.endpoints.cancelTransaction}\` (creators only)
|
|
153
|
+
- Transaction History: \`GET ${config.endpoints.getTransactionHistory}\` (completed/expired)
|
|
154
|
+
- Callback Endpoint: \`POST [your-callback-url]\` (configured by you)
|
|
155
|
+
|
|
156
|
+
**Required Headers (All Requests):**
|
|
157
|
+
${Object.entries(config.headers).map(([key, value]) => `- ${key}: ${value}`).join('\n')}
|
|
158
|
+
- Authorization: Bearer {JWT_TOKEN} (with contentMd5 for POST/PATCH)
|
|
159
|
+
|
|
160
|
+
**JWT Requirements:**
|
|
161
|
+
- Algorithm: RS256
|
|
162
|
+
- Issuer (iss): Your Partner ID
|
|
163
|
+
- Audience (aud): https://payware.eu
|
|
164
|
+
- Content-MD5: Required in JWT header for POST/PATCH requests
|
|
165
|
+
- Private Key: RSA 2048-bit minimum
|
|
166
|
+
|
|
167
|
+
**Required Fields for Transaction Creation:**
|
|
168
|
+
- trData.currency: ISO 3-character code (required)
|
|
169
|
+
- trData.reasonL1: Description, max 100 chars (required)
|
|
170
|
+
- trData.reasonL2: Continuation, max 100 chars (optional)
|
|
171
|
+
- trData.amount: Currency value as string/number, 0.00+ (optional for flexible)
|
|
172
|
+
- trOptions.type: PLAIN, QR, or BARCODE (default: PLAIN)
|
|
173
|
+
- trOptions.timeToLive: 60-600 seconds (default: 120)
|
|
174
|
+
|
|
175
|
+
**Next Steps:**
|
|
176
|
+
1. Generate RSA key pair (2048-bit minimum)
|
|
177
|
+
2. Register public key in payware portal
|
|
178
|
+
3. Create JWT token with proper structure
|
|
179
|
+
4. Test with create transaction endpoint
|
|
180
|
+
5. Implement callback handler for status updates
|
|
181
|
+
|
|
182
|
+
**⚠️ Sandbox Only:**
|
|
183
|
+
This configuration is for sandbox testing only. Do not use in production.`
|
|
184
|
+
}]
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment configuration for payware MCP server
|
|
3
|
+
* Supports different partner types: merchant, isv, payment_institution
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Suppress dotenv informational messages that interfere with MCP JSON-RPC transport
|
|
7
|
+
process.env.DOTENV_CONFIG_QUIET = 'true';
|
|
8
|
+
|
|
9
|
+
import { config } from 'dotenv';
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import { resolve } from 'path';
|
|
12
|
+
|
|
13
|
+
// Load environment variables from .env file (silent mode for MCP compatibility)
|
|
14
|
+
config({ debug: false });
|
|
15
|
+
|
|
16
|
+
// Valid partner types
|
|
17
|
+
const VALID_PARTNER_TYPES = ['merchant', 'isv', 'payment_institution'];
|
|
18
|
+
const DEFAULT_PARTNER_TYPE = 'merchant';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get partner ID from environment
|
|
22
|
+
* @returns {string} Partner ID
|
|
23
|
+
* @throws {Error} If partner ID is not configured
|
|
24
|
+
*/
|
|
25
|
+
export function getPartnerId() {
|
|
26
|
+
const partnerId = process.env.PAYWARE_PARTNER_ID;
|
|
27
|
+
if (!partnerId) {
|
|
28
|
+
throw new Error('PAYWARE_PARTNER_ID environment variable is required');
|
|
29
|
+
}
|
|
30
|
+
return partnerId;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get private key from environment-specified path
|
|
35
|
+
* @param {boolean} useSandbox - Whether to use sandbox environment
|
|
36
|
+
* @returns {string} Private key content
|
|
37
|
+
* @throws {Error} If private key path is not configured or file cannot be read
|
|
38
|
+
*/
|
|
39
|
+
export function getPrivateKey(useSandbox = true) {
|
|
40
|
+
let privateKeyPath;
|
|
41
|
+
|
|
42
|
+
if (useSandbox) {
|
|
43
|
+
privateKeyPath = process.env.PAYWARE_SANDBOX_PRIVATE_KEY_PATH;
|
|
44
|
+
} else {
|
|
45
|
+
privateKeyPath = process.env.PAYWARE_PRODUCTION_PRIVATE_KEY_PATH;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!privateKeyPath) {
|
|
49
|
+
const envVar = useSandbox ? 'PAYWARE_SANDBOX_PRIVATE_KEY_PATH' : 'PAYWARE_PRODUCTION_PRIVATE_KEY_PATH';
|
|
50
|
+
throw new Error(`${envVar} environment variable is required`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
// Resolve path relative to project root
|
|
55
|
+
const fullPath = resolve(privateKeyPath);
|
|
56
|
+
const privateKey = readFileSync(fullPath, 'utf8');
|
|
57
|
+
return privateKey;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new Error(`Cannot read private key from ${privateKeyPath}: ${error.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get sandbox base URL from environment (with default)
|
|
65
|
+
* @returns {string} Sandbox base URL
|
|
66
|
+
*/
|
|
67
|
+
export function getSandboxUrl() {
|
|
68
|
+
return process.env.PAYWARE_SANDBOX_URL || 'https://sandbox.payware.eu/api';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get production base URL from environment (with default)
|
|
73
|
+
* @returns {string} Production base URL
|
|
74
|
+
*/
|
|
75
|
+
export function getProductionUrl() {
|
|
76
|
+
return process.env.PAYWARE_PRODUCTION_URL || 'https://api.payware.eu/api';
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get environment configuration object
|
|
81
|
+
* @returns {Object} Configuration object with all environment settings
|
|
82
|
+
*/
|
|
83
|
+
export function getEnvironmentConfig() {
|
|
84
|
+
return {
|
|
85
|
+
partnerId: getPartnerId(),
|
|
86
|
+
sandboxPrivateKeyPath: process.env.PAYWARE_SANDBOX_PRIVATE_KEY_PATH,
|
|
87
|
+
productionPrivateKeyPath: process.env.PAYWARE_PRODUCTION_PRIVATE_KEY_PATH,
|
|
88
|
+
sandboxUrl: getSandboxUrl(),
|
|
89
|
+
productionUrl: getProductionUrl(),
|
|
90
|
+
hasSandboxPrivateKey: !!process.env.PAYWARE_SANDBOX_PRIVATE_KEY_PATH,
|
|
91
|
+
hasProductionPrivateKey: !!process.env.PAYWARE_PRODUCTION_PRIVATE_KEY_PATH,
|
|
92
|
+
configuredAt: new Date().toISOString()
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get partner ID safely (returns undefined if not configured)
|
|
98
|
+
* @returns {string|undefined} Partner ID or undefined
|
|
99
|
+
*/
|
|
100
|
+
export function getPartnerIdSafe() {
|
|
101
|
+
try {
|
|
102
|
+
return getPartnerId();
|
|
103
|
+
} catch (error) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get private key safely (returns undefined if not configured)
|
|
110
|
+
* @param {boolean} useSandbox - Whether to use sandbox environment
|
|
111
|
+
* @returns {string|undefined} Private key content or undefined
|
|
112
|
+
*/
|
|
113
|
+
export function getPrivateKeySafe(useSandbox = true) {
|
|
114
|
+
try {
|
|
115
|
+
return getPrivateKey(useSandbox);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get partner type from environment
|
|
123
|
+
* @returns {string} Partner type (merchant, isv, or payment_institution)
|
|
124
|
+
*/
|
|
125
|
+
export function getPartnerType() {
|
|
126
|
+
const partnerType = process.env.PAYWARE_PARTNER_TYPE || DEFAULT_PARTNER_TYPE;
|
|
127
|
+
|
|
128
|
+
if (!VALID_PARTNER_TYPES.includes(partnerType)) {
|
|
129
|
+
throw new Error(`Invalid partner type: ${partnerType}. Valid types: ${VALID_PARTNER_TYPES.join(', ')}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return partnerType;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get partner type safely (returns default if not configured)
|
|
137
|
+
* @returns {string} Partner type or default
|
|
138
|
+
*/
|
|
139
|
+
export function getPartnerTypeSafe() {
|
|
140
|
+
try {
|
|
141
|
+
return getPartnerType();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
return DEFAULT_PARTNER_TYPE;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Check if current partner type is ISV
|
|
149
|
+
* @returns {boolean} True if partner type is ISV
|
|
150
|
+
*/
|
|
151
|
+
export function isISV() {
|
|
152
|
+
return getPartnerTypeSafe() === 'isv';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if current partner type is Payment Institution
|
|
157
|
+
* @returns {boolean} True if partner type is Payment Institution
|
|
158
|
+
*/
|
|
159
|
+
export function isPaymentInstitution() {
|
|
160
|
+
return getPartnerTypeSafe() === 'payment_institution';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Check if current partner type is Merchant
|
|
165
|
+
* @returns {boolean} True if partner type is Merchant
|
|
166
|
+
*/
|
|
167
|
+
export function isMerchant() {
|
|
168
|
+
return getPartnerTypeSafe() === 'merchant';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Get OAuth2 client ID for ISV partners
|
|
173
|
+
* @returns {string|undefined} OAuth2 client ID
|
|
174
|
+
*/
|
|
175
|
+
export function getOAuth2ClientId() {
|
|
176
|
+
if (!isISV()) return undefined;
|
|
177
|
+
return process.env.PAYWARE_OAUTH_CLIENT_ID;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get OAuth2 client secret for ISV partners
|
|
182
|
+
* @returns {string|undefined} OAuth2 client secret
|
|
183
|
+
*/
|
|
184
|
+
export function getOAuth2ClientSecret() {
|
|
185
|
+
if (!isISV()) return undefined;
|
|
186
|
+
return process.env.PAYWARE_OAUTH_CLIENT_SECRET;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get default merchant ID for ISV partners
|
|
191
|
+
* @returns {string|undefined} Default merchant ID
|
|
192
|
+
*/
|
|
193
|
+
export function getDefaultMerchantId() {
|
|
194
|
+
if (!isISV()) return undefined;
|
|
195
|
+
return process.env.PAYWARE_DEFAULT_MERCHANT_ID;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Validate that all required environment variables are set for the partner type
|
|
200
|
+
* @throws {Error} If any required environment variable is missing
|
|
201
|
+
*/
|
|
202
|
+
export function validateEnvironment() {
|
|
203
|
+
const partnerType = getPartnerType(); // Will throw if invalid
|
|
204
|
+
getPartnerId(); // Will throw if missing
|
|
205
|
+
getPrivateKey(true); // Will throw if missing or unreadable (check sandbox key)
|
|
206
|
+
|
|
207
|
+
// ISV-specific validation
|
|
208
|
+
if (isISV()) {
|
|
209
|
+
if (!getOAuth2ClientId()) {
|
|
210
|
+
throw new Error('PAYWARE_OAUTH_CLIENT_ID is required for ISV partners');
|
|
211
|
+
}
|
|
212
|
+
if (!getOAuth2ClientSecret()) {
|
|
213
|
+
throw new Error('PAYWARE_OAUTH_CLIENT_SECRET is required for ISV partners');
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
console.log('✅ Environment configuration validated');
|
|
218
|
+
console.log(` Partner Type: ${partnerType}`);
|
|
219
|
+
console.log(` Partner ID: ${getPartnerId()}`);
|
|
220
|
+
console.log(` Sandbox Private Key: ${process.env.PAYWARE_SANDBOX_PRIVATE_KEY_PATH ? 'Set' : 'Not set'}`);
|
|
221
|
+
console.log(` Production Private Key: ${process.env.PAYWARE_PRODUCTION_PRIVATE_KEY_PATH ? 'Set' : 'Not set'}`);
|
|
222
|
+
console.log(` Sandbox URL: ${getSandboxUrl()}`);
|
|
223
|
+
console.log(` Production URL: ${getProductionUrl()}`);
|
|
224
|
+
|
|
225
|
+
if (isISV()) {
|
|
226
|
+
console.log(` OAuth2 Client ID: ${getOAuth2ClientId()}`);
|
|
227
|
+
console.log(` Default Merchant ID: ${getDefaultMerchantId() || 'Not set'}`);
|
|
228
|
+
}
|
|
229
|
+
}
|