@apps-in-toss/native-modules 0.0.0-dev.1758103372343 → 0.0.0-dev.1758275837494
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/index.cjs +76 -5
- package/dist/index.d.cts +93 -28
- package/dist/index.d.ts +93 -28
- package/dist/index.js +73 -5
- package/package.json +3 -3
- package/src/AppsInTossModule/native-modules/AppsInTossModule.ts +9 -8
- package/src/AppsInTossModule/native-modules/iap.ts +157 -31
package/dist/index.cjs
CHANGED
|
@@ -50,11 +50,14 @@ __export(index_exports, {
|
|
|
50
50
|
getSchemeUri: () => getSchemeUri,
|
|
51
51
|
getTossAppVersion: () => getTossAppVersion,
|
|
52
52
|
getTossShareLink: () => getTossShareLink,
|
|
53
|
+
iapCreateOneTimePurchaseOrder: () => iapCreateOneTimePurchaseOrder,
|
|
53
54
|
isMinVersionSupported: () => isMinVersionSupported,
|
|
54
55
|
onVisibilityChangedByTransparentServiceWeb: () => onVisibilityChangedByTransparentServiceWeb,
|
|
55
56
|
openCamera: () => openCamera,
|
|
56
57
|
openGameCenterLeaderboard: () => openGameCenterLeaderboard,
|
|
57
58
|
openURL: () => openURL2,
|
|
59
|
+
processProductGrant: () => processProductGrant,
|
|
60
|
+
requestOneTimePurchase: () => requestOneTimePurchase,
|
|
58
61
|
saveBase64Data: () => saveBase64Data,
|
|
59
62
|
setClipboardText: () => setClipboardText,
|
|
60
63
|
setDeviceOrientation: () => setDeviceOrientation,
|
|
@@ -709,15 +712,80 @@ async function getTossShareLink(path) {
|
|
|
709
712
|
}
|
|
710
713
|
|
|
711
714
|
// src/AppsInTossModule/native-modules/iap.ts
|
|
712
|
-
|
|
713
|
-
|
|
715
|
+
var import_es_toolkit3 = require("es-toolkit");
|
|
716
|
+
function iapCreateOneTimePurchaseOrder(params) {
|
|
717
|
+
const sku = params.sku ?? params.productId;
|
|
718
|
+
return AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku });
|
|
719
|
+
}
|
|
720
|
+
function processProductGrant(params) {
|
|
721
|
+
return AppsInTossModule.processProductGrant({ orderId: params.orderId, isProductGranted: params.isProductGranted });
|
|
722
|
+
}
|
|
723
|
+
function requestOneTimePurchase(params) {
|
|
724
|
+
const { options, onEvent, onError } = params;
|
|
725
|
+
const sku = options.sku ?? options.productId;
|
|
726
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
727
|
+
"requestOneTimePurchase",
|
|
728
|
+
{ sku },
|
|
729
|
+
{
|
|
730
|
+
onPurchased: (params2) => {
|
|
731
|
+
onEvent({ type: "purchased", data: params2 });
|
|
732
|
+
},
|
|
733
|
+
onSuccess: (result) => {
|
|
734
|
+
onEvent({ type: "success", data: result });
|
|
735
|
+
},
|
|
736
|
+
onError: (error) => {
|
|
737
|
+
onError(error);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
);
|
|
741
|
+
return unregisterCallbacks;
|
|
742
|
+
}
|
|
743
|
+
function createOneTimePurchaseOrder(params) {
|
|
744
|
+
const isIAPSupported = isMinVersionSupported({
|
|
714
745
|
android: "5.219.0",
|
|
715
746
|
ios: "5.219.0"
|
|
716
747
|
});
|
|
717
|
-
if (!
|
|
718
|
-
return;
|
|
748
|
+
if (!isIAPSupported) {
|
|
749
|
+
return import_es_toolkit3.noop;
|
|
750
|
+
}
|
|
751
|
+
const isProcessProductGrantSupported = isMinVersionSupported({
|
|
752
|
+
android: "5.230.0",
|
|
753
|
+
ios: "5.230.0"
|
|
754
|
+
});
|
|
755
|
+
const { options, onEvent, onError } = params;
|
|
756
|
+
const sku = options.sku ?? options.productId;
|
|
757
|
+
if (!isProcessProductGrantSupported) {
|
|
758
|
+
const v1 = () => {
|
|
759
|
+
AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku }).then((response) => {
|
|
760
|
+
Promise.resolve(options.processProductGrant({ orderId: response.orderId })).then(() => {
|
|
761
|
+
onEvent({ type: "success", data: response });
|
|
762
|
+
}).catch((error) => {
|
|
763
|
+
onError(error);
|
|
764
|
+
});
|
|
765
|
+
}).catch((error) => {
|
|
766
|
+
onError(error);
|
|
767
|
+
});
|
|
768
|
+
return import_es_toolkit3.noop;
|
|
769
|
+
};
|
|
770
|
+
return v1();
|
|
719
771
|
}
|
|
720
|
-
|
|
772
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
773
|
+
"requestOneTimePurchase",
|
|
774
|
+
{ sku },
|
|
775
|
+
{
|
|
776
|
+
onPurchased: async (params2) => {
|
|
777
|
+
const isProductGranted = await options.processProductGrant(params2);
|
|
778
|
+
await AppsInTossModule.processProductGrant({ orderId: params2.orderId, isProductGranted });
|
|
779
|
+
},
|
|
780
|
+
onSuccess: (result) => {
|
|
781
|
+
onEvent({ type: "success", data: result });
|
|
782
|
+
},
|
|
783
|
+
onError: (error) => {
|
|
784
|
+
onError(error);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
);
|
|
788
|
+
return unregisterCallbacks;
|
|
721
789
|
}
|
|
722
790
|
async function getProductItemList() {
|
|
723
791
|
const isSupported = isMinVersionSupported({
|
|
@@ -1005,11 +1073,14 @@ var INTERNAL__module = {
|
|
|
1005
1073
|
getSchemeUri,
|
|
1006
1074
|
getTossAppVersion,
|
|
1007
1075
|
getTossShareLink,
|
|
1076
|
+
iapCreateOneTimePurchaseOrder,
|
|
1008
1077
|
isMinVersionSupported,
|
|
1009
1078
|
onVisibilityChangedByTransparentServiceWeb,
|
|
1010
1079
|
openCamera,
|
|
1011
1080
|
openGameCenterLeaderboard,
|
|
1012
1081
|
openURL,
|
|
1082
|
+
processProductGrant,
|
|
1083
|
+
requestOneTimePurchase,
|
|
1013
1084
|
saveBase64Data,
|
|
1014
1085
|
setClipboardText,
|
|
1015
1086
|
setDeviceOrientation,
|
package/dist/index.d.cts
CHANGED
|
@@ -1411,16 +1411,16 @@ type GameCenterGameProfileResponse = {
|
|
|
1411
1411
|
*/
|
|
1412
1412
|
declare function getGameCenterGameProfile(): Promise<GameCenterGameProfileResponse | undefined>;
|
|
1413
1413
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
* @description 인앱결제 1건을 요청할 때 필요한 정보예요.
|
|
1419
|
-
* @property {string} productId - 주문할 상품의 ID예요.
|
|
1420
|
-
*/
|
|
1421
|
-
interface IapCreateOneTimePurchaseOrderOptions {
|
|
1414
|
+
type Sku = {
|
|
1415
|
+
/**
|
|
1416
|
+
* @deprecated `productId`는 더 이상 사용하지 않아요. 대신 `sku`를 사용해요.
|
|
1417
|
+
*/
|
|
1422
1418
|
productId: string;
|
|
1423
|
-
|
|
1419
|
+
sku?: string;
|
|
1420
|
+
} | {
|
|
1421
|
+
productId?: never;
|
|
1422
|
+
sku: string;
|
|
1423
|
+
};
|
|
1424
1424
|
/**
|
|
1425
1425
|
* @public
|
|
1426
1426
|
* @category 인앱결제
|
|
@@ -1443,15 +1443,54 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1443
1443
|
fraction: number;
|
|
1444
1444
|
miniAppIconUrl: string | null;
|
|
1445
1445
|
}
|
|
1446
|
+
interface SuccessEvent {
|
|
1447
|
+
type: 'success';
|
|
1448
|
+
data: IapCreateOneTimePurchaseOrderResult;
|
|
1449
|
+
}
|
|
1450
|
+
interface PurchasedEvent {
|
|
1451
|
+
type: 'purchased';
|
|
1452
|
+
data: {
|
|
1453
|
+
orderId: string;
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* @public
|
|
1458
|
+
* @category 인앱결제
|
|
1459
|
+
* @name IapCreateOneTimePurchaseOrderOptions
|
|
1460
|
+
* @property {Sku} options - 결제할 상품의 정보예요.
|
|
1461
|
+
* @property {string} options.sku - 주문할 상품의 고유 ID예요.
|
|
1462
|
+
* @property {(params: { orderId: string }) => boolean | Promise<boolean>} processProductGrant - 주문이 만들어진 뒤 실제로 상품을 지급할 때 호출해요. `orderId`를 받아서 지급 성공 여부를 `true` 또는 `Promise<true>`로 반환해요. 지급에 실패하면 `false`를 반환해요.
|
|
1463
|
+
* @property {(event: SuccessEvent) => void | Promise<void>} onEvent - 결제가 성공했을 때 호출해요. `event.type`이 `'success'`이고, `event.data`에 `IapCreateOneTimePurchaseOrderResult`가 들어 있어요.
|
|
1464
|
+
* @property {(error: unknown) => void | Promise<void>} onError - 결제 과정에서 에러가 발생했을 때 호출해요. 에러 객체를 받아서 로깅하거나 복구 절차를 실행할 수 있어요.
|
|
1465
|
+
*/
|
|
1466
|
+
interface IapCreateOneTimePurchaseOrderOptions {
|
|
1467
|
+
options: Sku & {
|
|
1468
|
+
processProductGrant: (params: {
|
|
1469
|
+
orderId: string;
|
|
1470
|
+
}) => boolean | Promise<boolean>;
|
|
1471
|
+
};
|
|
1472
|
+
onEvent: (event: SuccessEvent) => void | Promise<void>;
|
|
1473
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
1474
|
+
}
|
|
1475
|
+
interface IapRequestOneTimePurchaseOptions {
|
|
1476
|
+
options: Sku;
|
|
1477
|
+
onEvent: (event: PurchasedEvent | SuccessEvent) => void | Promise<void>;
|
|
1478
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
1479
|
+
}
|
|
1480
|
+
declare function iapCreateOneTimePurchaseOrder(params: Sku): Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1481
|
+
declare function processProductGrant(params: {
|
|
1482
|
+
orderId: string;
|
|
1483
|
+
isProductGranted: boolean;
|
|
1484
|
+
}): Promise<void>;
|
|
1485
|
+
declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions): () => void;
|
|
1446
1486
|
/**
|
|
1447
1487
|
* @public
|
|
1448
1488
|
* @category 인앱결제
|
|
1449
|
-
* @name
|
|
1489
|
+
* @name createOneTimePurchaseOrder
|
|
1450
1490
|
* @description
|
|
1451
1491
|
* 특정 인앱결제 주문서 페이지로 이동해요. 사용자가 상품 구매 버튼을 누르는 상황 등에 사용할 수 있어요. 사용자의 결제는 이동한 페이지에서 진행돼요. 만약 결제 중에 에러가 발생하면 에러 유형에 따라 에러 페이지로 이동해요.
|
|
1452
1492
|
* @param {IapCreateOneTimePurchaseOrderOptions} params - 인앱결제를 생성할 때 필요한 정보예요.
|
|
1453
|
-
* @
|
|
1454
|
-
* @returns {Promise<IapCreateOneTimePurchaseOrderResult | undefined>} 결제에 성공하면 결제 결과 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 인앱결제를 실행할 수 없어서 `undefined`를 반환해요.
|
|
1493
|
+
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 인앱결제 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
1455
1494
|
*
|
|
1456
1495
|
* @throw {code: "INVALID_PRODUCT_ID"} - 유효하지 않은 상품 ID이거나, 해당 상품이 존재하지 않을 때 발생해요.
|
|
1457
1496
|
* @throw {code: "PAYMENT_PENDING"} - 사용자가 요청한 결제가 아직 승인을 기다리고 있을 때 발생해요.
|
|
@@ -1463,6 +1502,7 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1463
1502
|
* @throw {code: "INTERNAL_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
1464
1503
|
* @throw {code: "KOREAN_ACCOUNT_ONLY"} - iOS 환경에서 사용자의 계정이 한국 계정이 아닐 때 발생해요.
|
|
1465
1504
|
* @throw {code: "USER_CANCELED"} - 사용자가 결제를 완료하지 않고 주문서 페이지를 이탈했을 때 발생해요.
|
|
1505
|
+
* @throw {code: "PRODUCT_NOT_GRANTED_BY_PARTNER"} - 파트너사의 상품 지급이 실패했을 때 발생해요.
|
|
1466
1506
|
*
|
|
1467
1507
|
* @example
|
|
1468
1508
|
* ### 특정 인앱결제 주문서 페이지로 이동하기
|
|
@@ -1470,28 +1510,39 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1470
1510
|
* ```tsx
|
|
1471
1511
|
* import { IAP } from "@apps-in-toss/web-framework";
|
|
1472
1512
|
* import { Button } from "@toss-design-system/react-native";
|
|
1513
|
+
* import { useCallback } from "react";
|
|
1473
1514
|
*
|
|
1474
1515
|
* interface Props {
|
|
1475
|
-
*
|
|
1516
|
+
* sku: string;
|
|
1476
1517
|
* }
|
|
1477
1518
|
*
|
|
1478
|
-
* function IapCreateOneTimePurchaseOrderButton({
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1485
|
-
*
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1519
|
+
* function IapCreateOneTimePurchaseOrderButton({ sku }: Props) {
|
|
1520
|
+
* const handleClick = useCallback(async () => {
|
|
1521
|
+
*
|
|
1522
|
+
* const cleanup = await IAP.createOneTimePurchaseOrder({
|
|
1523
|
+
* options: {
|
|
1524
|
+
* sku,
|
|
1525
|
+
* processProductGrant: ({ orderId }) => {
|
|
1526
|
+
* // 상품 지급 로직 작성
|
|
1527
|
+
* return true; // 상품 지급 여부
|
|
1528
|
+
* }
|
|
1529
|
+
* },
|
|
1530
|
+
* onEvent: (event) => {
|
|
1531
|
+
* console.log(event);
|
|
1532
|
+
* },
|
|
1533
|
+
* onError: (error) => {
|
|
1534
|
+
* console.error(error);
|
|
1535
|
+
* },
|
|
1536
|
+
* });
|
|
1537
|
+
*
|
|
1538
|
+
* return cleanup;
|
|
1539
|
+
* }, []);
|
|
1489
1540
|
*
|
|
1490
1541
|
* return <Button onClick={handleClick}>구매하기</Button>;
|
|
1491
1542
|
* }
|
|
1492
1543
|
* ```
|
|
1493
1544
|
*/
|
|
1494
|
-
declare function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions):
|
|
1545
|
+
declare function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions): () => void;
|
|
1495
1546
|
/**
|
|
1496
1547
|
* @public
|
|
1497
1548
|
* @category 인앱결제
|
|
@@ -1513,7 +1564,7 @@ interface IapProductListItem {
|
|
|
1513
1564
|
/**
|
|
1514
1565
|
* @public
|
|
1515
1566
|
* @category 인앱결제
|
|
1516
|
-
* @name
|
|
1567
|
+
* @name getProductItemList
|
|
1517
1568
|
* @description 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 상품 목록 화면에 진입할 때 호출해요.
|
|
1518
1569
|
* @returns {Promise<{ products: IapProductListItem[] } | undefined>} 상품 목록을 포함한 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 `undefined`를 반환해요.
|
|
1519
1570
|
*
|
|
@@ -1761,10 +1812,24 @@ interface Spec extends TurboModule {
|
|
|
1761
1812
|
}) => Promise<void>;
|
|
1762
1813
|
saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
|
|
1763
1814
|
/** IAP */
|
|
1764
|
-
iapCreateOneTimePurchaseOrder: (params: IapCreateOneTimePurchaseOrderOptions) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1765
1815
|
iapGetProductItemList: (arg: CompatiblePlaceholderArgument) => Promise<{
|
|
1766
1816
|
products: IapProductListItem[];
|
|
1767
1817
|
}>;
|
|
1818
|
+
/** @deprecated `requestOneTimePurchase`를 사용해주세요. */
|
|
1819
|
+
iapCreateOneTimePurchaseOrder: (params: {
|
|
1820
|
+
productId: string;
|
|
1821
|
+
}) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1822
|
+
requestOneTimePurchase: (params: {
|
|
1823
|
+
sku: string;
|
|
1824
|
+
}, fallbacks: {
|
|
1825
|
+
onPurchased: (params: {
|
|
1826
|
+
orderId: string;
|
|
1827
|
+
}) => void;
|
|
1828
|
+
}) => () => void;
|
|
1829
|
+
processProductGrant: (params: {
|
|
1830
|
+
orderId: string;
|
|
1831
|
+
isProductGranted: boolean;
|
|
1832
|
+
}) => Promise<void>;
|
|
1768
1833
|
getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse>;
|
|
1769
1834
|
submitGameCenterLeaderBoardScore: (params: {
|
|
1770
1835
|
score: string;
|
|
@@ -3183,4 +3248,4 @@ declare const INTERNAL__module: {
|
|
|
3183
3248
|
tossCoreEventLog: typeof tossCoreEventLog;
|
|
3184
3249
|
};
|
|
3185
3250
|
|
|
3186
|
-
export { AppsInTossModule, BedrockCoreModule, BedrockModule, type CheckoutPaymentOptions, type CheckoutPaymentResult, type ContactsViralParams, type EventLogParams, type GameCenterGameProfileResponse, GoogleAdMob, type HapticFeedbackType, IAP, AppsInTossModuleInstance as INTERNAL__AppsInTossModule, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapProductListItem, type LoadAdMobEvent, type LoadAdMobInterstitialAdEvent, type LoadAdMobInterstitialAdOptions, type LoadAdMobOptions, type LoadAdMobParams, type LoadAdMobRewardedAdEvent, type LoadAdMobRewardedAdOptions, type NetworkStatus, type Primitive, type SaveBase64DataParams, type ShowAdMobEvent, type ShowAdMobInterstitialAdEvent, type ShowAdMobInterstitialAdOptions, type ShowAdMobOptions, type ShowAdMobParams, type ShowAdMobRewardedAdEvent, type ShowAdMobRewardedAdOptions, Storage, type SubmitGameCenterLeaderBoardScoreResponse, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getTossAppVersion, getTossShareLink, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, startUpdateLocation, submitGameCenterLeaderBoardScore };
|
|
3251
|
+
export { AppsInTossModule, BedrockCoreModule, BedrockModule, type CheckoutPaymentOptions, type CheckoutPaymentResult, type ContactsViralParams, type EventLogParams, type GameCenterGameProfileResponse, GoogleAdMob, type HapticFeedbackType, IAP, AppsInTossModuleInstance as INTERNAL__AppsInTossModule, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapProductListItem, type LoadAdMobEvent, type LoadAdMobInterstitialAdEvent, type LoadAdMobInterstitialAdOptions, type LoadAdMobOptions, type LoadAdMobParams, type LoadAdMobRewardedAdEvent, type LoadAdMobRewardedAdOptions, type NetworkStatus, type Primitive, type SaveBase64DataParams, type ShowAdMobEvent, type ShowAdMobInterstitialAdEvent, type ShowAdMobInterstitialAdOptions, type ShowAdMobOptions, type ShowAdMobParams, type ShowAdMobRewardedAdEvent, type ShowAdMobRewardedAdOptions, Storage, type SubmitGameCenterLeaderBoardScoreResponse, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getTossAppVersion, getTossShareLink, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, processProductGrant, requestOneTimePurchase, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, startUpdateLocation, submitGameCenterLeaderBoardScore };
|
package/dist/index.d.ts
CHANGED
|
@@ -1411,16 +1411,16 @@ type GameCenterGameProfileResponse = {
|
|
|
1411
1411
|
*/
|
|
1412
1412
|
declare function getGameCenterGameProfile(): Promise<GameCenterGameProfileResponse | undefined>;
|
|
1413
1413
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
* @description 인앱결제 1건을 요청할 때 필요한 정보예요.
|
|
1419
|
-
* @property {string} productId - 주문할 상품의 ID예요.
|
|
1420
|
-
*/
|
|
1421
|
-
interface IapCreateOneTimePurchaseOrderOptions {
|
|
1414
|
+
type Sku = {
|
|
1415
|
+
/**
|
|
1416
|
+
* @deprecated `productId`는 더 이상 사용하지 않아요. 대신 `sku`를 사용해요.
|
|
1417
|
+
*/
|
|
1422
1418
|
productId: string;
|
|
1423
|
-
|
|
1419
|
+
sku?: string;
|
|
1420
|
+
} | {
|
|
1421
|
+
productId?: never;
|
|
1422
|
+
sku: string;
|
|
1423
|
+
};
|
|
1424
1424
|
/**
|
|
1425
1425
|
* @public
|
|
1426
1426
|
* @category 인앱결제
|
|
@@ -1443,15 +1443,54 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1443
1443
|
fraction: number;
|
|
1444
1444
|
miniAppIconUrl: string | null;
|
|
1445
1445
|
}
|
|
1446
|
+
interface SuccessEvent {
|
|
1447
|
+
type: 'success';
|
|
1448
|
+
data: IapCreateOneTimePurchaseOrderResult;
|
|
1449
|
+
}
|
|
1450
|
+
interface PurchasedEvent {
|
|
1451
|
+
type: 'purchased';
|
|
1452
|
+
data: {
|
|
1453
|
+
orderId: string;
|
|
1454
|
+
};
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* @public
|
|
1458
|
+
* @category 인앱결제
|
|
1459
|
+
* @name IapCreateOneTimePurchaseOrderOptions
|
|
1460
|
+
* @property {Sku} options - 결제할 상품의 정보예요.
|
|
1461
|
+
* @property {string} options.sku - 주문할 상품의 고유 ID예요.
|
|
1462
|
+
* @property {(params: { orderId: string }) => boolean | Promise<boolean>} processProductGrant - 주문이 만들어진 뒤 실제로 상품을 지급할 때 호출해요. `orderId`를 받아서 지급 성공 여부를 `true` 또는 `Promise<true>`로 반환해요. 지급에 실패하면 `false`를 반환해요.
|
|
1463
|
+
* @property {(event: SuccessEvent) => void | Promise<void>} onEvent - 결제가 성공했을 때 호출해요. `event.type`이 `'success'`이고, `event.data`에 `IapCreateOneTimePurchaseOrderResult`가 들어 있어요.
|
|
1464
|
+
* @property {(error: unknown) => void | Promise<void>} onError - 결제 과정에서 에러가 발생했을 때 호출해요. 에러 객체를 받아서 로깅하거나 복구 절차를 실행할 수 있어요.
|
|
1465
|
+
*/
|
|
1466
|
+
interface IapCreateOneTimePurchaseOrderOptions {
|
|
1467
|
+
options: Sku & {
|
|
1468
|
+
processProductGrant: (params: {
|
|
1469
|
+
orderId: string;
|
|
1470
|
+
}) => boolean | Promise<boolean>;
|
|
1471
|
+
};
|
|
1472
|
+
onEvent: (event: SuccessEvent) => void | Promise<void>;
|
|
1473
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
1474
|
+
}
|
|
1475
|
+
interface IapRequestOneTimePurchaseOptions {
|
|
1476
|
+
options: Sku;
|
|
1477
|
+
onEvent: (event: PurchasedEvent | SuccessEvent) => void | Promise<void>;
|
|
1478
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
1479
|
+
}
|
|
1480
|
+
declare function iapCreateOneTimePurchaseOrder(params: Sku): Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1481
|
+
declare function processProductGrant(params: {
|
|
1482
|
+
orderId: string;
|
|
1483
|
+
isProductGranted: boolean;
|
|
1484
|
+
}): Promise<void>;
|
|
1485
|
+
declare function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions): () => void;
|
|
1446
1486
|
/**
|
|
1447
1487
|
* @public
|
|
1448
1488
|
* @category 인앱결제
|
|
1449
|
-
* @name
|
|
1489
|
+
* @name createOneTimePurchaseOrder
|
|
1450
1490
|
* @description
|
|
1451
1491
|
* 특정 인앱결제 주문서 페이지로 이동해요. 사용자가 상품 구매 버튼을 누르는 상황 등에 사용할 수 있어요. 사용자의 결제는 이동한 페이지에서 진행돼요. 만약 결제 중에 에러가 발생하면 에러 유형에 따라 에러 페이지로 이동해요.
|
|
1452
1492
|
* @param {IapCreateOneTimePurchaseOrderOptions} params - 인앱결제를 생성할 때 필요한 정보예요.
|
|
1453
|
-
* @
|
|
1454
|
-
* @returns {Promise<IapCreateOneTimePurchaseOrderResult | undefined>} 결제에 성공하면 결제 결과 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 인앱결제를 실행할 수 없어서 `undefined`를 반환해요.
|
|
1493
|
+
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 인앱결제 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
1455
1494
|
*
|
|
1456
1495
|
* @throw {code: "INVALID_PRODUCT_ID"} - 유효하지 않은 상품 ID이거나, 해당 상품이 존재하지 않을 때 발생해요.
|
|
1457
1496
|
* @throw {code: "PAYMENT_PENDING"} - 사용자가 요청한 결제가 아직 승인을 기다리고 있을 때 발생해요.
|
|
@@ -1463,6 +1502,7 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1463
1502
|
* @throw {code: "INTERNAL_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
1464
1503
|
* @throw {code: "KOREAN_ACCOUNT_ONLY"} - iOS 환경에서 사용자의 계정이 한국 계정이 아닐 때 발생해요.
|
|
1465
1504
|
* @throw {code: "USER_CANCELED"} - 사용자가 결제를 완료하지 않고 주문서 페이지를 이탈했을 때 발생해요.
|
|
1505
|
+
* @throw {code: "PRODUCT_NOT_GRANTED_BY_PARTNER"} - 파트너사의 상품 지급이 실패했을 때 발생해요.
|
|
1466
1506
|
*
|
|
1467
1507
|
* @example
|
|
1468
1508
|
* ### 특정 인앱결제 주문서 페이지로 이동하기
|
|
@@ -1470,28 +1510,39 @@ interface IapCreateOneTimePurchaseOrderResult {
|
|
|
1470
1510
|
* ```tsx
|
|
1471
1511
|
* import { IAP } from "@apps-in-toss/web-framework";
|
|
1472
1512
|
* import { Button } from "@toss-design-system/react-native";
|
|
1513
|
+
* import { useCallback } from "react";
|
|
1473
1514
|
*
|
|
1474
1515
|
* interface Props {
|
|
1475
|
-
*
|
|
1516
|
+
* sku: string;
|
|
1476
1517
|
* }
|
|
1477
1518
|
*
|
|
1478
|
-
* function IapCreateOneTimePurchaseOrderButton({
|
|
1479
|
-
*
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
*
|
|
1484
|
-
*
|
|
1485
|
-
*
|
|
1486
|
-
*
|
|
1487
|
-
*
|
|
1488
|
-
*
|
|
1519
|
+
* function IapCreateOneTimePurchaseOrderButton({ sku }: Props) {
|
|
1520
|
+
* const handleClick = useCallback(async () => {
|
|
1521
|
+
*
|
|
1522
|
+
* const cleanup = await IAP.createOneTimePurchaseOrder({
|
|
1523
|
+
* options: {
|
|
1524
|
+
* sku,
|
|
1525
|
+
* processProductGrant: ({ orderId }) => {
|
|
1526
|
+
* // 상품 지급 로직 작성
|
|
1527
|
+
* return true; // 상품 지급 여부
|
|
1528
|
+
* }
|
|
1529
|
+
* },
|
|
1530
|
+
* onEvent: (event) => {
|
|
1531
|
+
* console.log(event);
|
|
1532
|
+
* },
|
|
1533
|
+
* onError: (error) => {
|
|
1534
|
+
* console.error(error);
|
|
1535
|
+
* },
|
|
1536
|
+
* });
|
|
1537
|
+
*
|
|
1538
|
+
* return cleanup;
|
|
1539
|
+
* }, []);
|
|
1489
1540
|
*
|
|
1490
1541
|
* return <Button onClick={handleClick}>구매하기</Button>;
|
|
1491
1542
|
* }
|
|
1492
1543
|
* ```
|
|
1493
1544
|
*/
|
|
1494
|
-
declare function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions):
|
|
1545
|
+
declare function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions): () => void;
|
|
1495
1546
|
/**
|
|
1496
1547
|
* @public
|
|
1497
1548
|
* @category 인앱결제
|
|
@@ -1513,7 +1564,7 @@ interface IapProductListItem {
|
|
|
1513
1564
|
/**
|
|
1514
1565
|
* @public
|
|
1515
1566
|
* @category 인앱결제
|
|
1516
|
-
* @name
|
|
1567
|
+
* @name getProductItemList
|
|
1517
1568
|
* @description 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 상품 목록 화면에 진입할 때 호출해요.
|
|
1518
1569
|
* @returns {Promise<{ products: IapProductListItem[] } | undefined>} 상품 목록을 포함한 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 `undefined`를 반환해요.
|
|
1519
1570
|
*
|
|
@@ -1761,10 +1812,24 @@ interface Spec extends TurboModule {
|
|
|
1761
1812
|
}) => Promise<void>;
|
|
1762
1813
|
saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
|
|
1763
1814
|
/** IAP */
|
|
1764
|
-
iapCreateOneTimePurchaseOrder: (params: IapCreateOneTimePurchaseOrderOptions) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1765
1815
|
iapGetProductItemList: (arg: CompatiblePlaceholderArgument) => Promise<{
|
|
1766
1816
|
products: IapProductListItem[];
|
|
1767
1817
|
}>;
|
|
1818
|
+
/** @deprecated `requestOneTimePurchase`를 사용해주세요. */
|
|
1819
|
+
iapCreateOneTimePurchaseOrder: (params: {
|
|
1820
|
+
productId: string;
|
|
1821
|
+
}) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
1822
|
+
requestOneTimePurchase: (params: {
|
|
1823
|
+
sku: string;
|
|
1824
|
+
}, fallbacks: {
|
|
1825
|
+
onPurchased: (params: {
|
|
1826
|
+
orderId: string;
|
|
1827
|
+
}) => void;
|
|
1828
|
+
}) => () => void;
|
|
1829
|
+
processProductGrant: (params: {
|
|
1830
|
+
orderId: string;
|
|
1831
|
+
isProductGranted: boolean;
|
|
1832
|
+
}) => Promise<void>;
|
|
1768
1833
|
getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse>;
|
|
1769
1834
|
submitGameCenterLeaderBoardScore: (params: {
|
|
1770
1835
|
score: string;
|
|
@@ -3183,4 +3248,4 @@ declare const INTERNAL__module: {
|
|
|
3183
3248
|
tossCoreEventLog: typeof tossCoreEventLog;
|
|
3184
3249
|
};
|
|
3185
3250
|
|
|
3186
|
-
export { AppsInTossModule, BedrockCoreModule, BedrockModule, type CheckoutPaymentOptions, type CheckoutPaymentResult, type ContactsViralParams, type EventLogParams, type GameCenterGameProfileResponse, GoogleAdMob, type HapticFeedbackType, IAP, AppsInTossModuleInstance as INTERNAL__AppsInTossModule, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapProductListItem, type LoadAdMobEvent, type LoadAdMobInterstitialAdEvent, type LoadAdMobInterstitialAdOptions, type LoadAdMobOptions, type LoadAdMobParams, type LoadAdMobRewardedAdEvent, type LoadAdMobRewardedAdOptions, type NetworkStatus, type Primitive, type SaveBase64DataParams, type ShowAdMobEvent, type ShowAdMobInterstitialAdEvent, type ShowAdMobInterstitialAdOptions, type ShowAdMobOptions, type ShowAdMobParams, type ShowAdMobRewardedAdEvent, type ShowAdMobRewardedAdOptions, Storage, type SubmitGameCenterLeaderBoardScoreResponse, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getTossAppVersion, getTossShareLink, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, startUpdateLocation, submitGameCenterLeaderBoardScore };
|
|
3251
|
+
export { AppsInTossModule, BedrockCoreModule, BedrockModule, type CheckoutPaymentOptions, type CheckoutPaymentResult, type ContactsViralParams, type EventLogParams, type GameCenterGameProfileResponse, GoogleAdMob, type HapticFeedbackType, IAP, AppsInTossModuleInstance as INTERNAL__AppsInTossModule, INTERNAL__appBridgeHandler, INTERNAL__module, type IapCreateOneTimePurchaseOrderOptions, type IapCreateOneTimePurchaseOrderResult, type IapProductListItem, type LoadAdMobEvent, type LoadAdMobInterstitialAdEvent, type LoadAdMobInterstitialAdOptions, type LoadAdMobOptions, type LoadAdMobParams, type LoadAdMobRewardedAdEvent, type LoadAdMobRewardedAdOptions, type NetworkStatus, type Primitive, type SaveBase64DataParams, type ShowAdMobEvent, type ShowAdMobInterstitialAdEvent, type ShowAdMobInterstitialAdOptions, type ShowAdMobOptions, type ShowAdMobParams, type ShowAdMobRewardedAdEvent, type ShowAdMobRewardedAdOptions, Storage, type SubmitGameCenterLeaderBoardScoreResponse, TossPay, type UpdateLocationEventEmitter, appLogin, appsInTossEvent, closeView, contactsViral, eventLog, fetchAlbumPhotos, fetchContacts, generateHapticFeedback, getClipboardText, getCurrentLocation, getDeviceId, getGameCenterGameProfile, getLocale, getNetworkStatus, getOperationalEnvironment, getPlatformOS, getSchemeUri, getTossAppVersion, getTossShareLink, iapCreateOneTimePurchaseOrder, isMinVersionSupported, onVisibilityChangedByTransparentServiceWeb, openCamera, openGameCenterLeaderboard, openURL, processProductGrant, requestOneTimePurchase, saveBase64Data, setClipboardText, setDeviceOrientation, setIosSwipeGestureEnabled, setScreenAwakeMode, setSecureScreen, share, startUpdateLocation, submitGameCenterLeaderBoardScore };
|
package/dist/index.js
CHANGED
|
@@ -640,15 +640,80 @@ async function getTossShareLink(path) {
|
|
|
640
640
|
}
|
|
641
641
|
|
|
642
642
|
// src/AppsInTossModule/native-modules/iap.ts
|
|
643
|
-
|
|
644
|
-
|
|
643
|
+
import { noop as noop3 } from "es-toolkit";
|
|
644
|
+
function iapCreateOneTimePurchaseOrder(params) {
|
|
645
|
+
const sku = params.sku ?? params.productId;
|
|
646
|
+
return AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku });
|
|
647
|
+
}
|
|
648
|
+
function processProductGrant(params) {
|
|
649
|
+
return AppsInTossModule.processProductGrant({ orderId: params.orderId, isProductGranted: params.isProductGranted });
|
|
650
|
+
}
|
|
651
|
+
function requestOneTimePurchase(params) {
|
|
652
|
+
const { options, onEvent, onError } = params;
|
|
653
|
+
const sku = options.sku ?? options.productId;
|
|
654
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
655
|
+
"requestOneTimePurchase",
|
|
656
|
+
{ sku },
|
|
657
|
+
{
|
|
658
|
+
onPurchased: (params2) => {
|
|
659
|
+
onEvent({ type: "purchased", data: params2 });
|
|
660
|
+
},
|
|
661
|
+
onSuccess: (result) => {
|
|
662
|
+
onEvent({ type: "success", data: result });
|
|
663
|
+
},
|
|
664
|
+
onError: (error) => {
|
|
665
|
+
onError(error);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
);
|
|
669
|
+
return unregisterCallbacks;
|
|
670
|
+
}
|
|
671
|
+
function createOneTimePurchaseOrder(params) {
|
|
672
|
+
const isIAPSupported = isMinVersionSupported({
|
|
645
673
|
android: "5.219.0",
|
|
646
674
|
ios: "5.219.0"
|
|
647
675
|
});
|
|
648
|
-
if (!
|
|
649
|
-
return;
|
|
676
|
+
if (!isIAPSupported) {
|
|
677
|
+
return noop3;
|
|
650
678
|
}
|
|
651
|
-
|
|
679
|
+
const isProcessProductGrantSupported = isMinVersionSupported({
|
|
680
|
+
android: "5.230.0",
|
|
681
|
+
ios: "5.230.0"
|
|
682
|
+
});
|
|
683
|
+
const { options, onEvent, onError } = params;
|
|
684
|
+
const sku = options.sku ?? options.productId;
|
|
685
|
+
if (!isProcessProductGrantSupported) {
|
|
686
|
+
const v1 = () => {
|
|
687
|
+
AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku }).then((response) => {
|
|
688
|
+
Promise.resolve(options.processProductGrant({ orderId: response.orderId })).then(() => {
|
|
689
|
+
onEvent({ type: "success", data: response });
|
|
690
|
+
}).catch((error) => {
|
|
691
|
+
onError(error);
|
|
692
|
+
});
|
|
693
|
+
}).catch((error) => {
|
|
694
|
+
onError(error);
|
|
695
|
+
});
|
|
696
|
+
return noop3;
|
|
697
|
+
};
|
|
698
|
+
return v1();
|
|
699
|
+
}
|
|
700
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
701
|
+
"requestOneTimePurchase",
|
|
702
|
+
{ sku },
|
|
703
|
+
{
|
|
704
|
+
onPurchased: async (params2) => {
|
|
705
|
+
const isProductGranted = await options.processProductGrant(params2);
|
|
706
|
+
await AppsInTossModule.processProductGrant({ orderId: params2.orderId, isProductGranted });
|
|
707
|
+
},
|
|
708
|
+
onSuccess: (result) => {
|
|
709
|
+
onEvent({ type: "success", data: result });
|
|
710
|
+
},
|
|
711
|
+
onError: (error) => {
|
|
712
|
+
onError(error);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
);
|
|
716
|
+
return unregisterCallbacks;
|
|
652
717
|
}
|
|
653
718
|
async function getProductItemList() {
|
|
654
719
|
const isSupported = isMinVersionSupported({
|
|
@@ -935,11 +1000,14 @@ export {
|
|
|
935
1000
|
getSchemeUri,
|
|
936
1001
|
getTossAppVersion,
|
|
937
1002
|
getTossShareLink,
|
|
1003
|
+
iapCreateOneTimePurchaseOrder,
|
|
938
1004
|
isMinVersionSupported,
|
|
939
1005
|
onVisibilityChangedByTransparentServiceWeb,
|
|
940
1006
|
openCamera,
|
|
941
1007
|
openGameCenterLeaderboard,
|
|
942
1008
|
openURL2 as openURL,
|
|
1009
|
+
processProductGrant,
|
|
1010
|
+
requestOneTimePurchase,
|
|
943
1011
|
saveBase64Data,
|
|
944
1012
|
setClipboardText,
|
|
945
1013
|
setDeviceOrientation,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apps-in-toss/native-modules",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-dev.
|
|
4
|
+
"version": "0.0.0-dev.1758275837494",
|
|
5
5
|
"description": "Native Modules for Apps In Toss",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"prepack": "yarn build",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"vitest": "^3.2.4"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@apps-in-toss/types": "^0.0.0-dev.
|
|
46
|
+
"@apps-in-toss/types": "^0.0.0-dev.1758275837494",
|
|
47
47
|
"es-toolkit": "^1.39.3"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"publishConfig": {
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "b68a923a00c75af3ca66633e450370f20f025a34"
|
|
58
58
|
}
|
|
@@ -15,11 +15,7 @@ import type {
|
|
|
15
15
|
import { TurboModuleRegistry, type TurboModule as __TurboModule } from 'react-native';
|
|
16
16
|
import type { CheckoutPaymentOptions, CheckoutPaymentResult } from './checkoutPayment';
|
|
17
17
|
import type { GameCenterGameProfileResponse } from './getGameCenterGameProfile';
|
|
18
|
-
import
|
|
19
|
-
IapCreateOneTimePurchaseOrderOptions,
|
|
20
|
-
IapCreateOneTimePurchaseOrderResult,
|
|
21
|
-
IapProductListItem,
|
|
22
|
-
} from './iap';
|
|
18
|
+
import { IapCreateOneTimePurchaseOrderResult, IapProductListItem } from './iap';
|
|
23
19
|
import type { SaveBase64DataParams } from './saveBase64Data';
|
|
24
20
|
import type { SubmitGameCenterLeaderBoardScoreResponse } from './submitGameCenterLeaderBoardScore';
|
|
25
21
|
import type { ContactsViralParams } from '../native-event-emitter/contactsViral';
|
|
@@ -68,10 +64,15 @@ interface Spec extends __TurboModule {
|
|
|
68
64
|
saveBase64Data: (params: SaveBase64DataParams) => Promise<void>;
|
|
69
65
|
|
|
70
66
|
/** IAP */
|
|
71
|
-
iapCreateOneTimePurchaseOrder: (
|
|
72
|
-
params: IapCreateOneTimePurchaseOrderOptions
|
|
73
|
-
) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
74
67
|
iapGetProductItemList: (arg: CompatiblePlaceholderArgument) => Promise<{ products: IapProductListItem[] }>;
|
|
68
|
+
/** @deprecated `requestOneTimePurchase`를 사용해주세요. */
|
|
69
|
+
iapCreateOneTimePurchaseOrder: (params: { productId: string }) => Promise<IapCreateOneTimePurchaseOrderResult>;
|
|
70
|
+
requestOneTimePurchase: (
|
|
71
|
+
params: { sku: string },
|
|
72
|
+
fallbacks: { onPurchased: (params: { orderId: string }) => void }
|
|
73
|
+
) => () => void;
|
|
74
|
+
processProductGrant: (params: { orderId: string; isProductGranted: boolean }) => Promise<void>;
|
|
75
|
+
|
|
75
76
|
getGameCenterGameProfile: (params: CompatiblePlaceholderArgument) => Promise<GameCenterGameProfileResponse>;
|
|
76
77
|
submitGameCenterLeaderBoardScore: (params: { score: string }) => Promise<SubmitGameCenterLeaderBoardScoreResponse>;
|
|
77
78
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
import { noop } from 'es-toolkit';
|
|
1
2
|
import { AppsInTossModule } from './AppsInTossModule';
|
|
2
3
|
import { isMinVersionSupported } from './isMinVersionSupported';
|
|
4
|
+
import { INTERNAL__appBridgeHandler } from '../native-event-emitter/internal/appBridge';
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
type Sku =
|
|
7
|
+
| {
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated `productId`는 더 이상 사용하지 않아요. 대신 `sku`를 사용해요.
|
|
10
|
+
*/
|
|
11
|
+
productId: string;
|
|
12
|
+
sku?: string;
|
|
13
|
+
}
|
|
14
|
+
| {
|
|
15
|
+
productId?: never;
|
|
16
|
+
sku: string;
|
|
17
|
+
};
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
20
|
* @public
|
|
@@ -35,15 +39,78 @@ export interface IapCreateOneTimePurchaseOrderResult {
|
|
|
35
39
|
miniAppIconUrl: string | null;
|
|
36
40
|
}
|
|
37
41
|
|
|
42
|
+
interface SuccessEvent {
|
|
43
|
+
type: 'success';
|
|
44
|
+
data: IapCreateOneTimePurchaseOrderResult;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface PurchasedEvent {
|
|
48
|
+
type: 'purchased';
|
|
49
|
+
data: { orderId: string };
|
|
50
|
+
}
|
|
51
|
+
|
|
38
52
|
/**
|
|
39
53
|
* @public
|
|
40
54
|
* @category 인앱결제
|
|
41
|
-
* @name
|
|
55
|
+
* @name IapCreateOneTimePurchaseOrderOptions
|
|
56
|
+
* @property {Sku} options - 결제할 상품의 정보예요.
|
|
57
|
+
* @property {string} options.sku - 주문할 상품의 고유 ID예요.
|
|
58
|
+
* @property {(params: { orderId: string }) => boolean | Promise<boolean>} processProductGrant - 주문이 만들어진 뒤 실제로 상품을 지급할 때 호출해요. `orderId`를 받아서 지급 성공 여부를 `true` 또는 `Promise<true>`로 반환해요. 지급에 실패하면 `false`를 반환해요.
|
|
59
|
+
* @property {(event: SuccessEvent) => void | Promise<void>} onEvent - 결제가 성공했을 때 호출해요. `event.type`이 `'success'`이고, `event.data`에 `IapCreateOneTimePurchaseOrderResult`가 들어 있어요.
|
|
60
|
+
* @property {(error: unknown) => void | Promise<void>} onError - 결제 과정에서 에러가 발생했을 때 호출해요. 에러 객체를 받아서 로깅하거나 복구 절차를 실행할 수 있어요.
|
|
61
|
+
*/
|
|
62
|
+
export interface IapCreateOneTimePurchaseOrderOptions {
|
|
63
|
+
options: Sku & { processProductGrant: (params: { orderId: string }) => boolean | Promise<boolean> };
|
|
64
|
+
onEvent: (event: SuccessEvent) => void | Promise<void>;
|
|
65
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface IapRequestOneTimePurchaseOptions {
|
|
69
|
+
options: Sku;
|
|
70
|
+
onEvent: (event: PurchasedEvent | SuccessEvent) => void | Promise<void>;
|
|
71
|
+
onError: (error: unknown) => void | Promise<void>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function iapCreateOneTimePurchaseOrder(params: Sku) {
|
|
75
|
+
const sku = (params.sku ?? params.productId) as string;
|
|
76
|
+
return AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function processProductGrant(params: { orderId: string; isProductGranted: boolean }) {
|
|
80
|
+
return AppsInTossModule.processProductGrant({ orderId: params.orderId, isProductGranted: params.isProductGranted });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function requestOneTimePurchase(params: IapRequestOneTimePurchaseOptions) {
|
|
84
|
+
const { options, onEvent, onError } = params;
|
|
85
|
+
const sku = (options.sku ?? options.productId) as string;
|
|
86
|
+
|
|
87
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
88
|
+
'requestOneTimePurchase',
|
|
89
|
+
{ sku },
|
|
90
|
+
{
|
|
91
|
+
onPurchased: (params: { orderId: string }) => {
|
|
92
|
+
onEvent({ type: 'purchased', data: params });
|
|
93
|
+
},
|
|
94
|
+
onSuccess: (result: IapCreateOneTimePurchaseOrderResult) => {
|
|
95
|
+
onEvent({ type: 'success', data: result });
|
|
96
|
+
},
|
|
97
|
+
onError: (error: any) => {
|
|
98
|
+
onError(error);
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return unregisterCallbacks;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @public
|
|
108
|
+
* @category 인앱결제
|
|
109
|
+
* @name createOneTimePurchaseOrder
|
|
42
110
|
* @description
|
|
43
111
|
* 특정 인앱결제 주문서 페이지로 이동해요. 사용자가 상품 구매 버튼을 누르는 상황 등에 사용할 수 있어요. 사용자의 결제는 이동한 페이지에서 진행돼요. 만약 결제 중에 에러가 발생하면 에러 유형에 따라 에러 페이지로 이동해요.
|
|
44
112
|
* @param {IapCreateOneTimePurchaseOrderOptions} params - 인앱결제를 생성할 때 필요한 정보예요.
|
|
45
|
-
* @
|
|
46
|
-
* @returns {Promise<IapCreateOneTimePurchaseOrderResult | undefined>} 결제에 성공하면 결제 결과 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 인앱결제를 실행할 수 없어서 `undefined`를 반환해요.
|
|
113
|
+
* @returns {() => void} 앱브릿지 cleanup 함수를 반환해요. 인앱결제 기능이 끝나면 반드시 이 함수를 호출해서 리소스를 해제해야 해요.
|
|
47
114
|
*
|
|
48
115
|
* @throw {code: "INVALID_PRODUCT_ID"} - 유효하지 않은 상품 ID이거나, 해당 상품이 존재하지 않을 때 발생해요.
|
|
49
116
|
* @throw {code: "PAYMENT_PENDING"} - 사용자가 요청한 결제가 아직 승인을 기다리고 있을 때 발생해요.
|
|
@@ -55,6 +122,7 @@ export interface IapCreateOneTimePurchaseOrderResult {
|
|
|
55
122
|
* @throw {code: "INTERNAL_ERROR"} - 서버 내부 문제로 요청을 처리할 수 없을 때 발생해요.
|
|
56
123
|
* @throw {code: "KOREAN_ACCOUNT_ONLY"} - iOS 환경에서 사용자의 계정이 한국 계정이 아닐 때 발생해요.
|
|
57
124
|
* @throw {code: "USER_CANCELED"} - 사용자가 결제를 완료하지 않고 주문서 페이지를 이탈했을 때 발생해요.
|
|
125
|
+
* @throw {code: "PRODUCT_NOT_GRANTED_BY_PARTNER"} - 파트너사의 상품 지급이 실패했을 때 발생해요.
|
|
58
126
|
*
|
|
59
127
|
* @example
|
|
60
128
|
* ### 특정 인앱결제 주문서 페이지로 이동하기
|
|
@@ -62,38 +130,96 @@ export interface IapCreateOneTimePurchaseOrderResult {
|
|
|
62
130
|
* ```tsx
|
|
63
131
|
* import { IAP } from "@apps-in-toss/web-framework";
|
|
64
132
|
* import { Button } from "@toss-design-system/react-native";
|
|
133
|
+
* import { useCallback } from "react";
|
|
65
134
|
*
|
|
66
135
|
* interface Props {
|
|
67
|
-
*
|
|
136
|
+
* sku: string;
|
|
68
137
|
* }
|
|
69
138
|
*
|
|
70
|
-
* function IapCreateOneTimePurchaseOrderButton({
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
139
|
+
* function IapCreateOneTimePurchaseOrderButton({ sku }: Props) {
|
|
140
|
+
* const handleClick = useCallback(async () => {
|
|
141
|
+
*
|
|
142
|
+
* const cleanup = await IAP.createOneTimePurchaseOrder({
|
|
143
|
+
* options: {
|
|
144
|
+
* sku,
|
|
145
|
+
* processProductGrant: ({ orderId }) => {
|
|
146
|
+
* // 상품 지급 로직 작성
|
|
147
|
+
* return true; // 상품 지급 여부
|
|
148
|
+
* }
|
|
149
|
+
* },
|
|
150
|
+
* onEvent: (event) => {
|
|
151
|
+
* console.log(event);
|
|
152
|
+
* },
|
|
153
|
+
* onError: (error) => {
|
|
154
|
+
* console.error(error);
|
|
155
|
+
* },
|
|
156
|
+
* });
|
|
157
|
+
*
|
|
158
|
+
* return cleanup;
|
|
159
|
+
* }, []);
|
|
81
160
|
*
|
|
82
161
|
* return <Button onClick={handleClick}>구매하기</Button>;
|
|
83
162
|
* }
|
|
84
163
|
* ```
|
|
85
164
|
*/
|
|
86
|
-
|
|
87
|
-
const
|
|
165
|
+
function createOneTimePurchaseOrder(params: IapCreateOneTimePurchaseOrderOptions) {
|
|
166
|
+
const isIAPSupported = isMinVersionSupported({
|
|
88
167
|
android: '5.219.0',
|
|
89
168
|
ios: '5.219.0',
|
|
90
169
|
});
|
|
91
170
|
|
|
92
|
-
if (!
|
|
93
|
-
return;
|
|
171
|
+
if (!isIAPSupported) {
|
|
172
|
+
return noop;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const isProcessProductGrantSupported = isMinVersionSupported({
|
|
176
|
+
android: '5.230.0',
|
|
177
|
+
ios: '5.230.0',
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const { options, onEvent, onError } = params;
|
|
181
|
+
const sku = (options.sku ?? options.productId) as string;
|
|
182
|
+
|
|
183
|
+
if (!isProcessProductGrantSupported) {
|
|
184
|
+
const v1 = () => {
|
|
185
|
+
AppsInTossModule.iapCreateOneTimePurchaseOrder({ productId: sku })
|
|
186
|
+
.then((response: IapCreateOneTimePurchaseOrderResult) => {
|
|
187
|
+
Promise.resolve(options.processProductGrant({ orderId: response.orderId }))
|
|
188
|
+
.then(() => {
|
|
189
|
+
onEvent({ type: 'success', data: response });
|
|
190
|
+
})
|
|
191
|
+
.catch((error: unknown) => {
|
|
192
|
+
onError(error);
|
|
193
|
+
});
|
|
194
|
+
})
|
|
195
|
+
.catch((error: unknown) => {
|
|
196
|
+
onError(error);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return noop;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return v1();
|
|
94
203
|
}
|
|
95
204
|
|
|
96
|
-
|
|
205
|
+
const unregisterCallbacks = INTERNAL__appBridgeHandler.invokeAppBridgeMethod(
|
|
206
|
+
'requestOneTimePurchase',
|
|
207
|
+
{ sku },
|
|
208
|
+
{
|
|
209
|
+
onPurchased: async (params: { orderId: string }) => {
|
|
210
|
+
const isProductGranted = await options.processProductGrant(params);
|
|
211
|
+
await AppsInTossModule.processProductGrant({ orderId: params.orderId, isProductGranted });
|
|
212
|
+
},
|
|
213
|
+
onSuccess: (result: IapCreateOneTimePurchaseOrderResult) => {
|
|
214
|
+
onEvent({ type: 'success', data: result });
|
|
215
|
+
},
|
|
216
|
+
onError: (error: unknown) => {
|
|
217
|
+
onError(error);
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
);
|
|
221
|
+
|
|
222
|
+
return unregisterCallbacks;
|
|
97
223
|
}
|
|
98
224
|
|
|
99
225
|
/**
|
|
@@ -118,7 +244,7 @@ export interface IapProductListItem {
|
|
|
118
244
|
/**
|
|
119
245
|
* @public
|
|
120
246
|
* @category 인앱결제
|
|
121
|
-
* @name
|
|
247
|
+
* @name getProductItemList
|
|
122
248
|
* @description 인앱결제로 구매할 수 있는 상품 목록을 가져와요. 상품 목록 화면에 진입할 때 호출해요.
|
|
123
249
|
* @returns {Promise<{ products: IapProductListItem[] } | undefined>} 상품 목록을 포함한 객체를 반환해요. 앱 버전이 최소 지원 버전(안드로이드 5.219.0, iOS 5.219.0)보다 낮으면 `undefined`를 반환해요.
|
|
124
250
|
*
|