requestTossPayPaysBilling
토스페이 정기결제 인증창을 띄워 사용자의 동의를 받고 billing key를 발급합니다. 이 함수는 정기결제 등록 인증만 처리하며, 실제 결제 청구는 인증 성공 후 서버에서 별도로 진행해야 합니다.
iap 네임스페이스의 checkoutPayment(단건 결제 인증)와는 다른 흐름입니다 — requestTossPayPaysBilling은 이후 서버 측에서 반복 청구할 수 있는 billing key를 발급받는 것이 목적입니다.
isSupported() 정적 메서드로 현재 환경에서 해당 기능이 지원되는지 먼저 확인할 수 있습니다.
시그니처
import { requestTossPayPaysBilling } from '@apps-in-toss/web-framework';
declare function requestTossPayPaysBilling(options: {
params: { wrappedToken: string };
}): Promise<{ success: boolean; reason?: string } | undefined>;
declare namespace requestTossPayPaysBilling {
function isSupported(): boolean;
}
파라미터
| 이름 | 타입 | 필수 | 설명 |
|---|---|---|---|
options.params.wrappedToken | string | ✓ | 서버에서 발급한 래핑된 토큰. 토스페이 정기결제 인증창에 전달되어 billing 컨텍스트를 식별합니다. |
반환값
Promise<{ success: boolean; reason?: string } | undefined>— 인증창에서 사용자 동의가 완료되면 resolve됩니다. 기능을 지원하지 않는 환경에서는undefined를 반환할 수 있습니다.success: true— 인증이 성공했습니다. 서버 측에서 billing key를 저장하고 이후 정기결제를 실행하세요.success: false+reason— 인증이 실패했습니다.reason을 사용자에게 표시하거나 로깅하세요.
인증 ≠ 결제 완료
success: true는 토스페이 정기결제 인증창에서 사용자 동의가 통과하고 billing key가 발급됐다는 의미입니다. 실제 결제 청구(서버 측 정기결제 실행)는 별도 API 호출로 마무리해야 합니다. 인증 성공만으로 결제가 이루어졌다고 가정하지 마세요.
권한
권한이 필요하지 않습니다. requestTossPayPaysBilling은 별도의 PermissionName에 바인딩되지 않습니다.
예제
최소 예제
import { requestTossPayPaysBilling } from '@apps-in-toss/web-framework';
async function registerBilling(wrappedToken: string) {
if (!requestTossPayPaysBilling.isSupported()) {
console.warn('정기결제 기능이 지원되지 않는 환경입니다.');
return;
}
const result = await requestTossPayPaysBilling({ params: { wrappedToken } });
if (!result) return;
if (result.success) {
// 서버 측 billing key 저장 및 정기결제 등록 완료 처리
await fetch('/api/billing/complete', { method: 'POST' });
} else {
console.warn('정기결제 인증 실패:', result.reason);
}
}
실전 예제 — 정기결제 등록 버튼
import { requestTossPayPaysBilling } from '@apps-in-toss/web-framework';
import { useCallback, useState } from 'react';
export function BillingRegisterButton({ planId }: { planId: string }) {
const [status, setStatus] = useState<'idle' | 'pending' | 'success' | 'error'>('idle');
const [message, setMessage] = useState('');
const handleRegister = useCallback(async () => {
if (!requestTossPayPaysBilling.isSupported()) {
setStatus('error');
setMessage('현재 환경에서는 정기결제 등록을 지원하지 않습니다.');
return;
}
setStatus('pending');
setMessage('');
try {
// 1. 서버에서 래핑된 토큰 발급
const { wrappedToken } = await fetch('/api/billing/prepare', {
method: 'POST',
body: JSON.stringify({ planId }),
headers: { 'Content-Type': 'application/json' },
}).then((res) => res.json());
// 2. 토스페이 정기결제 인증창 띄우기
const result = await requestTossPayPaysBilling({ params: { wrappedToken } });
if (!result) {
setStatus('error');
setMessage('정기결제 인증을 완료할 수 없습니다.');
return;
}
if (!result.success) {
setStatus('error');
setMessage(`정기결제 인증 실패: ${result.reason ?? '알 수 없는 오류'}`);
return;
}
// 3. 서버 측 billing key 저장 및 등록 완료
await fetch('/api/billing/complete', {
method: 'POST',
body: JSON.stringify({ planId }),
headers: { 'Content-Type': 'application/json' },
});
setStatus('success');
setMessage('정기결제가 등록됐어요.');
} catch (error) {
setStatus('error');
setMessage('정기결제 등록 중 오류가 발생했어요.');
console.error(error);
}
}, [planId]);
return (
<div>
<button type="button" onClick={handleRegister} disabled={status === 'pending'}>
{status === 'pending' ? '등록 진행 중…' : '정기결제 등록'}
</button>
{message && <p role="status">{message}</p>}
</div>
);
}
직접 실행해 보기
sdk-example의 Payment 페이지에서 requestTossPayPaysBilling 카드를 실행해 결과를 확인할 수 있습니다.
관련 API
checkoutPayment— 단건 결제(payToken 기반) 인증 흐름.
관련 가이드
- (작성 예정) Guides — "토스페이 정기결제 등록 흐름"
외부 참조
@apps-in-toss/web-framework— 상위 SDK 패키지. 실제 export는 내부적으로@apps-in-toss/web-bridge에서 가져옵니다.