payment-kit 1.21.2 → 1.21.3
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/api/src/routes/meter-events.ts +2 -2
- package/api/src/routes/meters.ts +1 -1
- package/api/src/routes/vendor.ts +1 -1
- package/api/src/store/models/meter-event.ts +1 -1
- package/api/src/store/models/meter.ts +2 -5
- package/blocklet.yml +1 -1
- package/package.json +6 -6
- package/src/pages/integrations/overview.tsx +1 -1
- package/src/libs/meter-utils.ts +0 -196
|
@@ -222,7 +222,7 @@ router.post('/', auth, async (req, res) => {
|
|
|
222
222
|
return res.status(400).json({ error: `Event with identifier "${req.body.identifier}" already exists` });
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
const meter = await Meter.getMeterByEventName(req.body.event_name
|
|
225
|
+
const meter = await Meter.getMeterByEventName(req.body.event_name);
|
|
226
226
|
if (!meter) {
|
|
227
227
|
return res
|
|
228
228
|
.status(400)
|
|
@@ -361,7 +361,7 @@ router.get('/:id', authMine, async (req, res) => {
|
|
|
361
361
|
if (customer.did !== req.user?.did && !['owner', 'admin'].includes(req.user?.role || '')) {
|
|
362
362
|
return res.status(403).json({ error: 'You are not allowed to access this resource' });
|
|
363
363
|
}
|
|
364
|
-
const meter = await Meter.getMeterByEventName(event.event_name
|
|
364
|
+
const meter = await Meter.getMeterByEventName(event.event_name);
|
|
365
365
|
let paymentCurrency = null;
|
|
366
366
|
if (meter) {
|
|
367
367
|
paymentCurrency = await PaymentCurrency.findByPk(meter.currency_id);
|
package/api/src/routes/meters.ts
CHANGED
|
@@ -68,7 +68,7 @@ router.post('/', auth, async (req, res) => {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
const existing = await Meter.findOne({
|
|
71
|
-
where: { event_name: req.body.event_name
|
|
71
|
+
where: { event_name: req.body.event_name },
|
|
72
72
|
});
|
|
73
73
|
if (existing) {
|
|
74
74
|
return res.status(409).json({ error: `Meter with event_name "${req.body.event_name}" already exists` });
|
package/api/src/routes/vendor.ts
CHANGED
|
@@ -603,7 +603,7 @@ router.get('/subscription/:sessionId', ensureVendorAuth, getVendorSubscription);
|
|
|
603
603
|
|
|
604
604
|
router.get(
|
|
605
605
|
'/open/:subscriptionId',
|
|
606
|
-
|
|
606
|
+
loginAuth,
|
|
607
607
|
validateParams(subscriptionIdParamSchema),
|
|
608
608
|
validateQuery(vendorRedirectQuerySchema),
|
|
609
609
|
redirectToVendor
|
|
@@ -374,7 +374,7 @@ export class MeterEvent extends Model<InferAttributes<MeterEvent>, InferCreation
|
|
|
374
374
|
|
|
375
375
|
await Promise.all(
|
|
376
376
|
events.map(async (event) => {
|
|
377
|
-
const meter = await Meter.getMeterByEventName(event.event_name
|
|
377
|
+
const meter = await Meter.getMeterByEventName(event.event_name);
|
|
378
378
|
if (!meter) {
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
@@ -146,11 +146,8 @@ export class Meter extends Model<InferAttributes<Meter>, InferCreationAttributes
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
public static getMeterByEventName(eventName: string
|
|
150
|
-
const whereClause: any = { event_name: eventName
|
|
151
|
-
if (livemode !== undefined) {
|
|
152
|
-
whereClause.livemode = livemode;
|
|
153
|
-
}
|
|
149
|
+
public static getMeterByEventName(eventName: string): Promise<Meter | null> {
|
|
150
|
+
const whereClause: any = { event_name: eventName };
|
|
154
151
|
return this.findOne({ where: whereClause });
|
|
155
152
|
}
|
|
156
153
|
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.3",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"@blocklet/error": "^0.2.5",
|
|
57
57
|
"@blocklet/js-sdk": "^1.16.52-beta-20250912-112002-e3499e9c",
|
|
58
58
|
"@blocklet/logger": "^1.16.52-beta-20250912-112002-e3499e9c",
|
|
59
|
-
"@blocklet/payment-broker-client": "1.21.
|
|
60
|
-
"@blocklet/payment-react": "1.21.
|
|
61
|
-
"@blocklet/payment-vendor": "1.21.
|
|
59
|
+
"@blocklet/payment-broker-client": "1.21.3",
|
|
60
|
+
"@blocklet/payment-react": "1.21.3",
|
|
61
|
+
"@blocklet/payment-vendor": "1.21.3",
|
|
62
62
|
"@blocklet/sdk": "^1.16.52-beta-20250912-112002-e3499e9c",
|
|
63
63
|
"@blocklet/ui-react": "^3.1.43",
|
|
64
64
|
"@blocklet/uploader": "^0.2.12",
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"devDependencies": {
|
|
129
129
|
"@abtnode/types": "^1.16.52-beta-20250912-112002-e3499e9c",
|
|
130
130
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
131
|
-
"@blocklet/payment-types": "1.21.
|
|
131
|
+
"@blocklet/payment-types": "1.21.3",
|
|
132
132
|
"@types/cookie-parser": "^1.4.9",
|
|
133
133
|
"@types/cors": "^2.8.19",
|
|
134
134
|
"@types/debug": "^4.1.12",
|
|
@@ -175,5 +175,5 @@
|
|
|
175
175
|
"parser": "typescript"
|
|
176
176
|
}
|
|
177
177
|
},
|
|
178
|
-
"gitHead": "
|
|
178
|
+
"gitHead": "ea1d64db9e337e2cdea02c86a0ab91b885830a11"
|
|
179
179
|
}
|
|
@@ -261,7 +261,7 @@ export default function Overview() {
|
|
|
261
261
|
actions={
|
|
262
262
|
<Box sx={{ display: 'flex', gap: 2 }}>
|
|
263
263
|
<Button onClick={() => setOpenMeterDialog(false)}>{t('common.cancel')}</Button>
|
|
264
|
-
<Button onClick={() => navigate('/admin/meters')} variant="contained">
|
|
264
|
+
<Button onClick={() => navigate('/admin/billing/meters')} variant="contained">
|
|
265
265
|
{t('common.goToConfigure')}
|
|
266
266
|
</Button>
|
|
267
267
|
</Box>
|
package/src/libs/meter-utils.ts
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { api } from '@blocklet/payment-react';
|
|
2
|
-
import type { TMeter, TCustomer, TPaymentCurrency, TSubscription } from '@blocklet/payment-types';
|
|
3
|
-
|
|
4
|
-
export interface MeterInfo {
|
|
5
|
-
meter?: TMeter & { paymentCurrency?: TPaymentCurrency };
|
|
6
|
-
customer?: TCustomer;
|
|
7
|
-
paymentCurrency?: TPaymentCurrency;
|
|
8
|
-
subscription?: TSubscription;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface GetMeterInfoOptions {
|
|
12
|
-
meterId?: string;
|
|
13
|
-
customerId?: string;
|
|
14
|
-
eventName?: string;
|
|
15
|
-
includeCustomer?: boolean;
|
|
16
|
-
includePaymentCurrency?: boolean;
|
|
17
|
-
includeSubscription?: boolean;
|
|
18
|
-
subscriptionId?: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* 获取meter相关信息的通用方法
|
|
23
|
-
* @param options 配置选项
|
|
24
|
-
* @returns Promise<MeterInfo>
|
|
25
|
-
*/
|
|
26
|
-
export async function getMeterInfo(options: GetMeterInfoOptions = {}): Promise<MeterInfo> {
|
|
27
|
-
const {
|
|
28
|
-
meterId,
|
|
29
|
-
customerId,
|
|
30
|
-
eventName,
|
|
31
|
-
includeCustomer = false,
|
|
32
|
-
includePaymentCurrency = false,
|
|
33
|
-
includeSubscription = false,
|
|
34
|
-
subscriptionId,
|
|
35
|
-
} = options;
|
|
36
|
-
|
|
37
|
-
const result: MeterInfo = {};
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
// 获取meter信息
|
|
41
|
-
if (meterId) {
|
|
42
|
-
const { data: meter } = await api.get(`/api/meters/${meterId}`);
|
|
43
|
-
result.meter = meter;
|
|
44
|
-
|
|
45
|
-
// 如果meter包含paymentCurrency且需要包含
|
|
46
|
-
if (includePaymentCurrency && meter.paymentCurrency) {
|
|
47
|
-
result.paymentCurrency = meter.paymentCurrency;
|
|
48
|
-
}
|
|
49
|
-
} else if (eventName) {
|
|
50
|
-
// 通过event_name查找meter
|
|
51
|
-
const { data: meters } = await api.get(`/api/meters?event_name=${encodeURIComponent(eventName)}`);
|
|
52
|
-
if (meters.list && meters.list.length > 0) {
|
|
53
|
-
const [firstMeter] = meters.list;
|
|
54
|
-
result.meter = firstMeter;
|
|
55
|
-
|
|
56
|
-
if (includePaymentCurrency && firstMeter.paymentCurrency) {
|
|
57
|
-
result.paymentCurrency = firstMeter.paymentCurrency;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// 获取customer信息
|
|
63
|
-
if (includeCustomer && customerId) {
|
|
64
|
-
const { data: customer } = await api.get(`/api/customers/${customerId}`);
|
|
65
|
-
result.customer = customer;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// 获取subscription信息
|
|
69
|
-
if (includeSubscription && subscriptionId) {
|
|
70
|
-
const { data: subscription } = await api.get(`/api/subscriptions/${subscriptionId}`);
|
|
71
|
-
result.subscription = subscription;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// 如果需要paymentCurrency但还没有获取到,尝试从meter的currency_id获取
|
|
75
|
-
if (includePaymentCurrency && !result.paymentCurrency && result.meter?.currency_id) {
|
|
76
|
-
try {
|
|
77
|
-
const { data: paymentCurrency } = await api.get(`/api/payment-currencies/${result.meter.currency_id}`);
|
|
78
|
-
result.paymentCurrency = paymentCurrency;
|
|
79
|
-
} catch (err) {
|
|
80
|
-
console.warn('Failed to fetch payment currency:', err);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return result;
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.error('Error fetching meter info:', error);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* 获取meter的完整信息(包含所有关联数据)
|
|
93
|
-
* @param meterId meter ID
|
|
94
|
-
* @returns Promise<MeterInfo>
|
|
95
|
-
*/
|
|
96
|
-
export function getMeterFullInfo(meterId: string): Promise<MeterInfo> {
|
|
97
|
-
return getMeterInfo({
|
|
98
|
-
meterId,
|
|
99
|
-
includePaymentCurrency: true,
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* 根据事件名称获取meter信息
|
|
105
|
-
* @param eventName 事件名称
|
|
106
|
-
* @param includePaymentCurrency 是否包含支付货币信息
|
|
107
|
-
* @returns Promise<MeterInfo>
|
|
108
|
-
*/
|
|
109
|
-
export function getMeterByEventName(eventName: string, includePaymentCurrency = true): Promise<MeterInfo> {
|
|
110
|
-
return getMeterInfo({
|
|
111
|
-
eventName,
|
|
112
|
-
includePaymentCurrency,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 获取meter事件的完整上下文信息
|
|
118
|
-
* @param options 配置选项
|
|
119
|
-
* @returns Promise<MeterInfo>
|
|
120
|
-
*/
|
|
121
|
-
export function getMeterEventContext(options: {
|
|
122
|
-
meterId?: string;
|
|
123
|
-
eventName?: string;
|
|
124
|
-
customerId?: string;
|
|
125
|
-
subscriptionId?: string;
|
|
126
|
-
}): Promise<MeterInfo> {
|
|
127
|
-
const { meterId, eventName, customerId, subscriptionId } = options;
|
|
128
|
-
|
|
129
|
-
return getMeterInfo({
|
|
130
|
-
meterId,
|
|
131
|
-
eventName,
|
|
132
|
-
customerId,
|
|
133
|
-
subscriptionId,
|
|
134
|
-
includeCustomer: !!customerId,
|
|
135
|
-
includePaymentCurrency: true,
|
|
136
|
-
includeSubscription: !!subscriptionId,
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* 批量获取多个meter的信息
|
|
142
|
-
* @param meterIds meter ID数组
|
|
143
|
-
* @param includePaymentCurrency 是否包含支付货币信息
|
|
144
|
-
* @returns Promise<MeterInfo[]>
|
|
145
|
-
*/
|
|
146
|
-
export function getBatchMeterInfo(meterIds: string[], includePaymentCurrency = true): Promise<MeterInfo[]> {
|
|
147
|
-
const promises = meterIds.map((meterId) =>
|
|
148
|
-
getMeterInfo({
|
|
149
|
-
meterId,
|
|
150
|
-
includePaymentCurrency,
|
|
151
|
-
}).catch((error) => {
|
|
152
|
-
console.warn(`Failed to fetch meter ${meterId}:`, error);
|
|
153
|
-
return { meter: undefined };
|
|
154
|
-
})
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
return Promise.all(promises);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* 获取客户的meter使用情况
|
|
162
|
-
* @param customerId 客户ID
|
|
163
|
-
* @param meterId 可选的meter ID,如果不提供则获取所有meter
|
|
164
|
-
* @returns Promise<MeterInfo[]>
|
|
165
|
-
*/
|
|
166
|
-
export async function getCustomerMeterUsage(customerId: string, meterId?: string): Promise<MeterInfo[]> {
|
|
167
|
-
try {
|
|
168
|
-
// 获取客户的credit transactions来找到相关的meters
|
|
169
|
-
const params = new URLSearchParams();
|
|
170
|
-
params.append('customer_id', customerId);
|
|
171
|
-
if (meterId) {
|
|
172
|
-
params.append('meter_id', meterId);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const { data: transactions } = await api.get(`/api/credit-transactions?${params.toString()}`);
|
|
176
|
-
|
|
177
|
-
// 提取唯一的meter IDs
|
|
178
|
-
const uniqueMeterIds = [
|
|
179
|
-
...new Set(
|
|
180
|
-
transactions.list
|
|
181
|
-
?.map((t: any) => t.meter?.id)
|
|
182
|
-
.filter((id: any): id is string => Boolean(id) && typeof id === 'string')
|
|
183
|
-
),
|
|
184
|
-
] as string[];
|
|
185
|
-
|
|
186
|
-
if (uniqueMeterIds.length === 0) {
|
|
187
|
-
return [];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// 批量获取meter信息
|
|
191
|
-
return await getBatchMeterInfo(uniqueMeterIds);
|
|
192
|
-
} catch (error) {
|
|
193
|
-
console.error('Error fetching customer meter usage:', error);
|
|
194
|
-
return [];
|
|
195
|
-
}
|
|
196
|
-
}
|