@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,167 @@
|
|
|
1
|
+
import { getProductDeepLink } from '../../shared/deep-links/api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get deep link for a product (ISV on behalf of merchant)
|
|
6
|
+
*/
|
|
7
|
+
export const getProductLinkTool = {
|
|
8
|
+
name: "payware_deep_links_get_product_link",
|
|
9
|
+
description: `Get an active deep link for a product on behalf of a merchant. Returns a clickable URL that redirects to the payware mobile app.
|
|
10
|
+
|
|
11
|
+
**ISV Authentication:**
|
|
12
|
+
- Requires ISV JWT token with merchant partner ID in 'aud' claim
|
|
13
|
+
- Requires OAuth2 token in 'sub' claim
|
|
14
|
+
|
|
15
|
+
**Deep Link Format:**
|
|
16
|
+
- Web URL: https://url.payware.eu/{productId}
|
|
17
|
+
- Mobile Redirect: payware://{productId}
|
|
18
|
+
|
|
19
|
+
**Use Cases:**
|
|
20
|
+
- Mobile-only e-commerce product references
|
|
21
|
+
- Advertisement links to products
|
|
22
|
+
- Product sharing via messaging
|
|
23
|
+
|
|
24
|
+
**Important Notes:**
|
|
25
|
+
- Deep links are only supported in production environment
|
|
26
|
+
- Link expiration is synchronized with the referenced product
|
|
27
|
+
- Traditional deep links that route to app content when app is installed`,
|
|
28
|
+
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
productId: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "The product identifier (e.g., 'pr7e4rCToG')",
|
|
35
|
+
pattern: "^[a-zA-Z0-9]+$"
|
|
36
|
+
},
|
|
37
|
+
merchantPartnerId: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Partner ID of the merchant for whom the product is being retrieved"
|
|
40
|
+
},
|
|
41
|
+
oauth2Token: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "OAuth2 access token for merchant authorization"
|
|
44
|
+
},
|
|
45
|
+
isvPartnerId: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "ISV Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
48
|
+
default: getPartnerIdSafe()
|
|
49
|
+
},
|
|
50
|
+
privateKey: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "ISV RSA private key for JWT token creation. Uses environment-specific private key as default.",
|
|
53
|
+
default: getPrivateKeySafe()
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
required: ["productId", "merchantPartnerId", "oauth2Token"]
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async handler(args) {
|
|
60
|
+
const {
|
|
61
|
+
productId,
|
|
62
|
+
merchantPartnerId,
|
|
63
|
+
oauth2Token,
|
|
64
|
+
isvPartnerId = getPartnerIdSafe(),
|
|
65
|
+
privateKey = getPrivateKeySafe()
|
|
66
|
+
} = args;
|
|
67
|
+
|
|
68
|
+
if (!productId) {
|
|
69
|
+
throw new Error("productId is required");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!merchantPartnerId) {
|
|
73
|
+
throw new Error("merchantPartnerId is required for ISV operations");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!oauth2Token) {
|
|
77
|
+
throw new Error("oauth2Token is required for ISV operations");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!isvPartnerId) {
|
|
81
|
+
throw new Error("ISV Partner ID is required. Provide via 'isvPartnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!privateKey) {
|
|
85
|
+
throw new Error("Private key is required. Provide via 'privateKey' parameter or set PAYWARE_PRIVATE_KEY environment variable.");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await getProductDeepLink({
|
|
90
|
+
productId,
|
|
91
|
+
partnerType: 'isv',
|
|
92
|
+
isvPartnerId,
|
|
93
|
+
privateKey,
|
|
94
|
+
merchantPartnerId,
|
|
95
|
+
oauth2Token
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Extract the URL - API returns either string directly or object with link property
|
|
99
|
+
const linkUrl = typeof result.data === 'string' ? result.data : (result.data.link || result.data)
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
content: [{
|
|
103
|
+
type: "text",
|
|
104
|
+
text: `🔗 **Product Deep Link Retrieved (ISV)**
|
|
105
|
+
|
|
106
|
+
**Deep Link Details:**
|
|
107
|
+
- Product ID: ${productId}
|
|
108
|
+
- Merchant: ${merchantPartnerId}
|
|
109
|
+
- Web URL: ${linkUrl}
|
|
110
|
+
- Mobile Redirect: payware://${productId}
|
|
111
|
+
|
|
112
|
+
**ISV Authentication:**
|
|
113
|
+
- ISV Partner ID: ${isvPartnerId}
|
|
114
|
+
- Merchant Partner ID: ${merchantPartnerId}
|
|
115
|
+
- OAuth2 Token: ${oauth2Token.substring(0, 10)}...
|
|
116
|
+
|
|
117
|
+
**Link Information:**
|
|
118
|
+
- Status: Active
|
|
119
|
+
- Expiration: Synchronized with product
|
|
120
|
+
- Platform: Production only
|
|
121
|
+
|
|
122
|
+
**API Response:**
|
|
123
|
+
\`\`\`json
|
|
124
|
+
${JSON.stringify(result.data, null, 2)}
|
|
125
|
+
\`\`\`
|
|
126
|
+
|
|
127
|
+
**API Call Details:**
|
|
128
|
+
- Endpoint: GET ${result.requestInfo.url}
|
|
129
|
+
- Status: ${result.requestInfo.statusCode}
|
|
130
|
+
- Method: ${result.requestInfo.method}
|
|
131
|
+
|
|
132
|
+
**Usage:**
|
|
133
|
+
1. Share the web URL: \`${linkUrl}\`
|
|
134
|
+
2. On mobile devices, it will redirect to: \`payware://${productId}\`
|
|
135
|
+
3. Link expires when the product expires
|
|
136
|
+
4. Recreate if product is updated`
|
|
137
|
+
}]
|
|
138
|
+
};
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
content: [{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: `❌ **Failed to Get Product Deep Link (ISV)**
|
|
144
|
+
|
|
145
|
+
**Error Details:**
|
|
146
|
+
- Product ID: ${productId}
|
|
147
|
+
- Merchant: ${merchantPartnerId}
|
|
148
|
+
- Message: ${error.message}
|
|
149
|
+
|
|
150
|
+
**Common Issues:**
|
|
151
|
+
1. **Product not found**: Check if product exists and is not expired
|
|
152
|
+
2. **Authentication failed**: Verify ISV partner ID, private key, and OAuth2 token
|
|
153
|
+
3. **Authorization failed**: Ensure OAuth2 token authorizes access to merchant
|
|
154
|
+
4. **Sandbox environment**: Deep links are production-only
|
|
155
|
+
5. **Invalid product ID**: Ensure product ID format is correct
|
|
156
|
+
|
|
157
|
+
**Troubleshooting:**
|
|
158
|
+
1. Verify product exists in merchant's payware dashboard
|
|
159
|
+
2. Check OAuth2 token is valid and not expired
|
|
160
|
+
3. Ensure ISV has permission to access merchant data
|
|
161
|
+
4. Check if running in production environment
|
|
162
|
+
5. Ensure JWT authentication is working`
|
|
163
|
+
}]
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { getTransactionDeepLink } from '../../shared/deep-links/api.js';
|
|
2
|
+
import { getPartnerIdSafe, getPrivateKeySafe } from '../../config/env.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get deep link for a transaction (ISV on behalf of merchant)
|
|
6
|
+
*/
|
|
7
|
+
export const getTransactionLinkTool = {
|
|
8
|
+
name: "payware_deep_links_get_transaction_link",
|
|
9
|
+
description: `Get an active deep link for a transaction on behalf of a merchant. Returns a clickable URL that redirects to the payware mobile app.
|
|
10
|
+
|
|
11
|
+
**ISV Authentication:**
|
|
12
|
+
- Requires ISV JWT token with merchant partner ID in 'aud' claim
|
|
13
|
+
- Requires OAuth2 token in 'sub' claim
|
|
14
|
+
|
|
15
|
+
**Deep Link Format:**
|
|
16
|
+
- Web URL: https://url.payware.eu/{transactionId}
|
|
17
|
+
- Mobile Redirect: payware://{transactionId}
|
|
18
|
+
|
|
19
|
+
**Use Cases:**
|
|
20
|
+
- P2P payments via messaging services
|
|
21
|
+
- Mobile-only e-commerce payments
|
|
22
|
+
- Advertisement references
|
|
23
|
+
|
|
24
|
+
**Important Notes:**
|
|
25
|
+
- Deep links are only supported in production environment
|
|
26
|
+
- Link expiration is synchronized with the referenced transaction
|
|
27
|
+
- Traditional deep links that route to app content when app is installed`,
|
|
28
|
+
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
transactionId: {
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "The transaction identifier (e.g., 'pw7e4rCToG')",
|
|
35
|
+
pattern: "^[a-zA-Z0-9]+$"
|
|
36
|
+
},
|
|
37
|
+
merchantPartnerId: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Partner ID of the merchant for whom the transaction is being retrieved"
|
|
40
|
+
},
|
|
41
|
+
oauth2Token: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "OAuth2 access token for merchant authorization"
|
|
44
|
+
},
|
|
45
|
+
isvPartnerId: {
|
|
46
|
+
type: "string",
|
|
47
|
+
description: "ISV Partner ID from payware dashboard. Uses PAYWARE_PARTNER_ID env var as default.",
|
|
48
|
+
default: getPartnerIdSafe()
|
|
49
|
+
},
|
|
50
|
+
privateKey: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "ISV RSA private key for JWT token creation. Uses environment-specific private key as default.",
|
|
53
|
+
default: getPrivateKeySafe()
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
required: ["transactionId", "merchantPartnerId", "oauth2Token"]
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async handler(args) {
|
|
60
|
+
const {
|
|
61
|
+
transactionId,
|
|
62
|
+
merchantPartnerId,
|
|
63
|
+
oauth2Token,
|
|
64
|
+
isvPartnerId = getPartnerIdSafe(),
|
|
65
|
+
privateKey = getPrivateKeySafe()
|
|
66
|
+
} = args;
|
|
67
|
+
|
|
68
|
+
if (!transactionId) {
|
|
69
|
+
throw new Error("transactionId is required");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!merchantPartnerId) {
|
|
73
|
+
throw new Error("merchantPartnerId is required for ISV operations");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!oauth2Token) {
|
|
77
|
+
throw new Error("oauth2Token is required for ISV operations");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!isvPartnerId) {
|
|
81
|
+
throw new Error("ISV Partner ID is required. Provide via 'isvPartnerId' parameter or set PAYWARE_PARTNER_ID environment variable.");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!privateKey) {
|
|
85
|
+
throw new Error("Private key is required. Provide via 'privateKey' parameter or set PAYWARE_PRIVATE_KEY environment variable.");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
try {
|
|
89
|
+
const result = await getTransactionDeepLink({
|
|
90
|
+
transactionId,
|
|
91
|
+
partnerType: 'isv',
|
|
92
|
+
isvPartnerId,
|
|
93
|
+
privateKey,
|
|
94
|
+
merchantPartnerId,
|
|
95
|
+
oauth2Token
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Extract the URL - API returns either string directly or object with link property
|
|
99
|
+
const linkUrl = typeof result.data === 'string' ? result.data : (result.data.link || result.data)
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
content: [{
|
|
103
|
+
type: "text",
|
|
104
|
+
text: `🔗 **Transaction Deep Link Retrieved (ISV)**
|
|
105
|
+
|
|
106
|
+
**Deep Link Details:**
|
|
107
|
+
- Transaction ID: ${transactionId}
|
|
108
|
+
- Merchant: ${merchantPartnerId}
|
|
109
|
+
- Web URL: ${linkUrl}
|
|
110
|
+
- Mobile Redirect: payware://${transactionId}
|
|
111
|
+
|
|
112
|
+
**ISV Authentication:**
|
|
113
|
+
- ISV Partner ID: ${isvPartnerId}
|
|
114
|
+
- Merchant Partner ID: ${merchantPartnerId}
|
|
115
|
+
- OAuth2 Token: ${oauth2Token.substring(0, 10)}...
|
|
116
|
+
|
|
117
|
+
**Link Information:**
|
|
118
|
+
- Status: Active
|
|
119
|
+
- Expiration: Synchronized with transaction
|
|
120
|
+
- Platform: Production only
|
|
121
|
+
|
|
122
|
+
**API Response:**
|
|
123
|
+
\`\`\`json
|
|
124
|
+
${JSON.stringify(result.data, null, 2)}
|
|
125
|
+
\`\`\`
|
|
126
|
+
|
|
127
|
+
**API Call Details:**
|
|
128
|
+
- Endpoint: GET ${result.requestInfo.url}
|
|
129
|
+
- Status: ${result.requestInfo.statusCode}
|
|
130
|
+
- Method: ${result.requestInfo.method}
|
|
131
|
+
|
|
132
|
+
**Usage:**
|
|
133
|
+
1. Share the web URL: \`${linkUrl}\`
|
|
134
|
+
2. On mobile devices, it will redirect to: \`payware://${transactionId}\`
|
|
135
|
+
3. Link expires when the transaction expires
|
|
136
|
+
4. Recreate if transaction is extended`
|
|
137
|
+
}]
|
|
138
|
+
};
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return {
|
|
141
|
+
content: [{
|
|
142
|
+
type: "text",
|
|
143
|
+
text: `❌ **Failed to Get Transaction Deep Link (ISV)**
|
|
144
|
+
|
|
145
|
+
**Error Details:**
|
|
146
|
+
- Transaction ID: ${transactionId}
|
|
147
|
+
- Merchant: ${merchantPartnerId}
|
|
148
|
+
- Message: ${error.message}
|
|
149
|
+
|
|
150
|
+
**Common Issues:**
|
|
151
|
+
1. **Transaction not found**: Check if transaction exists and is not expired
|
|
152
|
+
2. **Authentication failed**: Verify ISV partner ID, private key, and OAuth2 token
|
|
153
|
+
3. **Authorization failed**: Ensure OAuth2 token authorizes access to merchant
|
|
154
|
+
4. **Sandbox environment**: Deep links are production-only
|
|
155
|
+
5. **Invalid transaction ID**: Ensure transaction ID format is correct
|
|
156
|
+
|
|
157
|
+
**Troubleshooting:**
|
|
158
|
+
1. Verify transaction exists using \`payware_transactions_get_transaction_status\`
|
|
159
|
+
2. Check OAuth2 token is valid and not expired
|
|
160
|
+
3. Ensure ISV has permission to access merchant data
|
|
161
|
+
4. Check if running in production environment
|
|
162
|
+
5. Ensure JWT authentication is working`
|
|
163
|
+
}]
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISV Deep Links Tools
|
|
3
|
+
* Deep link management for ISVs acting on behalf of merchants
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { getTransactionLinkTool } from './get-transaction-link.js';
|
|
7
|
+
import { getProductLinkTool } from './get-product-link.js';
|
|
8
|
+
import { deleteTransactionLinkTool } from './delete-transaction-link.js';
|
|
9
|
+
import { deleteProductLinkTool } from './delete-product-link.js';
|
|
10
|
+
|
|
11
|
+
export const isvDeepLinksTools = [
|
|
12
|
+
getTransactionLinkTool,
|
|
13
|
+
getProductLinkTool,
|
|
14
|
+
deleteTransactionLinkTool,
|
|
15
|
+
deleteProductLinkTool
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
getTransactionLinkTool,
|
|
20
|
+
getProductLinkTool,
|
|
21
|
+
deleteTransactionLinkTool,
|
|
22
|
+
deleteProductLinkTool
|
|
23
|
+
};
|
package/src/isv/index.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISV (Independent Software Vendor) partner tools registry
|
|
3
|
+
* Tools available for ISVs serving multiple merchants
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// OAuth2 tools
|
|
7
|
+
import { obtainTokenTool } from './oauth2/obtain-token.js';
|
|
8
|
+
import { getTokenInfoTool } from './oauth2/get-token-info.js';
|
|
9
|
+
import { tokenHelperTool } from './oauth2/token-helper.js';
|
|
10
|
+
|
|
11
|
+
// Transaction tools
|
|
12
|
+
import { createTransactionTool } from './transactions/create-transaction.js';
|
|
13
|
+
import { getTransactionStatusTool } from './transactions/get-status.js';
|
|
14
|
+
import { cancelTransactionTool } from './transactions/cancel-transaction.js';
|
|
15
|
+
import { getTransactionHistoryTool } from './transactions/transaction-history.js';
|
|
16
|
+
import { processTransactionTool } from './transactions/process-transaction.js';
|
|
17
|
+
import { simulateCallbackTool } from './transactions/simulate-callback.js';
|
|
18
|
+
|
|
19
|
+
// Data tools
|
|
20
|
+
import { isvDataTools } from './data/index.js';
|
|
21
|
+
|
|
22
|
+
// Product tools
|
|
23
|
+
import { isvProductTools } from './products/index.js';
|
|
24
|
+
|
|
25
|
+
// Deep links tools
|
|
26
|
+
import { isvDeepLinksTools } from './deep-links/index.js';
|
|
27
|
+
|
|
28
|
+
// Import shared tools
|
|
29
|
+
import { sharedTools } from '../shared/index.js';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* All ISV-specific tools
|
|
33
|
+
*/
|
|
34
|
+
export const isvTools = [
|
|
35
|
+
// Shared tools (authentication, utilities, etc.)
|
|
36
|
+
...sharedTools,
|
|
37
|
+
|
|
38
|
+
// OAuth2 management (ISV-specific)
|
|
39
|
+
obtainTokenTool,
|
|
40
|
+
getTokenInfoTool,
|
|
41
|
+
tokenHelperTool,
|
|
42
|
+
|
|
43
|
+
// Transaction management
|
|
44
|
+
createTransactionTool,
|
|
45
|
+
getTransactionStatusTool,
|
|
46
|
+
cancelTransactionTool,
|
|
47
|
+
getTransactionHistoryTool,
|
|
48
|
+
processTransactionTool,
|
|
49
|
+
simulateCallbackTool,
|
|
50
|
+
|
|
51
|
+
// Data management
|
|
52
|
+
...isvDataTools,
|
|
53
|
+
|
|
54
|
+
// Product management
|
|
55
|
+
...isvProductTools,
|
|
56
|
+
|
|
57
|
+
// Deep links management
|
|
58
|
+
...isvDeepLinksTools
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get tools for ISV partner type with proper grouping
|
|
63
|
+
* @returns {Array} Array of ISV tools with grouped names
|
|
64
|
+
*/
|
|
65
|
+
export function getISVTools() {
|
|
66
|
+
return isvTools.map(tool => {
|
|
67
|
+
let newName = tool.name;
|
|
68
|
+
|
|
69
|
+
// Authentication tools use authentication grouping (shared tools)
|
|
70
|
+
if (tool.name.startsWith('payware_authentication_')) {
|
|
71
|
+
newName = tool.name; // Keep authentication grouping
|
|
72
|
+
}
|
|
73
|
+
// Authorization tools use authorization grouping (ISV-specific OAuth2)
|
|
74
|
+
else if (tool.name.startsWith('payware_authorization_')) {
|
|
75
|
+
newName = tool.name; // Keep authorization grouping
|
|
76
|
+
}
|
|
77
|
+
// Utility tools keep their utils grouping
|
|
78
|
+
else if (tool.name.startsWith('payware_utils_')) {
|
|
79
|
+
newName = tool.name; // Keep utils grouping
|
|
80
|
+
}
|
|
81
|
+
// Operations tools (previously transactions) keep operations grouping
|
|
82
|
+
else if (tool.name.startsWith('payware_operations_')) {
|
|
83
|
+
newName = tool.name; // Keep operations grouping
|
|
84
|
+
}
|
|
85
|
+
// Data tools keep their data grouping
|
|
86
|
+
else if (tool.name.startsWith('payware_data_')) {
|
|
87
|
+
newName = tool.name; // Keep data grouping
|
|
88
|
+
}
|
|
89
|
+
// Product tools keep their products grouping
|
|
90
|
+
else if (tool.name.startsWith('payware_products_')) {
|
|
91
|
+
newName = tool.name; // Keep products grouping
|
|
92
|
+
}
|
|
93
|
+
// Deep links tools keep their deep_links grouping
|
|
94
|
+
else if (tool.name.startsWith('payware_deep_links_')) {
|
|
95
|
+
newName = tool.name; // Keep deep_links grouping
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
...tool,
|
|
100
|
+
name: newName
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple OAuth2 token creation utility for testing
|
|
3
|
+
* Returns just the token string for easy command-line use
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { obtainTokenTool } from './obtain-token.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create OAuth2 token and return just the token string
|
|
10
|
+
* @param {Object} params - Optional parameters (uses env vars if not provided)
|
|
11
|
+
* @returns {string} The access token
|
|
12
|
+
*/
|
|
13
|
+
export async function createTokenSimple(params = {}) {
|
|
14
|
+
try {
|
|
15
|
+
const result = await obtainTokenTool.handler(params);
|
|
16
|
+
|
|
17
|
+
// Extract token from the response text
|
|
18
|
+
const responseText = result.content?.[0]?.text || '';
|
|
19
|
+
const tokenMatch = responseText.match(/🎯 \*\*NEW ACCESS TOKEN\*\*: ([A-Za-z0-9]+)/);
|
|
20
|
+
if (tokenMatch) {
|
|
21
|
+
return tokenMatch[1];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Fallback: look for any token pattern in the response
|
|
25
|
+
const fallbackMatch = responseText.match(/Access Token\*\*: ([A-Za-z0-9]+)/);
|
|
26
|
+
if (fallbackMatch) {
|
|
27
|
+
return fallbackMatch[1];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
throw new Error('Could not extract token from response');
|
|
31
|
+
} catch (error) {
|
|
32
|
+
throw new Error(`Token creation failed: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// For command line testing
|
|
37
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
38
|
+
createTokenSimple()
|
|
39
|
+
.then(token => {
|
|
40
|
+
console.log('🎯 New OAuth2 Token:');
|
|
41
|
+
console.log(token);
|
|
42
|
+
})
|
|
43
|
+
.catch(error => {
|
|
44
|
+
console.error('❌ Error:', error.message);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISV OAuth2 Token Management - Get Token Information
|
|
3
|
+
*
|
|
4
|
+
* Retrieves information about an existing OAuth2 access token.
|
|
5
|
+
* Use this to check token status and present information in POS software UI.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const getTokenInfoTool = {
|
|
9
|
+
name: 'payware_authorization_oauth2_get_token_info',
|
|
10
|
+
description: `Get information about an OAuth2 access token.
|
|
11
|
+
|
|
12
|
+
This endpoint exposes information about access tokens, including their status.
|
|
13
|
+
Only information about tokens requested by the ISV is returned.
|
|
14
|
+
|
|
15
|
+
Use this to check token status and present information to users in POS software.
|
|
16
|
+
|
|
17
|
+
Endpoint: GET /oauth2/tokens/{token}
|
|
18
|
+
Auth: Requires ISV JWT token`,
|
|
19
|
+
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
required: ['token'],
|
|
23
|
+
properties: {
|
|
24
|
+
token: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'The OAuth2 access token to get information about'
|
|
27
|
+
},
|
|
28
|
+
useSandbox: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
description: 'Use sandbox environment for testing',
|
|
31
|
+
default: true
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async handler({ token, useSandbox = true }) {
|
|
37
|
+
const axios = (await import('axios')).default;
|
|
38
|
+
const { createISVJWT } = await import('../utils/auth.js');
|
|
39
|
+
const { getSandboxUrl, getProductionUrl } = await import('../../config/env.js');
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
// Create JWT for token info request
|
|
43
|
+
const jwt = await createISVJWT({
|
|
44
|
+
isGetRequest: true,
|
|
45
|
+
isOAuth2Request: true,
|
|
46
|
+
audience: 'https://payware.eu'
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const { createISVAuthHeaders } = await import('../utils/auth.js');
|
|
50
|
+
|
|
51
|
+
const apiUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
|
|
52
|
+
const baseUrl = apiUrl.replace('/api', ''); // OAuth2 endpoints don't use /api
|
|
53
|
+
const headers = createISVAuthHeaders(jwt, true); // true = isOAuth2Request (no Api-Version header)
|
|
54
|
+
|
|
55
|
+
const response = await axios.get(`${baseUrl}/oauth2/tokens/${token}`, {
|
|
56
|
+
headers
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const result = response.data;
|
|
60
|
+
|
|
61
|
+
const statusEmoji = {
|
|
62
|
+
'PENDING': '⏳',
|
|
63
|
+
'GRANTED': '✅',
|
|
64
|
+
'REVOKED': '❌'
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const statusDescription = {
|
|
68
|
+
'PENDING': 'Token is pending approval',
|
|
69
|
+
'GRANTED': 'Token is active and valid for API requests',
|
|
70
|
+
'REVOKED': 'Token has been revoked and is no longer valid'
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
content: [{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: `📋 **OAuth2 Token Information**
|
|
77
|
+
|
|
78
|
+
🔑 **Token Details:**
|
|
79
|
+
- **Access Token**: ${result.access_token}
|
|
80
|
+
- **Token Type**: ${result.token_type}
|
|
81
|
+
- **Status**: ${statusEmoji[result.status]} ${result.status}
|
|
82
|
+
- **Description**: ${statusDescription[result.status]}
|
|
83
|
+
- **Scope**: ${result.scope}
|
|
84
|
+
- **Expires**: ${result.expires_in || 'Never (client_credentials tokens do not expire)'}
|
|
85
|
+
|
|
86
|
+
${result.status === 'GRANTED' ?
|
|
87
|
+
'✅ **Token is ready for use in API requests**' :
|
|
88
|
+
result.status === 'PENDING' ?
|
|
89
|
+
'⏳ **Token is pending - wait for merchant approval**' :
|
|
90
|
+
'❌ **Token is revoked - obtain a new token**'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
📋 **Usage Notes:**
|
|
94
|
+
- Only GRANTED tokens can be used for API requests
|
|
95
|
+
- Include this token in the "sub" claim of JWT for API calls
|
|
96
|
+
- Set "aud" claim to merchant partnerId when making API requests`
|
|
97
|
+
}]
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
} catch (error) {
|
|
101
|
+
let errorMessage = 'Failed to retrieve token information';
|
|
102
|
+
let errorDetails = {};
|
|
103
|
+
|
|
104
|
+
if (error.response) {
|
|
105
|
+
errorDetails.httpStatus = error.response.status;
|
|
106
|
+
errorDetails.responseData = error.response.data;
|
|
107
|
+
|
|
108
|
+
if (error.response.data?.errorCode) {
|
|
109
|
+
const errorCode = error.response.data.errorCode;
|
|
110
|
+
if (errorCode === 'ERR_TOKEN_NOT_FOUND') {
|
|
111
|
+
errorMessage = 'Token not found or you do not have permission to view this token';
|
|
112
|
+
} else {
|
|
113
|
+
errorMessage = `Error: ${errorCode} - ${error.response.data.message || ''}`;
|
|
114
|
+
}
|
|
115
|
+
} else {
|
|
116
|
+
errorMessage = `HTTP ${error.response.status}: ${error.response.statusText}`;
|
|
117
|
+
}
|
|
118
|
+
} else if (error.request) {
|
|
119
|
+
errorMessage = 'Network error - no response received';
|
|
120
|
+
errorDetails.requestInfo = {
|
|
121
|
+
url: error.config?.url,
|
|
122
|
+
method: error.config?.method,
|
|
123
|
+
headers: error.config?.headers
|
|
124
|
+
};
|
|
125
|
+
} else {
|
|
126
|
+
errorMessage = error.message;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
content: [{
|
|
131
|
+
type: "text",
|
|
132
|
+
text: `❌ Token Information Request Failed
|
|
133
|
+
|
|
134
|
+
**Error**: ${errorMessage}
|
|
135
|
+
|
|
136
|
+
**Request Details:**
|
|
137
|
+
- ISV Partner ID: ${process.env.PAYWARE_PARTNER_ID}
|
|
138
|
+
- Token: ${token}
|
|
139
|
+
- Target URL: ${getSandboxUrl().replace('/api', '')}/oauth2/tokens/${token}
|
|
140
|
+
|
|
141
|
+
${Object.keys(errorDetails).length > 0 ? `
|
|
142
|
+
**Error Details:**
|
|
143
|
+
\`\`\`json
|
|
144
|
+
${JSON.stringify(errorDetails, null, 2)}
|
|
145
|
+
\`\`\`
|
|
146
|
+
` : ''}
|
|
147
|
+
|
|
148
|
+
📋 **Troubleshooting:**
|
|
149
|
+
- Verify the token value is correct
|
|
150
|
+
- Ensure you have permission to view this token
|
|
151
|
+
- Check if the token was created by your ISV account
|
|
152
|
+
- Verify your ISV JWT token is properly signed`
|
|
153
|
+
}]
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
};
|