프로젝트(app) 에 등록되어 있는 PG·결제수단·발급키를 갱신한다. 신규 결제수단을 추가하거나, PG 사가 발급한 가맹점 키가 바뀌었을 때 본사 콘솔에서 이 API 만 호출하면 셀러 콘솔을 건드릴 필요가 없다.
핵심 요약
resources배열에 포함된 결제수단은 추가 또는 갱신된다. 배열에 빠진 결제수단은 그대로 유지된다 — 전체 덮어쓰기가 아니다.- 기존에 등록된 PG·결제수단 묶음에 같은
pg + method조합이 들어오면 발급키만 갱신된다. sandbox: true로 등록하면 테스트 모드 키로 분리된다. 운영 키로 교체할 때는sandbox: false또는 생략한다.- 응답으로 프로젝트의 최신 정보(application_keys, payment_apps) 가 모두 다시 내려온다.
API 정보
PATCH
https://api.bootpay.co.kr/v2/reseller/seller/app/resource/:app_idBasic Auth (리셀러 계정 키)메서드 표기
Rails 표준 resources 라우트라서 PATCH / PUT 둘 다 받는다. 본 문서는 PATCH 기준으로 표기한다.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
app_id |
String | 필수 | 갱신할 프로젝트 식별자 (URL 경로) |
resources |
Array | 필수 | 등록·갱신할 PG·결제수단 배열. 각 원소 구조는 아래 참고 |
resources 배열 형식
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
pg |
String | 필수 | PG 심볼 (예: nicepay, kcp, inicis, tosspayments) |
method |
String | 필수 | 결제수단 심볼 (예: 카드, 계좌이체, 가상계좌, 카드자동) |
sandbox |
Boolean | 선택 | true 면 테스트 모드 키로 등록 |
resource |
Object | 필수 | PG 가 발급한 가맹점 키 묶음 |
코드 예제
import fetch from 'node-fetch'
const RESELLER_AUTH = 'Basic ' + Buffer
.from(`${process.env.BOOTPAY_RESELLER_CLIENT_KEY}:${process.env.BOOTPAY_RESELLER_SECRET_KEY}`)
.toString('base64')
const appId = '65a1c0ab8f1b5b00367a0010'
const res = await fetch(`https://api.bootpay.co.kr/v2/reseller/seller/app/resource/${appId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': RESELLER_AUTH
},
body: JSON.stringify({
resources: [
{
pg: 'nicepay',
method: '카드',
sandbox: false,
resource: {
mid: 'nicepay00m',
merchant_key: 'EYzu8jGGMfqaDEp76gSckuvnaHHu+...='
}
},
{
pg: 'nicepay',
method: '카드자동',
sandbox: false,
resource: {
mid: 'nicepay00m',
merchant_key: 'EYzu8jGGMfqaDEp76gSckuvnaHHu+...='
}
}
]
})
})
const data = await res.json()
console.log(data)javascriptimport base64, os, requests
auth = 'Basic ' + base64.b64encode(
f"{os.environ['BOOTPAY_RESELLER_CLIENT_KEY']}:{os.environ['BOOTPAY_RESELLER_SECRET_KEY']}".encode()
).decode()
app_id = '65a1c0ab8f1b5b00367a0010'
payload = {
'resources': [
{
'pg': 'nicepay',
'method': '카드',
'sandbox': False,
'resource': {
'mid': 'nicepay00m',
'merchant_key': 'EYzu8jGGMfqaDEp76gSckuvnaHHu+...='
}
},
{
'pg': 'nicepay',
'method': '카드자동',
'sandbox': False,
'resource': {
'mid': 'nicepay00m',
'merchant_key': 'EYzu8jGGMfqaDEp76gSckuvnaHHu+...='
}
}
]
}
res = requests.patch(
f'https://api.bootpay.co.kr/v2/reseller/seller/app/resource/{app_id}',
json=payload,
headers={'Authorization': auth}
)
print(res.json())pythonRESELLER_AUTH=$(printf '%s' "$BOOTPAY_RESELLER_CLIENT_KEY:$BOOTPAY_RESELLER_SECRET_KEY" | base64)
APP_ID='65a1c0ab8f1b5b00367a0010'
curl -X PATCH "https://api.bootpay.co.kr/v2/reseller/seller/app/resource/$APP_ID" \
-H "Authorization: Basic $RESELLER_AUTH" \
-H 'Content-Type: application/json' \
-d '{
"resources": [
{
"pg": "nicepay",
"method": "카드",
"sandbox": false,
"resource": {
"mid": "nicepay00m",
"merchant_key": "EYzu8jGGMfqaDEp76gSckuvnaHHu+...="
}
},
{
"pg": "nicepay",
"method": "카드자동",
"sandbox": false,
"resource": {
"mid": "nicepay00m",
"merchant_key": "EYzu8jGGMfqaDEp76gSckuvnaHHu+...="
}
}
]
}'bash응답
프로젝트의 최신 상태가 통째로 내려온다.
{
"app_id": "65a1c0ab8f1b5b00367a0010",
"app_name": "한입가게 — 정기구독",
"real": { "name": "비실물", "value": 0, "desc": "" },
"unit": "KRW",
"application_keys": [
{ "type": 1, "name": "WEB", "key": "65a1c0ab8f1b5b00367a0011" },
{ "type": 2, "name": "Android", "key": "65a1c0ab8f1b5b00367a0012" },
{ "type": 3, "name": "iOS", "key": "65a1c0ab8f1b5b00367a0013" },
{ "type": 4, "name": "REST", "key": "65a1c0ab8f1b5b00367a0014" }
],
"private_key": "kQ3f8vB2pN7sXq1wE5rT9yU0iO4aS6dF8gH2jK5lZ0c=",
"payment_apps": [
{
"payment_resource_id": "65a1c0ab8f1b5b00367a0015",
"pg_id": "6098a1b2c3d4e5f600000101",
"pg_name": "나이스페이먼츠",
"pg_alias": "nicepay",
"method_id": "6098a1b2c3d4e5f600000201",
"method_name": "카드",
"method_alias": "card",
"resource_mode": 1,
"sandbox_mode": false,
"easypay": false,
"updated_at": "2024-01-12T18:04:11+09:00",
"status": 20,
"resource": {
"mid": "nicepay00m",
"merchant_key": "EYzu8jGGMfqaDEp76gSckuvnaHHu+..."
}
},
{
"payment_resource_id": "65a1c0ab8f1b5b00367a0016",
"pg_id": "6098a1b2c3d4e5f600000101",
"pg_name": "나이스페이먼츠",
"pg_alias": "nicepay",
"method_id": "6098a1b2c3d4e5f600000202",
"method_name": "카드자동",
"method_alias": "card_rebill",
"resource_mode": 1,
"sandbox_mode": false,
"easypay": false,
"updated_at": "2024-01-12T18:04:11+09:00",
"status": 20,
"resource": {
"mid": "nicepay00m",
"merchant_key": "EYzu8jGGMfqaDEp76gSckuvnaHHu+..."
}
}
],
"status": 20
}json응답 파라미터
| 파라미터 | 타입 | 설명 |
|---|---|---|
| app_id | String | 프로젝트 식별자 |
| app_name | String | 프로젝트명 |
| real | Object | 거래 상품 유형. { name, value, desc } 구조다 |
| unit | String | 결제 통화 |
| application_keys | Array | 플랫폼별 SDK 연동키 묶음. WEB / Android / iOS / REST 4 건이 내려온다 |
| application_keys[].type | Number | 플랫폼 코드. 1 = WEB, 2 = Android, 3 = iOS, 4 = REST |
| application_keys[].name | String | 플랫폼 이름 (WEB / Android / iOS / REST) |
| application_keys[].key | String | SDK 초기화에 넣는 application_id. Basic Auth 에 쓰는 client_key 와는 다른 값이다 |
| private_key | String | 프로젝트 단위의 백엔드 키. SHA256 Base64 다이제스트 형태다 |
| payment_apps | Array | 프로젝트에 등록된 PG·결제수단 목록 |
| payment_apps[].payment_resource_id | String | 등록된 결제수단 리소스 식별자 |
| payment_apps[].pg_id / pg_name / pg_alias | String | 매칭된 PG 식별자·이름·심볼 |
| payment_apps[].method_id / method_name / method_alias | String | 매칭된 결제수단 식별자·이름·심볼 |
| payment_apps[].resource_mode | Number | 리소스 등록 모드 |
| payment_apps[].sandbox_mode | Boolean | 테스트 모드 여부 |
| payment_apps[].easypay | Boolean | 간편결제 여부 |
| payment_apps[].updated_at | String | 리소스 갱신 시각 (ISO 8601) |
| payment_apps[].status | Number | 결제수단 상태 |
| payment_apps[].resource | Object | 등록된 PG 발급키 묶음. 요청에 보낸 값이 그대로 다시 내려온다 |
| status | Number | 프로젝트 상태. 기본값 20 (심사통과) |
응답 로깅 주의
payment_apps[].resource 에는 PG 가 발급한 가맹점 키가 평문으로 들어 있다. 이 응답을 그대로 로그·APM·에러 리포팅에 남기지 않는다. 저장이 필요하면 resource 를 마스킹하거나 제거한 뒤 기록한다.
동작 규칙
| 상황 | 결과 |
|---|---|
신규 pg + method 가 들어옴 |
결제수단이 추가된다 |
기존 pg + method 에 새 resource 가 들어옴 |
발급키가 덮어쓰기 된다 |
기존에 있던 pg + method 가 배열에서 빠짐 |
그대로 유지된다 (자동 제거되지 않는다) |
resource 안에 PG 가 요구하는 키가 빠짐 |
이 엔드포인트는 필수 키를 검증하지 않는다. 빠진 채로 저장된다 |
필수 키 검증 범위
resource 에 PG 가 요구하는 필수 키가 다 들어 있는지 확인하는 RESOURCE_KEY_BLANK 검증은 가맹점 생성 (POST /v2/reseller/seller) 경로에서만 동작한다. 이 갱신 API 는 해당 검증을 거치지 않으므로, 키가 빠진 채로 저장되면 실제 결제 요청 시점에 가서야 실패한다. 요청 전에 본사 쪽에서 필수 키를 채웠는지 직접 확인한다.
에러 코드
| 코드 | 메시지 | 대처 방법 |
|---|---|---|
API_ONLY_RESELLER |
리셀러만 이용이 가능한 API 다 | 리셀러 권한 계정 키로 호출한다 |
API_NOT_PERMIT_LV (10000) |
허가된 API 권한이 아니다 (HTTP 401) | 계정에 이 API 호출 권한이 열려 있는지 부트페이 관리자에게 문의한다 |
API_NOT_PERMIT (10001) |
허가된 API 권한이 아니다 (HTTP 401) | 계정에 이 API 호출 권한이 열려 있는지 부트페이 관리자에게 문의한다 |
APP_NOT_FOUND (200) |
해당 app_id 의 프로젝트가 존재하지 않는다 (HTTP 404) |
app_id 오타·삭제 여부를 확인한다 |
APP_NOT_PERMIT (201) |
프로젝트는 있으나 본인 리셀러 하위가 아니다 (HTTP 401) | 해당 프로젝트가 본인 하위 셀러 소속인지 확인한다 |
PG_RESOURCE_NOT_FOUND |
resources[].pg 심볼을 찾지 못했다 |
PG 코드 에서 PG 심볼을 확인한다 |
METHOD_RESOURCE_NOT_FOUND |
resources[].method 심볼을 찾지 못했다 |
PG 가 지원하는 결제수단 심볼인지 확인한다 |