@jolibox/implement 1.1.29 → 1.1.31
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/.rush/temp/package-deps_build.json +22 -20
- package/dist/common/context/index.d.ts +6 -0
- package/dist/common/rewards/reward-emitter.d.ts +2 -1
- package/dist/index.js +9 -9
- package/dist/index.native.js +154 -111
- package/dist/native/api/base.d.ts +1 -0
- package/dist/native/payment/payment-helper.d.ts +5 -1
- package/dist/native/payment/registers/base.d.ts +8 -6
- package/dist/native/payment/registers/const.d.ts +3 -0
- package/dist/native/payment/registers/jolicoin-iap.d.ts +21 -0
- package/implement.build.log +2 -2
- package/package.json +5 -5
- package/src/common/context/index.ts +21 -2
- package/src/common/rewards/registers/use-ads.ts +1 -0
- package/src/common/rewards/registers/use-jolicoin-only.ts +1 -0
- package/src/common/rewards/registers/utils/coins/index.ts +0 -1
- package/src/common/rewards/reward-emitter.ts +2 -1
- package/src/native/api/base.ts +4 -0
- package/src/native/api/lifecycle.ts +3 -0
- package/src/native/api/login.ts +5 -5
- package/src/native/api/navigate.ts +4 -1
- package/src/native/api/request.ts +3 -3
- package/src/native/bootstrap/init-env.ts +10 -0
- package/src/native/network/create-fetch.ts +0 -18
- package/src/native/payment/index.ts +2 -0
- package/src/native/payment/payment-helper.ts +2 -1
- package/src/native/payment/registers/base.ts +15 -19
- package/src/native/payment/registers/const.ts +14 -0
- package/src/native/payment/registers/joli-coin.ts +10 -0
- package/src/native/payment/registers/jolicoin-iap.ts +220 -0
- package/src/native/rewards/check-frequency.ts +2 -1
- package/src/native/rewards/index.ts +86 -8
- package/src/native/ui/retention.ts +2 -2
|
@@ -0,0 +1,220 @@
|
|
|
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
|
+
import { applyNative, onNative } from '@jolibox/native-bridge';
|
|
6
|
+
import { Deferred, isNumber, platform } from '@jolibox/common';
|
|
7
|
+
import { context } from '@/common/context';
|
|
8
|
+
import { createToast } from '@jolibox/ui';
|
|
9
|
+
import { IPaymentIAPFailedStatusMap } from './const';
|
|
10
|
+
|
|
11
|
+
export interface IPlaceOrderJoliCoinIAPParamas {
|
|
12
|
+
productId: string;
|
|
13
|
+
appStoreProductId: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface IJoliCoinProductInfo {
|
|
17
|
+
quantity: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface IJolicoinPaymentIAPResponse {
|
|
21
|
+
totalAmount: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IJolicoinPaymentIAPContext {
|
|
25
|
+
type: 'JOLI_COIN_IAP_CONTEXT';
|
|
26
|
+
state: 'TO_CHECKOUT' | 'TO_VALIDATE';
|
|
27
|
+
productId: string;
|
|
28
|
+
appStoreProductId: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const pendingPayments = new Map<string, Deferred<StandardResponse<{ totalAmount: string }>>>();
|
|
32
|
+
|
|
33
|
+
onNative('onPaymentStateChange', (data) => {
|
|
34
|
+
console.info('onPaymentStateChange', data);
|
|
35
|
+
const { orderUUID, status, totalAmount, orderResponse } = data;
|
|
36
|
+
|
|
37
|
+
const deferred = pendingPayments.get(orderUUID);
|
|
38
|
+
if (!deferred) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (status === 'SUCCESS') {
|
|
43
|
+
createToast(`{slot-success} {slot-i18n-jolicoin.unlockSuccess}`, {
|
|
44
|
+
position: 'center',
|
|
45
|
+
duration: 3000
|
|
46
|
+
});
|
|
47
|
+
deferred.resolve({
|
|
48
|
+
code: 'SUCCESS' as ResponseType,
|
|
49
|
+
message: 'jolicoin payment success',
|
|
50
|
+
data: { totalAmount }
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
if (status === 'FAILED') {
|
|
54
|
+
if (isNumber(orderResponse?.errNo) && orderResponse?.errNo !== 0) {
|
|
55
|
+
throw createPaymentInternalError(
|
|
56
|
+
`jolicoin payment failed: ${orderResponse?.errMsg}`,
|
|
57
|
+
PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const failedStatus = IPaymentIAPFailedStatusMap[status] ?? 'unlockFailed';
|
|
62
|
+
createToast(`{slot-error} {slot-i18n-jolicoin.${failedStatus}}`, {
|
|
63
|
+
position: 'center',
|
|
64
|
+
duration: 3000
|
|
65
|
+
});
|
|
66
|
+
deferred.resolve({
|
|
67
|
+
code: 'FAILED' as ResponseType,
|
|
68
|
+
message: 'jolicoin payment failed'
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Clean up map
|
|
73
|
+
pendingPayments.delete(orderUUID);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const payInApp = async (params: { appStoreProductId: string; appAccountToken?: string }) => {
|
|
77
|
+
const deferred = new Deferred<StandardResponse<{ totalAmount: string }>>();
|
|
78
|
+
let targetOrderUUID: string | undefined;
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const response = await applyNative('requestPaymentSync', {
|
|
82
|
+
paymentBody: {
|
|
83
|
+
appStoreProductId: params.appStoreProductId,
|
|
84
|
+
appAccountToken: params.appAccountToken
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
targetOrderUUID = response.data?.orderUUID;
|
|
88
|
+
|
|
89
|
+
console.info('---payInApp---', response);
|
|
90
|
+
if (!targetOrderUUID) {
|
|
91
|
+
throw createPaymentInternalError(
|
|
92
|
+
'orderUUID is null',
|
|
93
|
+
PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
pendingPayments.set(targetOrderUUID, deferred);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
throw createPaymentInternalError(
|
|
100
|
+
JSON.stringify(e) ?? 'jolicoin payment failed',
|
|
101
|
+
PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return deferred.promise;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
class JolicoinIAPAndroidPaymentResiter extends BasePaymentRegister<
|
|
109
|
+
IPlaceOrderJoliCoinIAPParamas,
|
|
110
|
+
IJoliCoinProductInfo,
|
|
111
|
+
IJolicoinPaymentIAPResponse
|
|
112
|
+
> {
|
|
113
|
+
constructor(readonly productId: string, readonly appStoreProductId: string) {
|
|
114
|
+
super();
|
|
115
|
+
}
|
|
116
|
+
async placeOrder(
|
|
117
|
+
params: IPlaceOrderJoliCoinIAPParamas
|
|
118
|
+
): Promise<StandardResponse<IPlaceOrderResponse<IJoliCoinProductInfo>, unknown>> {
|
|
119
|
+
return {
|
|
120
|
+
code: 'SUCCESS' as ResponseType,
|
|
121
|
+
message: 'placeorder jolicoin success in native'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
generatePaymentContext = (): IJolicoinPaymentIAPContext => {
|
|
126
|
+
return {
|
|
127
|
+
type: 'JOLI_COIN_IAP_CONTEXT',
|
|
128
|
+
state: 'TO_VALIDATE',
|
|
129
|
+
productId: this.productId,
|
|
130
|
+
appStoreProductId: this.appStoreProductId
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
pay = async (): Promise<StandardResponse<{ totalAmount: string }>> => {
|
|
135
|
+
return await payInApp({ appStoreProductId: this.appStoreProductId });
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class JolicoinIAPIOSPaymentResiter extends BasePaymentRegister<
|
|
140
|
+
IPlaceOrderJoliCoinIAPParamas,
|
|
141
|
+
IJoliCoinProductInfo,
|
|
142
|
+
IJolicoinPaymentIAPResponse
|
|
143
|
+
> {
|
|
144
|
+
private appAccountToken: string | undefined;
|
|
145
|
+
constructor(readonly productId: string, readonly appStoreProductId: string) {
|
|
146
|
+
super();
|
|
147
|
+
}
|
|
148
|
+
async placeOrder(
|
|
149
|
+
params: IPlaceOrderJoliCoinIAPParamas
|
|
150
|
+
): Promise<StandardResponse<IPlaceOrderResponse<IJoliCoinProductInfo>, unknown>> {
|
|
151
|
+
console.log('----start place order for ios----');
|
|
152
|
+
const { response } = await fetch<StandardResponse<{ iapToken: string }>>('/api/orders/iap-init', {
|
|
153
|
+
method: 'GET',
|
|
154
|
+
appendHostCookie: true
|
|
155
|
+
});
|
|
156
|
+
const { data, code } = response ?? {};
|
|
157
|
+
console.log('----iap init----', data, code);
|
|
158
|
+
if (data.code !== 'SUCCESS') {
|
|
159
|
+
throw createPaymentInternalError(
|
|
160
|
+
'iap-init failed',
|
|
161
|
+
PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
this.appAccountToken = data?.data?.iapToken;
|
|
165
|
+
return {
|
|
166
|
+
code: 'SUCCESS' as ResponseType,
|
|
167
|
+
message: 'placeorder jolicoin success in native'
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
generatePaymentContext = (): IJolicoinPaymentIAPContext => {
|
|
172
|
+
return {
|
|
173
|
+
type: 'JOLI_COIN_IAP_CONTEXT',
|
|
174
|
+
state: 'TO_VALIDATE',
|
|
175
|
+
productId: this.productId,
|
|
176
|
+
appStoreProductId: this.appStoreProductId
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
pay = async (): Promise<StandardResponse<{ totalAmount: string }>> => {
|
|
181
|
+
return await payInApp({
|
|
182
|
+
appStoreProductId: this.appStoreProductId,
|
|
183
|
+
appAccountToken: this.appAccountToken
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const IAPPaymentRegisterMap = {
|
|
189
|
+
android: JolicoinIAPAndroidPaymentResiter,
|
|
190
|
+
ios: JolicoinIAPIOSPaymentResiter
|
|
191
|
+
} as const;
|
|
192
|
+
|
|
193
|
+
type JolicoinIAPPaymentResiter = JolicoinIAPAndroidPaymentResiter | JolicoinIAPIOSPaymentResiter;
|
|
194
|
+
export const createJolicoinIAPPaymentHandler = () => {
|
|
195
|
+
const productPaymentMap = new Map<string, JolicoinIAPPaymentResiter>();
|
|
196
|
+
return async (params: { productId: string; appStoreProductId: string }) => {
|
|
197
|
+
const { productId, appStoreProductId } = params;
|
|
198
|
+
let instance = productPaymentMap.get(productId);
|
|
199
|
+
if (!instance) {
|
|
200
|
+
const Register = IAPPaymentRegisterMap[context.platform as keyof typeof IAPPaymentRegisterMap];
|
|
201
|
+
if (!Register) {
|
|
202
|
+
throw createPaymentInternalError(
|
|
203
|
+
'platform not supported',
|
|
204
|
+
PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
instance = new Register(productId, appStoreProductId);
|
|
208
|
+
productPaymentMap.set(productId, instance);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const { code, message } = await instance.startPayment({ productId, appStoreProductId });
|
|
212
|
+
if (code !== 'SUCCESS') {
|
|
213
|
+
throw createPaymentError(message, PaymentErrorCodeMap.JolicoinPlaceOrderRequestFailed);
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
code: 'SUCCESS' as ResponseType,
|
|
217
|
+
message: 'jolicoin payment success'
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
};
|
|
@@ -20,6 +20,7 @@ const parseFrequency = (data: string) => {
|
|
|
20
20
|
export const checkUseModalFrequency = async (config: { dailyMaxPopUps: number; minInterval: number }) => {
|
|
21
21
|
const { dailyMaxPopUps, minInterval } = config;
|
|
22
22
|
const res = (await getGlobalStorage('joli_coin_use_modal_frequency')) as StandardResponse<string>;
|
|
23
|
+
console.log('checkUseModalFrequency', res.data);
|
|
23
24
|
if (!res.data) {
|
|
24
25
|
return true;
|
|
25
26
|
}
|
|
@@ -53,7 +54,7 @@ export const updateUseModalFrequency = async () => {
|
|
|
53
54
|
export const checkPaymentFrequency = async (config: { dailyMaxPopUps: number; minInterval: number }) => {
|
|
54
55
|
const { dailyMaxPopUps, minInterval } = config;
|
|
55
56
|
const res = (await getGlobalStorage('joli_coin_payment_frequency')) as StandardResponse<string>;
|
|
56
|
-
|
|
57
|
+
console.log('checkPaymentFrequency', res.data);
|
|
57
58
|
if (!res.data) {
|
|
58
59
|
return true;
|
|
59
60
|
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
UseModalFrequencyEventName,
|
|
15
15
|
IUseModalFrequencyConfig
|
|
16
16
|
} from '@/common/rewards/reward-emitter';
|
|
17
|
-
import { createConfirmJolicoinModal, createPaymentJolicoinModal } from '@jolibox/ui';
|
|
17
|
+
import { createConfirmJolicoinModal, createPaymentJolicoinModal, createToast } from '@jolibox/ui';
|
|
18
18
|
import { innerFetch as fetch } from '../network';
|
|
19
19
|
import { StandardResponse } from '@jolibox/types';
|
|
20
20
|
import { context } from '@/common/context';
|
|
@@ -28,6 +28,10 @@ import {
|
|
|
28
28
|
updatePaymentFrequency
|
|
29
29
|
} from './check-frequency';
|
|
30
30
|
import { paymentHelper } from '../payment';
|
|
31
|
+
import { createLoading } from '@jolibox/ui';
|
|
32
|
+
import { canIUseNative } from '../api/base';
|
|
33
|
+
import { applyNative } from '@jolibox/native-bridge';
|
|
34
|
+
import { isUndefinedOrNull } from '@jolibox/common';
|
|
31
35
|
|
|
32
36
|
const modalUseFrequencyConfig = createEventPromiseHandler<
|
|
33
37
|
IUseModalFrequencyConfig,
|
|
@@ -36,6 +40,8 @@ const modalUseFrequencyConfig = createEventPromiseHandler<
|
|
|
36
40
|
|
|
37
41
|
modalUseFrequencyConfig.getData();
|
|
38
42
|
|
|
43
|
+
const loading = createLoading();
|
|
44
|
+
|
|
39
45
|
/**
|
|
40
46
|
* update config
|
|
41
47
|
*/
|
|
@@ -67,9 +73,13 @@ const updateAutoDeductConfig = async (enabled: boolean): Promise<void> => {
|
|
|
67
73
|
rewardsEmitter.on(UseModalEventName, async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN', params: IUseModalEvent) => {
|
|
68
74
|
if (type === 'ADS-JOLI_COIN') {
|
|
69
75
|
//TODO
|
|
70
|
-
|
|
76
|
+
await loading.show({
|
|
77
|
+
duration: 3000
|
|
78
|
+
});
|
|
71
79
|
const config = await modalUseFrequencyConfig.getData();
|
|
72
80
|
const canShowUseModal = await checkUseModalFrequency(config.joliCoinUseAndCharge.useJolicoin);
|
|
81
|
+
console.log('use modal show by frequency', canShowUseModal);
|
|
82
|
+
loading.hide();
|
|
73
83
|
if (!canShowUseModal) {
|
|
74
84
|
// return by frequency control
|
|
75
85
|
rewardsEmitter.emit(UseModalResultEventName, { useModalResult: 'CONFIRM' });
|
|
@@ -115,11 +125,24 @@ rewardsEmitter.on(
|
|
|
115
125
|
InvokePaymentEventName,
|
|
116
126
|
async (type: 'JOLI_COIN' | 'ADS-JOLI_COIN', params: IInvokePaymentEvent) => {
|
|
117
127
|
try {
|
|
128
|
+
// TODO: temp remove it for dev
|
|
129
|
+
if (!canIUseNative('requestPaymentSync:paymentBody:appStoreProductId')) {
|
|
130
|
+
//TODO: show Toast
|
|
131
|
+
console.info('requestPaymentSync:paymentBody:appStoreProductId not supported');
|
|
132
|
+
setTimeout(() => {
|
|
133
|
+
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'FAILED' });
|
|
134
|
+
}, 0);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
118
137
|
// handle showup frequecy
|
|
119
138
|
if (type === 'ADS-JOLI_COIN') {
|
|
120
|
-
|
|
139
|
+
await loading.show({
|
|
140
|
+
duration: 3000
|
|
141
|
+
});
|
|
121
142
|
const config = await modalUseFrequencyConfig.getData();
|
|
122
143
|
const canShowPaymentModal = await checkPaymentFrequency(config.joliCoinUseAndCharge.charge);
|
|
144
|
+
console.log('use payment show by frequency', canShowPaymentModal);
|
|
145
|
+
loading.hide();
|
|
123
146
|
if (!canShowPaymentModal) {
|
|
124
147
|
// return by frequency control
|
|
125
148
|
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'SUCCESS' });
|
|
@@ -128,7 +151,15 @@ rewardsEmitter.on(
|
|
|
128
151
|
console.log('show by frequency');
|
|
129
152
|
}
|
|
130
153
|
|
|
154
|
+
/**
|
|
155
|
+
* TODO: need merge totalAmountStr from native
|
|
156
|
+
*/
|
|
157
|
+
await loading.show({
|
|
158
|
+
duration: 3000
|
|
159
|
+
});
|
|
131
160
|
const balenceDetails = await getBalenceDetails();
|
|
161
|
+
loading.hide();
|
|
162
|
+
|
|
132
163
|
if (!balenceDetails) {
|
|
133
164
|
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'FAILED' });
|
|
134
165
|
return;
|
|
@@ -137,15 +168,17 @@ rewardsEmitter.on(
|
|
|
137
168
|
data: {
|
|
138
169
|
userJolicoin: params.userJoliCoin,
|
|
139
170
|
joliCoinQuantity: params.joliCoinQuantity,
|
|
140
|
-
paymentChoices:
|
|
171
|
+
paymentChoices:
|
|
172
|
+
balenceDetails.paymentChoices?.map((choice) => ({
|
|
173
|
+
...choice,
|
|
174
|
+
totalAmountStr: choice.totalAmountStr ?? ''
|
|
175
|
+
})) ?? [],
|
|
141
176
|
enableAutoDeduct: balenceDetails.enableAutoDeduct
|
|
142
177
|
},
|
|
143
178
|
buttons: {
|
|
144
179
|
confirm: {
|
|
145
180
|
text: params.confirmButtonText,
|
|
146
181
|
onPress: async (productId: string) => {
|
|
147
|
-
// TODO: native payment
|
|
148
|
-
// await invokeNativePayment(productId);
|
|
149
182
|
if (!context.hostUserInfo?.isLogin) {
|
|
150
183
|
const { data } = await login();
|
|
151
184
|
if (!data?.isLogin) {
|
|
@@ -161,12 +194,28 @@ rewardsEmitter.on(
|
|
|
161
194
|
}
|
|
162
195
|
}
|
|
163
196
|
console.log('invokeNativePayment', productId);
|
|
164
|
-
const
|
|
165
|
-
|
|
197
|
+
const appStoreProductId = balenceDetails?.paymentChoices?.find(
|
|
198
|
+
(choice) => choice.productId === productId
|
|
199
|
+
)?.appStoreProductId;
|
|
200
|
+
|
|
201
|
+
if (!appStoreProductId) {
|
|
166
202
|
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'FAILED' });
|
|
167
203
|
modal.destroy();
|
|
168
204
|
return;
|
|
169
205
|
}
|
|
206
|
+
await loading.show({
|
|
207
|
+
duration: 3000
|
|
208
|
+
});
|
|
209
|
+
const { code } = await paymentHelper.invokePayment('JOLI_COIN_IAP', {
|
|
210
|
+
productId,
|
|
211
|
+
appStoreProductId
|
|
212
|
+
});
|
|
213
|
+
loading.hide();
|
|
214
|
+
if (code !== 'SUCCESS') {
|
|
215
|
+
/** add timeout for google panel closed */
|
|
216
|
+
console.info('[JoliboxSDK] payment failed in payment.invokePaymet');
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
170
219
|
rewardsEmitter.emit(PaymentResultEventName, { paymentResult: 'SUCCESS' });
|
|
171
220
|
modal.destroy();
|
|
172
221
|
}
|
|
@@ -194,6 +243,23 @@ rewardsEmitter.on(
|
|
|
194
243
|
}
|
|
195
244
|
);
|
|
196
245
|
|
|
246
|
+
const mergeResponseData = (
|
|
247
|
+
responseData: { paymentChoices: IPaymentChoice[] },
|
|
248
|
+
data: { [appStoreProductId: string]: { price: string } }
|
|
249
|
+
) => {
|
|
250
|
+
Object.keys(data).forEach((key) => {
|
|
251
|
+
const choice = responseData.paymentChoices.find((choice) => choice.appStoreProductId === key);
|
|
252
|
+
if (choice) {
|
|
253
|
+
choice.totalAmountStr = data[key].price;
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
responseData.paymentChoices = responseData.paymentChoices.filter(
|
|
258
|
+
(choice) => !isUndefinedOrNull(choice.totalAmountStr)
|
|
259
|
+
) as IPaymentChoice[];
|
|
260
|
+
console.info('----mergeResponseData-----', responseData.paymentChoices);
|
|
261
|
+
};
|
|
262
|
+
|
|
197
263
|
const getBalenceDetails = async (): Promise<
|
|
198
264
|
| {
|
|
199
265
|
balance: number;
|
|
@@ -214,5 +280,17 @@ const getBalenceDetails = async (): Promise<
|
|
|
214
280
|
responseType: 'json'
|
|
215
281
|
});
|
|
216
282
|
|
|
283
|
+
console.info('getBalenceDetails', response);
|
|
284
|
+
const { data } = await applyNative('requestProductDetailsAsync', {
|
|
285
|
+
appStoreProductIds:
|
|
286
|
+
response.data?.data?.paymentChoices
|
|
287
|
+
?.filter((choice) => typeof choice.appStoreProductId === 'string')
|
|
288
|
+
.map((choice) => choice.appStoreProductId as string) ?? []
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
if (response.data?.data && data) {
|
|
292
|
+
mergeResponseData(response.data?.data, data);
|
|
293
|
+
}
|
|
294
|
+
console.info('productDetails', response.data?.data);
|
|
217
295
|
return response.data?.data;
|
|
218
296
|
};
|
|
@@ -108,7 +108,7 @@ export async function openRetentionSchema() {
|
|
|
108
108
|
break;
|
|
109
109
|
case 'dismiss':
|
|
110
110
|
quitResultDeffer.resolve(true);
|
|
111
|
-
modal.
|
|
111
|
+
modal.destroy();
|
|
112
112
|
break;
|
|
113
113
|
case 'navigate':
|
|
114
114
|
// TODO: 跳转游戏
|
|
@@ -121,7 +121,7 @@ export async function openRetentionSchema() {
|
|
|
121
121
|
} else {
|
|
122
122
|
quitResultDeffer.resolve(true);
|
|
123
123
|
}
|
|
124
|
-
modal.
|
|
124
|
+
modal.destroy();
|
|
125
125
|
break;
|
|
126
126
|
default:
|
|
127
127
|
// 关闭弹框,留在当前游戏
|