이 문서는 서버에서 결제 취소 API를 호출하는 방법을 설명해요. 주문 취소, 고객 환불, 오결제 처리 시 전액 취소와 부분 취소를 서버에서 처리해야 해요.
API 엔드포인트
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(client_key='CLIENT_KEY', secret_key='SECRET_KEY')
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::setClientKeyConfiguration('CLIENT_KEY', 'SECRET_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 = Bootpay.withClientKey("CLIENT_KEY", "SECRET_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(client_key: 'CLIENT_KEY', secret_key: 'SECRET_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.NewAPIWithClientKey("CLIENT_KEY", "SECRET_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 = BootpayApi.WithClientKey("CLIENT_KEY", "SECRET_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일 이내 |
휴대폰 소액결제는 통신사 정산 주기 때문에 결제한 달(당월) 안에서만 취소할 수 있고, 부분취소도 지원하지 않아요. 달이 바뀐 뒤에는 PG를 통한 취소가 막히므로, 이런 건은 가맹점이 고객에게 직접 환불(계좌 송금 등)해야 해요. 같은 이유로, 표의 취소 가능 기간이 지났거나 가상계좌처럼 별도 특약이 없는 건도 PG 자동 취소가 불가능하니 직접 환불 흐름을 마련해 둬요.
가상계좌 취소 시 refund 객체에 환불 계좌 정보(bank_account, bank_username, bank_code)를 반드시 포함해야 해요. 지원 PG: KCP(에스크로만), 이니시스, 웰컴페이먼츠, 나이스페이먼츠, 다날.
결제수단별 취소 가능 기간이 경과한 건은 PG사를 통한 자동 취소가 불가능해요. 가맹점에서 직접 고객에게 환불 처리해야 해요.
