fix(core): api:docgen 재생성이 문서를 손실·열화시키는 결함 수정

재생성이 사람이 채운 서술과 이전 실측 결과를 지우고, 코드가 바뀌지 않은
문서까지 매 실행마다 흔들던 결함 5건을 고쳤다.

- 중첩 객체 파라미터가 문서에서 통째로 누락되던 문제: 배열 요소(items.*.id)를
 상위로 대표시키려던 스킵 조건이 점(.) 포함 여부만 봐서, 와일드카드가 없는
 중첩 객체 필드(refund_bank.*, general.*, content.* 등 17개 엔드포인트 수백 개)
 까지 함께 버렸다. 와일드카드가 있을 때만 스킵하도록 좁혔다.
- 사람이 보강한 에러 응답 표가 자동 추론 초안에 덮여 사라지던 문제:
 상태코드 키 단위로 병합한다.
- 실측 실패가 이전에 관측해 둔 응답 예시를 지우던 문제: 실측 성패는 호출 시점
 데이터 유무에 좌우되므로(DELETE /checkout 은 대상이 없으면 404), 실패는
 "새로 관측하지 못했다"는 뜻이지 기존 관측이 무효라는 뜻이 아니다.
- 실측 예시값·응답 예시 JSON 이 DB 상태를 그대로 반영해 비멱등하던 문제:
 값이 아니라 스펙(필드 집합·타입)이 바뀐 경우에만 갱신한다. nullable 이
 null 로 관측된 것은 타입 변경이 아니므로 기존 값을 유지한다.
- 요청 예시 path 파라미터가 실측 성패에 따라 흔들리던 문제: placeholder 로 고정.

결과: 문서 63개 전수 대조에서 손실 0(서술·표 셀·응답 예시), 전 scope 연속
재생성 시 diff 0(멱등).
This commit is contained in:
HeuJung committed 2026-08-06 13:54:35 +09:00
1 parent 3f2674f1a7
commit 403154167a
86 files changed
+186546 -700

No files matched your search

@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Images 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -32,7 +32,7 @@
**요청 예시**
```http
GET /api/plugins/sirsoft-ckeditor5/images/a1b2c3d4e5f6 HTTP/1.1
GET /api/plugins/sirsoft-ckeditor5/images/{hash} HTTP/1.1
Host: api.example.com
Accept: application/json
```
@@ -41,6 +41,10 @@ Accept: application/json
<!-- 실측 제외: unresolved-path-param — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
<!-- 실측 제외: unresolved-path-param — 응답 예시는 사람이 작성하세요. -->
**에러 응답**
| 상태코드 | 의미 | 발생 조건 |
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Upload 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -48,7 +48,11 @@ Content-Type: application/octet-stream
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: side-effectful-write — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
<!-- 실측 제외: side-effectful-write — 응답 예시는 사람이 작성하세요. -->
**에러 응답**
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Consent Log 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Consent 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -53,7 +53,7 @@ Authorization: Bearer {YOUR_TOKEN} (optional.sanctum: 비회원은 헤더 생
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: http-422 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
@@ -149,7 +149,7 @@ Authorization: Bearer {YOUR_TOKEN}
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: http-422 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
@@ -424,7 +424,7 @@ Authorization: Bearer {YOUR_TOKEN}
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: http-422 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Policy Versions 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -239,7 +239,7 @@ HTTP/1.1 200
**요청 예시**
```http
GET /api/plugins/sirsoft-gdpr/admin/policy-versions/1 HTTP/1.1
GET /api/plugins/sirsoft-gdpr/admin/policy-versions/{version} HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer {YOUR_TOKEN}
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Settings 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -182,7 +182,7 @@ Content-Type: application/json
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: http-422 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Channels 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -38,7 +38,11 @@ Authorization: Bearer {YOUR_TOKEN}
**응답 필드** (`data` 내부)
<!-- 실측 제외: write-method — 응답 필드는 사람이 작성하세요. -->
<!-- 실측 제외: http-422 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
<!-- 실측 제외: http-422 — 응답 예시는 사람이 작성하세요. -->
**에러 응답**
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Settings 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -52,6 +52,45 @@ _단건 응답: `data` 객체의 필드._
| info_disclosure_terms_slug_set | boolean | `false` | 정보 이용 안내 약관 slug 존재 여부. 프론트의 약관 링크 표시 판정에 쓴다. |
| channels | array | `[{"key":"email_subscription","label":"광고성 이메일 수신","label_…` | `MarketingConsentService::getRegisteredChannels()` 가 반환하는 활성 채널 목록. 각 원소는 `key`·현재 로케일 해석 `label`·로케일 맵 원본 `label_i18n`·`enabled`·`terms_slug`·`terms_slug_set` 를 갖는다. 폼의 반복 렌더링에 그대로 쓰인다. |
**응답 예시**
<!-- @probed -->
```http
HTTP/1.1 200
```
```json
{
"success": true,
"message": "messages.success",
"data": {
"marketing_consent_enabled": true,
"marketing_consent_terms_slug": "marketing-terms",
"marketing_consent_terms_slug_set": true,
"third_party_consent_enabled": true,
"third_party_consent_terms_slug": null,
"third_party_consent_terms_slug_set": false,
"info_disclosure_enabled": true,
"info_disclosure_terms_slug": null,
"info_disclosure_terms_slug_set": false,
"channels": [
{
"key": "email_subscription",
"label": "광고성 이메일 수신",
"label_i18n": {
"ko": "광고성 이메일 수신",
"en": "Email Marketing"
},
"enabled": true,
"terms_slug": null,
"terms_slug_set": false
}
]
}
}
```
**에러 응답**
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Cbt 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Orders 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Payment 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -396,15 +396,15 @@ Accept: application/json
| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 |
| --- | --- | --- | --- | --- | --- |
| sid | body | string | 아니오 | max 255 | CBT 인증 세션 ID. 서버가 `/cbtapprove` 최종 승인 요청에 MID 와 함께 전송하는 승인 키이며, 결제 메타에 `cbt_sid` 로 저장된다. |
| resultCode | body | string | 아니오 | max 100 | CBT 인증 결과 코드 (`OK`/`00`/`0000` = 성공). `2001`/`0021`/`0022` 또는 취소 문구 포함 시 사용자 취소로 간주한다. |
| resultMsg | body | string | 아니오 | max 500 | CBT 인증 결과 메시지. 사용자 취소 판별(일본어/한국어 취소 문구)과 실패 리다이렉트 메시지에 사용된다. |
| orderID | body | string | 아니오 | max 100 | 주문번호 (1순위 키). `orderId` → `oid` 순으로 폴백해 주문을 조회한다. |
| orderId | body | string | 아니오 | max 100 | 주문번호 (2순위 폴백 키). |
| oid | body | string | 아니오 | max 100 | 주문번호 (3순위 폴백 키). |
| mid | body | string | 아니오 | max 30 | 일본 CBT 가맹점 MID. 설정된 일본 MID 와 불일치하면 결제를 중단한다(위조 콜백 차단). |
| paymethod | body | string | 아니오 | max 50 | CBT 결제수단 (CARD / PAYPAY / CVS). 승인 응답의 결제수단과 대조하며, CVS 는 편의점 입금대기 처리로 분기한다. |
| selectedPaymentMethod | body | string | 아니오 | max 50 | 체크아웃에서 사용자가 선택한 결제수단 식별값(`card` / `kginicis_japan_paypay` / `kginicis_japan_cvs`). 기대 결제수단 검증과 결제 메타 기록에 사용된다. |
| sid | body | string | 아니오 | max 255 | <!-- TODO: 용도 --> |
| resultCode | body | string | 아니오 | max 100 | 결제 인증 결과 코드 (`0000` = 성공). `2001`/`0021`/`0022`/빈값은 사용자 취소로 간주해 에러 없이 체크아웃으로 복귀한다. |
| resultMsg | body | string | 아니오 | max 500 | 결제 인증 결과 메시지. 실패 시 실패 URL 의 `message` 파라미터로 전달되며 '취소'/'사용자' 포함 여부로 사용자 취소를 판별한다. |
| orderID | body | string | 아니오 | max 100 | <!-- TODO: 용도 --> |
| orderId | body | string | 아니오 | max 100 | <!-- TODO: 용도 --> |
| oid | body | string | 아니오 | max 100 | 결제 대상 주문의 주문번호. 서버가 주문을 조회해 결제 가능 상태·통화·금액을 검증하고 이 값을 서명 생성 입력으로 사용한다. |
| mid | body | string | 아니오 | max 30 | <!-- TODO: 용도 --> |
| paymethod | body | string | 아니오 | max 50 | <!-- TODO: 용도 --> |
| selectedPaymentMethod | body | string | 아니오 | max 50 | <!-- TODO: 용도 --> |
**요청 예시**
@@ -445,7 +445,11 @@ Content-Type: application/json
**설명**
위 `GET /plugins/sirsoft-pay_kginicis/payment/cbt/callback` 과 동일한 CBT 인증 콜백이며, KG 이니시스가 폼 전송(POST)으로 되돌려보내는 경우를 처리합니다. 파라미터가 query 대신 body 로 들어오는 점만 다르고, 승인·검증·리다이렉트 동작과 주의사항은 GET 버전과 완전히 같습니다. 결제창 설정이나 결제수단에 따라 GET/POST 중 어느 쪽으로 돌아올지 달라질 수 있어 두 메서드를 모두 열어 둡니다.
일본 CBT(국경 간 결제) 인증 결과를 수신해 서버 승인(`/cbtapprove`)까지 마무리하는 콜백입니다(GET·POST 동일 처리). 브라우저가 KG 이니시스 일본 결제창에서 인증을 마치면 `sid` 와 주문번호가 붙어 이 주소로 되돌아오고, 서버는 그 `sid` 로 최종 승인을 요청한 뒤 결제완료 또는 편의점 입금대기 처리를 하고 결과 페이지로 리다이렉트합니다. GET 은 결제창이 리다이렉트로 되돌려보내는 경로, POST 는 폼 전송으로 되돌려보내는 경로이며 파라미터 위치만 다릅니다.
주의사항: (1) 브라우저가 전달한 인증 결과는 무인증 값이므로 그것만으로 주문 상태를 바꾸지 않고, 반드시 서버 승인 응답을 권위 있는 결과로 사용합니다. (2) 콜백의 `mid` 가 설정된 일본 가맹점 MID 와 다르면 위조 콜백으로 보고 즉시 중단합니다(`error=mid_mismatch`). (3) 승인 응답의 주문번호·MID·통화(JPY)·결제수단이 주문·체크아웃 선택값과 모두 일치해야 하며, 하나라도 어긋나면 승인 이후라도 실패로 처리합니다. (4) 결제수단이 `CVS`(편의점)면 결제완료가 아니라 입금대기로 저장하고 확인번호·접수번호·입금기한을 기록하며, 실제 완료는 편의점 입금통보(cvs-notify) 시점입니다. (5) 승인이 확정된 뒤 후속 처리에서 예외가 나면 자동 환불을 시도하고, 환불까지 실패하면 수동 환불 필요 상태로 대사 레코드를 남깁니다. (6) 사용자 취소(취소 코드 또는 일본어·한국어 취소 문구)는 실패가 아니므로 에러 없이 체크아웃으로 복귀하며, PayPay 업스트림 처리 실패는 별도 안내 메시지로 치환됩니다.
예시 시나리오: 일본 구매자가 PayPay 로 결제 → 결제창이 `sid` 를 붙여 이 콜백으로 복귀 → 서버가 승인 요청 → 성공 시 주문 결제완료 후 완료 페이지로 리다이렉트. 편의점결제를 선택했다면 같은 흐름이지만 입금대기 상태로 남고, 구매자가 편의점에서 입금하면 그때 완료됩니다.
### POST /plugins/sirsoft-pay_kginicis/payment/cbt/cvs-notify
@@ -554,7 +558,7 @@ Accept: application/json
**에러 응답**
_대표 에러 없음 (공개 조회)._
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
@@ -593,7 +597,7 @@ Accept: application/json
**에러 응답**
_대표 에러 없음 (공개 조회)._
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
@@ -630,7 +634,7 @@ Accept: application/json
**에러 응답**
_대표 에러 없음 (공개 조회)._
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
@@ -669,7 +673,7 @@ Accept: application/json
**에러 응답**
_대표 에러 없음 (공개 조회)._
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
@@ -784,13 +788,13 @@ Accept: application/json
| 이름 | 위치 | 타입 | 필수 | 허용값 | 용도 |
| --- | --- | --- | --- | --- | --- |
| P_STATUS | body | string | 예 | — | 모바일 결제 인증 결과 코드 (`00` = 성공). 그 외 값은 실패이며 `P_RMESG1` 문구로 사용자 취소 여부를 분기한다. |
| P_RMESG1 | body | string | 아니오 | — | 모바일 결제 인증 결과 메시지. '사용자가 결제를 취소' 등 취소 문구 포함 시 오류 없이 체크아웃으로 복귀한다. |
| P_TID | body | string | 아니오 | — | KG 이니시스 거래번호. 서버 승인 요청(`P_REQ_URL`)에 MID 와 함께 전송된다. |
| P_REQ_URL | body | string | 아니오 | — | 서버 승인 API 요청 URL. `idc_name` 과 함께 화이트리스트 검증(SSRF 방어)을 통과해야 호출된다. |
| P_AMT | body | string | 아니오 | — | 결제 금액. 서버 승인 응답의 `P_AMT` 가 없을 때 결제 완료 금액의 폴백으로 사용된다. |
| P_OID | body | string | 아니오 | — | 주문번호. 없으면 콜백 URL 쿼리스트링의 `orderId` 를 폴백으로 사용한다. |
| idc_name | body | string | 아니오 | — | KG 이니시스 IDC 센터 코드(fc/ks/stg). 승인 URL 화이트리스트 검증의 기준값. |
| P_STATUS | body | string | 예 | — | <!-- TODO: 용도 --> |
| P_RMESG1 | body | string | 아니오 | — | <!-- TODO: 용도 --> |
| P_TID | body | string | 아니오 | — | <!-- TODO: 용도 --> |
| P_REQ_URL | body | string | 아니오 | — | <!-- TODO: 용도 --> |
| P_AMT | body | string | 아니오 | — | <!-- TODO: 용도 --> |
| P_OID | body | string | 아니오 | — | <!-- TODO: 용도 --> |
| idc_name | body | string | 아니오 | — | KG 이니시스 IDC 센터 코드(fc/ks/stg). 승인/망취소 URL 화이트리스트 검증의 기준값. |
**요청 예시**
@@ -829,7 +833,11 @@ Content-Type: application/json
**설명**
위 `GET /plugins/sirsoft-pay_kginicis/payment/mobile/callback` 과 동일한 모바일 결제 인증 콜백이며, KG 이니시스가 폼 전송(POST)으로 결과를 돌려보내는 표준 경로입니다. 파라미터가 query 대신 body 로 들어오는 점만 다르고, 서버 승인·화이트리스트 검증·가상계좌 분기·자동 취소·사용자 취소 처리 등 동작과 주의사항은 GET 버전과 동일합니다. 실제 운영에서는 대부분 이 POST 경로로 콜백이 들어옵니다.
모바일 표준결제창(KRW)의 인증 결과를 수신해 서버 승인까지 마무리하는 콜백입니다(GET·POST 동일 처리). 모바일 결제는 결제창 인증 후 KG 이니시스가 이 주소로 결과를 돌려보내고, 서버가 전달받은 승인 요청 URL 로 거래번호를 재전송해 최종 승인을 얻은 뒤 주문을 결제완료 처리하고 결과 페이지로 리다이렉트합니다. GET 은 일부 PG 환경의 리다이렉트 복귀 패턴을 위해 함께 열어 둔 경로로, 동작은 POST 와 같습니다.
주의사항: (1) 응답은 JSON 이 아니라 리다이렉트(302)이며, 실패 시 체크아웃 URL 에 `error`·`message`·`orderId` 쿼리가 붙습니다. (2) 승인 요청 URL 은 콜백 값을 그대로 신뢰하지 않고 IDC 코드 기준 화이트리스트로 검증해 SSRF 를 차단합니다(실패 시 `error=req_url_invalid`). (3) 모바일 표준 응답에는 주문번호가 빠질 수 있어, 없으면 콜백 URL 쿼리스트링의 `orderId` 를 대체로 사용합니다. (4) 승인 결과가 가상계좌면 결제완료 처리를 하지 않고 계좌 정보만 저장해 입금대기로 두며, 완료는 모바일 가상계좌 입금통보 시점입니다. (5) 같은 거래번호가 이미 결제완료면 재처리하지 않고 성공 페이지로 복귀합니다. (6) 승인 후 금액 불일치나 예외가 발생하면 자동 취소를 호출해 PG 측 승인 잔존을 해제하며, 자동 취소마저 실패하면 수동 정산이 필요합니다. (7) 사용자가 결제창을 닫은 취소는 결과 코드만으로 일반 실패와 구분되지 않으므로 결과 메시지의 취소 문구로 판별하며, 이 경우 에러 없이 체크아웃으로 조용히 복귀합니다.
예시 시나리오: 모바일 구매자가 카드 결제를 승인 → KG 이니시스가 이 콜백으로 인증 성공과 승인 요청 URL 을 전송 → 서버가 승인 요청 → 성공 시 주문 결제완료 후 완료 페이지로 리다이렉트.
### POST /plugins/sirsoft-pay_kginicis/payment/mobile/vbank-notify
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Transaction 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Vbank 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Payment 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -8,7 +8,7 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Webhook 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(curl) + 실측 응답 필드 표 + 응답 예시(envelope)
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
@@ -111,6 +111,9 @@ OK
| eventType | body | string | 아니오 | max 64 | 토스 이벤트 종류 (예: `PAYMENT_STATUS_CHANGED`). |
| createdAt | body | string | 아니오 | max 64 | 토스가 이벤트를 생성한 시각. |
| data | body | array | 예 | — | 결제 정보 객체. `data.orderId`(주문번호)와 `data.status`(토스 결제상태)를 읽어 로컬 상태와 대조한다. |
| data.orderId | body | string | 예 | max 100 | <!-- TODO: 용도 --> |
| data.status | body | string | 예 | max 40 | <!-- TODO: 용도 --> |
| data.paymentKey | body | string | 아니오 | max 255 | <!-- TODO: 용도 --> |
**요청 예시**
@@ -125,7 +128,10 @@ Content-Type: application/json
"createdAt": "예시값",
"data": [
"예시값"
]
],
"data.orderId": "예시값",
"data.status": "예시값",
"data.paymentKey": "예시값"
}
```
@@ -4,11 +4,12 @@
> 아래 표는 자동 생성됩니다. 각 문서를 열면 엔드포인트별 파라미터·응답·예시를 볼 수 있습니다.
<!-- @generated:start:api-readme-index -->
- **문서 수**: 1 · **엔드포인트 수**: 1
- **문서 수**: 2 · **엔드포인트 수**: 3
| 문서 | 도메인 | 엔드포인트 |
| --- | --- | --- |
| [identity.md](identity.md) | `identity` | 1 |
| [plugin.md](plugin.md) | `plugin` | 2 |
<!-- @generated:end -->
@@ -8,8 +8,8 @@
```text
1. 이 문서는 실제 API 호출로 실측한 Identity 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 실측 응답 필드 표
3. 응답 필드의 예시값은 실제 호출 응답에서 관측된 값입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
@@ -42,6 +42,22 @@ Authorization: Bearer {YOUR_TOKEN}
<!-- 실측 응답에 필드 없음(빈 목록 등) — 데이터가 있는 상태로 재실측하거나 사람이 작성. -->
**응답 예시**
<!-- @probed -->
```http
HTTP/1.1 200
```
```json
{
"success": true,
"message": "messages.success",
"data": null
}
```
**에러 응답**
| 상태코드 | 의미 | 발생 조건 |
@@ -0,0 +1,89 @@
# Plugin API 레퍼런스
> **소유**: plugin `sirsoft-verification_kginicis` · **생성**: `php artisan api:docgen` (실측 기반). @generated 블록은 재생성 시 갱신되며, 사람이 작성한 설명은 보존됩니다.
---
## TL;DR (5초 요약)
```text
1. 이 문서는 실제 API 호출로 실측한 Plugin 엔드포인트 레퍼런스입니다
2. 각 엔드포인트: 메서드/URI/권한 + 요청 파라미터 표 + 요청 예시(raw HTTP) + 실측 응답 필드 표 + 응답 예시(envelope)
3. 응답 필드의 예시값·응답 예시 JSON 은 실제 호출 응답에서 관측된 값입니다
4. 갱신: 코드 변경 후 php artisan api:docgen 재실행
5. 설명(TODO) 칸은 사람이 채웁니다
```
---
### POST /plugins/sirsoft-verification_kginicis/plugin/inicis/callback
<!-- @generated:start:web.plugins.sirsoft-verification_kginicis.plugin.verification_kginicis.callback -->
- **라우트명**: `web.plugins.sirsoft-verification_kginicis.plugin.verification_kginicis.callback`
- **컨트롤러**: `Plugins\Sirsoft\VerificationKginicis\Http\Controllers\InicisCallbackController@handle`
- **인증/권한**: 공개 (인증 불필요)
**요청 파라미터**
_요청 파라미터 없음._
**요청 예시**
```http
POST /plugins/sirsoft-verification_kginicis/plugin/inicis/callback HTTP/1.1
Host: api.example.com
Accept: application/json
```
**응답 필드** (`data` 내부)
<!-- 실측 제외: http-302 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
<!-- 실측 제외: http-302 — 응답 예시는 사람이 작성하세요. -->
**에러 응답**
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
**설명** <!-- TODO: 이 엔드포인트의 용도·주의사항·예시 시나리오를 작성하세요 -->
### GET /plugins/sirsoft-verification_kginicis/plugin/inicis/popup-bridge
<!-- @generated:start:web.plugins.sirsoft-verification_kginicis.plugin.verification_kginicis.popup-bridge -->
- **라우트명**: `web.plugins.sirsoft-verification_kginicis.plugin.verification_kginicis.popup-bridge`
- **컨트롤러**: `Plugins\Sirsoft\VerificationKginicis\Http\Controllers\InicisPopupBridgeController@show`
- **인증/권한**: 공개 (인증 불필요)
**요청 파라미터**
_요청 파라미터 없음._
**요청 예시**
```http
GET /plugins/sirsoft-verification_kginicis/plugin/inicis/popup-bridge HTTP/1.1
Host: api.example.com
Accept: application/json
```
**응답 필드** (`data` 내부)
<!-- 실측 제외: http-200 — 응답 필드는 사람이 작성하세요. -->
**응답 예시**
<!-- 실측 제외: http-200 — 응답 예시는 사람이 작성하세요. -->
**에러 응답**
_대표 에러 없음 (공개 조회). <!-- TODO: 도메인 특이 에러가 있으면 보강 -->_
<!-- @generated:end -->
**설명** <!-- TODO: 이 엔드포인트의 용도·주의사항·예시 시나리오를 작성하세요 -->