이 문서는 서버에서 결제 취소 API를 호출하는 방법을 설명해요. 주문 취소, 고객 환불, 오결제 처리 시 전액 취소와 부분 취소를 서버에서 처리해야 해요.
API 엔드포인트
POST
https://api.bootpay.co.kr/v2/cancelBasic Auth요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
receipt_id |
String | 필수 | 취소할 결제의 영수증 ID |
cancel_price |
Integer | 선택 | 부분 취소 금액 (미입력 시 전액 취소) |
cancel_tax_free |
Integer | 선택 | 취소 면세 금액 |
cancel_id |
String | 선택 | 가맹점 취소 고유 ID (중복 방지) |
cancel_username |
String | 선택 | 취소자명 |
cancel_message |
String | 선택 | 취소 사유 |
코드 예제
import { Bootpay } from '@bootpay/backend-js'
Bootpay.setConfiguration({
client_key: '[ Client Key ]',
secret_key: '[ Secret Key ]'
})
try {
const response = await Bootpay.cancelPayment({
receipt_id: '[ receipt_id ]',
cancel_price: 1000,
cancel_tax_free: 0,
cancel_id: '[ 가맹점 취소 고유 ID ]',
cancel_username: '홍길동',
cancel_message: '고객 요청에 의한 취소'
})
console.log(response)
} catch (e) {
console.log(e)
}javascriptfrom bootpay_backend import BootpayBackend
bootpay = BootpayBackend('APPLICATION_ID', 'PRIVATE_KEY')
if 'error_code' not in token:
response = bootpay.cancel_payment(
receipt_id='[ receipt_id ]',
cancel_price=1000,
cancel_tax_free=0,
cancel_id='[ cancel_id ]',
cancel_username='홍길동',
cancel_message='고객 요청에 의한 취소'
)
print(response)pythonuse Bootpay\ServerPhp\BootpayApi;
BootpayApi::setConfiguration('APPLICATION_ID', 'PRIVATE_KEY');
$response = BootpayApi::cancelPayment([
'receipt_id' => '[ receipt_id ]',
'cancel_price' => 1000,
'cancel_tax_free' => 0,
'cancel_id' => '[ cancel_id ]',
'cancel_username' => '홍길동',
'cancel_message' => '고객 요청에 의한 취소',
]);
print_r($response);phpimport kr.co.bootpay.pg.Bootpay;
import kr.co.bootpay.pg.model.request.Cancel;
Bootpay bootpay = new Bootpay("APPLICATION_ID", "PRIVATE_KEY");
Cancel cancel = new Cancel();
cancel.receiptId = "[ receipt_id ]";
cancel.cancelPrice = 1000;
cancel.cancelTaxFree = 0;
cancel.cancelId = "[ cancel_id ]";
cancel.cancelUsername = "홍길동";
cancel.cancelMessage = "고객 요청에 의한 취소";
var response = bootpay.receiptCancel(cancel);
System.out.println(response);javabootpay = Bootpay::Api.new(application_id: 'APPLICATION_ID', private_key: 'PRIVATE_KEY')
response = bootpay.cancel_payment(
receipt_id: '[ receipt_id ]',
cancel_price: 1000,
cancel_tax_free: 0,
cancel_id: '[ cancel_id ]',
cancel_username: '홍길동',
cancel_message: '고객 요청에 의한 취소'
)
puts responserubyimport "github.com/bootpay/backend-go/v2"
api := bootpay.NewAPI("APPLICATION_ID", "PRIVATE_KEY", nil, "")
response, err := api.ReceiptCancel(bootpay.CancelData{
ReceiptId: "[ receipt_id ]",
CancelPrice: 1000,
CancelTaxFree: 0,
CancelId: "[ cancel_id ]",
CancelUsername: "홍길동",
CancelMessage: "고객 요청에 의한 취소",
})
fmt.Println(response)gousing Bootpay;
using Bootpay.models;
var bootpay = new BootpayApi("APPLICATION_ID", "PRIVATE_KEY");
var response = await bootpay.ReceiptCancel(new Cancel
{
receiptId = "[ receipt_id ]",
cancelPrice = 1000,
cancelTaxFree = 0,
cancelId = "[ cancel_id ]",
cancelUsername = "홍길동",
cancelMessage = "고객 요청에 의한 취소"
});
Console.WriteLine(response);csharp응답
취소 요청 결과도 status를 기준으로 처리해요. status: 20이면 취소가 완료된 상태예요.
{
"receipt_id": "6244f60c1fc19202e42e8c4e",
"order_id": "1648686604470",
"price": 1000,
"cancelled_price": 1000,
"status": 20,
"status_locale": "결제취소완료",
"cancelled_at": "2025-01-16T10:30:00+09:00"
}json{
"error_code": "RC_CANCEL_FAILED",
"pg_error_code": "8104",
"message": "취소 가능 기간이 지나 취소할 수 없습니다.",
"payload": {
"receipt_id": "6244f60c1fc19202e42e8c4e",
"order_id": "1648686604470"
}
}json에러 코드
공통 에러
인증·권한 관련 에러는 에러 코드표를 참고해요.
| 코드 | 메시지 | 대처 방법 |
|---|---|---|
RC_NOT_FOUND (2000) |
영수증 정보를 찾지 못했습니다 | receipt_id가 올바른지 확인해요 |
RC_ALREADY_CANCELLED (2027) |
이미 취소 처리된 결제이다 | 결제 상태를 먼저 조회한다 |
RC_NOT_ABLE_CANCEL (2028) |
결제 완료 상태가 아니라 취소할 수 없다 | 결제 상태를 확인해요 |
RC_CANCEL_PRICE_NOT_ZERO (2051) |
취소금액이 0보다 커야 한다 | cancel_price를 0보다 큰 값으로 설정해요 |
RC_CANCEL_PRICE_OVER (2052) |
취소 요청 금액이 취소 가능 금액 초과 | 남은 취소 가능 금액을 확인 후 재시도해요 |
RC_CANCEL_TAX_FREE_OVER (2053) |
면세 취소 금액이 취소 가능 금액 초과 | cancel_tax_free 금액을 확인해요 |
RC_CANCEL_ID_ALREADY_EXIST (2029) |
동일한 cancel_id로 이미 취소 요청됨 | 다른 cancel_id를 사용해요 |
RC_PM_CANCEL_NOT_SUPPORT (2030) |
PG 결제수단에서 취소 API 미지원 | PG사에 취소 지원 여부를 확인해요 |
RC_PM_P_CANCEL_NOT_SUPPORT (2031) |
PG 결제수단에서 부분취소 미지원 | 전액 취소를 시도하거나 PG사에 문의해요 |
RC_CANCEL_METHOD_NOT_FOUND (2033) |
취소 구현이 되지 않은 PG이다 | PG사에 문의해요 |
RC_CANCEL_SERVER_ERROR (2032) |
결제 취소 오류 | 잠시 후 재시도하거나 부트페이에 문의해요 |
RC_CANCEL_CRITICAL_ERROR (2086) |
결제 취소 중 치명적 오류 발생 | 부트페이 관리자에 문의해요 |
RC_NOT_ISSUED (2039) |
가상계좌 입금 대기 상태가 아닙니다 | 결제 상태를 확인해요 |
부분 취소는 일부 PG사에서 지원하지 않을 수 있어요. 부분 취소 미지원 PG사에서는 전액 취소만 가능해요.
부분취소·전표 매입 후 취소 시 안내
전체취소는 즉시 처리되어 카드사에서 카드 소유주에게 취소 알림이 바로 발송돼요. 그러나 부분취소 또는 전표 매입 후 취소(후취소)의 경우, 영업일 기준 3~5일 후 취소 정보가 카드 소유주에게 전달돼요. 이 기간 동안 고객이 취소 여부를 인지하기 어려울 수 있으므로, 취소 처리 후 고객에게 별도로 안내하는 것을 권장해요.
결제수단별 취소 정책
| 결제수단 | 부분취소 | 취소 가능 기간 | 비고 |
|---|---|---|---|
| 카드 | O | 180일 이내 | 당일 결제: 즉시 취소 / 전표 매입 후: 영업일 3~5일 소요 |
| 계좌이체 | O | 180일 이내 | 즉시 처리 |
| 가상계좌 | 일부 PG만 | 1년 이내 | CMS 이체 특약 필요, 취소 시 약 300원 수수료 발생 |
| 휴대폰 | X | 당월만 | 이전 달 결제는 취소 불가 |
| 네이버페이 | O | 3년(1,095일) 이내 | |
| 카카오페이 | O | 카드 1년 / 머니 5년 이내 | |
| 페이코 | O | 카드 180일 / 계좌 90일 이내 |
가상계좌 환불
가상계좌 취소 시 refund 객체에 환불 계좌 정보(bank_account, bank_username, bank_code)를 반드시 포함해야 해요. 지원 PG: KCP(에스크로만), 이니시스, 웰컴페이먼츠, 나이스페이먼츠, 다날.
취소 기한 초과 시
결제수단별 취소 가능 기간이 경과한 건은 PG사를 통한 자동 취소가 불가능해요. 가맹점에서 직접 고객에게 환불 처리해야 해요.
