가상계좌 플로우

가상계좌는 발급 직후 승인 완료가 아니라 입금 대기 상태로 생성되고, 입금 후 웹훅으로 상태가 갱신됩니다.

발급

POST /v1/virtual-accounts
{
  "orderId": "order-va-001",
  "orderName": "무통장 주문",
  "amount": 25000,
  "customerName": "홍길동"
}

{
  "paymentKey": "pay_va_123",
  "status": "WAITING_FOR_DEPOSIT",
  "virtualAccount": {
    "bank": "신한",
    "accountNumber": "140-123-456789",
    "dueDate": "2026-04-22T23:59:59+09:00",
    "expired": false
  }
}

결제 승인 시 상태

가상계좌를 포함한 결제를 승인하면 즉시 `DONE`이 아니라 `WAITING_FOR_DEPOSIT` 상태가 내려오고 `virtualAccount` 객체가 같이 포함됩니다.

{
  "paymentKey": "pay_va_123",
  "orderId": "order-va-001",
  "status": "WAITING_FOR_DEPOSIT",
  "virtualAccount": {
    "bank": "신한",
    "accountNumber": "140-123-456789",
    "dueDate": "2026-04-22T23:59:59+09:00"
  }
}

DEPOSIT_CALLBACK 웹훅

{
  "eventType": "DEPOSIT_CALLBACK",
  "createdAt": "2026-04-21T10:30:00+09:00",
  "secret": "whsec_123",
  "data": {
    "paymentKey": "pay_va_123",
    "depositedAmount": 25000,
    "status": "DONE"
  }
}
export async function POST(request: Request) {
  const payload = await request.json();
  console.log("deposit webhook", payload.data.paymentKey, payload.data.status);
  return Response.json({ received: true });
}

관리자 수동 입금 발사

운영 화면의 `/admin/webhooks`에서 `Fire webhook`을 눌러 입금 이벤트를 수동으로 다시 보낼 수 있습니다. 리시버 검증이나 데모 시연에 유용합니다.

만료·환불 시나리오

입금 기한은 `virtualAccount.dueDate`로 확인합니다. 기한이 지나면 `expired: true`, `status: EXPIRED`로 바뀌며, 이미 입금 완료된 건은 일반 취소 API로 환불합니다.