@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.
Files changed (106) hide show
  1. package/.env.example +92 -0
  2. package/MCP-SETUP.md +190 -0
  3. package/README.md +483 -0
  4. package/check-keys.js +52 -0
  5. package/keys/README.md +112 -0
  6. package/mcp-config.json +9 -0
  7. package/package.json +66 -0
  8. package/payware-mcp-config.json +12 -0
  9. package/src/auth/rsa-keys.js +82 -0
  10. package/src/auth/sandbox-setup.js +187 -0
  11. package/src/config/env.js +229 -0
  12. package/src/config/partner-types.js +143 -0
  13. package/src/core/auth/jwt-factory.js +182 -0
  14. package/src/core/auth/jwt-token.js +735 -0
  15. package/src/core/utils/json-serializer.js +100 -0
  16. package/src/core/utils/key-utils.js +133 -0
  17. package/src/index.js +237 -0
  18. package/src/isv/data/index.js +291 -0
  19. package/src/isv/deep-links/delete-product-link.js +154 -0
  20. package/src/isv/deep-links/delete-transaction-link.js +154 -0
  21. package/src/isv/deep-links/get-product-link.js +167 -0
  22. package/src/isv/deep-links/get-transaction-link.js +167 -0
  23. package/src/isv/deep-links/index.js +23 -0
  24. package/src/isv/index.js +103 -0
  25. package/src/isv/oauth2/create-token-simple.js +46 -0
  26. package/src/isv/oauth2/get-token-info.js +157 -0
  27. package/src/isv/oauth2/obtain-token.js +189 -0
  28. package/src/isv/oauth2/token-helper.js +151 -0
  29. package/src/isv/products/audios.js +470 -0
  30. package/src/isv/products/create-product.js +314 -0
  31. package/src/isv/products/delete-product.js +119 -0
  32. package/src/isv/products/get-product-image.js +247 -0
  33. package/src/isv/products/get-product.js +168 -0
  34. package/src/isv/products/index.js +65 -0
  35. package/src/isv/products/list-products.js +136 -0
  36. package/src/isv/products/schedules.js +522 -0
  37. package/src/isv/products/update-product.js +265 -0
  38. package/src/isv/transactions/cancel-transaction.js +129 -0
  39. package/src/isv/transactions/create-transaction.js +361 -0
  40. package/src/isv/transactions/get-status.js +217 -0
  41. package/src/isv/transactions/process-transaction.js +145 -0
  42. package/src/isv/transactions/simulate-callback.js +146 -0
  43. package/src/isv/transactions/transaction-history.js +186 -0
  44. package/src/isv/utils/auth.js +159 -0
  45. package/src/mcp-proxy.js +150 -0
  46. package/src/merchant/data/export-report.js +108 -0
  47. package/src/merchant/data/generate-report.js +151 -0
  48. package/src/merchant/data/get-report-status.js +120 -0
  49. package/src/merchant/data/index.js +351 -0
  50. package/src/merchant/deep-links/delete-product-link.js +121 -0
  51. package/src/merchant/deep-links/delete-transaction-link.js +121 -0
  52. package/src/merchant/deep-links/get-product-link.js +134 -0
  53. package/src/merchant/deep-links/get-transaction-link.js +134 -0
  54. package/src/merchant/deep-links/index.js +23 -0
  55. package/src/merchant/index.js +92 -0
  56. package/src/merchant/products/audios.js +606 -0
  57. package/src/merchant/products/create-product.js +288 -0
  58. package/src/merchant/products/delete-product.js +111 -0
  59. package/src/merchant/products/get-product-image.js +252 -0
  60. package/src/merchant/products/get-product.js +144 -0
  61. package/src/merchant/products/index.js +65 -0
  62. package/src/merchant/products/list-products.js +112 -0
  63. package/src/merchant/products/schedules.js +646 -0
  64. package/src/merchant/products/update-product.js +282 -0
  65. package/src/merchant/transactions/cancel-transaction.js +241 -0
  66. package/src/merchant/transactions/create-transaction.js +482 -0
  67. package/src/merchant/transactions/get-status.js +196 -0
  68. package/src/merchant/transactions/process-transaction.js +349 -0
  69. package/src/merchant/transactions/simulate-callback.js +246 -0
  70. package/src/merchant/transactions/transaction-history.js +258 -0
  71. package/src/payment-institution/data/index.js +280 -0
  72. package/src/payment-institution/deep-links/delete-transaction-link.js +128 -0
  73. package/src/payment-institution/deep-links/get-transaction-link.js +141 -0
  74. package/src/payment-institution/deep-links/index.js +17 -0
  75. package/src/payment-institution/index.js +92 -0
  76. package/src/payment-institution/transactions/create-pi-transaction.js +484 -0
  77. package/src/payment-institution/transactions/finalize-transaction.js +340 -0
  78. package/src/payment-institution/transactions/get-transaction-history.js +269 -0
  79. package/src/payment-institution/transactions/get-transaction-status.js +234 -0
  80. package/src/payment-institution/transactions/process-pi-transaction.js +421 -0
  81. package/src/payment-institution/transactions/simulate-pi-callback.js +326 -0
  82. package/src/payment-institution/transactions/soundbite-transaction.js +269 -0
  83. package/src/proxy-server.js +205 -0
  84. package/src/shared/data/data-api.js +372 -0
  85. package/src/shared/deep-links/api.js +214 -0
  86. package/src/shared/index.js +44 -0
  87. package/src/shared/products/products-api.js +872 -0
  88. package/src/tools/advanced-code-generator.js +2247 -0
  89. package/src/utils/code-examples/common/auth-examples.js +1482 -0
  90. package/src/utils/code-examples/common/helpers.js +416 -0
  91. package/src/utils/code-examples/common/utils-examples.js +591 -0
  92. package/src/utils/code-examples/frameworks/examples.js +859 -0
  93. package/src/utils/code-examples/index.js +441 -0
  94. package/src/utils/code-examples/isv/oauth2.js +600 -0
  95. package/src/utils/code-examples/isv/products.js +666 -0
  96. package/src/utils/code-examples/isv/transactions.js +813 -0
  97. package/src/utils/code-examples/merchant/products.js +497 -0
  98. package/src/utils/code-examples/merchant/transactions.js +623 -0
  99. package/src/utils/code-examples/payment-institution/transactions.js +388 -0
  100. package/src/utils/code-examples/shared/data.js +607 -0
  101. package/src/utils/code-examples/shared/deep-links.js +662 -0
  102. package/src/utils/code-examples/shared/soundbites.js +808 -0
  103. package/src/utils/code-examples.js +646 -0
  104. package/src/utils/format-request.js +363 -0
  105. package/src/utils/json-formatter.js +249 -0
  106. package/src/utils/server-info.js +132 -0
@@ -0,0 +1,189 @@
1
+ /**
2
+ * ISV OAuth2 Token Management - Obtain Access Token
3
+ *
4
+ * Allows ISVs to request an access token on behalf of a payware registered merchant.
5
+ * This is the first step in the ISV authorization flow.
6
+ */
7
+
8
+ export const obtainTokenTool = {
9
+ name: 'payware_authorization_oauth2_obtain_token',
10
+ description: `Obtain an OAuth2 access token for a merchant.
11
+
12
+ ISVs must be authorized by payware registered merchants to make requests on their behalf.
13
+ This endpoint allows ISVs to request a token using the merchant's credentials.
14
+
15
+ IMPORTANT: Access tokens do not expire and only one token is allowed per merchant.
16
+ Store tokens securely using strong encryption.
17
+
18
+ Endpoint: POST /oauth2/tokens
19
+ Auth: Requires ISV JWT token with aud: "https://payware.eu"`,
20
+
21
+ inputSchema: {
22
+ type: 'object',
23
+ required: [],
24
+ properties: {
25
+ grantType: {
26
+ type: 'string',
27
+ enum: ['client_credentials'],
28
+ default: 'client_credentials',
29
+ description: 'OAuth2 grant type. Only "client_credentials" is supported.'
30
+ },
31
+ clientId: {
32
+ type: 'string',
33
+ description: 'The partnerId of the merchant (e.g., "ZJJTFQDQ"). Defaults to PAYWARE_OAUTH_CLIENT_ID env var.'
34
+ },
35
+ clientSecret: {
36
+ type: 'string',
37
+ description: 'Base64 encoded value of the payware secret of the merchant. Defaults to PAYWARE_OAUTH_CLIENT_SECRET env var.'
38
+ },
39
+ useSandbox: {
40
+ type: 'boolean',
41
+ description: 'Use sandbox environment for testing',
42
+ default: true
43
+ }
44
+ }
45
+ },
46
+
47
+ async handler({ grantType = 'client_credentials', clientId, clientSecret, useSandbox = true }) {
48
+ const axios = (await import('axios')).default;
49
+ const { createISVJWT } = await import('../utils/auth.js');
50
+ const { getSandboxUrl, getProductionUrl } = await import('../../config/env.js');
51
+
52
+ // Use environment variables as defaults
53
+ const finalClientId = clientId || process.env.PAYWARE_OAUTH_CLIENT_ID;
54
+ const finalClientSecret = clientSecret || process.env.PAYWARE_OAUTH_CLIENT_SECRET;
55
+
56
+ if (!finalClientId) {
57
+ throw new Error('Client ID is required. Provide via parameter or set PAYWARE_OAUTH_CLIENT_ID environment variable.');
58
+ }
59
+
60
+ if (!finalClientSecret) {
61
+ throw new Error('Client Secret is required. Provide via parameter or set PAYWARE_OAUTH_CLIENT_SECRET environment variable.');
62
+ }
63
+
64
+ try {
65
+ const requestBody = {
66
+ grantType,
67
+ clientId: finalClientId,
68
+ clientSecret: finalClientSecret
69
+ };
70
+
71
+ // Create JWT for OAuth2 request (audience must be https://payware.eu)
72
+ const jwt = await createISVJWT({
73
+ requestBody,
74
+ audience: 'https://payware.eu',
75
+ isOAuth2Request: true
76
+ });
77
+
78
+ const { createISVAuthHeaders } = await import('../utils/auth.js');
79
+
80
+ const apiUrl = useSandbox ? getSandboxUrl() : getProductionUrl();
81
+ const baseUrl = apiUrl.replace('/api', ''); // OAuth2 endpoints don't use /api
82
+ const headers = createISVAuthHeaders(jwt, true); // true = isOAuth2Request (no Api-Version header)
83
+
84
+ const response = await axios.post(`${baseUrl}/oauth2/tokens`, requestBody, {
85
+ headers
86
+ });
87
+
88
+ const result = response.data;
89
+
90
+ return {
91
+ content: [{
92
+ type: "text",
93
+ text: `✅ OAuth2 Token Request Successful
94
+
95
+ 🎯 **NEW ACCESS TOKEN**: ${result.accessToken}
96
+
97
+ 📄 **Response Details:**
98
+ - **Access Token**: ${result.accessToken}
99
+ - **Token Type**: ${result.tokenType}
100
+ - **Status**: ${result.status}
101
+ - **Scope**: ${result.scope}
102
+ - **Expires**: ${result.expiresIn || 'Never (client_credentials tokens do not expire)'}
103
+
104
+ 📋 **Copy this token for next operations:**
105
+ \`${result.accessToken}\`
106
+
107
+ 🔐 **Security Reminder:**
108
+ - Store this token securely with strong encryption
109
+ - Only one token is allowed per merchant
110
+ - Use this token in the "sub" claim of future JWT requests
111
+
112
+ 📋 **Next Steps:**
113
+ 1. Check token status: Use token \`${result.accessToken}\` with payware_oauth2_get_token_info
114
+ 2. Wait for merchant approval (status will change from PENDING to GRANTED)
115
+ 3. Use this token in JWT "sub" claim for API requests to merchant data
116
+ 4. Set JWT "aud" claim to the merchant's partnerId (${finalClientId}) for API calls`
117
+ }]
118
+ };
119
+
120
+ } catch (error) {
121
+ let errorMessage = 'OAuth2 token request failed';
122
+ let errorDetails = {};
123
+
124
+ if (error.response) {
125
+ errorDetails.httpStatus = error.response.status;
126
+ errorDetails.responseData = error.response.data;
127
+
128
+ if (error.response.data?.error) {
129
+ const errorCode = error.response.data.error;
130
+ const errorMappings = {
131
+ 'ERR_UNSUPPORTED_GRANT_TYPE': 'Grant type must be "client_credentials"',
132
+ 'ERR_MISSING_CLIENT_ID': 'Client ID (merchant partnerId) is required',
133
+ 'ERR_MISSING_CLIENT_SECRET': 'Client secret (base64 encoded merchant secret) is required',
134
+ 'ERR_CLIENT_NOT_FOUND': 'Merchant not found with provided client ID',
135
+ 'ERR_CLIENT_DISABLED': 'Merchant account is disabled',
136
+ 'ERR_TOKEN_EXISTS': 'Token already exists for this merchant. Only one token per merchant is allowed.'
137
+ };
138
+
139
+ errorMessage = errorMappings[errorCode] || `Error: ${errorCode}`;
140
+
141
+ // Special handling for ERR_TOKEN_EXISTS - try to get existing token info
142
+ if (errorCode === 'ERR_TOKEN_EXISTS') {
143
+ errorMessage += '\\n\\n🔍 **To find your existing token:**\\n1. Check your secure storage where you saved the previous token\\n2. Or use payware_oauth2_get_token_info if you know the token\\n3. Contact merchant to revoke existing token if you need a new one';
144
+ }
145
+ } else {
146
+ errorMessage = `HTTP ${error.response.status}: ${error.response.statusText}`;
147
+ }
148
+ } else if (error.request) {
149
+ errorMessage = 'Network error - no response received';
150
+ errorDetails.requestInfo = {
151
+ url: error.config?.url,
152
+ method: error.config?.method,
153
+ headers: error.config?.headers
154
+ };
155
+ } else {
156
+ errorMessage = error.message;
157
+ }
158
+
159
+ return {
160
+ content: [{
161
+ type: "text",
162
+ text: `❌ OAuth2 Token Request Failed
163
+
164
+ **Error**: ${errorMessage}
165
+
166
+ **Request Details:**
167
+ - ISV Partner ID: ${process.env.PAYWARE_PARTNER_ID}
168
+ - Merchant Partner ID: ${finalClientId}
169
+ - Grant Type: ${grantType}
170
+ - Target URL: ${getSandboxUrl().replace('/api', '')}/oauth2/tokens
171
+
172
+ ${Object.keys(errorDetails).length > 0 ? `
173
+ **Error Details:**
174
+ \`\`\`json
175
+ ${JSON.stringify(errorDetails, null, 2)}
176
+ \`\`\`
177
+ ` : ''}
178
+
179
+ 📋 **Troubleshooting:**
180
+ - Verify merchant partnerId (clientId) is correct
181
+ - Ensure merchant secret is properly base64 encoded
182
+ - Check if merchant account is active
183
+ - Confirm no existing token for this merchant
184
+ - Verify ISV JWT token is properly signed for OAuth2 requests`
185
+ }]
186
+ };
187
+ }
188
+ }
189
+ };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * OAuth2 Token Helper Utility
3
+ * Helps users manage OAuth2 tokens more easily
4
+ */
5
+
6
+ import { obtainTokenTool } from './obtain-token.js';
7
+ import { getTokenInfoTool } from './get-token-info.js';
8
+
9
+ /**
10
+ * Helper tool to create or find OAuth2 tokens with clear output
11
+ */
12
+ export const tokenHelperTool = {
13
+ name: 'payware_authorization_oauth2_token_helper',
14
+ description: `OAuth2 Token Helper - Create or manage tokens with clear output.
15
+
16
+ This tool helps you:
17
+ 1. Create new OAuth2 tokens (if none exists)
18
+ 2. Guide you on finding existing tokens
19
+ 3. Display token information clearly
20
+
21
+ Use this when you need a token but aren't sure if one exists or what it is.`,
22
+
23
+ inputSchema: {
24
+ type: 'object',
25
+ required: [],
26
+ properties: {
27
+ action: {
28
+ type: 'string',
29
+ enum: ['create', 'help'],
30
+ default: 'create',
31
+ description: 'Action to perform: create (attempt to create token) or help (show guidance)'
32
+ },
33
+ clientId: {
34
+ type: 'string',
35
+ description: 'Merchant Partner ID (defaults to PAYWARE_OAUTH_CLIENT_ID env var)'
36
+ },
37
+ clientSecret: {
38
+ type: 'string',
39
+ description: 'Merchant Secret (defaults to PAYWARE_OAUTH_CLIENT_SECRET env var)'
40
+ },
41
+ useSandbox: {
42
+ type: 'boolean',
43
+ description: 'Use sandbox environment for testing',
44
+ default: true
45
+ }
46
+ }
47
+ },
48
+
49
+ async handler({ action = 'create', clientId, clientSecret, useSandbox = true }) {
50
+ if (action === 'help') {
51
+ return {
52
+ content: [{
53
+ type: 'text',
54
+ text: `📋 **OAuth2 Token Management Help**
55
+
56
+ 🔑 **About OAuth2 Tokens:**
57
+ - Only ONE token allowed per merchant
58
+ - Tokens don't expire (client_credentials flow)
59
+ - Token status: PENDING → GRANTED (after merchant approval)
60
+
61
+ 🎯 **To get your token:**
62
+
63
+ **Option 1: Try creating a token**
64
+ Use: \`payware_oauth2_obtain_token\`
65
+ - If successful: New token will be clearly displayed
66
+ - If error "ERR_TOKEN_EXISTS": A token already exists
67
+
68
+ **Option 2: Check a known token**
69
+ Use: \`payware_oauth2_get_token_info\` with your saved token
70
+ - Shows current status (PENDING/GRANTED/REVOKED)
71
+
72
+ **Option 3: Create new token (if current is lost)**
73
+ 1. Contact merchant to revoke existing token
74
+ 2. Then use \`payware_oauth2_obtain_token\` to create new one
75
+
76
+ 🔐 **Security:**
77
+ - Always store tokens securely
78
+ - Keep a backup copy in secure location
79
+ - Never share tokens or commit to code repositories`
80
+ }]
81
+ };
82
+ }
83
+
84
+ // Try to create a token
85
+ const result = await obtainTokenTool.handler({ clientId, clientSecret, useSandbox });
86
+
87
+ // Check if the result indicates an ERR_TOKEN_EXISTS error
88
+ if (result.content?.[0]?.text?.includes('ERR_TOKEN_EXISTS')) {
89
+ return {
90
+ content: [{
91
+ type: 'text',
92
+ text: `⚠️ **Token Already Exists for This Merchant**
93
+
94
+ 🔍 **Your existing token is stored somewhere secure** (as per OAuth2 best practices, the server doesn't return existing tokens).
95
+
96
+ 📋 **To find your token:**
97
+
98
+ **Option 1: Check your secure storage**
99
+ - Look where you saved tokens before
100
+ - Environment variables file
101
+ - Secure configuration management
102
+ - Password manager
103
+
104
+ **Option 2: If you have the token value**
105
+ Use: \`payware_oauth2_get_token_info\` with your token to check its status
106
+
107
+ **Option 3: Create new token**
108
+ 1. Contact the merchant (Partner ID: ${process.env.PAYWARE_OAUTH_CLIENT_ID || 'not configured'})
109
+ 2. Ask them to revoke the existing token
110
+ 3. Then use \`payware_oauth2_obtain_token\` to create a new one
111
+
112
+ 💡 **Tip:** Always keep a secure backup of your OAuth2 tokens!
113
+
114
+ 📋 **For immediate help:**
115
+ Run this tool with action='help' for more detailed guidance.`
116
+ }]
117
+ };
118
+ }
119
+
120
+ // If successful, extract and highlight the token
121
+ const tokenMatch = result.content?.[0]?.text?.match(/NEW ACCESS TOKEN\*\*: ([A-Za-z0-9]+)/);
122
+ const token = tokenMatch ? tokenMatch[1] : null;
123
+
124
+ if (token) {
125
+ return {
126
+ content: [{
127
+ type: 'text',
128
+ text: `${result.content[0].text}
129
+
130
+ 🚨 **IMPORTANT: SAVE THIS TOKEN NOW!**
131
+
132
+ 📋 **Your OAuth2 Token:**
133
+ \`\`\`
134
+ ${token}
135
+ \`\`\`
136
+
137
+ 🔄 **Next Steps:**
138
+ 1. **SAVE THIS TOKEN** securely (you won't be able to retrieve it later)
139
+ 2. Check status: \`payware_oauth2_get_token_info\` with token: \`${token}\`
140
+ 3. Wait for merchant approval (status will change to GRANTED)
141
+ 4. Use token in API requests once GRANTED`
142
+ }]
143
+ };
144
+ }
145
+
146
+ // Return original result if we can't extract token but no error occurred
147
+ return result;
148
+ }
149
+ };
150
+
151
+ export default tokenHelperTool;