무통장입금 주문의 현금영수증 발급을 관리자·회원·비회원 세 경로에서 제공하고,
입금이 확인되면 자동 발급하며, 부분환불로 금액이 바뀌면 전액취소 후 재발급한다.
발급 프로바이더에 종속되지 않도록 발급/취소는 필터 훅으로 위임한다.
자동발급 리스너는 결제완료 전이(after_payment_complete)와 입금만 기록
(after_deposit_recorded) 두 경로를 모두 구독한다 — 후자가 없으면 관리자가
"입금만 기록"했을 때 자동발급이 통째로 누락된다.
금액 동기화(syncFromOrder)는 트랜잭션이 닫힌 뒤에 부른다. 재발급 실패 이력은
국세청 신고 누락을 막는 원장이라 롤백에 휩쓸리면 안 되고, 프로바이더 왕복 2회
동안 DB 잠금을 붙들 수 없기 때문이다. 환불은 이미 확정됐으므로 어떤 실패도
호출부로 전파하지 않고 FAILED 이력 + 로그로 남겨 관리자 수동 복구에 맡긴다.
식별번호는 재발급용으로만 암호화 보관하고 구매확정 시점에 폐기한다.
그 시점을 잡기 위해 order.after_purchase_confirmed 훅을 신설했다.
함께 고친 사전 결함:
- 취소 시 total_cash_equivalent_amount 가 재계산되지 않아 syncFromOrder 가
"금액 변동 없음"으로 판정, 부분환불 후 재발급이 아예 동작하지 않았다.
산정 규칙을 PaymentMethodEnum::resolveCashEquivalentAmount 로 SSoT 화해
주문 생성 시점과 취소 재계산 시점이 같은 규칙을 쓰게 했다.
- 현금영수증 발급이 payment.receipt_url 을 덮어써 카드 매출전표 URL 이
유실됐다. 한 컬럼이 두 의미를 갖던 문제로, 현금영수증 URL 은 이력 테이블이
보관하도록 분리했다.
- OrderService::confirmOption 이 confirmed_at 을 무조건 now 로 덮어썼다
(v0.16.1 부터 존재). 재확정 시 최초 확정 시점이 소실되고 구매확정 훅이
중복 발화한다. OrderOptionService 와 대칭으로 멱등 가드를 넣었다.
- 코어 api:docgen 이 사람이 작성한 API 문서를 재생성 때마다 지웠다.
@generated 블록 안의 표 셀·응답 본문이 대상이었고, extractGeneratedBlock
이 앞의 `## ` 헤딩까지 거슬러 올라가 여러 엔드포인트를 한 덩어리로 반환하던
문제도 함께 고쳤다. 실측 산출 응답 예시에 @probed 출처 마커를 붙여, 마커가
없는 본문은 사람 작성분으로 보고 보존한다 — 실측 1회의 표본은 사람이 코드에서
읽어낸 사실보다 좁으므로 실측은 기본값이지 덮어쓰기 권한이 아니다.
ParameterDescriber 가 {order} 같은 path 파라미터를 "정렬 방향 asc/desc" 로
설명하던 오염도 정정했다.
47 lines
2.3 KiB
Markdown
47 lines
2.3 KiB
Markdown
# API 레퍼런스 문서 목차
|
|
|
|
> **소유**: 모듈 `sirsoft-ecommerce` · **생성**: `php artisan api:docgen` (실측 기반).
|
|
> 아래 표는 자동 생성됩니다. 각 문서를 열면 엔드포인트별 파라미터·응답·예시를 볼 수 있습니다.
|
|
|
|
<!-- @generated:start:api-readme-index -->
|
|
- **문서 수**: 33 · **엔드포인트 수**: 239
|
|
|
|
| 문서 | 도메인 | 엔드포인트 |
|
|
| --- | --- | --- |
|
|
| [addresses.md](addresses.md) | `addresses` | 6 |
|
|
| [brands.md](brands.md) | `brands` | 6 |
|
|
| [cart.md](cart.md) | `cart` | 11 |
|
|
| [categories.md](categories.md) | `categories` | 14 |
|
|
| [category-image.md](category-image.md) | `category-image` | 1 |
|
|
| [checkout.md](checkout.md) | `checkout` | 5 |
|
|
| [claim-reasons.md](claim-reasons.md) | `claim-reasons` | 8 |
|
|
| [coupons.md](coupons.md) | `coupons` | 4 |
|
|
| [currency.md](currency.md) | `currency` | 2 |
|
|
| [dashboard.md](dashboard.md) | `dashboard` | 4 |
|
|
| [extra-fee-templates.md](extra-fee-templates.md) | `extra-fee-templates` | 10 |
|
|
| [guest.md](guest.md) | `guest` | 7 |
|
|
| [inquiries.md](inquiries.md) | `inquiries` | 10 |
|
|
| [mileage.md](mileage.md) | `mileage` | 3 |
|
|
| [mileage-transactions.md](mileage-transactions.md) | `mileage-transactions` | 5 |
|
|
| [options.md](options.md) | `options` | 3 |
|
|
| [orders.md](orders.md) | `orders` | 27 |
|
|
| [payments.md](payments.md) | `payments` | 1 |
|
|
| [presets.md](presets.md) | `presets` | 4 |
|
|
| [product-common-infos.md](product-common-infos.md) | `product-common-infos` | 6 |
|
|
| [product-image.md](product-image.md) | `product-image` | 1 |
|
|
| [product-labels.md](product-labels.md) | `product-labels` | 6 |
|
|
| [product-notice-templates.md](product-notice-templates.md) | `product-notice-templates` | 7 |
|
|
| [products.md](products.md) | `products` | 31 |
|
|
| [promotion-coupons.md](promotion-coupons.md) | `promotion-coupons` | 9 |
|
|
| [review-image.md](review-image.md) | `review-image` | 1 |
|
|
| [reviews.md](reviews.md) | `reviews` | 12 |
|
|
| [settings.md](settings.md) | `settings` | 10 |
|
|
| [shipping-carriers.md](shipping-carriers.md) | `shipping-carriers` | 7 |
|
|
| [shipping-country.md](shipping-country.md) | `shipping-country` | 2 |
|
|
| [shipping-policies.md](shipping-policies.md) | `shipping-policies` | 11 |
|
|
| [users.md](users.md) | `users` | 2 |
|
|
| [wishlist.md](wishlist.md) | `wishlist` | 3 |
|
|
|
|
<!-- @generated:end -->
|
|
|