payment-kit 1.13.142 → 1.13.144
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/integrations/stripe/handlers/invoice.ts +3 -0
- package/api/src/libs/api.ts +7 -2
- package/api/src/queues/checkout-session.ts +11 -0
- package/api/tests/libs/util.spec.ts +13 -2
- package/blocklet.yml +1 -1
- package/package.json +4 -4
- package/src/components/invoice/list.tsx +7 -4
- package/src/components/payment-intent/list.tsx +8 -6
- package/src/components/subscription/list.tsx +8 -4
- package/src/libs/util.ts +12 -0
- package/src/pages/admin/customers/customers/index.tsx +6 -1
|
@@ -133,6 +133,9 @@ export async function ensureStripeInvoice(stripeInvoice: any, subscription: Subs
|
|
|
133
133
|
stripe_id: stripeInvoice.id,
|
|
134
134
|
},
|
|
135
135
|
});
|
|
136
|
+
if (checkoutSession) {
|
|
137
|
+
await checkoutSession.update({ invoice_id: invoice.id });
|
|
138
|
+
}
|
|
136
139
|
await client.invoices.update(stripeInvoice.id, { metadata: { appPid: env.appPid, id: invoice.id } });
|
|
137
140
|
logger.info('stripe invoice mirrored', { local: invoice.id, remote: stripeInvoice.id });
|
|
138
141
|
|
package/api/src/libs/api.ts
CHANGED
|
@@ -76,11 +76,16 @@ export const getWhereFromKvQuery = (query: string) => {
|
|
|
76
76
|
const likes: any = [];
|
|
77
77
|
query.split(' ').forEach((kv: string) => {
|
|
78
78
|
const [k, v] = kv.split(':');
|
|
79
|
+
|
|
79
80
|
if (v) {
|
|
80
81
|
let value = decodeURIComponent(v).replace('+', ' ');
|
|
81
82
|
if ((k as any).indexOf('like') > -1) {
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
let kk = k?.slice(5);
|
|
84
|
+
if (kk === 'did' || kk === 'name' || kk === 'email') {
|
|
85
|
+
kk = `$customer.${kk}$`;
|
|
86
|
+
}
|
|
87
|
+
value = { [kk as any]: { [Op.like]: `%${v}%` } } as any;
|
|
88
|
+
|
|
84
89
|
likes.push(value);
|
|
85
90
|
} else {
|
|
86
91
|
out[k as string] = value;
|
|
@@ -106,6 +106,17 @@ export async function startCheckoutSessionQueue() {
|
|
|
106
106
|
checkoutSession: checkoutSession.id,
|
|
107
107
|
invoice: checkoutSession.invoice_id,
|
|
108
108
|
});
|
|
109
|
+
} else {
|
|
110
|
+
// Do some reverse lookup if invoice is not related to checkout session
|
|
111
|
+
const invoice = await Invoice.findOne({ where: { checkout_session_id: checkoutSession.id } });
|
|
112
|
+
if (invoice) {
|
|
113
|
+
await InvoiceItem.destroy({ where: { invoice_id: invoice.id } });
|
|
114
|
+
await Invoice.destroy({ where: { id: invoice.id } });
|
|
115
|
+
logger.info('Invoice and InvoiceItem for checkout session deleted on expire', {
|
|
116
|
+
checkoutSession: checkoutSession.id,
|
|
117
|
+
invoice: invoice.id,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
109
120
|
}
|
|
110
121
|
if (checkoutSession.setup_intent_id) {
|
|
111
122
|
await SetupIntent.destroy({ where: { id: checkoutSession.setup_intent_id } });
|
|
@@ -196,12 +196,23 @@ describe('getWhereFromKvQuery', () => {
|
|
|
196
196
|
});
|
|
197
197
|
|
|
198
198
|
it('should return a likes object when the q string with like', () => {
|
|
199
|
-
const q = 'like-status:succ like-
|
|
199
|
+
const q = 'like-status:succ like-number:1533';
|
|
200
200
|
const result = getWhereFromKvQuery(q);
|
|
201
201
|
expect(result).toEqual({
|
|
202
202
|
[Op.or]: [
|
|
203
203
|
{ status: { [Op.like]: `%succ%` } },
|
|
204
|
-
{
|
|
204
|
+
{ number: { [Op.like]: `%1533%` } }
|
|
205
|
+
],
|
|
206
|
+
});
|
|
207
|
+
});
|
|
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%` } }
|
|
205
216
|
],
|
|
206
217
|
});
|
|
207
218
|
});
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.13.
|
|
3
|
+
"version": "1.13.144",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "cross-env COMPONENT_STORE_URL=https://test.store.blocklet.dev blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"@arcblock/jwt": "^1.18.110",
|
|
51
51
|
"@arcblock/ux": "^2.9.29",
|
|
52
52
|
"@blocklet/logger": "1.16.23",
|
|
53
|
-
"@blocklet/payment-react": "1.13.
|
|
53
|
+
"@blocklet/payment-react": "1.13.144",
|
|
54
54
|
"@blocklet/sdk": "1.16.23",
|
|
55
55
|
"@blocklet/ui-react": "^2.9.29",
|
|
56
56
|
"@blocklet/uploader": "^0.0.73",
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@abtnode/types": "1.16.23",
|
|
112
112
|
"@arcblock/eslint-config-ts": "^0.2.4",
|
|
113
|
-
"@blocklet/payment-types": "1.13.
|
|
113
|
+
"@blocklet/payment-types": "1.13.144",
|
|
114
114
|
"@types/cookie-parser": "^1.4.6",
|
|
115
115
|
"@types/cors": "^2.8.17",
|
|
116
116
|
"@types/dotenv-flow": "^3.3.3",
|
|
@@ -149,5 +149,5 @@
|
|
|
149
149
|
"parser": "typescript"
|
|
150
150
|
}
|
|
151
151
|
},
|
|
152
|
-
"gitHead": "
|
|
152
|
+
"gitHead": "ffef3d0804ed91778330d90394718922388d3403"
|
|
153
153
|
}
|
|
@@ -9,6 +9,7 @@ import { useRequest } from 'ahooks';
|
|
|
9
9
|
import { useEffect, useState } from 'react';
|
|
10
10
|
import { useNavigate } from 'react-router-dom';
|
|
11
11
|
|
|
12
|
+
import { debounce } from '../../libs/util';
|
|
12
13
|
import CustomerLink from '../customer/link';
|
|
13
14
|
import Table from '../table';
|
|
14
15
|
import InvoiceActions from './action';
|
|
@@ -96,7 +97,9 @@ export default function InvoiceList({ customer_id, subscription_id, features, st
|
|
|
96
97
|
|
|
97
98
|
const { loading, error, data, refresh } = useRequest(() => fetchData(search));
|
|
98
99
|
useEffect(() => {
|
|
99
|
-
|
|
100
|
+
debounce(() => {
|
|
101
|
+
refresh();
|
|
102
|
+
}, 1000)();
|
|
100
103
|
}, [search, refresh]);
|
|
101
104
|
|
|
102
105
|
if (error) {
|
|
@@ -256,9 +259,9 @@ export default function InvoiceList({ customer_id, subscription_id, features, st
|
|
|
256
259
|
if (text) {
|
|
257
260
|
setSearch({
|
|
258
261
|
q: {
|
|
259
|
-
'like-
|
|
260
|
-
'like-
|
|
261
|
-
'like-
|
|
262
|
+
'like-did': text,
|
|
263
|
+
'like-name': text,
|
|
264
|
+
'like-number': text,
|
|
262
265
|
},
|
|
263
266
|
pageSize: 100,
|
|
264
267
|
page: 1,
|
|
@@ -8,6 +8,7 @@ import { fromUnitToToken } from '@ocap/util';
|
|
|
8
8
|
import { useEffect, useState } from 'react';
|
|
9
9
|
import { useNavigate } from 'react-router-dom';
|
|
10
10
|
|
|
11
|
+
import { debounce } from '../../libs/util';
|
|
11
12
|
import CustomerLink from '../customer/link';
|
|
12
13
|
import Table from '../table';
|
|
13
14
|
import PaymentIntentActions from './actions';
|
|
@@ -85,9 +86,11 @@ export default function PaymentList({ customer_id, invoice_id, features }: ListP
|
|
|
85
86
|
const [data, setData] = useState({}) as any;
|
|
86
87
|
|
|
87
88
|
useEffect(() => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
debounce(() => {
|
|
90
|
+
fetchData(search).then((res: any) => {
|
|
91
|
+
setData(res);
|
|
92
|
+
});
|
|
93
|
+
}, 1000)();
|
|
91
94
|
}, [search]);
|
|
92
95
|
|
|
93
96
|
if (!data) {
|
|
@@ -216,9 +219,8 @@ export default function PaymentList({ customer_id, invoice_id, features }: ListP
|
|
|
216
219
|
if (text) {
|
|
217
220
|
setSearch({
|
|
218
221
|
q: {
|
|
219
|
-
'like-
|
|
220
|
-
'like-
|
|
221
|
-
'like-description': text,
|
|
222
|
+
'like-did': text,
|
|
223
|
+
'like-name': text,
|
|
222
224
|
},
|
|
223
225
|
pageSize: 100,
|
|
224
226
|
page: 1,
|
|
@@ -8,6 +8,7 @@ import { useRequest } from 'ahooks';
|
|
|
8
8
|
import { useEffect, useState } from 'react';
|
|
9
9
|
import { useNavigate } from 'react-router-dom';
|
|
10
10
|
|
|
11
|
+
import { debounce } from '../../libs/util';
|
|
11
12
|
import CustomerLink from '../customer/link';
|
|
12
13
|
import Table from '../table';
|
|
13
14
|
import SubscriptionActions from './actions';
|
|
@@ -80,7 +81,9 @@ export default function SubscriptionList({ customer_id, features, status }: List
|
|
|
80
81
|
|
|
81
82
|
const { loading, error, data, refresh } = useRequest(() => fetchData(search));
|
|
82
83
|
useEffect(() => {
|
|
83
|
-
|
|
84
|
+
debounce(() => {
|
|
85
|
+
refresh();
|
|
86
|
+
}, 1000)();
|
|
84
87
|
}, [search, refresh]);
|
|
85
88
|
|
|
86
89
|
if (error) {
|
|
@@ -216,9 +219,10 @@ export default function SubscriptionList({ customer_id, features, status }: List
|
|
|
216
219
|
if (text) {
|
|
217
220
|
setSearch({
|
|
218
221
|
q: {
|
|
219
|
-
'like-
|
|
220
|
-
|
|
221
|
-
'like-
|
|
222
|
+
'like-metadata': text,
|
|
223
|
+
'like-did': text,
|
|
224
|
+
'like-name': text,
|
|
225
|
+
// 'like-product-name': text, // 这个还没实现
|
|
222
226
|
},
|
|
223
227
|
pageSize: 100,
|
|
224
228
|
page: 1,
|
package/src/libs/util.ts
CHANGED
|
@@ -191,3 +191,15 @@ export function getSupportedPaymentCurrencies(items: TLineItemExpanded[]) {
|
|
|
191
191
|
}, []);
|
|
192
192
|
return Array.from(new Set(currencies));
|
|
193
193
|
}
|
|
194
|
+
|
|
195
|
+
export const debounce = (fun: Function, wait: number) => {
|
|
196
|
+
let timeout: any = null;
|
|
197
|
+
return function () {
|
|
198
|
+
if (timeout) {
|
|
199
|
+
clearTimeout(timeout);
|
|
200
|
+
}
|
|
201
|
+
timeout = setTimeout(() => {
|
|
202
|
+
fun();
|
|
203
|
+
}, wait);
|
|
204
|
+
};
|
|
205
|
+
};
|
|
@@ -10,6 +10,7 @@ import { useEffect, useState } from 'react';
|
|
|
10
10
|
import { useNavigate } from 'react-router-dom';
|
|
11
11
|
|
|
12
12
|
import Table from '../../../../components/table';
|
|
13
|
+
import { debounce } from '../../../../libs/util';
|
|
13
14
|
|
|
14
15
|
const fetchData = (params: Record<string, any> = {}): Promise<{ list: TCustomer[]; count: number }> => {
|
|
15
16
|
const search = new URLSearchParams();
|
|
@@ -41,7 +42,9 @@ export default function CustomersList() {
|
|
|
41
42
|
|
|
42
43
|
const { loading, error, data, refresh } = useRequest(() => fetchData(search));
|
|
43
44
|
useEffect(() => {
|
|
44
|
-
|
|
45
|
+
debounce(() => {
|
|
46
|
+
refresh();
|
|
47
|
+
}, 1000)();
|
|
45
48
|
}, [search, refresh]);
|
|
46
49
|
|
|
47
50
|
if (error) {
|
|
@@ -119,12 +122,14 @@ export default function CustomersList() {
|
|
|
119
122
|
const item = data.list[dataIndex] as TCustomer;
|
|
120
123
|
navigate(`/admin/customers/${item.id}`);
|
|
121
124
|
},
|
|
125
|
+
|
|
122
126
|
onSearchChange: (text: string) => {
|
|
123
127
|
if (text) {
|
|
124
128
|
setSearch({
|
|
125
129
|
q: {
|
|
126
130
|
'like-name': text,
|
|
127
131
|
'like-email': text,
|
|
132
|
+
'like-did': text,
|
|
128
133
|
},
|
|
129
134
|
pageSize: 100,
|
|
130
135
|
page: 1,
|