188 lines
10 KiB
PHP
188 lines
10 KiB
PHP
@extends('admin.layouts.app')
|
|
|
|
@section('title', '결제/수수료 정책 관리')
|
|
@section('page_title', '결제/수수료 정책 관리')
|
|
@section('page_desc', '매입(출금) 기본 정책과 결제 수단별 PG 수수료를 관리합니다.')
|
|
|
|
@push('head')
|
|
<style>
|
|
.grid-layout { display: grid; grid-template-columns: 1fr 350px; gap: 20px; align-items: start; }
|
|
@media (max-width: 980px) { .grid-layout { grid-template-columns: 1fr; } }
|
|
|
|
.item-list { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10); border-radius: 12px; }
|
|
.item-row { padding: 12px 16px; border-bottom: 1px solid rgba(255,255,255,.05); display: flex; justify-content: space-between; align-items: center; transition: background 0.2s; }
|
|
.item-row:last-child { border-bottom: none; }
|
|
.item-info { display: flex; align-items: center; gap: 10px; }
|
|
.item-actions { display: flex; gap: 4px; align-items: center; }
|
|
.btn-sort { padding: 4px 8px; font-size: 11px; }
|
|
</style>
|
|
@endpush
|
|
|
|
@section('content')
|
|
<div class="a-card" style="padding:16px; margin-bottom:20px; border-top: 3px solid rgba(244,63,94,.88);">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:12px;">💸 매입(출금) 기본 수수료 정책</div>
|
|
<form method="POST" action="{{ route('admin.fees.buyback.update') }}" style="display:flex; gap:16px; align-items:flex-end; flex-wrap:wrap;">
|
|
@csrf @method('PUT')
|
|
<div class="a-field" style="flex:1; min-width:200px;">
|
|
<label class="a-label">고객 차감 매입 수수료율 (%)</label>
|
|
<input type="number" step="0.01" class="a-input" name="customer_fee_rate" value="{{ $buybackPolicy->customer_fee_rate ?? 15.00 }}">
|
|
</div>
|
|
<div class="a-field" style="flex:1; min-width:150px;">
|
|
<label class="a-label">자사 펌뱅킹 수수료 부과 방식</label>
|
|
<select class="a-input" name="bank_fee_type">
|
|
<option value="FLAT" {{ ($buybackPolicy->bank_fee_type ?? '') === 'FLAT' ? 'selected' : '' }}>정액 (원)</option>
|
|
<option value="PERCENT" {{ ($buybackPolicy->bank_fee_type ?? '') === 'PERCENT' ? 'selected' : '' }}>정률 (%)</option>
|
|
</select>
|
|
</div>
|
|
<div class="a-field" style="flex:1; min-width:200px;">
|
|
<label class="a-label">자사 펌뱅킹 수수료 값 (원/%)</label>
|
|
<input type="number" step="0.01" class="a-input" name="bank_fee_value" value="{{ $buybackPolicy->bank_fee_value ?? 500.00 }}">
|
|
</div>
|
|
<button type="submit" class="lbtn lbtn--danger" style="height:40px; margin-bottom:4px;">정책 저장</button>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="grid-layout">
|
|
<div class="a-card" style="padding:16px;">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:16px;">💳 결제 수단 및 수수료 목록</div>
|
|
|
|
<div class="item-list" id="payment-root">
|
|
@forelse($paymentMethods as $pm)
|
|
<div class="item-row" data-id="{{ $pm['id'] }}">
|
|
<div class="item-info">
|
|
<span class="pill {{ $pm['is_active'] ? 'pill--ok' : 'pill--muted' }}">
|
|
{{ $pm['is_active'] ? 'ON' : 'OFF' }}
|
|
</span>
|
|
<strong>{{ $pm['name'] }}</strong>
|
|
<span class="pill pill--bad" style="font-size:11px;">노출명칭 : {{$pm['display_name'] }}</span>
|
|
<span class="pill pill--ok" style="font-size:12px;">CODE : {{ $pm['code'] }}</span>
|
|
<span class="pill pill--warn" style="font-size:11px;">고객: {{ (float)$pm['customer_fee_rate'] }}%</span>
|
|
<span class="pill pill--muted" style="font-size:11px;">PG원가: {{ (float)$pm['pg_fee_rate'] }}%</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<div class="item-actions">
|
|
<button type="button" class="lbtn lbtn--ghost btn-sort" onclick="moveRow(this, -1)">▲</button>
|
|
<button type="button" class="lbtn lbtn--ghost btn-sort" onclick="moveRow(this, 1)">▼</button>
|
|
<button type="button" class="lbtn lbtn--sm lbtn--ghost" style="margin-left:8px;" onclick="editPayment({{ json_encode($pm) }})">수정</button>
|
|
|
|
<form action="{{ route('admin.fees.payment.destroy', $pm['id']) }}" method="POST" onsubmit="return confirm('이 결제 수단을 삭제하시겠습니까?');" style="margin:0;">
|
|
@csrf @method('DELETE')
|
|
<button type="submit" class="lbtn lbtn--sm lbtn--danger">삭제</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div style="padding: 20px; text-align: center;" class="a-muted">등록된 결제 수단이 없습니다.</div>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
|
|
<div class="a-card" style="padding:16px;">
|
|
<div style="font-weight:900; font-size:16px; margin-bottom:16px;" id="formTitle">새 결제 수단 등록</div>
|
|
|
|
<form id="paymentForm" method="POST" action="{{ route('admin.fees.payment.store') }}">
|
|
@csrf
|
|
<input type="hidden" name="_method" id="formMethod" value="POST">
|
|
|
|
<div style="display:grid; gap:12px;">
|
|
<div class="a-field">
|
|
<label class="a-label">결제수단 코드 (연동 키)</label>
|
|
<input class="a-input" name="code" id="pmCode" placeholder="예: MOBILE" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">관리자용 명칭</label>
|
|
<input class="a-input" name="name" id="pmName" placeholder="예: 다날 신용카드" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">사용자 노출 명칭</label>
|
|
<input class="a-input" name="display_name" id="pmDisplayName" placeholder="예: 신용카드결제" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">고객 부과 수수료율 (%)</label>
|
|
<input type="number" step="0.01" class="a-input" name="customer_fee_rate" id="pmCustomerFee" value="0.00" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">자사(PG) 원가 수수료율 (%)</label>
|
|
<input type="number" step="0.01" class="a-input" name="pg_fee_rate" id="pmPgFee" value="0.00" required>
|
|
</div>
|
|
<div class="a-field">
|
|
<label class="a-label">사용 여부</label>
|
|
<select class="a-input" name="is_active" id="pmActive">
|
|
<option value="1">ON (사용)</option>
|
|
<option value="0">OFF (숨김)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div style="display:flex; gap:10px; margin-top:10px;">
|
|
<button type="button" class="lbtn lbtn--ghost" style="flex:1;" onclick="resetForm()">신규 등록 초기화</button>
|
|
<button type="submit" class="lbtn lbtn--primary" style="flex:1;">저장</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<script>
|
|
const baseActionUrl = '{{ route('admin.fees.index') }}';
|
|
|
|
function editPayment(pm) {
|
|
document.getElementById('formTitle').innerText = '결제 수단 수정 (#'+pm.id+')';
|
|
document.getElementById('paymentForm').action = baseActionUrl + '/payment/' + pm.id;
|
|
document.getElementById('formMethod').value = 'PUT';
|
|
|
|
document.getElementById('pmCode').value = pm.code;
|
|
document.getElementById('pmCode').readOnly = true; // 코드는 수정 불가
|
|
document.getElementById('pmName').value = pm.name;
|
|
document.getElementById('pmDisplayName').value = pm.display_name;
|
|
document.getElementById('pmCustomerFee').value = pm.customer_fee_rate;
|
|
document.getElementById('pmPgFee').value = pm.pg_fee_rate;
|
|
document.getElementById('pmActive').value = pm.is_active;
|
|
}
|
|
|
|
function resetForm() {
|
|
document.getElementById('formTitle').innerText = '새 결제 수단 등록';
|
|
document.getElementById('paymentForm').action = '{{ route('admin.fees.payment.store') }}';
|
|
document.getElementById('formMethod').value = 'POST';
|
|
|
|
document.getElementById('pmCode').value = '';
|
|
document.getElementById('pmCode').readOnly = false;
|
|
document.getElementById('pmName').value = '';
|
|
document.getElementById('pmDisplayName').value = '';
|
|
document.getElementById('pmCustomerFee').value = '0.00';
|
|
document.getElementById('pmPgFee').value = '0.00';
|
|
document.getElementById('pmActive').value = '1';
|
|
}
|
|
|
|
function moveRow(btn, direction) {
|
|
const item = btn.closest('.item-row');
|
|
const container = item.parentNode;
|
|
|
|
if (direction === -1 && item.previousElementSibling) {
|
|
container.insertBefore(item, item.previousElementSibling);
|
|
saveSort(container);
|
|
} else if (direction === 1 && item.nextElementSibling) {
|
|
container.insertBefore(item.nextElementSibling, item);
|
|
saveSort(container);
|
|
}
|
|
}
|
|
|
|
function saveSort(container) {
|
|
const ids = Array.from(container.children).map(el => el.getAttribute('data-id'));
|
|
fetch('{{ route('admin.fees.payment.sort') }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
'Accept': 'application/json'
|
|
},
|
|
body: JSON.stringify({ ids: ids })
|
|
});
|
|
}
|
|
</script>
|
|
@endpush
|