- 18개 엔드포인트 전체 명세 (CRUD, 상태변경, 일괄생성, 미리보기 등) - 4대보험/근로소득세 계산 엔진 설명 - 상태 흐름도 (draft → confirmed → paid) - 프론트엔드 구현 가이드 및 UI 와이어프레임 - INDEX.md에 문서 등록
31 KiB
급여관리 API 명세
작성일: 2026-03-11 상태: 개발 완료 (API 배포됨) Base URL:
api.codebridge-x.com(운영) /api.dev.codebridge-x.com(개발)
1. 개요
월별 급여를 등록/확정/지급하고, 4대보험과 근로소득세를 자동 계산하는 급여관리 API이다.
1.1 인증
모든 요청에 다음 헤더가 필요하다:
X-API-KEY: {api_key}
Authorization: Bearer {token}
1.2 공통 응답 형식
{
"success": true,
"message": "조회 성공",
"data": { ... }
}
에러 시:
{
"success": false,
"message": "에러 메시지"
}
1.3 엔드포인트 요약
| # | Method | Path | 설명 |
|---|---|---|---|
| 1 | GET | /api/v1/payrolls |
급여 목록 (페이지네이션) |
| 2 | POST | /api/v1/payrolls |
급여 등록 |
| 3 | GET | /api/v1/payrolls/summary |
월간 요약 통계 |
| 4 | POST | /api/v1/payrolls/calculate |
급여 일괄 계산 (draft 재계산) |
| 5 | POST | /api/v1/payrolls/calculate-preview |
계산 미리보기 (저장 안 함) |
| 6 | POST | /api/v1/payrolls/bulk-confirm |
일괄 확정 |
| 7 | POST | /api/v1/payrolls/bulk-generate |
재직사원 일괄 생성 |
| 8 | POST | /api/v1/payrolls/copy-from-previous |
전월 급여 복사 |
| 9 | GET | /api/v1/payrolls/{id} |
급여 상세 |
| 10 | PUT | /api/v1/payrolls/{id} |
급여 수정 |
| 11 | DELETE | /api/v1/payrolls/{id} |
급여 삭제 |
| 12 | POST | /api/v1/payrolls/{id}/confirm |
확정 |
| 13 | POST | /api/v1/payrolls/{id}/unconfirm |
확정 취소 |
| 14 | POST | /api/v1/payrolls/{id}/pay |
지급 처리 |
| 15 | POST | /api/v1/payrolls/{id}/unpay |
지급 취소 (슈퍼관리자) |
| 16 | GET | /api/v1/payrolls/{id}/payslip |
급여명세서 조회 |
| 17 | GET | /api/v1/payrolls/settings |
급여 설정 조회 |
| 18 | PUT | /api/v1/payrolls/settings |
급여 설정 수정 |
2. 상태 흐름도
┌────────────────┐
│ draft (작성중) │
└───┬──────┬─────┘
│ ▲
│ confirm │ unconfirm
▼ │
┌────────────────┐
│confirmed (확정) │
└───┬──────┬─────┘
│ ▲
│ pay │ unpay*
▼ │
┌────────────────┐
│ paid (지급완료)│
└────────────────┘
* unpay는 슈퍼관리자 전용 (paid → draft 초기화)
2.1 상태값
| 상태 | 값 | 설명 | UI 배지 색상 |
|---|---|---|---|
| 작성중 | draft |
수정/삭제/확정 가능 | gray |
| 확정 | confirmed |
확정취소/지급 가능 | blue |
| 지급완료 | paid |
상세보기만 가능 | green |
2.2 상태별 가능한 작업
| 상태 | 일반 사용자 | 슈퍼관리자 |
|---|---|---|
draft |
수정, 삭제, 확정, 일괄계산 | 동일 |
confirmed |
확정취소, 지급처리 | + 수정 |
paid |
상세보기만 | + 수정, 지급취소 |
3. 급여 계산 엔진
3.1 과세표준
과세표준 = 총지급액(gross_salary) - 식대(bonus)
bonus필드는 식대(비과세) 항목이다- 4대보험과 세금은 과세표준 기준으로 계산한다
3.2 4대보험 자동 계산
| 항목 | 계산식 | 기본 요율 | 비고 |
|---|---|---|---|
| 건강보험 | 과세표준 × 3.545% |
3.545% | 10원 단위 절삭 |
| 장기요양보험 | 건강보험료 × 0.9082% |
0.9082% | 건강보험료 기준, 10원 단위 절삭 |
| 국민연금 | 과세표준 × 4.5% |
4.5% | 상한 590만 / 하한 37만 적용 |
| 고용보험 | 과세표준 × 0.9% |
0.9% | 10원 단위 절삭 |
모든 보험료는 10원 단위 절삭 (floor to nearest 10)
3.3 근로소득세
- 770천원 미만: 0원
- 770~10,000천원: 간이세액표(DB) 조회 (연도, 월급여 천원단위, 가족수)
- 10,000천원 초과: 공식 계산 (소득세법 시행령 별표2)
3.4 지방소득세
지방소득세 = 근로소득세 × 10% (10원 단위 절삭)
3.5 가족수 (공제대상가족수)
- 기본: 본인 1인
- TenantUserProfile의
json_extra.dependents배열에서is_dependent: true인 수만큼 추가 - 범위: 최소 1, 최대 11
3.6 요율 설정
요율은 payroll_settings 테이블에서 테넌트별로 관리한다. 기본값은 위 표와 동일하며, 설정 API(17, 18번)를 통해 변경 가능하다.
4. 데이터 모델
4.1 Payroll 객체
{
"id": 1,
"tenant_id": 1,
"user_id": 5,
"pay_year": 2026,
"pay_month": 3,
"base_salary": "3500000",
"overtime_pay": "0",
"bonus": "200000",
"allowances": [
{"name": "직책수당", "amount": 300000},
{"name": "교통비", "amount": 100000}
],
"gross_salary": "4100000",
"income_tax": "117750",
"resident_tax": "11770",
"health_insurance": "138220",
"long_term_care": "1250",
"pension": "175500",
"employment_insurance": "35100",
"deductions": [
{"name": "대출상환", "amount": 500000}
],
"options": null,
"total_deductions": "979590",
"net_salary": "3120410",
"status": "draft",
"confirmed_at": null,
"confirmed_by": null,
"paid_at": null,
"withdrawal_id": null,
"note": null,
"created_by": 1,
"updated_by": 1,
"created_at": "2026-03-11T10:00:00.000000Z",
"updated_at": "2026-03-11T10:00:00.000000Z",
"user": {
"id": 5,
"name": "홍길동",
"email": "hong@example.com"
},
"creator": {
"id": 1,
"name": "관리자"
}
}
4.2 필드 설명
지급 항목:
| 필드 | 타입 | 설명 |
|---|---|---|
base_salary |
decimal(0) | 기본급 |
overtime_pay |
decimal(0) | 고정연장근로수당 |
bonus |
decimal(0) | 식대 (비과세) |
allowances |
json | 추가 수당 [{name, amount}] |
gross_salary |
decimal(0) | 총지급액 (자동 계산) |
법정 공제 항목 (자동 계산):
| 필드 | 타입 | 설명 |
|---|---|---|
income_tax |
decimal(0) | 근로소득세 |
resident_tax |
decimal(0) | 지방소득세 |
health_insurance |
decimal(0) | 건강보험료 |
long_term_care |
decimal(0) | 장기요양보험료 |
pension |
decimal(0) | 국민연금 |
employment_insurance |
decimal(0) | 고용보험료 |
기타 공제:
| 필드 | 타입 | 설명 |
|---|---|---|
deductions |
json | 기타공제 [{name, amount}] |
결과:
| 필드 | 타입 | 설명 |
|---|---|---|
total_deductions |
decimal(0) | 총공제액 (법정 + 기타) |
net_salary |
decimal(0) | 실수령액 = gross - total_deductions |
상태:
| 필드 | 타입 | 설명 |
|---|---|---|
status |
string | draft / confirmed / paid |
confirmed_at |
datetime | 확정 일시 |
confirmed_by |
int | 확정자 user_id |
paid_at |
datetime | 지급 일시 |
withdrawal_id |
int | 연결된 출금 ID |
5. API 상세
5.1 급여 목록 조회
GET /api/v1/payrolls
Query Parameters:
| 파라미터 | 타입 | 필수 | 설명 | 예시 |
|---|---|---|---|---|
year |
int | - | 귀속연도 | 2026 |
month |
int | - | 귀속월 | 3 |
user_id |
int | - | 사원 ID | 5 |
status |
string | - | 상태 필터 | draft |
department_id |
int | - | 부서 필터 | 2 |
search |
string | - | 사원명 검색 | 홍길동 |
sort_by |
string | - | 정렬 기준 (기본: pay_year) |
net_salary |
sort_dir |
string | - | 정렬 방향 (기본: desc) |
asc |
per_page |
int | - | 페이지당 건수 (기본: 20) | 50 |
page |
int | - | 페이지 번호 | 1 |
응답 (200):
{
"success": true,
"message": "조회 성공",
"data": {
"current_page": 1,
"data": [
{
"id": 1,
"user_id": 5,
"pay_year": 2026,
"pay_month": 3,
"base_salary": "3500000",
"gross_salary": "4100000",
"total_deductions": "979590",
"net_salary": "3120410",
"status": "draft",
"user": {"id": 5, "name": "홍길동", "email": "hong@example.com"},
"creator": {"id": 1, "name": "관리자"}
}
],
"per_page": 20,
"total": 15,
"last_page": 1
}
}
프론트엔드 참고:
- 연월을 선택하는 UI를 제공하면
year+month필터 사용 sort_by=period전달 시pay_year+pay_month복합 정렬
5.2 급여 등록
POST /api/v1/payrolls
Request Body:
{
"user_id": 5,
"pay_year": 2026,
"pay_month": 3,
"base_salary": 3500000,
"overtime_pay": 0,
"bonus": 200000,
"allowances": [
{"name": "직책수당", "amount": 300000}
],
"deductions": [
{"name": "대출상환", "amount": 500000}
],
"family_count": 3,
"deduction_overrides": {
"income_tax": 100000,
"pension": 170000
},
"note": "메모"
}
필드 규칙:
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
user_id |
int | ✅ | 급여 대상 사원 ID |
pay_year |
int | ✅ | 귀속연도 (2000~2100) |
pay_month |
int | ✅ | 귀속월 (1~12) |
base_salary |
numeric | ✅ | 기본급 (0 이상) |
overtime_pay |
numeric | - | 고정연장근로수당 |
bonus |
numeric | - | 식대 (비과세) |
allowances |
array | - | 추가수당 [{name, amount}] |
deductions |
array | - | 기타공제 [{name, amount}] |
family_count |
int | - | 공제대상가족수 (1~11, 미전달 시 자동) |
deduction_overrides |
object | - | 법정공제 수동 입력 (아래 참고) |
note |
string | - | 메모 (최대 1000자) |
deduction_overrides 필드:
자동 계산된 법정 공제 항목을 수동으로 덮어쓸 때 사용한다. 지정한 항목만 덮어쓰고, 나머지는 자동 계산값을 유지한다.
{
"income_tax": 100000,
"resident_tax": 10000,
"health_insurance": 140000,
"long_term_care": 1300,
"pension": 170000,
"employment_insurance": 35000
}
응답 (201):
{
"success": true,
"message": "등록 성공",
"data": { /* Payroll 객체 (4.1 참고) */ }
}
에러:
| 상황 | 응답 코드 | 메시지 |
|---|---|---|
| 동일 연월+사원 중복 | 400 | 해당 연월에 이미 급여가 등록되어 있습니다. |
| 검증 실패 | 422 | 요청 데이터 검증에 실패했습니다. |
5.3 월간 요약 통계
GET /api/v1/payrolls/summary?year=2026&month=3
Query Parameters:
| 파라미터 | 타입 | 필수 | 기본값 |
|---|---|---|---|
year |
int | - | 현재 연도 |
month |
int | - | 현재 월 |
응답 (200):
{
"success": true,
"message": "조회 성공",
"data": {
"year": 2026,
"month": 3,
"total_count": 15,
"draft_count": 3,
"confirmed_count": 7,
"paid_count": 5,
"total_gross": 62500000,
"total_deductions": 15800000,
"total_net": 46700000
}
}
프론트엔드 참고:
- 대시보드 카드에
total_count,total_gross,total_net표시 - 상태별 카운트로 진행 상태 게이지 표현 가능
5.4 급여 일괄 계산
기존 draft 상태 급여의 공제 항목을 재계산한다.
POST /api/v1/payrolls/calculate
Request Body:
{
"year": 2026,
"month": 3,
"user_ids": [5, 8, 12]
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
year |
int | ✅ | 대상 연도 |
month |
int | ✅ | 대상 월 |
user_ids |
array | - | 특정 사원만 지정 (미전달 시 전체) |
응답 (200):
{
"success": true,
"message": "급여가 일괄 계산되었습니다.",
"data": [
{ /* 재계산된 Payroll 객체들 */ }
]
}
주의:
confirmed/paid상태 급여는 재계산하지 않는다 (draft만 대상).
5.5 계산 미리보기
급여 데이터를 저장하지 않고 계산 결과만 미리 확인한다. 급여 등록/수정 폼에서 실시간 미리보기용.
POST /api/v1/payrolls/calculate-preview
Request Body:
{
"user_id": 5,
"base_salary": 3500000,
"overtime_pay": 0,
"bonus": 200000,
"allowances": [
{"name": "직책수당", "amount": 300000}
],
"deductions": [
{"name": "대출상환", "amount": 500000}
]
}
응답 (200):
{
"success": true,
"message": "계산 완료",
"data": {
"gross_salary": 4100000,
"taxable_base": 3900000,
"income_tax": 117750,
"resident_tax": 11770,
"health_insurance": 138220,
"long_term_care": 1250,
"pension": 175500,
"employment_insurance": 35100,
"total_deductions": 979590,
"net_salary": 3120410,
"family_count": 3
}
}
프론트엔드 참고:
user_id를 전달하면 해당 사원의 가족수를 자동 반영user_id미전달 시 가족수 1로 계산- 폼 입력값이 변경될 때마다 호출하여 실시간 계산 결과를 표시 (debounce 300ms 권장)
5.6 일괄 확정
해당 월의 모든 draft 급여를 한 번에 confirmed로 변경한다.
POST /api/v1/payrolls/bulk-confirm
Request Body:
{
"year": 2026,
"month": 3
}
응답 (200):
{
"success": true,
"message": "급여가 일괄 확정되었습니다.",
"data": {
"count": 12
}
}
5.7 재직사원 일괄 생성
해당 연월에 재직 중인(employee_status=active) 모든 사원의 급여를 자동 생성한다.
POST /api/v1/payrolls/bulk-generate
Request Body:
{
"year": 2026,
"month": 3
}
응답 (200):
{
"success": true,
"message": "급여가 일괄 생성되었습니다.",
"data": {
"created": 12,
"skipped": 3
}
}
동작 설명:
- 사원별 연봉 정보(
json_extra.salary_info.annual_salary)에서÷12로 월 기본급 산출 - 이미 존재하는 사원은
skipped처리 (중복 생성하지 않음) - 연봉 정보가 없는 사원도 기본급 0으로 생성됨
- 모든 급여는
draft상태로 생성됨
프론트엔드 참고:
- 매월 초에 "일괄 생성" 버튼을 눌러 해당 월 급여를 초기화
created/skipped결과를 토스트 메시지로 표시
5.8 전월 급여 복사
전월 급여 데이터를 현재 월로 복사한다. 매월 동일한 급여 구조를 유지할 때 사용.
POST /api/v1/payrolls/copy-from-previous
Request Body:
{
"year": 2026,
"month": 3
}
응답 (200):
{
"success": true,
"message": "전월 급여가 복사되었습니다.",
"data": {
"created": 15,
"skipped": 0
}
}
동작 설명:
- 지급/공제 항목을 전월 그대로 복사 (
base_salary,allowances,deductions등) - 상태는
draft로 초기화 - 이미 존재하는 사원은
skipped처리 - 1월 요청 시 전년 12월 데이터 참조
에러:
| 상황 | 응답 코드 | 메시지 |
|---|---|---|
| 전월 데이터 없음 | 400 | 전월 급여 데이터가 없습니다. |
5.9 급여 상세 조회
GET /api/v1/payrolls/{id}
응답 (200):
{
"success": true,
"message": "조회 성공",
"data": {
"id": 1,
"user": {"id": 5, "name": "홍길동", "email": "hong@example.com"},
"confirmer": {"id": 1, "name": "관리자"},
"withdrawal": null,
"creator": {"id": 1, "name": "관리자"},
/* ... 전체 Payroll 필드 */
}
}
5.10 급여 수정
PUT /api/v1/payrolls/{id}
Request Body:
{
"base_salary": 3600000,
"overtime_pay": 100000,
"bonus": 200000,
"allowances": [
{"name": "직책수당", "amount": 300000}
],
"deductions": [
{"name": "대출상환", "amount": 500000}
],
"deduction_overrides": {
"pension": 175000
},
"_is_super_admin": false,
"note": "기본급 인상 반영"
}
필드 규칙:
_is_super_admin: true전달 시confirmed/paid상태에서도 수정 가능deduction_overrides로 법정 공제 항목을 수동 변경 가능- 전달하지 않은 필드는 기존값 유지
에러:
| 상황 | 응답 코드 | 메시지 |
|---|---|---|
| draft 아닌 상태에서 수정 | 400 | 작성중 상태의 급여만 수정할 수 있습니다. |
| 연월/사원 변경 시 중복 | 400 | 해당 연월에 이미 급여가 등록되어 있습니다. |
5.11 급여 삭제
DELETE /api/v1/payrolls/{id}
응답 (200):
{
"success": true,
"message": "삭제 성공",
"data": null
}
draft상태에서만 삭제 가능. Soft delete 처리.
5.12 확정
POST /api/v1/payrolls/{id}/confirm
Request Body: 없음
응답 (200):
{
"success": true,
"message": "급여가 확정되었습니다.",
"data": {
"id": 1,
"status": "confirmed",
"confirmed_at": "2026-03-11T14:30:00.000000Z",
"confirmer": {"id": 1, "name": "관리자"}
}
}
5.13 확정 취소
POST /api/v1/payrolls/{id}/unconfirm
Request Body: 없음
응답 (200):
{
"success": true,
"message": "급여 확정이 취소되었습니다.",
"data": {
"id": 1,
"status": "draft",
"confirmed_at": null,
"confirmed_by": null
}
}
confirmed상태에서만 가능.draft로 되돌린다.
5.14 지급 처리
POST /api/v1/payrolls/{id}/pay
Request Body:
{
"withdrawal_id": 42
}
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
withdrawal_id |
int | - | 연결할 출금 내역 ID |
응답 (200):
{
"success": true,
"message": "급여가 지급 처리되었습니다.",
"data": {
"id": 1,
"status": "paid",
"paid_at": "2026-03-25T09:00:00.000000Z",
"withdrawal": { "id": 42, "..." : "..." }
}
}
5.15 지급 취소
POST /api/v1/payrolls/{id}/unpay
Request Body: 없음
슈퍼관리자 전용.
paid→draft로 초기화. 확정/지급 이력 모두 제거.
응답 (200):
{
"success": true,
"message": "급여 지급이 취소되었습니다.",
"data": {
"id": 1,
"status": "draft",
"confirmed_at": null,
"paid_at": null,
"withdrawal_id": null
}
}
5.16 급여명세서 조회
GET /api/v1/payrolls/{id}/payslip
응답 (200):
{
"success": true,
"message": "조회 성공",
"data": {
"payroll": { /* 전체 Payroll 객체 */ },
"period": "2026년 03월",
"employee": {
"id": 5,
"name": "홍길동",
"email": "hong@example.com"
},
"earnings": {
"base_salary": 3500000,
"overtime_pay": 0,
"bonus": 200000,
"allowances": [
{"name": "직책수당", "amount": 300000},
{"name": "교통비", "amount": 100000}
],
"allowances_total": 400000,
"gross_total": 4100000
},
"deductions": {
"income_tax": 117750,
"resident_tax": 11770,
"health_insurance": 138220,
"long_term_care": 1250,
"pension": 175500,
"employment_insurance": 35100,
"other_deductions": [
{"name": "대출상환", "amount": 500000}
],
"other_total": 500000,
"total": 979590
},
"net_salary": 3120410,
"status": "confirmed",
"status_label": "확정",
"paid_at": null
}
}
프론트엔드 참고:
earnings구조로 지급 항목 테이블 구성deductions구조로 공제 항목 테이블 구성period,employee,net_salary로 명세서 헤더 구성- 인쇄용 레이아웃은 A4 세로 기준 권장
5.17 급여 설정 조회
GET /api/v1/payrolls/settings
응답 (200):
{
"success": true,
"message": "조회 성공",
"data": {
"id": 1,
"tenant_id": 1,
"income_tax_rate": "0.00",
"resident_tax_rate": "10.00",
"health_insurance_rate": "3.545",
"long_term_care_rate": "0.9082",
"pension_rate": "4.500",
"employment_insurance_rate": "0.900",
"pension_max_salary": "5900000.00",
"pension_min_salary": "370000.00",
"pay_day": 25,
"auto_calculate": false,
"allowance_types": [
{"code": "meal", "name": "식대", "is_taxable": false},
{"code": "transport", "name": "교통비", "is_taxable": false},
{"code": "position", "name": "직책수당", "is_taxable": true},
{"code": "skill", "name": "기술수당", "is_taxable": true},
{"code": "family", "name": "가족수당", "is_taxable": true},
{"code": "housing", "name": "주거수당", "is_taxable": true}
],
"deduction_types": [
{"code": "loan", "name": "대출상환"},
{"code": "union", "name": "조합비"},
{"code": "savings", "name": "저축"},
{"code": "etc", "name": "기타공제"}
]
}
}
프론트엔드 참고:
allowance_types로 수당 입력 폼의 드롭다운 구성deduction_types로 공제 입력 폼의 드롭다운 구성pay_day를 급여 지급일 표시에 활용
5.18 급여 설정 수정
PUT /api/v1/payrolls/settings
Request Body:
{
"health_insurance_rate": 3.545,
"pension_rate": 4.5,
"pay_day": 25,
"allowance_types": [
{"code": "meal", "name": "식대", "is_taxable": false},
{"code": "transport", "name": "교통비", "is_taxable": false}
]
}
전달한 필드만 업데이트. 미전달 필드는 기존값 유지.
6. 에러 코드 정리
| 에러 키 | 메시지 | 발생 상황 |
|---|---|---|
error.payroll.not_found |
급여 정보를 찾을 수 없습니다. | 존재하지 않는 ID |
error.payroll.already_exists |
해당 연월에 이미 급여가 등록되어 있습니다. | 동일 사원+연월 중복 |
error.payroll.not_editable |
작성중 상태의 급여만 수정할 수 있습니다. | draft 외 수정 시도 |
error.payroll.not_deletable |
작성중 상태의 급여만 삭제할 수 있습니다. | draft 외 삭제 시도 |
error.payroll.not_confirmable |
작성중 상태의 급여만 확정할 수 있습니다. | draft 외 확정 시도 |
error.payroll.not_unconfirmable |
확정된 급여만 확정 취소할 수 있습니다. | confirmed 외 확정취소 |
error.payroll.not_payable |
확정된 급여만 지급 처리할 수 있습니다. | confirmed 외 지급 |
error.payroll.not_unpayable |
지급완료된 급여만 지급 취소할 수 있습니다. | paid 외 지급취소 |
error.payroll.no_previous_month |
전월 급여 데이터가 없습니다. | 전월 복사 시 데이터 없음 |
error.payroll.invalid_withdrawal |
유효하지 않은 출금 내역입니다. | 존재하지 않는 withdrawal_id |
7. 프론트엔드 구현 가이드
7.1 추천 화면 구성
┌─────────────────────────────────────────────────────┐
│ 급여관리 [2026년 03월 ▼] │
├─────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
│ │ 총 인원 │ │ 총 지급액 │ │ 총 공제액 │ │ 실수령액 ││
│ │ 15명 │ │ 62,500천원│ │ 15,800천원│ │46,700천원││
│ └──────────┘ └──────────┘ └──────────┘ └─────────┘│
│ │
│ [일괄생성] [전월복사] [일괄계산] [일괄확정] [+ 등록] │
│ │
│ ┌───┬──────┬──────┬──────┬──────┬──────┬────┬────┐│
│ │ # │ 사원 │ 기본급│총지급액│총공제액│실수령액│상태 │ 작업││
│ ├───┼──────┼──────┼──────┼──────┼──────┼────┼────┤│
│ │ 1 │홍길동│ 350만│ 410만│ 98만 │ 312만│작성│ ⋮ ││
│ │ 2 │김철수│ 300만│ 350만│ 85만 │ 265만│확정│ ⋮ ││
│ └───┴──────┴──────┴──────┴──────┴──────┴────┴────┘│
└─────────────────────────────────────────────────────┘
7.2 급여 등록/수정 폼
┌─────────────────────────────────────────────────────┐
│ 급여 등록 │
├─────────────────────────────────────────────────────┤
│ 사원: [홍길동 ▼] 연도: [2026] 월: [3 ▼] │
│ │
│ ── 지급 항목 ──────────────────────────────────── │
│ 기본급: [ 3,500,000 ] │
│ 연장근로수당: [ 0 ] │
│ 식대(비과세): [ 200,000 ] │
│ 수당: │
│ 직책수당 [ 300,000 ] [삭제] │
│ 교통비 [ 100,000 ] [삭제] │
│ [+ 수당 추가] │
│ ────────────────────────── 총 지급액: 4,100,000 │
│ │
│ ── 공제 항목 (자동 계산) ──────────────────────── │
│ 근로소득세: [ 117,750 ] ← 자동 (수정 가능) │
│ 지방소득세: [ 11,770 ] ← 자동 (수정 가능) │
│ 건강보험: [ 138,220 ] ← 자동 (수정 가능) │
│ 장기요양보험: [ 1,250 ] ← 자동 (수정 가능) │
│ 국민연금: [ 175,500 ] ← 자동 (수정 가능) │
│ 고용보험: [ 35,100 ] ← 자동 (수정 가능) │
│ 기타 공제: │
│ 대출상환 [ 500,000 ] [삭제] │
│ [+ 기타 공제 추가] │
│ ────────────────────────── 총 공제액: 979,590 │
│ │
│ ═════════════════════════ 실수령액: 3,120,410 │
│ │
│ 메모: [ ] │
│ │
│ [취소] [미리보기] [저장]│
└─────────────────────────────────────────────────────┘
구현 포인트:
- 지급 항목 변경 시
calculate-previewAPI 호출하여 공제 항목 자동 갱신 - 법정 공제 필드는 기본 readonly + "수정" 토글로 수동 입력 허용
- 수동 입력된 공제 항목은
deduction_overrides로 전달 allowance_types,deduction_types는 설정 API에서 조회하여 드롭다운 제공
7.3 급여명세서 (인쇄용)
payslip API 응답의 earnings/deductions 구조를 활용:
┌─────────────────────────────────────────────┐
│ 급 여 명 세 서 │
│ │
│ 사원명: 홍길동 귀속기간: 2026년 03월 │
│ │
│ ┌──── 지급 내역 ────┬── 공제 내역 ────┐ │
│ │ 기본급 3,500,000│ 소득세 117,750│ │
│ │ 식대 200,000│ 지방소득세 11,770│ │
│ │ 직책수당 300,000│ 건강보험 138,220│ │
│ │ 교통비 100,000│ 장기요양 1,250│ │
│ │ │ 국민연금 175,500│ │
│ │ │ 고용보험 35,100│ │
│ │ │ 대출상환 500,000│ │
│ ├───────────────────┼─────────────────┤ │
│ │ 지급합계 4,100,000│ 공제합계 979,590│ │
│ └───────────────────┴─────────────────┘ │
│ │
│ 실수령액: 3,120,410원 │
└─────────────────────────────────────────────┘
7.4 월간 워크플로우
1. 월초 → [일괄생성] 또는 [전월복사] 실행
2. 개별 급여 데이터 확인/수정
3. [일괄계산] 실행 (공제 항목 최신 요율로 재계산)
4. 데이터 확인 완료 → [일괄확정]
5. 급여 지급일 → 개별 [지급처리] (출금과 연결)
6. 급여명세서 조회/인쇄
7.5 금액 표시 규칙
- 모든 금액은 원(KRW) 단위 정수
- 천 단위 콤마 필수:
3,500,000 - 음수 금액(환급): 빨간색 +
-부호
관련 문서
- 급여관리 기능 상세 — 전표 변환, 권한, 멀티테넌트
- DB 스키마 — 인사
- 결재관리 API 명세
최종 업데이트: 2026-03-11