결제 API 연동 가이드

결제 대행 API를 통해 간편하게 카드 결제, 취소, 조회 기능을 연동할 수 있습니다.

가맹점
결제 API
PG사

기본 정보

Base URL https://api.multisystem.kr/api/external
요청 형식 JSON (Content-Type: application/json)
인코딩 UTF-8
Rate Limit 분당 60회 (설정에 따라 변동)

인증

모든 API 요청에는 API KeyAPI 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분 간격).

에러 코드

인증 에러 (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"
  }'

기술 지원이 필요하신가요?

연동 중 문제가 발생하거나 추가 문의사항이 있으시면 언제든 연락주세요.

기술 지원
관리자에게 문의