payment-kit 1.13.161 → 1.13.162
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/.eslintrc.js +2 -1
- package/api/src/libs/api.ts +18 -29
- package/api/src/routes/customers.ts +12 -7
- package/api/src/routes/invoices.ts +17 -6
- package/api/src/routes/payment-intents.ts +19 -7
- package/api/src/routes/products.ts +2 -2
- package/api/src/routes/refunds.ts +53 -3
- package/api/src/routes/subscription-items.ts +18 -9
- package/api/src/routes/subscriptions.ts +20 -31
- package/api/tests/libs/util.spec.ts +0 -26
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/src/components/filter-toolbar.tsx +375 -0
- package/src/components/invoice/list.tsx +17 -46
- package/src/components/payment-intent/list.tsx +17 -41
- package/src/components/payment-link/product-select.tsx +47 -28
- package/src/components/refund/list.tsx +52 -26
- package/src/components/subscription/items/usage-records.tsx +1 -0
- package/src/components/subscription/list.tsx +15 -44
- package/src/components/table.tsx +13 -1
- package/src/global.css +1 -1
- package/src/pages/admin/customers/customers/index.tsx +15 -8
- package/src/pages/admin/payments/links/index.tsx +1 -0
- package/src/pages/admin/products/prices/list.tsx +1 -0
- package/src/pages/admin/products/pricing-tables/index.tsx +1 -0
- package/src/pages/admin/products/products/index.tsx +1 -0
- package/src/pages/customer/index.tsx +1 -13
package/.eslintrc.js
CHANGED
|
@@ -11,6 +11,7 @@ module.exports = {
|
|
|
11
11
|
'@typescript-eslint/no-use-before-define': 'off',
|
|
12
12
|
'@typescript-eslint/lines-between-class-members': 'off',
|
|
13
13
|
'import/prefer-default-export': 'off',
|
|
14
|
-
"react-hooks/exhaustive-deps": "off"
|
|
14
|
+
"react-hooks/exhaustive-deps": "off",
|
|
15
|
+
'jsx-a11y/no-noninteractive-element-interactions': "off"
|
|
15
16
|
},
|
|
16
17
|
};
|
package/api/src/libs/api.ts
CHANGED
|
@@ -71,44 +71,33 @@ export function getWhereFromQuery(query: string) {
|
|
|
71
71
|
return handleCondition(parsed);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
export const getWhereFromKvQuery = (query
|
|
74
|
+
export const getWhereFromKvQuery = (query?: string) => {
|
|
75
|
+
if (!query) {
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
75
78
|
const out: any = {};
|
|
76
79
|
const likes: any = [];
|
|
77
|
-
const
|
|
78
|
-
query.split(' ').forEach((kv: string) => {
|
|
80
|
+
const fn = (kv: string) => {
|
|
79
81
|
const [k, v] = kv.split(':');
|
|
80
|
-
|
|
81
82
|
if (v) {
|
|
82
83
|
let value = decodeURIComponent(v).replace('+', ' ');
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
likes.push(value);
|
|
93
|
-
}
|
|
84
|
+
if (value.includes(',')) {
|
|
85
|
+
value = {
|
|
86
|
+
[Op.in]: v.split(','),
|
|
87
|
+
} as any;
|
|
88
|
+
out[k as string] = value;
|
|
89
|
+
} else if ((k as any).includes('like')) {
|
|
90
|
+
const kk = k?.slice(5);
|
|
91
|
+
value = { [kk as any]: { [Op.like]: `%${v}%` } } as any;
|
|
92
|
+
likes.push(value);
|
|
94
93
|
} else {
|
|
95
94
|
out[k as string] = value;
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
{
|
|
103
|
-
[Op.or]: likes,
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
[Op.or]: subLikes,
|
|
107
|
-
},
|
|
108
|
-
];
|
|
109
|
-
}
|
|
110
|
-
if (likes.length || subLikes.length) {
|
|
111
|
-
out[Op.or] = subLikes.concat(likes);
|
|
97
|
+
};
|
|
98
|
+
query.split(' ').forEach(fn);
|
|
99
|
+
if (likes.length) {
|
|
100
|
+
out[Op.or] = likes;
|
|
112
101
|
}
|
|
113
102
|
return out;
|
|
114
103
|
};
|
|
@@ -2,7 +2,6 @@ import { user } from '@blocklet/sdk/lib/middlewares';
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import pick from 'lodash/pick';
|
|
5
|
-
import type { WhereOptions } from 'sequelize';
|
|
6
5
|
|
|
7
6
|
import { getWhereFromKvQuery, getWhereFromQuery } from '../libs/api';
|
|
8
7
|
import { authenticate } from '../libs/security';
|
|
@@ -26,15 +25,19 @@ const schema = Joi.object<{
|
|
|
26
25
|
pageSize: number;
|
|
27
26
|
did?: string;
|
|
28
27
|
livemode?: boolean;
|
|
28
|
+
q?: string;
|
|
29
|
+
o?: string;
|
|
29
30
|
}>({
|
|
30
31
|
page: Joi.number().integer().min(1).default(1),
|
|
31
32
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
32
33
|
did: Joi.string().empty(''),
|
|
33
34
|
livemode: Joi.boolean().empty(''),
|
|
35
|
+
q: Joi.string().empty(''), // query
|
|
36
|
+
o: Joi.string().empty(''), // order
|
|
34
37
|
});
|
|
35
38
|
router.get('/', auth, async (req, res) => {
|
|
36
39
|
const { page, pageSize, ...query } = await schema.validateAsync(req.query, { stripUnknown: true });
|
|
37
|
-
const where
|
|
40
|
+
const where = getWhereFromKvQuery(query.q);
|
|
38
41
|
|
|
39
42
|
if (typeof query.livemode === 'boolean') {
|
|
40
43
|
where.livemode = query.livemode;
|
|
@@ -46,7 +49,7 @@ router.get('/', auth, async (req, res) => {
|
|
|
46
49
|
try {
|
|
47
50
|
const { rows: list, count } = await Customer.findAndCountAll({
|
|
48
51
|
where,
|
|
49
|
-
order: [['created_at', 'DESC']],
|
|
52
|
+
order: [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']],
|
|
50
53
|
offset: (page - 1) * pageSize,
|
|
51
54
|
limit: pageSize,
|
|
52
55
|
include: [],
|
|
@@ -66,26 +69,28 @@ const searchSchema = Joi.object<{
|
|
|
66
69
|
query: string;
|
|
67
70
|
livemode?: boolean;
|
|
68
71
|
q?: string;
|
|
72
|
+
o?: string;
|
|
69
73
|
}>({
|
|
70
74
|
page: Joi.number().integer().min(1).default(1),
|
|
71
75
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
72
76
|
query: Joi.string(),
|
|
73
77
|
livemode: Joi.boolean().empty(''),
|
|
74
|
-
q: Joi.string(),
|
|
78
|
+
q: Joi.string().empty(''), // query
|
|
79
|
+
o: Joi.string().empty(''), // order
|
|
75
80
|
});
|
|
76
81
|
router.get('/search', auth, async (req, res) => {
|
|
77
|
-
const { page, pageSize, query, livemode, q } = await searchSchema.validateAsync(req.query, {
|
|
82
|
+
const { page, pageSize, query, livemode, q, o } = await searchSchema.validateAsync(req.query, {
|
|
78
83
|
stripUnknown: false,
|
|
79
84
|
allowUnknown: true,
|
|
80
85
|
});
|
|
81
86
|
|
|
82
|
-
const where = q ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
87
|
+
const where = q != null ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
83
88
|
if (typeof livemode === 'boolean') {
|
|
84
89
|
where.livemode = livemode;
|
|
85
90
|
}
|
|
86
91
|
const { rows: list, count } = await Customer.findAndCountAll({
|
|
87
92
|
where,
|
|
88
|
-
order: [['created_at', 'DESC']],
|
|
93
|
+
order: [['created_at', o === 'asc' ? 'ASC' : 'DESC']],
|
|
89
94
|
offset: (page - 1) * pageSize,
|
|
90
95
|
limit: pageSize,
|
|
91
96
|
include: [],
|
|
@@ -2,7 +2,6 @@ import { isValid } from '@arcblock/did';
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import pick from 'lodash/pick';
|
|
5
|
-
import type { WhereOptions } from 'sequelize';
|
|
6
5
|
|
|
7
6
|
import { syncStripeInvoice } from '../integrations/stripe/handlers/invoice';
|
|
8
7
|
import { getWhereFromKvQuery } from '../libs/api';
|
|
@@ -40,6 +39,9 @@ const schema = Joi.object<{
|
|
|
40
39
|
customer_id?: string;
|
|
41
40
|
customer_did?: string;
|
|
42
41
|
subscription_id?: string;
|
|
42
|
+
currency_id?: string;
|
|
43
|
+
q?: string;
|
|
44
|
+
o?: string;
|
|
43
45
|
}>({
|
|
44
46
|
page: Joi.number().integer().min(1).default(1),
|
|
45
47
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
@@ -48,13 +50,16 @@ const schema = Joi.object<{
|
|
|
48
50
|
customer_id: Joi.string().empty(''),
|
|
49
51
|
customer_did: Joi.string().empty(''),
|
|
50
52
|
subscription_id: Joi.string().empty(''),
|
|
53
|
+
currency_id: Joi.string().empty(''),
|
|
54
|
+
q: Joi.string().empty(''), // query
|
|
55
|
+
o: Joi.string().empty(''), // order
|
|
51
56
|
});
|
|
52
57
|
router.get('/', authMine, async (req, res) => {
|
|
53
58
|
const { page, pageSize, livemode, status, ...query } = await schema.validateAsync(req.query, {
|
|
54
59
|
stripUnknown: false,
|
|
55
60
|
allowUnknown: true,
|
|
56
61
|
});
|
|
57
|
-
const where
|
|
62
|
+
const where = getWhereFromKvQuery(query.q);
|
|
58
63
|
|
|
59
64
|
if (status) {
|
|
60
65
|
where.status = status
|
|
@@ -65,6 +70,9 @@ router.get('/', authMine, async (req, res) => {
|
|
|
65
70
|
if (query.customer_id) {
|
|
66
71
|
where.customer_id = query.customer_id;
|
|
67
72
|
}
|
|
73
|
+
if (query.currency_id) {
|
|
74
|
+
where.currency_id = query.currency_id;
|
|
75
|
+
}
|
|
68
76
|
if (query.customer_did && isValid(query.customer_did)) {
|
|
69
77
|
const customer = await Customer.findOne({ where: { did: query.customer_did } });
|
|
70
78
|
if (customer) {
|
|
@@ -91,7 +99,7 @@ router.get('/', authMine, async (req, res) => {
|
|
|
91
99
|
try {
|
|
92
100
|
const { rows: list, count } = await Invoice.findAndCountAll({
|
|
93
101
|
where,
|
|
94
|
-
order: [['created_at', 'DESC']],
|
|
102
|
+
order: [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']],
|
|
95
103
|
offset: (page - 1) * pageSize,
|
|
96
104
|
limit: pageSize,
|
|
97
105
|
include: [
|
|
@@ -115,14 +123,16 @@ const searchSchema = Joi.object<{
|
|
|
115
123
|
pageSize: number;
|
|
116
124
|
livemode?: boolean;
|
|
117
125
|
q: string;
|
|
126
|
+
o?: string;
|
|
118
127
|
}>({
|
|
119
128
|
page: Joi.number().integer().min(1).default(1),
|
|
120
129
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
121
130
|
livemode: Joi.boolean().empty(''),
|
|
122
|
-
q: Joi.string(),
|
|
131
|
+
q: Joi.string().empty(''), // query
|
|
132
|
+
o: Joi.string().empty(''), // order
|
|
123
133
|
});
|
|
124
134
|
router.get('/search', authMine, async (req, res) => {
|
|
125
|
-
const { page, pageSize, livemode, q } = await searchSchema.validateAsync(req.query, {
|
|
135
|
+
const { page, pageSize, livemode, q, o } = await searchSchema.validateAsync(req.query, {
|
|
126
136
|
stripUnknown: false,
|
|
127
137
|
allowUnknown: true,
|
|
128
138
|
});
|
|
@@ -134,9 +144,10 @@ router.get('/search', authMine, async (req, res) => {
|
|
|
134
144
|
|
|
135
145
|
const { rows: list, count } = await Invoice.findAndCountAll({
|
|
136
146
|
where,
|
|
137
|
-
order: [['created_at', 'DESC']],
|
|
147
|
+
order: [['created_at', o === 'asc' ? 'ASC' : 'DESC']],
|
|
138
148
|
offset: (page - 1) * pageSize,
|
|
139
149
|
limit: pageSize,
|
|
150
|
+
distinct: true,
|
|
140
151
|
include: [
|
|
141
152
|
{ model: PaymentCurrency, as: 'paymentCurrency' },
|
|
142
153
|
{ model: Customer, as: 'customer' },
|
|
@@ -2,7 +2,6 @@ import { isValid } from '@arcblock/did';
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import pick from 'lodash/pick';
|
|
5
|
-
import type { WhereOptions } from 'sequelize';
|
|
6
5
|
|
|
7
6
|
import { syncStripPayment } from '../integrations/stripe/handlers/payment-intent';
|
|
8
7
|
import { getWhereFromKvQuery, getWhereFromQuery } from '../libs/api';
|
|
@@ -38,6 +37,9 @@ const paginationSchema = Joi.object<{
|
|
|
38
37
|
invoice_id?: string;
|
|
39
38
|
customer_id?: string;
|
|
40
39
|
customer_did?: string;
|
|
40
|
+
currency_id?: string;
|
|
41
|
+
q?: string;
|
|
42
|
+
o?: string;
|
|
41
43
|
}>({
|
|
42
44
|
page: Joi.number().integer().min(1).default(1),
|
|
43
45
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
@@ -46,13 +48,16 @@ const paginationSchema = Joi.object<{
|
|
|
46
48
|
invoice_id: Joi.string().empty(''),
|
|
47
49
|
customer_id: Joi.string().empty(''),
|
|
48
50
|
customer_did: Joi.string().empty(''),
|
|
51
|
+
currency_id: Joi.string().empty(''),
|
|
52
|
+
q: Joi.string().empty(''), // query
|
|
53
|
+
o: Joi.string().empty(''), // order
|
|
49
54
|
});
|
|
50
55
|
router.get('/', authMine, async (req, res) => {
|
|
51
56
|
const { page, pageSize, status, livemode, ...query } = await paginationSchema.validateAsync(req.query, {
|
|
52
57
|
stripUnknown: false,
|
|
53
58
|
allowUnknown: true,
|
|
54
59
|
});
|
|
55
|
-
const where
|
|
60
|
+
const where = getWhereFromKvQuery(query.q);
|
|
56
61
|
|
|
57
62
|
if (status) {
|
|
58
63
|
where.status = status
|
|
@@ -75,6 +80,11 @@ router.get('/', authMine, async (req, res) => {
|
|
|
75
80
|
if (query.invoice_id) {
|
|
76
81
|
where.invoice_id = query.invoice_id;
|
|
77
82
|
}
|
|
83
|
+
|
|
84
|
+
if (query.currency_id) {
|
|
85
|
+
where.currency_id = query.currency_id;
|
|
86
|
+
}
|
|
87
|
+
|
|
78
88
|
if (typeof livemode === 'boolean') {
|
|
79
89
|
where.livemode = livemode;
|
|
80
90
|
}
|
|
@@ -89,7 +99,7 @@ router.get('/', authMine, async (req, res) => {
|
|
|
89
99
|
try {
|
|
90
100
|
const { rows: list, count } = await PaymentIntent.findAndCountAll({
|
|
91
101
|
where,
|
|
92
|
-
order: [['created_at', 'DESC']],
|
|
102
|
+
order: [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']],
|
|
93
103
|
offset: (page - 1) * pageSize,
|
|
94
104
|
limit: pageSize,
|
|
95
105
|
include: [
|
|
@@ -113,27 +123,29 @@ const searchSchema = Joi.object<{
|
|
|
113
123
|
query: string;
|
|
114
124
|
livemode?: boolean;
|
|
115
125
|
q?: string;
|
|
126
|
+
o?: string;
|
|
116
127
|
}>({
|
|
117
128
|
page: Joi.number().integer().min(1).default(1),
|
|
118
129
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
119
130
|
query: Joi.string(),
|
|
120
131
|
livemode: Joi.boolean().empty(''),
|
|
121
|
-
q: Joi.string(),
|
|
132
|
+
q: Joi.string().empty(''), // query
|
|
133
|
+
o: Joi.string().empty(''), // order
|
|
122
134
|
});
|
|
123
135
|
router.get('/search', authMine, async (req, res) => {
|
|
124
|
-
const { page, pageSize, query, livemode, q } = await searchSchema.validateAsync(req.query, {
|
|
136
|
+
const { page, pageSize, query, livemode, q, o } = await searchSchema.validateAsync(req.query, {
|
|
125
137
|
stripUnknown: false,
|
|
126
138
|
allowUnknown: true,
|
|
127
139
|
});
|
|
128
140
|
|
|
129
|
-
const where = q ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
141
|
+
const where = q != null ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
130
142
|
if (typeof livemode === 'boolean') {
|
|
131
143
|
where.livemode = livemode;
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
const { rows: list, count } = await PaymentIntent.findAndCountAll({
|
|
135
147
|
where,
|
|
136
|
-
order: [['created_at', 'DESC']],
|
|
148
|
+
order: [['created_at', o === 'asc' ? 'ASC' : 'DESC']],
|
|
137
149
|
offset: (page - 1) * pageSize,
|
|
138
150
|
limit: pageSize,
|
|
139
151
|
include: [
|
|
@@ -173,7 +173,7 @@ const searchSchema = Joi.object<{
|
|
|
173
173
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
174
174
|
query: Joi.string(),
|
|
175
175
|
livemode: Joi.boolean().empty(''),
|
|
176
|
-
q: Joi.string(),
|
|
176
|
+
q: Joi.string().empty(''), // query
|
|
177
177
|
});
|
|
178
178
|
router.get('/search', auth, async (req, res) => {
|
|
179
179
|
const { page, pageSize, query, livemode, q } = await searchSchema.validateAsync(req.query, {
|
|
@@ -181,7 +181,7 @@ router.get('/search', auth, async (req, res) => {
|
|
|
181
181
|
allowUnknown: true,
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
const where = q ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
184
|
+
const where = q != null ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
185
185
|
if (typeof livemode === 'boolean') {
|
|
186
186
|
where.livemode = livemode;
|
|
187
187
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { Router } from 'express';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
import pick from 'lodash/pick';
|
|
5
|
-
import type { WhereOptions } from 'sequelize';
|
|
6
5
|
|
|
6
|
+
import { getWhereFromKvQuery } from '../libs/api';
|
|
7
7
|
import { authenticate } from '../libs/security';
|
|
8
8
|
import { formatMetadata } from '../libs/util';
|
|
9
9
|
import {
|
|
@@ -36,22 +36,28 @@ const paginationSchema = Joi.object<{
|
|
|
36
36
|
status?: string;
|
|
37
37
|
invoice_id: string;
|
|
38
38
|
subscription_id: string;
|
|
39
|
+
currency_id: string;
|
|
39
40
|
customer_id: string;
|
|
41
|
+
q?: string;
|
|
42
|
+
o?: string;
|
|
40
43
|
}>({
|
|
41
44
|
page: Joi.number().integer().min(1).default(1),
|
|
42
45
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
43
46
|
livemode: Joi.boolean().empty(''),
|
|
44
47
|
status: Joi.string().empty(''),
|
|
45
48
|
invoice_id: Joi.string().empty(''),
|
|
49
|
+
currency_id: Joi.string().empty(''),
|
|
46
50
|
subscription_id: Joi.string().empty(''),
|
|
47
51
|
customer_id: Joi.string().empty(''),
|
|
52
|
+
q: Joi.string().empty(''), // query
|
|
53
|
+
o: Joi.string().empty(''), // order
|
|
48
54
|
});
|
|
49
55
|
router.get('/', auth, async (req, res) => {
|
|
50
56
|
const { page, pageSize, livemode, status, ...query } = await paginationSchema.validateAsync(req.query, {
|
|
51
57
|
stripUnknown: false,
|
|
52
58
|
allowUnknown: true,
|
|
53
59
|
});
|
|
54
|
-
const where
|
|
60
|
+
const where = getWhereFromKvQuery(query.q);
|
|
55
61
|
|
|
56
62
|
if (typeof livemode === 'boolean') {
|
|
57
63
|
where.livemode = livemode;
|
|
@@ -61,6 +67,10 @@ router.get('/', auth, async (req, res) => {
|
|
|
61
67
|
where.invoice_id = query.invoice_id;
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
if (query.currency_id) {
|
|
71
|
+
where.currency_id = query.currency_id;
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
if (query.customer_id) {
|
|
65
75
|
where.customer_id = query.customer_id;
|
|
66
76
|
}
|
|
@@ -68,6 +78,7 @@ router.get('/', auth, async (req, res) => {
|
|
|
68
78
|
if (query.subscription_id) {
|
|
69
79
|
where.subscription_id = query.subscription_id;
|
|
70
80
|
}
|
|
81
|
+
|
|
71
82
|
if (status) {
|
|
72
83
|
where.status = status
|
|
73
84
|
.split(',')
|
|
@@ -84,7 +95,7 @@ router.get('/', auth, async (req, res) => {
|
|
|
84
95
|
|
|
85
96
|
const { rows: list, count } = await Refund.findAndCountAll({
|
|
86
97
|
where,
|
|
87
|
-
order: [['created_at', 'DESC']],
|
|
98
|
+
order: [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']],
|
|
88
99
|
offset: (page - 1) * pageSize,
|
|
89
100
|
limit: pageSize,
|
|
90
101
|
include: [
|
|
@@ -101,6 +112,45 @@ router.get('/', auth, async (req, res) => {
|
|
|
101
112
|
res.json({ count, list });
|
|
102
113
|
});
|
|
103
114
|
|
|
115
|
+
const searchSchema = Joi.object<{
|
|
116
|
+
page: number;
|
|
117
|
+
pageSize: number;
|
|
118
|
+
livemode?: boolean;
|
|
119
|
+
q: string;
|
|
120
|
+
o?: string;
|
|
121
|
+
}>({
|
|
122
|
+
page: Joi.number().integer().min(1).default(1),
|
|
123
|
+
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
124
|
+
livemode: Joi.boolean().empty(''),
|
|
125
|
+
q: Joi.string().empty(''), // query
|
|
126
|
+
o: Joi.string().empty(''), // order
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
router.get('/search', auth, async (req, res) => {
|
|
130
|
+
const { page, pageSize, livemode, q, o } = await searchSchema.validateAsync(req.query, {
|
|
131
|
+
stripUnknown: false,
|
|
132
|
+
allowUnknown: true,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const where = getWhereFromKvQuery(q);
|
|
136
|
+
if (typeof livemode === 'boolean') {
|
|
137
|
+
where.livemode = livemode;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const { rows: list, count } = await Refund.findAndCountAll({
|
|
141
|
+
where,
|
|
142
|
+
order: [['created_at', o === 'asc' ? 'ASC' : 'DESC']],
|
|
143
|
+
offset: (page - 1) * pageSize,
|
|
144
|
+
limit: pageSize,
|
|
145
|
+
include: [
|
|
146
|
+
{ model: PaymentCurrency, as: 'paymentCurrency' },
|
|
147
|
+
{ model: Customer, as: 'customer' },
|
|
148
|
+
],
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
res.json({ count, list });
|
|
152
|
+
});
|
|
153
|
+
|
|
104
154
|
router.get('/:id', auth, async (req, res) => {
|
|
105
155
|
const doc = await Refund.findByPk(req.params.id as string, {
|
|
106
156
|
include: [
|
|
@@ -42,16 +42,26 @@ const schema = Joi.object<{
|
|
|
42
42
|
page: number;
|
|
43
43
|
pageSize: number;
|
|
44
44
|
subscription_id: string;
|
|
45
|
+
price_id: string;
|
|
45
46
|
livemode?: boolean;
|
|
46
47
|
}>({
|
|
47
48
|
page: Joi.number().integer().min(1).default(1),
|
|
48
49
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
49
|
-
subscription_id: Joi.string()
|
|
50
|
+
subscription_id: Joi.string(),
|
|
51
|
+
price_id: Joi.string(),
|
|
50
52
|
livemode: Joi.boolean().empty(''),
|
|
51
53
|
});
|
|
52
54
|
router.get('/', auth, async (req, res) => {
|
|
53
55
|
const { page, pageSize, ...query } = await schema.validateAsync(req.query, { stripUnknown: true });
|
|
54
|
-
const where: WhereOptions<SubscriptionItem> = {
|
|
56
|
+
const where: WhereOptions<SubscriptionItem> = {};
|
|
57
|
+
|
|
58
|
+
if (query.subscription_id) {
|
|
59
|
+
where.subscription_id = query.subscription_id;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (query.price_id) {
|
|
63
|
+
where.price_id = query.price_id;
|
|
64
|
+
}
|
|
55
65
|
|
|
56
66
|
if (typeof query.livemode === 'boolean') {
|
|
57
67
|
where.livemode = query.livemode;
|
|
@@ -65,14 +75,13 @@ router.get('/', auth, async (req, res) => {
|
|
|
65
75
|
limit: pageSize,
|
|
66
76
|
include: [],
|
|
67
77
|
});
|
|
68
|
-
|
|
69
78
|
const list = rows.map((x) => x.toJSON());
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
if (where.subscription_id) {
|
|
80
|
+
const products = (await Product.findAll()).map((x) => x.toJSON());
|
|
81
|
+
const prices = (await Price.findAll()).map((x) => x.toJSON());
|
|
82
|
+
// @ts-ignore
|
|
83
|
+
expandLineItems(list, products, prices);
|
|
84
|
+
}
|
|
76
85
|
res.json({ count, list });
|
|
77
86
|
} catch (err) {
|
|
78
87
|
console.error(err);
|
|
@@ -4,7 +4,6 @@ import { Router } from 'express';
|
|
|
4
4
|
import Joi from 'joi';
|
|
5
5
|
import pick from 'lodash/pick';
|
|
6
6
|
import uniq from 'lodash/uniq';
|
|
7
|
-
import type { WhereOptions } from 'sequelize';
|
|
8
7
|
|
|
9
8
|
import { ensureStripeSubscription } from '../integrations/stripe/resource';
|
|
10
9
|
import { getWhereFromKvQuery, getWhereFromQuery } from '../libs/api';
|
|
@@ -66,6 +65,8 @@ const schema = Joi.object<{
|
|
|
66
65
|
customer_id?: string;
|
|
67
66
|
customer_did?: string;
|
|
68
67
|
livemode?: boolean;
|
|
68
|
+
q?: string;
|
|
69
|
+
o?: string;
|
|
69
70
|
}>({
|
|
70
71
|
page: Joi.number().integer().min(1).default(1),
|
|
71
72
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
@@ -73,13 +74,15 @@ const schema = Joi.object<{
|
|
|
73
74
|
customer_id: Joi.string().empty(''),
|
|
74
75
|
customer_did: Joi.string().empty(''),
|
|
75
76
|
livemode: Joi.boolean().empty(''),
|
|
77
|
+
q: Joi.string().empty(''), // query
|
|
78
|
+
o: Joi.string().empty(''), // order
|
|
76
79
|
});
|
|
77
80
|
router.get('/', authMine, async (req, res) => {
|
|
78
81
|
const { page, pageSize, status, livemode, ...query } = await schema.validateAsync(req.query, {
|
|
79
82
|
stripUnknown: false,
|
|
80
83
|
allowUnknown: true,
|
|
81
84
|
});
|
|
82
|
-
const where
|
|
85
|
+
const where = getWhereFromKvQuery(query.q);
|
|
83
86
|
|
|
84
87
|
if (status) {
|
|
85
88
|
where.status = status
|
|
@@ -113,7 +116,7 @@ router.get('/', authMine, async (req, res) => {
|
|
|
113
116
|
try {
|
|
114
117
|
const { rows: list, count } = await Subscription.findAndCountAll({
|
|
115
118
|
where,
|
|
116
|
-
order: [['created_at', 'DESC']],
|
|
119
|
+
order: [['created_at', query.o === 'asc' ? 'ASC' : 'DESC']],
|
|
117
120
|
offset: (page - 1) * pageSize,
|
|
118
121
|
limit: pageSize,
|
|
119
122
|
include: [
|
|
@@ -146,27 +149,29 @@ const searchSchema = Joi.object<{
|
|
|
146
149
|
query: string;
|
|
147
150
|
livemode?: boolean;
|
|
148
151
|
q?: string;
|
|
152
|
+
o?: string;
|
|
149
153
|
}>({
|
|
150
154
|
page: Joi.number().integer().min(1).default(1),
|
|
151
155
|
pageSize: Joi.number().integer().min(1).max(100).default(20),
|
|
152
156
|
query: Joi.string(),
|
|
153
157
|
livemode: Joi.boolean().empty(''),
|
|
154
|
-
q: Joi.string(),
|
|
158
|
+
q: Joi.string().empty(''), // query
|
|
159
|
+
o: Joi.string().empty(''), // order
|
|
155
160
|
});
|
|
156
161
|
router.get('/search', auth, async (req, res) => {
|
|
157
|
-
const { page, pageSize, query, livemode, q } = await searchSchema.validateAsync(req.query, {
|
|
162
|
+
const { page, pageSize, query, livemode, q, o } = await searchSchema.validateAsync(req.query, {
|
|
158
163
|
stripUnknown: false,
|
|
159
164
|
allowUnknown: true,
|
|
160
165
|
});
|
|
161
166
|
|
|
162
|
-
const where = q ? getWhereFromKvQuery(q
|
|
167
|
+
const where = q != null ? getWhereFromKvQuery(q) : getWhereFromQuery(query);
|
|
163
168
|
if (typeof livemode === 'boolean') {
|
|
164
169
|
where.livemode = livemode;
|
|
165
170
|
}
|
|
166
171
|
// fix here https://github.com/blocklet/payment-kit/issues/394
|
|
167
|
-
const { rows:
|
|
168
|
-
where
|
|
169
|
-
order: [['created_at', 'DESC']],
|
|
172
|
+
const { rows: list, count } = await Subscription.findAndCountAll({
|
|
173
|
+
where,
|
|
174
|
+
order: [['created_at', o === 'asc' ? 'ASC' : 'DESC']],
|
|
170
175
|
offset: (page - 1) * pageSize,
|
|
171
176
|
limit: pageSize,
|
|
172
177
|
distinct: true,
|
|
@@ -178,28 +183,12 @@ router.get('/search', auth, async (req, res) => {
|
|
|
178
183
|
],
|
|
179
184
|
});
|
|
180
185
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
offset: (page - 1) * pageSize,
|
|
188
|
-
limit: pageSize,
|
|
189
|
-
distinct: true,
|
|
190
|
-
include: [
|
|
191
|
-
{ model: Customer, as: 'customer', where: where[1] },
|
|
192
|
-
{ model: PaymentCurrency, as: 'paymentCurrency' },
|
|
193
|
-
{ model: PaymentMethod, as: 'paymentMethod' },
|
|
194
|
-
{ model: SubscriptionItem, as: 'items' },
|
|
195
|
-
],
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
count = count1 + count2;
|
|
199
|
-
list = list1.concat(list2 || []);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
res.json({ count, list });
|
|
186
|
+
const products = (await Product.findAll()).map((x) => x.toJSON());
|
|
187
|
+
const prices = (await Price.findAll()).map((x) => x.toJSON());
|
|
188
|
+
const docs = list.map((x) => x.toJSON());
|
|
189
|
+
// @ts-ignore
|
|
190
|
+
docs.forEach((x) => expandLineItems(x.items, products, prices));
|
|
191
|
+
res.json({ count, list: docs });
|
|
203
192
|
});
|
|
204
193
|
|
|
205
194
|
// FIXME: exclude some sensitive fields from PaymentMethod
|
|
@@ -206,30 +206,4 @@ describe('getWhereFromKvQuery', () => {
|
|
|
206
206
|
});
|
|
207
207
|
});
|
|
208
208
|
|
|
209
|
-
it('should return a customer likes object when the q string with like', () => {
|
|
210
|
-
const q = 'like-did:123 like-number:1533';
|
|
211
|
-
const result = getWhereFromKvQuery(q);
|
|
212
|
-
expect(result).toEqual({
|
|
213
|
-
[Op.or]: [
|
|
214
|
-
{ '$customer.did$': { [Op.like]: `%123%` } },
|
|
215
|
-
{ number: { [Op.like]: `%1533%` } }
|
|
216
|
-
],
|
|
217
|
-
});
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
it('should return a customer likes object when the subWhere is true', () => {
|
|
221
|
-
const q = 'like-did:123 like-number:1533';
|
|
222
|
-
const result = getWhereFromKvQuery(q, true);
|
|
223
|
-
expect(result).toEqual([
|
|
224
|
-
{
|
|
225
|
-
[Op.or]: [
|
|
226
|
-
{ number: { [Op.like]: `%1533%` } }
|
|
227
|
-
],
|
|
228
|
-
}, {
|
|
229
|
-
[Op.or]: [
|
|
230
|
-
{ did: { [Op.like]: `%123%` } }
|
|
231
|
-
],
|
|
232
|
-
}
|
|
233
|
-
]);
|
|
234
|
-
});
|
|
235
209
|
});
|