payment-kit 1.18.20 → 1.18.21
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/blocklet/user.ts +1 -0
- package/api/src/queues/payment.ts +2 -2
- package/api/src/routes/checkout-sessions.ts +36 -4
- package/api/src/routes/connect/shared.ts +1 -0
- package/api/src/routes/customers.ts +2 -2
- package/api/src/routes/settings.ts +3 -3
- package/api/src/store/models/customer.ts +22 -0
- package/blocklet.yml +1 -1
- package/package.json +8 -8
- package/src/components/layout/user.tsx +10 -0
- package/src/pages/customer/index.tsx +5 -3
|
@@ -125,8 +125,8 @@ export const handlePaymentSucceed = async (
|
|
|
125
125
|
did: user.did,
|
|
126
126
|
name: user.fullName,
|
|
127
127
|
email: user.email,
|
|
128
|
-
phone:
|
|
129
|
-
address:
|
|
128
|
+
phone: user.phone,
|
|
129
|
+
address: Customer.formatAddressFromUser(user),
|
|
130
130
|
description: user.remark,
|
|
131
131
|
metadata: {},
|
|
132
132
|
balance: '0',
|
|
@@ -76,6 +76,7 @@ import { ensureInvoiceForCheckout } from './connect/shared';
|
|
|
76
76
|
import { isCreditSufficientForPayment, isDelegationSufficientForPayment } from '../libs/payment';
|
|
77
77
|
import { handleStripeSubscriptionSucceed } from '../integrations/stripe/handlers/subscription';
|
|
78
78
|
import { CHARGE_SUPPORTED_CHAIN_TYPES } from '../libs/constants';
|
|
79
|
+
import { blocklet } from '../libs/auth';
|
|
79
80
|
|
|
80
81
|
const router = Router();
|
|
81
82
|
|
|
@@ -838,14 +839,15 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
838
839
|
|
|
839
840
|
let customer = await Customer.findOne({ where: { did: req.user.did } });
|
|
840
841
|
if (!customer) {
|
|
842
|
+
const { user: userInfo } = await blocklet.getUser(req.user.did);
|
|
841
843
|
customer = await Customer.create({
|
|
842
844
|
livemode: !!checkoutSession.livemode,
|
|
843
845
|
did: req.user.did,
|
|
844
846
|
name: req.body.customer_name,
|
|
845
|
-
email: req.body.customer_email,
|
|
846
|
-
phone: req.body.customer_phone,
|
|
847
|
-
address: req.body.billing_address,
|
|
848
|
-
description: '',
|
|
847
|
+
email: req.body.customer_email || userInfo?.email || '',
|
|
848
|
+
phone: req.body.customer_phone || userInfo?.phone || '',
|
|
849
|
+
address: req.body.billing_address || Customer.formatAddressFromUser(userInfo),
|
|
850
|
+
description: userInfo?.remark || '',
|
|
849
851
|
metadata: {},
|
|
850
852
|
balance: '0',
|
|
851
853
|
next_invoice_sequence: 1,
|
|
@@ -853,6 +855,20 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
853
855
|
invoice_prefix: Customer.getInvoicePrefix(),
|
|
854
856
|
});
|
|
855
857
|
logger.info('customer created on checkout session submit', { did: req.user.did, id: customer.id });
|
|
858
|
+
try {
|
|
859
|
+
await blocklet.updateUserAddress({
|
|
860
|
+
did: customer.did,
|
|
861
|
+
address: Customer.formatAddressFromCustomer(customer),
|
|
862
|
+
});
|
|
863
|
+
logger.info('updateUserAddress success', {
|
|
864
|
+
did: customer.did,
|
|
865
|
+
});
|
|
866
|
+
} catch (err) {
|
|
867
|
+
logger.error('updateUserAddress failed', {
|
|
868
|
+
error: err,
|
|
869
|
+
customerId: customer.id,
|
|
870
|
+
});
|
|
871
|
+
}
|
|
856
872
|
} else {
|
|
857
873
|
const updates: Record<string, string> = {};
|
|
858
874
|
if (checkoutSession.customer_update?.name) {
|
|
@@ -868,6 +884,22 @@ router.put('/:id/submit', user, ensureCheckoutSessionOpen, async (req, res) => {
|
|
|
868
884
|
}
|
|
869
885
|
|
|
870
886
|
await customer.update(updates);
|
|
887
|
+
try {
|
|
888
|
+
await blocklet.updateUserAddress({
|
|
889
|
+
did: customer.did,
|
|
890
|
+
address: Customer.formatAddressFromCustomer(customer),
|
|
891
|
+
// @ts-ignore
|
|
892
|
+
phone: customer.phone,
|
|
893
|
+
});
|
|
894
|
+
logger.info('updateUserAddress success', {
|
|
895
|
+
did: customer.did,
|
|
896
|
+
});
|
|
897
|
+
} catch (err) {
|
|
898
|
+
logger.error('updateUserAddress failed', {
|
|
899
|
+
error: err,
|
|
900
|
+
customerId: customer.id,
|
|
901
|
+
});
|
|
902
|
+
}
|
|
871
903
|
}
|
|
872
904
|
|
|
873
905
|
// check if customer can make new purchase
|
|
@@ -117,6 +117,7 @@ export async function ensurePaymentIntent(checkoutSessionId: string, userDid?: s
|
|
|
117
117
|
metadata: { fromDonation: true },
|
|
118
118
|
livemode: checkoutSession.livemode,
|
|
119
119
|
phone: user.phone,
|
|
120
|
+
address: Customer.formatAddressFromUser(user),
|
|
120
121
|
delinquent: false,
|
|
121
122
|
balance: '0',
|
|
122
123
|
next_invoice_sequence: 1,
|
|
@@ -115,7 +115,7 @@ router.get('/me', sessionMiddleware(), async (req, res) => {
|
|
|
115
115
|
name: user.fullName,
|
|
116
116
|
email: user.email,
|
|
117
117
|
phone: user.phone,
|
|
118
|
-
address:
|
|
118
|
+
address: Customer.formatAddressFromUser(user),
|
|
119
119
|
description: user.remark,
|
|
120
120
|
metadata: {},
|
|
121
121
|
balance: '0',
|
|
@@ -169,7 +169,7 @@ router.get('/me', sessionMiddleware(), async (req, res) => {
|
|
|
169
169
|
});
|
|
170
170
|
|
|
171
171
|
// get overdue invoices
|
|
172
|
-
router.get('/:id/overdue/invoices',
|
|
172
|
+
router.get('/:id/overdue/invoices', sessionMiddleware(), async (req, res) => {
|
|
173
173
|
if (!req.user) {
|
|
174
174
|
return res.status(403).json({ error: 'Unauthorized' });
|
|
175
175
|
}
|
|
@@ -140,7 +140,7 @@ router.post('/', async (req, res) => {
|
|
|
140
140
|
const defaultSetting = {
|
|
141
141
|
amount: {
|
|
142
142
|
presets: ['1', '5', '10'],
|
|
143
|
-
preset: '
|
|
143
|
+
preset: '5',
|
|
144
144
|
minimum: '0.01',
|
|
145
145
|
maximum: '100',
|
|
146
146
|
custom: true,
|
|
@@ -154,7 +154,7 @@ router.post('/', async (req, res) => {
|
|
|
154
154
|
presets: Joi.array()
|
|
155
155
|
.items(Joi.string())
|
|
156
156
|
.when('custom', { is: false, then: Joi.required(), otherwise: Joi.optional() }),
|
|
157
|
-
preset: Joi.string().optional(),
|
|
157
|
+
preset: Joi.string().empty('').optional(),
|
|
158
158
|
minimum: Joi.string().when('custom', { is: true, then: Joi.required() }),
|
|
159
159
|
maximum: Joi.string().when('custom', { is: true, then: Joi.required() }),
|
|
160
160
|
custom: Joi.boolean().required(),
|
|
@@ -238,7 +238,7 @@ router.put('/:mountLocationOrId', authAdmin, async (req, res) => {
|
|
|
238
238
|
presets: Joi.array()
|
|
239
239
|
.items(Joi.string())
|
|
240
240
|
.when('custom', { is: false, then: Joi.required(), otherwise: Joi.optional() }),
|
|
241
|
-
preset: Joi.string().optional(),
|
|
241
|
+
preset: Joi.string().empty('').optional(),
|
|
242
242
|
minimum: Joi.string().when('custom', { is: true, then: Joi.required() }),
|
|
243
243
|
maximum: Joi.string().when('custom', { is: true, then: Joi.required() }),
|
|
244
244
|
custom: Joi.boolean().required(),
|
|
@@ -282,6 +282,28 @@ export class Customer extends Model<InferAttributes<Customer>, InferCreationAttr
|
|
|
282
282
|
public static getInvoicePrefix() {
|
|
283
283
|
return nextInvoicePrefix();
|
|
284
284
|
}
|
|
285
|
+
|
|
286
|
+
public static formatAddressFromUser(user: any) {
|
|
287
|
+
return {
|
|
288
|
+
country: user.address?.country || '',
|
|
289
|
+
state: user.address?.province || '',
|
|
290
|
+
city: user.address?.city || '',
|
|
291
|
+
line1: user.address?.line1 || '',
|
|
292
|
+
line2: user.address?.line2 || '',
|
|
293
|
+
postal_code: user.address?.postalCode || '',
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
public static formatAddressFromCustomer(customer: Customer) {
|
|
298
|
+
return {
|
|
299
|
+
country: customer.address?.country || '',
|
|
300
|
+
province: customer.address?.state || '',
|
|
301
|
+
city: customer.address?.city || '',
|
|
302
|
+
line1: customer.address?.line1 || '',
|
|
303
|
+
line2: customer.address?.line2 || '',
|
|
304
|
+
postalCode: customer.address?.postal_code || '',
|
|
305
|
+
};
|
|
306
|
+
}
|
|
285
307
|
}
|
|
286
308
|
|
|
287
309
|
export type TCustomer = InferAttributes<Customer>;
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.18.
|
|
3
|
+
"version": "1.18.21",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
"@abtnode/cron": "^1.16.40",
|
|
47
47
|
"@arcblock/did": "^1.19.15",
|
|
48
48
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
49
|
-
"@arcblock/did-connect": "^2.12.
|
|
49
|
+
"@arcblock/did-connect": "^2.12.43",
|
|
50
50
|
"@arcblock/did-util": "^1.19.15",
|
|
51
51
|
"@arcblock/jwt": "^1.19.15",
|
|
52
|
-
"@arcblock/ux": "^2.12.
|
|
52
|
+
"@arcblock/ux": "^2.12.43",
|
|
53
53
|
"@arcblock/validator": "^1.19.15",
|
|
54
54
|
"@blocklet/js-sdk": "^1.16.40",
|
|
55
55
|
"@blocklet/logger": "^1.16.40",
|
|
56
|
-
"@blocklet/payment-react": "1.18.
|
|
56
|
+
"@blocklet/payment-react": "1.18.21",
|
|
57
57
|
"@blocklet/sdk": "^1.16.40",
|
|
58
|
-
"@blocklet/ui-react": "^2.12.
|
|
58
|
+
"@blocklet/ui-react": "^2.12.43",
|
|
59
59
|
"@blocklet/uploader": "^0.1.79",
|
|
60
60
|
"@blocklet/xss": "^0.1.30",
|
|
61
61
|
"@mui/icons-material": "^5.16.6",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"devDependencies": {
|
|
122
122
|
"@abtnode/types": "^1.16.40",
|
|
123
123
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
124
|
-
"@blocklet/payment-types": "1.18.
|
|
124
|
+
"@blocklet/payment-types": "1.18.21",
|
|
125
125
|
"@types/cookie-parser": "^1.4.7",
|
|
126
126
|
"@types/cors": "^2.8.17",
|
|
127
127
|
"@types/debug": "^4.1.12",
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
"vite": "^5.3.5",
|
|
152
152
|
"vite-node": "^2.0.4",
|
|
153
153
|
"vite-plugin-babel-import": "^2.0.5",
|
|
154
|
-
"vite-plugin-blocklet": "^0.9.
|
|
154
|
+
"vite-plugin-blocklet": "^0.9.27",
|
|
155
155
|
"vite-plugin-node-polyfills": "^0.21.0",
|
|
156
156
|
"vite-plugin-svgr": "^4.2.0",
|
|
157
157
|
"vite-tsconfig-paths": "^4.3.2",
|
|
@@ -167,5 +167,5 @@
|
|
|
167
167
|
"parser": "typescript"
|
|
168
168
|
}
|
|
169
169
|
},
|
|
170
|
-
"gitHead": "
|
|
170
|
+
"gitHead": "cf08902482dded20ee91402ed6d4678383965daf"
|
|
171
171
|
}
|
|
@@ -3,10 +3,19 @@ import { PaymentProvider } from '@blocklet/payment-react';
|
|
|
3
3
|
import { UserCenter } from '@blocklet/ui-react';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
5
|
|
|
6
|
+
import { useSearchParams } from 'react-router-dom';
|
|
6
7
|
import { useSessionContext } from '../../contexts/session';
|
|
7
8
|
|
|
8
9
|
export default function UserLayout(props: any) {
|
|
9
10
|
const { session, connectApi, events } = useSessionContext();
|
|
11
|
+
const [params] = useSearchParams();
|
|
12
|
+
const embed = params.get('embed') || sessionStorage.getItem('embed');
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (embed) {
|
|
16
|
+
sessionStorage.setItem('embed', embed);
|
|
17
|
+
}
|
|
18
|
+
}, [embed]);
|
|
10
19
|
|
|
11
20
|
useEffect(() => {
|
|
12
21
|
events.once('logout', () => {
|
|
@@ -28,6 +37,7 @@ export default function UserLayout(props: any) {
|
|
|
28
37
|
currentTab={`${window.blocklet.prefix}customer`}
|
|
29
38
|
userDid={session.user.did}
|
|
30
39
|
hideFooter
|
|
40
|
+
embed={embed === '1'}
|
|
31
41
|
notLoginContent="undefined">
|
|
32
42
|
{props.children}
|
|
33
43
|
</UserCenter>
|
|
@@ -35,7 +35,7 @@ import { styled } from '@mui/system';
|
|
|
35
35
|
import { useRequest, useSetState } from 'ahooks';
|
|
36
36
|
import { flatten, isEmpty } from 'lodash';
|
|
37
37
|
import { memo, useEffect, useState } from 'react';
|
|
38
|
-
import { useNavigate } from 'react-router-dom';
|
|
38
|
+
import { useNavigate, useSearchParams } from 'react-router-dom';
|
|
39
39
|
import { joinURL } from 'ufo';
|
|
40
40
|
|
|
41
41
|
import { useTransitionContext } from '../../components/progress-bar';
|
|
@@ -251,6 +251,8 @@ export default function CustomerHome() {
|
|
|
251
251
|
}))
|
|
252
252
|
)
|
|
253
253
|
);
|
|
254
|
+
const [params] = useSearchParams();
|
|
255
|
+
const embed = params.get('embed') || sessionStorage.getItem('embed');
|
|
254
256
|
|
|
255
257
|
const { livemode, setLivemode } = usePaymentContext();
|
|
256
258
|
const [state, setState] = useSetState({
|
|
@@ -508,14 +510,14 @@ export default function CustomerHome() {
|
|
|
508
510
|
<Box className="base-card section section-invoices">
|
|
509
511
|
<Box className="section-header">
|
|
510
512
|
<Typography variant="h3">{t('customer.invoiceHistory')}</Typography>
|
|
511
|
-
{isEmpty(data?.summary?.due)
|
|
513
|
+
{isEmpty(data?.summary?.due) !== false && (
|
|
512
514
|
<Tooltip title={t('payment.customer.pastDue.warning')}>
|
|
513
515
|
<Button
|
|
514
516
|
variant="text"
|
|
515
517
|
color="error"
|
|
516
518
|
component="a"
|
|
517
519
|
size="small"
|
|
518
|
-
href={joinURL(getPrefix(), '/customer/invoice/past-due')}
|
|
520
|
+
href={joinURL(getPrefix(), '/customer/invoice/past-due', `${embed === '1' ? '?embed=1' : ''}`)}
|
|
519
521
|
target="_blank"
|
|
520
522
|
rel="noreferrer"
|
|
521
523
|
style={{ textDecoration: 'none', fontSize: 13 }}>
|