결제 API 연동 가이드
결제 대행 API를 통해 간편하게 카드 결제, 취소, 조회 기능을 연동할 수 있습니다.
가맹점
결제 API
PG사
기본 정보
| Base URL | https://api.multisystem.kr/api/external |
| 요청 형식 | JSON (Content-Type: application/json) |
| 인코딩 | UTF-8 |
| Rate Limit | 분당 60회 (설정에 따라 변동) |
인증
모든 API 요청에는 API Key와 API Secret이 필요합니다.
중요! API Secret은 발급 시 단 한 번만 표시됩니다. 안전한 곳에 보관하세요.
인증 헤더
모든 요청에 아래 헤더를 포함하세요:
X-Api-Key: your_api_key_here X-Api-Secret: your_api_secret_here Content-Type: application/json
API 키 발급받기
API 키는 관리자에게 요청하여 발급받습니다. 발급 시 아래 정보를 받게 됩니다:
- API Key - 64자리 문자열 (공개 키)
- API Secret - 64자리 문자열 (비밀 키, 1회만 표시)
빠른 시작
3단계로 첫 번째 결제를 연동해보세요.
API 키 발급
관리자에게 요청하여 API Key와 Secret을 발급받습니다.
테스트 결제 요청
아래 cURL 명령으로 테스트 결제를 요청합니다.
curl -X POST https://api.multisystem.kr/api/external/payment.php \ -H "Content-Type: application/json" \ -H "X-Api-Key: YOUR_API_KEY" \ -H "X-Api-Secret: YOUR_API_SECRET" \ -d '{ "order_id": "ORDER-001", "customer_name": "홍길동", "customer_phone": "01012345678", "product_name": "테스트 상품", "amount": 1000, "card_no": "1234567890123456", "exp_mm": "12", "exp_yy": "28" }'
응답 확인
결제가 성공하면 아래와 같은 응답을 받습니다.
{
"success": true,
"data": {
"order_id": "ORDER-001",
"transaction_id": 12345,
"approval_no": "64343548",
"amount": 1000,
"status": "APPROVED"
}
}
결제 요청
POST
/payment.php
카드 결제를 요청합니다.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| order_id | string | 필수 | 가맹점 주문번호 (고유값, 최대 100자) |
| customer_name | string | 필수 | 고객명 |
| customer_phone | string | 필수 | 고객 휴대폰번호 (숫자만) |
| product_name | string | 필수 | 상품명 (최대 200자) |
| amount | integer | 필수 | 결제 금액 (원 단위) |
| card_no | string | 필수 | 카드번호 (숫자만, 13-19자리) |
| exp_mm | string | 필수 | 유효기간 월 (01-12) |
| exp_yy | string | 필수 | 유효기간 년 (YY 형식, 예: 28) |
| installment | string | 선택 | 할부개월 (00=일시불, 02-12) |
| customer_email | string | 선택 | 고객 이메일 |
요청 예시
{
"order_id": "ORDER-2024011500001",
"customer_name": "홍길동",
"customer_phone": "01012345678",
"product_name": "프리미엄 구독권 1개월",
"amount": 50000,
"card_no": "1234567890123456",
"exp_mm": "12",
"exp_yy": "28",
"installment": "00"
}
응답
성공 (HTTP 200)
{
"success": true,
"message": "Payment approved successfully",
"data": {
"order_id": "ORDER-2024011500001",
"transaction_id": 12345,
"tid": "TRX64145357194B59295",
"approval_no": "64343548",
"amount": 50000,
"status": "APPROVED",
"card_company": "우리카드",
"card_no_masked": "1234********3456",
"installment": 0,
"approved_at": "2024-01-15T10:30:00+09:00"
},
"timestamp": "2024-01-15T10:30:00+09:00"
}
실패 (HTTP 400)
{
"success": false,
"error": {
"code": "PAYMENT_FAILED",
"message": "카드 한도 초과"
},
"timestamp": "2024-01-15T10:30:00+09:00"
}
결제 취소
POST
/cancel.php
결제를 전액 또는 부분 취소합니다.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| order_id | string | 택1 | 가맹점 주문번호 |
| transaction_id | integer | 택1 | 내부 거래 ID |
| cancel_amount | integer | 선택 | 취소 금액 (미입력 시 전액 취소) |
| reason | string | 선택 | 취소 사유 |
order_id 또는 transaction_id 중 하나는 필수입니다.요청 예시
{
"order_id": "ORDER-2024011500001",
"cancel_amount": 10000,
"reason": "고객 요청"
}
응답
{
"success": true,
"message": "Payment canceled successfully",
"data": {
"order_id": "ORDER-2024011500001",
"original_amount": 50000,
"cancel_amount": 10000,
"total_canceled": 10000,
"remaining": 40000,
"status": "APPROVED",
"is_full_cancel": false,
"canceled_at": "2024-01-15T11:00:00+09:00"
}
}
거래 조회
GET
POST
/inquiry.php
거래를 단건 또는 목록으로 조회합니다.
단건 조회
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| order_id | string | 택1 | 가맹점 주문번호 |
| transaction_id | integer | 택1 | 내부 거래 ID |
| tid | string | 택1 | PG 거래 ID |
목록 조회
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| start_date | string | 선택 | 조회 시작일 (YYYY-MM-DD) |
| end_date | string | 선택 | 조회 종료일 (YYYY-MM-DD) |
| status | string | 선택 | 거래 상태 (APPROVED, CANCELED) |
| page | integer | 선택 | 페이지 번호 (기본: 1) |
| limit | integer | 선택 | 페이지당 개수 (기본: 20, 최대: 100) |
요청 예시
# 단건 조회 GET /api/external/inquiry.php?order_id=ORDER-2024011500001 # 목록 조회 GET /api/external/inquiry.php?start_date=2024-01-01&end_date=2024-01-31&page=1&limit=20
Webhook
결제/취소 완료 시 지정된 URL로 실시간 알림을 받을 수 있습니다.
이벤트 종류
payment.approved |
결제 승인 완료 |
payment.canceled |
결제 취소 완료 |
Webhook 요청 헤더
POST /your-webhook-endpoint Content-Type: application/json X-Webhook-Signature: {hmac_sha256_signature} X-Webhook-Timestamp: {unix_timestamp} X-Webhook-Event: payment.approved
Webhook Payload 예시
{
"event": "payment.approved",
"timestamp": "1705282200",
"data": {
"order_id": "ORDER-2024011500001",
"transaction_id": 12345,
"tid": "TRX64145357194B59295",
"approval_no": "64343548",
"amount": 50000,
"status": "APPROVED"
}
}
서명 검증 (PHP)
// Webhook Secret으로 서명 검증 $payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE']; $secret = 'your_webhook_secret'; $expected = hash_hmac('sha256', $payload, $secret); if (hash_equals($expected, $signature)) { // 유효한 Webhook - 처리 http_response_code(200); } else { // 위조된 요청 http_response_code(401); }
재시도 정책
Webhook 전송 실패 시 최대 3회까지 재시도됩니다 (1분, 5분, 15분 간격).
Webhook 전송 실패 시 최대 3회까지 재시도됩니다 (1분, 5분, 15분 간격).
에러 코드
인증 에러 (HTTP 401, 403)
| 코드 | 설명 |
|---|---|
| AUTH_REQUIRED | 인증 헤더 누락 |
| INVALID_CREDENTIALS | 잘못된 API Key 또는 Secret |
| IP_NOT_ALLOWED | 허용되지 않은 IP |
요청 에러 (HTTP 400)
| 코드 | 설명 |
|---|---|
| INVALID_JSON | 잘못된 JSON 형식 |
| MISSING_REQUIRED_FIELDS | 필수 파라미터 누락 |
| INVALID_AMOUNT | 잘못된 금액 |
| INVALID_CARD_NUMBER | 잘못된 카드번호 |
| DUPLICATE_ORDER_ID | 중복 주문번호 |
| PAYMENT_FAILED | 결제 실패 (PG 응답 참조) |
| CANCEL_FAILED | 취소 실패 |
| ALREADY_CANCELED | 이미 취소된 거래 |
제한 에러 (HTTP 429)
| 코드 | 설명 |
|---|---|
| RATE_LIMIT_EXCEEDED | 분당 요청 한도 초과 |
| DAILY_LIMIT_EXCEEDED | 일일 요청 한도 초과 |
예제 코드
<?php // 결제 요청 예시 $apiKey = 'your_api_key'; $apiSecret = 'your_api_secret'; $url = 'https://api.multisystem.kr/api/external/payment.php'; $data = [ 'order_id' => 'ORDER-' . time(), 'customer_name' => '홍길동', 'customer_phone' => '01012345678', 'product_name' => '테스트 상품', 'amount' => 10000, 'card_no' => '1234567890123456', 'exp_mm' => '12', 'exp_yy' => '28', ]; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'X-Api-Key: ' . $apiKey, 'X-Api-Secret: ' . $apiSecret, ], ]); $response = curl_exec($ch); $result = json_decode($response, true); if ($result['success']) { echo "결제 성공! 승인번호: " . $result['data']['approval_no']; } else { echo "결제 실패: " . $result['error']['message']; }
import requests import time api_key = 'your_api_key' api_secret = 'your_api_secret' url = 'https://api.multisystem.kr/api/external/payment.php' headers = { 'Content-Type': 'application/json', 'X-Api-Key': api_key, 'X-Api-Secret': api_secret, } data = { 'order_id': f'ORDER-{int(time.time())}', 'customer_name': '홍길동', 'customer_phone': '01012345678', 'product_name': '테스트 상품', 'amount': 10000, 'card_no': '1234567890123456', 'exp_mm': '12', 'exp_yy': '28', } response = requests.post(url, json=data, headers=headers) result = response.json() if result['success']: print(f"결제 성공! 승인번호: {result['data']['approval_no']}") else: print(f"결제 실패: {result['error']['message']}")
const axios = require('axios'); const apiKey = 'your_api_key'; const apiSecret = 'your_api_secret'; const url = 'https://api.multisystem.kr/api/external/payment.php'; const data = { order_id: `ORDER-${Date.now()}`, customer_name: '홍길동', customer_phone: '01012345678', product_name: '테스트 상품', amount: 10000, card_no: '1234567890123456', exp_mm: '12', exp_yy: '28', }; axios.post(url, data, { headers: { 'Content-Type': 'application/json', 'X-Api-Key': apiKey, 'X-Api-Secret': apiSecret, } }) .then(response => { const result = response.data; if (result.success) { console.log(`결제 성공! 승인번호: ${result.data.approval_no}`); } }) .catch(error => { console.log(`결제 실패: ${error.response.data.error.message}`); });
curl -X POST https://api.multisystem.kr/api/external/payment.php \ -H "Content-Type: application/json" \ -H "X-Api-Key: your_api_key" \ -H "X-Api-Secret: your_api_secret" \ -d '{ "order_id": "ORDER-001", "customer_name": "홍길동", "customer_phone": "01012345678", "product_name": "테스트 상품", "amount": 10000, "card_no": "1234567890123456", "exp_mm": "12", "exp_yy": "28" }'
기술 지원이 필요하신가요?
연동 중 문제가 발생하거나 추가 문의사항이 있으시면 언제든 연락주세요.
기술 지원
관리자에게 문의