@payware/mcp-server 1.1.0 → 1.2.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/MCP-SETUP.md +0 -0
- package/README.md +56 -17
- package/check-keys.js +0 -0
- package/keys/README.md +0 -0
- package/mcp-config.json +0 -0
- package/package.json +1 -1
- package/payware-mcp-config.json +0 -0
- package/src/auth/rsa-keys.js +0 -0
- package/src/auth/sandbox-setup.js +2 -2
- 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 +0 -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 +0 -0
- package/src/isv/oauth2/token-helper.js +0 -0
- package/src/isv/poi/cancel-price.js +0 -0
- package/src/isv/poi/get-poi.js +0 -0
- package/src/isv/poi/get-qrcode.js +0 -0
- package/src/isv/poi/get-status.js +0 -0
- package/src/isv/poi/index.js +0 -0
- package/src/isv/poi/list-pois.js +0 -0
- package/src/isv/poi/set-price.js +0 -0
- package/src/isv/products/audios.js +0 -0
- package/src/isv/products/create-product.js +0 -0
- 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 +0 -0
- package/src/isv/transactions/cancel-transaction.js +2 -2
- package/src/isv/transactions/create-transaction.js +2 -2
- package/src/isv/transactions/get-status.js +0 -0
- package/src/isv/transactions/process-transaction.js +2 -2
- package/src/isv/transactions/simulate-callback.js +2 -2
- package/src/isv/transactions/transaction-history.js +0 -0
- 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 +0 -0
- 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 +0 -0
- package/src/merchant/products/audios.js +0 -0
- package/src/merchant/products/create-product.js +0 -0
- 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 +0 -0
- package/src/merchant/transactions/cancel-transaction.js +6 -6
- package/src/merchant/transactions/create-transaction.js +13 -13
- package/src/merchant/transactions/get-status.js +1 -1
- package/src/merchant/transactions/process-transaction.js +6 -6
- package/src/merchant/transactions/simulate-callback.js +0 -0
- package/src/merchant/transactions/transaction-history.js +1 -1
- 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 +4 -4
- package/src/payment-institution/transactions/finalize-transaction.js +3 -3
- 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 +3 -3
- package/src/payment-institution/transactions/simulate-pi-callback.js +0 -0
- package/src/payment-institution/transactions/soundbite-transaction.js +3 -3
- package/src/proxy-server.js +0 -0
- package/src/shared/data/data-api.js +0 -0
- package/src/shared/deep-links/api.js +0 -0
- package/src/shared/index.js +0 -0
- package/src/shared/products/products-api.js +0 -0
- package/src/tools/advanced-code-generator.js +53 -53
- package/src/utils/code-examples/common/auth-examples.js +38 -38
- package/src/utils/code-examples/common/helpers.js +0 -0
- 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 +0 -0
- package/src/utils/code-examples/isv/products.js +8 -8
- package/src/utils/code-examples/isv/transactions.js +9 -9
- 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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* JSON Consistency Utilities for payware API
|
|
3
3
|
*
|
|
4
4
|
* CORE REQUIREMENT: The exact same compact JSON string must be used for
|
|
5
|
-
* both JWT
|
|
5
|
+
* both JWT contentSha256 calculation and HTTP request body to prevent hash mismatches.
|
|
6
6
|
*
|
|
7
7
|
* SOLUTION: We use deterministic serialization (sorted keys) to guarantee
|
|
8
8
|
* consistent JSON output regardless of object property insertion order.
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
* Create consistent compact JSON string for payware API requests
|
|
16
16
|
*
|
|
17
17
|
* CORE REQUIREMENT: payware API requires that the exact same compact JSON string
|
|
18
|
-
* is used for both JWT
|
|
18
|
+
* is used for both JWT contentSha256 calculation and the HTTP request body.
|
|
19
19
|
*
|
|
20
20
|
* SOLUTION: This function uses deterministic serialization with sorted keys
|
|
21
|
-
* to guarantee the same output every time, preventing
|
|
21
|
+
* to guarantee the same output every time, preventing hash mismatch errors.
|
|
22
22
|
*
|
|
23
23
|
* @param {Object} obj - Object to serialize
|
|
24
24
|
* @returns {string} Compact JSON string with sorted keys (no whitespace)
|
|
@@ -72,7 +72,7 @@ function sortObjectKeys(obj) {
|
|
|
72
72
|
*
|
|
73
73
|
* payware REQUIRES:
|
|
74
74
|
* 1. JSON must be compact (no extra whitespace)
|
|
75
|
-
* 2. The EXACT same string must be used for JWT
|
|
75
|
+
* 2. The EXACT same string must be used for JWT contentSha256 and HTTP body
|
|
76
76
|
*
|
|
77
77
|
* This function ensures both requirements by using deterministic serialization.
|
|
78
78
|
*
|
|
@@ -86,7 +86,7 @@ export function createMinimizedJSON(requestBody) {
|
|
|
86
86
|
/**
|
|
87
87
|
* Validate that two objects produce the same JSON string
|
|
88
88
|
*
|
|
89
|
-
* This is crucial for payware API because the JWT
|
|
89
|
+
* This is crucial for payware API because the JWT contentSha256 and HTTP body
|
|
90
90
|
* must use the exact same string. This function helps test that requirement.
|
|
91
91
|
*
|
|
92
92
|
* @param {Object} obj1 - First object
|
|
File without changes
|
package/src/index.js
CHANGED
|
File without changes
|
package/src/isv/data/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/isv/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/isv/poi/get-poi.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/isv/poi/index.js
CHANGED
|
File without changes
|
package/src/isv/poi/list-pois.js
CHANGED
|
File without changes
|
package/src/isv/poi/set-price.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -31,13 +31,13 @@ export async function cancelTransaction({ transactionId, merchantPartnerId, oaut
|
|
|
31
31
|
oauth2Token
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
// Use the same JSON serialization method as the JWT factory for
|
|
34
|
+
// Use the same JSON serialization method as the JWT factory for SHA-256 calculation
|
|
35
35
|
const { createMinimizedJSON } = await import('../../core/utils/json-serializer.js');
|
|
36
36
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
37
37
|
|
|
38
38
|
try {
|
|
39
39
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
40
|
-
// Send the exact minimized JSON string that was used for
|
|
40
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
41
41
|
const response = await axios.delete(`${baseUrl}/transactions/${transactionId}`, {
|
|
42
42
|
headers: {
|
|
43
43
|
'Authorization': `Bearer ${jwtData.token}`,
|
|
@@ -119,13 +119,13 @@ export async function createTransaction({
|
|
|
119
119
|
oauth2Token
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
-
// Use the same JSON serialization method as the JWT factory for
|
|
122
|
+
// Use the same JSON serialization method as the JWT factory for SHA-256 calculation
|
|
123
123
|
const { createMinimizedJSON } = await import('../../core/utils/json-serializer.js');
|
|
124
124
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
127
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
128
|
-
// Send the exact minimized JSON string that was used for
|
|
128
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
129
129
|
const response = await axios.post(`${baseUrl}/transactions`, minimizedBodyString, {
|
|
130
130
|
headers: {
|
|
131
131
|
'Authorization': `Bearer ${jwtData.token}`,
|
|
File without changes
|
|
@@ -35,13 +35,13 @@ export async function processTransaction({ transactionId, merchantPartnerId, oau
|
|
|
35
35
|
oauth2Token
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
// Use the same JSON serialization method as the JWT factory for
|
|
38
|
+
// Use the same JSON serialization method as the JWT factory for SHA-256 calculation
|
|
39
39
|
const { createMinimizedJSON } = await import('../../core/utils/json-serializer.js');
|
|
40
40
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
41
41
|
|
|
42
42
|
try {
|
|
43
43
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
44
|
-
// Send the exact minimized JSON string that was used for
|
|
44
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
45
45
|
const response = await axios.patch(`${baseUrl}/transactions/${transactionId}`, minimizedBodyString, {
|
|
46
46
|
headers: {
|
|
47
47
|
'Authorization': `Bearer ${jwtData.token}`,
|
|
@@ -35,13 +35,13 @@ export async function simulateCallback({ transactionId, merchantPartnerId, oauth
|
|
|
35
35
|
oauth2Token
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
// Use the same JSON serialization method as the JWT factory for
|
|
38
|
+
// Use the same JSON serialization method as the JWT factory for SHA-256 calculation
|
|
39
39
|
const { createMinimizedJSON } = await import('../../core/utils/json-serializer.js');
|
|
40
40
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
41
41
|
|
|
42
42
|
try {
|
|
43
43
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
44
|
-
// Send the exact minimized JSON string that was used for
|
|
44
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
45
45
|
const response = await axios.post(`${baseUrl}/transactions/${transactionId}/simulate-callback`, minimizedBodyString, {
|
|
46
46
|
headers: {
|
|
47
47
|
'Authorization': `Bearer ${jwtData.token}`,
|
|
File without changes
|
package/src/isv/utils/auth.js
CHANGED
|
@@ -80,11 +80,11 @@ async function createOAuth2JWT({ isvPartnerId, privateKey, requestBody, audience
|
|
|
80
80
|
typ: 'JWT'
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
// Add
|
|
83
|
+
// Add contentSha256 to header if request body exists (SHA-256 is preferred over MD5)
|
|
84
84
|
if (requestBody) {
|
|
85
85
|
// Use standard JSON.stringify to match axios serialization (preserves property order)
|
|
86
86
|
const bodyString = JSON.stringify(requestBody);
|
|
87
|
-
header.
|
|
87
|
+
header.contentSha256 = crypto.default.createHash('sha256').update(bodyString, 'utf8').digest('base64');
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// JWT Payload for OAuth2 requests
|
package/src/mcp-proxy.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/merchant/index.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -37,21 +37,21 @@ export async function cancelTransaction({
|
|
|
37
37
|
statusMessage
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
-
// Convert to deterministic minimized JSON for
|
|
40
|
+
// Convert to deterministic minimized JSON for SHA-256 calculation
|
|
41
41
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
42
|
-
|
|
43
|
-
// Create JWT token with
|
|
42
|
+
|
|
43
|
+
// Create JWT token with contentSha256 for the request body (PATCH requires contentSha256)
|
|
44
44
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
// Required headers as per payware API documentation
|
|
47
47
|
const headers = {
|
|
48
48
|
'Authorization': `Bearer ${tokenData.token}`,
|
|
49
49
|
'Content-Type': 'application/json',
|
|
50
50
|
'Api-Version': '1' // Required: current API version
|
|
51
51
|
};
|
|
52
|
-
|
|
52
|
+
|
|
53
53
|
try {
|
|
54
|
-
// Send the exact minimized JSON string that was used for
|
|
54
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
55
55
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
56
56
|
const response = await axios.patch(`${baseUrl}/transactions/${transactionId}`, minimizedBodyString, {
|
|
57
57
|
headers,
|
|
@@ -99,10 +99,10 @@ export async function createTransaction({
|
|
|
99
99
|
...(type === 'BARCODE' && Object.keys(barOptions).length > 0 && { barOptions })
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
-
// Convert to deterministic minimized JSON as required by payware API for
|
|
102
|
+
// Convert to deterministic minimized JSON as required by payware API for SHA-256 calculation
|
|
103
103
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
104
|
-
|
|
105
|
-
// Create JWT token with
|
|
104
|
+
|
|
105
|
+
// Create JWT token with contentSha256 for the request body (POST requires contentSha256)
|
|
106
106
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
107
107
|
|
|
108
108
|
// Required headers as per payware API documentation
|
|
@@ -114,8 +114,8 @@ export async function createTransaction({
|
|
|
114
114
|
|
|
115
115
|
try {
|
|
116
116
|
|
|
117
|
-
// Send the exact minimized JSON string that was used for
|
|
118
|
-
// This ensures the server calculates the same
|
|
117
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
118
|
+
// This ensures the server calculates the same SHA-256 hash
|
|
119
119
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
120
120
|
const response = await axios.post(`${baseUrl}/transactions`, minimizedBodyString, {
|
|
121
121
|
headers,
|
|
@@ -130,15 +130,15 @@ export async function createTransaction({
|
|
|
130
130
|
timestamp: new Date().toISOString()
|
|
131
131
|
};
|
|
132
132
|
} catch (error) {
|
|
133
|
-
// Provide helpful error message for
|
|
133
|
+
// Provide helpful error message for hash mismatches
|
|
134
134
|
let enhancedMessage = error.response?.data?.message || error.message;
|
|
135
135
|
|
|
136
|
-
if (error.response?.data?.code === '
|
|
137
|
-
enhancedMessage?.includes('
|
|
138
|
-
enhancedMessage?.includes('
|
|
139
|
-
enhancedMessage = `
|
|
136
|
+
if (error.response?.data?.code === 'ERR_INVALID_CONTENT_HASH' ||
|
|
137
|
+
enhancedMessage?.includes('SHA-256') ||
|
|
138
|
+
enhancedMessage?.includes('contentSha256')) {
|
|
139
|
+
enhancedMessage = `Hash Mismatch Error: The contentSha256 in JWT header doesn't match the request body.
|
|
140
140
|
|
|
141
|
-
Cause: Different JSON strings were used for JWT
|
|
141
|
+
Cause: Different JSON strings were used for JWT contentSha256 calculation and HTTP body.
|
|
142
142
|
Solution: Ensure the EXACT same compact JSON string is used for both purposes.
|
|
143
143
|
|
|
144
144
|
Original error: ${enhancedMessage}`;
|
|
@@ -151,8 +151,8 @@ Original error: ${enhancedMessage}`;
|
|
|
151
151
|
status: error.response?.status,
|
|
152
152
|
code: error.response?.data?.code,
|
|
153
153
|
details: error.response?.data,
|
|
154
|
-
helpUrl: error.response?.data?.code === '
|
|
155
|
-
'https://github.com/payware/mcp-server#
|
|
154
|
+
helpUrl: error.response?.data?.code === 'ERR_INVALID_CONTENT_HASH' ?
|
|
155
|
+
'https://github.com/payware/mcp-server#sha256-consistency' : undefined
|
|
156
156
|
},
|
|
157
157
|
timestamp: new Date().toISOString()
|
|
158
158
|
};
|
|
@@ -16,7 +16,7 @@ export async function getTransactionStatus({ transactionId, partnerId, privateKe
|
|
|
16
16
|
throw new Error('Partner ID and private key are required for proper JWT creation');
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// Create JWT token without body (GET request - no
|
|
19
|
+
// Create JWT token without body (GET request - no contentSha256 required)
|
|
20
20
|
const tokenData = createJWTToken(partnerId, privateKey, null);
|
|
21
21
|
|
|
22
22
|
// Required headers as per payware API documentation
|
|
@@ -68,22 +68,22 @@ export async function processTransaction({
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
-
// Convert to deterministic minimized JSON for
|
|
71
|
+
// Convert to deterministic minimized JSON for SHA-256 calculation
|
|
72
72
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
73
|
-
|
|
74
|
-
// Create JWT token with
|
|
73
|
+
|
|
74
|
+
// Create JWT token with contentSha256 for the request body (POST requires contentSha256)
|
|
75
75
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
// Required headers as per payware API documentation
|
|
78
78
|
const headers = {
|
|
79
79
|
'Authorization': `Bearer ${tokenData.token}`,
|
|
80
80
|
'Content-Type': 'application/json',
|
|
81
81
|
'Api-Version': '1' // Required: current API version
|
|
82
82
|
};
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
try {
|
|
85
85
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
86
|
-
// Send the exact minimized JSON string that was used for
|
|
86
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
87
87
|
const response = await axios.post(`${baseUrl}/transactions/${transactionId}`, minimizedBodyString, {
|
|
88
88
|
headers,
|
|
89
89
|
// Tell axios to send the string as-is, don't serialize it again
|
|
File without changes
|
|
@@ -16,7 +16,7 @@ export async function getTransactionHistory({ transactionId, partnerId, privateK
|
|
|
16
16
|
throw new Error('Partner ID and private key are required for proper JWT creation');
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// Create JWT token without body (GET request - no
|
|
19
|
+
// Create JWT token without body (GET request - no contentSha256 required)
|
|
20
20
|
const tokenData = createJWTToken(partnerId, privateKey, null);
|
|
21
21
|
|
|
22
22
|
// Required headers as per payware API documentation
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -110,10 +110,10 @@ export async function createPITransaction({
|
|
|
110
110
|
...(type === 'BARCODE' && Object.keys(barOptions).length > 0 && { barOptions })
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
// Convert to deterministic minimized JSON as required by payware API for
|
|
113
|
+
// Convert to deterministic minimized JSON as required by payware API for SHA-256 calculation
|
|
114
114
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
115
115
|
|
|
116
|
-
// Create JWT token with
|
|
116
|
+
// Create JWT token with contentSha256 for the request body (POST requires contentSha256)
|
|
117
117
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
118
118
|
|
|
119
119
|
// Required headers as per payware API documentation
|
|
@@ -125,8 +125,8 @@ export async function createPITransaction({
|
|
|
125
125
|
|
|
126
126
|
try {
|
|
127
127
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
128
|
-
// Send the exact minimized JSON string that was used for
|
|
129
|
-
// This ensures the server calculates the same
|
|
128
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
129
|
+
// This ensures the server calculates the same SHA-256 hash
|
|
130
130
|
const response = await axios.post(`${baseUrl}/transactions`, minimizedBodyString, {
|
|
131
131
|
headers,
|
|
132
132
|
// Tell axios to send the string as-is, don't serialize it again
|
|
@@ -59,10 +59,10 @@ export async function finalizeTransaction({
|
|
|
59
59
|
})
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
-
// Convert to deterministic minimized JSON for
|
|
62
|
+
// Convert to deterministic minimized JSON for SHA-256 calculation
|
|
63
63
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
64
64
|
|
|
65
|
-
// Create JWT token with
|
|
65
|
+
// Create JWT token with contentSha256 for the request body (PATCH requires contentSha256)
|
|
66
66
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
67
67
|
|
|
68
68
|
// Required headers as per payware API documentation
|
|
@@ -74,7 +74,7 @@ export async function finalizeTransaction({
|
|
|
74
74
|
|
|
75
75
|
try {
|
|
76
76
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
77
|
-
// Send the exact minimized JSON string that was used for
|
|
77
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
78
78
|
const response = await axios.patch(`${baseUrl}/transactions/${transactionId}`, minimizedBodyString, {
|
|
79
79
|
headers,
|
|
80
80
|
// Tell axios to send the string as-is, don't serialize it again
|
|
@@ -21,7 +21,7 @@ export async function getPITransactionHistory({
|
|
|
21
21
|
throw new Error('Partner ID and private key are required for proper JWT creation');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// Create JWT token for GET request (no
|
|
24
|
+
// Create JWT token for GET request (no contentSha256 needed for GET)
|
|
25
25
|
const tokenData = createJWTToken(partnerId, privateKey, null);
|
|
26
26
|
|
|
27
27
|
// Required headers as per payware API documentation
|
|
@@ -21,7 +21,7 @@ export async function getPITransactionStatus({
|
|
|
21
21
|
throw new Error('Partner ID and private key are required for proper JWT creation');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
// Create JWT token for GET request (no
|
|
24
|
+
// Create JWT token for GET request (no contentSha256 needed for GET)
|
|
25
25
|
const tokenData = createJWTToken(partnerId, privateKey, null);
|
|
26
26
|
|
|
27
27
|
// Required headers as per payware API documentation
|
|
@@ -73,10 +73,10 @@ export async function processPITransaction({
|
|
|
73
73
|
...(deliveryAddress && { deliveryAddress })
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
// Convert to deterministic minimized JSON for
|
|
76
|
+
// Convert to deterministic minimized JSON for SHA-256 calculation
|
|
77
77
|
const minimizedBodyString = createMinimizedJSON(requestBody);
|
|
78
78
|
|
|
79
|
-
// Create JWT token with
|
|
79
|
+
// Create JWT token with contentSha256 for the request body (POST requires contentSha256)
|
|
80
80
|
const tokenData = createJWTToken(partnerId, privateKey, minimizedBodyString);
|
|
81
81
|
|
|
82
82
|
// Required headers as per payware API documentation
|
|
@@ -88,7 +88,7 @@ export async function processPITransaction({
|
|
|
88
88
|
|
|
89
89
|
try {
|
|
90
90
|
const baseUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
91
|
-
// Send the exact minimized JSON string that was used for
|
|
91
|
+
// Send the exact minimized JSON string that was used for SHA-256 calculation
|
|
92
92
|
const response = await axios.post(`${baseUrl}/transactions/${transactionId}`, minimizedBodyString, {
|
|
93
93
|
headers,
|
|
94
94
|
// Tell axios to send the string as-is, don't serialize it again
|
|
File without changes
|
|
@@ -37,8 +37,8 @@ export async function getSoundbiteTransaction({
|
|
|
37
37
|
contentType: 'application/octet-stream'
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
// For multipart/form-data requests, we don't calculate
|
|
41
|
-
// The JWT token is created without content
|
|
40
|
+
// For multipart/form-data requests, we don't calculate contentSha256 the same way
|
|
41
|
+
// The JWT token is created without content SHA-256 for multipart uploads
|
|
42
42
|
const tokenData = createJWTToken(partnerId, privateKey, null);
|
|
43
43
|
|
|
44
44
|
// Required headers as per payware API documentation
|
|
@@ -98,7 +98,7 @@ export const soundbiteTransactionTool = {
|
|
|
98
98
|
**API Request:**
|
|
99
99
|
- Uses multipart/form-data content type
|
|
100
100
|
- File uploaded as form field named 'file'
|
|
101
|
-
- JWT authentication without
|
|
101
|
+
- JWT authentication without contentSha256 (multipart upload)`,
|
|
102
102
|
inputSchema: {
|
|
103
103
|
type: "object",
|
|
104
104
|
properties: {
|
package/src/proxy-server.js
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/shared/index.js
CHANGED
|
File without changes
|
|
File without changes
|