@payware/mcp-server 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +0 -0
- package/README.md +22 -16
- package/check-keys.js +0 -0
- package/keys/README.md +0 -0
- package/mcp-config.json +0 -0
- package/package.json +69 -66
- package/payware-mcp-config.json +0 -0
- package/src/auth/rsa-keys.js +0 -0
- package/src/auth/sandbox-setup.js +186 -186
- package/src/config/env.js +0 -0
- package/src/config/partner-types.js +0 -0
- package/src/core/auth/jwt-factory.js +4 -4
- package/src/core/auth/jwt-token.js +107 -66
- package/src/core/utils/json-serializer.js +5 -5
- package/src/core/utils/key-utils.js +0 -0
- package/src/index.js +0 -0
- package/src/isv/data/index.js +0 -0
- package/src/isv/deep-links/delete-product-link.js +0 -0
- package/src/isv/deep-links/delete-transaction-link.js +0 -0
- package/src/isv/deep-links/get-product-link.js +0 -0
- package/src/isv/deep-links/get-transaction-link.js +0 -0
- package/src/isv/deep-links/index.js +0 -0
- package/src/isv/index.js +29 -1
- package/src/isv/invitations/index.js +471 -0
- package/src/isv/oauth2/create-token-simple.js +0 -0
- package/src/isv/oauth2/get-token-info.js +0 -0
- package/src/isv/oauth2/obtain-token.js +19 -8
- package/src/isv/oauth2/token-helper.js +5 -2
- package/src/isv/poi/cancel-price.js +2 -10
- package/src/isv/poi/create.js +19 -0
- package/src/isv/poi/get-poi.js +2 -10
- package/src/isv/poi/get-qrcode.js +2 -10
- package/src/isv/poi/get-status.js +2 -10
- package/src/isv/poi/index.js +5 -0
- package/src/isv/poi/list-pois.js +2 -10
- package/src/isv/poi/set-price.js +217 -225
- package/src/isv/products/audios.js +0 -0
- package/src/isv/products/create-product.js +313 -313
- package/src/isv/products/delete-product.js +0 -0
- package/src/isv/products/get-product-image.js +0 -0
- package/src/isv/products/get-product.js +0 -0
- package/src/isv/products/index.js +0 -0
- package/src/isv/products/list-products.js +0 -0
- package/src/isv/products/schedules.js +0 -0
- package/src/isv/products/update-product.js +264 -264
- package/src/isv/reference/index.js +249 -0
- package/src/isv/shops/index.js +22 -0
- package/src/isv/transactions/cancel-transaction.js +43 -12
- package/src/isv/transactions/create-transaction.js +22 -6
- package/src/isv/transactions/get-status.js +18 -11
- package/src/isv/transactions/process-transaction.js +160 -42
- package/src/isv/transactions/simulate-callback.js +128 -109
- package/src/isv/transactions/transaction-history.js +86 -90
- package/src/isv/utils/auth.js +2 -2
- package/src/mcp-proxy.js +0 -0
- package/src/merchant/data/export-report.js +0 -0
- package/src/merchant/data/generate-report.js +19 -1
- package/src/merchant/data/get-export-list.js +0 -0
- package/src/merchant/data/get-report-requests.js +0 -0
- package/src/merchant/data/get-report-status.js +0 -0
- package/src/merchant/data/index.js +0 -0
- package/src/merchant/data/list-reports.js +0 -0
- package/src/merchant/deep-links/delete-product-link.js +0 -0
- package/src/merchant/deep-links/delete-transaction-link.js +0 -0
- package/src/merchant/deep-links/get-product-link.js +0 -0
- package/src/merchant/deep-links/get-transaction-link.js +0 -0
- package/src/merchant/deep-links/index.js +0 -0
- package/src/merchant/index.js +21 -1
- package/src/merchant/logs/index.js +366 -0
- package/src/merchant/products/audios.js +0 -0
- package/src/merchant/products/create-product.js +287 -287
- package/src/merchant/products/delete-product.js +0 -0
- package/src/merchant/products/get-product-image.js +0 -0
- package/src/merchant/products/get-product.js +0 -0
- package/src/merchant/products/index.js +0 -0
- package/src/merchant/products/list-products.js +0 -0
- package/src/merchant/products/schedules.js +0 -0
- package/src/merchant/products/update-product.js +281 -281
- package/src/merchant/shops/index.js +18 -0
- package/src/merchant/transactions/cancel-transaction.js +16 -19
- package/src/merchant/transactions/create-transaction.js +99 -19
- package/src/merchant/transactions/get-status.js +41 -12
- package/src/merchant/transactions/process-transaction.js +8 -16
- package/src/merchant/transactions/simulate-callback.js +68 -9
- package/src/merchant/transactions/transaction-history.js +275 -257
- package/src/payment-institution/data/index.js +0 -0
- package/src/payment-institution/deep-links/delete-transaction-link.js +0 -0
- package/src/payment-institution/deep-links/get-transaction-link.js +0 -0
- package/src/payment-institution/deep-links/index.js +0 -0
- package/src/payment-institution/index.js +0 -0
- package/src/payment-institution/transactions/create-pi-transaction.js +6 -14
- package/src/payment-institution/transactions/finalize-transaction.js +333 -340
- package/src/payment-institution/transactions/get-transaction-history.js +3 -11
- package/src/payment-institution/transactions/get-transaction-status.js +39 -12
- package/src/payment-institution/transactions/process-pi-transaction.js +5 -13
- package/src/payment-institution/transactions/simulate-pi-callback.js +49 -9
- package/src/payment-institution/transactions/soundbite-transaction.js +5 -13
- package/src/proxy-server.js +0 -0
- package/src/shared/api-errors.js +188 -0
- package/src/shared/auth-headers.js +62 -0
- package/src/shared/data/data-api.js +11 -10
- package/src/shared/deep-links/api.js +5 -4
- package/src/shared/index.js +0 -0
- package/src/shared/logs/logs-api.js +242 -0
- package/src/shared/poi/poi-create-api.js +419 -0
- package/src/shared/products/products-api.js +17 -16
- package/src/shared/shops/shops-api.js +155 -0
- package/src/tools/advanced-code-generator.js +2255 -2246
- package/src/utils/code-examples/common/auth-examples.js +1484 -1481
- package/src/utils/code-examples/common/helpers.js +7 -4
- package/src/utils/code-examples/common/utils-examples.js +0 -0
- package/src/utils/code-examples/frameworks/examples.js +4 -4
- package/src/utils/code-examples/index.js +0 -0
- package/src/utils/code-examples/isv/oauth2.js +458 -600
- package/src/utils/code-examples/isv/products.js +8 -8
- package/src/utils/code-examples/isv/transactions.js +815 -812
- package/src/utils/code-examples/merchant/products.js +0 -0
- package/src/utils/code-examples/merchant/transactions.js +9 -9
- package/src/utils/code-examples/payment-institution/transactions.js +0 -0
- package/src/utils/code-examples/shared/data.js +0 -0
- package/src/utils/code-examples/shared/deep-links.js +0 -0
- package/src/utils/code-examples/shared/soundbites.js +0 -0
- package/src/utils/code-examples.js +24 -24
- package/src/utils/format-request.js +3 -3
- package/src/utils/json-formatter.js +20 -20
- package/src/utils/server-info.js +0 -0
- package/MCP-SETUP.md +0 -190
|
File without changes
|
|
@@ -158,14 +158,14 @@ def create_jwt_token(request_body=None, use_sandbox=True):
|
|
|
158
158
|
'typ': 'JWT'
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
# Add content
|
|
161
|
+
# Add content SHA-256 for requests with body
|
|
162
162
|
body_string = None
|
|
163
163
|
if request_body:
|
|
164
164
|
body_string = create_minimized_json(request_body)
|
|
165
|
-
|
|
166
|
-
hashlib.
|
|
165
|
+
content_sha256 = base64.b64encode(
|
|
166
|
+
hashlib.sha256(body_string.encode('utf-8')).digest()
|
|
167
167
|
).decode('utf-8')
|
|
168
|
-
header['
|
|
168
|
+
header['contentSha256'] = content_sha256
|
|
169
169
|
|
|
170
170
|
# Create JWT payload
|
|
171
171
|
payload = {
|
|
@@ -179,7 +179,7 @@ def create_jwt_token(request_body=None, use_sandbox=True):
|
|
|
179
179
|
return token, body_string
|
|
180
180
|
|
|
181
181
|
def create_minimized_json(data):
|
|
182
|
-
"""Create deterministic minimized JSON for
|
|
182
|
+
"""Create deterministic minimized JSON for SHA-256 calculation"""
|
|
183
183
|
def sort_dict(obj):
|
|
184
184
|
if isinstance(obj, dict):
|
|
185
185
|
return {k: sort_dict(v) for k, v in sorted(obj.items())}
|
|
@@ -415,15 +415,15 @@ function createJWTToken(requestBody = null, useSandbox = true) {
|
|
|
415
415
|
typ: 'JWT'
|
|
416
416
|
};
|
|
417
417
|
|
|
418
|
-
// Add content
|
|
418
|
+
// Add content SHA-256 for requests with body
|
|
419
419
|
let bodyString = null;
|
|
420
420
|
if (requestBody) {
|
|
421
421
|
bodyString = createMinimizedJSON(requestBody);
|
|
422
|
-
const
|
|
423
|
-
.createHash('
|
|
422
|
+
const contentSha256 = crypto
|
|
423
|
+
.createHash('sha256')
|
|
424
424
|
.update(bodyString, 'utf8')
|
|
425
425
|
.digest('base64');
|
|
426
|
-
header.
|
|
426
|
+
header.contentSha256 = contentSha256;
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
// Create JWT payload
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Generate code examples for different programming languages
|
|
3
3
|
*
|
|
4
4
|
* PAYWARE REQUIREMENT: All examples must demonstrate using the EXACT same
|
|
5
|
-
* compact JSON string for both JWT
|
|
5
|
+
* compact JSON string for both JWT contentSha256 calculation and HTTP body.
|
|
6
6
|
*
|
|
7
7
|
* Examples use deterministic serialization to guarantee this consistency.
|
|
8
8
|
*/
|
|
@@ -41,7 +41,7 @@ with open('private_key.pem', 'r') as f:
|
|
|
41
41
|
def create_deterministic_json(data):
|
|
42
42
|
"""Create consistent compact JSON for payware API
|
|
43
43
|
|
|
44
|
-
REQUIREMENT: The exact same string must be used for JWT
|
|
44
|
+
REQUIREMENT: The exact same string must be used for JWT contentSha256 and HTTP body.
|
|
45
45
|
SOLUTION: Sort keys to guarantee consistent output across all platforms.
|
|
46
46
|
"""
|
|
47
47
|
# Sort keys recursively to ensure deterministic output
|
|
@@ -66,11 +66,11 @@ def create_jwt_token(request_body=None):
|
|
|
66
66
|
'typ': 'JWT'
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
# Add content
|
|
69
|
+
# Add content SHA-256 for POST requests
|
|
70
70
|
if request_body:
|
|
71
71
|
body_string = create_deterministic_json(request_body)
|
|
72
|
-
|
|
73
|
-
header['
|
|
72
|
+
content_sha256 = base64.b64encode(hashlib.sha256(body_string.encode('utf-8')).digest()).decode('utf-8')
|
|
73
|
+
header['contentSha256'] = content_sha256
|
|
74
74
|
|
|
75
75
|
# JWT payload
|
|
76
76
|
payload = {
|
|
@@ -106,8 +106,8 @@ def create_transaction():
|
|
|
106
106
|
'Api-Version': '1'
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
# CRITICAL: Send the EXACT same string used for JWT
|
|
110
|
-
# This prevents
|
|
109
|
+
# CRITICAL: Send the EXACT same string used for JWT contentSha256 calculation
|
|
110
|
+
# This prevents ERR_INVALID_CONTENT_HASH authentication errors
|
|
111
111
|
response = requests.post(f"{SANDBOX_URL}/transactions", data=deterministic_body, headers=headers)
|
|
112
112
|
return response.json()
|
|
113
113
|
|
|
@@ -161,9 +161,9 @@ def create_jwt_token(request_body=None):
|
|
|
161
161
|
'typ': 'JWT'
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
# Add content
|
|
164
|
+
# Add content SHA-256 for requests with body
|
|
165
165
|
if request_body:
|
|
166
|
-
# PAYWARE REQUIREMENT: Same string for JWT
|
|
166
|
+
# PAYWARE REQUIREMENT: Same string for JWT SHA-256 and HTTP body
|
|
167
167
|
# SOLUTION: Use deterministic serialization (sorted keys)
|
|
168
168
|
def sort_dict(obj):
|
|
169
169
|
if isinstance(obj, dict):
|
|
@@ -175,8 +175,8 @@ def create_jwt_token(request_body=None):
|
|
|
175
175
|
|
|
176
176
|
sorted_data = sort_dict(request_body)
|
|
177
177
|
body_string = json.dumps(sorted_data, separators=(',', ':'))
|
|
178
|
-
|
|
179
|
-
header['
|
|
178
|
+
content_sha256 = base64.b64encode(hashlib.sha256(body_string.encode('utf-8')).digest()).decode('utf-8')
|
|
179
|
+
header['contentSha256'] = content_sha256
|
|
180
180
|
|
|
181
181
|
# JWT payload
|
|
182
182
|
payload = {
|
|
@@ -233,7 +233,7 @@ def create_transaction(jwt_token):
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
# PAYWARE REQUIREMENT: Same string for JWT
|
|
236
|
+
# PAYWARE REQUIREMENT: Same string for JWT SHA-256 and HTTP body
|
|
237
237
|
# SOLUTION: Use deterministic serialization (sorted keys)
|
|
238
238
|
def sort_dict(obj):
|
|
239
239
|
if isinstance(obj, dict):
|
|
@@ -254,7 +254,7 @@ def create_transaction(jwt_token):
|
|
|
254
254
|
|
|
255
255
|
return response.json()
|
|
256
256
|
|
|
257
|
-
# Note: JWT token must include
|
|
257
|
+
# Note: JWT token must include contentSha256 hash for the request body
|
|
258
258
|
# Use the auth_only example to create a proper token with body hash`;
|
|
259
259
|
|
|
260
260
|
default:
|
|
@@ -290,7 +290,7 @@ const SANDBOX_URL = 'https://sandbox.payware.eu/api';
|
|
|
290
290
|
const PRIVATE_KEY = fs.readFileSync('private_key.pem', 'utf8');
|
|
291
291
|
|
|
292
292
|
function createDeterministicJSON(data) {
|
|
293
|
-
// PAYWARE REQUIREMENT: Same compact JSON for JWT
|
|
293
|
+
// PAYWARE REQUIREMENT: Same compact JSON for JWT SHA-256 and HTTP body
|
|
294
294
|
// SOLUTION: Sort keys to guarantee consistent output
|
|
295
295
|
function sortObject(obj) {
|
|
296
296
|
if (Array.isArray(obj)) {
|
|
@@ -318,12 +318,12 @@ function createJWTToken(requestBody = null) {
|
|
|
318
318
|
typ: 'JWT'
|
|
319
319
|
};
|
|
320
320
|
|
|
321
|
-
// Add content
|
|
321
|
+
// Add content SHA-256 for POST requests
|
|
322
322
|
let deterministicBody = null;
|
|
323
323
|
if (requestBody) {
|
|
324
324
|
deterministicBody = createDeterministicJSON(requestBody);
|
|
325
|
-
const
|
|
326
|
-
header.
|
|
325
|
+
const contentSha256 = crypto.createHash('sha256').update(deterministicBody, 'utf8').digest('base64');
|
|
326
|
+
header.contentSha256 = contentSha256;
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
// JWT payload
|
|
@@ -361,8 +361,8 @@ async function createTransaction() {
|
|
|
361
361
|
};
|
|
362
362
|
|
|
363
363
|
try {
|
|
364
|
-
// CRITICAL: Send the EXACT same string used for JWT
|
|
365
|
-
// This prevents
|
|
364
|
+
// CRITICAL: Send the EXACT same string used for JWT contentSha256 calculation
|
|
365
|
+
// This prevents ERR_INVALID_CONTENT_HASH authentication errors
|
|
366
366
|
const response = await axios.post(\`\${SANDBOX_URL}/transactions\`, deterministicBody, {
|
|
367
367
|
headers,
|
|
368
368
|
// Tell axios to send the string as-is, don't serialize it again
|
|
@@ -429,9 +429,9 @@ function createJWTToken(requestBody = null) {
|
|
|
429
429
|
typ: 'JWT'
|
|
430
430
|
};
|
|
431
431
|
|
|
432
|
-
// Add content
|
|
432
|
+
// Add content SHA-256 for requests with body
|
|
433
433
|
if (requestBody) {
|
|
434
|
-
// PAYWARE REQUIREMENT: Same string for JWT
|
|
434
|
+
// PAYWARE REQUIREMENT: Same string for JWT SHA-256 and HTTP body
|
|
435
435
|
// SOLUTION: Use deterministic serialization (sorted keys)
|
|
436
436
|
function sortObject(obj) {
|
|
437
437
|
if (Array.isArray(obj)) {
|
|
@@ -448,8 +448,8 @@ function createJWTToken(requestBody = null) {
|
|
|
448
448
|
|
|
449
449
|
const sortedData = sortObject(requestBody);
|
|
450
450
|
const bodyString = JSON.stringify(sortedData);
|
|
451
|
-
const
|
|
452
|
-
header.
|
|
451
|
+
const contentSha256 = crypto.createHash('sha256').update(bodyString, 'utf8').digest('base64');
|
|
452
|
+
header.contentSha256 = contentSha256;
|
|
453
453
|
}
|
|
454
454
|
|
|
455
455
|
// JWT payload
|
|
@@ -617,7 +617,7 @@ ${code}
|
|
|
617
617
|
- Includes required \`Api-Version: 1\` header
|
|
618
618
|
- Uses proper request body structure with \`trData\` and \`trOptions\`
|
|
619
619
|
- JWT includes \`aud: 'https://payware.eu'\` claim
|
|
620
|
-
- POST requests include \`
|
|
620
|
+
- POST requests include \`contentSha256\` hash in JWT header
|
|
621
621
|
- Amount format uses decimal strings (e.g., '10.00')
|
|
622
622
|
- Uses \`reasonL1\`/\`reasonL2\` instead of \`description\`
|
|
623
623
|
|
|
@@ -241,7 +241,7 @@ ${formatted.request.trData.reasonL2 ? `- Description L2: ${formatted.request.trD
|
|
|
241
241
|
${formatted.request.callbackUrl ? `- Callback URL: ${formatted.request.callbackUrl}` : ''}
|
|
242
242
|
|
|
243
243
|
**Usage:**
|
|
244
|
-
Use the minimized JSON format for API calls to ensure
|
|
244
|
+
Use the minimized JSON format for API calls to ensure SHA-256 consistency:
|
|
245
245
|
\`\`\`javascript
|
|
246
246
|
const response = await fetch('https://sandbox.payware.eu/api/transactions', {
|
|
247
247
|
method: 'POST',
|
|
@@ -249,11 +249,11 @@ const response = await fetch('https://sandbox.payware.eu/api/transactions', {
|
|
|
249
249
|
'Authorization': 'Bearer YOUR_JWT_TOKEN',
|
|
250
250
|
'Content-Type': 'application/json'
|
|
251
251
|
},
|
|
252
|
-
body: '${minimizedJSON}' // Use pre-minimized string for
|
|
252
|
+
body: '${minimizedJSON}' // Use pre-minimized string for SHA-256 consistency
|
|
253
253
|
});
|
|
254
254
|
\`\`\`
|
|
255
255
|
|
|
256
|
-
**⚠️ Important:** Always use the minimized JSON format to ensure the
|
|
256
|
+
**⚠️ Important:** Always use the minimized JSON format to ensure the SHA-256 hash in your JWT token matches the request body.
|
|
257
257
|
|
|
258
258
|
**Formatted:** ${formatted.formatted}
|
|
259
259
|
**Timestamp:** ${formatted.timestamp}`
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { createDeterministicJSON, validateJSONConsistency } from '../core/utils/json-serializer.js';
|
|
7
|
-
import {
|
|
7
|
+
import { generateContentSha256 } from '../core/auth/jwt-token.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Format JSON with deterministic serialization tool
|
|
11
11
|
*/
|
|
12
12
|
export const formatJSONDeterministicTool = {
|
|
13
13
|
name: "payware_utils_format_json_deterministic",
|
|
14
|
-
description: "Format JSON payload with deterministic key sorting for consistent
|
|
14
|
+
description: "Format JSON payload with deterministic key sorting for consistent SHA-256 calculation and payware API compliance",
|
|
15
15
|
inputSchema: {
|
|
16
16
|
type: "object",
|
|
17
17
|
properties: {
|
|
@@ -24,9 +24,9 @@ export const formatJSONDeterministicTool = {
|
|
|
24
24
|
description: "Show comparison between standard and deterministic JSON",
|
|
25
25
|
default: true
|
|
26
26
|
},
|
|
27
|
-
|
|
27
|
+
calculateSHA256: {
|
|
28
28
|
type: "boolean",
|
|
29
|
-
description: "Calculate
|
|
29
|
+
description: "Calculate SHA-256 hash for JWT contentSha256 usage",
|
|
30
30
|
default: true
|
|
31
31
|
},
|
|
32
32
|
validateConsistency: {
|
|
@@ -43,7 +43,7 @@ export const formatJSONDeterministicTool = {
|
|
|
43
43
|
const {
|
|
44
44
|
payload,
|
|
45
45
|
showComparison = true,
|
|
46
|
-
|
|
46
|
+
calculateSHA256 = true,
|
|
47
47
|
validateConsistency = false
|
|
48
48
|
} = args;
|
|
49
49
|
|
|
@@ -57,8 +57,8 @@ export const formatJSONDeterministicTool = {
|
|
|
57
57
|
const prettyJson = JSON.stringify(payload, null, 2);
|
|
58
58
|
const deterministicJson = createDeterministicJSON(payload);
|
|
59
59
|
|
|
60
|
-
// Calculate
|
|
61
|
-
const
|
|
60
|
+
// Calculate SHA-256 hash
|
|
61
|
+
const sha256Hash = calculateSHA256 ? generateContentSha256(payload) : null;
|
|
62
62
|
|
|
63
63
|
// Get key ordering information
|
|
64
64
|
const originalKeys = Object.keys(payload);
|
|
@@ -115,27 +115,27 @@ ${isAlreadySorted ?
|
|
|
115
115
|
'- ✅ Your object keys are already in sorted order' :
|
|
116
116
|
`- ❌ Keys will be reordered: ${originalKeys.join(' → ')} becomes ${sortedKeys.join(' → ')}`}
|
|
117
117
|
- ✅ Deterministic JSON ensures consistent serialization across platforms
|
|
118
|
-
- ✅ Required for accurate
|
|
118
|
+
- ✅ Required for accurate SHA-256 hash calculation in JWT tokens
|
|
119
119
|
` : ''}
|
|
120
120
|
|
|
121
121
|
## ✅ **payware API Ready JSON**
|
|
122
122
|
|
|
123
|
-
Use this exact JSON string for both JWT
|
|
123
|
+
Use this exact JSON string for both JWT SHA-256 calculation and HTTP request body:
|
|
124
124
|
|
|
125
125
|
\`\`\`json
|
|
126
126
|
${deterministicJson}
|
|
127
127
|
\`\`\`
|
|
128
128
|
|
|
129
|
-
${
|
|
129
|
+
${calculateSHA256 ? `## 🔒 **SHA-256 Hash for JWT**
|
|
130
130
|
|
|
131
|
-
**
|
|
131
|
+
**contentSha256**: \`${sha256Hash}\`
|
|
132
132
|
|
|
133
133
|
**Usage in JWT Header**:
|
|
134
134
|
\`\`\`json
|
|
135
135
|
{
|
|
136
136
|
"alg": "RS256",
|
|
137
137
|
"typ": "JWT",
|
|
138
|
-
"
|
|
138
|
+
"contentSha256": "${sha256Hash}"
|
|
139
139
|
}
|
|
140
140
|
\`\`\`
|
|
141
141
|
` : ''}
|
|
@@ -187,22 +187,22 @@ ${consistencyTest ? `## 🧪 **Consistency Validation**
|
|
|
187
187
|
|
|
188
188
|
**All Match**: ${consistencyTest.allMatch ? '✅ Consistent' : '❌ Inconsistent'}
|
|
189
189
|
|
|
190
|
-
${!consistencyTest.allMatch ? '⚠️ **Warning**: Inconsistent serialization detected. This could cause
|
|
190
|
+
${!consistencyTest.allMatch ? '⚠️ **Warning**: Inconsistent serialization detected. This could cause SHA-256 mismatches.' : ''}
|
|
191
191
|
` : ''}
|
|
192
192
|
|
|
193
193
|
## ⚠️ **PAYWARE Critical Requirements**
|
|
194
194
|
|
|
195
|
-
1. **Same String Requirement**: The EXACT same compact JSON string must be used for both JWT
|
|
195
|
+
1. **Same String Requirement**: The EXACT same compact JSON string must be used for both JWT contentSha256 and HTTP request body
|
|
196
196
|
2. **Compact Format**: No extra whitespace (spaces, newlines) in JSON
|
|
197
197
|
3. **Consistent Serialization**: Use deterministic serialization to prevent variations
|
|
198
|
-
4. **
|
|
198
|
+
4. **SHA-256 Consistency**: Any difference will cause ERR_INVALID_CONTENT_HASH authentication failures
|
|
199
199
|
|
|
200
200
|
Note: Sorted keys are our METHOD to guarantee requirement #1, not a payware requirement itself.
|
|
201
201
|
|
|
202
202
|
## 🔗 **Next Steps**
|
|
203
203
|
|
|
204
204
|
1. Use the deterministic JSON above in your API request
|
|
205
|
-
2. Include the
|
|
205
|
+
2. Include the SHA-256 hash in your JWT header${calculateSHA256 ? ` (\`${sha256Hash}\`)` : ''}
|
|
206
206
|
3. Send the exact same JSON string in your HTTP request body
|
|
207
207
|
4. Verify with \`payware_authentication_validate_jwt\` tool
|
|
208
208
|
|
|
@@ -211,7 +211,7 @@ Note: Sorted keys are our METHOD to guarantee requirement #1, not a payware requ
|
|
|
211
211
|
- Tool: payware_utils_format_json_deterministic
|
|
212
212
|
- Keys Processed: ${originalKeys.length}
|
|
213
213
|
- Sorting Required: ${!isAlreadySorted}
|
|
214
|
-
-
|
|
214
|
+
- SHA-256 Calculated: ${calculateSHA256}
|
|
215
215
|
- Executed: ${new Date().toISOString()}
|
|
216
216
|
- Status: ✅ Complete`
|
|
217
217
|
}]
|
|
@@ -228,10 +228,10 @@ Note: Sorted keys are our METHOD to guarantee requirement #1, not a payware requ
|
|
|
228
228
|
- Invalid JSON structure
|
|
229
229
|
- Circular references in payload
|
|
230
230
|
- Non-serializable values (functions, undefined, etc.)
|
|
231
|
-
- Different JSON strings used for JWT
|
|
231
|
+
- Different JSON strings used for JWT SHA-256 vs HTTP body
|
|
232
232
|
|
|
233
|
-
**Debug Steps for
|
|
234
|
-
1. Verify the SAME string is used for JWT
|
|
233
|
+
**Debug Steps for SHA-256 Errors**:
|
|
234
|
+
1. Verify the SAME string is used for JWT contentSha256 and HTTP body
|
|
235
235
|
2. Check for extra whitespace or formatting differences
|
|
236
236
|
3. Ensure consistent property ordering (use deterministic serialization)
|
|
237
237
|
4. Validate that objects are properly serializable
|
package/src/utils/server-info.js
CHANGED
|
File without changes
|
package/MCP-SETUP.md
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
# payware MCP Server Configuration
|
|
2
|
-
|
|
3
|
-
This document explains how to configure the payware MCP server for use with Claude Code or other MCP clients.
|
|
4
|
-
|
|
5
|
-
## Configuration Files
|
|
6
|
-
|
|
7
|
-
### 1. `mcp-config.json` - Simple Configuration
|
|
8
|
-
Basic MCP server configuration for Claude Code:
|
|
9
|
-
|
|
10
|
-
```json
|
|
11
|
-
{
|
|
12
|
-
"mcpServers": {
|
|
13
|
-
"payware": {
|
|
14
|
-
"command": "node",
|
|
15
|
-
"args": ["src/index.js"],
|
|
16
|
-
"cwd": "."
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### 2. `payware-mcp-config.json` - Production Configuration
|
|
23
|
-
Enhanced configuration with environment variables:
|
|
24
|
-
|
|
25
|
-
```json
|
|
26
|
-
{
|
|
27
|
-
"mcpServers": {
|
|
28
|
-
"payware": {
|
|
29
|
-
"command": "node",
|
|
30
|
-
"args": ["src/index.js"],
|
|
31
|
-
"cwd": "/mnt/d/git/payware/mcp",
|
|
32
|
-
"env": {
|
|
33
|
-
"NODE_ENV": "production"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 3. `claude-code-config.json` - Full Documentation
|
|
41
|
-
Complete configuration with metadata and documentation.
|
|
42
|
-
|
|
43
|
-
## Setup Instructions
|
|
44
|
-
|
|
45
|
-
### For Claude Code Users
|
|
46
|
-
|
|
47
|
-
1. **Choose Configuration File**
|
|
48
|
-
- Use `mcp-config.json` for simple setup
|
|
49
|
-
- Use `payware-mcp-config.json` for production
|
|
50
|
-
- Use `claude-code-config.json` for full documentation
|
|
51
|
-
|
|
52
|
-
2. **Configure Claude Code**
|
|
53
|
-
- Copy the chosen configuration to your Claude Code MCP settings
|
|
54
|
-
- Update the `cwd` path to match your payware MCP server location
|
|
55
|
-
- Ensure Node.js is available in your PATH
|
|
56
|
-
|
|
57
|
-
3. **Start payware MCP Server**
|
|
58
|
-
```bash
|
|
59
|
-
cd /path/to/payware/mcp
|
|
60
|
-
npm install
|
|
61
|
-
node src/index.js
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
4. **Test Connection**
|
|
65
|
-
- Open Claude Code
|
|
66
|
-
- Try using `payware_generate_code_example` tool
|
|
67
|
-
- Verify the server responds correctly
|
|
68
|
-
|
|
69
|
-
### Environment Setup
|
|
70
|
-
|
|
71
|
-
Create a `.env` file in the payware MCP directory:
|
|
72
|
-
|
|
73
|
-
```env
|
|
74
|
-
# API Configuration
|
|
75
|
-
PAYWARE_SANDBOX_URL=https://sandbox.payware.eu/api
|
|
76
|
-
PAYWARE_PRODUCTION_URL=https://api.payware.eu/api
|
|
77
|
-
|
|
78
|
-
# Partner Configuration (set these for testing)
|
|
79
|
-
PAYWARE_PARTNER_ID=your_partner_id
|
|
80
|
-
PAYWARE_PRIVATE_KEY_FILE=keys/private-key.pem
|
|
81
|
-
|
|
82
|
-
# Server Configuration
|
|
83
|
-
NODE_ENV=development
|
|
84
|
-
PORT=3000
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Available Tools
|
|
88
|
-
|
|
89
|
-
### 1. `payware_generate_code_example`
|
|
90
|
-
Generate production-ready code examples for payware API integration.
|
|
91
|
-
|
|
92
|
-
**Parameters:**
|
|
93
|
-
- `operation`: API operation (create_transaction, get_product, etc.)
|
|
94
|
-
- `language`: Programming language (python, nodejs, php, java, csharp, curl)
|
|
95
|
-
- `partner_type`: Partner type (merchant, isv, payment_institution)
|
|
96
|
-
- `include_comments`: Include detailed comments (default: true)
|
|
97
|
-
- `include_error_handling`: Include error handling (default: true)
|
|
98
|
-
|
|
99
|
-
**Example:**
|
|
100
|
-
```javascript
|
|
101
|
-
payware_generate_code_example({
|
|
102
|
-
operation: "create_transaction",
|
|
103
|
-
language: "python",
|
|
104
|
-
partner_type: "merchant"
|
|
105
|
-
})
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### 2. `payware_generate_documentation`
|
|
109
|
-
Generate comprehensive integration documentation.
|
|
110
|
-
|
|
111
|
-
**Parameters:**
|
|
112
|
-
- `language`: Programming language focus
|
|
113
|
-
- `partner_type`: Partner type for documentation scope
|
|
114
|
-
|
|
115
|
-
**Example:**
|
|
116
|
-
```javascript
|
|
117
|
-
payware_generate_documentation({
|
|
118
|
-
language: "nodejs",
|
|
119
|
-
partner_type: "merchant"
|
|
120
|
-
})
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Supported Features
|
|
124
|
-
|
|
125
|
-
- **18+ Operations**: Complete API coverage
|
|
126
|
-
- **6 Languages**: python, nodejs, php, java, csharp, curl
|
|
127
|
-
- **3 Partner Types**: merchant, isv, payment_institution
|
|
128
|
-
- **JWT Authentication**: RS256 with content MD5
|
|
129
|
-
- **Error Handling**: Comprehensive try/catch patterns
|
|
130
|
-
- **Production Ready**: Immediately usable code
|
|
131
|
-
|
|
132
|
-
## Troubleshooting
|
|
133
|
-
|
|
134
|
-
### Common Issues
|
|
135
|
-
|
|
136
|
-
1. **"Command not found: node"**
|
|
137
|
-
- Ensure Node.js is installed and in PATH
|
|
138
|
-
- Update `command` in config to full path: `/usr/bin/node`
|
|
139
|
-
|
|
140
|
-
2. **"Cannot find module"**
|
|
141
|
-
- Run `npm install` in the payware MCP directory
|
|
142
|
-
- Check that `cwd` path is correct in configuration
|
|
143
|
-
|
|
144
|
-
3. **"Server not responding"**
|
|
145
|
-
- Verify the server starts without errors
|
|
146
|
-
- Check that port 3000 (or configured port) is available
|
|
147
|
-
- Review server logs for error messages
|
|
148
|
-
|
|
149
|
-
### Verification Steps
|
|
150
|
-
|
|
151
|
-
1. **Manual Server Test**
|
|
152
|
-
```bash
|
|
153
|
-
cd /path/to/payware/mcp
|
|
154
|
-
node src/index.js
|
|
155
|
-
# Should start without errors
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
2. **MCP Protocol Test**
|
|
159
|
-
```bash
|
|
160
|
-
# Test MCP communication (if tools available)
|
|
161
|
-
echo '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {}}' | node src/index.js
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
3. **Claude Code Integration Test**
|
|
165
|
-
- Add server to Claude Code settings
|
|
166
|
-
- Open new conversation
|
|
167
|
-
- Try: `payware_generate_code_example({operation: "authentication", language: "python"})`
|
|
168
|
-
|
|
169
|
-
## Support
|
|
170
|
-
|
|
171
|
-
For issues with MCP server configuration or integration:
|
|
172
|
-
|
|
173
|
-
1. Check server logs for error messages
|
|
174
|
-
2. Verify Node.js and npm versions
|
|
175
|
-
3. Ensure all dependencies are installed
|
|
176
|
-
4. Test with simple configuration first
|
|
177
|
-
5. Review Claude Code MCP documentation
|
|
178
|
-
|
|
179
|
-
## Security Notes
|
|
180
|
-
|
|
181
|
-
- Store private keys securely outside the repository
|
|
182
|
-
- Use environment variables for sensitive configuration
|
|
183
|
-
- Test with sandbox environment before production
|
|
184
|
-
- Regularly rotate API credentials and private keys
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
**Version**: 1.0.0
|
|
189
|
-
**Last Updated**: 2024-01-20
|
|
190
|
-
**Compatible with**: Claude Code, MCP Protocol v1.0
|