Glowb Dev Docs
Admin APIAdmin Campaign API

POST /ai/admin/campaigns/{campaignNo}/terminate

캠페인 강제 종료 (관리자 전용)

캠페인 강제 종료

진행 중인 캠페인을 관리자 권한으로 강제 종료합니다. 계약 조항에 따라 최초 입금액의 20%를 착수금으로 귀속시키고, 잔여 금액을 기업 글로벌 크레딧으로 환급합니다.

본 API는 관리자 전용입니다. 진행 중인 신청/계약/콘텐츠 데이터는 그대로 유지되며, 캠페인 단계만 CAMPAIGN_COMPLETED로 전환됩니다. 별도의 종료 사유 필드는 기록되지 않습니다.

HTTP 요청

POST /ai/admin/campaigns/{campaignNo}/terminate?waiveForfeit=false
Authorization: Bearer {access_token}

요청 본문은 없습니다. 처리자(adminId)는 JWT의 인증 컨텍스트에서 자동으로 추출됩니다.

Path / Query Parameters

파라미터위치타입필수설명
campaignNopathInteger예캠페인 번호 (SaaS 이후 캠페인만 지원)
waiveForfeitqueryboolean아니오true 면 착수금 귀속 없이 전액을 기업 크레딧으로 반환 (기본 false). 결제 자체를 취소해 줘야 해서 카드 환불(/ai/admin/finance/card-refund)로 이어갈 때 사용

처리 흐름

  1. 유효성 검증
    • 캠페인 존재 확인
    • 레거시 캠페인(SaaS 이전) 거부
    • 이미 CAMPAIGN_COMPLETED 상태인 캠페인 거부
  2. 착수금 귀속 계산 — 최초 CAMPAIGN_DEPOSIT 입금액 × 20%
  3. 환급금 계산 — max(0, 총 입금액 − 착수금)
  4. 회계 기록
    • CAMPAIGN_FORFEIT 트랜잭션 (회계 마커, 잔액 변동 없음)
    • 최초 유효 CAMPAIGN_DEPOSIT부터 반환액을 반영해 각 행을 0원까지 조정하고, 남은 반환액은 다음 입금에 반영합니다. CAMPAIGN_REFUND 행은 생성하지 않습니다.
    • 최초 변경 행부터 이후 balanceAfter를 재계산하고 마지막 잔액으로 기업 크레딧을 설정합니다. 잔액 합산 규칙은 어드민 원장 재계산과 같아 BUDGET_ADJUST만 제외합니다.
    • 재계산 구간은 최초 변경 행 이후뿐입니다. 그 앞 구간의 기존 잔액 오차는 건드리지 않고, 구간 안의 오차는 어드민 전체 재계산과 같은 방식으로 함께 교정됩니다. 이 경우 기업 크레딧 변동이 환급액보다 크거나 작을 수 있으며, 그 차이는 서버 로그에 교정분으로 남습니다.
    • 정산 전 예산과 반환액은 종료 스냅샷에, 행 변경 전후는 감사 로그에 보존합니다.
  5. LOCKED 예산 전부 해제 — 정산 전 LOCKED 금액·개수를 스냅샷에 보존한 뒤 LOCKED 행을 UNLOCKED로 변경합니다.
  6. 상태 전환 — campaign_sub_step = CAMPAIGN_COMPLETED, campaign_completed_at = 현재 시각 (최초 전환 시에만)
  7. 슬랙 알림 발송 — DB 커밋 이후 결제-정산 알리미 채널(slack.payment-alert.channel-id)로 전송

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "캠페인이 강제 종료되었습니다.",
  "data": {
    "collabNo": 1234,
    "initialDeposit": 5000000,
    "totalBudget": 5500000,
    "forfeitAmount": 1000000,
    "refundAmount": 4500000,
    "unlockedBudgetCount": 3,
    "remainCreditAfter": 4800000
  }
}

응답 필드

필드타입설명
collabNoInteger캠페인 번호
initialDepositInteger정산 전 최초 유효 입금액 (정산 스냅샷 보존)
totalBudgetInteger정산 전 총 입금액 (추가입금 포함, 정산 스냅샷 보존)
forfeitAmountInteger착수금 귀속 금액 (initialDeposit × 20%, waiveForfeit=true 면 0)
refundAmountInteger기업 크레딧으로 환급된 금액
unlockedBudgetCountInteger해제된 LOCKED 예산 행 수
remainCreditAfterInteger환급 후 기업 잔여 크레딧

에러 응답

상태 코드code사례
404INVALID_DATASaaS 이전 캠페인 (기존 오류 응답 유지)
404INVALID_DATA이미 완료·정산된 캠페인 (추가 반환 없음)
404INVALID_DATA기업 정보 누락 등
404INVALID_COLLAB캠페인 없음
409SETTLEMENT_LEDGER_MISMATCH정산 스냅샷·정산 표시가 서로 어긋나거나 원장 행에 필수값 누락
409SETTLEMENT_DEPOSIT_INVALID입금·취소 내역 또는 예산 데이터 불일치
422SETTLEMENT_AMOUNT_OVERFLOW정산 금액이 저장 범위 초과
401—인증 실패

정책 배경

기업과의 계약서 본문에는 다음 조항이 포함됩니다 (BusinessContractPdfService 참고):

영상 제작 캠페인 신청 시, 총예산의 20%를 착수금으로 선차감합니다. 캠페인이 정상 진행될 경우 해당 금액은 크레딧 사용분으로 자동 전환되나, "갑"의 사정으로 캠페인이 미진행 또는 최초 캠페인 설정 예산의 80% 이하가 사용될 경우 해당 착수금은 "을"의 행정 및 준비 비용으로 귀속되어 환불되지 않습니다.

본 API는 위 조항을 시스템화한 것으로, 모집 시작 이전의 단순 결제 취소(POST /campaign/{collabNo}/cancel, 100% 환불)와는 구분됩니다.

waiveForfeit=true 는 위 조항을 적용하지 않고 전액을 반환하는 관리자 재량 경로입니다. 정산 스냅샷의 settlementType 은 FORCED 대신 FORCED_FULL 로 남고, CAMPAIGN_FORFEIT 마커 행은 기록하지 않습니다. 반환된 크레딧을 카드까지 돌려주려면 이어서 카드 결제 취소를 호출합니다.

진행 중인 인플루언서 대금 정산은 본 흐름의 범위 밖이며 별도 운영 절차로 처리합니다.

API 테스트

최초 100만 원과 추가 50만 원 중 130만 원을 반환하면 두 예산 행의 금액은 각각 0원과 -20만 원으로 남습니다. 종료 재호출은 추가 반환하지 않으며, 기존 환급 내역은 소급 변환하지 않습니다.

On this page