@jolibox/implement 1.1.29-beta.1 → 1.1.30
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 +21 -19
- 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/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 +92 -14
- package/src/native/ui/retention.ts +2 -2
|
@@ -11,3 +11,4 @@ export declare const createAPI: <ParamsSchema extends import("@/common/api-facto
|
|
|
11
11
|
export declare const registerCanIUse: (name: string, config: import("@jolibox/common").CanIUseInfo) => void;
|
|
12
12
|
import { t } from '@/common/api-factory/validator';
|
|
13
13
|
export { t };
|
|
14
|
+
export declare const canIUseNative: (schema: string) => boolean;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
export type PaymentType = 'JOLI_COIN';
|
|
1
|
+
export type PaymentType = 'JOLI_COIN' | 'JOLI_COIN_IAP';
|
|
2
2
|
import { StandardResponse } from '@jolibox/types';
|
|
3
3
|
type PaymentResult = StandardResponse<void>;
|
|
4
4
|
export interface PaymentHandlerMap {
|
|
5
5
|
JOLI_COIN: (productId: string) => Promise<PaymentResult>;
|
|
6
|
+
JOLI_COIN_IAP: (params: {
|
|
7
|
+
productId: string;
|
|
8
|
+
appStoreProductId: string;
|
|
9
|
+
}) => Promise<PaymentResult>;
|
|
6
10
|
}
|
|
7
11
|
export type PaymentHandler<T extends PaymentType> = PaymentHandlerMap[T];
|
|
8
12
|
export declare function createPaymentHelper(): {
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { StandardResponse } from '@jolibox/types';
|
|
2
2
|
import type { IPlaceOrderJoliCoinParamas, IJoliCoinProductInfo, IJolicoinPaymentContext } from './joli-coin';
|
|
3
|
+
import type { IPlaceOrderJoliCoinIAPParamas, IJolicoinPaymentIAPContext } from './jolicoin-iap';
|
|
3
4
|
import type { IPlaceOrderResponse } from './type';
|
|
4
5
|
type PaymentStatus = 'INIT' | 'PENDING' | 'SUCCESS' | 'FAILED';
|
|
5
6
|
import { UserPaymentError, InternalPaymentError } from '@jolibox/common';
|
|
6
|
-
type IPlaceOrderParams = IPlaceOrderJoliCoinParamas;
|
|
7
|
-
type IOrderProductInfo = IJoliCoinProductInfo;
|
|
8
|
-
type IOrderPaymentContext = IJolicoinPaymentContext;
|
|
7
|
+
type IPlaceOrderParams = IPlaceOrderJoliCoinParamas | IPlaceOrderJoliCoinIAPParamas;
|
|
8
|
+
type IOrderProductInfo = IJoliCoinProductInfo | IJolicoinPaymentIAPContext;
|
|
9
|
+
type IOrderPaymentContext = IJolicoinPaymentContext | IJolicoinPaymentIAPContext;
|
|
9
10
|
declare const createPaymentError: (errMsg: string, errNo: number, extra?: Record<string, unknown>) => UserPaymentError | InternalPaymentError, createPaymentInternalError: (errMsg: string, errNo: number, extra?: Record<string, unknown>) => UserPaymentError | InternalPaymentError;
|
|
10
11
|
export { createPaymentError, createPaymentInternalError };
|
|
11
|
-
export declare abstract class BasePaymentRegister<T extends IPlaceOrderParams, E extends IOrderProductInfo> {
|
|
12
|
+
export declare abstract class BasePaymentRegister<T extends IPlaceOrderParams, E extends IOrderProductInfo, R = void> {
|
|
12
13
|
private _orderId;
|
|
13
14
|
private _orderStatus;
|
|
14
|
-
startPayment: (params: T) => Promise<
|
|
15
|
+
startPayment: (params: T) => Promise<StandardResponse<R>>;
|
|
15
16
|
cancelOrder: (orderId: string) => Promise<void>;
|
|
16
|
-
|
|
17
|
+
protected generateCallbackUrl: () => string;
|
|
17
18
|
abstract placeOrder(params: T): Promise<StandardResponse<IPlaceOrderResponse<E>>>;
|
|
18
19
|
abstract generatePaymentContext(): IOrderPaymentContext;
|
|
20
|
+
abstract pay(): Promise<StandardResponse<R>>;
|
|
19
21
|
get orderId(): string | null;
|
|
20
22
|
get status(): PaymentStatus;
|
|
21
23
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ResponseType } from '@jolibox/types';
|
|
2
|
+
export interface IPlaceOrderJoliCoinIAPParamas {
|
|
3
|
+
productId: string;
|
|
4
|
+
appStoreProductId: string;
|
|
5
|
+
}
|
|
6
|
+
export interface IJoliCoinProductInfo {
|
|
7
|
+
quantity: number;
|
|
8
|
+
}
|
|
9
|
+
export interface IJolicoinPaymentIAPContext {
|
|
10
|
+
type: 'JOLI_COIN_IAP_CONTEXT';
|
|
11
|
+
state: 'TO_CHECKOUT' | 'TO_VALIDATE';
|
|
12
|
+
productId: string;
|
|
13
|
+
appStoreProductId: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const createJolicoinIAPPaymentHandler: () => (params: {
|
|
16
|
+
productId: string;
|
|
17
|
+
appStoreProductId: string;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
code: ResponseType;
|
|
20
|
+
message: string;
|
|
21
|
+
}>;
|
package/implement.build.log
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Invoking: npm run clean && npm run build:esm && tsc
|
|
2
2
|
|
|
3
|
-
> @jolibox/implement@1.1.
|
|
3
|
+
> @jolibox/implement@1.1.30 clean
|
|
4
4
|
> rimraf ./dist
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
> @jolibox/implement@1.1.
|
|
7
|
+
> @jolibox/implement@1.1.30 build:esm
|
|
8
8
|
> BUILD_VERSION=$(node -p "require('./package.json').version") node esbuild.config.js --format=esm
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jolibox/implement",
|
|
3
3
|
"description": "This project is Jolibox JS-SDk implement for Native && H5",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.30",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@jolibox/common": "1.1.
|
|
10
|
-
"@jolibox/types": "1.1.
|
|
11
|
-
"@jolibox/native-bridge": "1.1.
|
|
12
|
-
"@jolibox/ads": "1.1.
|
|
9
|
+
"@jolibox/common": "1.1.30",
|
|
10
|
+
"@jolibox/types": "1.1.30",
|
|
11
|
+
"@jolibox/native-bridge": "1.1.30",
|
|
12
|
+
"@jolibox/ads": "1.1.30",
|
|
13
13
|
"localforage": "1.10.0",
|
|
14
14
|
"@jolibox/ui": "1.0.0",
|
|
15
15
|
"web-vitals": "4.2.4"
|
|
@@ -42,6 +42,11 @@ export enum SDKEnvironment {
|
|
|
42
42
|
funmax = 'funmax' // 小米
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
type Viewport = {
|
|
46
|
+
statusBarHeight: number;
|
|
47
|
+
navigationBarHeight: number;
|
|
48
|
+
};
|
|
49
|
+
|
|
45
50
|
function hasMetaTag(name: string, content: string): boolean {
|
|
46
51
|
const metaTag = document?.head.querySelector(`meta[name="${name}"][content="${content}"]`);
|
|
47
52
|
return metaTag !== null;
|
|
@@ -65,6 +70,9 @@ const wrapContext = () => {
|
|
|
65
70
|
const testMode = joliboxEnv === 'staging';
|
|
66
71
|
const channel = headerJson?.channel;
|
|
67
72
|
|
|
73
|
+
// default should show stay recommend panel
|
|
74
|
+
let shouldInterupt = payloadJson?.__shouldInterupt;
|
|
75
|
+
|
|
68
76
|
return {
|
|
69
77
|
get testMode(): boolean {
|
|
70
78
|
return testMode; // TODO: true test mode
|
|
@@ -112,7 +120,7 @@ const wrapContext = () => {
|
|
|
112
120
|
return env.webviewId ?? -1;
|
|
113
121
|
},
|
|
114
122
|
get shouldInterupt(): boolean | undefined {
|
|
115
|
-
return
|
|
123
|
+
return shouldInterupt;
|
|
116
124
|
},
|
|
117
125
|
get from(): number | undefined {
|
|
118
126
|
return payloadJson?.__from;
|
|
@@ -133,7 +141,15 @@ const wrapContext = () => {
|
|
|
133
141
|
}
|
|
134
142
|
return SDKEnvironment.jolibox;
|
|
135
143
|
},
|
|
136
|
-
|
|
144
|
+
get viewport(): Viewport {
|
|
145
|
+
const pixelRatio = env.deviceInfo.pixelRatio ?? 1;
|
|
146
|
+
const rawStatusHeight = env.deviceInfo.statusBarHeight ?? payloadJson?.__androidStatusBarHeight;
|
|
147
|
+
const rawNavHeight = env.deviceInfo.navigationBarHeight ?? payloadJson?.__androidNavigationBarHeight;
|
|
148
|
+
return {
|
|
149
|
+
statusBarHeight: rawStatusHeight !== undefined ? rawStatusHeight / pixelRatio : 20,
|
|
150
|
+
navigationBarHeight: rawNavHeight !== undefined ? rawNavHeight / pixelRatio : 10
|
|
151
|
+
};
|
|
152
|
+
},
|
|
137
153
|
onEnvConfigChanged: (newConfig: Partial<Env>) => {
|
|
138
154
|
mergeWith(env, newConfig, mergeArray);
|
|
139
155
|
},
|
|
@@ -145,6 +161,9 @@ const wrapContext = () => {
|
|
|
145
161
|
);
|
|
146
162
|
}
|
|
147
163
|
return urlParams.get('joliSource') ?? '';
|
|
164
|
+
},
|
|
165
|
+
setDoExitDirectly: () => {
|
|
166
|
+
shouldInterupt = false;
|
|
148
167
|
}
|
|
149
168
|
};
|
|
150
169
|
};
|
|
@@ -4,6 +4,7 @@ import { JoliboxAdsForGame } from '@jolibox/ads';
|
|
|
4
4
|
export type AdsRewardsHandler = (params: IRewardParams) => Promise<boolean>;
|
|
5
5
|
export const createAdsRewardHandler = (ads: JoliboxAdsForGame): AdsRewardsHandler => {
|
|
6
6
|
return async (params: IRewardParams) => {
|
|
7
|
+
console.log('trigger @jolibox/ads reward', params);
|
|
7
8
|
ads.adBreak(params);
|
|
8
9
|
return true;
|
|
9
10
|
};
|
package/src/native/api/base.ts
CHANGED
|
@@ -5,4 +5,8 @@ export const { createAPI, createSyncAPI } = createAPIFactory(track);
|
|
|
5
5
|
|
|
6
6
|
export const registerCanIUse = registerCanIUseFactory('native');
|
|
7
7
|
import { t } from '@/common/api-factory/validator';
|
|
8
|
+
import { registerCanIUseContext } from '@jolibox/native-bridge';
|
|
9
|
+
import { context } from '@/common/context';
|
|
8
10
|
export { t };
|
|
11
|
+
|
|
12
|
+
export const { canIUseNative } = registerCanIUseContext(() => context.sdkInfo.nativeSDKVersionCode);
|
package/src/native/api/login.ts
CHANGED
|
@@ -31,11 +31,6 @@ export const login = createAPI('login', {
|
|
|
31
31
|
if (isLogin) {
|
|
32
32
|
return { isLogin: true, token: context.hostUserInfo?.token };
|
|
33
33
|
}
|
|
34
|
-
onNative('onLoginStateChange', ({ isLogin, token, uuid }) => {
|
|
35
|
-
if (uuid == loginUUID) {
|
|
36
|
-
resolve({ isLogin, token });
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
34
|
const res = invokeNative('loginSync');
|
|
40
35
|
|
|
41
36
|
const {
|
|
@@ -47,6 +42,11 @@ export const login = createAPI('login', {
|
|
|
47
42
|
msg: 'login failed'
|
|
48
43
|
});
|
|
49
44
|
}
|
|
45
|
+
onNative('onLoginStateChange', ({ isLogin, token, uuid }) => {
|
|
46
|
+
if (uuid == loginUUID) {
|
|
47
|
+
resolve({ isLogin, token });
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
50
|
const { promise, resolve } = new Deferred<{ isLogin: boolean; token?: string }>();
|
|
51
51
|
|
|
52
52
|
const loginRes = await promise;
|
|
@@ -55,7 +55,10 @@ const interceptSystemExitSync = createSyncAPI('interceptSystemExitSync', {
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
const navigateToNativePage = createSyncAPI('navigateToNativePage', {
|
|
58
|
-
paramsSchema: t.tuple(
|
|
58
|
+
paramsSchema: t.tuple(
|
|
59
|
+
t.enum('openHistory', 'openDiscover', 'openDiscover', 'openGame', 'openDrama', 'openTopup'),
|
|
60
|
+
t.object()
|
|
61
|
+
),
|
|
59
62
|
implement: (path, params) => {
|
|
60
63
|
const { errNo, errMsg } = invokeNative('callHostMethodAsync', {
|
|
61
64
|
method: path,
|
|
@@ -48,7 +48,7 @@ const request = (_params: unknown) => {
|
|
|
48
48
|
t.object({
|
|
49
49
|
url: t.string(),
|
|
50
50
|
method: t.string(),
|
|
51
|
-
headers: t.object(),
|
|
51
|
+
headers: t.object().optional(),
|
|
52
52
|
data: t.object().optional(),
|
|
53
53
|
query: t.object().optional(),
|
|
54
54
|
dataType: t.string().default('json'),
|
|
@@ -73,7 +73,7 @@ const request = (_params: unknown) => {
|
|
|
73
73
|
|
|
74
74
|
const { data, dataType, responseType, enableCache, appendHostCookie } = params;
|
|
75
75
|
|
|
76
|
-
const header = normalizeHeader(params.headers);
|
|
76
|
+
const header = normalizeHeader(params.headers ?? {});
|
|
77
77
|
const method = normalizeMethod(params.method);
|
|
78
78
|
const timeout = normalizeTimeout(params.timeout);
|
|
79
79
|
const url = dirtyURL(params.url, method, data);
|
|
@@ -81,7 +81,7 @@ const request = (_params: unknown) => {
|
|
|
81
81
|
|
|
82
82
|
const _params = Object.assign({}, params, {
|
|
83
83
|
method,
|
|
84
|
-
header,
|
|
84
|
+
header: appendHostCookie ? undefined : header,
|
|
85
85
|
data: method === 'GET' || method === 'HEAD' ? undefined : data, // GET HEAD 请求不需要 data 参数
|
|
86
86
|
enableCache,
|
|
87
87
|
query: params.query ?? ({} as Record<string, string>),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { context } from '@/common/context';
|
|
2
|
+
|
|
1
3
|
export function initializeNativeEnv() {
|
|
2
4
|
let styleElement: HTMLStyleElement | null = null;
|
|
3
5
|
let viewportMeta: HTMLMetaElement | null = null;
|
|
@@ -44,6 +46,12 @@ export function initializeNativeEnv() {
|
|
|
44
46
|
document.documentElement.setAttribute('data-jolibox-root', '');
|
|
45
47
|
};
|
|
46
48
|
|
|
49
|
+
const setupSafeArea = () => {
|
|
50
|
+
const { statusBarHeight, navigationBarHeight } = context.viewport;
|
|
51
|
+
document.documentElement.style.setProperty('--status-bar-height', `${statusBarHeight}px`);
|
|
52
|
+
document.documentElement.style.setProperty('--navigation-bar-height', `${navigationBarHeight}px`);
|
|
53
|
+
};
|
|
54
|
+
|
|
47
55
|
const overrideFetch = () => {
|
|
48
56
|
async function fetchWasm(input: string | URL) {
|
|
49
57
|
const url = input instanceof URL ? input.href : input;
|
|
@@ -90,11 +98,13 @@ export function initializeNativeEnv() {
|
|
|
90
98
|
viewportMeta = null;
|
|
91
99
|
}
|
|
92
100
|
document.documentElement.removeAttribute('data-jolibox-root');
|
|
101
|
+
document.documentElement.style.removeProperty('--status-bar-height');
|
|
93
102
|
|
|
94
103
|
window.fetch = originalFetch;
|
|
95
104
|
};
|
|
96
105
|
createStyles();
|
|
97
106
|
overrideFetch();
|
|
107
|
+
setupSafeArea();
|
|
98
108
|
|
|
99
109
|
// 返回清理函数
|
|
100
110
|
return cleanup;
|
|
@@ -148,25 +148,12 @@ export function createFetch(
|
|
|
148
148
|
});
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
const report = (state: 'success' | 'fail', response: unknown) => {
|
|
152
|
-
reportNetworkAPI('request', url, {
|
|
153
|
-
state,
|
|
154
|
-
startTime,
|
|
155
|
-
endTime: Date.now(),
|
|
156
|
-
params,
|
|
157
|
-
response: response as FetchResponse,
|
|
158
|
-
requestId: requestTaskId,
|
|
159
|
-
requestFrom: type == 'public' ? RequestFrom.PUBLIC : RequestFrom.INNER
|
|
160
|
-
});
|
|
161
|
-
};
|
|
162
|
-
|
|
163
151
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
164
152
|
const { resolve, reject, promise } = new Deferred<FetchResponse<any>>();
|
|
165
153
|
promiseMap.set(requestTaskId, { resolve, reject });
|
|
166
154
|
|
|
167
155
|
try {
|
|
168
156
|
const res = await promise;
|
|
169
|
-
report('success', res);
|
|
170
157
|
let { data } = res;
|
|
171
158
|
if (dataType === 'json' && typeof data === 'string') {
|
|
172
159
|
data = parseJSON(data);
|
|
@@ -190,11 +177,6 @@ export function createFetch(
|
|
|
190
177
|
if (isObject(error)) {
|
|
191
178
|
const { errMsg, prefetchDetail, isPrefetch, errNo } = error;
|
|
192
179
|
if (isString(errMsg)) {
|
|
193
|
-
report('fail', {
|
|
194
|
-
errMsg,
|
|
195
|
-
isPrefetch,
|
|
196
|
-
prefetchDetail
|
|
197
|
-
});
|
|
198
180
|
reportError(createAPIError({ code: -1, msg: errMsg }, { errNo: errNo as number, errMsg }));
|
|
199
181
|
}
|
|
200
182
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { createPaymentHelper } from './payment-helper';
|
|
2
2
|
import { createJolicoinPaymentHandler } from './registers/joli-coin';
|
|
3
|
+
import { createJolicoinIAPPaymentHandler } from './registers/jolicoin-iap';
|
|
3
4
|
|
|
4
5
|
export const paymentHelper = createPaymentHelper();
|
|
5
6
|
paymentHelper.registerPaymentHandler('JOLI_COIN', createJolicoinPaymentHandler());
|
|
7
|
+
paymentHelper.registerPaymentHandler('JOLI_COIN_IAP', createJolicoinIAPPaymentHandler());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type PaymentType = 'JOLI_COIN'; // current only jolicoin
|
|
1
|
+
export type PaymentType = 'JOLI_COIN' | 'JOLI_COIN_IAP'; // current only jolicoin
|
|
2
2
|
|
|
3
3
|
import { StandardResponse } from '@jolibox/types';
|
|
4
4
|
import { reportError } from '@/common/report/errors/report';
|
|
@@ -8,6 +8,7 @@ type PaymentResult = StandardResponse<void>;
|
|
|
8
8
|
|
|
9
9
|
export interface PaymentHandlerMap {
|
|
10
10
|
JOLI_COIN: (productId: string) => Promise<PaymentResult>; // jolicoin
|
|
11
|
+
JOLI_COIN_IAP: (params: { productId: string; appStoreProductId: string }) => Promise<PaymentResult>; // jolicoin iap
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
export type PaymentHandler<T extends PaymentType> = PaymentHandlerMap[T];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StandardResponse } from '@jolibox/types';
|
|
2
2
|
import type { IPlaceOrderJoliCoinParamas, IJoliCoinProductInfo, IJolicoinPaymentContext } from './joli-coin';
|
|
3
|
+
import type { IPlaceOrderJoliCoinIAPParamas, IJolicoinPaymentIAPContext } from './jolicoin-iap';
|
|
3
4
|
import type { IPlaceOrderResponse } from './type';
|
|
4
5
|
import { PaymentErrorCodeMap } from './type';
|
|
5
6
|
type PaymentStatus = 'INIT' | 'PENDING' | 'SUCCESS' | 'FAILED';
|
|
@@ -7,9 +8,9 @@ import { UserPaymentError, InternalPaymentError } from '@jolibox/common';
|
|
|
7
8
|
import { context } from '@/common/context';
|
|
8
9
|
import { innerFetch as fetch } from '@/native/network';
|
|
9
10
|
|
|
10
|
-
type IPlaceOrderParams = IPlaceOrderJoliCoinParamas;
|
|
11
|
-
type IOrderProductInfo = IJoliCoinProductInfo;
|
|
12
|
-
type IOrderPaymentContext = IJolicoinPaymentContext;
|
|
11
|
+
type IPlaceOrderParams = IPlaceOrderJoliCoinParamas | IPlaceOrderJoliCoinIAPParamas;
|
|
12
|
+
type IOrderProductInfo = IJoliCoinProductInfo | IJolicoinPaymentIAPContext;
|
|
13
|
+
type IOrderPaymentContext = IJolicoinPaymentContext | IJolicoinPaymentIAPContext;
|
|
13
14
|
|
|
14
15
|
const createPaymentErrorFactory = () => {
|
|
15
16
|
const [createPaymentError, createPaymentInternalError] = [UserPaymentError, InternalPaymentError].map(
|
|
@@ -30,31 +31,25 @@ export { createPaymentError, createPaymentInternalError };
|
|
|
30
31
|
|
|
31
32
|
const CALLBACK_HOST = context.testMode ? 'https://stg-game.jolibox.com' : 'https://game.jolibox.com';
|
|
32
33
|
|
|
33
|
-
export abstract class BasePaymentRegister<
|
|
34
|
+
export abstract class BasePaymentRegister<
|
|
35
|
+
T extends IPlaceOrderParams,
|
|
36
|
+
E extends IOrderProductInfo,
|
|
37
|
+
R = void
|
|
38
|
+
> {
|
|
34
39
|
private _orderId: string | null = null;
|
|
35
40
|
private _orderStatus: PaymentStatus = 'INIT';
|
|
36
41
|
|
|
37
|
-
startPayment = async (params: T) => {
|
|
42
|
+
startPayment = async (params: T): Promise<StandardResponse<R>> => {
|
|
38
43
|
if (this._orderId) {
|
|
39
44
|
await this.cancelOrder(this.orderId as string);
|
|
40
45
|
}
|
|
41
46
|
|
|
42
|
-
const {
|
|
43
|
-
if (code !== 'SUCCESS'
|
|
47
|
+
const { code, message } = await this.placeOrder(params);
|
|
48
|
+
if (code !== 'SUCCESS') {
|
|
44
49
|
throw createPaymentError(message, PaymentErrorCodeMap.PlaceOrderFailed);
|
|
45
50
|
}
|
|
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
51
|
// invoke native payment;
|
|
56
|
-
|
|
57
|
-
const callbackUrl = this.generateCallbackUrl();
|
|
52
|
+
return await this.pay();
|
|
58
53
|
// 回调页
|
|
59
54
|
};
|
|
60
55
|
|
|
@@ -71,7 +66,7 @@ export abstract class BasePaymentRegister<T extends IPlaceOrderParams, E extends
|
|
|
71
66
|
}
|
|
72
67
|
};
|
|
73
68
|
|
|
74
|
-
|
|
69
|
+
protected generateCallbackUrl = () => {
|
|
75
70
|
// Set or replace gameId and joliSource parameters
|
|
76
71
|
const originalSearch = new URLSearchParams('');
|
|
77
72
|
originalSearch.set('utm_source', context.deviceInfo.platform);
|
|
@@ -86,6 +81,7 @@ export abstract class BasePaymentRegister<T extends IPlaceOrderParams, E extends
|
|
|
86
81
|
|
|
87
82
|
abstract placeOrder(params: T): Promise<StandardResponse<IPlaceOrderResponse<E>>>;
|
|
88
83
|
abstract generatePaymentContext(): IOrderPaymentContext;
|
|
84
|
+
abstract pay(): Promise<StandardResponse<R>>;
|
|
89
85
|
|
|
90
86
|
get orderId(): string | null {
|
|
91
87
|
return this._orderId;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type PaymentStatus = jsb.service.NativeEventMap['onPaymentStateChange'][number]['status'];
|
|
2
|
+
|
|
3
|
+
export const IPaymentIAPFailedStatusMap: Record<PaymentStatus, string> = {
|
|
4
|
+
SUCCESS: 'unlockSuccess',
|
|
5
|
+
FAIL_NOT_LOGIN: 'unlockFailedNotLogin',
|
|
6
|
+
FAIL_PAYING: 'unlockFailedPaying',
|
|
7
|
+
FAIL_PRODUCT_EMPTY: 'unlockFailedProductIdNotFound',
|
|
8
|
+
FAIL_GET_PRODUCT_INFO: 'unlockFailedProductInvalid',
|
|
9
|
+
FAIL_LAUNCH_BILLING: 'unlockFailedLaunch',
|
|
10
|
+
FAIL_TRANSACTION: 'unlockFailedTransaction',
|
|
11
|
+
FAIL_VERIFY: 'unlockFaileVerify',
|
|
12
|
+
TRANSACTION_PENDING: 'transactionPending',
|
|
13
|
+
FAILED: 'unlockFailed'
|
|
14
|
+
} as const;
|
|
@@ -63,6 +63,15 @@ class JolicoinPaymentResiter extends BasePaymentRegister<IPlaceOrderJoliCoinPara
|
|
|
63
63
|
orderId: this.orderId!
|
|
64
64
|
};
|
|
65
65
|
};
|
|
66
|
+
|
|
67
|
+
pay = async (): Promise<StandardResponse<void>> => {
|
|
68
|
+
const callbackUrl = this.generateCallbackUrl();
|
|
69
|
+
console.info('callbackUrl', callbackUrl);
|
|
70
|
+
return {
|
|
71
|
+
code: 'SUCCESS' as ResponseType,
|
|
72
|
+
message: 'jolicoin payment success'
|
|
73
|
+
};
|
|
74
|
+
};
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
export const createJolicoinPaymentHandler = () => {
|
|
@@ -75,6 +84,7 @@ export const createJolicoinPaymentHandler = () => {
|
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
await instance.startPayment({ productId });
|
|
87
|
+
// TODO: need to wait for the payment to be successful
|
|
78
88
|
return {
|
|
79
89
|
code: 'SUCCESS' as ResponseType,
|
|
80
90
|
message: 'jolicoin payment success'
|