payment-kit 1.22.13 → 1.22.15

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.
@@ -162,7 +162,9 @@ export class SubscriptionCanceledEmailTemplate extends BaseSubscriptionEmailTemp
162
162
  ];
163
163
 
164
164
  const matchedCondition = conditions.find((item) => item.condition);
165
- return matchedCondition ? translate(matchedCondition.key, locale) : '';
165
+ return matchedCondition
166
+ ? translate(matchedCondition.key, locale)
167
+ : translate('notification.subscriptionCanceled.adminCanceled', locale);
166
168
  }
167
169
 
168
170
  async getTemplate(): Promise<BaseEmailTemplateType> {
@@ -36,6 +36,12 @@ async function handleReturnProcessorJob(job: ReturnProcessorJob): Promise<void>
36
36
  }
37
37
 
38
38
  const vendorInfoList = checkoutSession.vendor_info as VendorInfo[];
39
+
40
+ if (!vendorInfoList || vendorInfoList.length === 0) {
41
+ logger.warn('No vendor info found', { checkoutSessionId });
42
+ return;
43
+ }
44
+
39
45
  let hasChanges = false;
40
46
 
41
47
  let i = -1;
@@ -68,6 +68,7 @@ async function findSessionsNeedingVendorReturn(): Promise<CheckoutSession[]> {
68
68
  where: {
69
69
  fulfillment_status: { [Op.notIn]: ['returning', 'returned', 'failed'] },
70
70
  subscription_id: { [Op.in]: canceledSubscriptionIds },
71
+ vendor_info: { [Op.not]: null as any },
71
72
  },
72
73
  order: [['updated_at', 'DESC']],
73
74
  limit: 100,
@@ -136,9 +137,12 @@ events.on('customer.subscription.deleted', async (subscription: Subscription) =>
136
137
 
137
138
  const session = await CheckoutSession.findOne({
138
139
  where: { subscription_id: subscription.id },
140
+ attributes: ['id', 'vendor_info'],
139
141
  });
140
142
 
141
- if (session) {
143
+ const isVendor = session?.vendor_info && session.vendor_info.length > 0;
144
+
145
+ if (session && isVendor) {
142
146
  const id = `vendor-return-process-${session.id}`;
143
147
  // eslint-disable-next-line no-await-in-loop
144
148
  const exists = await vendorReturnProcessorQueue.get(id);
@@ -2,9 +2,12 @@ import dayjs from 'dayjs';
2
2
  import { Router } from 'express';
3
3
  import Joi from 'joi';
4
4
 
5
+ import { getUrl } from '@blocklet/sdk';
6
+ import { joinURL } from 'ufo';
5
7
  import { authenticate } from '../libs/security';
6
8
  import { formatToShortUrl } from '../libs/url';
7
9
  import { CheckoutSession } from '../store/models';
10
+ import logger from '../libs/logger';
8
11
 
9
12
  const loginAuth = authenticate<CheckoutSession>({ component: false, ensureLogin: true, mine: true });
10
13
 
@@ -14,7 +17,7 @@ const shortUrlSchema = Joi.object({
14
17
  url: Joi.string().uri().required(),
15
18
  timeoutMin: Joi.number().optional(),
16
19
  maxVisits: Joi.number().optional(),
17
- });
20
+ }).unknown(true);
18
21
 
19
22
  router.get('/short-url', loginAuth, async (req, res) => {
20
23
  const { error } = shortUrlSchema.validate(req.query);
@@ -32,4 +35,31 @@ router.get('/short-url', loginAuth, async (req, res) => {
32
35
  return res.json({ url: shortUrl });
33
36
  });
34
37
 
38
+ router.get('/short-connect-url', async (req, res) => {
39
+ const { error } = shortUrlSchema.validate(req.query);
40
+ if (error) {
41
+ return res.status(400).json({ error: 'Invalid parameters', message: error.message });
42
+ }
43
+
44
+ const { url, timeoutMin = 60, maxVisits = 5 } = req.query;
45
+ const serverUrl = getUrl();
46
+
47
+ const allowedEndpoint = joinURL(new URL(serverUrl).origin, '.well-known/service/gen-simple-access-key');
48
+
49
+ if (!url?.toString().startsWith(allowedEndpoint)) {
50
+ logger.error('Client try to generate short connect url from invalid service', { url });
51
+ return res
52
+ .status(400)
53
+ .json({ error: 'Just support generate short connect url from gen-simple-access-key service' });
54
+ }
55
+
56
+ const timeoutMinNumber = Number(timeoutMin);
57
+ const validUntil = dayjs()
58
+ .add(timeoutMinNumber > 60 ? 60 : timeoutMinNumber, 'minutes')
59
+ .format('YYYY-MM-DDTHH:mm:ss+00:00');
60
+
61
+ const shortUrl = await formatToShortUrl({ url: url as string, validUntil, maxVisits: Number(maxVisits) });
62
+ return res.json({ url: shortUrl });
63
+ });
64
+
35
65
  export default router;
package/blocklet.yml CHANGED
@@ -14,7 +14,7 @@ repository:
14
14
  type: git
15
15
  url: git+https://github.com/blocklet/payment-kit.git
16
16
  specVersion: 1.2.8
17
- version: 1.22.13
17
+ version: 1.22.15
18
18
  logo: logo.png
19
19
  files:
20
20
  - dist
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payment-kit",
3
- "version": "1.22.13",
3
+ "version": "1.22.15",
4
4
  "scripts": {
5
5
  "dev": "blocklet dev --open",
6
6
  "lint": "tsc --noEmit && eslint src api/src --ext .mjs,.js,.jsx,.ts,.tsx",
@@ -57,9 +57,9 @@
57
57
  "@blocklet/error": "^0.3.2",
58
58
  "@blocklet/js-sdk": "^1.17.2",
59
59
  "@blocklet/logger": "^1.17.2",
60
- "@blocklet/payment-broker-client": "1.22.13",
61
- "@blocklet/payment-react": "1.22.13",
62
- "@blocklet/payment-vendor": "1.22.13",
60
+ "@blocklet/payment-broker-client": "1.22.15",
61
+ "@blocklet/payment-react": "1.22.15",
62
+ "@blocklet/payment-vendor": "1.22.15",
63
63
  "@blocklet/sdk": "^1.17.2",
64
64
  "@blocklet/ui-react": "^3.2.6",
65
65
  "@blocklet/uploader": "^0.3.11",
@@ -129,7 +129,7 @@
129
129
  "devDependencies": {
130
130
  "@abtnode/types": "^1.17.2",
131
131
  "@arcblock/eslint-config-ts": "^0.3.3",
132
- "@blocklet/payment-types": "1.22.13",
132
+ "@blocklet/payment-types": "1.22.15",
133
133
  "@types/cookie-parser": "^1.4.9",
134
134
  "@types/cors": "^2.8.19",
135
135
  "@types/debug": "^4.1.12",
@@ -176,5 +176,5 @@
176
176
  "parser": "typescript"
177
177
  }
178
178
  },
179
- "gitHead": "20ea282ac9d84c8d5a0e9549484462a6d46aebd3"
179
+ "gitHead": "4d8543567eb8958c55a8cf06d9031f3f64c57e27"
180
180
  }
@@ -55,7 +55,13 @@ export default function SubscriptionCancelForm({ data }: { data: TSubscriptionEx
55
55
  const { decimal, symbol } = data.paymentCurrency;
56
56
 
57
57
  return (
58
- <Root sx={{ width: 400 }}>
58
+ <Root
59
+ sx={{
60
+ width: {
61
+ xs: '100%',
62
+ sm: 450,
63
+ },
64
+ }}>
59
65
  <Stack
60
66
  direction="row"
61
67
  spacing={3}
@@ -230,6 +236,42 @@ export default function SubscriptionCancelForm({ data }: { data: TSubscriptionEx
230
236
  )}
231
237
  </>
232
238
  )}
239
+ <Divider sx={{ my: 1 }} />
240
+ <Stack
241
+ direction="row"
242
+ spacing={3}
243
+ sx={{
244
+ alignItems: 'flex-start',
245
+ }}>
246
+ <Typography className="form-title">{t('admin.subscription.cancel.comment.title')}</Typography>
247
+ <Controller
248
+ name="cancel.comment"
249
+ control={control}
250
+ rules={{
251
+ required: t('common.required'),
252
+ validate: (value) => value.trim() !== '' || t('common.required'),
253
+ }}
254
+ render={({ field }) => (
255
+ <TextField
256
+ {...field}
257
+ variant="outlined"
258
+ size="small"
259
+ fullWidth
260
+ multiline
261
+ minRows={2}
262
+ maxRows={4}
263
+ placeholder={t('admin.subscription.cancel.comment.placeholder')}
264
+ error={!!(formState.errors as any)?.cancel?.comment}
265
+ helperText={(formState.errors as any)?.cancel?.comment?.message}
266
+ slotProps={{
267
+ htmlInput: {
268
+ maxLength: 200,
269
+ },
270
+ }}
271
+ />
272
+ )}
273
+ />
274
+ </Stack>
233
275
  </Root>
234
276
  );
235
277
  }
@@ -209,6 +209,7 @@ export default function SubscriptionActions(rawProps: Props) {
209
209
  refund: 'none',
210
210
  staking: 'none',
211
211
  slashReason: '',
212
+ comment: '',
212
213
  },
213
214
  pause: {
214
215
  type: 'never',
@@ -1386,6 +1386,10 @@ export default flat({
1386
1386
  'The remaining stake of this subscription {unused}{symbol} will be slashed, please confirm to continue?',
1387
1387
  slashTitle: 'Slash stake',
1388
1388
  },
1389
+ comment: {
1390
+ title: 'Reason',
1391
+ placeholder: 'Please provide the reason for cancellation',
1392
+ },
1389
1393
  },
1390
1394
  pause: {
1391
1395
  title: 'Pause payment collection',
@@ -1352,6 +1352,10 @@ export default flat({
1352
1352
  slashTip: '该订阅剩余的质押部分 {unused}{symbol} 将被罚没, 请确认是否继续?',
1353
1353
  slashTitle: '罚没质押',
1354
1354
  },
1355
+ comment: {
1356
+ title: '原因',
1357
+ placeholder: '请填写取消订阅的原因',
1358
+ },
1355
1359
  },
1356
1360
  pause: {
1357
1361
  title: '暂停付款',