발급 관리
PIN 발급과 쿠폰 발송에 공통으로 적용되는 조회, 취소, 재발송, 이미지 조회 API를 설명합니다.
발급 상태 라이프사이클
쿠폰의 상태는 다음과 같이 전이됩니다.
쿠폰 상태
| 상태 | 설명 |
|---|---|
PENDING | 발급 처리 중 |
ISSUED | 발급 완료, 사용 가능 |
USED | 사용 완료 |
CANCELED | 취소됨 |
EXPIRED | 유효기간 만료 |
INACTIVE | 비활성 (벤더 측 이상) |
FAIL | 발급 실패 |
메시지 상태 (SEND 타입만 해당)
| 상태 | 설명 |
|---|---|
PENDING | 발송 대기 중 |
REQUESTED | 벤더에 발송 요청됨 |
SENT | 발송 완료 |
FAILED | 발송 실패 |
RESENT | 재발송 완료 |
발급 조회
/v1/coupons/issued발급 결과를 조회합니다. id 또는 orderId 중 하나를 지정해야 합니다. PIN 발급과 쿠폰 발송 모두 이 엔드포인트로 조회합니다.
Query Parameters
idstring발급 ID. iss_ 접두사로 시작합니다.
orderIdstring발급 시 전달한 고객사 주문 ID
imageTtlDaysinteger응답에 포함되는 이미지 URL의 유효기간(일). 기본 1일, 최대 365일.기본값: 1
id와 orderId 중 정확히 하나만 지정해야 합니다. 둘 다 지정하거나 둘 다 생략하면 400 에러가 반환됩니다.
Response Body
idstring필수발급 식별자 (iss_ 접두사)
couponIdstring필수쿠폰 식별자
orderIdstring | null필수고객사 주문 ID
orderNumberstring필수고객 응대용 주문 번호
typestring필수발급 유형
PINSENDcouponobject필수쿠폰 상태 정보
statusstring필수쿠폰 상태
PENDINGISSUEDUSEDCANCELEDEXPIREDINACTIVEFAILpinNumberstring | null필수PIN/바코드 번호
validityobject | null필수쿠폰 유효기간
fromstring | null필수유효 시작일 (KST, YYYY-MM-DD)
tostring | null필수유효 종료일 (KST, YYYY-MM-DD)
reasonstring | null필수취소 또는 발급 실패 사유
issuedAtstring | null필수발급 완료 시각 (ISO 8601)
usedAtstring | null필수사용 시각 (ISO 8601)
canceledAtstring | null필수취소 시각 (ISO 8601)
messageobject | null필수메시지 발송 정보. PIN 타입에서는 null입니다.
statusstring필수메시지 발송 상태
PENDINGREQUESTEDSENTFAILEDRESENTtitlestring | null필수메시지 제목
contentstring | null필수메시지 본문
senderNumberstring | null필수발신번호
receiverNumberstring | null필수수신자 전화번호
receiverNamestring | null필수수신자 이름
reasonstring | null필수메시지 발송 실패 사유
sentAtstring | null필수발송 시각 (ISO 8601)
imageUrlstring | null필수Pre-signed 이미지 URL. PIN 타입에서만 제공되며, 브라우저나 <img> 태그에서 인증 없이 직접 사용할 수 있습니다. imageTtlDays에 따라 유효기간이 설정됩니다.
createdAtstring필수발급 요청 시각 (ISO 8601)
요청 예시
- cURL
- Node.js
- Python
- Java
# id로 조회
curl -u "test_sk_your_key_here:" \
"https://api.aiconbiz.kr/v1/coupons/issued?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"
# orderId로 조회
curl -u "test_sk_your_key_here:" \
"https://api.aiconbiz.kr/v1/coupons/issued?orderId=ORD-20260318-0001"
const secretKey = 'test_sk_your_key_here';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const res = await fetch(
'https://api.aiconbiz.kr/v1/coupons/issued?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a',
{ headers: { 'Authorization': `Basic ${encoded}` } },
);
const data = await res.json();
console.log(data.type); // PIN or SEND
console.log(data.coupon.status); // ISSUED, CANCELED, USED, ...
import base64
import requests
secret_key = "test_sk_your_key_here"
encoded = base64.b64encode(f"{secret_key}:".encode()).decode()
res = requests.get(
"https://api.aiconbiz.kr/v1/coupons/issued",
headers={"Authorization": f"Basic {encoded}"},
params={"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"},
)
data = res.json()
print(data["type"]) # PIN or SEND
print(data["coupon"]["status"]) # ISSUED, CANCELED, USED, ...
import java.net.URI;
import java.net.http.*;
import java.util.Base64;
String secretKey = "test_sk_your_key_here";
String encoded = Base64.getEncoder()
.encodeToString((secretKey + ":").getBytes());
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://api.aiconbiz.kr/v1/coupons/issued?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"))
.header("Authorization", "Basic " + encoded)
.GET()
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
응답 예시 (PIN 타입)
{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"couponId": "cpn_01JNX8D7W7F6J0QYJ7YQ6G7M2R",
"orderId": "ORD-20260318-0001",
"orderNumber": "123456789012",
"type": "PIN",
"coupon": {
"status": "ISSUED",
"pinNumber": "1234-5678-9012",
"validity": {
"from": "2026-03-18",
"to": "2026-04-17"
},
"reason": null,
"issuedAt": "2026-03-18T03:00:03.000+09:00",
"usedAt": null,
"canceledAt": null
},
"message": null,
"imageUrl": "https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a&expires=1711411200&sig=a1b2c3d4...",
"createdAt": "2026-03-18T03:00:00.000+09:00"
}
응답 예시 (SEND 타입)
{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"couponId": "cpn_01JNX8D7W7F6J0QYJ7YQ6G7M2R",
"orderId": "ORD-20260323-0001",
"orderNumber": "123456789012",
"type": "SEND",
"coupon": {
"status": "ISSUED",
"pinNumber": null,
"validity": {
"from": "2026-03-23",
"to": "2026-04-22"
},
"reason": null,
"issuedAt": "2026-03-23T03:00:03.000+09:00",
"usedAt": null,
"canceledAt": null
},
"message": {
"status": "SENT",
"title": "쿠폰이 도착했습니다",
"content": "회원가입을 축하합니다!",
"senderNumber": "01011112222",
"receiverNumber": "01012345678",
"receiverName": "홍길동",
"reason": null,
"sentAt": "2026-03-23T03:00:05.000+09:00"
},
"imageUrl": null,
"createdAt": "2026-03-23T03:00:00.000+09:00"
}
에러 응답
| 코드 | HTTP | 설명 |
|---|---|---|
COUPON_INVALID_ISSUANCE_ID | 400 | 발급 ID 형식이 올바르지 않습니다. |
COUPON_ISSUANCE_NOT_FOUND | 404 | 발급 내역을 찾을 수 없습니다. |
이 외에 인증, 요청 형식 관련 공통 에러가 발생할 수 있습니다.
발급 취소
/v1/coupons/issued/cancel발급 또는 발송된 쿠폰을 취소합니다. id 또는 orderId 중 하나를 지정해야 합니다. ISSUED 상태인 쿠폰만 취소할 수 있습니다.
Request Body
요청 파라미터
idstring발급 ID. iss_ 접두사로 시작합니다.
orderIdstring발급 시 전달한 고객사 주문 ID
reasonstring필수취소 사유. 최소 1자, 최대 500자.
id와 orderId 중 정확히 하나만 지정해야 합니다. 둘 다 지정하거나 둘 다 생략하면 400 에러가 반환됩니다.
Response Body
idstring필수취소된 발급 식별자
canceledAtstring필수취소 처리 시각 (ISO 8601)
요청 예시
- cURL
- Node.js
- Python
- Java
# id로 취소
curl -X POST https://api.aiconbiz.kr/v1/coupons/issued/cancel \
-u "test_sk_your_key_here:" \
-H "Content-Type: application/json" \
-d '{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"reason": "고객 요청에 의한 취소"
}'
# orderId로 취소
curl -X POST https://api.aiconbiz.kr/v1/coupons/issued/cancel \
-u "test_sk_your_key_here:" \
-H "Content-Type: application/json" \
-d '{
"orderId": "ORD-20260318-0001",
"reason": "고객 요청에 의한 취소"
}'
const secretKey = 'test_sk_your_key_here';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const res = await fetch('https://api.aiconbiz.kr/v1/coupons/issued/cancel', {
method: 'POST',
headers: {
'Authorization': `Basic ${encoded}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: 'iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a',
reason: '고객 요청에 의한 취소',
}),
});
const data = await res.json();
console.log(data.canceledAt); // 2026-03-18T12:00:00.000Z
import base64
import requests
secret_key = "test_sk_your_key_here"
encoded = base64.b64encode(f"{secret_key}:".encode()).decode()
res = requests.post(
"https://api.aiconbiz.kr/v1/coupons/issued/cancel",
headers={
"Authorization": f"Basic {encoded}",
"Content-Type": "application/json",
},
json={
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"reason": "고객 요청에 의한 취소",
},
)
data = res.json()
print(data["canceledAt"]) # 2026-03-18T12:00:00.000Z
import java.net.URI;
import java.net.http.*;
import java.util.Base64;
String secretKey = "test_sk_your_key_here";
String encoded = Base64.getEncoder()
.encodeToString((secretKey + ":").getBytes());
String body = """
{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"reason": "고객 요청에 의한 취소"
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.aiconbiz.kr/v1/coupons/issued/cancel"))
.header("Authorization", "Basic " + encoded)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
응답 예시
{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"canceledAt": "2026-03-18T12:00:00.000Z"
}
에러 응답
| 코드 | HTTP | 설명 |
|---|---|---|
COUPON_INVALID_ISSUANCE_ID | 400 | 발급 ID 형식이 올바르지 않습니다. |
COUPON_ISSUANCE_NOT_FOUND | 404 | 발급 내역을 찾을 수 없습니다. |
COUPON_ALREADY_CANCELED | 409 | 이미 취소된 쿠폰입니다. |
COUPON_NOT_CANCELABLE | 409 | 취소할 수 없는 상태입니다. |
COUPON_CANCEL_VENDOR_FAILED | 502 | 쿠폰 취소에 실패했습니다. |
이 외에 인증, 요청 형식 관련 공통 에러가 발생할 수 있습니다.
메시지 재발송
/v1/coupons/issued/resend발송 실패 또는 발급 완료 상태인 쿠폰을 재발송합니다. id 또는 orderId 중 하나를 지정해야 합니다. SEND 타입의 발급 건에만 사용할 수 있습니다.
Request Body
요청 파라미터
idstring발급 ID. iss_ 접두사로 시작합니다.
orderIdstring발급 시 전달한 고객사 주문 ID
id와 orderId 중 정확히 하나만 지정해야 합니다. 둘 다 지정하거나 둘 다 생략하면 400 에러가 반환됩니다.
Response Body
issuanceIdstring필수발급 식별자
resentAtstring필수재발송 시각 (ISO 8601)
요청 예시
- cURL
- Node.js
- Python
- Java
curl -X POST https://api.aiconbiz.kr/v1/coupons/issued/resend \
-u "test_sk_your_key_here:" \
-H "Content-Type: application/json" \
-d '{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"
}'
const secretKey = 'test_sk_your_key_here';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const res = await fetch('https://api.aiconbiz.kr/v1/coupons/issued/resend', {
method: 'POST',
headers: {
'Authorization': `Basic ${encoded}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: 'iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a',
}),
});
const data = await res.json();
console.log(data.resentAt); // 2026-03-23T15:30:00.000Z
import base64
import requests
secret_key = "test_sk_your_key_here"
encoded = base64.b64encode(f"{secret_key}:".encode()).decode()
res = requests.post(
"https://api.aiconbiz.kr/v1/coupons/issued/resend",
headers={
"Authorization": f"Basic {encoded}",
"Content-Type": "application/json",
},
json={
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
},
)
data = res.json()
print(data["resentAt"]) # 2026-03-23T15:30:00.000Z
import java.net.URI;
import java.net.http.*;
import java.util.Base64;
String secretKey = "test_sk_your_key_here";
String encoded = Base64.getEncoder()
.encodeToString((secretKey + ":").getBytes());
String body = """
{
"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.aiconbiz.kr/v1/coupons/issued/resend"))
.header("Authorization", "Basic " + encoded)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(
request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
응답 예시
{
"issuanceId": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a",
"resentAt": "2026-03-23T15:30:00.000Z"
}
에러 응답
| 코드 | HTTP | 설명 |
|---|---|---|
COUPON_INVALID_ISSUANCE_ID | 400 | 발급 ID 형식이 올바르지 않습니다. |
COUPON_ISSUANCE_NOT_FOUND | 404 | 발급 내역을 찾을 수 없습니다. |
COUPON_RESEND_NOT_ALLOWED | 409 | 재발송할 수 없는 상태입니다. |
COUPON_RESEND_VENDOR_FAILED | 502 | 재발송에 실패했습니다. |
이 외에 인증, 요청 형식 관련 공통 에러가 발생할 수 있습니다.
발급 이미지 조회
/v1/coupons/issued/image발급된 쿠폰의 이미지를 PNG 형식으로 조회합니다. 두 가지 인증 방식을 지원합니다.
발급 직후에는 이미지 생성에 수 초가 소요될 수 있습니다. 아직 생성되지 않은 경우 404를 반환합니다.
인증 방식
이 엔드포인트는 두 가지 인증 방식을 지원합니다. 용도에 따라 적합한 방식을 선택하세요.
| Basic Auth | Pre-signed URL | |
|---|---|---|
| 인증 방법 | Authorization 헤더에 API 키 | URL에 expires + sig 쿼리 파라미터 포함 |
| 용도 | 서버에서 이미지 다운로드 | 브라우저 / <img> 태그 / 앱에서 직접 표시 |
| API 키 노출 | 서버 측에서만 사용 (안전) | 불필요 (URL 자체가 인증) |
| 유효기간 | API 키가 유효한 동안 | expires에 지정된 시각까지 |
방식 1: Basic Auth (서버 간 통신)
기존 API 키 인증 방식입니다. 서버에서 이미지를 다운로드하여 저장하거나 가공할 때 사용합니다.
GET /v1/coupons/issued/image?id=iss_xxx
Authorization: Basic {base64(secretKey:)}
방식 2: Pre-signed URL (브라우저 / 프론트엔드)
발급 조회 응답의 imageUrl 필드에 포함된 URL을 그대로 사용합니다. 인증 헤더가 필요 없으므로 <img> 태그, 브라우저 주소창 등에서 바로 이미지를 표시할 수 있습니다.
<!-- 발급 조회 응답의 imageUrl을 그대로 사용 -->
<img src="https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_xxx&expires=1711411200&sig=a1b2c3d4..." />
imageUrl의 유효기간은 발급 조회 시 imageTtlDays 파라미터로 설정할 수 있습니다 (기본 1일, 최대 365일). 만료된 URL로 접근하면 401 에러가 반환됩니다. 필요하면 발급 조회를 다시 호출하여 새 URL을 받으세요.
Query Parameters
idstring발급 ID. iss_ 접두사로 시작합니다.
orderIdstring발급 시 전달한 고객사 주문 ID
expiresstringPre-signed URL 만료 시각 (Unix timestamp). Pre-signed URL 방식에서만 사용합니다.
sigstringPre-signed URL 서명. Pre-signed URL 방식에서만 사용합니다.
id와 orderId 중 정확히 하나만 지정해야 합니다.
Response
- Content-Type:
image/png - Cache-Control:
private, max-age=86400
응답 본문은 PNG 이미지 바이너리입니다.
요청 예시 — Basic Auth
- cURL
- Node.js
- Python
- Java
curl -u "test_sk_your_key_here:" \
"https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a" \
--output coupon-image.png
import { writeFile } from 'fs/promises';
const secretKey = 'test_sk_your_key_here';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const res = await fetch(
'https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a',
{ headers: { 'Authorization': `Basic ${encoded}` } },
);
const buffer = Buffer.from(await res.arrayBuffer());
await writeFile('coupon-image.png', buffer);
import base64
import requests
secret_key = "test_sk_your_key_here"
encoded = base64.b64encode(f"{secret_key}:".encode()).decode()
res = requests.get(
"https://api.aiconbiz.kr/v1/coupons/issued/image",
headers={"Authorization": f"Basic {encoded}"},
params={"id": "iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"},
)
with open("coupon-image.png", "wb") as f:
f.write(res.content)
import java.net.URI;
import java.net.http.*;
import java.nio.file.*;
import java.util.Base64;
String secretKey = "test_sk_your_key_here";
String encoded = Base64.getEncoder()
.encodeToString((secretKey + ":").getBytes());
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"))
.header("Authorization", "Basic " + encoded)
.GET()
.build();
HttpResponse<Path> response = client.send(
request, HttpResponse.BodyHandlers.ofFile(Path.of("coupon-image.png")));
요청 예시 — Pre-signed URL
발급 조회 응답의 imageUrl을 그대로 사용합니다. 인증 헤더가 필요 없습니다.
- HTML
- cURL
- Node.js
<!-- 발급 조회 응답의 imageUrl을 src에 그대로 사용 -->
<img src="https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a&expires=1711411200&sig=a1b2c3d4..." />
# 인증 헤더 없이 URL만으로 접근
curl "https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a&expires=1711411200&sig=a1b2c3d4..." \
--output coupon-image.png
// 발급 조회로 imageUrl 획득
const secretKey = 'test_sk_your_key_here';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const statusRes = await fetch(
'https://api.aiconbiz.kr/v1/coupons/issued?id=iss_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a&imageTtlDays=30',
{ headers: { 'Authorization': `Basic ${encoded}` } },
);
const { imageUrl } = await statusRes.json();
// imageUrl을 프론트엔드에 전달하면 인증 없이 바로 표시 가능
console.log(imageUrl);
// → https://api.aiconbiz.kr/v1/coupons/issued/image?id=iss_...&expires=...&sig=...
에러 응답
| 코드 | HTTP | 설명 |
|---|---|---|
AUTH_INVALID_PRESIGNED_URL | 401 | 유효하지 않거나 만료된 URL입니다. |
COUPON_INVALID_ISSUANCE_ID | 400 | 발급 ID 형식이 올바르지 않습니다. |
COUPON_ISSUANCE_NOT_FOUND | 404 | 발급 내역을 찾을 수 없습니다. |
COUPON_IMAGE_NOT_READY | 404 | 이미지가 아직 생성되지 않았습니다. |
COUPON_IMAGE_NOT_SUPPORTED | 400 | 이미지를 지원하지 않는 쿠폰입니다. |
이 외에 인증, 요청 형식 관련 공통 에러가 발생할 수 있습니다.