# 빌링계정 API - 결제 수단 생성
## 1. API Overview
### Target Coverage
| PG |
결제 수단 |
| Worldpay |
[badge:Card,indigo-subtle] |
| Omise |
[badge:Card,indigo-subtle] [badge:Direct_Debit,indigo-subtle]
|
### Purpose
[context]
재사용할 결제 수단을 생성하는 API입니다.
사용자가 제공한 결제 수단 정보를 토큰화하여 안전하게 저장하고 민감한 데이터를 직접 노출하지 않도록 설계되었습니다.
이 API는 이후 결제 요청에서 저장된 결제 수단을 활용해 편리하고 안전한 결제 경험을 제공하는 것을 목표로 합니다.
Worldpay의 상세 가이드는 다음을 참조하세요: [Worldpay 상세 가이드](/docs/appendix/store-iframe-guide/worldpay)
Omise의 상세 가이드는 다음을 참조하세요: [Omise 상세 가이드](/docs/appendix/store-iframe-guide/omise)
Checkout.com의 상세 가이드는 다음을 참조하세요: [Checkout.com 상세 가이드](/docs/appendix/store-iframe-guide/checkout)
[/context]
### Details
[table:key-value]
| 항목 | 값 |
| :-------------- | :--------------------------- |
| **API Name** | 결제 수단 생성 |
| **API Path** | /api/v2/payment-methods |
| **API ID** | EBP_API_120 |
| **HTTP Method** | [badge:POST,blue,lg] |
| **Region** | [badge:Global,green-subtle,lg] |
[/table]
@@include:billing-account-creation.md@@
## 2. Request Specification
### 2.1 Request Header
@@include:common-headers-link.md@@
### 2.2 Request Data Schema
| depth | Field | Details & Description |
|:------|:--------------------|:---------------------------------------------------------------------|
| 0 | userNo | [type-ml:string,500] [req:Yes] [desc:사용자를 식별하는 고유 번호] |
| 0 | email | [type-ml:string,128] [req:Yes] [desc:사용자 이메일 주소] |
| 0 | paymentMethod | [type:string] [req:Yes] [desc:등록할 결제 수단 유형] [eg: CARD, DIRECT_DEBIT] |
| 0 | successUrl | [type-ml:string,500] [req:Yes] [desc:결제 수단 등록 성공 후 리다이렉트할 URL] |
| 0 | failureUrl | [type-ml:string,500] [req:Yes] [desc:결제 수단 등록 과정이 실패했을 때 이동할 URL] |
| 0 | billingAddress | [type:object] [req:Optional] [desc:청구지 주소 정보 (세금계산서 발급 시 필수)] |
| 1 | billingEmail | [type-ml:string,128] [req:Optional] [desc:청구 담당자 이메일 주소] |
| 1 | billingLastName | [type-ml:string,100] [req:Conditional] [desc:청구 담당자 성(현지 언어)] |
| 1 | billingFirstName | [type-ml:string,100] [req:Conditional] [desc:청구 담당자 이름(현지 언어)] |
| 1 | billingCountry | [type-ml:string,3] [req:Conditional] [desc:ISO 3166-1 alpha-3 국가 코드] |
| 1 | billingStreet | [type-ml:string,100] [req:Conditional] [desc:청구지 도로명] |
| 1 | billingAddressLine1 | [type-ml:string,100] [req:Conditional] [desc:청구지 주소 1] |
| 1 | billingAddressLine2 | [type-ml:string,100] [req:Optional] [desc:청구지 주소 2] |
| 1 | billingCity | [type-ml:string,100] [req:Conditional] [desc:청구지 도시] |
| 1 | billingPostalCode | [type-ml:string,100] [req:Conditional] [desc:청구지 우편번호] |
| 1 | billingState | [type-ml:string,100] [req:Conditional] [desc:청구지 주/도] |
| 0 | account | [type:object] [req:Optional] [desc:계정 소유자 정보] |
| 1 | accountLastName | [type-ml:string,100] [req:Optional] [desc:사용자 성(현지 언어)] |
| 1 | accountFirstName | [type-ml:string,100] [req:Optional] [desc:사용자 이름(현지 언어)] |
| 0 | directDebitType | [type:string] [req:Conditional] [desc:결제 수단 DIRECT_DEBIT 이용 시 필수 항목입니다. 상세 내용은 하단의 [**직불계좌 결제 정보 안내**](#direct-debit-info)를 참조하십시오.] |
> **직불계좌 결제 정보 (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.3 Request Examples
#### JSON Example
[tabs]
[tab:CARD]
```json
{
"userNo": "AU1234567890",
"userId": "gildong.hong@example.com",
"email": "gildong.hong@example.com",
"paymentMethod": "CARD",
"successUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/worldpay/success",
"failureUrl": "https://devkic-pgui.nebp.lge.com/pgui/v2/hpp/worldpay/failure"
}
```
[tab:DIRECT_DEBIT]
```json
{
"userNo": "TH1234567890",
"userId": "gildong.hong@example.com",
"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"
}
```
[/tabs]
## 3. Response Specification
### 3.1 Response Data Schema
#### Response Data Schema
@@include:standard-response.md@@
| -1 | data | [type:object] [req:Yes] [desc:응답 데이터 (비즈니스 결과물)] |
| 0 | paymentMethodId | [type:string] [req:Yes] [desc:저장된 결제 수단 ID] |
| 0 | orderNo | [type:string] [req:Yes] [desc:주문 번호] |
| 0 | status | [type:string] [req:Yes] [desc:결제 수단 상태] [eg:ACTION_REQUIRED] |
| 0 | paymentUrl | [type:string] [req:Optional] [desc:추가 인증(HPP 등)이 필요한 경우 사용자를 리다이렉트시킬 EBP 표준 URL입니다. `requiresClientAction`이 `true`인 경우 필수적으로 참조합니다.] |
| 0 | paymentHeaderContext | [type:string] [req:Optional] [desc:EBP에서 발급한 암호화된 결제 헤더 컨텍스트. '결제 수단 등록 완료 API' 호출 시 x-ebp-context 헤더 값으로 전달해야 합니다.] |
| 0 | pgResponse | [type:object] [req:Optional] [desc:PG사 응답 원본 객체 (직접 액션 시 필요)] |
| 1 | resultCode | [type:string] [req:Optional] [desc:PG사 응답 결과 코드] |
| 1 | data | [type:object] [req:Optional] [desc:PG사 응답 데이터 상세. PG별 상이] |
| 0 | successUrl | [type-ml:string,500] [req:Optional] [desc:결제 수단 등록 성공 후 리다이렉트할 URL] |
| 0 | failureUrl | [type-ml:string,500] [req:Optional] [desc:결제 수단 등록 실패 시 리다이렉트할 URL] |
| -1 | instructions | [type:object] [req:Yes] [desc:후속 처리를 위한 지침 (프로세스 제어)] |
| 0 | nextStep | [type:string] [req:Yes] [desc:다음 행동 지시] [eg:CLIENT_ACTION] |
| 0 | completionMethod | [type:string] [req:Yes] [desc:전체 프로세스의 최종 등록 완료 방식] [eg:WEBHOOK, API] |
| 0 | requiresClientAction | [type:boolean] [req:Yes] [desc:클라이언트 추가 액션(HPP 이동, 토큰화 등)이 필요한지 여부] |
| 0 | clientAction | [type:object] [req:Optional] [desc:클라이언트의 추가 액션 지시 정보 객체. `requiresClientAction`이 `true`인 경우 필수적으로 참조합니다.] |
| 1 | type | [type:string] [req:Optional] [desc:클라이언트 액션 유형] [eg:TOKENIZE_CARD, CREATE_SOURCE] |
| 1 | pgProvider | [type:string] [req:Optional] [desc:액션을 처리할 PG사] |
| 0 | requiresFollowUpApi | [type:boolean] [req:Yes] [desc:후속 API(등록 완료 API) 호출이 필수인지 여부] |
| 0 | followUpApi | [type:object] [req:Optional] [desc:Information for the follow-up API to be called after the client action. Mandatory if `requiresFollowUpApi` is `true`.] |
| 1 | method | [type:string] [req:Optional] [desc:HTTP method of the follow-up API] [eg:POST] |
| 1 | url | [type:string] [req:Optional] [desc:Call path of the follow-up API] |
| 1 | description | [type:string] [req:Optional] [desc:Additional description of the follow-up API] |
### 3.2 Response Samples
#### Case 1: Worldpay 카드 등록 (리다이렉트 + 웹훅 완료)
PG사의 결제 페이지(HPP)를 통해 카드 정보를 입력받는 방식입니다. 사용자가 정보를 입력하면 PG사에서 EBP로 웹훅을 보내 등록이 최종 완료됩니다.
* **Next Step**: `REDIRECT` (PG사 HPP로 이동 필요)
* **Completion**: `WEBHOOK` (사용자 인증 완료 후 웹훅에 의해 비동기로 완료됨)
```json
{
"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...",
"pgResponse": {
"resultCode": "PASS",
"data": {
"pgRefId": "3579052412",
"returnUrl": "https://payments-test.worldpay.com/app/hpp/...",
"referenceUrl": "https://payments-test.worldpay.com/app/hpp/..."
}
},
"successUrl": "http:///v2/ebp/test/token/success",
"failureUrl": "http:///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](/docs/api-endpoints/billing/complete-payment-methods) 호출 필요)
```json
{
"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...",
"pgResponse": {
"resultCode": "SUCCESS",
"data": {
"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` (사용자 인증 완료 후 웹훅에 의해 비동기로 활성화됨)
```json
{
"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",
"pgResponse": {
"resultCode": "OK",
"pgProvider": "OMISE",
"data": {
"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
}
}
```