이벤트 레퍼런스
전달 순서와 최신 상태는 웹훅 개요, 중복 처리는 응답과 처리를 참고해요.
| 이벤트 | 언제 와요 | data 객체 | 주의점 |
|---|---|---|---|
order.paid | 결제가 성공할 때 와요. | 주문 객체 전체예요. | 구독 결제 유형은 아래에서 확인해요. |
order.refunded | 부분 또는 전체 환불이 확정될 때 와요. | 주문 객체 전체와 이번 환불 건을 나타내는 refund 객체예요. | — |
subscription.created | 새 구독이 만들어질 때 와요. | 구독 객체 전체와 change예요. change.kind는 항상 created예요. | 최초 결제 성공에 대한 order.paid도 별도로 올 수 있어요. |
subscription.updated | 플랜·결제 주기 변경, 해지 예약·취소, 구독 기간 갱신, 가격 인상 고지·동의 때 와요. | 구독 객체 전체와 change 객체예요. kind로 변경 종류를 구분해요. | 갱신 결제에서 order.paid와 함께 올 수 있어요. |
subscription.ended | 구독이 실제로 종료될 때 와요. | 종료된 구독 객체 전체와 endReason예요. | — |
subscription.payment_failed | 구독 갱신 결제가 실패할 때 와요. | 해당 구독 객체 전체와 실패 횟수 attempts, 실패 금액 amount, 통화 currency예요. | 구독 상태가 바뀔 수 있어요. |
refund.requested | 구매자의 환불 요청이 접수될 때 와요. | 환불 요청 객체 전체예요. | 요청을 검토하고 상태를 처리해요. |
refund.approved | 환불 요청이 승인될 때 와요. | 환불 요청 객체 전체예요. | — |
refund.rejected | 환불 요청이 거절될 때 와요. | 환불 요청 객체 전체예요. | 요청 상태와 거절 정보를 확인해요. |
refund.on_hold | 환불 요청이 보류될 때 와요. | 환불 요청 객체 전체예요. | 보류 사유와 최신 상태를 확인해요. |
refund.withdrawn | 구매자가 환불 요청을 철회할 때 와요. | 환불 요청 객체 전체예요. | — |
license.issue | 결제 확정 직후 내 서버에서 라이선스 키를 발급하도록 동기 요청해요. | 발급에 필요한 요청 객체예요. | data 필드와 응답 규칙은 내 서버에서 발급을 참고해요. |
webhook.test | 셀러 콘솔에서 테스트 발송을 실행할 때 와요. | endpointId, mode, sentAt을 포함해요. | 테스트 발송 전용 표시이며 실제 업무 이벤트 type이 아니에요. live와 test 엔드포인트 모두로 보낼 수 있어요. |
결제와 구독 이벤트
order.paid
data.subscriptionEvent | 의미 |
|---|---|
null | 비구독 주문이에요. |
initial | 최초 구독 결제예요. |
renewal | 구독 갱신 결제예요. |
proration | 플랜·주기 변경 차액 결제예요. |
subscription.created
새 구독이 생성되면 보내요.
본문과 data의 mode는 test 또는 live예요.
서명 헤더와 본문 형식은 웹훅에서 확인해요.
data 필드
data는 구독 객체에 아래 필드를 더한 것이에요.
changeobject새 구독이 만들어진 변경 정보예요.
하위 필드 9개
amountnumbernull 가능변경 시 적용된 금액을 원 단위로 알려줘요.
currencystringnull 가능변경 금액 통화예요.
KRW, nulleffectiveAtstringnull 가능변경 효력이 발생하는 시각이에요.
extensionDaysnumbernull 가능구독 기간 연장 일수예요.
fromobjectnull 가능변경 전 플랜과 주기예요.
하위 필드 2개
billingIntervalstring변경 전후 청구 주기예요.
monthly, yearlyplanIdstring변경 전후 구독 플랜 식별자예요.
kindstring이 이벤트에서 발생한 구독 변경 유형이에요.
createdorderIdstringnull 가능변경과 연결된 주문 식별자예요.
prorationAmountnumbernull 가능차액 결제 금액을 원 단위로 알려줘요.
toobjectnull 가능변경 후 플랜과 주기예요.
하위 필드 2개
billingIntervalstring변경 전후 청구 주기예요.
monthly, yearlyplanIdstring변경 전후 구독 플랜 식별자예요.
subscription.updated
플랜, 주기, 기간 또는 해지 예약이 변경되면 보내요.
본문과 data의 mode는 test 또는 live예요.
서명 헤더와 본문 형식은 웹훅에서 확인해요.
data 필드
data는 구독 객체에 아래 필드를 더한 것이에요.
changeobject구독의 변경 전후 플랜 정보예요.
하위 필드 9개
amountnumbernull 가능변경 시 적용된 금액을 원 단위로 알려줘요.
currencystringnull 가능변경 금액 통화예요.
KRW, nulleffectiveAtstringnull 가능변경 효력이 발생하는 시각이에요.
extensionDaysnumbernull 가능구독 기간 연장 일수예요.
fromobjectnull 가능변경 전 플랜과 주기예요.
하위 필드 2개
billingIntervalstring변경 전후 청구 주기예요.
monthly, yearlyplanIdstring변경 전후 구독 플랜 식별자예요.
kindstring이 이벤트에서 발생한 구독 변경 유형이에요.
plan_changed, plan_change_scheduled, billing_interval_changed, billing_interval_change_scheduled, cancel_scheduled, cancel_resumed, period_renewed, period_extended, price_change_scheduled, price_change_consentedorderIdstringnull 가능변경과 연결된 주문 식별자예요.
prorationAmountnumbernull 가능차액 결제 금액을 원 단위로 알려줘요.
toobjectnull 가능변경 후 플랜과 주기예요.
하위 필드 2개
billingIntervalstring변경 전후 청구 주기예요.
monthly, yearlyplanIdstring변경 전후 구독 플랜 식별자예요.
data.change.kind | 의미 |
|---|---|
plan_changed | 플랜 변경이 적용됐어요. |
plan_change_scheduled | 플랜 변경이 예약됐어요. |
billing_interval_changed | 결제 주기 변경이 적용됐어요. |
billing_interval_change_scheduled | 결제 주기 변경이 예약됐어요. |
cancel_scheduled | 기간말 해지가 예약됐어요. |
cancel_resumed | 해지 예약이 취소됐어요. |
period_renewed | 갱신 결제로 구독 기간이 갱신됐어요. |
period_extended | 구독 기간이 연장됐어요. |
price_change_scheduled | 가격 인상이 고지됐어요. 새 금액은 change.amount, 적용일은 change.effectiveAt이에요. |
price_change_consented | 구매자가 인상된 가격에 동의했어요. |
권한은 change.kind가 아니라 구독 객체의 최신 상태로 맞춰요.
async function handleSubscriptionUpdated(event) {
const subscription = event.data
if (!(await saveSubscriptionIfNewer(subscription, event.createdAt))) return
await syncAccessFromSubscription(subscription)
switch (event.data.change.kind) {
case 'cancel_scheduled':
await sendMail('cancel-scheduled', subscription); break
case 'cancel_resumed':
await sendMail('cancel-resumed', subscription); break
case 'plan_change_scheduled':
case 'billing_interval_change_scheduled':
await sendMail('subscription-change-scheduled', subscription); break
default:
break
}
}subscription.ended
구독이 종료되면 보내요.
본문과 data의 mode는 test 또는 live예요.
서명 헤더와 본문 형식은 웹훅에서 확인해요.
data 필드
data는 구독 객체에 아래 필드를 더한 것이에요.
endReasonstringnull 가능구독 종료 사유예요.
canceled, refunded, payment_failed, product_unavailable, plan_unavailable, pg_canceled, price_increase_declined, nullrefundAmountinteger즉시 해지로 환불한 금액이에요. 환불을 수반한 즉시 해지에서 전달해요.
종료된 구독의 endReason 값과 의미는 구독 REST API를 참고해요.
subscription.payment_failed
환불 이벤트
order.refunded
환불이 여러 번이면 건별 이벤트가 올 수 있으므로 누적 금액과 최신 상태는 주문을 다시 조회해요.
refund.requested
refund.approved
실제 환불 여부는 order.refunded와 주문의 최신 상태를 확인해요.
refund.rejected
refund.on_hold
refund.withdrawn
refund.withdrawn로 철회된 요청은 승인·거절하지 않아요.
라이선스 발급 이벤트
재시도·멱등 처리와 서명 검증을 참고해요.
테스트 이벤트
콘솔에서 테스트 발송을 요청하면 실제 이벤트와 구분되는 테스트 이벤트를 보내요.
본문과 data의 mode는 test 또는 live예요.
서명 헤더와 본문 형식은 웹훅에서 확인해요.
data 필드
endpointIdstring테스트 이벤트를 보낸 엔드포인트 식별자예요.
modestring이벤트의 결제 환경이에요.
live, testsentAtstring테스트 이벤트가 발송된 시각이에요.