API 이용 안내

KPC 허브 포인트를 외부 서비스(투표시스템, 영상부스, 쇼핑몰 등)에서 결제수단으로 사용하려면 아래 API로 연동합니다. API Key/Secret 발급은 협업 문의를 통해 받으실 수 있습니다.

1. 인증 방식

모든 요청에 아래 3개 헤더가 필요합니다.

X-API-Key: kpch_xxxxxxxxxxxxxxxx
X-Timestamp: 1737000000        (현재 UNIX 타임스탬프, 5분 이내만 허용)
X-Signature: HMAC-SHA256(secret, "{timestamp}.{body}")

body는 POST 요청은 raw JSON 문자열, GET 요청은 쿼리스트링(예: code=xxxx)입니다. 서명은 반드시 hash_hmac('sha256', "{timestamp}.{body}", secret)와 동일한 방식으로 생성해야 합니다.

2. 결제요청 생성

POST https://kpchub.ginienm.com/api/payments_create.php

요청 본문(JSON):

{
  "merchant_order_id": "order-1234",   // 가맹점 측 주문번호(고유값, 1~100자)
  "amount": 21.69,                      // 포인트 금액(1~10,000,000, 소수점 4자리까지 허용)
  "item_name": "유기농 아카시아 꿀 500g" // 선택, 실제 상품/서비스명 권장(아래 참고)
}

item_name은 결제확인화면(pay_url)과 웹훅 페이로드에 그대로 노출됩니다. "주문 order-1234"처럼 가맹점명+주문번호만 넣지 말고, 사용자가 뭘 결제하는지 알 수 있는 실제 상품/서비스명을 넣어주세요(주문에 상품이 여러 개면 "상품명 외 N건" 형태를 권장).

응답:

{
  "success": true,
  "data": {
    "payment_code": "a1b2c3...",          // 40자 — QR/URL용
    "short_code": "A3F7K2M9",             // 8자 — 화면 표시·수동입력용(아래 5번 참고)
    "pay_url": "https://kpchub.ginienm.com/pay.php?code=a1b2c3...",
    "qr_text": "https://kpchub.ginienm.com/pay.php?code=a1b2c3...",
    "status": "pending",
    "expires_at": "2026-09-15 12:10:00",
    "idempotent_replay": false
  }
}

같은 merchant_order_id로 다시 요청하면 새로 만들지 않고 기존 결제를 그대로 반환합니다(멱등성 보장). 단, 그 사이 결제 유효시간(10분)이 지났다면 같은 요청 안에서 자동으로 새 코드로 갱신해서 돌려줍니다(idempotent_replay: false, refreshed: true로 구분) — 만료됐다고 결제가 영구히 막히지 않으니, 화면에서 남은 시간을 보여주다가 0이 되면 이 API를 같은 merchant_order_id로 다시 호출 + 새로고침하는 방식을 권장합니다. pay_url을 QR코드로 만들어 보여주면 사용자가 KPC 허브 앱에서 스캔해 결제합니다.

3. 결제상태 조회

GET https://kpchub.ginienm.com/api/payments_status.php?code=xxxx

서명 대상 문자열은 "code=xxxx"입니다. 웹훅을 못 받았을 때 재확인용으로 사용하세요.

{
  "success": true,
  "data": {
    "payment_code": "a1b2c3...",
    "short_code": "A3F7K2M9",
    "merchant_order_id": "order-1234",
    "amount": 21.69,
    "item_name": "유기농 아카시아 꿀 500g",
    "status": "completed",   // pending | completed | expired | cancelled
    "paid_at": "2026-09-15 12:05:00",
    "expires_at": "2026-09-15 12:10:00"
  }
}

status가 pending인데 expires_at이 이미 지났다면, 이 API를 호출하는 시점에 서버가 자동으로 expired로 반영합니다(별도 처리 불필요) — 화면은 2번의 재요청으로 새 코드를 받아 이어가면 됩니다.

4. 웹훅(결제 완료 통보)

결제 상태가 바뀌면 등록하신 콜백 URL로 KPC 허브가 아래 형식으로 POST합니다.

POST {callback_url}
Content-Type: application/json
X-Signature: HMAC-SHA256(secret, "{timestamp}.{body}")
X-Timestamp: 1737000000

{
  "event": "payment.completed",         // payment.{status} — completed | expired | cancelled
  "payment_code": "a1b2c3...",
  "merchant_order_id": "order-1234",
  "amount": 21.69,
  "item_name": "유기농 아카시아 꿀 500g",
  "status": "completed",
  "paid_at": "2026-09-15 12:05:00"
}

수신 측은 동일한 방식으로 서명을 재계산해 X-Signature와 비교(반드시 hash_equals 등 타이밍 공격에 안전한 방식 사용) 검증해야 합니다. 2xx 응답을 주지 않으면 실패로 기록되고 자동으로 최대 5회까지 재시도합니다. 200~299 외 응답이거나 타임아웃이면 실패 처리됩니다. 결제 유효시간이 지나 자동 만료됐을 때도(가맹점이 새로고침으로 재요청해서 이어가는 것과 별개로) payment.expired 웹훅이 한 번 옵니다 — 재고 복원 등 파괴적인 동작은 이 이벤트만으로 하지 말고, 실제로 그 주문을 포기했는지(2번 API로 재요청하지 않는지)까지 가맹점 쪽에서 판단하세요.

5. 결제 코드 화면 표시(카메라 안 될 때 수동 입력용)

pay_url을 QR로 보여주는 것과 별개로, 카메라를 못 쓰는 사용자를 위해 short_code (8자, 대문자+숫자, 혼동되는 0/O·1/I/L 제외)를 QR 아래에 큼직하게 같이 보여주는 것을 권장합니다. 사용자가 KPC 허브 앱의 QR 스캔 화면에서 이 코드를 직접 입력하면 카메라 없이도 결제를 진행할 수 있습니다. 40자 payment_code는 QR/URL 생성에만 쓰고 화면에 그대로 노출하지 마세요 (손으로 입력하기엔 너무 깁니다).

<img src="{QR로 렌더링한 pay_url}">
<p>카메라가 작동하지 않으면 결제 코드를 직접 입력하세요:<br>
   <code>{short_code}</code></p>

6. 서명 생성 예시 (PHP)

$timestamp = (string) time();
$body = json_encode(['merchant_order_id' => 'order-1234', 'amount' => 1000]);
$signature = hash_hmac('sha256', $timestamp . '.' . $body, $apiSecret);

$ch = curl_init('https://kpchub.ginienm.com/api/payments_create.php');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-API-Key: ' . $apiKey,
        'X-Timestamp: ' . $timestamp,
        'X-Signature: ' . $signature,
    ],
    CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);

추가 문의는 협업 문의로 남겨주세요.