payment-kit 1.24.2 → 1.24.4

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.
@@ -66,8 +66,8 @@ export default flat({
66
66
  },
67
67
 
68
68
  webhookEndpointFailed: {
69
- title: 'Webhook endpoint alert: {webhookUrl}',
70
- body: 'Your webhook endpoint has failed {failedCount} times consecutively. Please check the webhook details and ensure the endpoint is accessible and functioning correctly.',
69
+ title: 'System Alert: Webhook Failure ({webhookUrl})',
70
+ body: 'Your webhook endpoint has failed {failedCount} times in a row. Please check your endpoint configuration immediately.',
71
71
  },
72
72
 
73
73
  sendTo: 'Sent to',
@@ -89,38 +89,70 @@ export default flat({
89
89
  view: 'Manage subscriptions',
90
90
  },
91
91
 
92
+ healthReport: {
93
+ title: 'Payment Kit Daily Data Report',
94
+ period: 'Data period: {start} – {end} (UTC)',
95
+ attentionSummary: '⚠️ {count} items need attention',
96
+ attentionSummaryEmpty: '✅ No items need attention today',
97
+ attentionEmpty: 'No items need attention',
98
+ attentionUnreportedLabel: 'Metering anomaly subscriptions',
99
+ attentionUnreportedValue: '{count} total, IDs: {ids}',
100
+ attentionDiscrepantLabel: 'Billing discrepancy subscriptions',
101
+ attentionDiscrepantValue: '{count} total, IDs: {ids}',
102
+ attentionPendingConsumptionLabel: 'Overdue consumption',
103
+ attentionPendingConsumptionValue: '{customers} customers, total {amount}',
104
+ attentionRefundLabel: 'Refunds',
105
+ attentionRefundValue: '{refundCount} refunds, total {refundAmount}',
106
+ attentionPastDueLabel: 'Past due subscriptions',
107
+ attentionPastDueValue: '{count}',
108
+ coreMetricsTitle: '💰 Core Operating Metrics',
109
+ coreRevenueLabel: 'Revenue',
110
+ coreRevenueValue: '{revenue}',
111
+ coreNewSubscriptionsLabel: 'New subscriptions',
112
+ coreNewSubscriptionsValue: '{count}',
113
+ coreCanceledSubscriptionsLabel: 'Canceled subscriptions',
114
+ coreCanceledSubscriptionsValue: '{count}',
115
+ corePaymentSuccessRateLabel: 'Payment success rate',
116
+ corePaymentSuccessRateValue: '{rate}% ({succeeded}, {failed})',
117
+ paymentSuccessCount: 'Success {count}',
118
+ paymentFailedCount: 'Failed {count}',
119
+ viewDataOverview: 'Data Overview',
120
+ viewSubscriptions: 'View Subscriptions',
121
+ viewOverdue: 'View Overdue Consumption',
122
+ },
123
+
92
124
  subscriptionTrialStart: {
93
- title: 'Welcome to the start of your {productName} trial',
94
- body: 'Congratulations on starting your {productName} trial! Your trial period is {trialDuration} and will end on {subscriptionTrialEnd}. Enjoy exploring {productName}!',
125
+ title: '{productName} Trial Active',
126
+ body: 'Your {productName} trial is now active. You have full access until {subscriptionTrialEnd}.',
95
127
  },
96
128
 
97
129
  subscriptionTrialWillEnd: {
98
- title: 'The {productName} trial will end soon',
99
- body: 'Your trial for {productName} will end in {willRenewDuration}. Please ensure your account balance is sufficient for automatic billing after the trial ends. Thank you for your support and trust!',
130
+ title: 'Trial Ending Soon: {productName}',
131
+ body: 'Your trial for {productName} ends in {willRenewDuration}. To ensure uninterrupted service, please check your payment details.',
100
132
  unableToPayBody:
101
- 'Your trial for {productName} will end in {willRenewDuration}. Your current balance is {balance}, which is less than {price}. Please ensure your balance is sufficient for automatic billing. Thank you for your support and trust!',
133
+ 'Your trial ends in {willRenewDuration}, but your current balance ({balance}) is below the renewal price ({price}). Please add funds to ensure uninterrupted service.',
102
134
  unableToPayReason:
103
- 'The estimated payment amount is {price}, but your current balance is insufficient ({balance}). Please ensure your account has enough balance to avoid payment failure.',
135
+ 'The estimated renewal is {price}, but your balance is only {balance}. Please add funds to avoid payment failure.',
104
136
  },
105
137
 
106
138
  subscriptionSucceed: {
107
- title: "Congratulations! You've successfully subscribed to {productName}",
108
- body: 'Thank you for successfully subscribing to {productName} on {at}. We are happy to provide you with excellent service, and we wish you a pleasant experience.',
139
+ title: '{productName} is ready to use',
140
+ body: 'Your subscription is confirmed. You can now access {productName} or manage your deployment settings below.',
109
141
  },
110
142
 
111
143
  oneTimePaymentSucceeded: {
112
- title: 'Congratulations! Your purchase of {productName} was successful',
113
- body: 'Thank you for successfully purchasing {productName} on {at}. We will provide you with excellent service, and we wish you a pleasant experience!',
144
+ title: 'Purchase Confirmed: {productName}',
145
+ body: 'We have received your payment for {productName} on {at}. Your service is ready to use.',
114
146
  },
115
147
 
116
148
  subscriptionUpgraded: {
117
- title: 'Congratulations! Your subscription plan for {productName} has been successfully upgraded',
118
- body: 'Your subscription plan for {productName} has been successfully upgraded on {at}. Thank you for your support, and we wish you a pleasant experience!',
149
+ title: 'Upgrade Complete: {productName}',
150
+ body: 'Your {productName} plan was successfully upgraded on {at}. All new features are available immediately.',
119
151
  },
120
152
 
121
153
  subscriptionWillRenew: {
122
- title: '{productName} automatic payment reminder',
123
- body: 'Your subscription to {productName} is scheduled for automatic payment on {at}({willRenewDuration} later). If you have any questions or need assistance, please feel free to contact us.',
154
+ title: 'Upcoming renewal: {productName}',
155
+ body: 'Just a heads up that your subscription for {productName} will renew on {at}. No action is needed if you want to keep running.',
124
156
  unableToPayBody:
125
157
  'Your subscription to {productName} is scheduled for automatic payment on {at}({willRenewDuration} later). If you have any questions or need assistance, please feel free to contact us.',
126
158
  unableToPayReason:
@@ -130,14 +162,14 @@ export default flat({
130
162
  },
131
163
 
132
164
  subscriptionRenewed: {
133
- title: '{productName} payment successful',
134
- body: 'Payment for your {productName} subscription was successfully collected on {at}. Thanks for your continued support and trust. We wish you a pleasant experience using this service!',
165
+ title: 'Payment Successful: {productName}',
166
+ body: 'Your renewal for {productName} was processed on {at}. No further action is needed.',
135
167
  noExpenseIncurred: 'No expenses incurred during the service period',
136
168
  },
137
169
 
138
170
  subscriptionRenewFailed: {
139
- title: '{productName} automatic payment failed',
140
- body: 'We are sorry to inform you that your {productName} automatic payment failed on {at}. If you have any questions, please contact us promptly. Thank you!',
171
+ title: 'Action Required: Payment for {productName} failed',
172
+ body: "We couldn't process the renewal for {productName} on {at}. To prevent your App from going offline, please update your payment method.",
141
173
  reason: {
142
174
  noDidWallet: 'You have not connected a DID Wallet. Please connect your DID Wallet to ensure sufficient balance',
143
175
  noDelegation: 'Your DID Wallet has not been authorized. Please update authorization',
@@ -156,8 +188,8 @@ export default flat({
156
188
  },
157
189
 
158
190
  autoRechargeFailed: {
159
- title: 'Auto Top-Up payment failed',
160
- body: 'We are sorry to inform you that your {creditCurrencyName} auto top-up automatic payment failed on {at}. If you have any questions, please contact us promptly. Thank you!',
191
+ title: 'Action Required: Auto Top-Up Failed',
192
+ body: "We couldn't process your auto top-up for {creditCurrencyName} on {at}. Please update your payment method to ensure your services stay online.",
161
193
  reason: {
162
194
  noDidWallet: 'You have not connected a DID Wallet. Please connect your DID Wallet to ensure sufficient balance',
163
195
  noDelegation: 'Your DID Wallet has not been authorized. Please update authorization',
@@ -175,9 +207,16 @@ export default flat({
175
207
  },
176
208
  },
177
209
 
210
+ autoRechargeDailyLimitExceeded: {
211
+ title: 'Auto Top-Up daily limit reached',
212
+ body: 'Your {creditCurrencyName} balance is low, but auto top-up was not triggered because you have reached the daily recharge limit on {at}. You can manually reload or wait until tomorrow for automatic top-up.',
213
+ dailyLimit: 'Daily Limit',
214
+ dailyUsed: 'Used Today',
215
+ },
216
+
178
217
  subscriptionRefundSucceeded: {
179
- title: '{productName} refund successful',
180
- body: 'Your subscription to {productName} has been successfully refunded on {at}, with a refund amount of {refundInfo}. If you have any questions, please feel free to contact us.',
218
+ title: 'Refund Processed: {productName}',
219
+ body: 'A refund of {refundInfo} for {productName} was processed on {at}. It may take a few days to appear in your account.',
181
220
  },
182
221
 
183
222
  oneTimePaymentRefundSucceeded: {
@@ -207,23 +246,23 @@ export default flat({
207
246
 
208
247
  customerRevenueSucceeded: {
209
248
  donate: {
210
- title: 'You received a tip',
211
- body: 'Congratulations! On {at}, you received a tip of {amount} from {user}.',
249
+ title: 'New Tip Received!',
250
+ body: 'You received a tip of {amount} from {user} on {at}. Nice work!',
212
251
  tipDetail: 'View Tip Reference',
213
252
  },
214
253
  payment: {
215
- title: 'You received a payment',
216
- body: 'Congratulations! On {at}, you received a payment of {amount} from {user}.',
254
+ title: 'Payment Received',
255
+ body: 'You received a payment of {amount} from {user} on {at}.',
217
256
  },
218
257
  sender: 'Payer',
219
258
  viewDetail: 'View Details',
220
259
  sent: '{address} has sent {amount}',
221
260
  },
222
261
  subscriptWillCanceled: {
223
- title: '{productName} subscription is about to be cancelled',
262
+ title: 'Subscription Cancelled: {productName}',
263
+ body: "This subscription has been cancelled and will end on {at}. If this was a mistake, or if you'd like to reactivate, you can do so below.",
224
264
  pastDue:
225
265
  'Your {productName} subscription will be automatically cancelled by the system after {at} ({willCancelDuration} later) due to repeated automatic payment failures. Please resolve the automatic payment issue manually to avoid service interruption. If you have any questions, please feel free to contact us.',
226
- body: 'Your subscription to {productName} will be automatically canceled on {at} ({willCancelDuration} later). If you have any questions, please feel free to contact us.',
227
266
  renewAmount: 'Deduction amount',
228
267
  cancelReason: 'Cancel reason',
229
268
  revokeStake: 'Revoke stake',
@@ -263,11 +302,9 @@ export default flat({
263
302
  },
264
303
 
265
304
  creditInsufficient: {
266
- title: 'Insufficient Credit Balance',
305
+ title: 'Service Risk: Low Credit Balance',
267
306
  bodyWithSubscription:
268
- 'Your available credit balance ({availableAmount}) is not enough to cover your subscription to {subscriptionName}. To ensure uninterrupted service, please reload your account.',
269
- bodyWithoutSubscription:
270
- 'Your available credit balance ({availableAmount}) is not enough to continue using the service. To ensure uninterrupted service, please reload your account.',
307
+ 'Your credits ({availableAmount}) are too low to maintain your {subscriptionName} subscription. Please reload now to ensure your App stays online.',
271
308
  exhaustedTitle: 'Credit Balance Exhausted – Please Reload',
272
309
  exhaustedBodyWithSubscription:
273
310
  'Your credit balance is fully exhausted and can no longer cover your subscription to {subscriptionName}. To ensure uninterrupted service, please reload your account.',
@@ -276,6 +313,7 @@ export default flat({
276
313
  meterEventName: 'Service',
277
314
  availableCredit: 'Available Balance',
278
315
  requiredCredit: 'Required Credit',
316
+ pendingAmount: 'Outstanding Amount',
279
317
  },
280
318
 
281
319
  creditGrantGranted: {
@@ -288,8 +326,8 @@ export default flat({
288
326
  },
289
327
 
290
328
  creditLowBalance: {
291
- title: 'Your credit balance is low',
292
- body: 'Your {currency} balance has dropped to critical levels ({lowBalancePercentage}). To ensure uninterrupted service, please reload your account.',
329
+ title: 'Low Balance Alert',
330
+ body: 'Your {currency} balance is down to {lowBalancePercentage}. Please reload soon to prevent service interruption.',
293
331
  remainingBalance: 'Remaining Balance',
294
332
  status: 'Status',
295
333
  lessThanOnePercent: 'less than 1%',
@@ -76,11 +76,6 @@ export default flat({
76
76
  body: '检测到 {productName} 账单金额核算不一致,请留意。',
77
77
  },
78
78
 
79
- webhookEndpointFailed: {
80
- title: 'Webhook 端点警告: {webhookUrl}',
81
- body: '您的 Webhook 端点已连续失败 {failedCount} 次,请查看详情并确保端点可正常访问和工作。',
82
- },
83
-
84
79
  meteringSubscriptionDetection: {
85
80
  title: '[{appName}] 按量计费订阅检测',
86
81
  body: '在 {startTimeStr} - {endTimeStr} 期间,共扫描了 {totalCount} 份按量计费的订阅,其中 {normalCount} 份为正常订阅,{abnormalCount} 份存在异常,包括 {unreportedCount} 份未上报的订阅和 {discrepantCount} 份账单核算有问题的订阅。\n\n 异常订阅:',
@@ -88,38 +83,74 @@ export default flat({
88
83
  view: '管理订阅',
89
84
  },
90
85
 
86
+ webhookEndpointFailed: {
87
+ title: '系统警报:Webhook 失败 ({webhookUrl})',
88
+ body: '您的 Webhook 端点已连续失败 {failedCount} 次,请立即检查您的端点配置。',
89
+ },
90
+
91
+ healthReport: {
92
+ title: 'Payment Kit 每日数据报告',
93
+ period: '数据周期:{start} – {end}(UTC)',
94
+ attentionSummary: '⚠️ {count} 个需要关注的事项',
95
+ attentionSummaryEmpty: '✅ 今日无需要关注的事项',
96
+ attentionEmpty: '暂无需要关注的事项',
97
+ attentionUnreportedLabel: '计费异常订阅',
98
+ attentionUnreportedValue: '共 {count} 个,ID:{ids}',
99
+ attentionDiscrepantLabel: '计费差异订阅',
100
+ attentionDiscrepantValue: '共 {count} 个,ID:{ids}',
101
+ attentionPendingConsumptionLabel: '欠费额度',
102
+ attentionPendingConsumptionValue: '{customers} 个用户,合计 {amount}',
103
+ attentionRefundLabel: '退款',
104
+ attentionRefundValue: '{refundCount} 笔退款,合计 {refundAmount}',
105
+ attentionPastDueLabel: '逾期订阅',
106
+ attentionPastDueValue: '{count} 个',
107
+ coreMetricsTitle: '💰 核心运营指标',
108
+ coreRevenueLabel: '收入',
109
+ coreRevenueValue: '{revenue}',
110
+ coreNewSubscriptionsLabel: '新增订阅',
111
+ coreNewSubscriptionsValue: '{count} 个',
112
+ coreCanceledSubscriptionsLabel: '取消订阅',
113
+ coreCanceledSubscriptionsValue: '{count} 个',
114
+ corePaymentSuccessRateLabel: '支付成功率',
115
+ corePaymentSuccessRateValue: '{rate}%,{succeeded},{failed}',
116
+ paymentSuccessCount: '成功 {count} 笔',
117
+ paymentFailedCount: '失败 {count} 笔',
118
+ viewDataOverview: '数据总览',
119
+ viewSubscriptions: '查看订阅列表',
120
+ viewOverdue: '查看欠费额度',
121
+ },
122
+
91
123
  subscriptionTrialStart: {
92
- title: '欢迎开始您的 {productName} 试用之旅',
93
- body: '恭喜您获得了 {productName} 的试用资格!试用期时长为 {trialDuration},将于 {subscriptionTrialEnd} 结束。祝您使用愉快!',
124
+ title: '{productName} 试用已激活',
125
+ body: '您的 {productName} 试用现已激活。在 {subscriptionTrialEnd} 之前,您可以完全使用所有功能。',
94
126
  },
95
127
 
96
128
  subscriptionTrialWillEnd: {
97
- title: '{productName} 试用期即将结束',
98
- body: '您订阅的 {productName} 试用资格将在 {willRenewDuration} 后结束。请确保您的账户余额充足,以便在试用期结束后自动完成扣费。感谢您的支持与信任!',
129
+ title: '试用期即将结束:{productName}',
130
+ body: '您的 {productName} 试用期将在 {willRenewDuration} 后结束。为确保服务不中断,请检查您的支付详情。',
99
131
  unableToPayBody:
100
- '您订阅的 {productName} 试用资格将在 {willRenewDuration} 后结束。您的当前余额为 {balance},不足 {price},请确保余额充足以便自动完成扣费。感谢您的支持与信任!',
101
- unableToPayReason:
102
- '预计扣款金额为 {price},但当前余额不足(余额为 {balance}),请确保您的账户余额充足,避免扣费失败。',
132
+ '您的试用期将在 {willRenewDuration} 后结束,但您的当前余额({balance})低于续费价格({price})。请充值以确保服务不中断。',
133
+ unableToPayReason: '预计续费金额为 {price},但您的余额仅为 {balance}。请充值以避免扣费失败。',
103
134
  },
104
135
 
105
136
  subscriptionSucceed: {
106
- title: '恭喜!您已成功订阅 {productName}',
107
- body: '感谢您于 {at} 成功订阅了 {productName}。我们将竭诚为您提供优质的服务,祝您使用愉快!',
137
+ title: '{productName} 已准备就绪',
138
+ body: '您的订阅已确认。您现在可以访问 {productName} 或在下方管理您的部署设置。',
108
139
  },
109
140
 
110
141
  oneTimePaymentSucceeded: {
111
- title: '恭喜!您已成功购买 {productName}',
112
- body: '感谢您于 {at} 成功购买了 {productName}。我们将竭诚为您提供优质的服务,祝您使用愉快!',
142
+ title: '购买已确认:{productName}',
143
+ body: '我们已收到您在 {at} {productName} 的付款。您的服务已准备就绪。',
113
144
  },
114
145
 
115
146
  subscriptionUpgraded: {
116
- title: '恭喜!您订阅的 {productName} 套餐已成功变更',
117
- body: '您订阅的 {productName} 套餐已于 {at} 变更成功,感谢您的支持,祝您使用愉快!',
147
+ title: '升级完成:{productName}',
148
+ body: '您的 {productName} 套餐已于 {at} 成功升级。所有新功能现已立即可用。',
118
149
  },
119
150
 
120
151
  subscriptionWillRenew: {
121
- title: '{productName} 自动扣费提醒',
122
- body: '您订阅的 {productName} 将在 {at}({willRenewDuration}后) 发起自动扣费。若有任何疑问或需要帮助,请随时与我们联系。',
152
+ title: '即将续费:{productName}',
153
+ body: '提醒您,{productName} 订阅将在 {at} 续费。如果您想继续运行,无需任何操作。',
123
154
  unableToPayBody:
124
155
  '您订阅的 {productName} 将在 {at}({willRenewDuration}后) 发起自动扣费,若有任何疑问或者需要帮助,请随时与我们联系。',
125
156
  unableToPayReason:
@@ -129,14 +160,14 @@ export default flat({
129
160
  },
130
161
 
131
162
  subscriptionRenewed: {
132
- title: '{productName} 扣费成功',
133
- body: '您的 {productName} 已于 {at} 扣费成功。感谢您的持续支持与信任,祝您使用愉快!',
163
+ title: '扣费成功:{productName}',
164
+ body: '您的 {productName} 续费已于 {at} 处理完成。无需进一步操作。',
134
165
  noExpenseIncurred: '服务期间未产生费用',
135
166
  },
136
167
 
137
168
  subscriptionRenewFailed: {
138
- title: '{productName} 扣费失败',
139
- body: '很抱歉地通知您,您的 {productName} {at} 扣费失败。如有任何疑问,请及时联系我们。谢谢!',
169
+ title: '需要操作:{productName} 扣费失败',
170
+ body: '我们无法处理 {productName} {at} 的续费。为防止您的应用下线,请更新您的支付方式。',
140
171
  reason: {
141
172
  noDidWallet: '您尚未绑定 DID Wallet,请绑定 DID Wallet,确保余额充足。',
142
173
  noDelegation: '您的 DID Wallet 尚未授权,请更新授权。',
@@ -151,8 +182,8 @@ export default flat({
151
182
  },
152
183
  },
153
184
  autoRechargeFailed: {
154
- title: '自动充值扣费失败',
155
- body: '很抱歉地通知您,您的 {creditCurrencyName} 自动充值于 {at} 扣费失败。如有任何疑问,请及时联系我们。谢谢!',
185
+ title: '需要操作:自动充值失败',
186
+ body: '我们无法处理您在 {at} {creditCurrencyName} 的自动充值。请更新您的支付方式以确保服务保持在线。',
156
187
  reason: {
157
188
  noDidWallet: '您尚未绑定 DID Wallet,请绑定 DID Wallet,确保余额充足。',
158
189
  noDelegation: '您的 DID Wallet 尚未授权,请更新授权。',
@@ -167,9 +198,16 @@ export default flat({
167
198
  },
168
199
  },
169
200
 
201
+ autoRechargeDailyLimitExceeded: {
202
+ title: '自动充值已达每日限额',
203
+ body: '您的 {creditCurrencyName} 余额偏低,但由于已达到每日充值限额,自动充值于 {at} 未能触发。您可以手动充值,或等待明天自动充值。',
204
+ dailyLimit: '每日限额',
205
+ dailyUsed: '今日已用',
206
+ },
207
+
170
208
  subscriptionRefundSucceeded: {
171
- title: '{productName} 退款成功',
172
- body: '您订阅的 {productName} {at} 已退款成功,退款金额为 {refundInfo}。如有任何疑问,请随时与我们联系。',
209
+ title: '退款已处理:{productName}',
210
+ body: '{productName} 的退款 {refundInfo} 已于 {at} 处理完成。可能需要几天时间才会显示在您的账户中。',
173
211
  },
174
212
 
175
213
  oneTimePaymentRefundSucceeded: {
@@ -199,13 +237,13 @@ export default flat({
199
237
 
200
238
  customerRevenueSucceeded: {
201
239
  donate: {
202
- title: '您收到了一笔打赏',
203
- body: '恭喜您于 {at} 收到了一笔来自 {user} 的打赏,打赏金额为 {amount}',
240
+ title: '收到新打赏!',
241
+ body: '您于 {at} 收到了来自 {user} {amount} 打赏。干得好!',
204
242
  tipDetail: '查看打赏原文',
205
243
  },
206
244
  payment: {
207
- title: '您收到了一笔付款',
208
- body: '恭喜您于 {at} 收到一笔来自 {user} 的 {amount}',
245
+ title: '收到付款',
246
+ body: '您于 {at} 收到了来自 {user} 的 {amount} 付款。',
209
247
  },
210
248
  sender: '付款方',
211
249
  viewDetail: '查看详情',
@@ -213,10 +251,10 @@ export default flat({
213
251
  },
214
252
 
215
253
  subscriptWillCanceled: {
216
- title: '{productName} 订阅即将取消',
254
+ title: '订阅已取消:{productName}',
255
+ body: '此订阅已被取消,将于 {at} 结束。如果这是个错误,或者您想重新激活,可以在下方操作。',
217
256
  pastDue:
218
257
  '由于长时间未能自动完成扣费,您订阅的 {productName} 将于 {at} ({willCancelDuration}后) 被系统自动取消订阅。请您及时手动处理扣费问题,以免影响使用。如有任何疑问,请随时与我们联系。',
219
- body: '您订阅的 {productName} 将于 {at} ({willCancelDuration}后) 被系统取消订阅,如有疑问,请随时与我们联系。',
220
258
  renewAmount: '扣费金额',
221
259
  cancelReason: '取消原因',
222
260
  adminCanceled: '管理员取消',
@@ -253,10 +291,9 @@ export default flat({
253
291
  },
254
292
 
255
293
  creditInsufficient: {
256
- title: '额度不足,服务可能受限',
294
+ title: '服务风险:额度偏低',
257
295
  bodyWithSubscription:
258
- '您的信用额度仅剩 {availableAmount},不足以支付您订阅的 {subscriptionName}。为避免服务中断,请及时充值。',
259
- bodyWithoutSubscription: '您的信用额度仅剩 {availableAmount},不足以继续使用服务。为避免服务受限,请及时充值。',
296
+ '您的额度({availableAmount})过低,无法维持您的 {subscriptionName} 订阅。请立即充值以确保您的应用保持在线。',
260
297
  exhaustedTitle: '额度已用尽,请尽快充值',
261
298
  exhaustedBodyWithSubscription:
262
299
  '您的信用额度已用尽,无法继续支付您订阅的 {subscriptionName}。为避免服务中断,请及时充值。',
@@ -264,6 +301,7 @@ export default flat({
264
301
  meterEventName: '服务项目',
265
302
  availableCredit: '剩余额度',
266
303
  requiredCredit: '所需额度',
304
+ pendingAmount: '待支付额度',
267
305
  },
268
306
 
269
307
  creditGrantGranted: {
@@ -276,8 +314,8 @@ export default flat({
276
314
  },
277
315
 
278
316
  creditLowBalance: {
279
- title: '您的信用余额偏低',
280
- body: '您的 {currency} 余额已降至临界水平({lowBalancePercentage})。为避免服务中断,请及时充值。',
317
+ title: '低余额警报',
318
+ body: '您的 {currency} 余额已降至 {lowBalancePercentage}。请尽快充值以防止服务中断。',
281
319
  remainingBalance: '剩余余额',
282
320
  status: '状态',
283
321
  lessThanOnePercent: '低于 1%',
@@ -15,6 +15,7 @@ import {
15
15
  TPriceExpanded,
16
16
  } from '../store/models';
17
17
  import logger from '../libs/logger';
18
+ import { createEvent } from '../libs/audit';
18
19
  import { createStripeInvoiceForAutoRecharge } from '../integrations/stripe/resource';
19
20
  import { ensureInvoiceAndItems } from '../libs/invoice';
20
21
  import dayjs from '../libs/dayjs';
@@ -126,6 +127,12 @@ export async function processAutoRecharge(job: AutoRechargeJobData) {
126
127
  customerId,
127
128
  currencyId,
128
129
  });
130
+ // Send notification when daily limit is exceeded
131
+ createEvent('Customer', 'customer.auto_recharge.daily_limit_exceeded', customer, {
132
+ autoRechargeConfigId: config.id,
133
+ currencyId,
134
+ currentBalance: totalAvailable.toString(),
135
+ });
129
136
  return;
130
137
  }
131
138
 
@@ -55,7 +55,9 @@ async function checkLowBalance(
55
55
  const totalCreditAmountBn = new BN(totalCreditAmount);
56
56
  if (totalCreditAmountBn.lte(new BN(0))) return;
57
57
  const remainingAmountBn = new BN(remainingBalance);
58
- const threshold = totalCreditAmountBn.mul(new BN(10)).div(new BN(100));
58
+ // Get threshold percentage from env var, default to 10%
59
+ const thresholdPercentage = parseInt(process.env.CREDIT_LOW_BALANCE_THRESHOLD_PERCENTAGE || '10', 10);
60
+ const threshold = totalCreditAmountBn.mul(new BN(thresholdPercentage)).div(new BN(100));
59
61
  if (remainingAmountBn.gt(new BN(0)) && remainingAmountBn.lte(threshold)) {
60
62
  const percentage = remainingAmountBn.mul(new BN(100)).div(totalCreditAmountBn).toString();
61
63
  await createEvent('Customer', 'customer.credit.low_balance', context.customer, {
@@ -249,6 +251,9 @@ async function consumeAvailableCredits(
249
251
  const pendingAmount = Math.max(0, finalPending.toNumber()).toString();
250
252
  const remainingBalance = totalAvailable.sub(consumed).toString();
251
253
 
254
+ // Track whether insufficient event was triggered to skip low_balance notification
255
+ let insufficientTriggered = false;
256
+
252
257
  // 如果无法完全消费所需额度,记录不足事件
253
258
  if (finalPending.gt(new BN(0))) {
254
259
  logger.warn('Insufficient credit balance', {
@@ -260,6 +265,7 @@ async function consumeAvailableCredits(
260
265
  pendingAmount,
261
266
  });
262
267
  if ((context.subscription && context.subscription.isActive()) || !context.subscription) {
268
+ insufficientTriggered = true;
263
269
  await createEvent('Customer', 'customer.credit.insufficient', context.customer, {
264
270
  metadata: {
265
271
  meter_event_id: context.meterEvent.id,
@@ -297,6 +303,7 @@ async function consumeAvailableCredits(
297
303
  });
298
304
  }
299
305
  } else if (remainingBalance === '0') {
306
+ insufficientTriggered = true;
300
307
  await createEvent('Customer', 'customer.credit.insufficient', context.customer, {
301
308
  metadata: {
302
309
  meter_event_id: context.meterEvent.id,
@@ -312,7 +319,10 @@ async function consumeAvailableCredits(
312
319
  }).catch(console.error);
313
320
  }
314
321
 
315
- await checkLowBalance(customerId, currencyId, totalCreditAmountBN.toString(), remainingBalance, context);
322
+ // Skip low_balance check if insufficient was already triggered (insufficient takes priority)
323
+ if (!insufficientTriggered) {
324
+ await checkLowBalance(customerId, currencyId, totalCreditAmountBN.toString(), remainingBalance, context);
325
+ }
316
326
 
317
327
  return {
318
328
  consumed: totalConsumed.toString(),
@@ -396,16 +406,26 @@ async function createCreditTransaction(
396
406
  fromUnitToToken(consumeAmount, context.meter.paymentCurrency.decimal),
397
407
  context.meter.paymentCurrency.symbol
398
408
  );
409
+
399
410
  let description = `Consume ${formattedAmount}`;
400
411
  const resolvedSubscriptionId =
401
412
  context.meterEvent.getSubscriptionId() || creditGrant.metadata?.subscription_id || context.subscription?.id;
413
+
402
414
  if (resolvedSubscriptionId) {
403
415
  description += ' for Subscription';
404
416
  }
417
+
405
418
  if (context.meterEvent.metadata?.description) {
406
419
  description = context.meterEvent.metadata.description;
407
420
  }
408
421
 
422
+ const hasPendingBalance = new BN(context.meterEvent.credit_pending || '0').gt(new BN(0));
423
+ const hasFailureHistory = !!(context.meterEvent.metadata?.last_error || context.meterEvent.metadata?.failed_at);
424
+ const isRepayment = hasPendingBalance && hasFailureHistory;
425
+ if (isRepayment) {
426
+ description = `Repay ${formattedAmount}`;
427
+ }
428
+
409
429
  try {
410
430
  const transaction = await CreditTransaction.create({
411
431
  customer_id: context.meterEvent.getCustomerId(),
@@ -425,6 +445,7 @@ async function createCreditTransaction(
425
445
  ...(context.meterEvent.metadata || {}),
426
446
  meter_event_id: context.meterEvent.id,
427
447
  grant_depleted: consumeResult.depleted,
448
+ is_repayment: isRepayment,
428
449
  },
429
450
  });
430
451