@jolibox/implement 1.1.24 → 1.1.26

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.
Files changed (38) hide show
  1. package/.rush/temp/package-deps_build.json +19 -14
  2. package/dist/common/context/index.d.ts +1 -0
  3. package/dist/common/context/url-parse.d.ts +1 -0
  4. package/dist/common/report/task-track/index.d.ts +1 -1
  5. package/dist/h5/api/base.d.ts +1 -1
  6. package/dist/h5/api/storage.d.ts +1 -1
  7. package/dist/index.js +8 -8
  8. package/dist/index.native.js +119 -103
  9. package/dist/native/api/base.d.ts +1 -1
  10. package/dist/native/api/keyboard.d.ts +3 -3
  11. package/dist/native/api/login.d.ts +1 -1
  12. package/dist/native/api/storage.d.ts +5 -5
  13. package/dist/native/payment/index.d.ts +4 -0
  14. package/dist/native/payment/payment-helper.d.ts +13 -0
  15. package/dist/native/payment/registers/base.d.ts +21 -0
  16. package/dist/native/payment/registers/joli-coin.d.ts +17 -0
  17. package/dist/native/payment/registers/type.d.ts +14 -0
  18. package/dist/native/report/task-tracker.d.ts +1 -1
  19. package/implement.build.log +2 -2
  20. package/package.json +5 -5
  21. package/src/common/context/index.ts +3 -0
  22. package/src/common/context/url-parse.ts +1 -0
  23. package/src/common/report/task-track/index.ts +5 -3
  24. package/src/common/rewards/registers/use-jolicoin-only.ts +4 -4
  25. package/src/common/rewards/registers/use-jolicoin.ts +4 -4
  26. package/src/h5/api/task.ts +43 -131
  27. package/src/native/api/ads.ts +4 -1
  28. package/src/native/api/storage.ts +9 -7
  29. package/src/native/api/task.ts +41 -159
  30. package/src/native/bootstrap/index.ts +2 -0
  31. package/src/native/payment/index.ts +5 -0
  32. package/src/native/payment/payment-helper.ts +44 -0
  33. package/src/native/payment/registers/base.ts +97 -0
  34. package/src/native/payment/registers/joli-coin.ts +83 -0
  35. package/src/native/payment/registers/type.ts +15 -0
  36. package/src/native/report/task-tracker.ts +1 -1
  37. package/src/native/rewards/check-frequency.ts +28 -15
  38. package/src/native/rewards/index.ts +8 -2
@@ -1,5 +1,4 @@
1
1
  import { createCommands } from '@jolibox/common';
2
-
3
2
  import { createAPI, registerCanIUse, t } from './base';
4
3
  import { taskTracker } from '../report';
5
4
 
@@ -7,20 +6,22 @@ const commands = createCommands();
7
6
 
8
7
  const onLevelFinished = createAPI('levelFinished', {
9
8
  paramsSchema: t.tuple(
10
- t.string(),
11
9
  t.object({
12
- result: t.boolean(),
13
- duration: t.number()
10
+ levelId: t.or(t.string(), t.number()),
11
+ duration: t.number().optional(),
12
+ rating: t.number().optional(),
13
+ score: t.number().optional()
14
14
  })
15
15
  ),
16
- implement: async (levelId, parmas) => {
17
- const { result, duration } = parmas;
16
+ implement: async (parmas) => {
17
+ const { levelId, duration, rating, score } = parmas;
18
18
  const tasks = [];
19
19
  tasks.push(
20
20
  taskTracker.tracker('LevelFinished', {
21
21
  levelId,
22
- result,
23
- duration
22
+ duration,
23
+ rating,
24
+ score
24
25
  })
25
26
  );
26
27
 
@@ -33,195 +34,76 @@ const onLevelFinished = createAPI('levelFinished', {
33
34
  }
34
35
  });
35
36
 
36
- const onTaskFinished = createAPI('taskFinished', {
37
+ const onGamePlayEnded = createAPI('gamePlayEnded', {
37
38
  paramsSchema: t.tuple(
38
- t.string(),
39
39
  t.object({
40
- duration: t.number()
40
+ duration: t.number().optional(),
41
+ rating: t.number().optional(),
42
+ score: t.number()
41
43
  })
42
44
  ),
43
- implement: async (taskId, params) => {
44
- const { duration } = params;
45
- return await taskTracker.reportToNative({
46
- event: 'TaskFinished',
47
- params: {
48
- duration,
49
- taskId
50
- }
45
+ implement: async (params) => {
46
+ const { duration, rating, score } = params;
47
+ return taskTracker.tracker('GamePlayEnded', {
48
+ duration,
49
+ rating,
50
+ score
51
51
  });
52
52
  }
53
53
  });
54
54
 
55
55
  const onLevelUpgrade = createAPI('levelUpgrade', {
56
- paramsSchema: t.tuple(t.string(), t.string()),
57
- implement: async (levelId, name) => {
58
- const tasks = [];
59
- tasks.push(
60
- taskTracker.reportToNative({
61
- event: 'LevelUpgrade',
62
- params: {
63
- name,
64
- levelId
65
- }
66
- })
67
- );
68
- await Promise.all(tasks);
69
- }
70
- });
71
-
72
- const onHistoryUserLevel = createAPI('onHistoryUserLevel', {
73
- paramsSchema: t.tuple(t.number()),
74
- implement: async (level) => {
75
- return await taskTracker.reportToNative({
76
- event: 'HistoryUserLevel',
77
- params: {
78
- level
79
- }
80
- });
81
- }
82
- });
83
-
84
- const onHistoryUserScore = createAPI('onHistoryUserScore', {
85
- paramsSchema: t.tuple(t.number()),
86
- implement: async (score) => {
87
- return await taskTracker.reportToNative({
88
- event: 'HistoryUserScore',
89
- params: {
90
- score
91
- }
92
- });
93
- }
94
- });
95
-
96
- const onTaskEvent = createAPI('taskEvent', {
97
56
  paramsSchema: t.tuple(
98
- t.string(),
99
57
  t.object({
100
- tools: t
101
- .array(
102
- t.object({
103
- id: t.string(),
104
- name: t.string(),
105
- count: t.number(),
106
- description: t.string().optional(),
107
- price: t
108
- .object({
109
- amount: t.number(),
110
- unit: t.string()
111
- })
112
- .optional()
113
- })
114
- )
115
- .optional(),
116
- awards: t
117
- .array(
118
- t.object({
119
- id: t.string(),
120
- name: t.string()
121
- })
122
- )
123
- .optional()
58
+ levelId: t.or(t.string(), t.number()),
59
+ name: t.string().optional()
124
60
  })
125
61
  ),
126
- implement: async (taskId, params) => {
62
+ implement: async ({ levelId, name }) => {
127
63
  const tasks = [];
128
64
  tasks.push(
129
- taskTracker.reportToNative({
130
- event: 'TaskEvent',
131
- params: {
132
- taskId,
133
- ...params
134
- }
65
+ taskTracker.tracker('LevelUpgrade', {
66
+ name,
67
+ levelId
135
68
  })
136
69
  );
137
- // 使用了道具,上报任务
138
- if (params.tools?.length ?? 0 > 0) {
139
- tasks.push(
140
- taskTracker.reporter({
141
- event: 'USE_GAME_ITEM'
142
- })
143
- );
144
- tasks.push(
145
- taskTracker.reportToNative({
146
- event: 'UseGameItem',
147
- params: {
148
- taskId,
149
- ...params
150
- }
151
- })
152
- );
153
- }
154
70
  await Promise.all(tasks);
155
71
  }
156
72
  });
157
73
 
158
74
  commands.registerCommand('TaskTrackerSDK.levelFinished', onLevelFinished);
159
- commands.registerCommand('TaskTrackerSDK.taskFinished', onTaskFinished);
75
+ commands.registerCommand('TaskTrackerSDK.gamePlayEnded', onGamePlayEnded);
160
76
  commands.registerCommand('TaskTrackerSDK.levelUpgrade', onLevelUpgrade);
161
- commands.registerCommand('TaskTrackerSDK.historyUserLevel', onHistoryUserLevel);
162
- commands.registerCommand('TaskTrackerSDK.historyUserScore', onHistoryUserScore);
163
- commands.registerCommand('TaskTrackerSDK.taskEvent', onTaskEvent);
164
77
 
165
78
  registerCanIUse('TaskTrackerSDK.onLevelFinished', {
166
- version: '1.0.0',
79
+ version: '1.1.25',
167
80
  properties: {
168
- levelId: '1.0.0',
169
81
  params: {
170
- result: '1.0.0',
171
- duration: '1.0.0'
82
+ levelId: '1.1.25',
83
+ duration: '1.1.25',
84
+ rating: '1.1.25',
85
+ score: '1.1.25'
172
86
  }
173
87
  }
174
88
  });
175
89
 
176
- registerCanIUse('TaskTrackerSDK.onTaskFinished', {
177
- version: '1.0.0',
90
+ registerCanIUse('TaskTrackerSDK.onGamePlayEnded', {
91
+ version: '1.1.25',
178
92
  properties: {
179
- taskId: '1.0.0',
180
- duration: '1.0.0'
93
+ params: {
94
+ duration: '1.1.25',
95
+ rating: '1.1.25',
96
+ score: '1.1.25'
97
+ }
181
98
  }
182
99
  });
183
100
 
184
101
  registerCanIUse('TaskTrackerSDK.onLevelUpgrade', {
185
- version: '1.0.0',
186
- properties: {
187
- levelId: '1.0.0',
188
- name: '1.0.0'
189
- }
190
- });
191
-
192
- registerCanIUse('TaskTrackerSDK.onHistoryUserLevel', {
193
- version: '1.0.0',
194
- properties: {
195
- level: '1.0.0'
196
- }
197
- });
198
-
199
- registerCanIUse('TaskTrackerSDK.onHistoryUserScore', {
200
- version: '1.0.0',
201
- properties: {
202
- score: '1.0.0'
203
- }
204
- });
205
-
206
- registerCanIUse('TaskTrackerSDK.onTaskEvent', {
207
- version: '1.0.0',
102
+ version: '1.1.25',
208
103
  properties: {
209
- taskId: '1.0.0',
210
104
  params: {
211
- tools: {
212
- id: '1.0.0',
213
- name: '1.0.0',
214
- count: '1.0.0',
215
- description: '1.0.0',
216
- price: {
217
- amount: '1.0.0',
218
- unit: '1.0.0'
219
- }
220
- },
221
- awards: {
222
- id: '1.0.0',
223
- name: '1.0.0'
224
- }
105
+ levelId: '1.1.25',
106
+ name: '1.1.25'
225
107
  }
226
108
  }
227
109
  });
@@ -7,6 +7,7 @@ import { adEventEmitter } from '@/common/ads';
7
7
  import { openRetentionSchema } from '../ui/retention';
8
8
  import { innerFetch } from '../network';
9
9
  import { Env } from '@jolibox/types';
10
+ import { registerLanguageHandler } from '@jolibox/ui';
10
11
  import { createIframeModal, registerIframeModalToGlobal } from '../ui/modal-iframe';
11
12
  interface IBasicMetaConfig {
12
13
  canShowRecommended: boolean;
@@ -135,6 +136,7 @@ function addGameServiceReadyListener() {
135
136
 
136
137
  // 任务上报
137
138
  handleTaskTracker(loadDuration);
139
+ registerLanguageHandler(() => context.language);
138
140
  });
139
141
 
140
142
  onNative('onBeforeExit', ({ uuid }) => {
@@ -0,0 +1,5 @@
1
+ import { createPaymentHelper } from './payment-helper';
2
+ import { createJolicoinPaymentHandler } from './registers/joli-coin';
3
+
4
+ export const paymentHelper = createPaymentHelper();
5
+ paymentHelper.registerPaymentHandler('JOLI_COIN', createJolicoinPaymentHandler());
@@ -0,0 +1,44 @@
1
+ export type PaymentType = 'JOLI_COIN'; // current only jolicoin
2
+
3
+ import { StandardResponse } from '@jolibox/types';
4
+ import { reportError } from '@/common/report/errors/report';
5
+ import { BaseError } from '@jolibox/common';
6
+
7
+ type PaymentResult = StandardResponse<void>;
8
+
9
+ export interface PaymentHandlerMap {
10
+ JOLI_COIN: (productId: string) => Promise<PaymentResult>; // jolicoin
11
+ }
12
+
13
+ export type PaymentHandler<T extends PaymentType> = PaymentHandlerMap[T];
14
+
15
+ export function createPaymentHelper() {
16
+ const paymentHandlers = new Map<PaymentType, PaymentHandler<any>>();
17
+
18
+ return {
19
+ registerPaymentHandler<T extends PaymentType>(type: T, handler: PaymentHandler<T>) {
20
+ paymentHandlers.set(type, handler);
21
+ },
22
+ async invokePayment<T extends PaymentType>(type: T, ...args: Parameters<PaymentHandler<T>>) {
23
+ const paymentHandler = paymentHandlers.get(type);
24
+ if (!paymentHandler) {
25
+ return {
26
+ code: 'FAILED',
27
+ message: `[joliboxSDK]: ${type} payment not supported in this platform`
28
+ };
29
+ }
30
+ try {
31
+ const result = await paymentHandler(...args);
32
+ return result;
33
+ } catch (e) {
34
+ reportError(e as BaseError);
35
+ return {
36
+ code: 'FAILED',
37
+ message: `[joliboxSDK]: paymenterror ${e}`
38
+ };
39
+ }
40
+ }
41
+ };
42
+ }
43
+
44
+ export type PaymentHelper = ReturnType<typeof createPaymentHelper>;
@@ -0,0 +1,97 @@
1
+ import { StandardResponse } from '@jolibox/types';
2
+ import type { IPlaceOrderJoliCoinParamas, IJoliCoinProductInfo, IJolicoinPaymentContext } from './joli-coin';
3
+ import type { IPlaceOrderResponse } from './type';
4
+ import { PaymentErrorCodeMap } from './type';
5
+ type PaymentStatus = 'INIT' | 'PENDING' | 'SUCCESS' | 'FAILED';
6
+ import { UserPaymentError, InternalPaymentError } from '@jolibox/common';
7
+ import { context } from '@/common/context';
8
+ import { innerFetch as fetch } from '@/native/network';
9
+
10
+ type IPlaceOrderParams = IPlaceOrderJoliCoinParamas;
11
+ type IOrderProductInfo = IJoliCoinProductInfo;
12
+ type IOrderPaymentContext = IJolicoinPaymentContext;
13
+
14
+ const createPaymentErrorFactory = () => {
15
+ const [createPaymentError, createPaymentInternalError] = [UserPaymentError, InternalPaymentError].map(
16
+ (ctor) => {
17
+ return (errMsg: string, errNo: number, extra?: Record<string, unknown>) => {
18
+ return new ctor(errMsg, errNo, extra);
19
+ };
20
+ }
21
+ );
22
+ return {
23
+ createPaymentError,
24
+ createPaymentInternalError
25
+ };
26
+ };
27
+
28
+ const { createPaymentError, createPaymentInternalError } = createPaymentErrorFactory();
29
+ export { createPaymentError, createPaymentInternalError };
30
+
31
+ const CALLBACK_HOST = context.testMode ? 'https://stg-game.jolibox.com' : 'https://game.jolibox.com';
32
+
33
+ export abstract class BasePaymentRegister<T extends IPlaceOrderParams, E extends IOrderProductInfo> {
34
+ private _orderId: string | null = null;
35
+ private _orderStatus: PaymentStatus = 'INIT';
36
+
37
+ startPayment = async (params: T) => {
38
+ if (this._orderId) {
39
+ await this.cancelOrder(this.orderId as string);
40
+ }
41
+
42
+ const { data, code, message } = await this.placeOrder(params);
43
+ if (code !== 'SUCCESS' || !data || !data.orderId) {
44
+ throw createPaymentError(message, PaymentErrorCodeMap.PlaceOrderFailed);
45
+ }
46
+ if (data?.status !== 'PENDING') {
47
+ throw createPaymentInternalError(
48
+ `Place order failed, status: ${data?.status}`,
49
+ PaymentErrorCodeMap.PlaceOrderFailed
50
+ );
51
+ }
52
+
53
+ const { orderId } = data;
54
+ this._orderId = orderId;
55
+ // invoke native payment;
56
+
57
+ const callbackUrl = this.generateCallbackUrl();
58
+ // 回调页
59
+ };
60
+
61
+ cancelOrder = async (orderId: string) => {
62
+ const { response } = await fetch(`/api/orders/${orderId}/cancel`, {
63
+ method: 'POST',
64
+ data: {}
65
+ });
66
+ if (response.code !== 'SUCCCESS') {
67
+ throw createPaymentError(
68
+ response.message ?? response.errMsg ?? '',
69
+ PaymentErrorCodeMap.CancelOrderFailed
70
+ );
71
+ }
72
+ };
73
+
74
+ private generateCallbackUrl = () => {
75
+ // Set or replace gameId and joliSource parameters
76
+ const originalSearch = new URLSearchParams('');
77
+ originalSearch.set('utm_source', context.deviceInfo.platform);
78
+ originalSearch.set(
79
+ 'joliSource',
80
+ context.encodeJoliSourceQuery({
81
+ ...this.generatePaymentContext()
82
+ })
83
+ );
84
+ return `${CALLBACK_HOST}//payment/callback?${originalSearch.toString()}`;
85
+ };
86
+
87
+ abstract placeOrder(params: T): Promise<StandardResponse<IPlaceOrderResponse<E>>>;
88
+ abstract generatePaymentContext(): IOrderPaymentContext;
89
+
90
+ get orderId(): string | null {
91
+ return this._orderId;
92
+ }
93
+
94
+ get status(): PaymentStatus {
95
+ return this._orderStatus;
96
+ }
97
+ }
@@ -0,0 +1,83 @@
1
+ import { innerFetch as fetch } from '@/native/network';
2
+ import { BasePaymentRegister, createPaymentError, createPaymentInternalError } from './base';
3
+ import { PaymentErrorCodeMap, IPlaceOrderResponse } from './type';
4
+ import { ResponseType, StandardResponse } from '@jolibox/types';
5
+
6
+ export interface IPlaceOrderJoliCoinParamas {
7
+ productId: string;
8
+ }
9
+
10
+ export interface IJoliCoinProductInfo {
11
+ quantity: number;
12
+ }
13
+
14
+ export interface IJolicoinPaymentContext {
15
+ type: 'JOLI_COIN_ORDER_CONTEXT';
16
+ state: 'TO_CHECKOUT' | 'TO_VALIDATE';
17
+ productId: string;
18
+ orderId: string;
19
+ }
20
+
21
+ class JolicoinPaymentResiter extends BasePaymentRegister<IPlaceOrderJoliCoinParamas, IJoliCoinProductInfo> {
22
+ constructor(readonly productId: string) {
23
+ super();
24
+ }
25
+ async placeOrder(
26
+ params: IPlaceOrderJoliCoinParamas
27
+ ): Promise<StandardResponse<IPlaceOrderResponse<IJoliCoinProductInfo>, unknown>> {
28
+ try {
29
+ const { response } = await fetch<IPlaceOrderResponse<IJoliCoinProductInfo>>(
30
+ '/api/orders/checkout/joli-coin',
31
+ {
32
+ method: 'POST',
33
+ data: { productId: params.productId }
34
+ }
35
+ );
36
+
37
+ if (response.code !== 'SUCCESS') {
38
+ throw createPaymentError(
39
+ response.errMsg ?? response.message ?? '',
40
+ PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
41
+ );
42
+ }
43
+
44
+ return {
45
+ code: 'SUCCESS' as ResponseType,
46
+ message: response.message ?? 'placeorder jolicoin success',
47
+ data: response.data
48
+ };
49
+ } catch (e) {
50
+ console.info(`[JoliboxSDK] placeorder failed`, e);
51
+ throw createPaymentInternalError(
52
+ JSON.stringify(e) ?? 'jolicoin placeorder failed',
53
+ PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
54
+ );
55
+ }
56
+ }
57
+
58
+ generatePaymentContext = (): IJolicoinPaymentContext => {
59
+ return {
60
+ type: 'JOLI_COIN_ORDER_CONTEXT',
61
+ state: 'TO_VALIDATE',
62
+ productId: this.productId,
63
+ orderId: this.orderId!
64
+ };
65
+ };
66
+ }
67
+
68
+ export const createJolicoinPaymentHandler = () => {
69
+ const productPaymentMap = new Map<string, JolicoinPaymentResiter>();
70
+ return async (productId: string) => {
71
+ let instance = productPaymentMap.get(productId);
72
+ if (!instance) {
73
+ instance = new JolicoinPaymentResiter(productId);
74
+ productPaymentMap.set(productId, instance);
75
+ }
76
+
77
+ await instance.startPayment({ productId });
78
+ return {
79
+ code: 'SUCCESS' as ResponseType,
80
+ message: 'jolicoin payment success'
81
+ };
82
+ };
83
+ };
@@ -0,0 +1,15 @@
1
+ type OrderStatus = 'PENDING' | 'PAYING' | 'PAYMENT_FAILED' | 'PAYMENT_SUCCESS' | 'PAYMENT_CLOSED';
2
+
3
+ export interface IPlaceOrderResponse<T> {
4
+ orderId: string;
5
+ status: OrderStatus;
6
+ totalAmountStr: string;
7
+ joliBizType: 'DRAMA' | 'JOLI_COIN';
8
+ productInfo: T;
9
+ }
10
+
11
+ export enum PaymentErrorCodeMap {
12
+ PlaceOrderFailed = 1001,
13
+ JolicoinPlaceOrderRequestFailed = 1002,
14
+ CancelOrderFailed = 1003
15
+ }
@@ -19,7 +19,7 @@ type NativeTaskPointEvent =
19
19
  | 'HistoryUserLevel'
20
20
  | 'HistoryUserScore'
21
21
  | 'UseGameItem'
22
- | 'TaskEvent';
22
+ | 'GameTaskEvent';
23
23
 
24
24
  export type NativeTaskPoint = {
25
25
  event: NativeTaskPointEvent;
@@ -2,6 +2,16 @@ import { StandardResponse } from '@jolibox/types';
2
2
  import { getGlobalStorage, setGlobalStorage } from '../api/storage';
3
3
  import { filterTodayTimestamps } from './utils';
4
4
 
5
+ const parseFrequency = (data: string) => {
6
+ let fequeycies;
7
+ try {
8
+ fequeycies = JSON.parse(data);
9
+ } catch (e) {
10
+ fequeycies = [];
11
+ }
12
+ return fequeycies;
13
+ };
14
+
5
15
  /**
6
16
  * check can show useModal
7
17
  * @param config
@@ -9,11 +19,12 @@ import { filterTodayTimestamps } from './utils';
9
19
  */
10
20
  export const checkUseModalFrequency = async (config: { dailyMaxPopUps: number; minInterval: number }) => {
11
21
  const { dailyMaxPopUps, minInterval } = config;
12
- const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<number[]>;
22
+ const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<string>;
13
23
  if (!res.data) {
14
24
  return true;
15
25
  }
16
- const fequeycies = res.data;
26
+
27
+ const fequeycies = parseFrequency(res.data);
17
28
  const todayFequencies = filterTodayTimestamps(fequeycies);
18
29
  if (todayFequencies.length >= dailyMaxPopUps) {
19
30
  return false;
@@ -27,12 +38,13 @@ export const checkUseModalFrequency = async (config: { dailyMaxPopUps: number; m
27
38
 
28
39
  export const updateUseModalFrequency = async () => {
29
40
  const now = Date.now();
30
- const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<number[]>;
41
+ const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<string>;
31
42
 
32
- const fequeycies = res.data ?? [];
33
- fequeycies.push(now);
34
- fequeycies.sort((a, b) => b - a).splice(8);
35
- await setGlobalStorage('joli_coin_use_modal_frequency', fequeycies);
43
+ const frequencies = parseFrequency(res.data ?? '[]') as number[];
44
+ frequencies.push(now);
45
+ frequencies.sort((a, b) => b - a).splice(8);
46
+
47
+ await setGlobalStorage('joli_coin_use_modal_frequency', JSON.stringify(frequencies));
36
48
  };
37
49
 
38
50
  /**
@@ -40,13 +52,13 @@ export const updateUseModalFrequency = async () => {
40
52
  */
41
53
  export const checkPaymentFrequency = async (config: { dailyMaxPopUps: number; minInterval: number }) => {
42
54
  const { dailyMaxPopUps, minInterval } = config;
43
- const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<number[]>;
55
+ const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<string>;
44
56
 
45
57
  if (!res.data) {
46
58
  return true;
47
59
  }
48
- const fequeycies = res.data;
49
- const todayFequencies = filterTodayTimestamps(fequeycies);
60
+ const frequencies = parseFrequency(res.data);
61
+ const todayFequencies = filterTodayTimestamps(frequencies);
50
62
  if (todayFequencies.length >= dailyMaxPopUps) {
51
63
  return false;
52
64
  }
@@ -62,9 +74,10 @@ export const checkPaymentFrequency = async (config: { dailyMaxPopUps: number; mi
62
74
  */
63
75
  export const updatePaymentFrequency = async () => {
64
76
  const now = Date.now();
65
- const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<number[]>;
66
- const frequencies = res.data ?? [];
67
- frequencies.push(now);
68
- frequencies.sort((a, b) => b - a).splice(8);
69
- await setGlobalStorage('joli_coin_payment_frequency', frequencies);
77
+ const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<string>;
78
+ const fequeycies: number[] = parseFrequency(res.data ?? '[]');
79
+
80
+ fequeycies.push(now);
81
+ fequeycies.sort((a, b) => b - a).splice(8);
82
+ await setGlobalStorage('joli_coin_payment_frequency', JSON.stringify(fequeycies));
70
83
  };
@@ -27,6 +27,7 @@ import {
27
27
  checkPaymentFrequency,
28
28
  updatePaymentFrequency
29
29
  } from './check-frequency';
30
+ import { paymentHelper } from '../payment';
30
31
 
31
32
  const modalUseFrequencyConfig = createEventPromiseHandler<
32
33
  IUseModalFrequencyConfig,
@@ -153,14 +154,19 @@ rewardsEmitter.on(
153
154
  }
154
155
 
155
156
  const balenceDetails = await getBalenceDetails();
156
- if ((balenceDetails?.balance ?? 0) >= params.joliCoinQuantity && params.enableAutoDeduct) {
157
+ if ((balenceDetails?.balance ?? 0) >= params.joliCoinQuantity) {
157
158
  rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'SUCCESS' });
158
159
  modal.destroy();
159
160
  return;
160
161
  }
161
162
  }
162
163
  console.log('invokeNativePayment', productId);
163
-
164
+ const { code } = await paymentHelper.invokePayment('JOLI_COIN', productId);
165
+ if (code !== 'SUCCESS') {
166
+ rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'FAILED' });
167
+ modal.destroy();
168
+ return;
169
+ }
164
170
  rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'SUCCESS' });
165
171
  modal.destroy();
166
172
  }