Vouchereto API로 개발하기
한 가지 일을 위한 간단한 REST API입니다. 바우처를 받아 고객에게 묶고, 내 플랫폼의 잔액으로 바꿉니다.
- Base URL
- api.vouchereto.com/v1
- 테스트와 라이브
- vch_test_… 및 vch_live_… 키
- 인증
- Bearer 키 + HMAC-SHA256
- 형식
- JSON · 금액은 최소 통화 단위
첫 번째 사용 처리
키 발급
가맹점 포털에서 테스트 키를 만드세요. 전체 키는 한 번만 표시되며, 키의 마지막 부분이 요청 서명에 쓰는 시크릿입니다.
바우처 예약
코드, 통화, 고객 참조값을 보내세요. 바우처가 해당 고객에게 묶여 다른 곳에서는 사용할 수 없게 됩니다.
적립 후 확정
내 쪽에서 잔액을 적립한 뒤 확정하세요. 충전에 실패하면 대신 취소하면 바우처가 해제됩니다.
웹훅 수신
엔드포인트를 등록해 확정, 취소, 만료, 결제 화면 이벤트를 서명된 형태로 받으세요.
POST /v1/redemptions
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213
Vouchereto-Signature: t=1790500000,v1=9c1e5f07…
Content-Type: application/json
{ "code": "7K2M-9QXR-4HTB-2WNZ", "customer_ref": "acct_48213", "currency": "USD" }
# 201 Created
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "reserved",
"amount_minor": 5000, "currency": "USD", "voucher_last4": "2WNZ",
"customer_ref": "acct_48213", "livemode": false,
"expires_at": "2026-09-27T14:12:00Z", "captured_at": null }
# Credit the customer first, then capture. Irreversible.
POST /v1/redemptions/5f0c2a7e-…/capture
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-capture
Vouchereto-Signature: t=1790500012,v1=4b7d2e91…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "captured",
"captured_at": "2026-09-27T14:02:31Z", … }
# The top-up failed: release the voucher back to the customer
POST /v1/redemptions/5f0c2a7e-…/cancel
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-cancel
Vouchereto-Signature: t=1790500015,v1=77aa01c3…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "cancelled", … }
// Vouchereto-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, t + "." + rawBody)>
// secret = the whsec_… signing secret of your webhook endpoint
import crypto from "node:crypto";
export function verifyWebhook(rawBody, header, secret) {
const parts = header.split(",").map((p) => p.trim().split("="));
const t = Number(parts.find(([k]) => k === "t")?.[1]);
const sigs = parts.filter(([k]) => k === "v1").map(([, v]) => Buffer.from(v, "hex"));
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return sigs.some((s) => s.length === expected.length && crypto.timingSafeEqual(s, expected));
}
사용 처리 라이프사이클
- 확정됨바우처가 사용되었습니다. 되돌릴 수 없습니다.
- 취소됨가맹점이 취소했습니다. 바우처를 다시 사용할 수 있습니다.
- 예약 만료제시간에 확정되지 않았습니다(기본 15분). 바우처를 다시 사용할 수 있습니다.
개발 시 알아 둘 사항
요청 서명
모든 요청에는 Vouchereto-Signature 헤더가 포함됩니다. 타임스탬프와, 타임스탬프·메서드·경로·본문을 API 키 시크릿으로 계산한 HMAC-SHA256 값입니다. 시간 오차는 최대 300초까지 허용합니다.
// Sign every request with the secret part of your API key (the text after the last "_")
const t = Math.floor(Date.now() / 1000);
const payload = `${t}.${method} ${pathWithQuery}\n${body}`;
const v1 = crypto.createHmac("sha256", keySecret).update(payload).digest("hex");
headers["Vouchereto-Signature"] = `t=${t},v1=${v1}`;
멱등성
모든 POST 요청에는 Idempotency-Key 헤더가 필요합니다. 같은 키로 요청을 반복하면 원래 응답이 Idempotent-Replayed: true 표시와 함께 반환됩니다. 키는 최소 30일 동안 보관됩니다.
샌드박스 바우처
테스트 키로 POST /v1/sandbox/vouchers를 호출하면 요청한 상태(active, reserved, redeemed, expired, risk_hold, void)의 테스트 바우처가 생성되고 코드가 반환됩니다. 테스트 키는 테스트 데이터만 볼 수 있습니다.
웹훅 이벤트
| 이벤트 | 발송 시점 |
|---|---|
| redemption.captured | 예약된 바우처가 확정되었습니다. 적립한 잔액을 유지해도 됩니다. |
| redemption.cancelled | 예약이 취소되었습니다. 바우처를 다시 사용할 수 있습니다. |
| redemption.expired | 확정되지 않은 채 예약 시간이 만료되었습니다. |
| checkout.completed | 호스팅 결제가 완료되고 바우처가 적용되었습니다. |
| checkout.expired | 호스팅 결제 세션이 결제 없이 만료되었습니다. |
| checkout.failed | 결제된 결제 세션이 환불 등으로 취소되었습니다. |
오류
| 상태 | 코드 | 고객 안내 문구 |
|---|---|---|
| 404 | VOUCHER_INVALID | 코드를 찾을 수 없습니다. 확인 후 다시 시도해 주세요. |
| 409 | VOUCHER_ALREADY_REDEEMED | 이미 사용된 바우처입니다. |
| 409 | VOUCHER_RESERVED | 이 바우처는 지금 다른 결제에서 사용 중입니다. |
| 422 | VOUCHER_EXPIRED | 만료된 바우처입니다. |
| 422 | UNIVERSAL_NOT_ACCEPTED | 유니버설 바우처는 받지 않습니다. 이 사이트 전용 바우처를 사용해 주세요. |
| 422 | CURRENCY_MISMATCH | 이 바우처는 다른 통화입니다. |
| 429 | TOO_MANY_INVALID_ATTEMPTS | 시도 횟수가 너무 많습니다. 몇 분 후 다시 시도해 주세요. |
오류는 RFC 7807(application/problem+json) 형식을 따르며, 고정된 코드와 request_id를 포함합니다.
이 페이지는 API 요약입니다. 모든 필드를 담은 전체 레퍼런스는 www.vouchereto.com/docs/reference에 있습니다.
막히는 부분이 있나요?
[DEVELOPER SUPPORT EMAIL]로 연락해 주세요. 개발자가 모든 메시지를 직접 읽습니다.
- OpenAPI 명세
- Postman 컬렉션
- API 상태 · [URL]
- 변경 내역