payment-kit 1.14.32 → 1.14.34
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/libs/subscription.ts +1 -1
- package/api/src/queues/invoice.ts +1 -0
- package/api/src/queues/payment.ts +111 -6
- package/api/src/queues/subscription.ts +49 -92
- package/api/src/routes/invoices.ts +15 -5
- package/api/src/store/models/invoice.ts +2 -1
- package/blocklet.yml +1 -1
- package/package.json +11 -11
- package/src/components/customer/form.tsx +5 -1
- package/src/components/subscription/portal/list.tsx +2 -1
|
@@ -398,7 +398,7 @@ export async function getUpcomingInvoiceAmount(subscriptionId: string) {
|
|
|
398
398
|
}
|
|
399
399
|
|
|
400
400
|
if (subscription.isActive() === false) {
|
|
401
|
-
throw new Error(
|
|
401
|
+
throw new Error(`Subscription not active for ${subscriptionId}, so usage check is skipped`);
|
|
402
402
|
}
|
|
403
403
|
|
|
404
404
|
const currency = await PaymentCurrency.findByPk(subscription.currency_id);
|
|
@@ -122,6 +122,7 @@ export const handleInvoice = async (job: InvoiceJob) => {
|
|
|
122
122
|
subscription_cycle: 'Subscription cycle',
|
|
123
123
|
subscription_update: 'Subscription update',
|
|
124
124
|
subscription_threshold: 'Subscription threshold',
|
|
125
|
+
slash_stake: 'Slash stake',
|
|
125
126
|
};
|
|
126
127
|
// TODO: support partial payment from user balance
|
|
127
128
|
paymentIntent = await PaymentIntent.create({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import isEmpty from 'lodash/isEmpty';
|
|
2
2
|
|
|
3
|
+
import { toStakeAddress } from '@arcblock/did-util';
|
|
3
4
|
import { ensureStakedForGas } from '../integrations/arcblock/stake';
|
|
4
5
|
import { transferErc20FromUser } from '../integrations/ethereum/token';
|
|
5
6
|
import { createEvent } from '../libs/audit';
|
|
@@ -11,6 +12,7 @@ import logger from '../libs/logger';
|
|
|
11
12
|
import { getGasPayerExtra, isDelegationSufficientForPayment } from '../libs/payment';
|
|
12
13
|
import createQueue from '../libs/queue';
|
|
13
14
|
import {
|
|
15
|
+
checkRemainingStake,
|
|
14
16
|
getDaysUntilCancel,
|
|
15
17
|
getDaysUntilDue,
|
|
16
18
|
getDueUnit,
|
|
@@ -53,10 +55,10 @@ async function updateQuantitySold(checkoutSession: CheckoutSession) {
|
|
|
53
55
|
await Promise.all(updatePromises);
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
export const handlePaymentSucceed = async (paymentIntent: PaymentIntent) => {
|
|
58
|
+
export const handlePaymentSucceed = async (paymentIntent: PaymentIntent, slashStake: boolean = false) => {
|
|
57
59
|
// FIXME: @wangshijun we should check stripe payment here before
|
|
58
60
|
|
|
59
|
-
if (paymentIntent.beneficiaries?.length) {
|
|
61
|
+
if (paymentIntent.beneficiaries?.length && !slashStake) {
|
|
60
62
|
Promise.all(
|
|
61
63
|
paymentIntent.beneficiaries.map(async (x) => {
|
|
62
64
|
let customer = await Customer.findByPkOrDid(x.address);
|
|
@@ -119,7 +121,7 @@ export const handlePaymentSucceed = async (paymentIntent: PaymentIntent) => {
|
|
|
119
121
|
if (paymentIntent.invoice_id) {
|
|
120
122
|
invoice = await Invoice.findByPk(paymentIntent.invoice_id);
|
|
121
123
|
}
|
|
122
|
-
if (!invoice) {
|
|
124
|
+
if (!invoice && !slashStake) {
|
|
123
125
|
const checkoutSession = await CheckoutSession.findOne({ where: { payment_intent_id: paymentIntent.id } });
|
|
124
126
|
if (checkoutSession && checkoutSession.status === 'open') {
|
|
125
127
|
updateQuantitySold(checkoutSession).catch((err) => {
|
|
@@ -138,7 +140,7 @@ export const handlePaymentSucceed = async (paymentIntent: PaymentIntent) => {
|
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
if (invoice
|
|
143
|
+
if (invoice && invoice?.status !== 'paid') {
|
|
142
144
|
await invoice.update({
|
|
143
145
|
paid: true,
|
|
144
146
|
status: 'paid',
|
|
@@ -151,7 +153,7 @@ export const handlePaymentSucceed = async (paymentIntent: PaymentIntent) => {
|
|
|
151
153
|
logger.info(`Invoice ${invoice.id} updated on payment done: ${paymentIntent.id}`);
|
|
152
154
|
}
|
|
153
155
|
|
|
154
|
-
if (invoice.subscription_id) {
|
|
156
|
+
if (invoice && invoice.subscription_id && !slashStake) {
|
|
155
157
|
const subscription = await Subscription.findByPk(invoice.subscription_id);
|
|
156
158
|
|
|
157
159
|
// We only update subscription status when the invoice is the latest one
|
|
@@ -212,7 +214,7 @@ export const handlePaymentSucceed = async (paymentIntent: PaymentIntent) => {
|
|
|
212
214
|
}
|
|
213
215
|
}
|
|
214
216
|
|
|
215
|
-
if (invoice.checkout_session_id) {
|
|
217
|
+
if (invoice && invoice.checkout_session_id && !slashStake) {
|
|
216
218
|
const checkoutSession = await CheckoutSession.findByPk(invoice.checkout_session_id);
|
|
217
219
|
if (checkoutSession && checkoutSession.status === 'open') {
|
|
218
220
|
updateQuantitySold(checkoutSession).catch((err) => {
|
|
@@ -375,6 +377,105 @@ export const handlePaymentFailed = async (
|
|
|
375
377
|
return updates.retry;
|
|
376
378
|
};
|
|
377
379
|
|
|
380
|
+
const handleStakeSlash = async (
|
|
381
|
+
invoice: Invoice,
|
|
382
|
+
paymentIntent: PaymentIntent,
|
|
383
|
+
paymentMethod: PaymentMethod,
|
|
384
|
+
customer: Customer,
|
|
385
|
+
paymentCurrency: PaymentCurrency
|
|
386
|
+
) => {
|
|
387
|
+
const subscription = await Subscription.findByPk(invoice.subscription_id);
|
|
388
|
+
if (!subscription) {
|
|
389
|
+
logger.warn('Stake slashing skipped because Subscription not found', {
|
|
390
|
+
subscription: invoice.subscription_id,
|
|
391
|
+
paymentIntent: paymentIntent.id,
|
|
392
|
+
invoice: invoice.id,
|
|
393
|
+
});
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (!subscription.cancelation_details?.slash_stake || subscription.status !== 'canceled') {
|
|
397
|
+
logger.warn('Stake slashing skipped because subscription not canceled or slash_stake is false', {
|
|
398
|
+
subscription: invoice.subscription_id,
|
|
399
|
+
paymentIntent: paymentIntent.id,
|
|
400
|
+
invoice: invoice.id,
|
|
401
|
+
});
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const address = toStakeAddress(customer.did, wallet.address, subscription.id);
|
|
406
|
+
const slashAmount = paymentIntent.amount;
|
|
407
|
+
const stakeEnough = await checkRemainingStake(paymentMethod, paymentCurrency, address, slashAmount);
|
|
408
|
+
if (!stakeEnough.enough) {
|
|
409
|
+
logger.warn('Stake slashing aborted because no enough staking', {
|
|
410
|
+
subscription: subscription.id,
|
|
411
|
+
paymentIntent: paymentIntent.id,
|
|
412
|
+
invoice: invoice.id,
|
|
413
|
+
address,
|
|
414
|
+
staked: stakeEnough.revoked,
|
|
415
|
+
revoked: stakeEnough.revoked,
|
|
416
|
+
});
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
if (slashAmount === '0') {
|
|
420
|
+
logger.warn('Stake slashing aborted because slashAmount is 0', {
|
|
421
|
+
subscription: subscription.id,
|
|
422
|
+
paymentIntent: paymentIntent.id,
|
|
423
|
+
invoice: invoice.id,
|
|
424
|
+
address,
|
|
425
|
+
slashAmount,
|
|
426
|
+
});
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// do the slash
|
|
431
|
+
const client = paymentMethod.getOcapClient();
|
|
432
|
+
const signed = await client.signSlashStakeTx({
|
|
433
|
+
tx: {
|
|
434
|
+
itx: {
|
|
435
|
+
address: toStakeAddress(customer.did, wallet.address, subscription.id),
|
|
436
|
+
outputs: [{ owner: wallet.address, tokens: [{ address: paymentCurrency.contract, value: slashAmount }] }],
|
|
437
|
+
message: 'stake_slash_on_subscription_cancel',
|
|
438
|
+
data: {
|
|
439
|
+
typeUrl: 'json',
|
|
440
|
+
// @ts-ignore
|
|
441
|
+
value: {
|
|
442
|
+
appId: wallet.address,
|
|
443
|
+
reason: 'stake_slash_on_subscription_cancel',
|
|
444
|
+
subscriptionId: subscription.id,
|
|
445
|
+
invoiceId: invoice.id,
|
|
446
|
+
paymentIntentId: paymentIntent.id,
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
wallet,
|
|
452
|
+
});
|
|
453
|
+
// @ts-ignore
|
|
454
|
+
const { buffer } = await client.encodeSlashStakeTx({ tx: signed });
|
|
455
|
+
// @ts-ignore
|
|
456
|
+
const txHash = await client.sendSlashStakeTx({ tx: signed, wallet }, getGasPayerExtra(buffer));
|
|
457
|
+
logger.info('Stake slashing done', {
|
|
458
|
+
subscription: subscription.id,
|
|
459
|
+
amount: slashAmount,
|
|
460
|
+
paymentIntent: paymentIntent.id,
|
|
461
|
+
invoice: invoice.id,
|
|
462
|
+
address,
|
|
463
|
+
txHash,
|
|
464
|
+
});
|
|
465
|
+
await paymentIntent.update({
|
|
466
|
+
status: 'succeeded',
|
|
467
|
+
amount_received: slashAmount,
|
|
468
|
+
payment_details: {
|
|
469
|
+
arcblock: {
|
|
470
|
+
tx_hash: txHash,
|
|
471
|
+
payer: customer.did,
|
|
472
|
+
type: 'slash',
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
await handlePaymentSucceed(paymentIntent, true);
|
|
477
|
+
};
|
|
478
|
+
|
|
378
479
|
export const handlePayment = async (job: PaymentJob) => {
|
|
379
480
|
logger.info('handle payment', job);
|
|
380
481
|
|
|
@@ -450,6 +551,10 @@ export const handlePayment = async (job: PaymentJob) => {
|
|
|
450
551
|
try {
|
|
451
552
|
await paymentIntent.update({ status: 'processing', last_payment_error: null });
|
|
452
553
|
if (paymentMethod.type === 'arcblock') {
|
|
554
|
+
if (invoice?.billing_reason === 'slash_stake') {
|
|
555
|
+
await handleStakeSlash(invoice, paymentIntent, paymentMethod, customer, paymentCurrency);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
453
558
|
const client = paymentMethod.getOcapClient();
|
|
454
559
|
|
|
455
560
|
// check balance before capture with transaction
|
|
@@ -529,7 +529,6 @@ const slashStakeOnCancel = async (subscription: Subscription) => {
|
|
|
529
529
|
});
|
|
530
530
|
return;
|
|
531
531
|
}
|
|
532
|
-
const client = paymentMethod.getOcapClient();
|
|
533
532
|
const address = toStakeAddress(customer.did, wallet.address, subscription.id);
|
|
534
533
|
const currency = await PaymentCurrency.findByPk(subscription.currency_id);
|
|
535
534
|
if (!currency) {
|
|
@@ -560,99 +559,57 @@ const slashStakeOnCancel = async (subscription: Subscription) => {
|
|
|
560
559
|
return;
|
|
561
560
|
}
|
|
562
561
|
|
|
563
|
-
//
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
outputs: [{ owner: wallet.address, tokens: [{ address: currency.contract, value: result.return_amount }] }],
|
|
569
|
-
message: 'stake_slash_on_subscription_cancel',
|
|
570
|
-
data: {
|
|
571
|
-
typeUrl: 'json',
|
|
572
|
-
// @ts-ignore
|
|
573
|
-
value: {
|
|
574
|
-
appId: wallet.address,
|
|
575
|
-
reason: 'stake_slash_on_subscription_cancel',
|
|
576
|
-
subscriptionId: subscription.id,
|
|
577
|
-
invoiceId: subscription.latest_invoice_id,
|
|
578
|
-
paymentIntentId: result?.lastInvoice?.payment_intent_id as string,
|
|
579
|
-
},
|
|
580
|
-
},
|
|
581
|
-
},
|
|
582
|
-
},
|
|
583
|
-
wallet,
|
|
584
|
-
});
|
|
585
|
-
// @ts-ignore
|
|
586
|
-
const { buffer } = await client.encodeSlashStakeTx({ tx: signed });
|
|
587
|
-
// @ts-ignore
|
|
588
|
-
const txHash = await client.sendSlashStakeTx({ tx: signed, wallet }, getGasPayerExtra(buffer));
|
|
589
|
-
logger.info('Stake slashing done', {
|
|
590
|
-
subscription: subscription.id,
|
|
591
|
-
amount: result.return_amount,
|
|
592
|
-
address,
|
|
593
|
-
txHash,
|
|
594
|
-
});
|
|
595
|
-
// create new payment intent
|
|
596
|
-
const paymentIntent = await PaymentIntent.create({
|
|
597
|
-
livemode: subscription.livemode,
|
|
598
|
-
amount: result.return_amount,
|
|
599
|
-
amount_received: result.return_amount,
|
|
600
|
-
amount_capturable: '0',
|
|
601
|
-
currency_id: subscription.currency_id,
|
|
602
|
-
customer_id: subscription.customer_id,
|
|
603
|
-
payment_method_id: subscription.default_payment_method_id,
|
|
604
|
-
status: 'succeeded',
|
|
605
|
-
capture_method: 'manual',
|
|
606
|
-
last_payment_error: null,
|
|
607
|
-
description: 'Stake slash on subscription cancel',
|
|
608
|
-
statement_descriptor: result.lastInvoice?.statement_descriptor || getStatementDescriptor([]),
|
|
609
|
-
payment_method_types: ['arcblock'],
|
|
610
|
-
confirmation_method: '',
|
|
611
|
-
payment_details: {
|
|
612
|
-
arcblock: {
|
|
613
|
-
tx_hash: txHash,
|
|
614
|
-
payer: subscription.payment_details?.arcblock?.payer as string,
|
|
615
|
-
type: 'slash',
|
|
616
|
-
},
|
|
562
|
+
// FIXME: handle exist one more invoices
|
|
563
|
+
const invoice = await Invoice.findOne({
|
|
564
|
+
where: {
|
|
565
|
+
subscription_id: subscription.id,
|
|
566
|
+
billing_reason: 'slash_stake',
|
|
617
567
|
},
|
|
618
568
|
});
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
569
|
+
if (invoice) {
|
|
570
|
+
invoiceQueue.push({
|
|
571
|
+
id: invoice.id,
|
|
572
|
+
job: { invoiceId: invoice.id, retryOnError: true },
|
|
573
|
+
});
|
|
574
|
+
logger.info('Invoice job scheduled for slash stake', { invoice: invoice.id, subscription: subscription.id });
|
|
575
|
+
} else {
|
|
576
|
+
const { invoice: newInvoice } = await ensureInvoiceAndItems({
|
|
577
|
+
customer,
|
|
578
|
+
currency,
|
|
579
|
+
subscription,
|
|
580
|
+
trialing: false,
|
|
581
|
+
metered: false,
|
|
582
|
+
lineItems: [],
|
|
583
|
+
props: {
|
|
584
|
+
livemode: subscription.livemode,
|
|
585
|
+
description: 'Slash stake',
|
|
586
|
+
statement_descriptor: result.lastInvoice?.statement_descriptor,
|
|
587
|
+
period_start: subscription.canceled_at,
|
|
588
|
+
period_end: subscription.current_period_end as number,
|
|
589
|
+
|
|
590
|
+
auto_advance: true,
|
|
591
|
+
status: 'open',
|
|
592
|
+
billing_reason: 'slash_stake',
|
|
593
|
+
currency_id: subscription.currency_id,
|
|
594
|
+
|
|
595
|
+
total: result.return_amount,
|
|
596
|
+
subtotal: result.return_amount,
|
|
597
|
+
amount_paid: '0',
|
|
598
|
+
amount_remaining: result.return_amount,
|
|
599
|
+
amount_due: result.return_amount,
|
|
600
|
+
|
|
601
|
+
payment_settings: subscription.payment_settings,
|
|
602
|
+
default_payment_method_id: subscription.default_payment_method_id,
|
|
603
|
+
subscription_id: subscription.id,
|
|
604
|
+
} as unknown as Invoice,
|
|
605
|
+
});
|
|
606
|
+
logger.info('Invoice created for stake slash', { invoice: newInvoice.id, subscription: subscription.id });
|
|
607
|
+
invoiceQueue.push({
|
|
608
|
+
id: newInvoice.id,
|
|
609
|
+
job: { invoiceId: newInvoice.id, retryOnError: true },
|
|
610
|
+
});
|
|
611
|
+
logger.info('Invoice job scheduled for slash stake', { invoice: newInvoice.id, subscription: subscription.id });
|
|
612
|
+
}
|
|
656
613
|
};
|
|
657
614
|
|
|
658
615
|
// generate invoice for subscription periodically
|
|
@@ -150,11 +150,21 @@ router.get('/', authMine, async (req, res) => {
|
|
|
150
150
|
stakeAmount = state.tokens.find((x: any) => x.address === currency?.contract)?.value;
|
|
151
151
|
// stakeAmount should not be zero if nonce exist
|
|
152
152
|
if (!Number(stakeAmount)) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
if (subscription.cancelation_details?.return_stake) {
|
|
154
|
+
const refund = await Refund.findOne({
|
|
155
|
+
where: { subscription_id: subscription.id, status: 'succeeded', type: 'stake_return' },
|
|
156
|
+
});
|
|
157
|
+
if (refund) {
|
|
158
|
+
stakeAmount = refund.amount;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (subscription.cancelation_details?.slash_stake) {
|
|
162
|
+
const invoice = await Invoice.findOne({
|
|
163
|
+
where: { subscription_id: subscription.id, status: 'paid', billing_reason: 'slash_stake' },
|
|
164
|
+
});
|
|
165
|
+
if (invoice) {
|
|
166
|
+
stakeAmount = invoice.total;
|
|
167
|
+
}
|
|
158
168
|
}
|
|
159
169
|
}
|
|
160
170
|
}
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.34",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"eject": "vite eject",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@abtnode/cron": "1.16.
|
|
45
|
+
"@abtnode/cron": "1.16.30",
|
|
46
46
|
"@arcblock/did": "^1.18.132",
|
|
47
47
|
"@arcblock/did-auth-storage-nedb": "^1.7.1",
|
|
48
48
|
"@arcblock/did-connect": "^2.10.23",
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@arcblock/jwt": "^1.18.132",
|
|
51
51
|
"@arcblock/ux": "^2.10.23",
|
|
52
52
|
"@arcblock/validator": "^1.18.132",
|
|
53
|
-
"@blocklet/js-sdk": "1.16.
|
|
54
|
-
"@blocklet/logger": "1.16.
|
|
55
|
-
"@blocklet/payment-react": "1.14.
|
|
56
|
-
"@blocklet/sdk": "1.16.
|
|
53
|
+
"@blocklet/js-sdk": "1.16.30",
|
|
54
|
+
"@blocklet/logger": "1.16.30",
|
|
55
|
+
"@blocklet/payment-react": "1.14.34",
|
|
56
|
+
"@blocklet/sdk": "1.16.30",
|
|
57
57
|
"@blocklet/ui-react": "^2.10.23",
|
|
58
|
-
"@blocklet/uploader": "^0.1.
|
|
58
|
+
"@blocklet/uploader": "^0.1.27",
|
|
59
59
|
"@mui/icons-material": "^5.16.6",
|
|
60
60
|
"@mui/lab": "^5.0.0-alpha.173",
|
|
61
61
|
"@mui/material": "^5.16.6",
|
|
@@ -117,9 +117,9 @@
|
|
|
117
117
|
"validator": "^13.12.0"
|
|
118
118
|
},
|
|
119
119
|
"devDependencies": {
|
|
120
|
-
"@abtnode/types": "1.16.
|
|
120
|
+
"@abtnode/types": "1.16.30",
|
|
121
121
|
"@arcblock/eslint-config-ts": "^0.3.2",
|
|
122
|
-
"@blocklet/payment-types": "1.14.
|
|
122
|
+
"@blocklet/payment-types": "1.14.34",
|
|
123
123
|
"@types/cookie-parser": "^1.4.7",
|
|
124
124
|
"@types/cors": "^2.8.17",
|
|
125
125
|
"@types/debug": "^4.1.12",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"typescript": "^4.9.5",
|
|
146
146
|
"vite": "^5.3.5",
|
|
147
147
|
"vite-node": "^2.0.4",
|
|
148
|
-
"vite-plugin-blocklet": "^0.
|
|
148
|
+
"vite-plugin-blocklet": "^0.9.1",
|
|
149
149
|
"vite-plugin-node-polyfills": "^0.21.0",
|
|
150
150
|
"vite-plugin-svgr": "^4.2.0",
|
|
151
151
|
"vite-tsconfig-paths": "^4.3.2",
|
|
@@ -161,5 +161,5 @@
|
|
|
161
161
|
"parser": "typescript"
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
|
-
"gitHead": "
|
|
164
|
+
"gitHead": "7e2c9a3dd52ccd6880ebbd08a953d93aec715dff"
|
|
165
165
|
}
|
|
@@ -76,7 +76,11 @@ export default function CustomerForm() {
|
|
|
76
76
|
/>
|
|
77
77
|
|
|
78
78
|
<FormLabel className="base-label">{t('payment.checkout.billing.required')}</FormLabel>
|
|
79
|
-
<Controller
|
|
79
|
+
<Controller
|
|
80
|
+
name="address.country"
|
|
81
|
+
control={control}
|
|
82
|
+
render={({ field }) => <CountrySelect {...field} sx={{ pl: '6px' }} />}
|
|
83
|
+
/>
|
|
80
84
|
<FormInput
|
|
81
85
|
name="address.state"
|
|
82
86
|
variant="outlined"
|
|
@@ -29,7 +29,7 @@ type Props = {
|
|
|
29
29
|
changeActive?: (active: boolean) => void;
|
|
30
30
|
} & Omit<StackProps, 'onChange'>;
|
|
31
31
|
|
|
32
|
-
const pageSize =
|
|
32
|
+
const pageSize = 5;
|
|
33
33
|
|
|
34
34
|
export default function CurrentSubscriptions({
|
|
35
35
|
id,
|
|
@@ -84,6 +84,7 @@ export default function CurrentSubscriptions({
|
|
|
84
84
|
md: '500px',
|
|
85
85
|
},
|
|
86
86
|
overflowY: 'auto',
|
|
87
|
+
webkitOverflowScrolling: 'touch',
|
|
87
88
|
}}>
|
|
88
89
|
{data.list.map((subscription) => {
|
|
89
90
|
return (
|