payment-kit 1.18.30 → 1.18.32
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/crons/metering-subscription-detection.ts +9 -0
- package/api/src/integrations/arcblock/nft.ts +1 -0
- package/api/src/integrations/blocklet/passport.ts +1 -1
- package/api/src/integrations/stripe/handlers/invoice.ts +2 -2
- package/api/src/integrations/stripe/handlers/setup-intent.ts +29 -1
- package/api/src/integrations/stripe/handlers/subscription.ts +19 -15
- package/api/src/integrations/stripe/resource.ts +81 -1
- package/api/src/libs/audit.ts +42 -0
- package/api/src/libs/invoice.ts +54 -7
- package/api/src/libs/notification/index.ts +72 -4
- package/api/src/libs/notification/template/base.ts +2 -0
- package/api/src/libs/notification/template/subscription-renew-failed.ts +1 -5
- package/api/src/libs/notification/template/subscription-renewed.ts +1 -5
- package/api/src/libs/notification/template/subscription-succeeded.ts +8 -18
- package/api/src/libs/notification/template/subscription-trial-start.ts +2 -10
- package/api/src/libs/notification/template/subscription-upgraded.ts +1 -5
- package/api/src/libs/payment.ts +47 -14
- package/api/src/libs/product.ts +1 -4
- package/api/src/libs/session.ts +600 -8
- package/api/src/libs/setting.ts +172 -0
- package/api/src/libs/subscription.ts +7 -69
- package/api/src/libs/ws.ts +5 -0
- package/api/src/queues/checkout-session.ts +42 -36
- package/api/src/queues/notification.ts +3 -2
- package/api/src/queues/payment.ts +33 -6
- package/api/src/queues/usage-record.ts +2 -10
- package/api/src/routes/checkout-sessions.ts +324 -187
- package/api/src/routes/connect/shared.ts +160 -38
- package/api/src/routes/connect/subscribe.ts +123 -64
- package/api/src/routes/payment-currencies.ts +3 -6
- package/api/src/routes/payment-links.ts +11 -1
- package/api/src/routes/payment-stats.ts +2 -2
- package/api/src/routes/payouts.ts +2 -1
- package/api/src/routes/settings.ts +45 -0
- package/api/src/routes/subscriptions.ts +1 -2
- package/api/src/store/migrations/20250408-subscription-grouping.ts +39 -0
- package/api/src/store/migrations/20250419-subscription-grouping.ts +69 -0
- package/api/src/store/models/checkout-session.ts +52 -0
- package/api/src/store/models/index.ts +1 -0
- package/api/src/store/models/payment-link.ts +6 -0
- package/api/src/store/models/subscription.ts +8 -6
- package/api/src/store/models/types.ts +31 -1
- package/api/tests/libs/session.spec.ts +423 -0
- package/api/tests/libs/subscription.spec.ts +0 -110
- package/blocklet.yml +3 -1
- package/package.json +20 -19
- package/scripts/sdk.js +486 -155
- package/src/locales/en.tsx +1 -1
- package/src/locales/zh.tsx +1 -1
- package/src/pages/admin/settings/vault-config/edit-form.tsx +1 -1
- package/src/pages/customer/subscription/change-payment.tsx +8 -3
package/api/src/libs/payment.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { sign } from '@arcblock/jwt';
|
|
|
5
5
|
import { getWalletDid } from '@blocklet/sdk/lib/did';
|
|
6
6
|
import type { DelegateState, TokenLimit } from '@ocap/client';
|
|
7
7
|
import { toTxHash } from '@ocap/mcrypto';
|
|
8
|
-
import { BN,
|
|
8
|
+
import { BN, fromUnitToToken } from '@ocap/util';
|
|
9
9
|
import cloneDeep from 'lodash/cloneDeep';
|
|
10
10
|
import type { LiteralUnion } from 'type-fest';
|
|
11
11
|
|
|
@@ -24,7 +24,7 @@ import type { TPaymentCurrency } from '../store/models/payment-currency';
|
|
|
24
24
|
import { blocklet, ethWallet, wallet, getVaultAddress } from './auth';
|
|
25
25
|
import logger from './logger';
|
|
26
26
|
import { getBlockletJson, getUserOrAppInfo, OCAP_PAYMENT_TX_TYPE, resolveAddressChainTypes } from './util';
|
|
27
|
-
import { CHARGE_SUPPORTED_CHAIN_TYPES,
|
|
27
|
+
import { CHARGE_SUPPORTED_CHAIN_TYPES, EVM_CHAIN_TYPES } from './constants';
|
|
28
28
|
import { getTokenByAddress } from '../integrations/arcblock/stake';
|
|
29
29
|
|
|
30
30
|
export interface SufficientForPaymentResult {
|
|
@@ -44,6 +44,7 @@ export interface SufficientForPaymentResult {
|
|
|
44
44
|
delegator?: string;
|
|
45
45
|
state?: DelegateState;
|
|
46
46
|
token?: { address: string; balance: string };
|
|
47
|
+
requestedAmount?: string;
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
export async function isDelegationSufficientForPayment(args: {
|
|
@@ -51,10 +52,17 @@ export async function isDelegationSufficientForPayment(args: {
|
|
|
51
52
|
paymentCurrency: TPaymentCurrency;
|
|
52
53
|
userDid: string;
|
|
53
54
|
amount: string;
|
|
55
|
+
delegatorAmounts?: string[];
|
|
54
56
|
}): Promise<SufficientForPaymentResult> {
|
|
55
|
-
const { paymentCurrency, paymentMethod, userDid, amount } = args;
|
|
57
|
+
const { paymentCurrency, paymentMethod, userDid, amount, delegatorAmounts } = args;
|
|
56
58
|
const tokenAddress = paymentCurrency.contract as string;
|
|
57
59
|
|
|
60
|
+
let totalAmount = new BN(amount);
|
|
61
|
+
const hasDelegatorAmounts = delegatorAmounts && delegatorAmounts.length > 0;
|
|
62
|
+
if (hasDelegatorAmounts) {
|
|
63
|
+
totalAmount = delegatorAmounts.reduce((sum, amt) => sum.add(new BN(amt)), new BN('0'));
|
|
64
|
+
}
|
|
65
|
+
|
|
58
66
|
if (paymentMethod.type === 'arcblock') {
|
|
59
67
|
// user have bond wallet did?
|
|
60
68
|
const { user } = await blocklet.getUser(userDid, { enableConnectedAccount: true });
|
|
@@ -95,10 +103,25 @@ export async function isDelegationSufficientForPayment(args: {
|
|
|
95
103
|
return { sufficient: false, reason: 'NO_TRANSFER_TO' };
|
|
96
104
|
}
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
// check allowance
|
|
107
|
+
if (tokenLimit.txAllowance !== '0') {
|
|
108
|
+
const allowance = new BN(tokenLimit.txAllowance);
|
|
109
|
+
if (hasDelegatorAmounts) {
|
|
110
|
+
// check each delegator amount
|
|
111
|
+
const invalidAmount = delegatorAmounts.find((amt) => new BN(amt).gt(allowance));
|
|
112
|
+
|
|
113
|
+
if (invalidAmount) {
|
|
114
|
+
return {
|
|
115
|
+
sufficient: false,
|
|
116
|
+
reason: 'NO_ENOUGH_ALLOWANCE',
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
} else if (totalAmount.gt(allowance)) {
|
|
120
|
+
return {
|
|
121
|
+
sufficient: false,
|
|
122
|
+
reason: 'NO_ENOUGH_ALLOWANCE',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
102
125
|
}
|
|
103
126
|
}
|
|
104
127
|
|
|
@@ -108,11 +131,23 @@ export async function isDelegationSufficientForPayment(args: {
|
|
|
108
131
|
if (!token) {
|
|
109
132
|
return { sufficient: false, reason: 'NO_TOKEN' };
|
|
110
133
|
}
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
|
|
135
|
+
if (new BN(token.balance).lt(totalAmount)) {
|
|
136
|
+
return {
|
|
137
|
+
sufficient: false,
|
|
138
|
+
reason: 'NO_ENOUGH_TOKEN',
|
|
139
|
+
token,
|
|
140
|
+
requestedAmount: totalAmount.toString(),
|
|
141
|
+
};
|
|
113
142
|
}
|
|
114
143
|
|
|
115
|
-
return {
|
|
144
|
+
return {
|
|
145
|
+
sufficient: true,
|
|
146
|
+
delegator,
|
|
147
|
+
state,
|
|
148
|
+
token,
|
|
149
|
+
requestedAmount: totalAmount.toString(),
|
|
150
|
+
};
|
|
116
151
|
}
|
|
117
152
|
|
|
118
153
|
if (paymentMethod.type === 'stripe') {
|
|
@@ -459,10 +494,8 @@ export async function checkDepositVaultAmount(paymentCurrencyId: string): Promis
|
|
|
459
494
|
return { depositAmount: '0', message: 'No amount available to deposit after calculations' };
|
|
460
495
|
}
|
|
461
496
|
|
|
462
|
-
const bufferThreshold =
|
|
463
|
-
|
|
464
|
-
fromTokenToUnit(VAULT_BUFFER_THRESHOLD, paymentCurrency.decimal).toString();
|
|
465
|
-
if (new BN(amountToDeposit).lt(new BN(bufferThreshold))) {
|
|
497
|
+
const bufferThreshold = paymentCurrency?.vault_config?.buffer_threshold;
|
|
498
|
+
if (bufferThreshold && bufferThreshold !== '0' && new BN(amountToDeposit).lt(new BN(bufferThreshold))) {
|
|
466
499
|
return { depositAmount: '0', message: 'Amount to deposit is less than the buffer threshold' };
|
|
467
500
|
}
|
|
468
501
|
|
package/api/src/libs/product.ts
CHANGED
|
@@ -12,10 +12,7 @@ export async function getMainProductName(subscriptionId: string): Promise<string
|
|
|
12
12
|
return subscription.description!;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const checkoutSession = await CheckoutSession.
|
|
16
|
-
where: {
|
|
17
|
-
subscription_id: subscriptionId,
|
|
18
|
-
},
|
|
15
|
+
const checkoutSession = await CheckoutSession.findBySubscriptionId(subscriptionId, {
|
|
19
16
|
attributes: ['line_items'],
|
|
20
17
|
});
|
|
21
18
|
const priceId: string = checkoutSession?.line_items.find((x) => !x.cross_sell)?.price_id as string;
|