@apps-in-toss/native-modules 1.14.1 → 2.0.0
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/dist/bridges-meta.json +11 -7
- package/dist/index.cjs +201 -219
- package/dist/index.d.cts +1479 -1446
- package/dist/index.d.ts +1479 -1446
- package/dist/index.js +173 -192
- package/package.json +10 -8
- package/src/BedrockModule/native-modules/index.ts +0 -2
- package/src/BedrockModule/native-modules/natives/BedrockModule.ts +8 -18
- package/src/BedrockModule/native-modules/natives/closeView.ts +2 -2
- package/src/BedrockModule/native-modules/natives/generateHapticFeedback/index.ts +2 -2
- package/src/BedrockModule/native-modules/natives/getLocale.ts +2 -2
- package/src/BedrockModule/native-modules/natives/getNetworkStatus/index.ts +2 -2
- package/src/BedrockModule/native-modules/natives/getSchemeUri.ts +2 -2
- package/src/BedrockModule/native-modules/natives/setIosSwipeGestureEnabled.ts +3 -3
- package/src/BedrockModule/native-modules/natives/setScreenAwakeMode.ts +2 -2
- package/src/BedrockModule/native-modules/natives/setSecureScreen.ts +2 -2
- package/src/BedrockModule/native-modules/natives/share.ts +2 -2
- package/src/CommonModule.brick.ts +36 -0
- package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/event-plugins/UpdateLocationEvent.ts +9 -6
- package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/internal/AppBridgeCallbackEvent.ts +8 -9
- package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/internal/VisibilityChangedByTransparentServiceWebEvent.ts +13 -12
- package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/internal/appBridge.spec.ts +5 -5
- package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/internal/appBridge.ts +4 -12
- package/src/MiniAppModule/native-modules/ads/types.ts +179 -0
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/appLogin.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/appsInTossSignTossCert.ts +6 -18
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/checkoutPayment.ts +3 -3
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/eventLog.ts +3 -3
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getDeviceId.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getGameCenterGameProfile.ts +2 -2
- package/src/MiniAppModule/native-modules/getGroupId.ts +20 -0
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getIsTossLoginIntegratedService.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getOperationalEnvironment.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getPermission.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getServerTime.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getTossAppVersion.ts +2 -2
- package/src/MiniAppModule/native-modules/getTossShareLink.ts +39 -0
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/getUserKeyForGame.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/grantPromotionRewardForGame.ts +10 -6
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/iap.ts +11 -12
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/index.ts +5 -3
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/isMinVersionSupported.ts +3 -3
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/fetchAlbumPhotos/fetchAlbumPhotos.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/fetchContacts/fetchContacts.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/getClipboardText/getClipboardText.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/getCurrentLocation/getCurrentLocation.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/openCamera/openCamera.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/openPermissionDialog.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/setClipboardText/setClipboardText.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/saveBase64Data.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/setDeviceOrientation.ts +2 -2
- package/src/MiniAppModule/native-modules/shareWithScheme.ts +23 -0
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/storage.ts +5 -8
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/submitGameCenterLeaderBoardScore.ts +2 -2
- package/src/{AppsInTossModule → MiniAppModule}/native-modules/tossCore.ts +5 -17
- package/src/MiniAppModule.brick.ts +158 -0
- package/src/TossCoreModule.brick.ts +17 -0
- package/src/async-bridges.ts +23 -23
- package/src/constant-bridges.ts +4 -3
- package/src/event-bridges.ts +3 -3
- package/src/index.ts +6 -5
- package/src/natives.ts +10 -0
- package/src/AppsInTossModule/native-event-emitter/nativeEventEmitter.ts +0 -35
- package/src/AppsInTossModule/native-modules/AppsInTossModule.ts +0 -107
- package/src/AppsInTossModule/native-modules/getTossShareLink.ts +0 -65
- package/src/BedrockModule/native-modules/core/BedrockCoreModule.ts +0 -8
- /package/src/{AppsInTossModule → MiniAppModule}/constants.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/StartUpdateLocationPermissionError.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/appsInTossEvent.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/contactsViral.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/index.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/internal/onVisibilityChangedByTransparentServiceWeb.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/startUpdateLocation.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-event-emitter/types.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/ads/googleAdMobV2.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/eventLog.spec.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/isMinVersionSupported.spec.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/openGameCenterLeaderboard.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/createPermissionFunction.ts +0 -0
- /package/src/{AppsInTossModule → MiniAppModule}/native-modules/permissions/requestPermission.ts +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,1044 +1,826 @@
|
|
|
1
1
|
import * as _apps_in_toss_types from '@apps-in-toss/types';
|
|
2
|
-
import {
|
|
2
|
+
import { CompatiblePlaceholderArgument, PermissionName, PermissionAccess, PermissionStatus, ContactResult, ImageResponse, Location, StartUpdateLocationEventParams, Accuracy, LoadAdMobParams, ShowAdMobParams, IsAdMobLoadedOptions, FetchAlbumPhotos, FetchContacts, GetClipboardText, GetCurrentLocation, SetClipboardText, OpenCamera } from '@apps-in-toss/types';
|
|
3
3
|
export { IsAdMobLoadedOptions, LoadAdMobEvent, LoadAdMobOptions, LoadAdMobParams, ShowAdMobEvent, ShowAdMobOptions, ShowAdMobParams, StartUpdateLocationPermissionError } from '@apps-in-toss/types';
|
|
4
4
|
import { GraniteEventDefinition, GraniteEvent } from '@granite-js/react-native';
|
|
5
|
-
import {
|
|
5
|
+
import { AnyObject } from 'brick-module';
|
|
6
6
|
|
|
7
|
-
interface
|
|
8
|
-
|
|
9
|
-
params: P;
|
|
7
|
+
interface AppsInTossSignTossCertParams {
|
|
8
|
+
txId: string;
|
|
10
9
|
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @name UpdateLocationEventEmitter
|
|
14
|
-
* @kind typedef
|
|
15
|
-
* @description
|
|
16
|
-
* 디바이스의 위치 정보 변경을 감지해요
|
|
17
|
-
*/
|
|
18
|
-
type UpdateLocationEventEmitter = EventEmitterSchema<'updateLocation', [Location]>;
|
|
19
10
|
/**
|
|
20
11
|
* @public
|
|
21
|
-
* @category
|
|
22
|
-
* @name
|
|
23
|
-
* @description
|
|
24
|
-
* 실시간 위치 추적이 필요한 기능을 구현할 때 사용할 수 있어요. 예를 들어 지도 앱에서 사용자의 현재 위치를 실시간으로 업데이트할 때, 운동 앱에서 사용자의 이동 거리를 기록할 때 등이에요.
|
|
25
|
-
* 위치 업데이트 주기와 정확도를 조정해 배터리 소모를 최소화하면서도 필요한 정보를 얻을 수 있어요.
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param {(error: unknown) => void} onError 위치 정보 감지에 실패했을 때 호출되는 콜백 함수예요.
|
|
29
|
-
* @param {(location: Location) => void} onEvent 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/react-native/reference/native-modules/Types/Location.html)을 참고해주세요.
|
|
30
|
-
* @param {StartUpdateLocationOptions} options - 위치 정보 감지에 필요한 설정 객체에요.
|
|
31
|
-
* @param {number} [options.accuracy] 위치 정확도를 설정해요.
|
|
32
|
-
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
33
|
-
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
34
|
-
*
|
|
35
|
-
* @property [openPermissionDialog] - 위치 정보 권한을 다시 요청하는 다이얼로그를 표시해요. 사용자는 "허용", "한 번만 허용", "안하기" 중 하나를 선택할 수 있어요. "허용"이나 "한 번만 허용"을 선택하면 `allowed`를 반환하고, "안하기"를 선택하면 `denied`를 반환해요.
|
|
36
|
-
* @property [getPermission] - 위치 정보 권한의 현재 상태를 반환해요. `allowed`는 사용자가 위치 정보 권한을 허용한 상태예요. `denied`는 사용자가 위치 정보 권한을 거부한 상태예요. `notDetermined`는 위치 정보 권한 요청을 한 번도 하지 않은 상태예요.
|
|
12
|
+
* @category 토스인증
|
|
13
|
+
* @name appsInTossSignTossCert
|
|
14
|
+
* @description 토스 인증서를 사용해 서명하는 기능을 제공해요. 이 함수를 사용하면 앱인토스에서 제공하는 인증서를 활용해 서명을 할 수 있어요.
|
|
37
15
|
*
|
|
38
|
-
* @
|
|
39
|
-
*
|
|
40
|
-
* function startUpdateLocation(options: {
|
|
41
|
-
* onError: (error: unknown) => void;
|
|
42
|
-
* onEvent: (location: Location) => void;
|
|
43
|
-
* options: StartUpdateLocationOptions;
|
|
44
|
-
* }): () => void;
|
|
45
|
-
* ```
|
|
16
|
+
* @param {AppsInTossSignTossCertParams} params - 서명에 필요한 파라미터를 포함하는 객체예요.
|
|
17
|
+
* @param {string} params.txId - 토스인증서를 사용한 본인확인이나 간편인증, 전자서명에서 사용하는 Transaction Id예요.
|
|
46
18
|
*
|
|
47
19
|
* @example
|
|
48
|
-
* ### 위치 정보 변경 감지하기
|
|
49
|
-
*
|
|
50
|
-
* 위치 정보가 변경되는것을 감지하는 예제예요. "위치 정보 변경 감지하기"를 눌러서 감지할 수 있어요.
|
|
51
|
-
*
|
|
52
|
-
* "권한 확인하기"버튼을 눌러서 현재 위치 정보 변경 감지 권한을 확인해요.
|
|
53
|
-
* 사용자가 권한을 거부했거나 시스템에서 권한이 제한된 경우에는 [`StartUpdateLocationPermissionError`](/react-native/reference/types/권한/StartUpdateLocationPermissionError)를 반환해요.
|
|
54
|
-
* "권한 요청하기"버튼을 눌러서 위치 정보 변경 감지 권한을 요청할 수 있어요.
|
|
55
|
-
*
|
|
56
20
|
* ```tsx
|
|
57
|
-
* import {
|
|
58
|
-
* import { useCallback, useState } from 'react';
|
|
59
|
-
* import { Alert, Button, Text, View } from 'react-native';
|
|
60
|
-
*
|
|
61
|
-
* // 위치 정보 변경 감지하기
|
|
62
|
-
* function LocationWatcher() {
|
|
63
|
-
* const [location, setLocation] = useState<Location | null>(null);
|
|
64
|
-
*
|
|
65
|
-
* const handlePress = useCallback(() => {
|
|
66
|
-
* startUpdateLocation({
|
|
67
|
-
* options: {
|
|
68
|
-
* accuracy: Accuracy.Balanced,
|
|
69
|
-
* timeInterval: 3000,
|
|
70
|
-
* distanceInterval: 10,
|
|
71
|
-
* },
|
|
72
|
-
* onEvent: (location) => {
|
|
73
|
-
* setLocation(location);
|
|
74
|
-
* },
|
|
75
|
-
* onError: (error) => {
|
|
76
|
-
* if (error instanceof StartUpdateLocationPermissionError) {
|
|
77
|
-
* // 위치 정보 변경 감지 권한 없음
|
|
78
|
-
* }
|
|
79
|
-
* console.error('위치 정보를 가져오는데 실패했어요:', error);
|
|
80
|
-
* },
|
|
81
|
-
* });
|
|
82
|
-
* }, []);
|
|
83
|
-
*
|
|
84
|
-
* return (
|
|
85
|
-
* <View>
|
|
86
|
-
* {location != null && (
|
|
87
|
-
* <>
|
|
88
|
-
* <Text>위도: {location.coords.latitude}</Text>
|
|
89
|
-
* <Text>경도: {location.coords.longitude}</Text>
|
|
90
|
-
* <Text>위치 정확도: {location.coords.accuracy}m</Text>
|
|
91
|
-
* <Text>높이: {location.coords.altitude}m</Text>
|
|
92
|
-
* <Text>고도 정확도: {location.coords.altitudeAccuracy}m</Text>
|
|
93
|
-
* <Text>방향: {location.coords.heading}°</Text>
|
|
94
|
-
* </>
|
|
95
|
-
* )}
|
|
21
|
+
* import { appsInTossSignTossCert } from '@apps-in-toss/framework';
|
|
96
22
|
*
|
|
97
|
-
*
|
|
23
|
+
* // 서명에 필요한 파라미터를 정의해요.
|
|
24
|
+
* const params = {
|
|
25
|
+
* txId: "f2e1a6df..."
|
|
26
|
+
* };
|
|
98
27
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* <Button
|
|
107
|
-
* title="권한 요청하기"
|
|
108
|
-
* onPress={async () => {
|
|
109
|
-
* const permission = await startUpdateLocation.openPermissionDialog();
|
|
110
|
-
* Alert.alert(permission);
|
|
111
|
-
* }}
|
|
112
|
-
* />
|
|
113
|
-
* </View>
|
|
114
|
-
* );
|
|
115
|
-
* }
|
|
28
|
+
* appsInTossSignTossCert(params)
|
|
29
|
+
* .then(() => {
|
|
30
|
+
* console.log('서명 작업이 성공적으로 완료되었어요.');
|
|
31
|
+
* })
|
|
32
|
+
* .catch((error) => {
|
|
33
|
+
* console.error('서명 작업 중 에러가 발생했어요:', error);
|
|
34
|
+
* });
|
|
116
35
|
* ```
|
|
117
36
|
*/
|
|
118
|
-
declare function
|
|
119
|
-
declare namespace startUpdateLocation {
|
|
120
|
-
var openPermissionDialog: _apps_in_toss_types.PermissionDialogFunction;
|
|
121
|
-
var getPermission: _apps_in_toss_types.GetPermissionFunction;
|
|
122
|
-
}
|
|
37
|
+
declare function appsInTossSignTossCert(params: AppsInTossSignTossCertParams): Promise<void>;
|
|
123
38
|
|
|
124
39
|
/**
|
|
125
40
|
* @public
|
|
126
|
-
* @category
|
|
127
|
-
* @name
|
|
128
|
-
* @description
|
|
129
|
-
* @property {
|
|
130
|
-
* @property {Object} data - 지급할 리워드 관련 정보를 담고 있어요.
|
|
131
|
-
* @property {number} data.rewardAmount - 지급할 리워드 수량이에요. 앱인토스 콘솔에서 설정한 수량 및 금액 값이에요.
|
|
132
|
-
* @property {string} data.rewardUnit - 리워드의 단위예요. 앱인토스 콘솔에 설정된 리워드 이름인 '하트', '보석' 등이 리워드 단위예요.
|
|
133
|
-
*/
|
|
134
|
-
type RewardFromContactsViralEvent = {
|
|
135
|
-
type: 'sendViral';
|
|
136
|
-
data: {
|
|
137
|
-
rewardAmount: number;
|
|
138
|
-
rewardUnit: string;
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* @public
|
|
143
|
-
* @category 친구초대
|
|
144
|
-
* @name ContactsViralSuccessEvent
|
|
145
|
-
* @description 연락처 공유 모듈이 정상적으로 종료됐을 때 전달되는 이벤트 객체예요. 종료 이유와 함께 리워드 상태 및 남은 친구 수 등 관련 정보를 제공해요.
|
|
146
|
-
* @property {'close'} type - 이벤트의 타입이에요. `'close'`는 공유 모듈이 종료됐을 때 돌아와요.
|
|
147
|
-
* @property {Object} data - 모듈 종료와 관련된 세부 정보를 담고 있어요.
|
|
148
|
-
* @property {'clickBackButton' | 'noReward'} data.closeReason - 모듈이 종료된 이유예요. `'clickBackButton'`은 사용자가 뒤로 가기 버튼을 눌러 종료한 경우이고, `'noReward'`는 받을 수 있는 리워드가 없어서 종료된 경우예요.
|
|
149
|
-
* @property {number} data.sentRewardAmount - 사용자가 받은 전체 리워드 수량이에요.
|
|
150
|
-
* @property {number} data.sendableRewardsCount - 아직 공유할 수 있는 친구 수예요.
|
|
151
|
-
* @property {number} data.sentRewardsCount - 사용자가 공유를 완료한 친구 수예요.
|
|
152
|
-
* @property {string} data.rewardUnit - 리워드의 단위예요. 앱인토스 콘솔에 설정된 리워드 이름인 '하트', '보석' 등이 리워드 단위예요.
|
|
153
|
-
*/
|
|
154
|
-
type ContactsViralSuccessEvent = {
|
|
155
|
-
type: 'close';
|
|
156
|
-
data: {
|
|
157
|
-
closeReason: 'clickBackButton' | 'noReward';
|
|
158
|
-
sentRewardAmount?: number;
|
|
159
|
-
sendableRewardsCount?: number;
|
|
160
|
-
sentRewardsCount: number;
|
|
161
|
-
rewardUnit?: string;
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
type ContactsViralEvent = RewardFromContactsViralEvent | ContactsViralSuccessEvent;
|
|
165
|
-
/**
|
|
166
|
-
* @public
|
|
167
|
-
* @category 친구초대
|
|
168
|
-
* @name ContactsViralOption
|
|
169
|
-
* @description [연락처 공유 기능](/react-native/reference/native-modules/친구초대/contactsViral.html)을 사용할 때 필요한 옵션이에요.
|
|
170
|
-
* @property {string} moduleId - 공유 리워드를 구분하는 UUID 형식의 고유 ID예요. 앱인토스 콘솔의 미니앱 > 공유 리워드 메뉴에서 확인할 수 있어요.
|
|
41
|
+
* @category 토스페이
|
|
42
|
+
* @name CheckoutPaymentOptions
|
|
43
|
+
* @description 토스페이 결제창을 띄울 때 필요한 옵션이에요.
|
|
44
|
+
* @property {string} payToken 결제 토큰이에요.
|
|
171
45
|
*/
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
46
|
+
interface CheckoutPaymentOptions {
|
|
47
|
+
/**
|
|
48
|
+
* 결제 토큰이에요.
|
|
49
|
+
*/
|
|
50
|
+
payToken: string;
|
|
51
|
+
}
|
|
175
52
|
/**
|
|
176
53
|
* @public
|
|
177
|
-
* @category
|
|
178
|
-
* @name
|
|
179
|
-
* @description
|
|
180
|
-
* @property {
|
|
181
|
-
* @property {
|
|
182
|
-
* @property {(error: unknown) => void} onError - 예기치 않은 에러가 발생했을 때 실행되는 함수예요.
|
|
54
|
+
* @category 토스페이
|
|
55
|
+
* @name CheckoutPaymentResult
|
|
56
|
+
* @description 토스페이 결제창에서 사용자가 인증에 성공했는지 여부예요.
|
|
57
|
+
* @property {boolean} success 인증이 성공했는지 여부예요.
|
|
58
|
+
* @property {string} [reason] 인증이 실패했을 경우의 이유예요.
|
|
183
59
|
*/
|
|
184
|
-
interface
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
60
|
+
interface CheckoutPaymentResult {
|
|
61
|
+
/**
|
|
62
|
+
* 인증이 성공했는지 여부예요.
|
|
63
|
+
*/
|
|
64
|
+
success: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* 인증이 실패했을 경우의 이유예요.
|
|
67
|
+
*/
|
|
68
|
+
reason?: string;
|
|
188
69
|
}
|
|
189
70
|
/**
|
|
190
71
|
* @public
|
|
191
|
-
* @category
|
|
192
|
-
* @name
|
|
193
|
-
* @description
|
|
194
|
-
*
|
|
195
|
-
*
|
|
72
|
+
* @category 토스페이
|
|
73
|
+
* @name checkoutPayment
|
|
74
|
+
* @description 토스페이 결제창을 띄우고, 사용자 인증을 수행해요. 인증이 완료되면 성공 여부를 반환해요.
|
|
75
|
+
*
|
|
76
|
+
* 이 함수는 결제창을 통해 사용자 인증만 해요. 실제 결제 처리는 인증 성공 후 서버에서 별도로 해야 해요.
|
|
77
|
+
*
|
|
78
|
+
* @param {CheckoutPaymentOptions} options 결제창을 띄울 때 필요한 옵션이에요.
|
|
79
|
+
* @returns {Promise<CheckoutPaymentResult>} 인증 성공 여부를 포함한 결과를 반환해요.
|
|
196
80
|
*
|
|
197
81
|
* @example
|
|
198
|
-
*
|
|
82
|
+
*
|
|
83
|
+
* ### 토스페이 결제창 띄우고 인증 처리하기
|
|
199
84
|
*
|
|
200
85
|
* ```tsx
|
|
201
|
-
* import {
|
|
202
|
-
* import { Button } from 'react-native';
|
|
203
|
-
* import { contactsViral } from '@apps-in-toss/framework';
|
|
86
|
+
* import { TossPay } from '@apps-in-toss/framework';
|
|
204
87
|
*
|
|
205
|
-
* function
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* options: { moduleId: moduleId.trim() },
|
|
210
|
-
* onEvent: (event) => {
|
|
211
|
-
* if (event.type === 'sendViral') {
|
|
212
|
-
* console.log('리워드 지급:', event.data.rewardAmount, event.data.rewardUnit);
|
|
213
|
-
* } else if (event.type === 'close') {
|
|
214
|
-
* console.log('모듈 종료:', event.data.closeReason);
|
|
215
|
-
* }
|
|
216
|
-
* },
|
|
217
|
-
* onError: (error) => {
|
|
218
|
-
* console.error('에러 발생:', error);
|
|
219
|
-
* },
|
|
220
|
-
* });
|
|
88
|
+
* async function handlePayment() {
|
|
89
|
+
* try {
|
|
90
|
+
* // 실제 구현 시 결제 생성 역할을 하는 API 엔드포인트로 대체해주세요.
|
|
91
|
+
* const { payToken } = await fetch('/my-api/payment/create').then(res => res.json());
|
|
221
92
|
*
|
|
222
|
-
*
|
|
223
|
-
* } catch (error) {
|
|
224
|
-
* console.error('실행 중 에러:', error);
|
|
225
|
-
* }
|
|
226
|
-
* }, [moduleId]);
|
|
93
|
+
* const { success, reason } = await TossPay.checkoutPayment({ payToken });
|
|
227
94
|
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
95
|
+
* if (success) {
|
|
96
|
+
* // 실제 구현 시 결제를 실행하는 API 엔드포인트로 대체해주세요.
|
|
97
|
+
* await fetch('/my-api/payment/execute', {
|
|
98
|
+
* method: 'POST',
|
|
99
|
+
* body: JSON.stringify({ payToken }),
|
|
100
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
101
|
+
* });
|
|
102
|
+
* } else {
|
|
103
|
+
* console.log('인증 실패:', reason);
|
|
104
|
+
* }
|
|
105
|
+
* } catch (error) {
|
|
106
|
+
* console.error('결제 인증 중 오류가 발생했어요:', error);
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
231
110
|
*/
|
|
232
|
-
declare function
|
|
111
|
+
declare function checkoutPayment(options: {
|
|
112
|
+
params: CheckoutPaymentOptions;
|
|
113
|
+
}): Promise<CheckoutPaymentResult>;
|
|
233
114
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
115
|
+
/**
|
|
116
|
+
* @category 게임센터
|
|
117
|
+
* @name GameCenterGameProfileResponse
|
|
118
|
+
* @description 토스게임센터 프로필을 가져온 결과 타입이에요.
|
|
119
|
+
* 앱에 프로필이 없는 경우, `statusCode`가 `'PROFILE_NOT_FOUND'`이고 다른 정보는 없어요.
|
|
120
|
+
* 프로필이 있는 경우 `statusCode`가 `'SUCCESS'`이고, 닉네임과 프로필 이미지 주소가 함께 제공돼요.
|
|
121
|
+
* @property {string} statusCode 프로필 조회 결과 상태예요. `'SUCCESS'` 또는 `'PROFILE_NOT_FOUND'` 중 하나예요.
|
|
122
|
+
* @property {string} [nickname] 프로필 닉네임이에요. `statusCode`가 `'SUCCESS'`일 때만 있어요.
|
|
123
|
+
* @property {string} [profileImageUri] 프로필 이미지 URL이에요. `statusCode`가 `'SUCCESS'`일 때만 있어요.
|
|
124
|
+
*/
|
|
125
|
+
type GameCenterGameProfileResponse = {
|
|
126
|
+
statusCode: 'PROFILE_NOT_FOUND';
|
|
127
|
+
} | {
|
|
128
|
+
statusCode: 'SUCCESS';
|
|
129
|
+
nickname: string;
|
|
130
|
+
profileImageUri: string;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* @category 게임센터
|
|
134
|
+
* @name getGameCenterGameProfile
|
|
135
|
+
* @description 토스게임센터 프로필 정보를 가져와요.
|
|
136
|
+
* 사용자가 프로필을 만들지 않았다면 `statusCode`가 `'PROFILE_NOT_FOUND'`인 응답이 반환돼요.
|
|
137
|
+
* 앱 버전이 최소 지원 버전(안드로이드 5.221.0, iOS 5.221.0)보다 낮으면 `undefined`를 반환해요.
|
|
138
|
+
* @returns {Promise<GameCenterGameProfileResponse | undefined>} 프로필 정보 또는 `undefined`를 반환해요.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ### 게임센터 프로필 가져오기
|
|
142
|
+
* ```tsx
|
|
143
|
+
* import { getGameCenterGameProfile } from './getGameCenterGameProfile';
|
|
144
|
+
* import { useState } from 'react';
|
|
145
|
+
* import { View, Button } from 'react-native';
|
|
146
|
+
*
|
|
147
|
+
* function GameProfile() {
|
|
148
|
+
* const [profile, setProfile] = useState<GameCenterGameProfileResponse | null>(null);
|
|
149
|
+
*
|
|
150
|
+
* const handlePress = async () => {
|
|
151
|
+
* try {
|
|
152
|
+
* const result = await getGameCenterGameProfile();
|
|
153
|
+
* if (result) {
|
|
154
|
+
* setProfile(result);
|
|
155
|
+
* }
|
|
156
|
+
* } catch (error) {
|
|
157
|
+
* console.error('게임센터 프로필 가져오기에 실패했어요.', error);
|
|
158
|
+
* }
|
|
159
|
+
* };
|
|
160
|
+
*
|
|
161
|
+
* return (
|
|
162
|
+
* <View>
|
|
163
|
+
* <Button title="게임센터 프로필 가져오기" onPress={handlePress} />
|
|
164
|
+
* </View>
|
|
165
|
+
* );
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
declare function getGameCenterGameProfile(): Promise<GameCenterGameProfileResponse | undefined>;
|
|
271
170
|
|
|
272
|
-
interface
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
declare class VisibilityChangedByTransparentServiceWebEvent extends GraniteEventDefinition<VisibilityChangedByTransparentServiceWebOptions, boolean> {
|
|
276
|
-
name: "onVisibilityChangedByTransparentServiceWeb";
|
|
277
|
-
subscription: EmitterSubscription | null;
|
|
278
|
-
remove(): void;
|
|
279
|
-
listener(options: VisibilityChangedByTransparentServiceWebOptions, onEvent: (isVisible: boolean) => void, onError: (error: unknown) => void): void;
|
|
280
|
-
private isVisibilityChangedByTransparentServiceWebResult;
|
|
171
|
+
interface GetUserKeyForGameSuccessResponse {
|
|
172
|
+
hash: string;
|
|
173
|
+
type: 'HASH';
|
|
281
174
|
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
declare function onVisibilityChangedByTransparentServiceWeb(eventParams: {
|
|
286
|
-
options: {
|
|
287
|
-
callbackId: string;
|
|
288
|
-
};
|
|
289
|
-
onEvent: (isVisible: boolean) => void;
|
|
290
|
-
onError: (error: unknown) => void;
|
|
291
|
-
}): () => void;
|
|
292
|
-
|
|
293
|
-
interface AppBridgeCompatCallbacks<Result> {
|
|
294
|
-
onSuccess: (result: Result) => void;
|
|
295
|
-
onError: (reason: unknown) => void;
|
|
175
|
+
interface GetUserKeyForGameErrorResponse {
|
|
176
|
+
type: 'NOT_AVAILABLE';
|
|
296
177
|
}
|
|
297
|
-
type
|
|
298
|
-
declare function invokeAppBridgeCallback(id: string, ...args: any[]): boolean;
|
|
299
|
-
declare function invokeAppBridgeMethod<Result = any, Params = any>(methodName: string, params: Params, callbacks: AppBridgeCompatCallbacks<Result> & Record<string, AppBridgeCallback>): () => void;
|
|
300
|
-
declare function registerCallback(callback: AppBridgeCallback, name?: string): string;
|
|
301
|
-
declare function unregisterCallback(id: string): void;
|
|
302
|
-
declare function getCallbackIds(): string[];
|
|
303
|
-
declare const INTERNAL__appBridgeHandler: {
|
|
304
|
-
invokeAppBridgeCallback: typeof invokeAppBridgeCallback;
|
|
305
|
-
invokeAppBridgeMethod: typeof invokeAppBridgeMethod;
|
|
306
|
-
registerCallback: typeof registerCallback;
|
|
307
|
-
unregisterCallback: typeof unregisterCallback;
|
|
308
|
-
getCallbackIds: typeof getCallbackIds;
|
|
309
|
-
};
|
|
310
|
-
|
|
178
|
+
type GetUserKeyForGameResponse = GetUserKeyForGameSuccessResponse | GetUserKeyForGameErrorResponse;
|
|
311
179
|
/**
|
|
312
180
|
* @public
|
|
313
|
-
* @category
|
|
314
|
-
* @name
|
|
315
|
-
* @description
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* @
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
181
|
+
* @category 게임
|
|
182
|
+
* @name getUserKeyForGame
|
|
183
|
+
* @description
|
|
184
|
+
* 게임 카테고리 미니앱에서 사용자의 고유 키를 가져와요. 이 키를 사용해서 사용자를 식별하고 게임 데이터를 관리할 수 있어요.
|
|
185
|
+
* 게임 카테고리가 아닌 미니앱에서 호출하면 `'INVALID_CATEGORY'`를 반환해요.
|
|
186
|
+
* @returns {Promise<GetUserKeyForGameSuccessResponse | 'INVALID_CATEGORY' | 'ERROR' | undefined>}
|
|
187
|
+
* 사용자 키 조회 결과를 반환해요.
|
|
188
|
+
* - `GetUserKeyForGameSuccessResponse`: 사용자 키 조회에 성공했어요. `{ type: 'HASH', hash: string }` 형태로 반환돼요.
|
|
189
|
+
* - `'INVALID_CATEGORY'`: 게임 카테고리가 아닌 미니앱에서 호출했어요.
|
|
190
|
+
* - `'ERROR'`: 알 수 없는 오류가 발생했어요.
|
|
191
|
+
* - `undefined`: 앱 버전이 최소 지원 버전보다 낮아요.
|
|
322
192
|
*
|
|
323
193
|
* @example
|
|
324
|
-
* ### 버튼 눌러 불러온 광고 보여주기
|
|
325
194
|
* ```tsx
|
|
326
|
-
*
|
|
327
|
-
* import {
|
|
328
|
-
* import {
|
|
329
|
-
* import { Button, Text, View } from 'react-native';
|
|
330
|
-
* import { useNavigation } from 'react-native-bedrock';
|
|
331
|
-
*
|
|
332
|
-
* const AD_GROUP_ID = '<AD_GROUP_ID>';
|
|
195
|
+
* // react-native
|
|
196
|
+
* import { Button } from 'react-native';
|
|
197
|
+
* import { getUserKeyForGame } from '@apps-in-toss/framework';
|
|
333
198
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
199
|
+
* function GameUserKeyButton() {
|
|
200
|
+
* async function handlePress() {
|
|
201
|
+
* const result = await getUserKeyForGame();
|
|
337
202
|
*
|
|
338
|
-
*
|
|
339
|
-
*
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
|
|
343
|
-
* const cleanup = GoogleAdMob.loadAppsInTossAdMob({
|
|
344
|
-
* options: {
|
|
345
|
-
* adGroupId: AD_GROUP_ID,
|
|
346
|
-
* },
|
|
347
|
-
* onEvent: (event) => {
|
|
348
|
-
* switch (event.type) {
|
|
349
|
-
* case 'loaded':
|
|
350
|
-
* console.log('광고 로드 성공', event.data);
|
|
351
|
-
* setAdLoadStatus('loaded');
|
|
352
|
-
* break;
|
|
353
|
-
* }
|
|
354
|
-
* },
|
|
355
|
-
* onError: (error) => {
|
|
356
|
-
* console.error('광고 불러오기 실패', error);
|
|
357
|
-
* },
|
|
358
|
-
* });
|
|
203
|
+
* if (!result) {
|
|
204
|
+
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
205
|
+
* return;
|
|
206
|
+
* }
|
|
359
207
|
*
|
|
360
|
-
*
|
|
361
|
-
*
|
|
208
|
+
* if (result === 'INVALID_CATEGORY') {
|
|
209
|
+
* console.error('게임 카테고리가 아닌 미니앱이에요.');
|
|
210
|
+
* return;
|
|
211
|
+
* }
|
|
362
212
|
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
213
|
+
* if (result === 'ERROR') {
|
|
214
|
+
* console.error('사용자 키 조회 중 오류가 발생했어요.');
|
|
215
|
+
* return;
|
|
216
|
+
* }
|
|
367
217
|
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
* }
|
|
372
|
-
*
|
|
373
|
-
* switch (event.type) {
|
|
374
|
-
* case 'requested':
|
|
375
|
-
* console.log('광고 보여주기 요청 완료');
|
|
376
|
-
* break;
|
|
218
|
+
* if (result.type === 'HASH') {
|
|
219
|
+
* console.log('사용자 키:', result.hash);
|
|
220
|
+
* // 여기에서 사용자 키를 사용해 게임 데이터를 관리할 수 있어요.
|
|
221
|
+
* }
|
|
222
|
+
* }
|
|
377
223
|
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
380
|
-
*
|
|
224
|
+
* return (
|
|
225
|
+
* <Button onPress={handlePress} title="유저 키 가져오기" />
|
|
226
|
+
* );
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
381
229
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```tsx
|
|
232
|
+
* // webview
|
|
233
|
+
* import { getUserKeyForGame } from '@apps-in-toss/web-framework';
|
|
386
234
|
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
235
|
+
* function GameUserKeyButton() {
|
|
236
|
+
* async function handleClick() {
|
|
237
|
+
* const result = await getUserKeyForGame();
|
|
390
238
|
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
239
|
+
* if (!result) {
|
|
240
|
+
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
241
|
+
* return;
|
|
242
|
+
* }
|
|
394
243
|
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
244
|
+
* if (result === 'INVALID_CATEGORY') {
|
|
245
|
+
* console.error('게임 카테고리가 아닌 미니앱이에요.');
|
|
246
|
+
* return;
|
|
247
|
+
* }
|
|
399
248
|
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
* },
|
|
405
|
-
* onError: (error) => {
|
|
406
|
-
* console.error('광고 보여주기 실패', error);
|
|
407
|
-
* },
|
|
408
|
-
* });
|
|
409
|
-
* }, []);
|
|
249
|
+
* if (result === 'ERROR') {
|
|
250
|
+
* console.error('사용자 키 조회 중 오류가 발생했어요.');
|
|
251
|
+
* return;
|
|
252
|
+
* }
|
|
410
253
|
*
|
|
411
|
-
*
|
|
254
|
+
* if (result.type === 'HASH') {
|
|
255
|
+
* console.log('사용자 키:', result.hash);
|
|
256
|
+
* // 여기에서 사용자 키를 사용해 게임 데이터를 관리할 수 있어요.
|
|
257
|
+
* }
|
|
258
|
+
* }
|
|
412
259
|
*
|
|
413
260
|
* return (
|
|
414
|
-
* <
|
|
415
|
-
* <Text>
|
|
416
|
-
* {adLoadStatus === 'not_loaded' && '광고 로드 하지 않음 '}
|
|
417
|
-
* {adLoadStatus === 'loaded' && '광고 로드 완료'}
|
|
418
|
-
* {adLoadStatus === 'failed' && '광고 로드 실패'}
|
|
419
|
-
* </Text>
|
|
420
|
-
*
|
|
421
|
-
* <Button title="Show Ad" onPress={showAd} disabled={adLoadStatus !== 'loaded'} />
|
|
422
|
-
* </View>
|
|
261
|
+
* <button onClick={handleClick}>유저 키 가져오기</button>
|
|
423
262
|
* );
|
|
424
263
|
* }
|
|
425
264
|
* ```
|
|
426
265
|
*/
|
|
427
|
-
declare function
|
|
428
|
-
declare namespace loadAppsInTossAdMob {
|
|
429
|
-
var isSupported: () => boolean;
|
|
430
|
-
}
|
|
266
|
+
declare function getUserKeyForGame(): Promise<GetUserKeyForGameSuccessResponse | 'INVALID_CATEGORY' | 'ERROR' | undefined>;
|
|
431
267
|
|
|
268
|
+
interface GrantPromotionRewardForGameSuccessResponse {
|
|
269
|
+
key: string;
|
|
270
|
+
}
|
|
271
|
+
interface GrantPromotionRewardForGameErrorResponse {
|
|
272
|
+
code: string;
|
|
273
|
+
[key: string]: any;
|
|
274
|
+
}
|
|
275
|
+
interface GrantPromotionRewardForGameErrorResult {
|
|
276
|
+
errorCode: string;
|
|
277
|
+
message: string;
|
|
278
|
+
}
|
|
279
|
+
type GrantPromotionRewardForGameResponse = GrantPromotionRewardForGameSuccessResponse | GrantPromotionRewardForGameErrorResponse;
|
|
280
|
+
type GrantPromotionRewardForGameResult = GrantPromotionRewardForGameResponse | GrantPromotionRewardForGameErrorResult | 'ERROR' | undefined;
|
|
432
281
|
/**
|
|
433
282
|
* @public
|
|
434
|
-
* @category
|
|
435
|
-
* @name
|
|
436
|
-
* @description
|
|
437
|
-
*
|
|
438
|
-
*
|
|
439
|
-
* @param {
|
|
440
|
-
* @param {
|
|
441
|
-
* @param {
|
|
442
|
-
* @
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
|
|
464
|
-
* const cleanup = GoogleAdMob.loadAppsInTossAdMob({
|
|
465
|
-
* options: {
|
|
466
|
-
* adGroupId: AD_GROUP_ID,
|
|
467
|
-
* },
|
|
468
|
-
* onEvent: (event) => {
|
|
469
|
-
* switch (event.type) {
|
|
470
|
-
* case 'loaded':
|
|
471
|
-
* console.log('광고 로드 성공', event.data);
|
|
472
|
-
* setAdLoadStatus('loaded');
|
|
473
|
-
* break;
|
|
474
|
-
* }
|
|
475
|
-
* },
|
|
476
|
-
* onError: (error) => {
|
|
477
|
-
* console.error('광고 불러오기 실패', error);
|
|
478
|
-
* },
|
|
479
|
-
* });
|
|
283
|
+
* @category 게임
|
|
284
|
+
* @name grantPromotionRewardForGame
|
|
285
|
+
* @description
|
|
286
|
+
* 이 함수를 사용하면 게임 카테고리 미니앱에서 프로모션 코드를 사용해서 유저에게 리워드를 지급할 수 있어요.
|
|
287
|
+
* 게임 카테고리가 아닌 미니앱에서 호출할 수 없어요.
|
|
288
|
+
* @param {{ params: { promotionCode: string; amount: number } }} params - 포인트를 지급하기 위해 필요한 정보예요.
|
|
289
|
+
* @param {string} params.promotionCode - 프로모션 코드예요.
|
|
290
|
+
* @param {number} params.amount - 지급할 포인트 금액이에요.
|
|
291
|
+
* @returns {Promise<{ key: string } | { errorCode: string; message: string } | 'ERROR' | undefined>}
|
|
292
|
+
* 포인트 지급 결과를 반환해요.
|
|
293
|
+
* - `{ key: string }`: 포인트 지급에 성공했어요. key는 리워드 키를 의미해요.
|
|
294
|
+
* - `{ errorCode: string, message: string }`: 포인트 지급에 실패했어요. 에러 코드는 다음과 같아요.
|
|
295
|
+
* - `"40000"`: 게임이 아닌 미니앱에서 호출했을 때
|
|
296
|
+
* - `"4100"`: 프로모션 정보를 찾을 수 없을 때
|
|
297
|
+
* - `"4104"`: 프로모션이 중지되었을 때
|
|
298
|
+
* - `"4105"`: 프로모션이 종료되었을 때
|
|
299
|
+
* - `"4108"`: 프로모션이 승인되지 않았을 때
|
|
300
|
+
* - `"4109"`: 프로모션이 실행중이 아닐 때
|
|
301
|
+
* - `"4110"`: 리워드를 지급/회수할 수 없을 때
|
|
302
|
+
* - `"4112"`: 프로모션 머니가 부족할 때
|
|
303
|
+
* - `"4113"`: 이미 지급/회수된 내역일 때
|
|
304
|
+
* - `"4114"`: 프로모션에 설정된 1회 지급 금액을 초과할 때
|
|
305
|
+
* - `'ERROR'`: 알 수 없는 오류가 발생했어요.
|
|
306
|
+
* - `undefined`: 앱 버전이 최소 지원 버전보다 낮아요.
|
|
307
|
+
* @example
|
|
308
|
+
* ```tsx
|
|
309
|
+
* // react-native
|
|
310
|
+
* import { Button } from 'react-native';
|
|
311
|
+
* import { grantPromotionRewardForGame } from '@apps-in-toss/framework';
|
|
480
312
|
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
313
|
+
* function GrantRewardButton() {
|
|
314
|
+
* async function handlePress() {
|
|
315
|
+
* const result = await grantPromotionRewardForGame({
|
|
316
|
+
* params: {
|
|
317
|
+
* promotionCode: 'GAME_EVENT_2024',
|
|
318
|
+
* amount: 1000,
|
|
319
|
+
* },
|
|
320
|
+
* });
|
|
483
321
|
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
487
|
-
*
|
|
322
|
+
* if (!result) {
|
|
323
|
+
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
324
|
+
* return;
|
|
325
|
+
* }
|
|
488
326
|
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
* }
|
|
493
|
-
* onEvent: (event) => {
|
|
494
|
-
* switch (event.type) {
|
|
495
|
-
* case 'requested':
|
|
496
|
-
* console.log('광고 보여주기 요청 완료');
|
|
497
|
-
* break;
|
|
327
|
+
* if (result === 'ERROR') {
|
|
328
|
+
* console.error('포인트 지급 중 알 수 없는 오류가 발생했어요.');
|
|
329
|
+
* return;
|
|
330
|
+
* }
|
|
498
331
|
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
332
|
+
* if ('key' in result) {
|
|
333
|
+
* console.log('포인트 지급 성공!', result.key);
|
|
334
|
+
* } else if ('errorCode' in result) {
|
|
335
|
+
* console.error('포인트 지급 실패:', result.errorCode, result.message);
|
|
336
|
+
* }
|
|
337
|
+
* }
|
|
502
338
|
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* break;
|
|
339
|
+
* return <Button onPress={handlePress} title="포인트 지급하기" />;
|
|
340
|
+
* }
|
|
341
|
+
* ```
|
|
507
342
|
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```tsx
|
|
345
|
+
* // webview
|
|
346
|
+
* import { grantPromotionRewardForGame } from '@apps-in-toss/web-framework';
|
|
511
347
|
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
348
|
+
* function GrantRewardButton() {
|
|
349
|
+
* async function handleClick() {
|
|
350
|
+
* const result = await grantPromotionRewardForGame({
|
|
351
|
+
* params: {
|
|
352
|
+
* promotionCode: 'GAME_EVENT_2024',
|
|
353
|
+
* amount: 1000,
|
|
354
|
+
* },
|
|
355
|
+
* });
|
|
515
356
|
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
357
|
+
* if (!result) {
|
|
358
|
+
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
359
|
+
* return;
|
|
360
|
+
* }
|
|
520
361
|
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
* },
|
|
526
|
-
* onError: (error) => {
|
|
527
|
-
* console.error('광고 보여주기 실패', error);
|
|
528
|
-
* },
|
|
529
|
-
* });
|
|
530
|
-
* }, []);
|
|
362
|
+
* if (result === 'ERROR') {
|
|
363
|
+
* console.error('포인트 지급 중 알 수 없는 오류가 발생했어요.');
|
|
364
|
+
* return;
|
|
365
|
+
* }
|
|
531
366
|
*
|
|
532
|
-
*
|
|
367
|
+
* if ('key' in result) {
|
|
368
|
+
* console.log('포인트 지급 성공!', result.key);
|
|
369
|
+
* } else if ('errorCode' in result) {
|
|
370
|
+
* console.error('포인트 지급 실패:', result.errorCode, result.message);
|
|
371
|
+
* }
|
|
372
|
+
* }
|
|
533
373
|
*
|
|
534
374
|
* return (
|
|
535
|
-
* <
|
|
536
|
-
* <Text>
|
|
537
|
-
* {adLoadStatus === 'not_loaded' && '광고 로드 하지 않음 '}
|
|
538
|
-
* {adLoadStatus === 'loaded' && '광고 로드 완료'}
|
|
539
|
-
* {adLoadStatus === 'failed' && '광고 로드 실패'}
|
|
540
|
-
* </Text>
|
|
541
|
-
*
|
|
542
|
-
* <Button title="Show Ad" onPress={showAd} disabled={adLoadStatus !== 'loaded'} />
|
|
543
|
-
* </View>
|
|
375
|
+
* <button onClick={handleClick}>포인트 지급하기</button>
|
|
544
376
|
* );
|
|
545
377
|
* }
|
|
546
378
|
* ```
|
|
547
379
|
*/
|
|
548
|
-
declare function
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
380
|
+
declare function grantPromotionRewardForGame(params: {
|
|
381
|
+
params: {
|
|
382
|
+
promotionCode: string;
|
|
383
|
+
amount: number;
|
|
384
|
+
};
|
|
385
|
+
}): Promise<GrantPromotionRewardForGameResult>;
|
|
552
386
|
|
|
387
|
+
type Sku = {
|
|
388
|
+
/**
|
|
389
|
+
* @deprecated `productId`는 더 이상 사용하지 않아요. 대신 `sku`를 사용해요.
|
|
390
|
+
*/
|
|
391
|
+
productId: string;
|
|
392
|
+
sku?: string;
|
|
393
|
+
} | {
|
|
394
|
+
productId?: never;
|
|
395
|
+
sku: string;
|
|
396
|
+
};
|
|
553
397
|
/**
|
|
554
398
|
* @public
|
|
555
|
-
* @category
|
|
556
|
-
* @name
|
|
557
|
-
* @description
|
|
558
|
-
* @
|
|
559
|
-
* @property {
|
|
399
|
+
* @category 인앱결제
|
|
400
|
+
* @name IapCreateOneTimePurchaseOrderResult
|
|
401
|
+
* @description 인앱결제 1건이 완료되면 결제 세부 정보와 상품 정보를 담아 반환해요. 반환된 정보로 결제한 상품의 정보를 화면에 표시할 수 있어요.
|
|
402
|
+
* @property {string} orderId - 결제 주문 ID이에요. 결제 완료 후 [결제 상태를 조회](https://developers-apps-in-toss.toss.im/api/getIapOrderStatus.html)할 때 사용해요.
|
|
403
|
+
* @property {string} displayName - 화면에 표시할 상품 이름이에요.
|
|
404
|
+
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
405
|
+
* @property {number} amount - 상품 가격 숫자 값이에요. 화폐 단위와 쉼표를 제외한 순수 숫자예요. 예를 들어 `1000`으로 표시돼요.
|
|
406
|
+
* @property {string} currency - [ISO 4217 표준](https://ko.wikipedia.org/wiki/ISO_4217)에 따른 상품 가격 통화 단위예요. 예를 들어 원화는 `KRW`, 달러는 `USD`로 표시돼요.
|
|
407
|
+
* @property {number} fraction - 가격을 표시할 때 소수점 아래 몇 자리까지 보여줄지 정하는 값이에요. 예를 들어 달러는 소수점 둘째 자리까지 보여줘서 `2`, 원화는 소수점이 필요 없어서 `0`이에요
|
|
408
|
+
* @property {string | null} miniAppIconUrl - 미니앱 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요. 콘솔에서 아이콘을 등록하지 않았다면 `null`로 반환돼요.
|
|
560
409
|
*/
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
410
|
+
interface IapCreateOneTimePurchaseOrderResult {
|
|
411
|
+
orderId: string;
|
|
412
|
+
displayName: string;
|
|
413
|
+
displayAmount: string;
|
|
414
|
+
amount: number;
|
|
415
|
+
currency: string;
|
|
416
|
+
fraction: number;
|
|
417
|
+
miniAppIconUrl: string | null;
|
|
564
418
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
interface CheckoutPaymentOptions {
|
|
575
|
-
/**
|
|
576
|
-
* 결제 토큰이에요.
|
|
577
|
-
*/
|
|
578
|
-
payToken: string;
|
|
419
|
+
interface OneTimePurchaseSuccessEvent {
|
|
420
|
+
type: 'success';
|
|
421
|
+
data: IapCreateOneTimePurchaseOrderResult;
|
|
422
|
+
}
|
|
423
|
+
interface PurchasedEvent {
|
|
424
|
+
type: 'purchased';
|
|
425
|
+
data: {
|
|
426
|
+
orderId: string;
|
|
427
|
+
};
|
|
579
428
|
}
|
|
580
429
|
/**
|
|
581
430
|
* @public
|
|
582
|
-
* @category
|
|
583
|
-
* @name
|
|
584
|
-
* @
|
|
585
|
-
* @property {
|
|
586
|
-
* @property {string}
|
|
431
|
+
* @category 인앱결제
|
|
432
|
+
* @name IapCreateOneTimePurchaseOrderOptions
|
|
433
|
+
* @property {Sku} options - 결제할 상품의 정보예요.
|
|
434
|
+
* @property {string} options.sku - 주문할 상품의 고유 ID예요.
|
|
435
|
+
* @property {(params: { orderId: string }) => boolean | Promise<boolean>} processProductGrant - 주문이 만들어진 뒤 실제로 상품을 지급할 때 호출해요. `orderId`를 받아서 지급 성공 여부를 `true` 또는 `Promise<true>`로 반환해요. 지급에 실패하면 `false`를 반환해요.
|
|
436
|
+
* @property {(event: SuccessEvent) => void | Promise<void>} onEvent - 결제가 성공했을 때 호출해요. `event.type`이 `'success'`이고, `event.data`에 `IapCreateOneTimePurchaseOrderResult`가 들어 있어요.
|
|
437
|
+
* @property {(error: unknown) => void | Promise<void>} onError - 결제 과정에서 에러가 발생했을 때 호출해요. 에러 객체를 받아서 로깅하거나 복구 절차를 실행할 수 있어요.
|
|
587
438
|
*/
|
|
588
|
-
interface
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
439
|
+
interface IapCreateOneTimePurchaseOrderOptions {
|
|
440
|
+
options: Sku & {
|
|
441
|
+
processProductGrant: (params: {
|
|
442
|
+
orderId: string;
|
|
443
|
+
}) => boolean | Promise<boolean>;
|
|
444
|
+
};
|
|
445
|
+
onEvent: (event: OneTimePurchaseSuccessEvent) => void | Promise<void>;
|
|
446
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
447
|
+
}
|
|
448
|
+
interface IapRequestOneTimePurchaseOptions {
|
|
449
|
+
options: Sku;
|
|
450
|
+
onEvent: (event: PurchasedEvent | OneTimePurchaseSuccessEvent) => void | Promise<void>;
|
|
451
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
597
452
|
}
|
|
453
|
+
declare function iapCreateOneTimePurchaseOrder(params: Sku): Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
454
|
+
declare function processProductGrant(params: {
|
|
455
|
+
orderId: string;
|
|
456
|
+
isProductGranted: boolean;
|
|
457
|
+
}): Promise<void>;
|
|
458
|
+
declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions): () => void;
|
|
598
459
|
/**
|
|
599
460
|
* @public
|
|
600
|
-
* @category
|
|
601
|
-
* @name
|
|
602
|
-
* @description
|
|
603
|
-
*
|
|
604
|
-
*
|
|
461
|
+
* @category 인앱결제
|
|
462
|
+
* @name createOneTimePurchaseOrder
|
|
463
|
+
* @description
|
|
464
|
+
* 특정 인앱결제 주문서 페이지로 이동해요. 사용자가 상품 구매 버튼을 누르는 상황 등에 사용할 수 있어요. 사용자의 결제는 이동한 페이지에서 진행돼요. 만약 결제 중에 에러가 발생하면 에러 유형에 따라 에러 페이지로 이동해요.
|
|
465
|
+
* @param {IapCreateOneTimePurchaseOrderOptions} params - 인앱결제를 생성할 때 필요한 정보예요.
|
|
466
|
+
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 인앱결제 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
605
467
|
*
|
|
606
|
-
* @
|
|
607
|
-
* @
|
|
468
|
+
* @throw {code: "INVALID_PRODUCT_ID"} - 유효하지 않은 상품 ID이거나, 해당 상품이 존재하지 않을 때 발생해요.
|
|
469
|
+
* @throw {code: "PAYMENT_PENDING"} - 사용자가 요청한 결제가 아직 승인을 기다리고 있을 때 발생해요.
|
|
470
|
+
* @throw {code: "NETWORK_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
471
|
+
* @throw {code: "INVALID_USER_ENVIRONMENT"} - 특정 기기, 계정 또는 설정 환경에서 구매할 수 없는 상품일 때 발생해요.
|
|
472
|
+
* @throw {code: "ITEM_ALREADY_OWNED"} - 사용자가 이미 구매한 상품을 다시 구매하려고 할 때 발생해요.
|
|
473
|
+
* @throw {code: "APP_MARKET_VERIFICATION_FAILED"} - 사용자가 결제를 완료했지만, 앱스토어에서 사용자 정보 검증에 실패했을 때 발생해요. 사용자가 앱스토어에 문의해서 환불을 요청해야해요.
|
|
474
|
+
* @throw {code: "TOSS_SERVER_VERIFICATION_FAILED"} - 사용자가 결제를 완료했지만, 서버 전송에 실패해서 결제 정보를 저장할 수 없을 때 발생해요.
|
|
475
|
+
* @throw {code: "INTERNAL_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
476
|
+
* @throw {code: "KOREAN_ACCOUNT_ONLY"} - iOS 환경에서 사용자의 계정이 한국 계정이 아닐 때 발생해요.
|
|
477
|
+
* @throw {code: "USER_CANCELED"} - 사용자가 결제를 완료하지 않고 주문서 페이지를 이탈했을 때 발생해요.
|
|
478
|
+
* @throw {code: "PRODUCT_NOT_GRANTED_BY_PARTNER"} - 파트너사의 상품 지급이 실패했을 때 발생해요.
|
|
608
479
|
*
|
|
609
480
|
* @example
|
|
481
|
+
* ### 특정 인앱결제 주문서 페이지로 이동하기
|
|
610
482
|
*
|
|
611
|
-
*
|
|
483
|
+
* ```tsx
|
|
484
|
+
* import { IAP } from "@apps-in-toss/web-framework";
|
|
485
|
+
* import { Button } from "@toss/tds-react-native";
|
|
486
|
+
* import { useCallback } from "react";
|
|
487
|
+
*
|
|
488
|
+
* interface Props {
|
|
489
|
+
* sku: string;
|
|
490
|
+
* }
|
|
612
491
|
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
492
|
+
* function IapCreateOneTimePurchaseOrderButton({ sku }: Props) {
|
|
493
|
+
* const handleClick = useCallback(async () => {
|
|
615
494
|
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
495
|
+
* const cleanup = await IAP.createOneTimePurchaseOrder({
|
|
496
|
+
* options: {
|
|
497
|
+
* sku,
|
|
498
|
+
* processProductGrant: ({ orderId }) => {
|
|
499
|
+
* // 상품 지급 로직 작성
|
|
500
|
+
* return true; // 상품 지급 여부
|
|
501
|
+
* }
|
|
502
|
+
* },
|
|
503
|
+
* onEvent: (event) => {
|
|
504
|
+
* console.log(event);
|
|
505
|
+
* },
|
|
506
|
+
* onError: (error) => {
|
|
507
|
+
* console.error(error);
|
|
508
|
+
* },
|
|
509
|
+
* });
|
|
620
510
|
*
|
|
621
|
-
*
|
|
511
|
+
* return cleanup;
|
|
512
|
+
* }, []);
|
|
622
513
|
*
|
|
623
|
-
*
|
|
624
|
-
* // 실제 구현 시 결제를 실행하는 API 엔드포인트로 대체해주세요.
|
|
625
|
-
* await fetch('/my-api/payment/execute', {
|
|
626
|
-
* method: 'POST',
|
|
627
|
-
* body: JSON.stringify({ payToken }),
|
|
628
|
-
* headers: { 'Content-Type': 'application/json' },
|
|
629
|
-
* });
|
|
630
|
-
* } else {
|
|
631
|
-
* console.log('인증 실패:', reason);
|
|
632
|
-
* }
|
|
633
|
-
* } catch (error) {
|
|
634
|
-
* console.error('결제 인증 중 오류가 발생했어요:', error);
|
|
635
|
-
* }
|
|
514
|
+
* return <Button onClick={handleClick}>구매하기</Button>;
|
|
636
515
|
* }
|
|
637
516
|
* ```
|
|
638
517
|
*/
|
|
639
|
-
declare function
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
518
|
+
declare function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions): () => void;
|
|
519
|
+
interface BasicProductListItem {
|
|
520
|
+
sku: string;
|
|
521
|
+
displayAmount: string;
|
|
522
|
+
displayName: string;
|
|
523
|
+
iconUrl: string;
|
|
524
|
+
description: string;
|
|
644
525
|
}
|
|
526
|
+
type Offer = {
|
|
527
|
+
type: 'FREE_TRIAL';
|
|
528
|
+
offerId: string;
|
|
529
|
+
period: string;
|
|
530
|
+
} | {
|
|
531
|
+
type: 'NEW_SUBSCRIPTION';
|
|
532
|
+
offerId: string;
|
|
533
|
+
period: string;
|
|
534
|
+
displayAmount: string;
|
|
535
|
+
} | {
|
|
536
|
+
type: 'RETURNING';
|
|
537
|
+
offerId: string;
|
|
538
|
+
period: string;
|
|
539
|
+
displayAmount: string;
|
|
540
|
+
};
|
|
645
541
|
/**
|
|
646
542
|
* @public
|
|
647
|
-
* @category
|
|
648
|
-
* @name
|
|
649
|
-
* @description
|
|
650
|
-
*
|
|
651
|
-
* @
|
|
652
|
-
* @
|
|
653
|
-
* @
|
|
654
|
-
*
|
|
655
|
-
* @
|
|
656
|
-
* ```tsx
|
|
657
|
-
* import { appsInTossSignTossCert } from '@apps-in-toss/framework';
|
|
658
|
-
*
|
|
659
|
-
* // 서명에 필요한 파라미터를 정의해요.
|
|
660
|
-
* const params = {
|
|
661
|
-
* txId: "f2e1a6df..."
|
|
662
|
-
* };
|
|
663
|
-
*
|
|
664
|
-
* appsInTossSignTossCert(params)
|
|
665
|
-
* .then(() => {
|
|
666
|
-
* console.log('서명 작업이 성공적으로 완료되었어요.');
|
|
667
|
-
* })
|
|
668
|
-
* .catch((error) => {
|
|
669
|
-
* console.error('서명 작업 중 에러가 발생했어요:', error);
|
|
670
|
-
* });
|
|
671
|
-
* ```
|
|
543
|
+
* @category 인앱결제
|
|
544
|
+
* @name ConsumableProductListItem
|
|
545
|
+
* @description 소모품 상품 정보를 담은 객체예요.
|
|
546
|
+
* @property {string} sku - 상품의 고유 ID예요.
|
|
547
|
+
* @property {string} type - 상품의 유형이에요. `CONSUMABLE`을 나타내요.
|
|
548
|
+
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
549
|
+
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
550
|
+
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
551
|
+
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
672
552
|
*/
|
|
673
|
-
|
|
674
|
-
|
|
553
|
+
interface ConsumableProductListItem extends BasicProductListItem {
|
|
554
|
+
type: 'CONSUMABLE';
|
|
555
|
+
}
|
|
675
556
|
/**
|
|
676
|
-
* @
|
|
677
|
-
* @
|
|
678
|
-
* @
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
* @property {string}
|
|
682
|
-
* @property {string}
|
|
683
|
-
* @property {string}
|
|
557
|
+
* @public
|
|
558
|
+
* @category 인앱결제
|
|
559
|
+
* @name NonConsumableProductListItem
|
|
560
|
+
* @description 비소모품 상품 정보를 담은 객체예요.
|
|
561
|
+
* @property {string} sku - 상품의 고유 ID예요.
|
|
562
|
+
* @property {string} type - 상품의 유형이에요. `NON_CONSUMABLE`을 나타내요.
|
|
563
|
+
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
564
|
+
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
565
|
+
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
566
|
+
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
684
567
|
*/
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
688
|
-
statusCode: 'SUCCESS';
|
|
689
|
-
nickname: string;
|
|
690
|
-
profileImageUri: string;
|
|
691
|
-
};
|
|
568
|
+
interface NonConsumableProductListItem extends BasicProductListItem {
|
|
569
|
+
type: 'NON_CONSUMABLE';
|
|
570
|
+
}
|
|
692
571
|
/**
|
|
693
|
-
* @
|
|
694
|
-
* @
|
|
695
|
-
* @
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
* @
|
|
699
|
-
*
|
|
700
|
-
* @
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
*
|
|
707
|
-
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
710
|
-
* const handlePress = async () => {
|
|
711
|
-
* try {
|
|
712
|
-
* const result = await getGameCenterGameProfile();
|
|
713
|
-
* if (result) {
|
|
714
|
-
* setProfile(result);
|
|
715
|
-
* }
|
|
716
|
-
* } catch (error) {
|
|
717
|
-
* console.error('게임센터 프로필 가져오기에 실패했어요.', error);
|
|
718
|
-
* }
|
|
719
|
-
* };
|
|
720
|
-
*
|
|
721
|
-
* return (
|
|
722
|
-
* <View>
|
|
723
|
-
* <Button title="게임센터 프로필 가져오기" onPress={handlePress} />
|
|
724
|
-
* </View>
|
|
725
|
-
* );
|
|
726
|
-
* }
|
|
727
|
-
* ```
|
|
572
|
+
* @public
|
|
573
|
+
* @category 인앱결제
|
|
574
|
+
* @name SubscriptionProductListItem
|
|
575
|
+
* @description 자동 갱신 구독 상품 정보를 담은 객체예요.
|
|
576
|
+
* @property {string} sku - 상품의 고유 ID예요.
|
|
577
|
+
* @property {string} type - 상품의 유형이에요. `SUBSCRIPTION`을 나타내요.
|
|
578
|
+
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
579
|
+
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
580
|
+
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
581
|
+
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
582
|
+
* @property {string} renewalCycle - 구독 갱신 주기이에요. `WEEKLY`, `MONTHLY`, `YEARLY` 중 하나를 나타내요.
|
|
583
|
+
* @property {Offer[]} offers - 구독 혜택 옵션 목록이에요. 각 옵션은 하나의 구독 혜택을 나타내요.
|
|
584
|
+
* @property {string} offers[].type - 구독 혜택 옵션 유형이에요. `FREE_TRIAL`, `NEW_SUBSCRIPTION`, `RETURNING` 중 하나를 나타내요.
|
|
585
|
+
* @property {string} offers[].offerId - 구독 혜택 옵션의 고유 ID예요.
|
|
586
|
+
* @property {string} offers[].period - 구독 혜택 옵션의 적용 기간이에요.
|
|
587
|
+
* @property {string} offers[].displayAmount - 통화 단위가 포함된 구독 혜택 옵션의 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
728
588
|
*/
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
type: 'HASH';
|
|
734
|
-
}
|
|
735
|
-
interface GetUserKeyForGameErrorResponse {
|
|
736
|
-
type: 'NOT_AVAILABLE';
|
|
589
|
+
interface SubscriptionProductListItem extends BasicProductListItem {
|
|
590
|
+
type: 'SUBSCRIPTION';
|
|
591
|
+
renewalCycle: 'WEEKLY' | 'MONTHLY' | 'YEARLY';
|
|
592
|
+
offers?: Offer[];
|
|
737
593
|
}
|
|
738
|
-
type GetUserKeyForGameResponse = GetUserKeyForGameSuccessResponse | GetUserKeyForGameErrorResponse;
|
|
739
594
|
/**
|
|
740
595
|
* @public
|
|
741
|
-
* @category
|
|
742
|
-
* @name
|
|
743
|
-
* @description
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
596
|
+
* @category 인앱결제
|
|
597
|
+
* @name IapProductListItem
|
|
598
|
+
* @description 인앱결제로 구매할 수 있는 상품 하나의 정보를 담은 객체예요. 상품 목록을 화면에 표시할 때 사용해요.
|
|
599
|
+
*/
|
|
600
|
+
type IapProductListItem = ConsumableProductListItem | NonConsumableProductListItem | SubscriptionProductListItem;
|
|
601
|
+
/**
|
|
602
|
+
* @public
|
|
603
|
+
* @category 인앱결제
|
|
604
|
+
* @name getProductItemList
|
|
605
|
+
* @description 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 상품 목록 화면에 진입할 때 호출해요.
|
|
606
|
+
* @returns {Promise<{ products: IapProductListItem[] } | undefined>} 상품 목록을 포함한 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 `undefined`를 반환해요.
|
|
752
607
|
*
|
|
753
608
|
* @example
|
|
754
|
-
*
|
|
755
|
-
* // react-native
|
|
756
|
-
* import { Button } from 'react-native';
|
|
757
|
-
* import { getUserKeyForGame } from '@apps-in-toss/framework';
|
|
758
|
-
*
|
|
759
|
-
* function GameUserKeyButton() {
|
|
760
|
-
* async function handlePress() {
|
|
761
|
-
* const result = await getUserKeyForGame();
|
|
762
|
-
*
|
|
763
|
-
* if (!result) {
|
|
764
|
-
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
765
|
-
* return;
|
|
766
|
-
* }
|
|
767
|
-
*
|
|
768
|
-
* if (result === 'INVALID_CATEGORY') {
|
|
769
|
-
* console.error('게임 카테고리가 아닌 미니앱이에요.');
|
|
770
|
-
* return;
|
|
771
|
-
* }
|
|
772
|
-
*
|
|
773
|
-
* if (result === 'ERROR') {
|
|
774
|
-
* console.error('사용자 키 조회 중 오류가 발생했어요.');
|
|
775
|
-
* return;
|
|
776
|
-
* }
|
|
777
|
-
*
|
|
778
|
-
* if (result.type === 'HASH') {
|
|
779
|
-
* console.log('사용자 키:', result.hash);
|
|
780
|
-
* // 여기에서 사용자 키를 사용해 게임 데이터를 관리할 수 있어요.
|
|
781
|
-
* }
|
|
782
|
-
* }
|
|
783
|
-
*
|
|
784
|
-
* return (
|
|
785
|
-
* <Button onPress={handlePress} title="유저 키 가져오기" />
|
|
786
|
-
* );
|
|
787
|
-
* }
|
|
788
|
-
* ```
|
|
609
|
+
* ### 구매 가능한 인앱결제 상품목록 가져오기
|
|
789
610
|
*
|
|
790
|
-
* @example
|
|
791
611
|
* ```tsx
|
|
792
|
-
*
|
|
793
|
-
* import {
|
|
612
|
+
* import { IAP, IapProductListItem } from "@apps-in-toss/framework";
|
|
613
|
+
* import { Button, List, ListRow } from "@toss/tds-react-native";
|
|
614
|
+
* import { useEffect, useState } from "react";
|
|
794
615
|
*
|
|
795
|
-
* function
|
|
796
|
-
*
|
|
797
|
-
* const result = await getUserKeyForGame();
|
|
616
|
+
* function IapProductList() {
|
|
617
|
+
* const [products, setProducts] = useState<IapProductListItem[]>([]);
|
|
798
618
|
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
801
|
-
*
|
|
802
|
-
*
|
|
619
|
+
* async function buyIapProduct(productId: string) {
|
|
620
|
+
* try {
|
|
621
|
+
* await IAP.createOneTimePurchaseOrder({
|
|
622
|
+
* productId,
|
|
623
|
+
* });
|
|
803
624
|
*
|
|
804
|
-
*
|
|
805
|
-
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
625
|
+
* console.error("인앱결제에 성공했어요");
|
|
626
|
+
* } catch (error) {
|
|
627
|
+
* console.error("인앱결제에 실패했어요:", error);
|
|
628
|
+
* }
|
|
629
|
+
* }
|
|
808
630
|
*
|
|
809
|
-
*
|
|
810
|
-
*
|
|
811
|
-
*
|
|
631
|
+
* useEffect(() => {
|
|
632
|
+
* async function fetchProducts() {
|
|
633
|
+
* try {
|
|
634
|
+
* const response = await IAP.getProductItemList();
|
|
635
|
+
* setProducts(response?.products ?? []);
|
|
636
|
+
* } catch (error) {
|
|
637
|
+
* console.error("상품 목록을 가져오는 데 실패했어요:", error);
|
|
812
638
|
* }
|
|
639
|
+
* }
|
|
813
640
|
*
|
|
814
|
-
*
|
|
815
|
-
*
|
|
816
|
-
* // 여기에서 사용자 키를 사용해 게임 데이터를 관리할 수 있어요.
|
|
817
|
-
* }
|
|
818
|
-
* }
|
|
641
|
+
* fetchProducts();
|
|
642
|
+
* }, []);
|
|
819
643
|
*
|
|
820
644
|
* return (
|
|
821
|
-
* <
|
|
645
|
+
* <List>
|
|
646
|
+
* {products.map((product) => (
|
|
647
|
+
* <ListRow
|
|
648
|
+
* key={product.sku}
|
|
649
|
+
* left={
|
|
650
|
+
* <ListRow.Image type="square" source={{ uri: product.iconUrl }} />
|
|
651
|
+
* }
|
|
652
|
+
* right={
|
|
653
|
+
* <Button size="medium" onPress={() => buyIapProduct(product.sku)}>
|
|
654
|
+
* 구매하기
|
|
655
|
+
* </Button>
|
|
656
|
+
* }
|
|
657
|
+
* contents={
|
|
658
|
+
* <ListRow.Texts
|
|
659
|
+
* type="3RowTypeA"
|
|
660
|
+
* top={product.displayName}
|
|
661
|
+
* middle={product.description}
|
|
662
|
+
* bottom={product.displayAmount}
|
|
663
|
+
* />
|
|
664
|
+
* }
|
|
665
|
+
* />
|
|
666
|
+
* ))}
|
|
667
|
+
* </List>
|
|
822
668
|
* );
|
|
823
669
|
* }
|
|
824
670
|
* ```
|
|
825
671
|
*/
|
|
826
|
-
declare function
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
key: string;
|
|
830
|
-
}
|
|
831
|
-
interface GrantPromotionRewardForGameErrorResponse {
|
|
832
|
-
code: string;
|
|
833
|
-
[key: string]: any;
|
|
834
|
-
}
|
|
835
|
-
interface GrantPromotionRewardForGameErrorResult {
|
|
836
|
-
errorCode: string;
|
|
837
|
-
message: string;
|
|
838
|
-
}
|
|
839
|
-
type GrantPromotionRewardForGameResponse = GrantPromotionRewardForGameSuccessResponse | GrantPromotionRewardForGameErrorResponse;
|
|
840
|
-
type GrantPromotionRewardForGameResult = GrantPromotionRewardForGameResponse | GrantPromotionRewardForGameErrorResult | 'ERROR' | undefined;
|
|
672
|
+
declare function getProductItemList(): Promise<{
|
|
673
|
+
products: any[];
|
|
674
|
+
} | undefined>;
|
|
841
675
|
/**
|
|
842
676
|
* @public
|
|
843
|
-
* @category
|
|
844
|
-
* @name
|
|
845
|
-
* @description
|
|
846
|
-
*
|
|
847
|
-
* 게임 카테고리가 아닌 미니앱에서 호출할 수 없어요.
|
|
848
|
-
* @param {{ params: { promotionCode: string; amount: number } }} params - 포인트를 지급하기 위해 필요한 정보예요.
|
|
849
|
-
* @param {string} params.promotionCode - 프로모션 코드예요.
|
|
850
|
-
* @param {number} params.amount - 지급할 포인트 금액이에요.
|
|
851
|
-
* @returns {Promise<{ key: string } | { errorCode: string; message: string } | 'ERROR' | undefined>}
|
|
852
|
-
* 포인트 지급 결과를 반환해요.
|
|
853
|
-
* - `{ key: string }`: 포인트 지급에 성공했어요. key는 리워드 키를 의미해요.
|
|
854
|
-
* - `{ errorCode: string, message: string }`: 포인트 지급에 실패했어요. 에러 코드는 다음과 같아요.
|
|
855
|
-
* - `"40000"`: 게임이 아닌 미니앱에서 호출했을 때
|
|
856
|
-
* - `"4100"`: 프로모션 정보를 찾을 수 없을 때
|
|
857
|
-
* - `"4104"`: 프로모션이 중지되었을 때
|
|
858
|
-
* - `"4105"`: 프로모션이 종료되었을 때
|
|
859
|
-
* - `"4108"`: 프로모션이 승인되지 않았을 때
|
|
860
|
-
* - `"4109"`: 프로모션이 실행중이 아닐 때
|
|
861
|
-
* - `"4110"`: 리워드를 지급/회수할 수 없을 때
|
|
862
|
-
* - `"4112"`: 프로모션 머니가 부족할 때
|
|
863
|
-
* - `"4113"`: 이미 지급/회수된 내역일 때
|
|
864
|
-
* - `"4114"`: 프로모션에 설정된 1회 지급 금액을 초과할 때
|
|
865
|
-
* - `'ERROR'`: 알 수 없는 오류가 발생했어요.
|
|
866
|
-
* - `undefined`: 앱 버전이 최소 지원 버전보다 낮아요.
|
|
867
|
-
* @example
|
|
868
|
-
* ```tsx
|
|
869
|
-
* // react-native
|
|
870
|
-
* import { Button } from 'react-native';
|
|
871
|
-
* import { grantPromotionRewardForGame } from '@apps-in-toss/framework';
|
|
872
|
-
*
|
|
873
|
-
* function GrantRewardButton() {
|
|
874
|
-
* async function handlePress() {
|
|
875
|
-
* const result = await grantPromotionRewardForGame({
|
|
876
|
-
* params: {
|
|
877
|
-
* promotionCode: 'GAME_EVENT_2024',
|
|
878
|
-
* amount: 1000,
|
|
879
|
-
* },
|
|
880
|
-
* });
|
|
881
|
-
*
|
|
882
|
-
* if (!result) {
|
|
883
|
-
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
884
|
-
* return;
|
|
885
|
-
* }
|
|
677
|
+
* @category 인앱결제
|
|
678
|
+
* @name getPendingOrders
|
|
679
|
+
* @description 대기 중인 주문 목록을 가져와요. 이 함수를 사용하면 결제가 아직 완료되지 않은 주문 정보를 확인할 수 있어요.
|
|
680
|
+
* @returns {Promise<{ orders: { orderId: string; sku: string; paymentCompletedDate: string; }[]}>} 대기 중인 주문의 배열을 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.234.0, iOS 5.231.0)보다 낮으면 `undefined`를 반환해요.
|
|
886
681
|
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
682
|
+
* @example
|
|
683
|
+
* ### 대기 중인 주문 목록 가져오기
|
|
684
|
+
* ```typescript
|
|
685
|
+
* import { IAP } from '@apps-in-toss/framework';
|
|
891
686
|
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
896
|
-
*
|
|
687
|
+
* async function fetchOrders() {
|
|
688
|
+
* try {
|
|
689
|
+
* const pendingOrders = await IAP.getPendingOrders();
|
|
690
|
+
* return pendingOrders;
|
|
691
|
+
* } catch (error) {
|
|
692
|
+
* console.error(error);
|
|
897
693
|
* }
|
|
898
|
-
*
|
|
899
|
-
* return <Button onPress={handlePress} title="포인트 지급하기" />;
|
|
900
694
|
* }
|
|
901
695
|
* ```
|
|
696
|
+
*/
|
|
697
|
+
declare function getPendingOrders(): Promise<{
|
|
698
|
+
orders: Array<{
|
|
699
|
+
orderId: string;
|
|
700
|
+
sku: string;
|
|
701
|
+
}>;
|
|
702
|
+
} | undefined>;
|
|
703
|
+
/**
|
|
704
|
+
* @public
|
|
705
|
+
* @category 인앱결제
|
|
706
|
+
* @name CompletedOrRefundedOrdersResult
|
|
707
|
+
* @description 인앱결제로 구매하거나 환불한 주문 목록을 나타내는 객체예요. 페이지네이션 정보를 포함해요.
|
|
708
|
+
* @property {boolean} hasNext 다음 페이지가 있는지 여부예요. `true`면 더 많은 주문이 남아 있어요.
|
|
709
|
+
* @property {string | null} [nextKey] 다음 주문 목록을 조회할 때 사용할 키예요. 마지막 페이지라면 `null`이거나 생략될 수 있어요.
|
|
710
|
+
* @property {Array} orders 주문 정보를 담은 배열이에요. 각 요소는 하나의 주문을 나타내요.
|
|
711
|
+
* @property {string} orders[].orderId 주문의 고유 ID예요.
|
|
712
|
+
* @property {string} orders[].sku 주문 상품의 고유 ID예요.
|
|
713
|
+
* @property {'COMPLETED' | 'REFUNDED'} orders[].status 주문의 상태예요. 'COMPLETED'는 주문이 완료된 상태, 'REFUNDED'는 환불된 상태를 의미해요.
|
|
714
|
+
* @property {string} orders[].date 주문의 날짜 정보예요. ISO 8601 형식(YYYY-MM-DDTHH:mm:ss)을 사용해요. 예를 들어 "2025-09-22T00:00:00" 형식으로 제공돼요. 주문 상태가 `COMPLETED`라면 주문한 날짜를, `REFUNDED`라면 환불한 날짜를 나타내요.
|
|
715
|
+
*/
|
|
716
|
+
interface CompletedOrRefundedOrdersResult {
|
|
717
|
+
hasNext: boolean;
|
|
718
|
+
nextKey?: string | null;
|
|
719
|
+
orders: {
|
|
720
|
+
orderId: string;
|
|
721
|
+
sku: string;
|
|
722
|
+
status: 'COMPLETED' | 'REFUNDED';
|
|
723
|
+
date: string;
|
|
724
|
+
}[];
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* @public
|
|
728
|
+
* @category 인앱결제
|
|
729
|
+
* @name getCompletedOrRefundedOrders
|
|
730
|
+
* @description 인앱결제로 구매하거나 환불한 주문 목록을 가져와요.
|
|
731
|
+
* @returns {Promise<CompletedOrRefundedOrdersResult>} 페이지네이션을 포함한 주문 목록 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.231.0, iOS 5.231.0)보다 낮으면 `undefined`를 반환해요.
|
|
902
732
|
*
|
|
903
733
|
* @example
|
|
904
|
-
* ```
|
|
905
|
-
*
|
|
906
|
-
* import { grantPromotionRewardForGame } from '@apps-in-toss/web-framework';
|
|
907
|
-
*
|
|
908
|
-
* function GrantRewardButton() {
|
|
909
|
-
* async function handleClick() {
|
|
910
|
-
* const result = await grantPromotionRewardForGame({
|
|
911
|
-
* params: {
|
|
912
|
-
* promotionCode: 'GAME_EVENT_2024',
|
|
913
|
-
* amount: 1000,
|
|
914
|
-
* },
|
|
915
|
-
* });
|
|
916
|
-
*
|
|
917
|
-
* if (!result) {
|
|
918
|
-
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
919
|
-
* return;
|
|
920
|
-
* }
|
|
921
|
-
*
|
|
922
|
-
* if (result === 'ERROR') {
|
|
923
|
-
* console.error('포인트 지급 중 알 수 없는 오류가 발생했어요.');
|
|
924
|
-
* return;
|
|
925
|
-
* }
|
|
734
|
+
* ```typescript
|
|
735
|
+
* import { IAP } from "@apps-in-toss/framework";
|
|
926
736
|
*
|
|
927
|
-
*
|
|
928
|
-
*
|
|
929
|
-
*
|
|
930
|
-
*
|
|
931
|
-
*
|
|
737
|
+
* async function fetchOrders() {
|
|
738
|
+
* try {
|
|
739
|
+
* const response = await IAP.getCompletedOrRefundedOrders();
|
|
740
|
+
* return response;
|
|
741
|
+
* } catch (error) {
|
|
742
|
+
* console.error(error);
|
|
932
743
|
* }
|
|
933
|
-
*
|
|
934
|
-
* return (
|
|
935
|
-
* <button onClick={handleClick}>포인트 지급하기</button>
|
|
936
|
-
* );
|
|
937
744
|
* }
|
|
938
745
|
* ```
|
|
939
746
|
*/
|
|
940
|
-
declare function
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
amount: number;
|
|
944
|
-
};
|
|
945
|
-
}): Promise<GrantPromotionRewardForGameResult>;
|
|
946
|
-
|
|
947
|
-
type Sku = {
|
|
948
|
-
/**
|
|
949
|
-
* @deprecated `productId`는 더 이상 사용하지 않아요. 대신 `sku`를 사용해요.
|
|
950
|
-
*/
|
|
951
|
-
productId: string;
|
|
952
|
-
sku?: string;
|
|
953
|
-
} | {
|
|
954
|
-
productId?: never;
|
|
955
|
-
sku: string;
|
|
956
|
-
};
|
|
747
|
+
declare function getCompletedOrRefundedOrders(params?: {
|
|
748
|
+
key?: string | null;
|
|
749
|
+
}): Promise<any>;
|
|
957
750
|
/**
|
|
958
|
-
* @public
|
|
959
|
-
* @category 인앱결제
|
|
960
|
-
* @name
|
|
961
|
-
* @description
|
|
962
|
-
* @
|
|
963
|
-
* @
|
|
964
|
-
* @
|
|
965
|
-
*
|
|
966
|
-
* @
|
|
967
|
-
*
|
|
968
|
-
*
|
|
751
|
+
* @public
|
|
752
|
+
* @category 인앱결제
|
|
753
|
+
* @name completeProductGrant
|
|
754
|
+
* @description 상품 지급 처리를 완료했다는 메시지를 앱에 전달해요. 이 함수를 사용하면 결제가 완료된 주문의 상품 지급이 정상적으로 완료되었음을 알릴 수 있어요.
|
|
755
|
+
* @param {{ params: { orderId: string } }} params 결제가 완료된 주문 정보를 담은 객체예요.
|
|
756
|
+
* @param {string} params.orderId 주문의 고유 ID예요. 상품 지급을 완료할 주문을 지정할 때 사용해요.
|
|
757
|
+
* @returns {Promise<boolean>} 상품 지급이 완료됐는지 여부를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.233.0, iOS 5.233.0)보다 낮으면 `undefined`를 반환해요.
|
|
758
|
+
*
|
|
759
|
+
* @example
|
|
760
|
+
* ### 결제를 성공한 뒤 상품을 지급하는 예시
|
|
761
|
+
* ```typescript
|
|
762
|
+
* import { IAP } from '@apps-in-toss/framework';
|
|
763
|
+
*
|
|
764
|
+
* async function handleGrantProduct(orderId: string) {
|
|
765
|
+
* try {
|
|
766
|
+
* await IAP.completeProductGrant({ params: { orderId } });
|
|
767
|
+
* } catch (error) {
|
|
768
|
+
* console.error(error);
|
|
769
|
+
* }
|
|
770
|
+
* }
|
|
771
|
+
* ```
|
|
969
772
|
*/
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
displayName: string;
|
|
973
|
-
displayAmount: string;
|
|
974
|
-
amount: number;
|
|
975
|
-
currency: string;
|
|
976
|
-
fraction: number;
|
|
977
|
-
miniAppIconUrl: string | null;
|
|
978
|
-
}
|
|
979
|
-
interface OneTimePurchaseSuccessEvent {
|
|
980
|
-
type: 'success';
|
|
981
|
-
data: IapCreateOneTimePurchaseOrderResult;
|
|
982
|
-
}
|
|
983
|
-
interface PurchasedEvent {
|
|
984
|
-
type: 'purchased';
|
|
985
|
-
data: {
|
|
773
|
+
declare function completeProductGrant(params: {
|
|
774
|
+
params: {
|
|
986
775
|
orderId: string;
|
|
987
776
|
};
|
|
988
|
-
}
|
|
777
|
+
}): Promise<boolean | undefined>;
|
|
989
778
|
/**
|
|
990
779
|
* @public
|
|
991
780
|
* @category 인앱결제
|
|
992
|
-
* @name
|
|
993
|
-
* @
|
|
994
|
-
* @property {
|
|
995
|
-
* @property {
|
|
996
|
-
* @property {
|
|
997
|
-
* @property {(
|
|
781
|
+
* @name CreateSubscriptionPurchaseOrderOptions
|
|
782
|
+
* @description 구독 인앱결제를 생성할 때 필요한 옵션이에요.
|
|
783
|
+
* @property {object} options - 결제할 구독 상품의 정보예요.
|
|
784
|
+
* @property {string} options.sku - 주문할 구독 상품의 고유 ID예요.
|
|
785
|
+
* @property {string | null} [options.offerId] - 적용할 offer ID예요. 없으면 기본 가격이 적용돼요.
|
|
786
|
+
* @property {(params: { orderId: string, subscriptionId?: string }) => boolean | Promise<boolean>} options.processProductGrant - 주문이 만들어진 뒤 실제로 상품을 지급할 때 호출해요.
|
|
787
|
+
* @property {(event: SubscriptionSuccessEvent) => void | Promise<void>} onEvent - 결제가 성공했을 때 호출해요.
|
|
788
|
+
* @property {(error: unknown) => void | Promise<void>} onError - 결제 과정에서 에러가 발생했을 때 호출해요.
|
|
998
789
|
*/
|
|
999
|
-
interface
|
|
1000
|
-
options:
|
|
790
|
+
interface CreateSubscriptionPurchaseOrderOptions {
|
|
791
|
+
options: {
|
|
792
|
+
sku: string;
|
|
793
|
+
offerId?: string | null;
|
|
1001
794
|
processProductGrant: (params: {
|
|
1002
795
|
orderId: string;
|
|
796
|
+
subscriptionId?: string;
|
|
1003
797
|
}) => boolean | Promise<boolean>;
|
|
1004
798
|
};
|
|
1005
|
-
onEvent: (event:
|
|
799
|
+
onEvent: (event: SubscriptionSuccessEvent) => void | Promise<void>;
|
|
1006
800
|
onError: (error: unknown) => void | Promise<void>;
|
|
1007
801
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
802
|
+
/**
|
|
803
|
+
* @public
|
|
804
|
+
* @category 인앱결제
|
|
805
|
+
* @name IapCreateSubscriptionPurchaseOrderResult
|
|
806
|
+
* @description 구독 인앱결제가 완료되면 결제 세부 정보와 상품 정보를 담아 반환해요. `IapCreateOneTimePurchaseOrderResult`와 동일한 구조예요.
|
|
807
|
+
*/
|
|
808
|
+
type IapCreateSubscriptionPurchaseOrderResult = IapCreateOneTimePurchaseOrderResult;
|
|
809
|
+
interface SubscriptionSuccessEvent {
|
|
810
|
+
type: 'success';
|
|
811
|
+
data: IapCreateSubscriptionPurchaseOrderResult;
|
|
1012
812
|
}
|
|
1013
|
-
declare function iapCreateOneTimePurchaseOrder(params: Sku): Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1014
|
-
declare function processProductGrant(params: {
|
|
1015
|
-
orderId: string;
|
|
1016
|
-
isProductGranted: boolean;
|
|
1017
|
-
}): Promise<void>;
|
|
1018
|
-
declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions): () => void;
|
|
1019
813
|
/**
|
|
1020
814
|
* @public
|
|
1021
815
|
* @category 인앱결제
|
|
1022
|
-
* @name
|
|
816
|
+
* @name createSubscriptionPurchaseOrder
|
|
1023
817
|
* @description
|
|
1024
|
-
*
|
|
1025
|
-
* @param {
|
|
818
|
+
* 구독 인앱결제 주문서 페이지로 이동해요. 사용자가 구독 상품 구매 버튼을 누르는 상황 등에 사용할 수 있어요.
|
|
819
|
+
* @param {CreateSubscriptionPurchaseOrderOptions} params - 구독 인앱결제를 생성할 때 필요한 정보예요.
|
|
1026
820
|
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 인앱결제 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
1027
821
|
*
|
|
1028
|
-
* @throw {code: "INVALID_PRODUCT_ID"} - 유효하지 않은 상품 ID이거나, 해당 상품이 존재하지 않을 때 발생해요.
|
|
1029
|
-
* @throw {code: "PAYMENT_PENDING"} - 사용자가 요청한 결제가 아직 승인을 기다리고 있을 때 발생해요.
|
|
1030
|
-
* @throw {code: "NETWORK_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
1031
|
-
* @throw {code: "INVALID_USER_ENVIRONMENT"} - 특정 기기, 계정 또는 설정 환경에서 구매할 수 없는 상품일 때 발생해요.
|
|
1032
|
-
* @throw {code: "ITEM_ALREADY_OWNED"} - 사용자가 이미 구매한 상품을 다시 구매하려고 할 때 발생해요.
|
|
1033
|
-
* @throw {code: "APP_MARKET_VERIFICATION_FAILED"} - 사용자가 결제를 완료했지만, 앱스토어에서 사용자 정보 검증에 실패했을 때 발생해요. 사용자가 앱스토어에 문의해서 환불을 요청해야해요.
|
|
1034
|
-
* @throw {code: "TOSS_SERVER_VERIFICATION_FAILED"} - 사용자가 결제를 완료했지만, 서버 전송에 실패해서 결제 정보를 저장할 수 없을 때 발생해요.
|
|
1035
|
-
* @throw {code: "INTERNAL_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
1036
|
-
* @throw {code: "KOREAN_ACCOUNT_ONLY"} - iOS 환경에서 사용자의 계정이 한국 계정이 아닐 때 발생해요.
|
|
1037
|
-
* @throw {code: "USER_CANCELED"} - 사용자가 결제를 완료하지 않고 주문서 페이지를 이탈했을 때 발생해요.
|
|
1038
|
-
* @throw {code: "PRODUCT_NOT_GRANTED_BY_PARTNER"} - 파트너사의 상품 지급이 실패했을 때 발생해요.
|
|
1039
|
-
*
|
|
1040
822
|
* @example
|
|
1041
|
-
* ###
|
|
823
|
+
* ### 구독 인앱결제 주문서 페이지로 이동하기
|
|
1042
824
|
*
|
|
1043
825
|
* ```tsx
|
|
1044
826
|
* import { IAP } from "@apps-in-toss/web-framework";
|
|
@@ -1047,19 +829,20 @@ declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions
|
|
|
1047
829
|
*
|
|
1048
830
|
* interface Props {
|
|
1049
831
|
* sku: string;
|
|
832
|
+
* offerId?: string;
|
|
1050
833
|
* }
|
|
1051
834
|
*
|
|
1052
|
-
* function
|
|
835
|
+
* function SubscriptionPurchaseButton({ sku, offerId }: Props) {
|
|
1053
836
|
* const handleClick = useCallback(async () => {
|
|
1054
|
-
*
|
|
1055
|
-
* const cleanup = await IAP.createOneTimePurchaseOrder({
|
|
837
|
+
* const cleanup = IAP.createSubscriptionPurchaseOrder({
|
|
1056
838
|
* options: {
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
1059
|
-
*
|
|
1060
|
-
*
|
|
1061
|
-
*
|
|
1062
|
-
*
|
|
839
|
+
* sku,
|
|
840
|
+
* offerId,
|
|
841
|
+
* processProductGrant: ({ orderId, subscriptionId }) => {
|
|
842
|
+
* // 상품 지급 로직 작성
|
|
843
|
+
* return true; // 상품 지급 여부
|
|
844
|
+
* },
|
|
845
|
+
* },
|
|
1063
846
|
* onEvent: (event) => {
|
|
1064
847
|
* console.log(event);
|
|
1065
848
|
* },
|
|
@@ -1069,606 +852,854 @@ declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions
|
|
|
1069
852
|
* });
|
|
1070
853
|
*
|
|
1071
854
|
* return cleanup;
|
|
1072
|
-
* }, []);
|
|
855
|
+
* }, [sku, offerId]);
|
|
1073
856
|
*
|
|
1074
|
-
* return <Button onClick={handleClick}
|
|
857
|
+
* return <Button onClick={handleClick}>구독하기</Button>;
|
|
1075
858
|
* }
|
|
1076
859
|
* ```
|
|
1077
860
|
*/
|
|
1078
|
-
declare function
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
offerId: string;
|
|
1098
|
-
period: string;
|
|
1099
|
-
displayAmount: string;
|
|
861
|
+
declare function createSubscriptionPurchaseOrder(params: CreateSubscriptionPurchaseOrderOptions): () => void;
|
|
862
|
+
/**
|
|
863
|
+
* @public
|
|
864
|
+
* @category 인앱결제
|
|
865
|
+
* @name IAP
|
|
866
|
+
* @description 인앱결제 관련 기능을 모은 객체예요. 단건 인앱결제 주문서 이동과 상품 목록 조회 기능을 제공해요.
|
|
867
|
+
* @property {typeof createOneTimePurchaseOrder} [createOneTimePurchaseOrder] 특정 인앱결제 주문서 페이지로 이동해요. 자세한 내용은 [createOneTimePurchaseOrder](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/createOneTimePurchaseOrder.html) 문서를 참고하세요.
|
|
868
|
+
* @property {typeof getProductItemList} [getProductItemList] 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 자세한 내용은 [getProductItemList](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getProductItemList.html) 문서를 참고하세요.
|
|
869
|
+
* @property {typeof getPendingOrders} [getPendingOrders] 대기 중인 주문 목록을 가져와요. 자세한 내용은 [getPendingOrders](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getPendingOrders.htm) 문서를 참고하세요.
|
|
870
|
+
* @property {typeof getCompletedOrRefundedOrders} [getCompletedOrRefundedOrders] 인앱결제로 구매하거나 환불한 주문 목록을 가져와요. 자세한 내용은 [getCompletedOrRefundedOrders](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getCompletedOrRefundedOrders.html) 문서를 참고하세요.
|
|
871
|
+
* @property {typeof completeProductGrant} [completeProductGrant] 상품 지급 처리를 완료했다는 메시지를 앱에 전달해요. 자세한 내용은 [completeProductGrant](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/completeProductGrant.html) 문서를 참고하세요.
|
|
872
|
+
*/
|
|
873
|
+
declare const IAP: {
|
|
874
|
+
createOneTimePurchaseOrder: typeof createOneTimePurchaseOrder;
|
|
875
|
+
createSubscriptionPurchaseOrder: typeof createSubscriptionPurchaseOrder;
|
|
876
|
+
getProductItemList: typeof getProductItemList;
|
|
877
|
+
getPendingOrders: typeof getPendingOrders;
|
|
878
|
+
getCompletedOrRefundedOrders: typeof getCompletedOrRefundedOrders;
|
|
879
|
+
completeProductGrant: typeof completeProductGrant;
|
|
1100
880
|
};
|
|
881
|
+
|
|
882
|
+
interface SaveBase64DataParams {
|
|
883
|
+
data: string;
|
|
884
|
+
fileName: string;
|
|
885
|
+
mimeType: string;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* @public
|
|
889
|
+
* @category 데이터
|
|
890
|
+
* @name saveBase64Data
|
|
891
|
+
* @description 문자열로 인코딩된 Base64 데이터를 지정한 파일 이름과 MIME 타입으로 사용자 기기에 저장해요. 이미지, 텍스트, PDF 등 다양한 형식의 데이터를 저장할 수 있어요.
|
|
892
|
+
* @param {SaveBase64DataParams} params - 저장할 데이터와 파일 정보를 담은 객체예요.
|
|
893
|
+
* @param {string} params.data - Base64 형식으로 인코딩된 데이터 문자열이에요.
|
|
894
|
+
* @param {string} params.fileName - 저장할 파일 이름이에요. 확장자도 같이 붙여줘야해요. 예를 들어, 'example.png'로 저장할 수 있어요.
|
|
895
|
+
* @param {string} params.mimeType - 저장할 파일의 MIME 타입이에요. 예를 들어 'image/png' 로 지정하면 이미지, 'application/pdf'는 PDF 파일이에요. 자세한 내용은 [MIME 문서](https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/MIME_types)를 참고해주세요.
|
|
896
|
+
*
|
|
897
|
+
* @example
|
|
898
|
+
* ### Base64 이미지 데이터를 사용자 기기에 저장하기
|
|
899
|
+
*
|
|
900
|
+
* ```tsx
|
|
901
|
+
* import { Button } from 'react-native';
|
|
902
|
+
* import { saveBase64Data } from '@apps-in-toss/framework';
|
|
903
|
+
*
|
|
904
|
+
* // '저장' 버튼을 누르면 이미지가 사용자 기기에 저장돼요.
|
|
905
|
+
* function SaveButton() {
|
|
906
|
+
* const handleSave = async () => {
|
|
907
|
+
* try {
|
|
908
|
+
* await saveBase64Data({
|
|
909
|
+
* data: 'iVBORw0KGgo...',
|
|
910
|
+
* fileName: 'some-photo.png',
|
|
911
|
+
* mimeType: 'image/png',
|
|
912
|
+
* });
|
|
913
|
+
* } catch (error) {
|
|
914
|
+
* console.error('데이터 저장에 실패했어요:', error);
|
|
915
|
+
* }
|
|
916
|
+
* };
|
|
917
|
+
*
|
|
918
|
+
* return <Button title="저장" onPress={handleSave} />;
|
|
919
|
+
* }
|
|
920
|
+
* ```
|
|
921
|
+
*/
|
|
922
|
+
declare function saveBase64Data(params: SaveBase64DataParams): Promise<void>;
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* @public
|
|
926
|
+
* @category 게임센터
|
|
927
|
+
* @name SubmitGameCenterLeaderBoardScoreResponse
|
|
928
|
+
* @description
|
|
929
|
+
* 토스게임센터 리더보드에 점수를 제출한 결과 정보를 담아서 반환해요. 반환된 정보를 사용해서 점수 제출 결과에 따라 적절한 에러 처리를 할 수 있어요.
|
|
930
|
+
* @property {'SUCCESS' | 'LEADERBOARD_NOT_FOUND' | 'PROFILE_NOT_FOUND' | 'UNPARSABLE_SCORE'} statusCode
|
|
931
|
+
* 점수 제출 결과를 나타내는 상태 코드예요.
|
|
932
|
+
* - `'SUCCESS'`: 점수 제출이 성공했어요.
|
|
933
|
+
* - `'LEADERBOARD_NOT_FOUND'`: `gameId`에 해당하는 리더보드를 찾을 수 없어요.
|
|
934
|
+
* - `'PROFILE_NOT_FOUND'`: 사용자의 프로필이 없어요.
|
|
935
|
+
* - `'UNPARSABLE_SCORE'`: 점수를 해석할 수 없어요. 점수는 실수(float) 형태의 문자열로 전달해야 해요.
|
|
936
|
+
*/
|
|
937
|
+
interface SubmitGameCenterLeaderBoardScoreResponse {
|
|
938
|
+
statusCode: 'SUCCESS' | 'LEADERBOARD_NOT_FOUND' | 'PROFILE_NOT_FOUND' | 'UNPARSABLE_SCORE';
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* @public
|
|
942
|
+
* @category 게임센터
|
|
943
|
+
* @name submitGameCenterLeaderBoardScore
|
|
944
|
+
* @description
|
|
945
|
+
* 사용자의 게임 점수를 토스게임센터 리더보드에 제출해요. 이 기능으로 사용자의 점수를 공식 리더보드에 기록하고 다른 사용자와 비교할 수 있어요.
|
|
946
|
+
* @param {string} params.score
|
|
947
|
+
* 제출할 게임 점수예요. 실수 형태의 숫자를 문자열로 전달해야 해요. 예를들어 `"123.45"` 또는 `"9999"` 예요.
|
|
948
|
+
* @returns {Promise<SubmitGameCenterLeaderBoardScoreResponse | undefined>}
|
|
949
|
+
* 점수 제출 결과를 반환해요. 앱 버전이 최소 지원 버전보다 낮으면 아무 동작도 하지 않고 `undefined`를 반환해요.
|
|
950
|
+
*
|
|
951
|
+
* @example
|
|
952
|
+
* ### 게임 점수를 토스게임센터 리더보드에 제출하기
|
|
953
|
+
* ```tsx
|
|
954
|
+
* import { Button } from 'react-native';
|
|
955
|
+
* import { submitGameCenterLeaderBoardScore } from '@apps-in-toss/framework';
|
|
956
|
+
*
|
|
957
|
+
* function GameCenterLeaderBoardScoreSubmitButton() {
|
|
958
|
+
* async function handlePress() {
|
|
959
|
+
* try {
|
|
960
|
+
* const result = await submitGameCenterLeaderBoardScore({ score: '123.45' });
|
|
961
|
+
*
|
|
962
|
+
* if (!result) {
|
|
963
|
+
* console.warn('지원하지 않는 앱 버전이에요.');
|
|
964
|
+
* return;
|
|
965
|
+
* }
|
|
966
|
+
*
|
|
967
|
+
* if (result.statusCode === 'SUCCESS') {
|
|
968
|
+
* console.log('점수 제출 성공!');
|
|
969
|
+
* } else {
|
|
970
|
+
* console.error('점수 제출 실패:', result.statusCode);
|
|
971
|
+
* }
|
|
972
|
+
* } catch (error) {
|
|
973
|
+
* console.error('점수 제출 중 오류가 발생했어요.', error);
|
|
974
|
+
* }
|
|
975
|
+
* }
|
|
976
|
+
*
|
|
977
|
+
* return (
|
|
978
|
+
* <Button onPress={handlePress}>점수 제출하기</Button>
|
|
979
|
+
* );
|
|
980
|
+
* }
|
|
981
|
+
* ```
|
|
982
|
+
*/
|
|
983
|
+
declare function submitGameCenterLeaderBoardScore(params: {
|
|
984
|
+
score: string;
|
|
985
|
+
}): Promise<SubmitGameCenterLeaderBoardScoreResponse | undefined>;
|
|
986
|
+
|
|
1101
987
|
/**
|
|
1102
|
-
*
|
|
1103
|
-
*
|
|
1104
|
-
* @name ConsumableProductListItem
|
|
1105
|
-
* @description 소모품 상품 정보를 담은 객체예요.
|
|
1106
|
-
* @property {string} sku - 상품의 고유 ID예요.
|
|
1107
|
-
* @property {string} type - 상품의 유형이에요. `CONSUMABLE`을 나타내요.
|
|
1108
|
-
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
1109
|
-
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
1110
|
-
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
1111
|
-
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
988
|
+
* Async Methods Map
|
|
989
|
+
* Type definitions for all async methods accessed via postMessage
|
|
1112
990
|
*/
|
|
1113
|
-
interface
|
|
1114
|
-
|
|
991
|
+
interface AsyncMethodsMap {
|
|
992
|
+
getStorageItem: (params: {
|
|
993
|
+
key: string;
|
|
994
|
+
}) => Promise<string | null>;
|
|
995
|
+
setStorageItem: (params: {
|
|
996
|
+
key: string;
|
|
997
|
+
value: string;
|
|
998
|
+
}) => Promise<void>;
|
|
999
|
+
removeStorageItem: (params: {
|
|
1000
|
+
key: string;
|
|
1001
|
+
}) => Promise<void>;
|
|
1002
|
+
clearStorage: (params: CompatiblePlaceholderArgument) => Promise<void>;
|
|
1003
|
+
getPermission: (params: {
|
|
1004
|
+
name: PermissionName;
|
|
1005
|
+
access: PermissionAccess;
|
|
1006
|
+
}) => Promise<PermissionStatus>;
|
|
1007
|
+
openPermissionDialog: (params: {
|
|
1008
|
+
name: PermissionName;
|
|
1009
|
+
access: PermissionAccess;
|
|
1010
|
+
}) => Promise<'allowed' | 'denied'>;
|
|
1011
|
+
getClipboardText: (params: CompatiblePlaceholderArgument) => Promise<string>;
|
|
1012
|
+
setClipboardText: (params: {
|
|
1013
|
+
text: string;
|
|
1014
|
+
}) => Promise<void>;
|
|
1015
|
+
fetchContacts: (params: {
|
|
1016
|
+
size: number;
|
|
1017
|
+
offset: number;
|
|
1018
|
+
query?: {
|
|
1019
|
+
contains?: string;
|
|
1020
|
+
};
|
|
1021
|
+
}) => Promise<ContactResult>;
|
|
1022
|
+
fetchAlbumPhotos: (params: {
|
|
1023
|
+
base64?: boolean;
|
|
1024
|
+
maxCount?: number;
|
|
1025
|
+
maxWidth?: number;
|
|
1026
|
+
}) => Promise<ImageResponse[]>;
|
|
1027
|
+
openCamera: (params: {
|
|
1028
|
+
base64?: boolean;
|
|
1029
|
+
maxWidth?: number;
|
|
1030
|
+
}) => Promise<ImageResponse>;
|
|
1031
|
+
startUpdateLocation: (params: {
|
|
1032
|
+
accuracy: number;
|
|
1033
|
+
timeInterval: number;
|
|
1034
|
+
distanceInterval: number;
|
|
1035
|
+
}) => Promise<void>;
|
|
1036
|
+
getCurrentLocation: (params: {
|
|
1037
|
+
accuracy: number;
|
|
1038
|
+
}) => Promise<Location>;
|
|
1039
|
+
iapCreateOneTimePurchaseOrder: (params: {
|
|
1040
|
+
productId: string;
|
|
1041
|
+
}) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1042
|
+
processProductGrant: (params: {
|
|
1043
|
+
orderId: string;
|
|
1044
|
+
isProductGranted: boolean;
|
|
1045
|
+
}) => Promise<void>;
|
|
1046
|
+
iapGetProductItemList: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1047
|
+
products: any[];
|
|
1048
|
+
}>;
|
|
1049
|
+
getPendingOrders: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1050
|
+
orders: Array<{
|
|
1051
|
+
orderId: string;
|
|
1052
|
+
sku: string;
|
|
1053
|
+
}>;
|
|
1054
|
+
}>;
|
|
1055
|
+
getCompletedOrRefundedOrders: (params: {
|
|
1056
|
+
key?: string | null;
|
|
1057
|
+
}) => Promise<any>;
|
|
1058
|
+
completeProductGrant: (params: {
|
|
1059
|
+
orderId: string;
|
|
1060
|
+
}) => Promise<boolean>;
|
|
1061
|
+
eventLog: (params: {
|
|
1062
|
+
log_name: string;
|
|
1063
|
+
log_type: string;
|
|
1064
|
+
params: Record<string, string>;
|
|
1065
|
+
}) => Promise<void>;
|
|
1066
|
+
getTossShareLink: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1067
|
+
shareLink: string;
|
|
1068
|
+
}>;
|
|
1069
|
+
appLogin: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1070
|
+
authorizationCode: string;
|
|
1071
|
+
referrer: 'DEFAULT' | 'SANDBOX';
|
|
1072
|
+
}>;
|
|
1073
|
+
checkoutPayment: (params: CheckoutPaymentOptions) => Promise<CheckoutPaymentResult>;
|
|
1074
|
+
setDeviceOrientation: (params: {
|
|
1075
|
+
type: 'portrait' | 'landscape';
|
|
1076
|
+
}) => Promise<void>;
|
|
1077
|
+
saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
|
|
1078
|
+
appsInTossSignTossCert: (params: AppsInTossSignTossCertParams) => Promise<void>;
|
|
1079
|
+
getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse | undefined>;
|
|
1080
|
+
getUserKeyForGame: (params: CompatiblePlaceholderArgument) => Promise<GetUserKeyForGameResponse | undefined>;
|
|
1081
|
+
grantPromotionRewardForGame: (params: {
|
|
1082
|
+
promotionCode: string;
|
|
1083
|
+
amount: number;
|
|
1084
|
+
}) => Promise<GrantPromotionRewardForGameResponse | undefined>;
|
|
1085
|
+
submitGameCenterLeaderBoardScore: (params: {
|
|
1086
|
+
score: string;
|
|
1087
|
+
}) => Promise<SubmitGameCenterLeaderBoardScoreResponse | undefined>;
|
|
1088
|
+
requestOneTimePurchase: (params: {
|
|
1089
|
+
sku: string;
|
|
1090
|
+
}) => Promise<void>;
|
|
1091
|
+
contactsViral: (params: {
|
|
1092
|
+
moduleId: string;
|
|
1093
|
+
}) => Promise<void>;
|
|
1094
|
+
getMiniAppsSupportContact: (params: object) => Promise<void>;
|
|
1095
|
+
loadAdMobInterstitialAd: (params: {
|
|
1096
|
+
adUnitId: string;
|
|
1097
|
+
}) => Promise<void>;
|
|
1098
|
+
showAdMobInterstitialAd: (params: {
|
|
1099
|
+
adUnitId: string;
|
|
1100
|
+
}) => Promise<void>;
|
|
1101
|
+
loadAdMobRewardedAd: (params: {
|
|
1102
|
+
adUnitId: string;
|
|
1103
|
+
}) => Promise<void>;
|
|
1104
|
+
showAdMobRewardedAd: (params: {
|
|
1105
|
+
adUnitId: string;
|
|
1106
|
+
}) => Promise<void>;
|
|
1107
|
+
loadAppsInTossAdmob: (params: {
|
|
1108
|
+
adGroupId: string;
|
|
1109
|
+
referrer: string;
|
|
1110
|
+
}) => Promise<void>;
|
|
1111
|
+
showAppsInTossAdmob: (params: {
|
|
1112
|
+
adGroupId: string;
|
|
1113
|
+
referrer: string;
|
|
1114
|
+
}) => Promise<void>;
|
|
1115
|
+
getIsTossLoginIntegratedService: (params: object) => Promise<boolean | undefined>;
|
|
1116
|
+
getServerTime: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1117
|
+
serverTime: number;
|
|
1118
|
+
}>;
|
|
1115
1119
|
}
|
|
1116
1120
|
/**
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1119
|
-
* @name NonConsumableProductListItem
|
|
1120
|
-
* @description 비소모품 상품 정보를 담은 객체예요.
|
|
1121
|
-
* @property {string} sku - 상품의 고유 ID예요.
|
|
1122
|
-
* @property {string} type - 상품의 유형이에요. `NON_CONSUMABLE`을 나타내요.
|
|
1123
|
-
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
1124
|
-
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
1125
|
-
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
1126
|
-
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
1121
|
+
* Sync Methods Map
|
|
1122
|
+
* Type definitions for all sync methods accessed via postMessageSync
|
|
1127
1123
|
*/
|
|
1128
|
-
interface
|
|
1129
|
-
|
|
1124
|
+
interface SyncMethodsMap {
|
|
1125
|
+
getWebBundleURL: (params: CompatiblePlaceholderArgument) => {
|
|
1126
|
+
url: string;
|
|
1127
|
+
};
|
|
1128
|
+
shareWithScheme: (params: {
|
|
1129
|
+
schemeURL: string;
|
|
1130
|
+
}) => void;
|
|
1131
|
+
stopUpdateLocation: (params: object) => void;
|
|
1130
1132
|
}
|
|
1131
1133
|
/**
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
* @name SubscriptionProductListItem
|
|
1135
|
-
* @description 자동 갱신 구독 상품 정보를 담은 객체예요.
|
|
1136
|
-
* @property {string} sku - 상품의 고유 ID예요.
|
|
1137
|
-
* @property {string} type - 상품의 유형이에요. `SUBSCRIPTION`을 나타내요.
|
|
1138
|
-
* @property {string} displayName - 화면에 표시할 상품 이름이에요. 상품 이름은 앱인토스 콘솔에서 설정한 값이에요.
|
|
1139
|
-
* @property {string} displayAmount - 통화 단위가 포함된 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
1140
|
-
* @property {string} iconUrl - 상품 아이콘 이미지의 URL이에요. 아이콘은 앱인토스 콘솔에서 설정한 이미지예요.
|
|
1141
|
-
* @property {string} description - 상품에 대한 설명이에요. 설명은 앱인토스 콘솔에서 설정한 값이에요.
|
|
1142
|
-
* @property {string} renewalCycle - 구독 갱신 주기이에요. `WEEKLY`, `MONTHLY`, `YEARLY` 중 하나를 나타내요.
|
|
1143
|
-
* @property {Offer[]} offers - 구독 혜택 옵션 목록이에요. 각 옵션은 하나의 구독 혜택을 나타내요.
|
|
1144
|
-
* @property {string} offers[].type - 구독 혜택 옵션 유형이에요. `FREE_TRIAL`, `NEW_SUBSCRIPTION`, `RETURNING` 중 하나를 나타내요.
|
|
1145
|
-
* @property {string} offers[].offerId - 구독 혜택 옵션의 고유 ID예요.
|
|
1146
|
-
* @property {string} offers[].period - 구독 혜택 옵션의 적용 기간이에요.
|
|
1147
|
-
* @property {string} offers[].displayAmount - 통화 단위가 포함된 구독 혜택 옵션의 가격 정보예요. 예를 들어 `1,000원`으로 가격과 통화가 함께 표시돼요.
|
|
1134
|
+
* Type-safe postMessage wrapper
|
|
1135
|
+
* Provides type inference for async method calls without requiring 'as unknown' casts
|
|
1148
1136
|
*/
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1137
|
+
declare function safePostMessage<K extends keyof AsyncMethodsMap>(method: K, params: Parameters<AsyncMethodsMap[K]>[0]): ReturnType<AsyncMethodsMap[K]>;
|
|
1138
|
+
/**
|
|
1139
|
+
* Type-safe postMessageSync wrapper
|
|
1140
|
+
* Provides type inference for sync method calls without requiring 'as unknown' casts
|
|
1141
|
+
*/
|
|
1142
|
+
declare function safeSyncPostMessage<K extends keyof SyncMethodsMap>(method: K, params: Parameters<SyncMethodsMap[K]>[0]): ReturnType<SyncMethodsMap[K]>;
|
|
1143
|
+
|
|
1144
|
+
interface EventEmitterSchema<K extends string, P extends unknown[]> {
|
|
1145
|
+
name: K;
|
|
1146
|
+
params: P;
|
|
1153
1147
|
}
|
|
1148
|
+
|
|
1154
1149
|
/**
|
|
1155
|
-
* @
|
|
1156
|
-
* @
|
|
1157
|
-
* @
|
|
1158
|
-
*
|
|
1150
|
+
* @name UpdateLocationEventEmitter
|
|
1151
|
+
* @kind typedef
|
|
1152
|
+
* @description
|
|
1153
|
+
* 디바이스의 위치 정보 변경을 감지해요
|
|
1159
1154
|
*/
|
|
1160
|
-
type
|
|
1155
|
+
type UpdateLocationEventEmitter = EventEmitterSchema<'updateLocation', [Location]>;
|
|
1161
1156
|
/**
|
|
1162
1157
|
* @public
|
|
1163
|
-
* @category
|
|
1164
|
-
* @name
|
|
1165
|
-
* @description
|
|
1166
|
-
*
|
|
1158
|
+
* @category 위치 정보
|
|
1159
|
+
* @name startUpdateLocation
|
|
1160
|
+
* @description 디바이스의 위치 정보를 지속적으로 감지하고, 위치가 변경되면 콜백을 실행하는 함수예요. 콜백 함수를 등록하면 위치가 변경될 때마다 자동으로 호출돼요.
|
|
1161
|
+
* 실시간 위치 추적이 필요한 기능을 구현할 때 사용할 수 있어요. 예를 들어 지도 앱에서 사용자의 현재 위치를 실시간으로 업데이트할 때, 운동 앱에서 사용자의 이동 거리를 기록할 때 등이에요.
|
|
1162
|
+
* 위치 업데이트 주기와 정확도를 조정해 배터리 소모를 최소화하면서도 필요한 정보를 얻을 수 있어요.
|
|
1167
1163
|
*
|
|
1168
|
-
* @example
|
|
1169
|
-
* ### 구매 가능한 인앱결제 상품목록 가져오기
|
|
1170
1164
|
*
|
|
1171
|
-
*
|
|
1172
|
-
*
|
|
1173
|
-
*
|
|
1174
|
-
*
|
|
1165
|
+
* @param {(error: unknown) => void} onError 위치 정보 감지에 실패했을 때 호출되는 콜백 함수예요.
|
|
1166
|
+
* @param {(location: Location) => void} onEvent 위치 정보가 변경될 때 호출되는 콜백 함수예요. 자세한 내용은 [Location](/react-native/reference/native-modules/Types/Location.html)을 참고해주세요.
|
|
1167
|
+
* @param {StartUpdateLocationOptions} options - 위치 정보 감지에 필요한 설정 객체에요.
|
|
1168
|
+
* @param {number} [options.accuracy] 위치 정확도를 설정해요.
|
|
1169
|
+
* @param {number} [options.timeInterval] 위치 정보를 업데이트하는 최소 주기로, 단위는 밀리초(ms)예요. 이 값은 위치 업데이트가 발생하는 가장 짧은 간격을 설정하지만, 시스템이나 환경의 영향을 받아 지정한 주기보다 더 긴 간격으로 업데이트될 수 있어요.
|
|
1170
|
+
* @param {number} [options.distanceInterval] 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
1175
1171
|
*
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1172
|
+
* @property [openPermissionDialog] - 위치 정보 권한을 다시 요청하는 다이얼로그를 표시해요. 사용자는 "허용", "한 번만 허용", "안하기" 중 하나를 선택할 수 있어요. "허용"이나 "한 번만 허용"을 선택하면 `allowed`를 반환하고, "안하기"를 선택하면 `denied`를 반환해요.
|
|
1173
|
+
* @property [getPermission] - 위치 정보 권한의 현재 상태를 반환해요. `allowed`는 사용자가 위치 정보 권한을 허용한 상태예요. `denied`는 사용자가 위치 정보 권한을 거부한 상태예요. `notDetermined`는 위치 정보 권한 요청을 한 번도 하지 않은 상태예요.
|
|
1178
1174
|
*
|
|
1179
|
-
*
|
|
1180
|
-
*
|
|
1181
|
-
*
|
|
1182
|
-
*
|
|
1183
|
-
*
|
|
1175
|
+
* @signature
|
|
1176
|
+
* ```typescript
|
|
1177
|
+
* function startUpdateLocation(options: {
|
|
1178
|
+
* onError: (error: unknown) => void;
|
|
1179
|
+
* onEvent: (location: Location) => void;
|
|
1180
|
+
* options: StartUpdateLocationOptions;
|
|
1181
|
+
* }): () => void;
|
|
1182
|
+
* ```
|
|
1184
1183
|
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
* console.error("인앱결제에 실패했어요:", error);
|
|
1188
|
-
* }
|
|
1189
|
-
* }
|
|
1184
|
+
* @example
|
|
1185
|
+
* ### 위치 정보 변경 감지하기
|
|
1190
1186
|
*
|
|
1191
|
-
*
|
|
1192
|
-
* async function fetchProducts() {
|
|
1193
|
-
* try {
|
|
1194
|
-
* const response = await IAP.getProductItemList();
|
|
1195
|
-
* setProducts(response?.products ?? []);
|
|
1196
|
-
* } catch (error) {
|
|
1197
|
-
* console.error("상품 목록을 가져오는 데 실패했어요:", error);
|
|
1198
|
-
* }
|
|
1199
|
-
* }
|
|
1187
|
+
* 위치 정보가 변경되는것을 감지하는 예제예요. "위치 정보 변경 감지하기"를 눌러서 감지할 수 있어요.
|
|
1200
1188
|
*
|
|
1201
|
-
*
|
|
1202
|
-
*
|
|
1189
|
+
* "권한 확인하기"버튼을 눌러서 현재 위치 정보 변경 감지 권한을 확인해요.
|
|
1190
|
+
* 사용자가 권한을 거부했거나 시스템에서 권한이 제한된 경우에는 [`StartUpdateLocationPermissionError`](/react-native/reference/types/권한/StartUpdateLocationPermissionError)를 반환해요.
|
|
1191
|
+
* "권한 요청하기"버튼을 눌러서 위치 정보 변경 감지 권한을 요청할 수 있어요.
|
|
1203
1192
|
*
|
|
1204
|
-
*
|
|
1205
|
-
*
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1216
|
-
*
|
|
1217
|
-
*
|
|
1218
|
-
*
|
|
1219
|
-
*
|
|
1220
|
-
*
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
*
|
|
1227
|
-
*
|
|
1193
|
+
* ```tsx
|
|
1194
|
+
* import { Accuracy, Location, startUpdateLocation, StartUpdateLocationPermissionError } from '@apps-in-toss/framework';
|
|
1195
|
+
* import { useCallback, useState } from 'react';
|
|
1196
|
+
* import { Alert, Button, Text, View } from 'react-native';
|
|
1197
|
+
*
|
|
1198
|
+
* // 위치 정보 변경 감지하기
|
|
1199
|
+
* function LocationWatcher() {
|
|
1200
|
+
* const [location, setLocation] = useState<Location | null>(null);
|
|
1201
|
+
*
|
|
1202
|
+
* const handlePress = useCallback(() => {
|
|
1203
|
+
* startUpdateLocation({
|
|
1204
|
+
* options: {
|
|
1205
|
+
* accuracy: Accuracy.Balanced,
|
|
1206
|
+
* timeInterval: 3000,
|
|
1207
|
+
* distanceInterval: 10,
|
|
1208
|
+
* },
|
|
1209
|
+
* onEvent: (location) => {
|
|
1210
|
+
* setLocation(location);
|
|
1211
|
+
* },
|
|
1212
|
+
* onError: (error) => {
|
|
1213
|
+
* if (error instanceof StartUpdateLocationPermissionError) {
|
|
1214
|
+
* // 위치 정보 변경 감지 권한 없음
|
|
1215
|
+
* }
|
|
1216
|
+
* console.error('위치 정보를 가져오는데 실패했어요:', error);
|
|
1217
|
+
* },
|
|
1218
|
+
* });
|
|
1219
|
+
* }, []);
|
|
1220
|
+
*
|
|
1221
|
+
* return (
|
|
1222
|
+
* <View>
|
|
1223
|
+
* {location != null && (
|
|
1224
|
+
* <>
|
|
1225
|
+
* <Text>위도: {location.coords.latitude}</Text>
|
|
1226
|
+
* <Text>경도: {location.coords.longitude}</Text>
|
|
1227
|
+
* <Text>위치 정확도: {location.coords.accuracy}m</Text>
|
|
1228
|
+
* <Text>높이: {location.coords.altitude}m</Text>
|
|
1229
|
+
* <Text>고도 정확도: {location.coords.altitudeAccuracy}m</Text>
|
|
1230
|
+
* <Text>방향: {location.coords.heading}°</Text>
|
|
1231
|
+
* </>
|
|
1232
|
+
* )}
|
|
1233
|
+
*
|
|
1234
|
+
* <Button title="위치 정보 변경 감지하기" onPress={handlePress} />
|
|
1235
|
+
*
|
|
1236
|
+
* <Button
|
|
1237
|
+
* title="권한 확인하기"
|
|
1238
|
+
* onPress={async () => {
|
|
1239
|
+
* const permission = await startUpdateLocation.getPermission();
|
|
1240
|
+
* Alert.alert(permission);
|
|
1241
|
+
* }}
|
|
1242
|
+
* />
|
|
1243
|
+
* <Button
|
|
1244
|
+
* title="권한 요청하기"
|
|
1245
|
+
* onPress={async () => {
|
|
1246
|
+
* const permission = await startUpdateLocation.openPermissionDialog();
|
|
1247
|
+
* Alert.alert(permission);
|
|
1248
|
+
* }}
|
|
1249
|
+
* />
|
|
1250
|
+
* </View>
|
|
1228
1251
|
* );
|
|
1229
1252
|
* }
|
|
1230
1253
|
* ```
|
|
1231
1254
|
*/
|
|
1232
|
-
declare function
|
|
1233
|
-
|
|
1234
|
-
|
|
1255
|
+
declare function startUpdateLocation(eventParams: StartUpdateLocationEventParams): () => void;
|
|
1256
|
+
declare namespace startUpdateLocation {
|
|
1257
|
+
var openPermissionDialog: _apps_in_toss_types.PermissionDialogFunction;
|
|
1258
|
+
var getPermission: _apps_in_toss_types.GetPermissionFunction;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1235
1261
|
/**
|
|
1236
1262
|
* @public
|
|
1237
|
-
* @category
|
|
1238
|
-
* @name
|
|
1239
|
-
* @description
|
|
1240
|
-
* @
|
|
1241
|
-
*
|
|
1242
|
-
* @
|
|
1243
|
-
*
|
|
1244
|
-
* ```typescript
|
|
1245
|
-
* import { IAP } from '@apps-in-toss/framework';
|
|
1246
|
-
*
|
|
1247
|
-
* async function fetchOrders() {
|
|
1248
|
-
* try {
|
|
1249
|
-
* const pendingOrders = await IAP.getPendingOrders();
|
|
1250
|
-
* return pendingOrders;
|
|
1251
|
-
* } catch (error) {
|
|
1252
|
-
* console.error(error);
|
|
1253
|
-
* }
|
|
1254
|
-
* }
|
|
1255
|
-
* ```
|
|
1263
|
+
* @category 친구초대
|
|
1264
|
+
* @name RewardFromContactsViralEvent
|
|
1265
|
+
* @description 친구에게 공유하기를 완료했을 때 지급할 리워드 정보를 담는 타입이에요. 이 타입을 사용하면 공유가 완료됐을 때 지급할 리워드 정보를 확인할 수 있어요.
|
|
1266
|
+
* @property {'sendViral'} type - 이벤트의 타입이에요. `'sendViral'`은 사용자가 친구에게 공유를 완료했을 때 돌아와요.
|
|
1267
|
+
* @property {Object} data - 지급할 리워드 관련 정보를 담고 있어요.
|
|
1268
|
+
* @property {number} data.rewardAmount - 지급할 리워드 수량이에요. 앱인토스 콘솔에서 설정한 수량 및 금액 값이에요.
|
|
1269
|
+
* @property {string} data.rewardUnit - 리워드의 단위예요. 앱인토스 콘솔에 설정된 리워드 이름인 '하트', '보석' 등이 리워드 단위예요.
|
|
1256
1270
|
*/
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
}
|
|
1263
|
-
}
|
|
1271
|
+
type RewardFromContactsViralEvent = {
|
|
1272
|
+
type: 'sendViral';
|
|
1273
|
+
data: {
|
|
1274
|
+
rewardAmount: number;
|
|
1275
|
+
rewardUnit: string;
|
|
1276
|
+
};
|
|
1277
|
+
};
|
|
1264
1278
|
/**
|
|
1265
1279
|
* @public
|
|
1266
|
-
* @category
|
|
1267
|
-
* @name
|
|
1268
|
-
* @description
|
|
1269
|
-
* @property {
|
|
1270
|
-
* @property {
|
|
1271
|
-
* @property {
|
|
1272
|
-
* @property {
|
|
1273
|
-
* @property {
|
|
1274
|
-
* @property {
|
|
1275
|
-
* @property {string}
|
|
1280
|
+
* @category 친구초대
|
|
1281
|
+
* @name ContactsViralSuccessEvent
|
|
1282
|
+
* @description 연락처 공유 모듈이 정상적으로 종료됐을 때 전달되는 이벤트 객체예요. 종료 이유와 함께 리워드 상태 및 남은 친구 수 등 관련 정보를 제공해요.
|
|
1283
|
+
* @property {'close'} type - 이벤트의 타입이에요. `'close'`는 공유 모듈이 종료됐을 때 돌아와요.
|
|
1284
|
+
* @property {Object} data - 모듈 종료와 관련된 세부 정보를 담고 있어요.
|
|
1285
|
+
* @property {'clickBackButton' | 'noReward'} data.closeReason - 모듈이 종료된 이유예요. `'clickBackButton'`은 사용자가 뒤로 가기 버튼을 눌러 종료한 경우이고, `'noReward'`는 받을 수 있는 리워드가 없어서 종료된 경우예요.
|
|
1286
|
+
* @property {number} data.sentRewardAmount - 사용자가 받은 전체 리워드 수량이에요.
|
|
1287
|
+
* @property {number} data.sendableRewardsCount - 아직 공유할 수 있는 친구 수예요.
|
|
1288
|
+
* @property {number} data.sentRewardsCount - 사용자가 공유를 완료한 친구 수예요.
|
|
1289
|
+
* @property {string} data.rewardUnit - 리워드의 단위예요. 앱인토스 콘솔에 설정된 리워드 이름인 '하트', '보석' 등이 리워드 단위예요.
|
|
1276
1290
|
*/
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1291
|
+
type ContactsViralSuccessEvent = {
|
|
1292
|
+
type: 'close';
|
|
1293
|
+
data: {
|
|
1294
|
+
closeReason: 'clickBackButton' | 'noReward';
|
|
1295
|
+
sentRewardAmount?: number;
|
|
1296
|
+
sendableRewardsCount?: number;
|
|
1297
|
+
sentRewardsCount: number;
|
|
1298
|
+
rewardUnit?: string;
|
|
1299
|
+
};
|
|
1300
|
+
};
|
|
1301
|
+
type ContactsViralEvent = RewardFromContactsViralEvent | ContactsViralSuccessEvent;
|
|
1287
1302
|
/**
|
|
1288
1303
|
* @public
|
|
1289
|
-
* @category
|
|
1290
|
-
* @name
|
|
1291
|
-
* @description
|
|
1292
|
-
* @
|
|
1293
|
-
*
|
|
1294
|
-
* @example
|
|
1295
|
-
* ```typescript
|
|
1296
|
-
* import { IAP } from "@apps-in-toss/framework";
|
|
1297
|
-
*
|
|
1298
|
-
* async function fetchOrders() {
|
|
1299
|
-
* try {
|
|
1300
|
-
* const response = await IAP.getCompletedOrRefundedOrders();
|
|
1301
|
-
* return response;
|
|
1302
|
-
* } catch (error) {
|
|
1303
|
-
* console.error(error);
|
|
1304
|
-
* }
|
|
1305
|
-
* }
|
|
1306
|
-
* ```
|
|
1304
|
+
* @category 친구초대
|
|
1305
|
+
* @name ContactsViralOption
|
|
1306
|
+
* @description [연락처 공유 기능](/react-native/reference/native-modules/친구초대/contactsViral.html)을 사용할 때 필요한 옵션이에요.
|
|
1307
|
+
* @property {string} moduleId - 공유 리워드를 구분하는 UUID 형식의 고유 ID예요. 앱인토스 콘솔의 미니앱 > 공유 리워드 메뉴에서 확인할 수 있어요.
|
|
1307
1308
|
*/
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
}
|
|
1309
|
+
type ContactsViralOption = {
|
|
1310
|
+
moduleId: string;
|
|
1311
|
+
};
|
|
1311
1312
|
/**
|
|
1312
1313
|
* @public
|
|
1313
|
-
* @category
|
|
1314
|
-
* @name
|
|
1315
|
-
* @description
|
|
1316
|
-
* @
|
|
1317
|
-
* @
|
|
1318
|
-
* @
|
|
1314
|
+
* @category 친구초대
|
|
1315
|
+
* @name ContactsViralParams
|
|
1316
|
+
* @description `ContactsViralParams`는 연락처 공유 기능을 사용할 때 전달해야 하는 파라미터 타입이에요. 옵션을 설정하고, 이벤트 및 에러 처리 콜백을 지정할 수 있어요.
|
|
1317
|
+
* @property {ContactsViralOption} options - 공유 기능에 사용할 옵션 객체예요.
|
|
1318
|
+
* @property {(event: ContactsViralEvent) => void} onEvent - 공유 이벤트가 발생했을 때 실행되는 함수예요. [`RewardFromContactsViralEvent`](/bedrock/reference/native-modules/친구초대/RewardFromContactsViralEvent.html) 또는 [`ContactsViralSuccessEvent`](/react-native/reference/native-modules/친구초대/ContactsViralSuccessEvent.html) 타입의 이벤트 객체가 전달돼요.
|
|
1319
|
+
* @property {(error: unknown) => void} onError - 예기치 않은 에러가 발생했을 때 실행되는 함수예요.
|
|
1320
|
+
*/
|
|
1321
|
+
interface ContactsViralParams {
|
|
1322
|
+
options: ContactsViralOption;
|
|
1323
|
+
onEvent: (event: ContactsViralEvent) => void;
|
|
1324
|
+
onError: (error: unknown) => void;
|
|
1325
|
+
}
|
|
1326
|
+
/**
|
|
1327
|
+
* @public
|
|
1328
|
+
* @category 친구초대
|
|
1329
|
+
* @name contactsViral
|
|
1330
|
+
* @description 친구에게 공유하고 리워드를 받을 수 있는 기능을 제공해요. 사용자가 친구에게 공유를 완료하면 앱브릿지가 이벤트를 통해 리워드 정보를 전달해요.
|
|
1331
|
+
* @param {ContactsViralParams} params - 연락처 공유 기능을 실행할 때 사용하는 파라미터예요. 옵션 설정과 이벤트 핸들러를 포함해요. 자세한 내용은 [ContactsViralParams](/bedrock/reference/native-modules/친구초대/ContactsViralParams.html) 문서를 참고하세요.
|
|
1332
|
+
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 공유 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
1319
1333
|
*
|
|
1320
1334
|
* @example
|
|
1321
|
-
* ###
|
|
1322
|
-
* ```typescript
|
|
1323
|
-
* import { IAP } from '@apps-in-toss/framework';
|
|
1335
|
+
* ### 친구에게 공유하고 리워드 받기
|
|
1324
1336
|
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1337
|
+
* ```tsx
|
|
1338
|
+
* import { useCallback } from 'react';
|
|
1339
|
+
* import { Button } from 'react-native';
|
|
1340
|
+
* import { contactsViral } from '@apps-in-toss/framework';
|
|
1341
|
+
*
|
|
1342
|
+
* function ContactsViralButton({ moduleId }: { moduleId: string }) {
|
|
1343
|
+
* const handleContactsViral = useCallback(() => {
|
|
1344
|
+
* try {
|
|
1345
|
+
* const cleanup = contactsViral({
|
|
1346
|
+
* options: { moduleId: moduleId.trim() },
|
|
1347
|
+
* onEvent: (event) => {
|
|
1348
|
+
* if (event.type === 'sendViral') {
|
|
1349
|
+
* console.log('리워드 지급:', event.data.rewardAmount, event.data.rewardUnit);
|
|
1350
|
+
* } else if (event.type === 'close') {
|
|
1351
|
+
* console.log('모듈 종료:', event.data.closeReason);
|
|
1352
|
+
* }
|
|
1353
|
+
* },
|
|
1354
|
+
* onError: (error) => {
|
|
1355
|
+
* console.error('에러 발생:', error);
|
|
1356
|
+
* },
|
|
1357
|
+
* });
|
|
1358
|
+
*
|
|
1359
|
+
* return cleanup;
|
|
1360
|
+
* } catch (error) {
|
|
1361
|
+
* console.error('실행 중 에러:', error);
|
|
1362
|
+
* }
|
|
1363
|
+
* }, [moduleId]);
|
|
1364
|
+
*
|
|
1365
|
+
* return <Button title="친구에게 공유하고 리워드 받기" onPress={handleContactsViral} />;
|
|
1331
1366
|
* }
|
|
1332
1367
|
* ```
|
|
1333
1368
|
*/
|
|
1334
|
-
declare function
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
processProductGrant: (params: {
|
|
1356
|
-
orderId: string;
|
|
1357
|
-
subscriptionId?: string;
|
|
1358
|
-
}) => boolean | Promise<boolean>;
|
|
1369
|
+
declare function contactsViral(params: ContactsViralParams): () => void;
|
|
1370
|
+
|
|
1371
|
+
interface StartUpdateLocationOptions {
|
|
1372
|
+
/**
|
|
1373
|
+
* 위치 정확도를 설정해요.
|
|
1374
|
+
*/
|
|
1375
|
+
accuracy: Accuracy;
|
|
1376
|
+
/**
|
|
1377
|
+
* 위치 업데이트 주기를 밀리초(ms) 단위로 설정해요.
|
|
1378
|
+
*/
|
|
1379
|
+
timeInterval: number;
|
|
1380
|
+
/**
|
|
1381
|
+
* 위치 변경 거리를 미터(m) 단위로 설정해요.
|
|
1382
|
+
*/
|
|
1383
|
+
distanceInterval: number;
|
|
1384
|
+
}
|
|
1385
|
+
declare class UpdateLocationEvent extends GraniteEventDefinition<StartUpdateLocationOptions, Location> {
|
|
1386
|
+
name: "updateLocationEvent";
|
|
1387
|
+
subscriptionCount: number;
|
|
1388
|
+
ref: {
|
|
1389
|
+
remove: () => void;
|
|
1359
1390
|
};
|
|
1360
|
-
|
|
1361
|
-
onError: (error: unknown) => void
|
|
1391
|
+
remove(): void;
|
|
1392
|
+
listener(options: StartUpdateLocationOptions, onEvent: (response: Location) => void, onError: (error: unknown) => void): void;
|
|
1362
1393
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1394
|
+
|
|
1395
|
+
interface AppBridgeCallbackResult {
|
|
1396
|
+
name: string;
|
|
1397
|
+
params?: any;
|
|
1398
|
+
}
|
|
1399
|
+
declare class AppBridgeCallbackEvent extends GraniteEventDefinition<void, AppBridgeCallbackResult> {
|
|
1400
|
+
private static INTERNAL__appBridgeSubscription?;
|
|
1401
|
+
name: "appBridgeCallbackEvent";
|
|
1402
|
+
constructor();
|
|
1403
|
+
remove(): void;
|
|
1404
|
+
listener(): void;
|
|
1405
|
+
private registerAppBridgeCallbackEventListener;
|
|
1406
|
+
private ensureInvokeAppBridgeCallback;
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
interface VisibilityChangedByTransparentServiceWebOptions {
|
|
1410
|
+
callbackId: string;
|
|
1373
1411
|
}
|
|
1412
|
+
declare class VisibilityChangedByTransparentServiceWebEvent extends GraniteEventDefinition<VisibilityChangedByTransparentServiceWebOptions, boolean> {
|
|
1413
|
+
name: "onVisibilityChangedByTransparentServiceWeb";
|
|
1414
|
+
unsubscribe: (() => void) | null;
|
|
1415
|
+
remove(): void;
|
|
1416
|
+
listener(options: VisibilityChangedByTransparentServiceWebOptions, onEvent: (isVisible: boolean) => void, onError: (error: unknown) => void): void;
|
|
1417
|
+
private isVisibilityChangedByTransparentServiceWebResult;
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
declare const appsInTossEvent: GraniteEvent<UpdateLocationEvent | AppBridgeCallbackEvent | VisibilityChangedByTransparentServiceWebEvent>;
|
|
1421
|
+
|
|
1422
|
+
declare function onVisibilityChangedByTransparentServiceWeb(eventParams: {
|
|
1423
|
+
options: {
|
|
1424
|
+
callbackId: string;
|
|
1425
|
+
};
|
|
1426
|
+
onEvent: (isVisible: boolean) => void;
|
|
1427
|
+
onError: (error: unknown) => void;
|
|
1428
|
+
}): () => void;
|
|
1429
|
+
|
|
1430
|
+
interface AppBridgeCompatCallbacks<Result> {
|
|
1431
|
+
onSuccess: (result: Result) => void;
|
|
1432
|
+
onError: (reason: unknown) => void;
|
|
1433
|
+
}
|
|
1434
|
+
type AppBridgeCallback = (...args: any[]) => void;
|
|
1435
|
+
declare function invokeAppBridgeCallback(id: string, ...args: any[]): boolean;
|
|
1436
|
+
declare function invokeAppBridgeMethod<Result = any, Params extends AnyObject = any>(methodName: string, params: Params, callbacks: AppBridgeCompatCallbacks<Result> & Record<string, AppBridgeCallback>): () => void;
|
|
1437
|
+
declare function registerCallback(callback: AppBridgeCallback, name?: string): string;
|
|
1438
|
+
declare function unregisterCallback(id: string): void;
|
|
1439
|
+
declare function getCallbackIds(): string[];
|
|
1440
|
+
declare const INTERNAL__appBridgeHandler: {
|
|
1441
|
+
invokeAppBridgeCallback: typeof invokeAppBridgeCallback;
|
|
1442
|
+
invokeAppBridgeMethod: typeof invokeAppBridgeMethod;
|
|
1443
|
+
registerCallback: typeof registerCallback;
|
|
1444
|
+
unregisterCallback: typeof unregisterCallback;
|
|
1445
|
+
getCallbackIds: typeof getCallbackIds;
|
|
1446
|
+
};
|
|
1447
|
+
|
|
1374
1448
|
/**
|
|
1375
1449
|
* @public
|
|
1376
|
-
* @category
|
|
1377
|
-
* @name
|
|
1378
|
-
* @description
|
|
1379
|
-
*
|
|
1380
|
-
* @param {
|
|
1381
|
-
* @
|
|
1450
|
+
* @category 광고
|
|
1451
|
+
* @name loadAppsInTossAdMob
|
|
1452
|
+
* @description 광고를 미리 불러와서, 광고가 필요한 시점에 바로 보여줄 수 있도록 준비하는 함수예요.
|
|
1453
|
+
* @param {LoadAdMobParams} params 광고를 불러올 때 사용할 설정 값이에요. 광고 그룹 ID와 광고의 동작에 대한 콜백을 설정할 수 있어요.
|
|
1454
|
+
* @param {LoadAdMobOptions} params.options 광고를 불러올 때 전달할 옵션 객체예요.
|
|
1455
|
+
* @param {string} params.options.adGroupId 광고 그룹 단위 ID예요. 콘솔에서 발급받은 ID를 입력해요.
|
|
1456
|
+
* @param {(event: LoadAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고가 닫히거나 클릭됐을 때). 자세한 이벤트 타입은 [LoadAdMobEvent](/react-native/reference/native-modules/광고/LoadAdMobEvent.html)를 참고하세요.
|
|
1457
|
+
* @param {(reason: unknown) => void} [params.onError] 광고를 불러오지 못했을 때 호출돼요. (예시: 네트워크 오류나 지원하지 않는 환경일 때)
|
|
1458
|
+
* @property {() => boolean} [isSupported] 현재 실행 중인 앱(예: 토스 앱, 개발용 샌드박스 앱 등)에서 Google AdMob 광고 기능을 지원하는지 확인하는 함수예요. 기능을 사용하기 전에 지원 여부를 확인해야 해요.
|
|
1382
1459
|
*
|
|
1383
1460
|
* @example
|
|
1384
|
-
* ###
|
|
1385
|
-
*
|
|
1461
|
+
* ### 버튼 눌러 불러온 광고 보여주기
|
|
1386
1462
|
* ```tsx
|
|
1387
|
-
* import {
|
|
1388
|
-
* import {
|
|
1389
|
-
* import { useCallback } from
|
|
1463
|
+
* import { GoogleAdMob } from '@apps-in-toss/framework';
|
|
1464
|
+
* import { useFocusEffect } from '@react-native-bedrock/native/@react-navigation/native';
|
|
1465
|
+
* import { useCallback, useState } from 'react';
|
|
1466
|
+
* import { Button, Text, View } from 'react-native';
|
|
1467
|
+
* import { useNavigation } from 'react-native-bedrock';
|
|
1390
1468
|
*
|
|
1391
|
-
*
|
|
1392
|
-
* sku: string;
|
|
1393
|
-
* offerId?: string;
|
|
1394
|
-
* }
|
|
1469
|
+
* const AD_GROUP_ID = '<AD_GROUP_ID>';
|
|
1395
1470
|
*
|
|
1396
|
-
* function
|
|
1397
|
-
* const
|
|
1398
|
-
*
|
|
1471
|
+
* export function GoogleAdmobExample() {
|
|
1472
|
+
* const [adLoadStatus, setAdLoadStatus] = useState<'not_loaded' | 'loaded' | 'failed'>('not_loaded');
|
|
1473
|
+
* const navigation = useNavigation();
|
|
1474
|
+
*
|
|
1475
|
+
* const loadAd = useCallback(() => {
|
|
1476
|
+
* if (GoogleAdMob.loadAppsInTossAdMob.isSupported() !== true) {
|
|
1477
|
+
* return;
|
|
1478
|
+
* }
|
|
1479
|
+
|
|
1480
|
+
* const cleanup = GoogleAdMob.loadAppsInTossAdMob({
|
|
1399
1481
|
* options: {
|
|
1400
|
-
*
|
|
1401
|
-
* offerId,
|
|
1402
|
-
* processProductGrant: ({ orderId, subscriptionId }) => {
|
|
1403
|
-
* // 상품 지급 로직 작성
|
|
1404
|
-
* return true; // 상품 지급 여부
|
|
1405
|
-
* },
|
|
1482
|
+
* adGroupId: AD_GROUP_ID,
|
|
1406
1483
|
* },
|
|
1407
1484
|
* onEvent: (event) => {
|
|
1408
|
-
*
|
|
1485
|
+
* switch (event.type) {
|
|
1486
|
+
* case 'loaded':
|
|
1487
|
+
* console.log('광고 로드 성공', event.data);
|
|
1488
|
+
* setAdLoadStatus('loaded');
|
|
1489
|
+
* break;
|
|
1490
|
+
* }
|
|
1409
1491
|
* },
|
|
1410
1492
|
* onError: (error) => {
|
|
1411
|
-
* console.error(error);
|
|
1493
|
+
* console.error('광고 불러오기 실패', error);
|
|
1412
1494
|
* },
|
|
1413
1495
|
* });
|
|
1414
1496
|
*
|
|
1415
1497
|
* return cleanup;
|
|
1416
|
-
* }, [
|
|
1498
|
+
* }, [navigation]);
|
|
1417
1499
|
*
|
|
1418
|
-
*
|
|
1419
|
-
*
|
|
1420
|
-
*
|
|
1421
|
-
|
|
1422
|
-
declare function createSubscriptionPurchaseOrder(params: CreateSubscriptionPurchaseOrderOptions): () => void;
|
|
1423
|
-
/**
|
|
1424
|
-
* @public
|
|
1425
|
-
* @category 인앱결제
|
|
1426
|
-
* @name IAP
|
|
1427
|
-
* @description 인앱결제 관련 기능을 모은 객체예요. 단건 인앱결제 주문서 이동과 상품 목록 조회 기능을 제공해요.
|
|
1428
|
-
* @property {typeof createOneTimePurchaseOrder} [createOneTimePurchaseOrder] 특정 인앱결제 주문서 페이지로 이동해요. 자세한 내용은 [createOneTimePurchaseOrder](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/createOneTimePurchaseOrder.html) 문서를 참고하세요.
|
|
1429
|
-
* @property {typeof getProductItemList} [getProductItemList] 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 자세한 내용은 [getProductItemList](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getProductItemList.html) 문서를 참고하세요.
|
|
1430
|
-
* @property {typeof getPendingOrders} [getPendingOrders] 대기 중인 주문 목록을 가져와요. 자세한 내용은 [getPendingOrders](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getPendingOrders.htm) 문서를 참고하세요.
|
|
1431
|
-
* @property {typeof getCompletedOrRefundedOrders} [getCompletedOrRefundedOrders] 인앱결제로 구매하거나 환불한 주문 목록을 가져와요. 자세한 내용은 [getCompletedOrRefundedOrders](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/getCompletedOrRefundedOrders.html) 문서를 참고하세요.
|
|
1432
|
-
* @property {typeof completeProductGrant} [completeProductGrant] 상품 지급 처리를 완료했다는 메시지를 앱에 전달해요. 자세한 내용은 [completeProductGrant](https://developers-apps-in-toss.toss.im/bedrock/reference/framework/%EC%9D%B8%EC%95%B1%20%EA%B2%B0%EC%A0%9C/completeProductGrant.html) 문서를 참고하세요.
|
|
1433
|
-
*/
|
|
1434
|
-
declare const IAP: {
|
|
1435
|
-
createOneTimePurchaseOrder: typeof createOneTimePurchaseOrder;
|
|
1436
|
-
createSubscriptionPurchaseOrder: typeof createSubscriptionPurchaseOrder;
|
|
1437
|
-
getProductItemList: typeof getProductItemList;
|
|
1438
|
-
getPendingOrders: typeof getPendingOrders;
|
|
1439
|
-
getCompletedOrRefundedOrders: typeof getCompletedOrRefundedOrders;
|
|
1440
|
-
completeProductGrant: typeof completeProductGrant;
|
|
1441
|
-
};
|
|
1442
|
-
|
|
1443
|
-
interface SaveBase64DataParams {
|
|
1444
|
-
data: string;
|
|
1445
|
-
fileName: string;
|
|
1446
|
-
mimeType: string;
|
|
1447
|
-
}
|
|
1448
|
-
/**
|
|
1449
|
-
* @public
|
|
1450
|
-
* @category 데이터
|
|
1451
|
-
* @name saveBase64Data
|
|
1452
|
-
* @description 문자열로 인코딩된 Base64 데이터를 지정한 파일 이름과 MIME 타입으로 사용자 기기에 저장해요. 이미지, 텍스트, PDF 등 다양한 형식의 데이터를 저장할 수 있어요.
|
|
1453
|
-
* @param {SaveBase64DataParams} params - 저장할 데이터와 파일 정보를 담은 객체예요.
|
|
1454
|
-
* @param {string} params.data - Base64 형식으로 인코딩된 데이터 문자열이에요.
|
|
1455
|
-
* @param {string} params.fileName - 저장할 파일 이름이에요. 확장자도 같이 붙여줘야해요. 예를 들어, 'example.png'로 저장할 수 있어요.
|
|
1456
|
-
* @param {string} params.mimeType - 저장할 파일의 MIME 타입이에요. 예를 들어 'image/png' 로 지정하면 이미지, 'application/pdf'는 PDF 파일이에요. 자세한 내용은 [MIME 문서](https://developer.mozilla.org/ko/docs/Web/HTTP/Guides/MIME_types)를 참고해주세요.
|
|
1500
|
+
* const showAd = useCallback(() => {
|
|
1501
|
+
* if (GoogleAdMob.showAppsInTossAdMob.isSupported() !== true) {
|
|
1502
|
+
* return;
|
|
1503
|
+
* }
|
|
1457
1504
|
*
|
|
1458
|
-
*
|
|
1459
|
-
*
|
|
1505
|
+
* GoogleAdMob.showAppsInTossAdMob({
|
|
1506
|
+
* options: {
|
|
1507
|
+
* adGroupId: AD_GROUP_ID,
|
|
1508
|
+
* },
|
|
1509
|
+
* onEvent: (event) => {
|
|
1510
|
+
* switch (event.type) {
|
|
1511
|
+
* case 'requested':
|
|
1512
|
+
* console.log('광고 보여주기 요청 완료');
|
|
1513
|
+
* break;
|
|
1460
1514
|
*
|
|
1461
|
-
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
1515
|
+
* case 'clicked':
|
|
1516
|
+
* console.log('광고 클릭');
|
|
1517
|
+
* break;
|
|
1464
1518
|
*
|
|
1465
|
-
*
|
|
1466
|
-
*
|
|
1467
|
-
*
|
|
1468
|
-
*
|
|
1469
|
-
* await saveBase64Data({
|
|
1470
|
-
* data: 'iVBORw0KGgo...',
|
|
1471
|
-
* fileName: 'some-photo.png',
|
|
1472
|
-
* mimeType: 'image/png',
|
|
1473
|
-
* });
|
|
1474
|
-
* } catch (error) {
|
|
1475
|
-
* console.error('데이터 저장에 실패했어요:', error);
|
|
1476
|
-
* }
|
|
1477
|
-
* };
|
|
1519
|
+
* case 'dismissed':
|
|
1520
|
+
* console.log('광고 닫힘');
|
|
1521
|
+
* navigation.navigate('/examples/google-admob-interstitial-ad-landing');
|
|
1522
|
+
* break;
|
|
1478
1523
|
*
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1489
|
-
*
|
|
1490
|
-
*
|
|
1491
|
-
*
|
|
1492
|
-
*
|
|
1493
|
-
*
|
|
1494
|
-
*
|
|
1495
|
-
*
|
|
1496
|
-
*
|
|
1524
|
+
* case 'failedToShow':
|
|
1525
|
+
* console.log('광고 보여주기 실패');
|
|
1526
|
+
* break;
|
|
1527
|
+
*
|
|
1528
|
+
* case 'impression':
|
|
1529
|
+
* console.log('광고 노출');
|
|
1530
|
+
* break;
|
|
1531
|
+
*
|
|
1532
|
+
* case 'userEarnedReward':
|
|
1533
|
+
* console.log('광고 보상 획득 unitType:', event.data.unitType);
|
|
1534
|
+
* console.log('광고 보상 획득 unitAmount:', event.data.unitAmount);
|
|
1535
|
+
* break;
|
|
1536
|
+
*
|
|
1537
|
+
* case 'show':
|
|
1538
|
+
* console.log('광고 컨텐츠 보여졌음');
|
|
1539
|
+
* break;
|
|
1540
|
+
* }
|
|
1541
|
+
* },
|
|
1542
|
+
* onError: (error) => {
|
|
1543
|
+
* console.error('광고 보여주기 실패', error);
|
|
1544
|
+
* },
|
|
1545
|
+
* });
|
|
1546
|
+
* }, []);
|
|
1547
|
+
*
|
|
1548
|
+
* useFocusEffect(loadAd);
|
|
1549
|
+
*
|
|
1550
|
+
* return (
|
|
1551
|
+
* <View>
|
|
1552
|
+
* <Text>
|
|
1553
|
+
* {adLoadStatus === 'not_loaded' && '광고 로드 하지 않음 '}
|
|
1554
|
+
* {adLoadStatus === 'loaded' && '광고 로드 완료'}
|
|
1555
|
+
* {adLoadStatus === 'failed' && '광고 로드 실패'}
|
|
1556
|
+
* </Text>
|
|
1557
|
+
*
|
|
1558
|
+
* <Button title="Show Ad" onPress={showAd} disabled={adLoadStatus !== 'loaded'} />
|
|
1559
|
+
* </View>
|
|
1560
|
+
* );
|
|
1561
|
+
* }
|
|
1562
|
+
* ```
|
|
1497
1563
|
*/
|
|
1498
|
-
|
|
1499
|
-
|
|
1564
|
+
declare function loadAppsInTossAdMob(params: LoadAdMobParams): () => void;
|
|
1565
|
+
declare namespace loadAppsInTossAdMob {
|
|
1566
|
+
var isSupported: () => boolean;
|
|
1500
1567
|
}
|
|
1568
|
+
|
|
1501
1569
|
/**
|
|
1502
1570
|
* @public
|
|
1503
|
-
* @category
|
|
1504
|
-
* @name
|
|
1505
|
-
* @description
|
|
1506
|
-
*
|
|
1507
|
-
* @param {
|
|
1508
|
-
*
|
|
1509
|
-
* @
|
|
1510
|
-
*
|
|
1571
|
+
* @category 광고
|
|
1572
|
+
* @name showAppsInTossAdMob
|
|
1573
|
+
* @description 광고를 사용자에게 노출해요. 이 함수는 `loadAppsInTossAdMob` 로 미리 불러온 광고를 실제로 사용자에게 노출해요.
|
|
1574
|
+
* @param {ShowAdMobParams} params 광고를 보여주기 위해 사용할 설정 값이에요. 광고 그룹 ID와과 광고의 동작에 대한 콜백을 설정할 수 있어요.
|
|
1575
|
+
* @param {ShowAdMobOptions} params.options 광고를 보여줄 때 전달할 옵션 객체예요.
|
|
1576
|
+
* @param {string} params.options.adUnitId 광고 그룹 단위 ID예요. `loadAppsInTossAdMob` 로 불러온 광고용 그룹 ID를 입력해요.
|
|
1577
|
+
* @param {(event: ShowAdMobEvent) => void} [params.onEvent] 광고 관련 이벤트가 발생했을 때 호출돼요. (예시: 광고 노출을 요청했을 때). 자세한 이벤트 타입은 [ShowAdMobEvent](/react-native/reference/native-modules/광고/ShowAdMobEvent.html)를 참고하세요.
|
|
1578
|
+
* @param {(reason: unknown) => void} [params.onError] 광고를 노출하지 못했을 때 호출돼요. (예시: 네트워크 오류나 지원하지 않는 환경일 때)
|
|
1579
|
+
* @property {() => boolean} [isSupported] 현재 실행 중인 앱(예: 토스 앱, 개발용 샌드박스 앱 등)에서 Google AdMob 광고 기능을 지원하는지 확인하는 함수예요. 기능을 사용하기 전에 지원 여부를 확인해야 해요.
|
|
1511
1580
|
*
|
|
1512
1581
|
* @example
|
|
1513
|
-
* ###
|
|
1582
|
+
* ### 버튼 눌러 불러온 광고 보여주기
|
|
1514
1583
|
* ```tsx
|
|
1515
|
-
* import {
|
|
1516
|
-
* import {
|
|
1584
|
+
* import { GoogleAdMob } from '@apps-in-toss/framework';
|
|
1585
|
+
* import { useFocusEffect } from '@react-native-bedrock/native/@react-navigation/native';
|
|
1586
|
+
* import { useCallback, useState } from 'react';
|
|
1587
|
+
* import { Button, Text, View } from 'react-native';
|
|
1588
|
+
* import { useNavigation } from 'react-native-bedrock';
|
|
1517
1589
|
*
|
|
1518
|
-
*
|
|
1519
|
-
* async function handlePress() {
|
|
1520
|
-
* try {
|
|
1521
|
-
* const result = await submitGameCenterLeaderBoardScore({ score: '123.45' });
|
|
1590
|
+
* const AD_GROUP_ID = '<AD_GROUP_ID>';
|
|
1522
1591
|
*
|
|
1523
|
-
*
|
|
1524
|
-
*
|
|
1525
|
-
*
|
|
1526
|
-
* }
|
|
1592
|
+
* export function GoogleAdmobExample() {
|
|
1593
|
+
* const [adLoadStatus, setAdLoadStatus] = useState<'not_loaded' | 'loaded' | 'failed'>('not_loaded');
|
|
1594
|
+
* const navigation = useNavigation();
|
|
1527
1595
|
*
|
|
1528
|
-
*
|
|
1529
|
-
*
|
|
1530
|
-
*
|
|
1531
|
-
* console.error('점수 제출 실패:', result.statusCode);
|
|
1532
|
-
* }
|
|
1533
|
-
* } catch (error) {
|
|
1534
|
-
* console.error('점수 제출 중 오류가 발생했어요.', error);
|
|
1596
|
+
* const loadAd = useCallback(() => {
|
|
1597
|
+
* if (GoogleAdMob.loadAppsInTossAdMob.isSupported() !== true) {
|
|
1598
|
+
* return;
|
|
1535
1599
|
* }
|
|
1536
|
-
|
|
1600
|
+
|
|
1601
|
+
* const cleanup = GoogleAdMob.loadAppsInTossAdMob({
|
|
1602
|
+
* options: {
|
|
1603
|
+
* adGroupId: AD_GROUP_ID,
|
|
1604
|
+
* },
|
|
1605
|
+
* onEvent: (event) => {
|
|
1606
|
+
* switch (event.type) {
|
|
1607
|
+
* case 'loaded':
|
|
1608
|
+
* console.log('광고 로드 성공', event.data);
|
|
1609
|
+
* setAdLoadStatus('loaded');
|
|
1610
|
+
* break;
|
|
1611
|
+
* }
|
|
1612
|
+
* },
|
|
1613
|
+
* onError: (error) => {
|
|
1614
|
+
* console.error('광고 불러오기 실패', error);
|
|
1615
|
+
* },
|
|
1616
|
+
* });
|
|
1617
|
+
*
|
|
1618
|
+
* return cleanup;
|
|
1619
|
+
* }, [navigation]);
|
|
1620
|
+
*
|
|
1621
|
+
* const showAd = useCallback(() => {
|
|
1622
|
+
* if (GoogleAdMob.showAppsInTossAdMob.isSupported() !== true) {
|
|
1623
|
+
* return;
|
|
1624
|
+
* }
|
|
1625
|
+
*
|
|
1626
|
+
* GoogleAdMob.showAppsInTossAdMob({
|
|
1627
|
+
* options: {
|
|
1628
|
+
* adGroupId: AD_GROUP_ID,
|
|
1629
|
+
* },
|
|
1630
|
+
* onEvent: (event) => {
|
|
1631
|
+
* switch (event.type) {
|
|
1632
|
+
* case 'requested':
|
|
1633
|
+
* console.log('광고 보여주기 요청 완료');
|
|
1634
|
+
* break;
|
|
1635
|
+
*
|
|
1636
|
+
* case 'clicked':
|
|
1637
|
+
* console.log('광고 클릭');
|
|
1638
|
+
* break;
|
|
1639
|
+
*
|
|
1640
|
+
* case 'dismissed':
|
|
1641
|
+
* console.log('광고 닫힘');
|
|
1642
|
+
* navigation.navigate('/examples/google-admob-interstitial-ad-landing');
|
|
1643
|
+
* break;
|
|
1644
|
+
*
|
|
1645
|
+
* case 'failedToShow':
|
|
1646
|
+
* console.log('광고 보여주기 실패');
|
|
1647
|
+
* break;
|
|
1648
|
+
*
|
|
1649
|
+
* case 'impression':
|
|
1650
|
+
* console.log('광고 노출');
|
|
1651
|
+
* break;
|
|
1652
|
+
*
|
|
1653
|
+
* case 'userEarnedReward':
|
|
1654
|
+
* console.log('광고 보상 획득 unitType:', event.data.unitType);
|
|
1655
|
+
* console.log('광고 보상 획득 unitAmount:', event.data.unitAmount);
|
|
1656
|
+
* break;
|
|
1657
|
+
*
|
|
1658
|
+
* case 'show':
|
|
1659
|
+
* console.log('광고 컨텐츠 보여졌음');
|
|
1660
|
+
* break;
|
|
1661
|
+
* }
|
|
1662
|
+
* },
|
|
1663
|
+
* onError: (error) => {
|
|
1664
|
+
* console.error('광고 보여주기 실패', error);
|
|
1665
|
+
* },
|
|
1666
|
+
* });
|
|
1667
|
+
* }, []);
|
|
1668
|
+
*
|
|
1669
|
+
* useFocusEffect(loadAd);
|
|
1537
1670
|
*
|
|
1538
1671
|
* return (
|
|
1539
|
-
* <
|
|
1672
|
+
* <View>
|
|
1673
|
+
* <Text>
|
|
1674
|
+
* {adLoadStatus === 'not_loaded' && '광고 로드 하지 않음 '}
|
|
1675
|
+
* {adLoadStatus === 'loaded' && '광고 로드 완료'}
|
|
1676
|
+
* {adLoadStatus === 'failed' && '광고 로드 실패'}
|
|
1677
|
+
* </Text>
|
|
1678
|
+
*
|
|
1679
|
+
* <Button title="Show Ad" onPress={showAd} disabled={adLoadStatus !== 'loaded'} />
|
|
1680
|
+
* </View>
|
|
1540
1681
|
* );
|
|
1541
1682
|
* }
|
|
1542
1683
|
* ```
|
|
1543
1684
|
*/
|
|
1544
|
-
declare function
|
|
1545
|
-
|
|
1546
|
-
|
|
1685
|
+
declare function showAppsInTossAdMob(params: ShowAdMobParams): () => void;
|
|
1686
|
+
declare namespace showAppsInTossAdMob {
|
|
1687
|
+
var isSupported: () => boolean;
|
|
1688
|
+
}
|
|
1547
1689
|
|
|
1548
1690
|
/**
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
*
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
setClipboardText: (option: SetClipboardTextOptions) => Promise<void>;
|
|
1560
|
-
fetchContacts: (option: FetchContactsOptions) => Promise<ContactResult>;
|
|
1561
|
-
fetchAlbumPhotos: (options: FetchAlbumPhotosOptions) => Promise<ImageResponse[]>;
|
|
1562
|
-
getCurrentLocation: (options: GetCurrentLocationOptions) => Promise<Location>;
|
|
1563
|
-
openCamera: (options: OpenCameraOptions) => Promise<ImageResponse>;
|
|
1564
|
-
getWebBundleURL: (arg: CompatiblePlaceholderArgument) => {
|
|
1565
|
-
url: string;
|
|
1566
|
-
};
|
|
1567
|
-
getPermission: (permission: {
|
|
1568
|
-
name: PermissionName;
|
|
1569
|
-
access: PermissionAccess;
|
|
1570
|
-
}) => Promise<PermissionStatus>;
|
|
1571
|
-
openPermissionDialog: (permission: {
|
|
1572
|
-
name: PermissionName;
|
|
1573
|
-
access: PermissionAccess;
|
|
1574
|
-
}) => Promise<Exclude<PermissionStatus, 'notDetermined'>>;
|
|
1575
|
-
appLogin: (arg: CompatiblePlaceholderArgument) => Promise<{
|
|
1576
|
-
authorizationCode: string;
|
|
1577
|
-
referrer: 'DEFAULT' | 'SANDBOX';
|
|
1578
|
-
}>;
|
|
1579
|
-
checkoutPayment: (options: {
|
|
1580
|
-
params: CheckoutPaymentOptions;
|
|
1581
|
-
}) => Promise<CheckoutPaymentResult>;
|
|
1582
|
-
/** Storage */
|
|
1583
|
-
getStorageItem: (params: {
|
|
1584
|
-
key: string;
|
|
1585
|
-
}) => Promise<string | null>;
|
|
1586
|
-
setStorageItem: (params: {
|
|
1587
|
-
key: string;
|
|
1588
|
-
value: string;
|
|
1589
|
-
}) => Promise<void>;
|
|
1590
|
-
removeStorageItem: (params: {
|
|
1591
|
-
key: string;
|
|
1592
|
-
}) => Promise<void>;
|
|
1593
|
-
clearStorage: (arg: CompatiblePlaceholderArgument) => Promise<void>;
|
|
1594
|
-
eventLog: (params: {
|
|
1595
|
-
log_name: string;
|
|
1596
|
-
log_type: 'debug' | 'info' | 'warn' | 'error' | 'event' | 'screen' | 'impression' | 'click';
|
|
1597
|
-
params: Record<string, string>;
|
|
1598
|
-
}) => Promise<void>;
|
|
1599
|
-
getTossShareLink: (params: object) => Promise<{
|
|
1600
|
-
shareLink: string;
|
|
1601
|
-
}>;
|
|
1602
|
-
setDeviceOrientation: (options: {
|
|
1603
|
-
type: 'portrait' | 'landscape';
|
|
1604
|
-
}) => Promise<void>;
|
|
1605
|
-
saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
|
|
1606
|
-
/** IAP */
|
|
1607
|
-
iapGetProductItemList: (arg: CompatiblePlaceholderArgument) => Promise<{
|
|
1608
|
-
products: IapProductListItem[];
|
|
1609
|
-
}>;
|
|
1610
|
-
/** @deprecated `requestOneTimePurchase`를 사용해주세요. */
|
|
1611
|
-
iapCreateOneTimePurchaseOrder: (params: {
|
|
1612
|
-
productId: string;
|
|
1613
|
-
}) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1614
|
-
requestOneTimePurchase: (params: {
|
|
1615
|
-
sku: string;
|
|
1616
|
-
}, fallbacks: {
|
|
1617
|
-
onPurchased: (params: {
|
|
1618
|
-
orderId: string;
|
|
1619
|
-
}) => void;
|
|
1620
|
-
}) => () => void;
|
|
1621
|
-
requestSubscriptionPurchase: (params: {
|
|
1622
|
-
sku: string;
|
|
1623
|
-
offerId: string | null;
|
|
1624
|
-
}, fallbacks: {
|
|
1625
|
-
onPurchased: (params: {
|
|
1626
|
-
orderId: string;
|
|
1627
|
-
subscriptionId?: string;
|
|
1628
|
-
}) => void;
|
|
1629
|
-
}) => () => void;
|
|
1630
|
-
processProductGrant: (params: {
|
|
1631
|
-
orderId: string;
|
|
1632
|
-
isProductGranted: boolean;
|
|
1633
|
-
}) => Promise<void>;
|
|
1634
|
-
getPendingOrders: (params: CompatiblePlaceholderArgument) => Promise<{
|
|
1635
|
-
orders: {
|
|
1636
|
-
orderId: string;
|
|
1637
|
-
sku: string;
|
|
1638
|
-
paymentCompletedDate: string;
|
|
1639
|
-
}[];
|
|
1640
|
-
}>;
|
|
1641
|
-
getCompletedOrRefundedOrders: (params: {
|
|
1642
|
-
key?: string | null;
|
|
1643
|
-
}) => Promise<CompletedOrRefundedOrdersResult>;
|
|
1644
|
-
completeProductGrant: (params: {
|
|
1645
|
-
params: {
|
|
1646
|
-
orderId: string;
|
|
1647
|
-
};
|
|
1648
|
-
}) => Promise<boolean>;
|
|
1649
|
-
getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse>;
|
|
1650
|
-
getUserKeyForGame: (params: CompatiblePlaceholderArgument) => Promise<GetUserKeyForGameResponse>;
|
|
1651
|
-
getIsTossLoginIntegratedService: (params: CompatiblePlaceholderArgument) => Promise<boolean>;
|
|
1652
|
-
grantPromotionRewardForGame: (params: {
|
|
1653
|
-
params: {
|
|
1654
|
-
promotionCode: string;
|
|
1655
|
-
amount: number;
|
|
1656
|
-
};
|
|
1657
|
-
}) => Promise<GrantPromotionRewardForGameResponse>;
|
|
1658
|
-
submitGameCenterLeaderBoardScore: (params: {
|
|
1659
|
-
score: string;
|
|
1660
|
-
}) => Promise<SubmitGameCenterLeaderBoardScoreResponse>;
|
|
1661
|
-
contactsViral: (params: ContactsViralParams) => () => void;
|
|
1662
|
-
/** 토스인증 */
|
|
1663
|
-
appsInTossSignTossCert: (params: {
|
|
1664
|
-
params: AppsInTossSignTossCertParams;
|
|
1665
|
-
}) => void;
|
|
1666
|
-
getServerTime: (arg: CompatiblePlaceholderArgument) => Promise<{
|
|
1667
|
-
serverTime: number;
|
|
1668
|
-
}>;
|
|
1691
|
+
* @public
|
|
1692
|
+
* @category 광고
|
|
1693
|
+
* @name showAppsInTossAdMob
|
|
1694
|
+
* @description 이 함수는 `loadAppsInTossAdMob` 로 광고가 잘 불러와졌는지 확인해요.
|
|
1695
|
+
* @param {string} params.adUnitId 광고 그룹 단위 ID예요.
|
|
1696
|
+
* @property {() => boolean} [isSupported] 현재 실행 중인 앱(예: 토스 앱, 개발용 샌드박스 앱 등)에서 `isAppsInTossAdMobLoaded` 를 지원하는지 확인하는 함수예요. 기능을 사용하기 전에 지원 여부를 확인해야 해요.
|
|
1697
|
+
*/
|
|
1698
|
+
declare function isAppsInTossAdMobLoaded(params: IsAdMobLoadedOptions): Promise<boolean>;
|
|
1699
|
+
declare namespace isAppsInTossAdMobLoaded {
|
|
1700
|
+
var isSupported: typeof isAppsInTossAdMobLoadedSupported;
|
|
1669
1701
|
}
|
|
1670
|
-
declare
|
|
1671
|
-
declare const AppsInTossModule: Spec;
|
|
1702
|
+
declare function isAppsInTossAdMobLoadedSupported(): boolean;
|
|
1672
1703
|
|
|
1673
1704
|
/**
|
|
1674
1705
|
* @public
|
|
@@ -2343,34 +2374,30 @@ declare function getTossAppVersion(): string;
|
|
|
2343
2374
|
* @kind function
|
|
2344
2375
|
* @name getTossShareLink
|
|
2345
2376
|
* @description
|
|
2346
|
-
* 사용자가 지정한 경로를 토스 앱에서 열 수 있는 공유 링크를
|
|
2377
|
+
* `getTossShareLink` 함수는 사용자가 지정한 경로를 토스 앱에서 열 수 있는 공유 링크를 반환해요.
|
|
2378
|
+
* 이 링크를 다른 사람과 공유하면 토스 앱이 실행되면서 지정한 경로로 진입해요. 토스앱이 없는 사람은 iOS 일 때는 앱스토어로 이동하고, Android 일 때는 플레이스토어로 이동해요.
|
|
2379
|
+
*
|
|
2380
|
+
* 경로는 토스 앱 내부 특정 화면을 나타내는 딥링크(deep link) 형식이어야 해요.
|
|
2381
|
+
* 예를 들어 `intoss://<앱 이름>`이나 `intoss://<앱 이름>/about?name=test`처럼 작성해요.
|
|
2347
2382
|
*
|
|
2348
|
-
*
|
|
2349
|
-
* - 토스 앱이 설치되어 있으면: 토스 앱이 실행되면서 지정한 경로로 이동해요.
|
|
2350
|
-
* - 토스 앱이 없으면: iOS는 앱스토어로, Android는 플레이스토어로 이동해요.
|
|
2383
|
+
* 이 함수를 사용하면 `deep_link_value`를 포함한 완성된 공유 링크를 만들 수 있어요.
|
|
2351
2384
|
*
|
|
2352
|
-
* @param path -
|
|
2353
|
-
* @
|
|
2354
|
-
* @returns {Promise<string>} 생성된 토스 공유 링크
|
|
2385
|
+
* @param path - 딥링크로 열고 싶은 경로예요. `intoss://`로 시작하는 문자열이어야 해요.
|
|
2386
|
+
* @returns {Promise<string>} `deep_link_value`가 포함된 토스 공유 링크를 반환해요.
|
|
2355
2387
|
*
|
|
2356
2388
|
* @example
|
|
2357
2389
|
* ```tsx
|
|
2358
2390
|
* import { share } from '@granite-js/react-native';
|
|
2359
2391
|
* import { getTossShareLink } from '@apps-in-toss/framework';
|
|
2360
2392
|
*
|
|
2361
|
-
* //
|
|
2393
|
+
* // '/' 경로를 딥링크로 포함한 토스 공유 링크를 생성해요.
|
|
2362
2394
|
* const tossLink = await getTossShareLink('intoss://my-app');
|
|
2363
|
-
* await share({ message: tossLink });
|
|
2364
2395
|
*
|
|
2365
|
-
* //
|
|
2366
|
-
*
|
|
2367
|
-
* 'intoss://my-app/event',
|
|
2368
|
-
* 'https://example.com/og-image.png'
|
|
2369
|
-
* );
|
|
2370
|
-
* await share({ message: linkWithImage });
|
|
2396
|
+
* // 생성한 링크를 메시지로 공유해요.
|
|
2397
|
+
* await share({ message: tossLink });
|
|
2371
2398
|
* ```
|
|
2372
2399
|
*/
|
|
2373
|
-
declare function getTossShareLink(path: string
|
|
2400
|
+
declare function getTossShareLink(path: string): Promise<string>;
|
|
2374
2401
|
|
|
2375
2402
|
/**
|
|
2376
2403
|
* @public
|
|
@@ -2636,6 +2663,45 @@ declare function openGameCenterLeaderboard(): Promise<void>;
|
|
|
2636
2663
|
*/
|
|
2637
2664
|
declare function getIsTossLoginIntegratedService(): Promise<boolean | undefined>;
|
|
2638
2665
|
|
|
2666
|
+
/**
|
|
2667
|
+
* @public
|
|
2668
|
+
* @category Constants
|
|
2669
|
+
* @name getGroupId
|
|
2670
|
+
* @description 앱인토스에서 제공하는 그룹 ID를 가져와요.
|
|
2671
|
+
* @returns {string} 그룹 ID
|
|
2672
|
+
*
|
|
2673
|
+
* @example
|
|
2674
|
+
* ```typescript
|
|
2675
|
+
* import { getGroupId } from '@apps-in-toss/native-modules';
|
|
2676
|
+
*
|
|
2677
|
+
* const groupId = getGroupId();
|
|
2678
|
+
* console.log('Group ID:', groupId);
|
|
2679
|
+
* ```
|
|
2680
|
+
*/
|
|
2681
|
+
declare function getGroupId(): string;
|
|
2682
|
+
|
|
2683
|
+
/**
|
|
2684
|
+
* @public
|
|
2685
|
+
* @category 공유
|
|
2686
|
+
* @kind function
|
|
2687
|
+
* @name shareWithScheme
|
|
2688
|
+
* @description
|
|
2689
|
+
* `shareWithScheme` 함수는 지정한 스킴 URL을 다른 앱과 공유해요.
|
|
2690
|
+
*
|
|
2691
|
+
* @param params - 공유할 스킴 URL 정보
|
|
2692
|
+
* @param params.schemeURL - 공유할 스킴 URL
|
|
2693
|
+
*
|
|
2694
|
+
* @example
|
|
2695
|
+
* ```tsx
|
|
2696
|
+
* import { shareWithScheme } from '@apps-in-toss/native-modules';
|
|
2697
|
+
*
|
|
2698
|
+
* shareWithScheme({ schemeURL: 'intoss://my-app?referrer=share' });
|
|
2699
|
+
* ```
|
|
2700
|
+
*/
|
|
2701
|
+
declare function shareWithScheme(params: {
|
|
2702
|
+
schemeURL: string;
|
|
2703
|
+
}): void;
|
|
2704
|
+
|
|
2639
2705
|
/**
|
|
2640
2706
|
* @public
|
|
2641
2707
|
* @category 시간
|
|
@@ -2682,6 +2748,7 @@ declare namespace getServerTime {
|
|
|
2682
2748
|
declare const TossPay: {
|
|
2683
2749
|
checkoutPayment: typeof checkoutPayment;
|
|
2684
2750
|
};
|
|
2751
|
+
|
|
2685
2752
|
/**
|
|
2686
2753
|
* @public
|
|
2687
2754
|
* @category 광고
|
|
@@ -3118,48 +3185,14 @@ declare function openURL(url: string): Promise<any>;
|
|
|
3118
3185
|
*/
|
|
3119
3186
|
declare function getPlatformOS(): 'ios' | 'android';
|
|
3120
3187
|
|
|
3121
|
-
interface BedrockModule {
|
|
3122
|
-
closeView: () => void;
|
|
3123
|
-
generateHapticFeedback: (options: HapticFeedbackOptions) => Promise<void>;
|
|
3124
|
-
share: (message: {
|
|
3125
|
-
message: string;
|
|
3126
|
-
}) => void;
|
|
3127
|
-
setSecureScreen: (options: {
|
|
3128
|
-
enabled: boolean;
|
|
3129
|
-
}) => Promise<{
|
|
3130
|
-
enabled: boolean;
|
|
3131
|
-
}>;
|
|
3132
|
-
setScreenAwakeMode: (options: {
|
|
3133
|
-
enabled: boolean;
|
|
3134
|
-
}) => Promise<{
|
|
3135
|
-
enabled: boolean;
|
|
3136
|
-
}>;
|
|
3137
|
-
getNetworkStatus: () => Promise<NetworkStatus>;
|
|
3138
|
-
setIosSwipeGestureEnabled: ({ isEnabled }: {
|
|
3139
|
-
isEnabled: boolean;
|
|
3140
|
-
}) => Promise<void>;
|
|
3141
|
-
deviceId: string;
|
|
3142
|
-
DeviceInfo: {
|
|
3143
|
-
locale: string;
|
|
3144
|
-
};
|
|
3145
|
-
schemeUri: string;
|
|
3146
|
-
}
|
|
3147
|
-
declare const BedrockModule: BedrockModule;
|
|
3148
|
-
|
|
3149
|
-
interface BedrockCoreModule {
|
|
3150
|
-
addListener: (eventType: string) => void;
|
|
3151
|
-
removeListeners: (count: number) => void;
|
|
3152
|
-
}
|
|
3153
|
-
declare const BedrockCoreModule: BedrockCoreModule;
|
|
3154
|
-
|
|
3155
3188
|
declare function tossCoreEventLog(params: {
|
|
3156
3189
|
log_name: string;
|
|
3157
3190
|
log_type: string;
|
|
3158
3191
|
params: Record<string, unknown>;
|
|
3159
|
-
}): void;
|
|
3192
|
+
}): Promise<void> | undefined;
|
|
3160
3193
|
|
|
3161
3194
|
declare const INTERNAL__module: {
|
|
3162
3195
|
tossCoreEventLog: typeof tossCoreEventLog;
|
|
3163
3196
|
};
|
|
3164
3197
|
|
|
3165
|
-
export {
|
|
3198
|
+
export { type AppsInTossSignTossCertParams, type CheckoutPaymentOptions, type CheckoutPaymentResult, type CompletedOrRefundedOrdersResult, type ConsumableProductListItem, type ContactsViralParams, type CreateSubscriptionPurchaseOrderOptions, type EventLogParams, type GameCenterGameProfileResponse, type GetUserKeyForGameErrorResponse, type GetUserKeyForGameResponse, type GetUserKeyForGameSuccessResponse, GoogleAdMob, type GrantPromotionRewardForGameErrorResponse, type GrantPromotionRewardForGameErrorResult, type GrantPromotionRewardForGameResponse, type GrantPromotionRewardForGameSuccessResponse, type HapticFeedbackType, IAP, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapCreateSubscriptionPurchaseOrderResult, type IapProductListItem, type NetworkStatus, type NonConsumableProductListItem, type Primitive, type SaveBase64DataParams, Storage, type SubmitGameCenterLeaderBoardScoreResponse, type SubscriptionProductListItem, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, appsInTossSignTossCert, checkoutPayment, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getGroupId, getIsTossLoginIntegratedService, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getServerTime, getTossAppVersion, getTossShareLink, getUserKeyForGame, grantPromotionRewardForGame, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, processProductGrant, requestOneTimePurchase, safePostMessage, safeSyncPostMessage, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, shareWithScheme, startUpdateLocation, submitGameCenterLeaderBoardScore };
|