payment-skill 1.0.1 → 1.1.1
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/dist/commands/limits.d.ts +8 -0
- package/dist/commands/limits.d.ts.map +1 -1
- package/dist/commands/limits.js +259 -24
- package/dist/commands/limits.js.map +1 -1
- package/dist/core/config.d.ts +13 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +107 -9
- package/dist/core/config.js.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +97 -2
- package/dist/server/server.js.map +1 -1
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/commands/limits.ts +280 -25
- package/src/core/config.ts +119 -9
- package/src/server/server.ts +112 -2
- package/src/types/index.ts +31 -0
package/src/core/config.ts
CHANGED
|
@@ -75,7 +75,22 @@ export class ConfigManager {
|
|
|
75
75
|
end: '22:00',
|
|
76
76
|
timezone: 'Europe/Bucharest'
|
|
77
77
|
},
|
|
78
|
-
|
|
78
|
+
advancedLimits: {
|
|
79
|
+
cumulativeBudgets: [],
|
|
80
|
+
domainControls: {
|
|
81
|
+
mode: 'blacklist',
|
|
82
|
+
domains: []
|
|
83
|
+
},
|
|
84
|
+
geographyControls: {
|
|
85
|
+
enabled: false,
|
|
86
|
+
mode: 'allow',
|
|
87
|
+
countries: []
|
|
88
|
+
},
|
|
89
|
+
categoryControls: {
|
|
90
|
+
blockedCategories: ['gambling', 'adult', 'drugs', 'weapons', 'tobacco'],
|
|
91
|
+
allowedCategories: []
|
|
92
|
+
}
|
|
93
|
+
},
|
|
79
94
|
verifiedMerchantsOnly: true,
|
|
80
95
|
webhookUrl: null
|
|
81
96
|
};
|
|
@@ -170,22 +185,117 @@ export class ConfigManager {
|
|
|
170
185
|
this.saveConfig();
|
|
171
186
|
}
|
|
172
187
|
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
return this.config.
|
|
188
|
+
// Advanced Limits - Cumulative Budgets
|
|
189
|
+
getCumulativeBudgets(): any[] {
|
|
190
|
+
return this.config.advancedLimits?.cumulativeBudgets || [];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
addCumulativeBudget(budget: any): void {
|
|
194
|
+
if (!this.config.advancedLimits) {
|
|
195
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
196
|
+
}
|
|
197
|
+
this.config.advancedLimits.cumulativeBudgets.push(budget);
|
|
198
|
+
this.saveConfig();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
removeCumulativeBudget(index: number): void {
|
|
202
|
+
if (this.config.advancedLimits?.cumulativeBudgets) {
|
|
203
|
+
this.config.advancedLimits.cumulativeBudgets.splice(index, 1);
|
|
204
|
+
this.saveConfig();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Advanced Limits - Domain Controls
|
|
209
|
+
getDomainControls(): any {
|
|
210
|
+
return this.config.advancedLimits?.domainControls || { mode: 'blacklist', domains: [] };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
setDomainControls(controls: any): void {
|
|
214
|
+
if (!this.config.advancedLimits) {
|
|
215
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
216
|
+
}
|
|
217
|
+
this.config.advancedLimits.domainControls = controls;
|
|
218
|
+
this.saveConfig();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
addDomain(domain: string): void {
|
|
222
|
+
if (!this.config.advancedLimits) {
|
|
223
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
224
|
+
}
|
|
225
|
+
if (!this.config.advancedLimits.domainControls.domains.includes(domain)) {
|
|
226
|
+
this.config.advancedLimits.domainControls.domains.push(domain);
|
|
227
|
+
this.saveConfig();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
removeDomain(domain: string): void {
|
|
232
|
+
if (this.config.advancedLimits?.domainControls?.domains) {
|
|
233
|
+
this.config.advancedLimits.domainControls.domains =
|
|
234
|
+
this.config.advancedLimits.domainControls.domains.filter((d: string) => d !== domain);
|
|
235
|
+
this.saveConfig();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Advanced Limits - Geography Controls
|
|
240
|
+
getGeographyControls(): any {
|
|
241
|
+
return this.config.advancedLimits?.geographyControls || { enabled: false, mode: 'allow', countries: [] };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
setGeographyControls(controls: any): void {
|
|
245
|
+
if (!this.config.advancedLimits) {
|
|
246
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
247
|
+
}
|
|
248
|
+
this.config.advancedLimits.geographyControls = controls;
|
|
249
|
+
this.saveConfig();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Advanced Limits - Category Controls
|
|
253
|
+
getCategoryControls(): any {
|
|
254
|
+
return this.config.advancedLimits?.categoryControls || { blockedCategories: [], allowedCategories: [] };
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
setCategoryControls(controls: any): void {
|
|
258
|
+
if (!this.config.advancedLimits) {
|
|
259
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
260
|
+
}
|
|
261
|
+
this.config.advancedLimits.categoryControls = controls;
|
|
262
|
+
this.saveConfig();
|
|
176
263
|
}
|
|
177
264
|
|
|
178
265
|
addBlockedCategory(category: string): void {
|
|
179
|
-
if (!this.config.
|
|
180
|
-
this.config.
|
|
266
|
+
if (!this.config.advancedLimits) {
|
|
267
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
268
|
+
}
|
|
269
|
+
if (!this.config.advancedLimits.categoryControls.blockedCategories.includes(category)) {
|
|
270
|
+
this.config.advancedLimits.categoryControls.blockedCategories.push(category);
|
|
181
271
|
this.saveConfig();
|
|
182
272
|
}
|
|
183
273
|
}
|
|
184
274
|
|
|
185
275
|
removeBlockedCategory(category: string): void {
|
|
186
|
-
this.config.blockedCategories
|
|
187
|
-
this.config.blockedCategories
|
|
188
|
-
|
|
276
|
+
if (this.config.advancedLimits?.categoryControls?.blockedCategories) {
|
|
277
|
+
this.config.advancedLimits.categoryControls.blockedCategories =
|
|
278
|
+
this.config.advancedLimits.categoryControls.blockedCategories.filter((c: string) => c !== category);
|
|
279
|
+
this.saveConfig();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
addAllowedCategory(category: string): void {
|
|
284
|
+
if (!this.config.advancedLimits) {
|
|
285
|
+
this.config.advancedLimits = this.getDefaultConfig().advancedLimits;
|
|
286
|
+
}
|
|
287
|
+
if (!this.config.advancedLimits.categoryControls.allowedCategories.includes(category)) {
|
|
288
|
+
this.config.advancedLimits.categoryControls.allowedCategories.push(category);
|
|
289
|
+
this.saveConfig();
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
removeAllowedCategory(category: string): void {
|
|
294
|
+
if (this.config.advancedLimits?.categoryControls?.allowedCategories) {
|
|
295
|
+
this.config.advancedLimits.categoryControls.allowedCategories =
|
|
296
|
+
this.config.advancedLimits.categoryControls.allowedCategories.filter((c: string) => c !== category);
|
|
297
|
+
this.saveConfig();
|
|
298
|
+
}
|
|
189
299
|
}
|
|
190
300
|
|
|
191
301
|
// Webhook URL
|
package/src/server/server.ts
CHANGED
|
@@ -84,14 +84,124 @@ export class PaymentSkillServer {
|
|
|
84
84
|
res.json({ success: true, message: 'Emergency stop deactivated' });
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
// Get limits
|
|
87
|
+
// Get all limits and controls
|
|
88
88
|
this.app.get('/api/limits', (req, res) => {
|
|
89
89
|
res.json({
|
|
90
90
|
limits: configManager.getLimits(),
|
|
91
|
-
timeWindow: configManager.getTimeWindow()
|
|
91
|
+
timeWindow: configManager.getTimeWindow(),
|
|
92
|
+
cumulativeBudgets: configManager.getCumulativeBudgets(),
|
|
93
|
+
domainControls: configManager.getDomainControls(),
|
|
94
|
+
geographyControls: configManager.getGeographyControls(),
|
|
95
|
+
categoryControls: configManager.getCategoryControls()
|
|
92
96
|
});
|
|
93
97
|
});
|
|
94
98
|
|
|
99
|
+
// Update basic limits
|
|
100
|
+
this.app.post('/api/limits', (req, res) => {
|
|
101
|
+
const { perTransaction, daily, weekly, monthly, maxTransactionsPerHour } = req.body;
|
|
102
|
+
configManager.setLimits({ perTransaction, daily, weekly, monthly, maxTransactionsPerHour });
|
|
103
|
+
res.json({ success: true, message: 'Limits updated' });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Cumulative Budgets
|
|
107
|
+
this.app.get('/api/limits/budgets', (req, res) => {
|
|
108
|
+
res.json(configManager.getCumulativeBudgets());
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
this.app.post('/api/limits/budgets', (req, res) => {
|
|
112
|
+
configManager.addCumulativeBudget(req.body);
|
|
113
|
+
res.json({ success: true, message: 'Budget added' });
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
this.app.delete('/api/limits/budgets/:index', (req, res) => {
|
|
117
|
+
configManager.removeCumulativeBudget(parseInt(req.params.index));
|
|
118
|
+
res.json({ success: true, message: 'Budget removed' });
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Domain Controls
|
|
122
|
+
this.app.get('/api/limits/domains', (req, res) => {
|
|
123
|
+
res.json(configManager.getDomainControls());
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
this.app.post('/api/limits/domains', (req, res) => {
|
|
127
|
+
const { mode, domain } = req.body;
|
|
128
|
+
if (mode) {
|
|
129
|
+
const controls = configManager.getDomainControls();
|
|
130
|
+
controls.mode = mode;
|
|
131
|
+
configManager.setDomainControls(controls);
|
|
132
|
+
}
|
|
133
|
+
if (domain) {
|
|
134
|
+
configManager.addDomain(domain);
|
|
135
|
+
}
|
|
136
|
+
res.json({ success: true, message: 'Domain controls updated' });
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
this.app.delete('/api/limits/domains/:domain', (req, res) => {
|
|
140
|
+
configManager.removeDomain(req.params.domain);
|
|
141
|
+
res.json({ success: true, message: 'Domain removed' });
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Time Window
|
|
145
|
+
this.app.get('/api/limits/time-window', (req, res) => {
|
|
146
|
+
res.json(configManager.getTimeWindow());
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
this.app.post('/api/limits/time-window', (req, res) => {
|
|
150
|
+
configManager.setTimeWindow(req.body);
|
|
151
|
+
res.json({ success: true, message: 'Time window updated' });
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Geography Controls
|
|
155
|
+
this.app.get('/api/limits/geo', (req, res) => {
|
|
156
|
+
res.json(configManager.getGeographyControls());
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
this.app.post('/api/limits/geo', (req, res) => {
|
|
160
|
+
const { enabled, mode, country } = req.body;
|
|
161
|
+
const controls = configManager.getGeographyControls();
|
|
162
|
+
if (enabled !== undefined) controls.enabled = enabled;
|
|
163
|
+
if (mode) controls.mode = mode;
|
|
164
|
+
if (country) {
|
|
165
|
+
if (!controls.countries.includes(country)) {
|
|
166
|
+
controls.countries.push(country);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
configManager.setGeographyControls(controls);
|
|
170
|
+
res.json({ success: true, message: 'Geography controls updated' });
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
this.app.delete('/api/limits/geo/:country', (req, res) => {
|
|
174
|
+
const controls = configManager.getGeographyControls();
|
|
175
|
+
controls.countries = controls.countries.filter((c: string) => c !== req.params.country);
|
|
176
|
+
configManager.setGeographyControls(controls);
|
|
177
|
+
res.json({ success: true, message: 'Country removed' });
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Category Controls
|
|
181
|
+
this.app.get('/api/limits/categories', (req, res) => {
|
|
182
|
+
res.json(configManager.getCategoryControls());
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
this.app.post('/api/limits/categories/block', (req, res) => {
|
|
186
|
+
configManager.addBlockedCategory(req.body.category);
|
|
187
|
+
res.json({ success: true, message: 'Category blocked' });
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
this.app.post('/api/limits/categories/unblock', (req, res) => {
|
|
191
|
+
configManager.removeBlockedCategory(req.body.category);
|
|
192
|
+
res.json({ success: true, message: 'Category unblocked' });
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
this.app.post('/api/limits/categories/allow', (req, res) => {
|
|
196
|
+
configManager.addAllowedCategory(req.body.category);
|
|
197
|
+
res.json({ success: true, message: 'Category added to allowed list' });
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
this.app.post('/api/limits/categories/disallow', (req, res) => {
|
|
201
|
+
configManager.removeAllowedCategory(req.body.category);
|
|
202
|
+
res.json({ success: true, message: 'Category removed from allowed list' });
|
|
203
|
+
});
|
|
204
|
+
|
|
95
205
|
// Webhook endpoints
|
|
96
206
|
this.app.post('/webhooks/wise', (req, res) => {
|
|
97
207
|
console.log('Wise webhook received:', req.body);
|
package/src/types/index.ts
CHANGED
|
@@ -135,6 +135,37 @@ export interface TimeWindowConfig {
|
|
|
135
135
|
blockedDays?: string[];
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
+
export interface CumulativeBudget {
|
|
139
|
+
enabled: boolean;
|
|
140
|
+
amount: number;
|
|
141
|
+
period: 'daily' | 'weekly' | 'monthly';
|
|
142
|
+
resetDay?: number; // For monthly: 1-31
|
|
143
|
+
resetDayOfWeek?: number; // For weekly: 0-6 (Sunday-Saturday)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface DomainControl {
|
|
147
|
+
mode: 'whitelist' | 'blacklist';
|
|
148
|
+
domains: string[];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface GeographyControl {
|
|
152
|
+
enabled: boolean;
|
|
153
|
+
mode: 'allow' | 'block';
|
|
154
|
+
countries: string[]; // ISO country codes
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface CategoryControl {
|
|
158
|
+
blockedCategories: string[];
|
|
159
|
+
allowedCategories?: string[]; // If set, only these are allowed
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface AdvancedLimits {
|
|
163
|
+
cumulativeBudgets: CumulativeBudget[];
|
|
164
|
+
domainControls: DomainControl;
|
|
165
|
+
geographyControls: GeographyControl;
|
|
166
|
+
categoryControls: CategoryControl;
|
|
167
|
+
}
|
|
168
|
+
|
|
138
169
|
// Emergency Stop Types
|
|
139
170
|
export interface EmergencyStopState {
|
|
140
171
|
active: boolean;
|