IAP.createOneTimePurchaseOrder
특정 SKU의 단건 인앱결제 주문서 페이지로 이동합니다. 사용자가 상품 구매 버튼을 누르는 상황에서 호출하며, 실제 결제는 이동한 페이지에서 처리됩니다. 결제 중 오류가 발생하면 오류 유형에 따라 에러 페이지로 이동합니다.
시그니처
createOneTimePurchaseOrder는 IAP 네임스페이스 객체의 멤버로 노출됩니다.
import { IAP } from '@apps-in-toss/web-framework';
declare const IAP: {
createOneTimePurchaseOrder(params: {
options: {
sku: string;
processProductGrant: (params: { orderId: string }) => boolean | Promise<boolean>;
};
onEvent: (event: { type: 'success'; data: IapCreateOneTimePurchaseOrderResult }) => void | Promise<void>;
onError: (error: unknown) => void | Promise<void>;
}): () => void;
// ...overview 참고
};
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
params.options.sku | string | ✓ | 주문할 상품의 고유 ID. |
params.options.processProductGrant | (params: { orderId: string }) => boolean | Promise<boolean> | ✓ | 주문이 생성된 뒤 서버에서 상품을 지급할 때 호출되는 콜백. 지급 성공 시 true, 실패 시 false를 반환합니다. |
params.onEvent | (event: SuccessEvent) => void | Promise<void> | ✓ | 결제 성공 시 호출되는 이벤트 핸들러. event.data에 IapCreateOneTimePurchaseOrderResult가 담깁니다. |
params.onError | (error: unknown) => void | Promise<void> | ✓ | 결제 중 에러 발생 시 호출되는 핸들러. |
IapCreateOneTimePurchaseOrderResult
| 필드 | 타입 | 설명 |
|---|---|---|
orderId | string | 결제 주문 ID. |
displayName | string | 화면에 표시할 상품 이름. |
displayAmount | string | 통화 단위 포함 가격 문자열 (예: 1,000원). |
amount | number | 순수 숫자 가격 (예: 1000). |
currency | string | ISO 4217 통화 코드 (예: KRW). |
fraction | number | 소수점 표시 자릿수. |
miniAppIconUrl | string | null | 미니앱 아이콘 URL. 미설정 시 null. |
반환값
() => void— 앱브릿지 cleanup 함수. 결제 흐름이 끝나면 반드시 호출해 리소스를 해제해야 합니다.
에러 코드
| 코드 | 설명 |
|---|---|
INVALID_PRODUCT_ID | 유효하지 않은 상품 ID이거나 상품이 존재하지 않습니다. |
PAYMENT_PENDING | 해당 결제가 이미 승인 대기 중입니다. |
NETWORK_ERROR | 서버 내부 문제로 요청을 처리할 수 없습니다. |
INVALID_USER_ENVIRONMENT | 특정 기기·계정·설정 환경에서 구매할 수 없는 상품입니다. |
ITEM_ALREADY_OWNED | 이미 구매한 상품을 다시 구매하려 했습니다. |
APP_MARKET_VERIFICATION_FAILED | 결제는 완료됐으나 앱스토어 사용자 정보 검증에 실패했습니다. |
TOSS_SERVER_VERIFICATION_FAILED | 결제는 완료됐으나 서버 전송에 실패해 결제 정보를 저장할 수 없습니다. |
INTERNAL_ERROR | 서버 내부 오류입니다. |
KOREAN_ACCOUNT_ONLY | iOS에서 한국 계정이 아닐 때 발생합니다. |
USER_CANCELED | 사용자가 주문서 페이지를 이탈했습니다. |
PRODUCT_NOT_GRANTED_BY_PARTNER | 파트너사 상품 지급에 실패했습니다. |
권한
권한이 필요하지 않습니다 — IAP 네임스페이스는 별도의 PermissionName에 바인딩되지 않습니다.
예제
최소 예제
import { IAP } from '@apps-in-toss/web-framework';
const cleanup = IAP.createOneTimePurchaseOrder({
options: {
sku: 'item_coin_100',
processProductGrant: async ({ orderId }) => {
// 서버에서 상품 지급 후 true 반환
return true;
},
},
onEvent: (event) => {
console.log('결제 완료', event.data);
cleanup();
},
onError: (error) => {
console.error('결제 오류', error);
cleanup();
},
});
실전 예제 — React 컴포넌트
import { IAP } from '@apps-in-toss/web-framework';
import { useCallback, useRef } from 'react';
interface Props {
sku: string;
}
function PurchaseButton({ sku }: Props) {
const cleanupRef = useRef<(() => void) | null>(null);
const handleClick = useCallback(() => {
cleanupRef.current = IAP.createOneTimePurchaseOrder({
options: {
sku,
processProductGrant: async ({ orderId }) => {
try {
await fetch('/api/grant', {
method: 'POST',
body: JSON.stringify({ orderId }),
headers: { 'Content-Type': 'application/json' },
});
return true;
} catch {
return false;
}
},
},
onEvent: (event) => {
console.log('구매 완료', event.data);
cleanupRef.current?.();
},
onError: (error) => {
console.error(error);
cleanupRef.current?.();
},
});
}, [sku]);
return (
<button type="button" onClick={handleClick}>
구매하기
</button>
);
}
직접 실행해 보기
sdk-example의 IAP 페이지에서 단건 구매 흐름을 실행해 볼 수 있습니다.
sdk-example에서 실행해 보기관련 API
IAP.createSubscriptionPurchaseOrder— 구독 구매 주문서로 이동합니다.IAP.getProductItemList— 구매 전 상품 목록을 조회합니다.IAP.completeProductGrant— 서버 지급 완료 신호를 전송합니다.IAP.getPendingOrders— 대기 중인 주문을 조회합니다.
관련 가이드
- Guides — IAP 결제 흐름 —
processProductGrant/completeProductGrant시퀀스·서버 fulfillment·복구 패턴을 한 곳에 정리한 가이드.
외부 참조
@apps-in-toss/web-framework— 상위 SDK 패키지. 실제 export는 내부적으로@apps-in-toss/web-bridge에서 가져옵니다.