쿠폰 사용 API (v2)

비볼디 쿠폰 사용 API(Redeem)는 발급된 쿠폰을 사용 완료 상태로 처리하는 기능을 제공합니다.

대시보드에서 수동 처리하지 않고, API를 통해 자동으로 사용 완료 처리할 수 있습니다.
호출 시 사용 횟수가 차감되며, 설정된 최대 사용 횟수를 초과하면 이후 사용이 차단됩니다.

이 API는 퍼스널 요금제 이상에서만 사용할 수 있습니다.

PUT

/api/coupon/v2/redeem

{
    "cpnNo": "ZJLF0399WQBEQZJM",
    "onsiteToken": "QsBkV0ryiCkxiV4KUNJBSWQcR8MzSlvez4ntLh2Tt2M",
    "userId": "x77hu",
    "memo": "IP Address: 210.123.111.222, Request Page: https://example.com/shop/bags/p112233",
    "processStoreIdx": 22
}

Request Parameters

cpnNo string required
쿠폰 번호.
onsiteToken string
현장 처리용 단기 교환 증표. v2는 비밀번호 평문(onsitePwd)을 받지 않습니다.
쿠폰에 onsiteYn = Y가 설정돼 있으면, 검증 API(Validate) 응답의 onsiteToken을 그대로 보내세요.
증표를 쓰는 요청에는 Idempotency-Key가 필수입니다. 같은 key의 재시도는 최초 결과를 그대로 재생하고, 다른 key로 같은 증표를 다시 쓰면 400(오류 코드 1228)으로 거부됩니다.
검증에서 처리 매장을 지정했다면 이 요청의 처리 매장도 같아야 합니다. 매장 없이 검증한 증표에 매장을 새로 붙일 수도 없습니다.
userId string
사용자 ID. 쿠폰 발급/사용자를 식별하는 ID.
쿠폰 사용 가능 횟수가 2~5로 설정된 경우 반드시 입력해야 합니다.
memo string
내부 참고용 메모. 사용자 IP, 쿠폰 사용처, 기타 정보를 기록할 수 있습니다.
쿠폰 사용 횟수가 무제한인 경우, userId 대신 메모를 활용해 사용자를 구분할 수 있습니다.
processStoreIdx integer
이 요청이 실제로 처리되는 매장 IDX. 보내면 조직 소유·활성 상태·권한을 서버가 확인한 뒤 처리 이력에 기록합니다.
처리 지점은 요청으로 받지 않고 이 매장에서 서버가 확인합니다. 발행 매장(storeIdx)과는 다른 값입니다.
{
    "code": 0,
    "message": "",
    "result": null
}

Response Parameters

code integer
응답 코드: 0 = 성공, 그 외 값 = 오류
message string
응답 메시지입니다. 응답 코드가 0이 아니면, 오류 관련 메시지가 반환됩니다.
result null

처리 매장 지정

파라미터 의미 설명
processStoreIdx 처리 매장 이 요청이 실제로 처리되는 매장입니다. 선택 항목이며, 보내면 조직 소유·활성 상태·권한을 서버가 확인한 뒤 처리 이력에 기록합니다.

처리 지점은 요청으로 받지 않습니다. 지정한 매장이 속한 지점을 서버가 확인해 기록합니다.

사용 가능 범위가 BRANCH인 경우, 확인된 처리 매장의 지점이 사용 가능 지점과 같거나 해당 지점의 현장 비밀번호로 인증해야 처리됩니다. 둘 다 없으면 거부됩니다.

사용할 수 없는 파라미터 — branchIdx(발행 지점), storeIdx(발행 매장), useScope(사용 가능 범위), useBranchIdx(사용 가능 지점)는 이미 저장된 발행 정책이라 이 API로 바꿀 수 없습니다. 함께 보내면 400(오류 코드 1227)으로 거부됩니다.

Idempotency-Key

네트워크 오류로 응답을 받지 못했을 때 안전하게 재시도하려면 Idempotency-Key 헤더에 요청마다 고유한 값을 담아 보냅니다. 본문의 requestId로도 보낼 수 있으며, 둘 다 보내고 값이 다르면 거부됩니다. 허용 형식은 영문·숫자와 . _ : - 를 조합한 8~64자입니다.

같은 key로 같은 요청을 다시 보내면 다시 처리하지 않고 최초 결과를 그대로 돌려줍니다. 중복으로 처리되지 않으며 웹훅도 다시 발송되지 않습니다.

같은 key는 같은 논리 작업의 재시도에만 사용하세요. 서로 다른 작업에는 반드시 새 key를 사용해야 합니다. 같은 key를 다른 요청 내용이나 다른 작업에 사용하면 409로 거부될 수 있습니다.

검증 API와 함께 사용하는 방법

쿠폰 사용 API는 상태를 실제로 변경하므로, 호출 전에 검증 API로 유효성을 먼저 확인하는 것을 권장합니다.

검증 API로 유효한 쿠폰임을 확인한 뒤 사용 API를 호출하면, 만료되었거나 이미 사용된 쿠폰에 대한 불필요한 처리를 방지할 수 있습니다.

검증 → 사용 순서로 API를 호출하는 것이 안정적인 쿠폰 처리 흐름의 기본 패턴입니다.

언제 이 API를 사용하나요?

쿠폰 검증 이후 실제로 쿠폰을 적용할 때 사용합니다.

  • 결제 완료 시 쿠폰 사용 처리
  • 주문 확정 시 할인 적용 기록
  • 오프라인/현장 사용 처리
  • 중복 사용 방지를 위한 상태 변경

즉, 쿠폰을 실제 소비하는 최종 단계입니다.

쿠폰 사용 처리 방식

쿠폰 번호(cpnNo)를 기준으로 해당 쿠폰을 사용 완료 상태로 변경합니다.

  • 사용 시 즉시 사용 횟수 차감
  • 재사용 불가 상태로 전환
  • 사용자 정보(userId) 기반 사용 기록 저장
  • 추가 정보(memo)를 통해 사용 로그 기록 가능

이 과정은 단순 상태 변경이 아니라, 결제와 연결된 핵심 트랜잭션 처리입니다.

사용자 식별 및 메모 활용

userId는 쿠폰을 사용한 사람을 식별하는데 사용됩니다.

쿠폰 사용 가능 횟수가 2~5로 설정된 경우 반드시 입력해야 하며, 동일 사용자의 중복 사용을 방지하는 기준값이 됩니다.

memo는 사용자 IP, 사용처, 요청 페이지 등 내부 참고용 정보를 자유롭게 기록할 수 있는 필드입니다.
사용 횟수 제한이 없는 경우 userId 대신 memo로 사용자를 구별하는 방식도 활용할 수 있습니다.

현장 인증 토큰 (onsiteToken)

v2는 현장 비밀번호 평문(onsitePwd)을 받지 않습니다. 검증 API(Validate)가 반환한 onsiteToken을 그대로 전송하세요. onsitePwd만 보내거나 onsiteToken과 함께 보내면 400(오류 코드 1227)으로 거부됩니다.

토큰을 사용하는 요청에는 Idempotency-Key가 필수입니다. 동일한 Idempotency-Key로 재시도하면 최초 처리 결과를 그대로 반환합니다. 같은 토큰을 다른 Idempotency-Key로 다시 사용하면 400(오류 코드 1228)으로 거부됩니다.

검증한 매장과 실제 처리 매장이 같아야 합니다. 검증 시 processStoreIdx를 지정했다면 이 요청에서도 같은 매장을 사용해야 합니다. 매장을 지정하지 않고 검증한 토큰에는 이후 매장을 새로 지정할 수 없습니다.

만료, 변조, 이미 사용된 토큰, 바인딩 불일치는 모두 1228로 응답합니다. 원인을 구분해 노출하면 제3자가 다른 토큰을 이용해 내부 상태를 추측할 수 있기 때문입니다.

현장 인증을 사용하지 않는 리소스(onsiteYn = N)에는 토큰이 필요하지 않습니다. v1은 기존과 동일하게 onsitePwd 평문을 받습니다.

활용 예시

  • 이커머스 결제 연동: 결제 완료 시점에 사용 API를 호출해 쿠폰 사용을 자동으로 처리하고 할인 내역을 기록합니다.
  • 오프라인 매장 처리: 직원이 QR 코드를 스캔해 쿠폰 번호를 확인한 뒤 사용 API를 호출해 즉시 사용 처리합니다.
  • 사용 이력 추적: memo에 사용자 IP와 요청 페이지를 기록해 쿠폰 남용이나 비정상 사용 패턴을 사후에 분석합니다.
  • 다중 사용 쿠폰 관리: userId를 기록해 동일 사용자가 허용 횟수 이상 사용하는 것을 방지합니다.

쿠폰이 삭제되어도 동일한 쿠폰 번호로 다시 생성하여 복구할 수 있습니다.

사용 시 주의사항

  • 반드시 검증 API 이후 호출하는 것이 안전합니다.
  • 사용 처리 후에는 쿠폰을 다시 사용할 수 없습니다.
  • 결제 실패 시 쿠폰 상태 롤백 전략이 필요할 수 있습니다.
  • 동일 요청 중복 호출 시 이중 사용 처리 방지 로직이 필요합니다.