결제 이벤트 스트림

결제 페이지에서 상태 변화를 실시간으로 표시하기 위한 Server-Sent Events 스트림입니다.

GEThttps://pay.apiacc.com/pay/{token}/events

인증이 필요 없는 공개 SSE 엔드포인트입니다. 연결 즉시 현재 상태를 담은 스냅샷을 보내고, 이후 변경사항을 계속 전송합니다.

인증 불필요

결제 세션 조회와 마찬가지로 공개 토큰만으로 동작하며 Authorization 헤더가 필요 없습니다.

경로 파라미터

필드타입필수제한예시
token

결제 생성 응답의 checkout_url에 포함된 공개 토큰입니다.

string필수"pub_xxx"

이벤트 종류

필드타입필수제한예시
payment.snapshot

연결이 열리면 가장 먼저 전송되는 현재 결제 상태 전체 스냅샷입니다.

초기필수
payment.updated

상태, 결제 수단, pin_charges 등 결제 정보가 변경될 때마다 전송됩니다.

갱신필수

모든 이벤트의 데이터 구조는 결제 세션 조회 응답과 동일합니다.

payment.snapshot 이벤트 예시

{
  "payment": {
    "id": "pay_xxx",
    "ref": "order_1234",
    "amount": 10000,
    "status": "processing",
    "method": "cultureland_pin"
  },
  "payment_methods": [
    "bank_transfer",
    "cultureland_pin"
  ],
  "fee_percent": 0,
  "pin_charges": [
    {
      "pin": "3110-0123-4567-8901",
      "status": "charged",
      "amount": 5000
    }
  ],
  "bank": null
}

원시 스트림 형태

text/event-stream
event: payment.snapshot
data: {"payment":{"id":"pay_xxx","status":"processing"},"payment_methods":["bank_transfer","cultureland_pin"]}

: heartbeat

event: payment.updated
data: {"payment":{"id":"pay_xxx","status":"approved"},"payment_methods":["bank_transfer","cultureland_pin"]}

retry: 3000
  • :로 시작하는 줄은 하트비트 주석입니다. 연결이 유지되고 있음을 나타낼 뿐 별도로 처리할 필요는 없습니다.
  • retry 필드는 연결이 끊겼을 때 클라이언트가 재연결을 시도해야 하는 대기 시간(ms)을 지정합니다.
  • 결제가 최종 상태(approved, rejected, expired, review_required)에 도달하면 서버가 스트림을 종료합니다.

언어별 예제

JavaScript (EventSource)
const events = new EventSource("https://pay.apiacc.com/pay/pub_xxx/events")

events.addEventListener("payment.snapshot", (e) => {
  const data = JSON.parse(e.data)
  renderPayment(data)
})

events.addEventListener("payment.updated", (e) => {
  const data = JSON.parse(e.data)
  renderPayment(data)
  if (["approved", "rejected", "expired", "review_required"].includes(data.payment.status)) {
    events.close()
  }
})

events.onerror = () => {
  // EventSource가 브라우저 기본 정책에 따라 자동으로 재연결을 시도합니다.
}
Python (requests, 스트리밍)
import json
import requests

url = "https://pay.apiacc.com/pay/pub_xxx/events"

with requests.get(url, stream=True, timeout=None) as res:
    event_name = None
    for raw_line in res.iter_lines(decode_unicode=True):
        if raw_line is None or raw_line == "":
            continue
        if raw_line.startswith(":"):
            continue  # heartbeat
        if raw_line.startswith("event:"):
            event_name = raw_line.removeprefix("event:").strip()
        elif raw_line.startswith("data:"):
            payload = json.loads(raw_line.removeprefix("data:").strip())
            print(event_name, payload)
            if payload["payment"]["status"] in ("approved", "rejected", "expired", "review_required"):
                break
curl
curl -N "https://pay.apiacc.com/pay/pub_xxx/events"

서버 사이드 알림

구매자 화면과 별도로, 결제가 처음으로 approved가 되면 apiacc는 판매자 서버로 payment.approved Webhook 이벤트를 전송합니다. Hosted Payment 계좌이체가 거절되면 payment.rejected 이벤트가 전송될 수 있습니다. 이 알림은 판매자 계정에 platformdefault인 Webhook이 등록되어 있을 때 전송됩니다. 이벤트 스트림은 화면 표시용이며, 결제 완료를 최종적으로 확정하는 로직은 Webhook 또는 결제 세션 조회 API로 처리하는 것을 권장합니다.