빌링계정 API - 결제 수단 생성 #
1. API Overview #
Target Coverage #
| 분류 | 결제 수단 (paymentMethod) |
|---|---|
| Instrument (직접 수단) |
CARD DIRECT_DEBIT |
| Agreement (결제 계약) |
NAVER_PAY KAKAO_PAY TOSS_PAY KFTC_CMS |
Purpose #
재사용 가능한 결제 수단 또는 결제 계약을 등록하는 API입니다.
기존의 카드/계좌 직접 등록 방식뿐만 아니라, 간편결제 서비스(네이버/카카오/토스) 및 금융결제원과 같은 계약 기반(Agreement) 수단을 통합 관리할 수 있도록 설계되었습니다.
핵심 설계 원칙:
- 인증 중심: 요청 시 상세 정보를 받지 않고, 응답받은
paymentUrl을 통해 사용자 인증을 거친 후 시스템이 등록을 완료합니다. - 성격 분류:
paymentMethodType필드를 통해 수단이 직접 관리 대상(INSTRUMENT)인지 권한 위임 계약(AGREEMENT)인지 구분합니다. - 데이터 유연성: 수단별 특화 정보는
detailsJSON 필드를 통해 다형적으로 제공하며, 등록 시 전달한 부가 정보는metadata를 통해 보존됩니다.
Details #
| 항목 | 값 |
|---|---|
| API Name | 결제 수단 생성 |
| API Path | /api/v2/payment-methods |
| API ID | EBP_API_120 |
| HTTP Method | POST |
| Region | Global |
2. Request Specification #
2.1 Request Data Schema #
결제 수단 등록을 시작하기 위한 최소 정보만 전달합니다. 상세 정보는 이후 인증 단계에서 수집됩니다.
| depth | Field | Details & Description |
|---|---|---|
| 0 | userNo |
🔴 Required 사용자를 식별하는 고유 번호 |
| 0 |
⚪ Optional 사용자 이메일 주소 | |
| 0 | paymentMethod |
🔴 Required 등록할 결제 수단 브랜드 e.g., CARD, NAVER_PAY, KFTC_CMS |
| 0 | successUrl |
🔴 Required 등록 성공 후 리다이렉트할 URL |
| 0 | failureUrl |
🔴 Required 등록 과정 실패 시 이동할 URL |
| 0 | billingAddress |
⚪ Optional 청구지 주소 정보 (필요 시) |
| 0 | directDebitType |
🟡 Conditional 결제 수단 DIRECT_DEBIT 이용 시 필수 항목입니다. 상세 내용은 하단의 직불계좌 결제 정보 안내를 참조하십시오. |
| 0 | metadata |
🟡 Conditional 결제 수단별 추가 정보. 네이버페이 등 특정 브랜드 등록 시 필수입니다. |
| 1 | mid |
🟡 Conditional 가맹점 식별 번호 (Merchant ID) |
| 1 | productCode |
🟡 Conditional 등록 시 기준이 되는 상품 코드 |
| 1 | productName |
🟡 Conditional 등록 시 기준이 되는 상품 명칭 |
| 1 | amount |
🟡 Conditional 등록 또는 첫 결제 기준 금액 |
직불계좌 결제 정보 (directDebitType) 안내
태국 직불계좌 결제(
DIRECT_DEBIT) 이용 시 다음의 지원 은행 코드를 확인하십시오.
- direct_debit_bay (Krungsri Bank)
- direct_debit_kbank (Kasikorn Bank)
- direct_debit_ktb (Krungthai Bank)
- direct_debit_scb (Siam Commercial Bank)
2.1.1 Metadata #
메타데이터는 결제 수단에 따라 포함되는 필드가 다릅니다.
2.1.1.1 NAVER_PAY #
| Field | Details & Description |
|---|---|
| productCode | 🔴 Required
등록 시 기준이 되는 상품 코드 |
| productName | 🔴 Required
등록 시 기준이 되는 상품 명칭 |
| totalPayAmount | 🔴 Required
등록 또는 첫 결제 기준 금액 |
| purchaserName | 🟡 Conditional
구매자 성명. 결제 상품이 보험 및 위험 업종 등인 경우에만 필수 값입니다. |
| purchaserBirthday | 🟡 Conditional
구매자 생년월일(yyyyMMdd). 결제 상품이 보험 및 위험 업종 등인 경우에만 필수 값입니다. |
2.2 Request Examples #
{
"userNo": "AU1234567890",
"email": "gildong.hong@example.com",
"paymentMethod": "CARD",
"successUrl": "https://example.com/success",
"failureUrl": "https://example.com/failure"
}
{
"userNo": "TH1234567890",
"email": "gildong.hong@example.com",
"paymentMethod": "DIRECT_DEBIT",
"successUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/success",
"failureUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/failure",
"directDebitType": "direct_debit_bay"
}
{
"userNo": "AU1234567890",
"email": "gildong.hong@example.com",
"paymentMethod": "NAVER_PAY",
"successUrl": "https://example.com/naver/success",
"failureUrl": "https://example.com/naver/failure",
"metadata": {
"mid": "NAVER_MID_12345",
"productCode": "SUBS_PROD_001",
"productName": "정기 구독 서비스",
"amount": 0
}
}
3. Response Specification #
3.1 Response Data Schema #
| depth | Field | Details & Description |
|---|---|---|
| -1 | resultCode |
🔴 Required 결과 코드 (성공 "0", 에러 시 "EBP-A-0001" 등) |
| -1 | message |
🔴 Required 결과 메시지 (성공 또는 에러 상세) |
| -1 | requestId |
🔴 Required 추적을 위한 고유 요청 ID |
| -1 | timestamp |
🔴 Required ISO 8601 형식의 응답 타임스탬프 e.g., 2025-12-19T14:24:00+09:00 |
| -1 | data |
🔴 Required 응답 데이터 |
| 0 | paymentMethodId |
🔴 Required EBP 결제 수단 식별자 |
| 0 | paymentMethod |
🔴 Required 결제 수단 브랜드 명칭 |
| 0 | paymentMethodType |
🔴 Required 수단 성격 분류. |
| 0 | pgChannel |
🔴 Required 등록 처리에 사용된 PG 채널 명칭 |
| 0 | status |
🔴 Required 현재 상태 e.g., PENDING_AUTH |
| 0 | paymentUrl |
⚪ Optional 사용자 인증을 진행할 EBP 표준 URL |
| 0 | paymentHeaderContext |
⚪ Optional EBP에서 발급한 암호화된 결제 헤더 컨텍스트. '결제 수단 등록 완료 API' 호출 시 x-ebp-context 헤더 값으로 전달해야 합니다. |
| 0 | details |
🔴 Required 수단별 상세 정보 [상세 규격 (#1.4.2) 참조] |
| 0 | metadata |
⚪ Optional 등록 시 전달된 추가 정보 객체 |
| 0 | pgResult |
⚪ Optional PG사 응답 결과 객체 |
| 1 | resultCode |
🔴 Required PG 응답 코드 |
| 1 | pgResponse |
🔴 Required PG사 원천 응답 데이터 상세 |
| -1 | instructions |
🔴 Required 후속 처리를 위한 지침 (프로세스 제어) |
| 0 | nextStep |
🔴 Required 다음 행동 지시 e.g., CLIENT_ACTION |
| 0 | completionMethod |
🔴 Required 전체 프로세스의 최종 등록 완료 방식 e.g., WEBHOOK, API |
| 0 | requiresClientAction |
🔴 Required 클라이언트 추가 액션(HPP 이동, 토큰화 등)이 필요한지 여부 |
| 0 | clientAction |
⚪ Optional 클라이언트의 추가 액션 지시 정보 객체. |
| 1 | type |
⚪ Optional 클라이언트 액션 유형 e.g., TOKENIZE_CARD, CREATE_SOURCE |
| 1 | pgProvider |
⚪ Optional 액션을 처리할 PG사 |
| 0 | requiresFollowUpApi |
🔴 Required 후속 API(등록 완료 API) 호출이 필수인지 여부 |
| 0 | followUpApi |
⚪ Optional Information for the follow-up API to be called after the client action. Mandatory if |
| 1 | method |
⚪ Optional HTTP method of the follow-up API e.g., POST |
| 1 | url |
⚪ Optional Call path of the follow-up API |
| 1 | description |
⚪ Optional Additional description of the follow-up API |
3.2 결제 수단별 상세 정보 (details) #
details 객체는 각 결제 수단의 특성에 따라 다르게 구성됩니다. (보안상 민감한 Billing Key 등은 포함되지 않습니다.)
CARD (Instrument) #
brand: 카드 브랜드 (VISA, MASTER 등)last4: 카드번호 끝 4자리expiry: 유효기간 (MM/YY)
NAVER_PAY (Agreement) #
maskedIdentifier: 마스킹된 계정 정보 (이메일 등)methodName: 연결된 주 결제 수단 명칭 (예: 네이버페이 머니)
KFTC_CMS (Agreement) #
bankName: 은행 명칭accountLast4: 계좌번호 끝 4자리holderName: 예금주 성명
3.3 Response Samples #
Case 1: Worldpay 카드 등록 (리다이렉트 + 웹훅 완료) #
PG사의 결제 페이지(HPP)를 통해 카드 정보를 입력받는 방식입니다. 사용자가 정보를 입력하면 PG사에서 EBP로 웹훅을 보내 등록이 최종 완료됩니다.
- Next Step:
REDIRECT(PG사 HPP로 이동 필요) - Completion:
WEBHOOK(사용자 인증 완료 후 웹훅에 의해 비동기로 완료됨)
{
"resultCode": "0",
"message": "SUCCESS",
"requestId": "06EFX0CRR7ME0KCSSTFEEDRDVG",
"timestamp": "2026-01-27T04:39:47.222978900Z",
"data": {
"paymentMethodId": "3e104ef7b98f4123948a8c248d0da4c5",
"orderNo": "ORD_7202603277730794",
"status": "ACTION_REQUIRED",
"paymentUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/worldpay/wrapping",
"paymentHeaderContext": "eyJhY3Rpb24iOiJSRURJUkVDVF9UT19IUFAiLCJwcm92aWRlciI6IldPUkxEUEFZIiwiY29udGV4dCI6I...",
"pgResult": {
"resultCode": "PASS",
"pgResponse": {
"pgRefId": "3579052412",
"returnUrl": "https://payments-test.worldpay.com/app/hpp/...",
"referenceUrl": "https://payments-test.worldpay.com/app/hpp/..."
}
},
"successUrl": "http://<yourhost>/v2/ebp/test/token/success",
"failureUrl": "http://<yourhost>/v2/ebp/test/token/fail"
},
"instructions": {
"nextStep": "REDIRECT",
"completionMethod": "WEBHOOK",
"requiresClientAction": true,
"clientAction": {
"type": "REDIRECT_TO_HPP",
"pgProvider": "WORLDPAY"
},
"requiresFollowUpApi": false
}
}
Case 2: Omise 카드 등록 (클라이언트 액션 + API 완료) #
클라이언트가 Omise JS SDK를 사용하여 카드 정보를 직접 토큰화하는 방식입니다. 획득한 토큰을 EBP의 등록 완료 API로 전달하여 등록을 확정합니다.
- Next Step:
CLIENT_ACTION(JS SDK 호출 및 토큰 획득 필요) - Completion:
API(획득한 토큰을 사용하여 결제 수단 등록 완료 API 호출 필요)
{
"resultCode": "0",
"message": "SUCCESS",
"requestId": "06EFWD32XT8HCBDCYR9RK7R0PC",
"timestamp": "2026-01-27T04:39:50.123456700Z",
"data": {
"paymentMethodId": "3a9437e612ac4ccb9beaa6585e899321",
"orderNo": "ORD_7202603277730795",
"status": "ACTION_REQUIRED",
"paymentUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/card/wrapping",
"paymentHeaderContext": "eyJhY3Rpb24iOiJUT0tFTklaRV9DQVJEIiwicHJvdmlkZXIiOiJPTUlTRSIsImNvbnRleHQiOiI...",
"pgResult": {
"resultCode": "SUCCESS",
"pgResponse": {
"publicKey": "pkey_test_46lmsec8z06uh..."
}
}
},
"instructions": {
"nextStep": "CLIENT_ACTION",
"completionMethod": "API",
"requiresClientAction": true,
"clientAction": {
"type": "TOKENIZE_CARD",
"pgProvider": "OMISE"
},
"requiresFollowUpApi": true,
"followUpApi": {
"method": "POST",
"url": "/api/v2/payment-methods/3a9437e612ac4ccb9beaa6585e899321/complete",
"description": "카드 토큰화 완료 후 이 API를 호출하여 등록을 확정해야 합니다."
}
}
}
Case 3: Omise 직불계좌 등록 (클라이언트 액션 + 인증 필요) #
클라이언트가 Omise JS SDK를 사용하여 계좌 정보를 소스화(SourceId 생성)하는 방식입니다. 획득한 소스 ID를 사용하여 응답받은 paymentUrl을 통해 사용자가 은행 인증을 진행하게 됩니다. 최종 등록은 인증 완료 후 웹훅을 통해 처리됩니다.
- 1단계 (현재 API):
CLIENT_ACTION(JS SDK 호출 및 SourceId 획득 필요) - 2단계 (인증): 응답받은
paymentUrl로 사용자 리다이렉트 및 은행 인증 - 최종 완료:
WEBHOOK(사용자 인증 완료 후 웹훅에 의해 비동기로 활성화됨)
{
"resultCode": "0",
"message": "SUCCESS",
"requestId": "06EP2JWT2DHQEQGBC3W3RRK72W",
"timestamp": "2026-04-06T05:37:22.536Z",
"data": {
"paymentMethodId": "1fc83f065287471987ee754ef01e7d40",
"orderNo": "ORD_7202603277730796",
"status": "ACTION_REQUIRED",
"paymentUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/direct-debit/wrapping",
"paymentHeaderContext": "eyJhY3Rpb24iOiJDUkVBVEVfU09VUkNFIiwicHJvdmlkZXIiOiJPTUlTRSIsImNvbnRleHQiOiI...",
"successUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/success",
"failureUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/omise/failure",
"pgResult": {
"resultCode": "OK",
"pgProvider": "OMISE",
"pgResponse": {
"type": "OMISE_DIRECT_DEBIT",
"linkedAccountId": "lnac_test_679grm7z8axarr41r6m",
"registrationUri": "https://pay.omise.co/registrations/linked_accounts/lnac_test_679grm7z8axarr41r6m/authorize"
}
}
},
"instructions": {
"nextStep": "CLIENT_ACTION",
"completionMethod": "WEBHOOK",
"requiresClientAction": true,
"clientAction": {
"type": "CREATE_SOURCE",
"pgProvider": "OMISE"
},
"requiresFollowUpApi": false
}
}
Case4: 네이버페이 등록 시작 (Agreement) #
{
"resultCode": "0",
"data": {
"paymentMethodId": "pm_20260427_001",
"paymentMethod": "NAVER_PAY",
"paymentMethodType": "AGREEMENT",
"pgChannel": "NAVER_PAY_BILLING",
"status": "PENDING_AUTH",
"paymentUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/naver/auth",
"details": {
"methodName": "네이버페이"
},
"metadata": {
"mid": "NAVER_MID_12345",
"productCode": "SUBS_PROD_001",
"productName": "정기 구독 서비스",
"amount": 0
},
"pgResult": {
"resultCode": "OK",
"pgResponse": {
"applyId": "REQ_20260427_XXX"
}
}
},
"instructions": {
"status": "ACTION_REQUIRED",
"requiresClientAction": true,
"clientAction": {
"type": "REDIRECT_TO_HPP",
"pgProvider": "NAVER_PAY"
}
}
}