본문으로 건너뛰기

Webhook Events 레퍼런스

본 페이지는 CROSS PAY API 가 발송하는 webhook 이벤트의 페이로드 스키마 사전입니다. 발화 시점·연동 흐름·머천트 측 처리 패턴은 Webhooks Overview 를 참고하세요.

범위

본 페이지는 envelope 의 JSON 본문 스키마에 집중합니다.

HTTP 요청 헤더

헤더형식설명
Content-Typeapplication/json본문 인코딩
webhook-idUUID이벤트 식별자. 멱등성 dedup 키
webhook-timestampUnix epoch seconds (string)발송 시점. replay 보호용 (권장 tolerance ±300초)
webhook-signaturev1,<base64> (공백 구분 다중 가능)HMAC-SHA256 서명. 서명 대상은 ${id}.${ts}.${body}

서명 검증 알고리즘과 코드 예시는 Verifying Webhooks 를 참고하세요.

공통 envelope

CROSS PAY 는 Standard Webhooks v1 규격의 envelope 을 사용합니다.

{
"type": "<dot-delimited 이벤트 이름>",
"timestamp": "<ISO-8601 UTC, 도메인 이벤트 발생 시각>",
"data": {
"payment": { ... },
"refund": { ... }
}
}
필드타입설명
typestringdot-delimited 이벤트 이름. 예: payment.completed
timestampISO-8601도메인 이벤트가 발생한 시각 (paid_at / failed_at / ...). UTC Z
dataobject이벤트별 페이로드. payment 객체는 항상 존재

data.payment 공통 필드

모든 이벤트의 data.payment 객체는 다음 필드 집합에서 선택됩니다. 필드의 존재 여부는 이벤트 종류에 따라 달라집니다.

필드타입항상?설명
idstring결제 식별자 (pay_...)
statusstring결제 상태 (이벤트별 고정값, 아래 표 참조)
currencystringISO-4217 통화 코드. 예: KRW, USD
amountstring결제 금액. 정밀도 손실 방지를 위해 문자열로 직렬화
payer_uidstring결제자 식별자
metadataobject결제 생성 시 머천트가 넘긴 metadata. 빈 경우 {}
receipt_idstringPG 발급 영수증 ID (payment.completed 에만)
providerstring결제 처리 PG (payment.completed 에만). 예: binancepay
failure_reasonstring실패 사유 enum (payment.failed 에만). 아래 enum 표 참조
paid_atISO-8601결제 확정 시각 (payment.completed)
cancelled_atISO-8601취소 처리 시각 (payment.cancelled)
failed_atISO-8601실패 처리 시각 (payment.failed)
expired_atISO-8601만료 처리 시각 (payment.expired)

status 이벤트별 매핑

이벤트직전 상태status
payment.completedPROCESSINGPAID
payment.failedPROCESSINGFAILED
payment.expiredPENDING 또는 PROCESSINGEXPIRED
payment.cancelledPENDINGCANCELLED
PROCESSING 경유 규칙

payment.completed / payment.failed 는 결제가 반드시 PROCESSING 을 거쳐서 종결합니다 (POST /checkout/{id}/quotes 가 PG session 을 만든 시점부터). PG webhook 이 도착하기 전까지는 머천트가 단독으로 cancel 호출이 불가합니다 — 409 INVALID_TRANSITION. 자세한 라이프사이클은 Webhooks Overview.

failure_reason enum

의미
UNKNOWNPG 가 분류하지 않은 실패. fallback
DECLINEDPG 가 결제를 거절
TX_REVERTED온체인 TX 가 mined 됐으나 컨트랙트 호출이 revert
AMOUNT_MISMATCH온체인 이벤트 금액이 예상치와 불일치
TOKEN_MISMATCH온체인 이벤트 토큰이 예상치와 불일치
ONCHAIN_TIMEOUT만료 전에 온체인 컨펌을 관측하지 못함

이 집합은 추가 확장 가능합니다. 머천트는 인식하지 못하는 값을 UNKNOWN 으로 fallback 처리하세요.

결제 상태 머신

  • PENDING → PAID/FAILED 직행은 허용되지 않습니다. PG·체인이 결제 결과를 보고하기 전에 반드시 PROCESSING 상태가 선행됩니다.
  • PROCESSING → CANCELLED 는 차단됩니다. PG 와의 race 를 피하기 위해 머천트 cancel API 는 409 INVALID_TRANSITION 으로 거부됩니다.
  • terminal 상태(PAID / FAILED / EXPIRED / CANCELLED / *_REFUNDED) 에서 다른 종결 상태로 전이하지 않습니다. 같은 결제에 대해 두 종류의 종결 이벤트가 발화되는 경우는 없습니다.

payment.completed

PG·체인이 결제 확정을 보고하면 payment 상태가 PAID 로 전이되고 본 이벤트가 발화됩니다.

필드 구성

필드필수비고
id
status항상 PAID
currency
amount
payer_uid
receipt_idPG 발급 영수증 ID
providerPG 식별자 (binancepay, payletter, ...)
paid_at
metadata

샘플

{
"type": "payment.completed",
"timestamp": "2026-04-21T12:00:00Z",
"data": {
"payment": {
"id": "pay_abc123",
"status": "PAID",
"currency": "KRW",
"amount": "50000",
"payer_uid": "user_789",
"receipt_id": "rcpt_xyz",
"provider": "binancepay",
"paid_at": "2026-04-21T12:00:00Z",
"metadata": { "order_id": "shop-order-789" }
}
}
}
fee breakdown

정산용 fee 정보는 본 페이로드에 포함되지 않습니다. 필요하면 GET /v1/payments/:id 로 보강 조회하세요.


payment.failed

PG·체인이 실패를 보고하면 payment 상태가 FAILED 로 전이되고 본 이벤트가 발화됩니다.

필드 구성

필드필수비고
id
status항상 FAILED
currency
amount
payer_uid
failure_reasonfailure_reason enum 참조
failed_at
metadata

샘플

{
"type": "payment.failed",
"timestamp": "2026-04-21T12:05:00Z",
"data": {
"payment": {
"id": "pay_abc123",
"status": "FAILED",
"currency": "KRW",
"amount": "50000",
"payer_uid": "user_789",
"failure_reason": "DECLINED",
"failed_at": "2026-04-21T12:05:00Z",
"metadata": { "order_id": "shop-order-789" }
}
}
}

payment.expired

세션 TTL 이 만료되면 expiry 워커가 in-flight 결제(PENDING 또는 PROCESSING) 를 EXPIRED 로 전이시키고 본 이벤트가 발화됩니다.

필드 구성

필드필수비고
id
status항상 EXPIRED
currency
amount
payer_uid
expired_at
metadata

샘플

{
"type": "payment.expired",
"timestamp": "2026-04-21T12:30:00Z",
"data": {
"payment": {
"id": "pay_abc123",
"status": "EXPIRED",
"currency": "KRW",
"amount": "50000",
"payer_uid": "user_789",
"expired_at": "2026-04-21T12:30:00Z",
"metadata": { "order_id": "shop-order-789" }
}
}
}

payment.cancelled

머천트가 PENDING 상태의 결제를 POST /v1/payments/{id}/cancel 로 명시 취소하면 본 이벤트가 발화됩니다. PROCESSING 결제는 cancel 호출이 409 INVALID_TRANSITION 으로 거부되므로 본 이벤트가 발생하지 않습니다 — 해당 흐름은 payment.expired 또는 payment.failed 로 종결됩니다.

필드 구성

필드필수비고
id
status항상 CANCELLED
currency
amount
payer_uid
cancelled_at
metadata

샘플

{
"type": "payment.cancelled",
"timestamp": "2026-04-21T12:10:00Z",
"data": {
"payment": {
"id": "pay_abc123",
"status": "CANCELLED",
"currency": "KRW",
"amount": "50000",
"payer_uid": "user_789",
"cancelled_at": "2026-04-21T12:10:00Z",
"metadata": { "order_id": "shop-order-789" }
}
}
}

payment.refunded (예약)

환불 완료 이벤트의 envelope 명세(data.refund 객체 포함)는 코드에 정의되어 있으나, CROSS PAY API 코드에는 현재 발화 경로가 연결되어 있지 않습니다. 머천트 endpoint 로 본 이벤트가 도착하지 않습니다. 환불 결과는 GET /v1/payments/:id 로 조회하세요.

발화 경로가 연결되면 본 페이지에 정식 스키마와 샘플이 추가됩니다.


알려진 제약

  • payment.created 는 발화되지 않습니다. 결제 생성 결과는 POST /v1/payments 응답으로 동기 전달됩니다.
  • metadata 가 빈 경우 {} 로 직렬화됩니다. null 이 아닙니다.
  • 모든 시간 필드는 ISO-8601 UTC (Z 접미사) 입니다.
  • amount 는 문자열입니다. 정밀도 손실 방지를 위해 number 가 아닌 string 으로 직렬화됩니다. 머천트는 decimal 라이브러리로 파싱 하세요.