개발자/연동

상품과 주문

이 문서는 구매 과정 전체를 순서대로 설명합니다. 잔액 확인, 상품 찾기, 가격 조회, 주문, 코드 받기 순입니다.

관련 문서: 인증 · 공통 규칙 · Webhook

#계정과 잔액

#계정

GET/api/v1/account는 회사 정보와 API 사용 가능 여부를 보여 줍니다.

JSON
{
  "merchant_id": "M00000001",
  "name": "Acme Shop",
  "legal_name": "Acme Shop Ltd",
  "billing_email": "[email protected]",
  "status": "active",
  "kyb_status": "approved",
  "api_access_enabled": true,
  "default_currency": "USD",
  "purchase_limits": {
    "currency": "USD",
    "verified": true,
    "max_order_amount": "1000.00",
    "daily_order_amount_limit": "10000.00",
    "daily_order_count_limit": 1000,
    "used_today_amount": "120.50",
    "used_today_count": 3,
    "day_resets_at": "2026-10-01T00:00:00+00:00"
  }
}
  • default_currency는 지갑 통화입니다. 결제 금액은 모두 이 통화 기준입니다.
  • api_access_enabled는 CardV가 사업자 심사를 승인하면 true가 됩니다.

#잔액

GET/api/v1/balance는 지금 쓸 수 있는 금액을 보여 줍니다.

JSON
{
  "currency": "USD",
  "balance": "1520.40",
  "reserved_amount": "0.00",
  "available_balance": "1520.40",
  "low_balance_threshold": "200.00",
  "low_balance_notified_at": null,
  "is_active": true
}
  • available_balance는 지금 바로 쓸 수 있는 금액입니다. balance에서 reserved_amount를 뺀 값입니다.
  • 주문 금액이 available_balance보다 크면 주문이 거절되고, 결제도 되지 않습니다.
  • low_balance_threshold는 잔액 부족 알림 이메일을 보내는 기준 금액입니다. 포털에서 설정합니다.
  • 지갑 충전은 포털에서 합니다.

#환율

GET/api/v1/fx-rates?quote=EUR는 USD에서 다른 통화로의 환율을 알려 줍니다.

스토어가 USD가 아닌 통화로 판매한다면 이 값을 사용하세요. CardV는 지갑에서 항상 USD로 차감합니다. 이 환율은 직접 가격을 정할 때 참고하는 용도입니다.

JSON
{
  "base": "USD",
  "quote": "EUR",
  "rate": "0.9234",
  "as_of": "2026-10-11T07:05:00Z"
}
  • quote는 ISO 4217 통화 코드입니다(예: EUR, GBP, JPY).
  • base는 생략할 수 있으며 USD만 지원합니다.
  • rate는 1 USD로 받을 수 있는 quote 통화의 양입니다. 10진수 문자열이므로 부동소수점으로 읽지 마세요.
  • as_of는 CardV가 이 환율을 마지막으로 업데이트한 시각입니다. 환율은 1시간마다 업데이트됩니다.
  • quote=USD는 "rate": "1"을 반환합니다.
  • 환율은 직접 저장해 두세요. 하루에 몇 번 조회하면 충분합니다.
상태의미조치
400quote가 없거나 3자리 코드가 아니거나, base가 USD가 아님요청을 수정하세요
404No exchange rate for this currency.이 통화의 가격은 직접 정하세요
503Exchange rate temporarily unavailable.마지막으로 저장한 환율을 계속 쓰고 나중에 다시 시도하세요

이 요청도 다른 요청처럼 서명해야 합니다. 서명하는 경로에는 쿼리 문자열이 포함됩니다(예: /api/v1/fx-rates?quote=EUR).

#상품(SKU)

SKU는 구매할 수 있는 상품 하나를 말합니다. 예: "Steam Wallet 10 USD" ID는 S000456 형태이며, 가격 조회와 주문은 SKU 단위로 합니다.

#상품 모델

모든 SKU는 아래 모델 중 하나입니다. denomination_type과 product_type으로 구분하세요.

모델구분 방법가격주문받는 것
고정 금액denomination_type: "fixed"merchant_price가 1개 가격입니다.quantity를 보냅니다.deliveries의 코드.
범위 금액denomination_type: "range"merchant_price_min부터 merchant_price_max까지. 실제 가격은 금액에 따라 다르므로 견적을 받으세요.quantity와 amount를 보냅니다.deliveries의 코드.
직접 충전product_type: "direct_charge"고정 금액과 같습니다.inputs도 보냅니다(직접 충전 참고).보통 코드가 없습니다. succeeded는 계정 충전이 완료되었다는 뜻입니다.
휴대폰 충전이 카탈로그에 없음별도 견적별도 API휴대폰 충전을 참고하세요.
  • vertical은 상품 라인이지 모델이 아닙니다. 직접 충전 상품도 vertical: "gift_card"일 수 있습니다.
  • 고정 금액이나 범위 금액 SKU는 코드 대신 CardV 교환 링크로 전달될 수 있습니다. 이때 SKU는 delivery_mode: "voucher"입니다. 링크를 받게 됩니다(delivery_type: "link", 링크는 redeem_url에 있음). 고객이 링크를 열면 코드를 받습니다. 코드처럼 고객에게 보내 주세요.

GET/api/v1/skus는 구매할 수 있는 SKU 목록을 반환합니다. 예:

HTTP
GET /api/v1/skus?search=steam&region=US&limit=50&offset=0

필터(모두 선택 사항):

필터예시검색 대상
searchsteamSKU ID, 상품명, 브랜드
brandSteam브랜드명(대소문자 구분 없음)
regionUS국가 코드 또는 국가명. GLC = 글로벌, EU = 유럽
categoryTravel비즈니스 카테고리(예: Travel, Digital Wallets & Payment, Game Credits)
verticalgift_card상품군
product_typepin_code제공 방식

페이지 나누기: limit(기본 100, 최대 500)과 offset을 보냅니다. offset을 늘려 가며 offset이 count에 도달할 때까지 요청하세요.

JSON
{
  "count": 7,
  "limit": 2,
  "results": [
    {
      "sku_id": "S000456",
      "product_id": "P000123",
      "name": "Steam Wallet 10 USD",
      "product_name": "Steam Wallet US",
      "brand": "Steam",
      "region": "US",
      "vertical": "gift_card",
      "product_type": "pin_code",
      "denomination_type": "fixed",
      "denomination_value": "10",
      "face_currency": "USD",
      "merchant_price": "9.25",
      "merchant_price_min": "9.25",
      "merchant_price_max": "9.25",
      "settlement_currency": "USD",
      "availability": "available",
      "min_quantity": 1,
      "max_quantity": 100,
      "required_input_schema": [],
      "...": "more fields"
    },
    {
      "sku_id": "S006126",
      "product_id": "P002210",
      "name": "Apple ES",
      "product_name": "Apple ES",
      "brand": "Apple",
      "region": "ES",
      "vertical": "gift_card",
      "product_type": "pin_code",
      "denomination_type": "range",
      "denomination_value": "0",
      "min_face_value": "2",
      "max_face_value": "250",
      "amount_step": null,
      "face_currency": "EUR",
      "merchant_price": "2.28",
      "merchant_price_min": "2.28",
      "merchant_price_max": "284.15",
      "price_label": "From 2.28 USD",
      "settlement_currency": "USD",
      "availability": "available",
      "...": "more fields"
    }
  ],
  "filter_options": {"brands": [], "regions": [], "categories": [], "verticals": []}
}

GET/api/v1/skus/{sku_id}는 SKU 하나를 같은 필드로 반환합니다.

자주 쓰는 필드:

필드의미
sku_id가격 조회와 주문에 쓰는 ID입니다.
merchant_price귀사가 내는 개당 가격(settlement_currency 기준). range SKU에서는 min_face_value 금액의 가격, 즉 시작 가격일 뿐입니다. 다른 금액에 쓰지 말고 amount로 견적을 받으세요.
availabilityavailable 또는 unavailable. available인 SKU만 주문하세요.
denomination_typefixed 또는 range. 고정 금액과 범위 금액을 참고하세요.
denomination_valuefixed SKU의 액면가. range SKU는 "0".
min_face_value, max_face_valuerange SKU: 고객이 고를 수 있는 최소·최대 금액(face_currency 기준).
merchant_price_min, merchant_price_max최소 금액과 최대 금액의 가격. fixed SKU에서는 merchant_price와 같습니다. 가격 범위를 보여 줄 때 쓰고, 주문 전에는 항상 정확한 금액으로 견적을 받으세요. 지금 가격을 계산할 수 없으면 merchant_price_max는 ""입니다.
price_labelmerchant_price의 표시용 텍스트. range SKU는 From으로 시작합니다(예: From 2.28 USD).
face_value_label액면가의 표시용 텍스트(예: 10 USD, 50 - 1000 GBP).
discount액면가 대비 할인(예: 7.50% off face value). 카드 통화가 지갑 통화와 같은 fixed SKU에만 있고, 그 외에는 ""입니다.
amount_step범위 금액 SKU만 해당합니다. 금액은 이 값의 배수여야 합니다. 예를 들어 "1"은 정수만 가능하다는 뜻입니다. null은 단위 제한이 없다는 뜻입니다.
face_currency카드에 표시된 통화입니다. 지갑 통화와 다를 수 있습니다.
min_quantity, max_quantity주문 항목 하나에 담을 수 있는 수량 범위입니다.
product_typepin_code(코드를 받음) 또는 direct_charge(CardV가 계정에 직접 충전).
delivery_type공급사가 전달하는 형태: code, code_pin, code_serial, url, direct_charge. delivery_mode가 voucher이면 대신 링크를 받습니다.
delivery_modecode(코드 자체를 받음) 또는 voucher(CardV 교환 링크를 받음).
voucher_instructionsvoucher SKU 전용: 고객에게 링크 사용법을 알려 주는 문구. 그 외에는 "".
vertical, category상품 라인과 비즈니스 카테고리. 필터와 표시에 사용합니다.
region, region_name, region_label국가·지역 코드, 그 이름, 표시용 라벨.
required_input_schema직접 충전 시 보내야 하는 정보입니다.
brand_logo_url, image_urlCardV가 호스팅하는 이미지, 또는 "".
description, redemption_instructions, terms, disclaimer고객에게 보여 줄 수 있는 안내 문구입니다.

참고:

  • 활성 상태이면서 귀사 계정에 공개된 SKU만 보입니다. 그 밖의 SKU는 404를 반환합니다.
  • SKU 목록은 5~15분마다 동기화하세요. 주문 직전에는 항상 가격을 다시 조회하세요.
  • 고객에게 보여 주는 가격은 동기화한 목록의 가격을 쓰세요. 페이지가 열릴 때마다, 또는 방문자마다 가격 조회 엔드포인트를 호출하지 마세요.
  • 범위 금액 SKU의 가격은 공급사 원가를 따르며 하루에도 몇 번 바뀔 수 있습니다. SKU를 동기화할 때 merchant_price_min과 merchant_price_max도 함께 갱신하세요.
  • filter_options에는 필터로 쓸 수 있는 브랜드, 지역, 상품군이 나옵니다.

#상품 단위 동기화

스토어가 '상품 하나에 페이지 하나, 페이지 안에서 금액 선택' 방식이라면 SKU 대신 상품 단위로 동기화하세요. GET/api/v1/products는 상품 목록을 반환하며, 각 상품에는 구매할 수 있는 모든 SKU가 들어 있습니다.

HTTP
GET /api/v1/products?brand=Steam&region=GB&limit=50&offset=0

필터와 페이지 처리는 GET/api/v1/skus와 같습니다. count는 상품 수, sku_count는 그 SKU 수입니다.

JSON
{
  "count": 1,
  "sku_count": 4,
  "limit": 50,
  "results": [
    {
      "product_id": "P000123",
      "product_name": "Steam Wallet UK",
      "brand": "Steam",
      "category": "Gaming",
      "region": "GB",
      "product_type": "pin_code",
      "image_url": "https://b2b.cardv.net/api/v1/catalog-assets/steam.png",
      "required_input_schema": [],
      "skus": [
        {
          "sku_id": "S000456",
          "name": "Steam Wallet 5 GBP",
          "label": "5 GBP",
          "denomination_type": "fixed",
          "denomination_value": "5",
          "face_currency": "GBP",
          "merchant_price": "7.61",
          "settlement_currency": "USD",
          "availability": "available",
          "min_quantity": 1,
          "max_quantity": 100,
          "...": "more fields"
        }
      ]
    }
  ],
  "filter_options": {"brands": [], "regions": [], "categories": [], "verticals": []}
}

GET/api/v1/products/{product_id}는 상품 하나와 그 SKU, 그리고 description, redemption_instructions, terms, disclaimer를 반환합니다.

  • skus 안의 각 SKU는 GET/api/v1/skus와 필드와 값이 모두 같습니다. 견적과 주문은 평소처럼 sku_id로 합니다.
  • 선택지 문구는 label을 쓰세요. 예: 5 GBP, Tinder Plus 1 Month. 금액이 아니라 요금제인 상품도 있습니다.
  • 한 상품의 액면 통화와 금액 유형은 하나뿐입니다. 범위 금액 SKU는 항상 별도 상품입니다.
  • 목록에는 긴 설명이 빠져 있습니다. 상품마다 GET/api/v1/products/{product_id}에서 한 번 읽으세요.

#고정 금액과 범위 금액

대부분의 SKU는 10 USD처럼 액면가가 고정되어 있습니다. 일부 SKU는 5~500 USD처럼 범위 안에서 고객이 금액을 정합니다.

유형가격 조회 시주문 시
fixedquantity를 보냄amount는 보내지 않음
rangequantity와 amount를 보냄amount를 보냄

범위 금액 SKU에서 amount는 min_face_value 이상 max_face_value 이하여야 합니다. 단위는 face_currency입니다.

범위 금액 SKU의 가격. SKU 목록과 상품 목록의 merchant_price와 price_label은 min_face_value 금액의 가격일 뿐입니다. merchant_price_min과 merchant_price_max는 최소 금액과 최대 금액의 가격입니다. 그 사이 금액의 가격은 어느 쪽의 단순한 배수도 아닙니다. 판매 가격을 정하거나 주문하기 전에 정확한 amount로 견적을 받고, 그 견적의 merchant_price를 expected_unit_price로 보내세요.

일부 범위 금액 SKU에는 amount_step도 있습니다. 값이 null이 아니면 amount는 그 배수여야 합니다. 예를 들어 "amount_step": "1"이면 25는 보낼 수 있지만 25.50은 보낼 수 없습니다. 단위에 맞지 않는 금액으로 견적이나 주문을 요청하면 HTTP 400이 반환되며, 결제되지 않습니다.

#직접 충전

일부 상품은 게임 계정처럼 고객의 계정에 바로 충전됩니다. 이런 상품은 CardV가 충전할 계정 정보가 필요하며, 필요한 항목은 SKU에 나와 있습니다.

JSON
"required_input_schema": [
  {"key": "player_id", "label": "Player ID", "type": "text", "required": true},
  {"key": "server", "label": "Server", "type": "text", "required": false}
]

주문 항목의 inputs에 각 key별로 값을 넣어 보냅니다.

JSON
"inputs": {"player_id": "123456789", "server": "EU"}
  • "required": false라고 표시되지 않은 항목은 모두 필수입니다. type은 입력 폼 필드 종류에 대한 힌트입니다(예: text).
  • 필수 값이 빠지면 items 오류와 함께 주문이 거절됩니다.
  • 이 값은 고객의 개인정보입니다. 안전하게 보호하세요(보안 참고).

#가격 조회

가격 조회를 하면 원하는 수량의 현재 가격을 알 수 있습니다.

HTTP
GET /api/v1/skus/S000456/quote?quantity=2
GET /api/v1/skus/S000789/quote?quantity=1&amount=25.00
JSON
{
  "sku_id": "S000456",
  "settlement_currency": "USD",
  "merchant_price": "9.25",
  "quantity": 2,
  "total_price": "18.50",
  "min_quantity": 1,
  "max_quantity": 100,
  "availability": "available"
}
  • 조회한 가격이 보장되지는 않습니다. 가격은 언제든 바뀔 수 있습니다.
  • 가격 조회는 고객이 결제할 때 한 번만, 5초 정도의 짧은 타임아웃으로 하세요. 시간이 초과되면 동기화한 가격을 계속 보여 주고 다시 시도하세요. 조회가 느리다는 이유로 오류 페이지를 보여 주면 안 됩니다.
  • 주문할 때 조회한 merchant_price를 expected_unit_price로 함께 보내세요. 직접 계산한 가격이 아니라 조회에서 받은 가격을 보내세요. 센트 단위까지 정확히 일치해야 합니다. 그 사이 가격이 바뀌었다면 CardV가 주문을 거절하고 결제하지 않습니다.
  • 수량이나 금액이 허용 범위를 벗어나거나 금액이 amount_step의 배수가 아니면HTTP 400과 함께 quantity 또는 amount 오류가 반환됩니다.

#주문하기

POST/api/v1/orders로 SKU를 하나 이상 구매하며, 대금은 지갑에서 결제됩니다. 다른 모든 요청처럼 이 요청에도 서명이 필요합니다.

JSON
{
  "external_order_id": "SHOP-20260929-10001",
  "items": [
    {"sku_id": "S000456", "quantity": 2, "expected_unit_price": "9.25"},
    {"sku_id": "S000789", "amount": "25.00", "expected_unit_price": "23.75"},
    {
      "sku_id": "S000900",
      "expected_unit_price": "4.90",
      "inputs": {"player_id": "123456789"}
    }
  ]
}
필드필수 여부의미
external_order_id필수자체 주문번호, 1~120자. 중복될 수 없습니다.
items필수주문 항목. 하나 이상 넣습니다.
items[].sku_id필수구매할 SKU입니다.
items[].quantity선택수량. 기본값은 1입니다.
items[].amount범위 금액 SKU만구매할 액면가입니다. min_face_value, max_face_value, amount_step에 맞아야 합니다.
items[].expected_unit_price권장조회한 merchant_price. 항상 보내세요.
items[].inputs직접 충전 상품만직접 충전에 필요한 계정 정보입니다.

CardV가 주문을 접수하면 총액 전체를 지갑에서 한 번에 결제합니다. 그다음 상품 발급은 백그라운드에서 진행됩니다.

응답은 HTTP 201입니다.

JSON
{
  "idempotent_replay": false,
  "order": {
    "order_id": "O-00001234",
    "external_order_id": "SHOP-20260929-10001",
    "status": "accepted",
    "total_amount": "46.20",
    "...": "more fields"
  }
}

order.order_id를 저장하세요. 이 응답에는 코드가 들어 있지 않습니다. 코드는 나중에 따로 조회합니다(주문 조회 참고).

#주문 거절

거절된 주문은 HTTP 400을 반환하며, 결제되지 않습니다. 거절 이유는 오류 키로 알 수 있습니다.

키원인해결 방법
items가격 변경, 판매 중지된 SKU, 잘못된 금액, 필수 정보 누락가격을 다시 조회하고 고친 뒤 다시 보내세요
balance지갑 잔액 부족포털에서 지갑을 충전하세요
risk주문당 한도 또는 일일 한도 초과CardV에 문의하세요
external_order_id자체 주문번호가 이미 다른 주문에 쓰임안전한 재시도를 참고하세요

가격이 바뀐 경우의 예:

JSON
{
  "items": "SKU S000456 price changed from 9.25 to 9.41 USD; refresh quote and confirm again."
}

계정에는 주문 1건 금액, 하루 결제 금액, 하루 주문 건수 한도가 있습니다. GET/api/v1/account의 purchase_limits에서 한도와 오늘 사용량을 확인할 수 있습니다. 0은 한도가 없다는 뜻입니다. 일일 한도는 매일 00:00(UTC)에 초기화됩니다.

#안전한 재시도

자체 주문번호(external_order_id)가 있으면 같은 주문이 두 번 결제되는 일을 막을 수 있습니다. 같은 주문번호로 같은 주문을 다시 보내면 CardV는 다시 결제하지 않고, 이미 있는 주문을 그대로 돌려줍니다.

보낸 요청결과
새 주문번호HTTP 201. 새 주문이 생성되고 지갑에서 결제됩니다.
같은 주문번호, 같은 주문 내용HTTP 200과 "idempotent_replay": true. 기존 주문이 반환되며 결제되지 않습니다.
같은 주문번호, 다른 주문 내용external_order_id에 대한 HTTP 400. 아무 일도 일어나지 않습니다.

"같은 주문 내용"이란 항목의 순서, SKU, 수량, 금액, 입력값이 모두 같다는 뜻입니다. expected_unit_price를 보낸다면 처음 주문할 때의 가격과 같아야 합니다.

중복 주문 여부는 잔액과 가격을 확인하기 전에 판단합니다. 따라서 그 사이 가격이 바뀌었더라도 항상 처음 주문이 반환됩니다.

#안전한 재시도 절차

결과를 확실히 모르겠다면 같은 주문을 그대로 다시 보내면 됩니다.

Text
주문번호 R로 POST /orders 전송
 ├─ 201 또는 200 → order_id를 저장합니다. 끝.
 ├─ 400 items / balance / risk → 주문이 생성되지 않았습니다.
 │      원인을 해결하고 다시 보냅니다. R을 그대로 써도 됩니다.
 ├─ 400 external_order_id → R은 다른 주문에 쓰인 번호입니다. 멈추고 확인하세요.
 ├─ 403 서명 오류 → 다시 서명해서 같은 본문을 보냅니다.
 ├─ 429 → Retry-After만큼 기다린 뒤 다시 서명해서 같은 본문을 보냅니다.
 └─ 타임아웃, 5xx, 연결 끊김
        → 같은 R로 같은 본문을 다시 보냅니다.
          201이면 첫 요청이 도착하지 않은 것이고, 200이면 도착했던 것입니다.

규칙:

  • 응답을 받지 못했다고 새 주문번호를 만들면 안 됩니다. 첫 요청이 실제로 도착했다면, 새 번호로 보낸 주문 때문에 같은 상품을 두 번 사게 됩니다.
  • 다시 보낼 때마다 타임스탬프, nonce, 서명은 새로 만들고, 본문은 그대로 둡니다.

#주문 조회

GET/api/v1/orders/{order_id}는 주문 정보와 상태, 코드를 반환합니다.

JSON
{
  "order_id": "O-00001234",
  "external_order_id": "SHOP-20260929-10001",
  "status": "succeeded",
  "currency": "USD",
  "total_amount": "18.50",
  "created_at": "2026-09-29T08:15:30.123456Z",
  "updated_at": "2026-09-29T08:15:41.004211Z",
  "items": [
    {
      "sku_id": "S000456",
      "product_name": "Steam Wallet US",
      "quantity": 2,
      "unit_price": "9.25",
      "total_price": "18.50",
      "delivery_count": 2,
      "deliveries": [{"...": "see Codes below"}]
    }
  ],
  "...": "more fields"
}
  • total_amount는 주문이 접수될 때 결제된 금액입니다.
  • items[].unit_price는 이 주문에 확정된 개당 가격입니다.
  • items[].deliveries에는 전체 코드가 들어 있습니다. 응답 전체를 비밀 정보로 다루세요.
  • invoice_url과 delivery_file_url은 인보이스와 코드 CSV 파일의 경로입니다. 둘 다 포털 전용이므로 API 키로 호출하면 HTTP 403이 반환됩니다.
  • 이 밖에 id(예전 번호이니 쓰지 마세요), events(화면 표시용 이력), 항목별 발급 진행 상황도 반환됩니다. 무시해도 됩니다.
  • 없는 주문 ID를 조회하면 HTTP 404가 반환됩니다.

#주문 상태와 코드

#주문 상태

Text
accepted ──► processing ──► succeeded
                  │
                  ├──► partially_succeeded   (일부 항목만 발급됨)
                  │
                  └──► failed ──► refunded   (지갑으로 환불됨)
상태완료 여부할 일
accepted아니요기다립니다. 지갑 결제는 끝났고 발급은 아직 시작되지 않았습니다.
processing아니요기다립니다. 같은 주문을 다시 넣지 마세요.
succeeded예코드를 받아 고객에게 전달합니다.
partially_succeeded예발급된 코드만 전달합니다. 나머지는 나중에 환불됩니다.
failed아직 아님refunded가 될 때까지 기다립니다. 실패했다고 바로 환불된 것은 아닙니다.
refunded예대금이 지갑으로 돌아왔습니다.

Webhook을 쓰지 않는다면 다음 간격으로 조회하세요. 5초 후, 10초, 30초, 60초 후, 그다음부터는 5분마다. 요청 한도를 넘지 않도록 주의하세요. 대부분의 주문은 몇 초 안에 끝나지만, 수동 확인이 필요한 주문은 몇 시간 걸릴 수 있습니다.

#코드

발급된 상품 1개는 items[].deliveries 안의 객체 하나입니다.

JSON
{
  "status": "stored",
  "delivery_type": "card_pin",
  "card_number": "X1234",
  "pin_code": "9876",
  "redeem_url": "",
  "expiry_date": "2027-09-29",
  "instructions": "Redeem at ..."
}
필드설명
card_number주 코드: 카드 번호, 바우처 코드 또는 PIN입니다.
pin_code두 번째 코드(PIN, 보안 코드 등)입니다. 없으면 비어 있습니다.
redeem_url교환 링크입니다. link 형태는 링크 자체가 코드입니다.
expiry_date코드를 사용할 수 있는 마지막 날이며 형식은 YYYY-MM-DD입니다. ""는 공급사가 유효기간을 제공하지 않았다는 뜻이며, 코드가 만료되었다는 뜻이 아닙니다.
  • 비어 있지 않은 필드는 모두 고객에게 전달하세요. card_number, pin_code, redeem_url, expiry_date, instructions.
  • delivery_type은 받은 코드의 형태입니다. code, card_pin, link, code_link, qr 중 하나입니다.
  • redeem_url도 코드처럼 비밀로 관리하세요.
  • expiry_date가 비어 있다는 이유로 코드를 삭제하거나 숨기거나 무효화하지 마세요. 유효기간은 비어 있지 않을 때만 고객에게 표시하세요.
  • status가 voided인 코드는 절대 고객에게 전달하지 마세요.
  • 직접 충전 상품은 보통 발급 코드가 없습니다. succeeded는 계정 충전이 끝났다는 뜻입니다.
  • Webhook에는 코드가 절대 들어 있지 않습니다. Webhook을 받은 뒤 주문을 조회하세요.

연동 관련 문의는 Merchant ID와 주문 ID 또는 요청 ID를 포함해 [email protected]로 보내 주세요.