payment-kit 1.19.0 → 1.19.1
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/index.ts +8 -0
- package/api/src/index.ts +4 -0
- package/api/src/libs/credit-grant.ts +146 -0
- package/api/src/libs/env.ts +1 -0
- package/api/src/libs/invoice.ts +4 -3
- package/api/src/libs/notification/template/base.ts +388 -2
- package/api/src/libs/notification/template/customer-credit-grant-granted.ts +149 -0
- package/api/src/libs/notification/template/customer-credit-grant-low-balance.ts +151 -0
- package/api/src/libs/notification/template/customer-credit-insufficient.ts +254 -0
- package/api/src/libs/notification/template/subscription-canceled.ts +193 -202
- package/api/src/libs/notification/template/subscription-refund-succeeded.ts +215 -237
- package/api/src/libs/notification/template/subscription-renewed.ts +130 -200
- package/api/src/libs/notification/template/subscription-succeeded.ts +100 -202
- package/api/src/libs/notification/template/subscription-trial-start.ts +142 -188
- package/api/src/libs/notification/template/subscription-trial-will-end.ts +146 -174
- package/api/src/libs/notification/template/subscription-upgraded.ts +96 -192
- package/api/src/libs/notification/template/subscription-will-canceled.ts +94 -135
- package/api/src/libs/notification/template/subscription-will-renew.ts +220 -245
- package/api/src/libs/payment.ts +69 -0
- package/api/src/libs/queue/index.ts +3 -2
- package/api/src/libs/session.ts +8 -0
- package/api/src/libs/subscription.ts +74 -3
- package/api/src/libs/ws.ts +23 -1
- package/api/src/locales/en.ts +33 -0
- package/api/src/locales/zh.ts +31 -0
- package/api/src/queues/credit-consume.ts +715 -0
- package/api/src/queues/credit-grant.ts +572 -0
- package/api/src/queues/notification.ts +173 -128
- package/api/src/queues/payment.ts +210 -122
- package/api/src/queues/subscription.ts +179 -0
- package/api/src/routes/checkout-sessions.ts +157 -9
- package/api/src/routes/connect/shared.ts +3 -2
- package/api/src/routes/credit-grants.ts +241 -0
- package/api/src/routes/credit-transactions.ts +208 -0
- package/api/src/routes/index.ts +8 -0
- package/api/src/routes/meter-events.ts +347 -0
- package/api/src/routes/meters.ts +219 -0
- package/api/src/routes/payment-currencies.ts +14 -2
- package/api/src/routes/payment-links.ts +1 -1
- package/api/src/routes/payment-methods.ts +14 -2
- package/api/src/routes/prices.ts +43 -0
- package/api/src/routes/pricing-table.ts +13 -7
- package/api/src/routes/products.ts +63 -4
- package/api/src/routes/settings.ts +1 -1
- package/api/src/routes/subscriptions.ts +4 -0
- package/api/src/store/migrations/20250610-billing-credit.ts +43 -0
- package/api/src/store/models/credit-grant.ts +486 -0
- package/api/src/store/models/credit-transaction.ts +268 -0
- package/api/src/store/models/customer.ts +8 -0
- package/api/src/store/models/index.ts +52 -1
- package/api/src/store/models/meter-event.ts +423 -0
- package/api/src/store/models/meter.ts +176 -0
- package/api/src/store/models/payment-currency.ts +66 -14
- package/api/src/store/models/price.ts +6 -0
- package/api/src/store/models/product.ts +2 -2
- package/api/src/store/models/subscription.ts +24 -0
- package/api/src/store/models/types.ts +28 -2
- package/api/tests/libs/subscription.spec.ts +53 -0
- package/blocklet.yml +9 -1
- package/package.json +4 -4
- package/scripts/sdk.js +233 -1
- package/src/app.tsx +10 -0
- package/src/components/collapse.tsx +11 -1
- package/src/components/customer/credit-grant-item-list.tsx +99 -0
- package/src/components/customer/credit-overview.tsx +233 -0
- package/src/components/customer/form.tsx +5 -2
- package/src/components/invoice/list.tsx +19 -1
- package/src/components/metadata/form.tsx +286 -90
- package/src/components/meter/actions.tsx +101 -0
- package/src/components/meter/add-usage-dialog.tsx +239 -0
- package/src/components/meter/events-list.tsx +657 -0
- package/src/components/meter/form.tsx +245 -0
- package/src/components/meter/products.tsx +264 -0
- package/src/components/meter/usage-guide.tsx +174 -0
- package/src/components/payment-currency/form.tsx +2 -0
- package/src/components/payment-intent/list.tsx +19 -1
- package/src/components/payment-link/preview.tsx +1 -1
- package/src/components/payment-link/product-select.tsx +52 -12
- package/src/components/payment-method/arcblock.tsx +2 -0
- package/src/components/payment-method/base.tsx +2 -0
- package/src/components/payment-method/bitcoin.tsx +2 -0
- package/src/components/payment-method/ethereum.tsx +2 -0
- package/src/components/payment-method/stripe.tsx +2 -0
- package/src/components/payouts/list.tsx +19 -1
- package/src/components/price/currency-select.tsx +51 -31
- package/src/components/price/form.tsx +881 -407
- package/src/components/pricing-table/preview.tsx +1 -1
- package/src/components/product/add-price.tsx +9 -7
- package/src/components/product/create.tsx +7 -4
- package/src/components/product/edit-price.tsx +21 -12
- package/src/components/product/features.tsx +17 -7
- package/src/components/product/form.tsx +104 -89
- package/src/components/refund/list.tsx +19 -1
- package/src/components/section/header.tsx +5 -18
- package/src/components/subscription/items/index.tsx +1 -1
- package/src/components/subscription/metrics.tsx +37 -5
- package/src/components/subscription/portal/actions.tsx +2 -1
- package/src/contexts/products.tsx +26 -9
- package/src/hooks/subscription.ts +34 -0
- package/src/libs/meter-utils.ts +196 -0
- package/src/libs/util.ts +4 -0
- package/src/locales/en.tsx +385 -4
- package/src/locales/zh.tsx +364 -0
- package/src/pages/admin/billing/index.tsx +61 -33
- package/src/pages/admin/billing/invoices/detail.tsx +1 -1
- package/src/pages/admin/billing/meters/create.tsx +60 -0
- package/src/pages/admin/billing/meters/detail.tsx +435 -0
- package/src/pages/admin/billing/meters/index.tsx +210 -0
- package/src/pages/admin/billing/meters/meter-event.tsx +346 -0
- package/src/pages/admin/billing/subscriptions/detail.tsx +47 -14
- package/src/pages/admin/customers/customers/credit-grant/detail.tsx +391 -0
- package/src/pages/admin/customers/customers/detail.tsx +22 -10
- package/src/pages/admin/customers/index.tsx +5 -0
- package/src/pages/admin/developers/events/detail.tsx +1 -1
- package/src/pages/admin/developers/index.tsx +1 -1
- package/src/pages/admin/payments/intents/detail.tsx +1 -1
- package/src/pages/admin/payments/payouts/detail.tsx +1 -1
- package/src/pages/admin/payments/refunds/detail.tsx +1 -1
- package/src/pages/admin/products/index.tsx +3 -2
- package/src/pages/admin/products/links/detail.tsx +1 -1
- package/src/pages/admin/products/prices/actions.tsx +16 -4
- package/src/pages/admin/products/prices/detail.tsx +30 -3
- package/src/pages/admin/products/prices/list.tsx +8 -1
- package/src/pages/admin/products/pricing-tables/detail.tsx +1 -1
- package/src/pages/admin/products/products/create.tsx +233 -57
- package/src/pages/admin/products/products/detail.tsx +2 -1
- package/src/pages/admin/settings/payment-methods/index.tsx +3 -0
- package/src/pages/customer/credit-grant/detail.tsx +308 -0
- package/src/pages/customer/index.tsx +35 -2
- package/src/pages/customer/recharge/account.tsx +5 -5
- package/src/pages/customer/subscription/change-payment.tsx +4 -2
- package/src/pages/customer/subscription/detail.tsx +48 -14
- package/src/pages/customer/subscription/embed.tsx +1 -1
|
@@ -1,28 +1,15 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/brace-style */
|
|
2
2
|
/* eslint-disable @typescript-eslint/indent */
|
|
3
3
|
import pWaitFor from 'p-wait-for';
|
|
4
|
-
import prettyMsI18n from 'pretty-ms-i18n';
|
|
5
4
|
import isEmpty from 'lodash/isEmpty';
|
|
6
5
|
|
|
7
|
-
import { getPaymentAmountForCycleSubscription
|
|
8
|
-
import { getUserLocale } from '../../../integrations/blocklet/notification';
|
|
6
|
+
import { getPaymentAmountForCycleSubscription } from '../../subscription';
|
|
9
7
|
import { translate } from '../../../locales';
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
PaymentMethod,
|
|
16
|
-
Subscription,
|
|
17
|
-
PaymentCurrency,
|
|
18
|
-
Invoice,
|
|
19
|
-
NFTMintChainType,
|
|
20
|
-
} from '../../../store/models';
|
|
21
|
-
import { getCustomerInvoicePageUrl, getOneTimeProductInfo } from '../../invoice';
|
|
22
|
-
import { getMainProductName } from '../../product';
|
|
23
|
-
import { formatTime, getPrettyMsI18nLocale } from '../../time';
|
|
24
|
-
import { formatCurrencyInfo, getExplorerLink, getSubscriptionNotificationCustomActions } from '../../util';
|
|
25
|
-
import type { BaseEmailTemplate, BaseEmailTemplateType } from './base';
|
|
8
|
+
import { CheckoutSession, NftMintItem, PaymentIntent, Invoice, NFTMintChainType } from '../../../store/models';
|
|
9
|
+
import { getOneTimeProductInfo } from '../../invoice';
|
|
10
|
+
import { formatTime } from '../../time';
|
|
11
|
+
import { formatCurrencyInfo, getExplorerLink } from '../../util';
|
|
12
|
+
import { BaseSubscriptionEmailTemplate, BaseEmailTemplateType } from './base';
|
|
26
13
|
|
|
27
14
|
export interface SubscriptionSucceededEmailTemplateOptions {
|
|
28
15
|
subscriptionId: string;
|
|
@@ -50,37 +37,31 @@ interface SubscriptionSucceededEmailTemplateContext {
|
|
|
50
37
|
viewTxHashLink: string | undefined;
|
|
51
38
|
oneTimeProductInfo?: Array<OneTimeProductInfo>;
|
|
52
39
|
customActions: any[];
|
|
40
|
+
isCreditSubscription: boolean;
|
|
53
41
|
}
|
|
54
42
|
|
|
55
|
-
export class SubscriptionSucceededEmailTemplate
|
|
56
|
-
implements BaseEmailTemplate<SubscriptionSucceededEmailTemplateContext>
|
|
57
|
-
{
|
|
43
|
+
export class SubscriptionSucceededEmailTemplate extends BaseSubscriptionEmailTemplate<SubscriptionSucceededEmailTemplateContext> {
|
|
58
44
|
options: SubscriptionSucceededEmailTemplateOptions;
|
|
59
45
|
|
|
60
46
|
constructor(options: SubscriptionSucceededEmailTemplateOptions) {
|
|
47
|
+
super();
|
|
61
48
|
this.options = options;
|
|
62
49
|
}
|
|
63
50
|
|
|
64
51
|
async getContext(): Promise<SubscriptionSucceededEmailTemplateContext> {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
52
|
+
// 获取基础订阅数据
|
|
53
|
+
const basicData = await this.getSubscriptionBasicData(this.options.subscriptionId);
|
|
54
|
+
const { subscription, userDid, locale, productName, paymentCurrency, isCreditSubscription } = basicData;
|
|
55
|
+
|
|
69
56
|
if (subscription.status !== 'active') {
|
|
70
57
|
throw new Error(`Subscription not active: ${this.options.subscriptionId}`);
|
|
71
58
|
}
|
|
72
59
|
|
|
73
|
-
|
|
74
|
-
if (!customer) {
|
|
75
|
-
throw new Error(`Customer not found: ${subscription.customer_id}`);
|
|
76
|
-
}
|
|
77
|
-
|
|
60
|
+
// 等待相关数据准备就绪
|
|
78
61
|
await pWaitFor(
|
|
79
62
|
async () => {
|
|
80
63
|
const invoice = await Invoice.findOne({
|
|
81
|
-
where: {
|
|
82
|
-
subscription_id: subscription.id,
|
|
83
|
-
},
|
|
64
|
+
where: { subscription_id: subscription.id },
|
|
84
65
|
order: [['created_at', 'ASC']],
|
|
85
66
|
});
|
|
86
67
|
const checkoutSession = await CheckoutSession.findBySubscriptionId(subscription.id);
|
|
@@ -94,95 +75,81 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
94
75
|
);
|
|
95
76
|
|
|
96
77
|
const invoice = (await Invoice.findByPk(subscription.latest_invoice_id)) as Invoice;
|
|
97
|
-
const paymentCurrency = (await PaymentCurrency.findOne({
|
|
98
|
-
where: {
|
|
99
|
-
id: subscription.currency_id,
|
|
100
|
-
},
|
|
101
|
-
})) as PaymentCurrency;
|
|
102
78
|
|
|
103
|
-
|
|
79
|
+
// 获取支付信息
|
|
80
|
+
const paymentInfoResult = await this.getPaymentInfo(
|
|
81
|
+
subscription,
|
|
82
|
+
paymentCurrency,
|
|
83
|
+
isCreditSubscription,
|
|
84
|
+
invoice?.id
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// 获取链接
|
|
88
|
+
const links = this.generateSubscriptionLinks(
|
|
89
|
+
subscription,
|
|
90
|
+
locale,
|
|
91
|
+
userDid,
|
|
92
|
+
'customer.subscription.started',
|
|
93
|
+
invoice?.id,
|
|
94
|
+
isCreditSubscription
|
|
95
|
+
);
|
|
104
96
|
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const productName = await getMainProductName(subscription.id);
|
|
108
|
-
const at: string = formatTime(subscription.created_at);
|
|
97
|
+
// 获取 NFT 信息
|
|
98
|
+
const nftInfo = await this.getNftMintInfo(subscription.id);
|
|
109
99
|
|
|
100
|
+
// 获取一次性产品信息
|
|
110
101
|
const oneTimeProductInfo = await getOneTimeProductInfo(subscription.latest_invoice_id as string, paymentCurrency);
|
|
111
|
-
const paymentAmount = await getPaymentAmountForCycleSubscription(subscription, paymentCurrency);
|
|
112
102
|
|
|
113
|
-
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
new Date(currentPeriodEnd).getTime() - new Date(currentPeriodStart).getTime(),
|
|
121
|
-
{
|
|
122
|
-
locale: getPrettyMsI18nLocale(locale),
|
|
123
|
-
}
|
|
103
|
+
// 计算支付金额和时间信息
|
|
104
|
+
const paymentAmount = await getPaymentAmountForCycleSubscription(subscription, paymentCurrency);
|
|
105
|
+
const formattedPaymentInfo = formatCurrencyInfo(
|
|
106
|
+
paymentAmount,
|
|
107
|
+
paymentCurrency,
|
|
108
|
+
paymentInfoResult.paymentMethod,
|
|
109
|
+
true
|
|
124
110
|
);
|
|
125
111
|
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
paymentMethod?.settings?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]?.api_host;
|
|
132
|
-
const viewSubscriptionLink = getCustomerSubscriptionPageUrl({
|
|
133
|
-
subscriptionId: subscription.id,
|
|
134
|
-
locale,
|
|
135
|
-
userDid,
|
|
136
|
-
});
|
|
137
|
-
const viewInvoiceLink = getCustomerInvoicePageUrl({
|
|
138
|
-
invoiceId: invoice.id,
|
|
139
|
-
userDid,
|
|
140
|
-
locale,
|
|
141
|
-
});
|
|
112
|
+
const periodInfo = this.formatSubscriptionPeriod(
|
|
113
|
+
subscription.current_period_start || invoice.period_start,
|
|
114
|
+
subscription.current_period_end || invoice.period_end,
|
|
115
|
+
locale
|
|
116
|
+
);
|
|
142
117
|
|
|
118
|
+
// 获取交易哈希链接
|
|
119
|
+
const checkoutSession = await CheckoutSession.findBySubscriptionId(subscription.id);
|
|
143
120
|
const paymentIntent = await PaymentIntent.findByPk(invoice.payment_intent_id);
|
|
144
121
|
const txHash: string | undefined =
|
|
145
122
|
paymentIntent?.payment_details?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]?.tx_hash;
|
|
146
|
-
const viewTxHashLink: string | undefined =
|
|
147
|
-
txHash &&
|
|
148
|
-
getExplorerLink({
|
|
149
|
-
type: 'tx',
|
|
150
|
-
did: txHash,
|
|
151
|
-
chainHost,
|
|
152
|
-
});
|
|
153
123
|
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
);
|
|
124
|
+
const chainHost: string | undefined =
|
|
125
|
+
paymentInfoResult.paymentMethod?.settings?.[checkoutSession?.nft_mint_details?.type as NFTMintChainType]
|
|
126
|
+
?.api_host;
|
|
127
|
+
|
|
128
|
+
const viewTxHashLink: string | undefined = txHash && getExplorerLink({ type: 'tx', did: txHash, chainHost });
|
|
159
129
|
|
|
160
130
|
return {
|
|
161
131
|
locale,
|
|
162
132
|
productName,
|
|
163
|
-
at,
|
|
164
|
-
|
|
133
|
+
at: formatTime(subscription.created_at),
|
|
165
134
|
userDid,
|
|
166
|
-
nftMintItem,
|
|
135
|
+
nftMintItem: nftInfo.nftMintItem,
|
|
167
136
|
chainHost,
|
|
168
|
-
paymentInfo,
|
|
169
|
-
currentPeriodStart,
|
|
170
|
-
currentPeriodEnd,
|
|
171
|
-
duration,
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
viewInvoiceLink,
|
|
137
|
+
paymentInfo: formattedPaymentInfo,
|
|
138
|
+
currentPeriodStart: periodInfo.currentPeriodStart,
|
|
139
|
+
currentPeriodEnd: periodInfo.currentPeriodEnd,
|
|
140
|
+
duration: periodInfo.duration,
|
|
141
|
+
viewSubscriptionLink: links.viewSubscriptionLink,
|
|
142
|
+
viewInvoiceLink: links.viewInvoiceLink!,
|
|
175
143
|
viewTxHashLink,
|
|
176
144
|
oneTimeProductInfo,
|
|
177
|
-
customActions,
|
|
145
|
+
customActions: links.customActions,
|
|
146
|
+
isCreditSubscription,
|
|
178
147
|
};
|
|
179
148
|
}
|
|
180
149
|
|
|
181
|
-
getOneTimeProductTemplate(oneTimeProductInfo: Array<OneTimeProductInfo>, locale: string = 'en') {
|
|
150
|
+
private getOneTimeProductTemplate(oneTimeProductInfo: Array<OneTimeProductInfo>, locale: string = 'en') {
|
|
182
151
|
return [
|
|
183
|
-
{
|
|
184
|
-
type: 'divider',
|
|
185
|
-
},
|
|
152
|
+
{ type: 'divider' },
|
|
186
153
|
{
|
|
187
154
|
type: 'text',
|
|
188
155
|
data: {
|
|
@@ -203,10 +170,7 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
203
170
|
},
|
|
204
171
|
{
|
|
205
172
|
type: 'text',
|
|
206
|
-
data: {
|
|
207
|
-
type: 'plain',
|
|
208
|
-
text: x?.productName,
|
|
209
|
-
},
|
|
173
|
+
data: { type: 'plain', text: x?.productName },
|
|
210
174
|
},
|
|
211
175
|
{
|
|
212
176
|
type: 'text',
|
|
@@ -218,10 +182,7 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
218
182
|
},
|
|
219
183
|
{
|
|
220
184
|
type: 'text',
|
|
221
|
-
data: {
|
|
222
|
-
type: 'plain',
|
|
223
|
-
text: x?.paymentInfo,
|
|
224
|
-
},
|
|
185
|
+
data: { type: 'plain', text: x?.paymentInfo },
|
|
225
186
|
},
|
|
226
187
|
{
|
|
227
188
|
type: 'text',
|
|
@@ -235,16 +196,16 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
235
196
|
type: 'text',
|
|
236
197
|
data: {
|
|
237
198
|
type: 'plain',
|
|
238
|
-
text: translate('notification.common.qty', locale, {
|
|
239
|
-
count: x.quantity,
|
|
240
|
-
}),
|
|
199
|
+
text: translate('notification.common.qty', locale, { count: x.quantity }),
|
|
241
200
|
},
|
|
242
201
|
},
|
|
243
202
|
]),
|
|
244
203
|
},
|
|
245
204
|
];
|
|
246
205
|
}
|
|
206
|
+
|
|
247
207
|
async getTemplate(): Promise<BaseEmailTemplateType> {
|
|
208
|
+
const context = await this.getContext();
|
|
248
209
|
const {
|
|
249
210
|
locale,
|
|
250
211
|
productName,
|
|
@@ -261,26 +222,41 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
261
222
|
viewTxHashLink,
|
|
262
223
|
oneTimeProductInfo,
|
|
263
224
|
customActions,
|
|
264
|
-
|
|
225
|
+
isCreditSubscription,
|
|
226
|
+
} = context;
|
|
227
|
+
|
|
265
228
|
const hasOneTimeProduct = !isEmpty(oneTimeProductInfo);
|
|
266
229
|
|
|
230
|
+
// 构建基础字段
|
|
231
|
+
const commonFields = this.buildCommonFields(userDid, productName, locale);
|
|
232
|
+
const paymentFields = this.buildPaymentField(paymentInfo, locale, isCreditSubscription);
|
|
233
|
+
const periodFields = this.buildPeriodField(
|
|
234
|
+
currentPeriodStart,
|
|
235
|
+
currentPeriodEnd,
|
|
236
|
+
duration,
|
|
237
|
+
locale,
|
|
238
|
+
isCreditSubscription
|
|
239
|
+
);
|
|
240
|
+
|
|
241
|
+
// 构建操作按钮
|
|
242
|
+
const actions = this.buildCommonActions(viewSubscriptionLink, viewInvoiceLink, locale, isCreditSubscription, [
|
|
243
|
+
viewTxHashLink && {
|
|
244
|
+
name: translate('notification.common.viewTxHash', locale),
|
|
245
|
+
title: translate('notification.common.viewTxHash', locale),
|
|
246
|
+
link: viewTxHashLink as string,
|
|
247
|
+
},
|
|
248
|
+
...customActions,
|
|
249
|
+
]);
|
|
250
|
+
|
|
267
251
|
const template: BaseEmailTemplateType = {
|
|
268
|
-
title:
|
|
269
|
-
|
|
270
|
-
})}`,
|
|
271
|
-
body: `${translate('notification.subscriptionSucceed.body', locale, {
|
|
272
|
-
at,
|
|
273
|
-
productName,
|
|
274
|
-
})}`,
|
|
252
|
+
title: translate('notification.subscriptionSucceed.title', locale, { productName }),
|
|
253
|
+
body: translate('notification.subscriptionSucceed.body', locale, { at, productName }),
|
|
275
254
|
// @ts-expect-error
|
|
276
255
|
attachments: [
|
|
277
256
|
nftMintItem &&
|
|
278
257
|
chainHost && {
|
|
279
258
|
type: 'asset',
|
|
280
|
-
data: {
|
|
281
|
-
chainHost,
|
|
282
|
-
did: nftMintItem.address,
|
|
283
|
-
},
|
|
259
|
+
data: { chainHost, did: nftMintItem.address },
|
|
284
260
|
},
|
|
285
261
|
hasOneTimeProduct && {
|
|
286
262
|
type: 'text',
|
|
@@ -291,92 +267,14 @@ export class SubscriptionSucceededEmailTemplate
|
|
|
291
267
|
},
|
|
292
268
|
{
|
|
293
269
|
type: 'section',
|
|
294
|
-
fields: [
|
|
295
|
-
{
|
|
296
|
-
type: 'text',
|
|
297
|
-
data: {
|
|
298
|
-
type: 'plain',
|
|
299
|
-
color: '#9397A1',
|
|
300
|
-
text: translate('notification.common.account', locale),
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
{
|
|
304
|
-
type: 'text',
|
|
305
|
-
data: {
|
|
306
|
-
type: 'plain',
|
|
307
|
-
text: userDid,
|
|
308
|
-
},
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
type: 'text',
|
|
312
|
-
data: {
|
|
313
|
-
type: 'plain',
|
|
314
|
-
color: '#9397A1',
|
|
315
|
-
text: translate('notification.common.product', locale),
|
|
316
|
-
},
|
|
317
|
-
},
|
|
318
|
-
{
|
|
319
|
-
type: 'text',
|
|
320
|
-
data: {
|
|
321
|
-
type: 'plain',
|
|
322
|
-
text: productName,
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
type: 'text',
|
|
327
|
-
data: {
|
|
328
|
-
type: 'plain',
|
|
329
|
-
color: '#9397A1',
|
|
330
|
-
text: translate('notification.common.paymentAmount', locale),
|
|
331
|
-
},
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
type: 'text',
|
|
335
|
-
data: {
|
|
336
|
-
type: 'plain',
|
|
337
|
-
text: paymentInfo,
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
{
|
|
341
|
-
type: 'text',
|
|
342
|
-
data: {
|
|
343
|
-
type: 'plain',
|
|
344
|
-
color: '#9397A1',
|
|
345
|
-
text: translate('notification.common.validityPeriod', locale),
|
|
346
|
-
},
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
type: 'text',
|
|
350
|
-
data: {
|
|
351
|
-
type: 'plain',
|
|
352
|
-
text: `${currentPeriodStart} ~ ${currentPeriodEnd}(${duration})`,
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
].filter(Boolean),
|
|
270
|
+
fields: [...commonFields, ...paymentFields, ...periodFields].filter(Boolean),
|
|
356
271
|
},
|
|
357
272
|
...(hasOneTimeProduct
|
|
358
273
|
? this.getOneTimeProductTemplate(oneTimeProductInfo as Array<OneTimeProductInfo>, locale)
|
|
359
274
|
: []),
|
|
360
275
|
].filter(Boolean),
|
|
361
276
|
// @ts-ignore
|
|
362
|
-
actions:
|
|
363
|
-
{
|
|
364
|
-
name: translate('notification.common.viewSubscription', locale),
|
|
365
|
-
title: translate('notification.common.viewSubscription', locale),
|
|
366
|
-
link: viewSubscriptionLink,
|
|
367
|
-
},
|
|
368
|
-
{
|
|
369
|
-
name: translate('notification.common.viewInvoice', locale),
|
|
370
|
-
title: translate('notification.common.viewInvoice', locale),
|
|
371
|
-
link: viewInvoiceLink,
|
|
372
|
-
},
|
|
373
|
-
viewTxHashLink && {
|
|
374
|
-
name: translate('notification.common.viewTxHash', locale),
|
|
375
|
-
title: translate('notification.common.viewTxHash', locale),
|
|
376
|
-
link: viewTxHashLink as string,
|
|
377
|
-
},
|
|
378
|
-
...customActions,
|
|
379
|
-
].filter(Boolean),
|
|
277
|
+
actions: actions.filter(Boolean),
|
|
380
278
|
};
|
|
381
279
|
|
|
382
280
|
return template;
|