feat: Phase 8 SaaS 확장 - 구독관리/결제내역 API 추가
- 사용량 조회 API (GET /subscriptions/usage)
- 데이터 내보내기 API (POST/GET /subscriptions/export)
- 결제 명세서 API (GET /payments/{id}/statement)
- DataExport 모델 및 마이그레이션 추가
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
use App\Models\Tenants\Payment;
|
||||
use App\Models\Tenants\Subscription;
|
||||
use App\Models\Tenants\Tenant;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
@@ -273,4 +274,84 @@ public function refund(int $id, ?string $reason = null): Payment
|
||||
|
||||
return $payment->fresh(['subscription.plan']);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// 결제 명세서
|
||||
// =========================================================================
|
||||
|
||||
/**
|
||||
* 결제 명세서 조회
|
||||
*/
|
||||
public function statement(int $id): array
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
|
||||
// 테넌트 검증 및 결제 조회
|
||||
$subscriptionIds = Subscription::query()
|
||||
->where('tenant_id', $tenantId)
|
||||
->pluck('id');
|
||||
|
||||
$payment = Payment::query()
|
||||
->whereIn('subscription_id', $subscriptionIds)
|
||||
->with(['subscription.plan'])
|
||||
->findOrFail($id);
|
||||
|
||||
// 테넌트 정보 조회
|
||||
$tenant = Tenant::findOrFail($tenantId);
|
||||
|
||||
$subscription = $payment->subscription;
|
||||
$plan = $subscription->plan;
|
||||
|
||||
return [
|
||||
'statement_no' => sprintf('INV-%s-%06d', $payment->paid_at?->format('Ymd') ?? now()->format('Ymd'), $payment->id),
|
||||
'issued_at' => now()->toIso8601String(),
|
||||
'payment' => [
|
||||
'id' => $payment->id,
|
||||
'amount' => $payment->amount,
|
||||
'formatted_amount' => $payment->formatted_amount,
|
||||
'payment_method' => $payment->payment_method,
|
||||
'payment_method_label' => $payment->payment_method_label,
|
||||
'transaction_id' => $payment->transaction_id,
|
||||
'status' => $payment->status,
|
||||
'status_label' => $payment->status_label,
|
||||
'paid_at' => $payment->paid_at?->toIso8601String(),
|
||||
'memo' => $payment->memo,
|
||||
],
|
||||
'subscription' => [
|
||||
'id' => $subscription->id,
|
||||
'started_at' => $subscription->started_at?->toDateString(),
|
||||
'ended_at' => $subscription->ended_at?->toDateString(),
|
||||
'status' => $subscription->status,
|
||||
'status_label' => $subscription->status_label,
|
||||
],
|
||||
'plan' => $plan ? [
|
||||
'id' => $plan->id,
|
||||
'name' => $plan->name,
|
||||
'code' => $plan->code,
|
||||
'price' => $plan->price,
|
||||
'billing_cycle' => $plan->billing_cycle,
|
||||
'billing_cycle_label' => $plan->billing_cycle_label ?? $plan->billing_cycle,
|
||||
] : null,
|
||||
'customer' => [
|
||||
'tenant_id' => $tenant->id,
|
||||
'company_name' => $tenant->company_name,
|
||||
'business_number' => $tenant->business_number ?? null,
|
||||
'representative' => $tenant->representative ?? null,
|
||||
'address' => $tenant->address ?? null,
|
||||
'email' => $tenant->email ?? null,
|
||||
'phone' => $tenant->phone ?? null,
|
||||
],
|
||||
'items' => [
|
||||
[
|
||||
'description' => $plan ? sprintf('%s 구독 (%s)', $plan->name, $subscription->started_at?->format('Y.m.d') ?? '-') : '구독 서비스',
|
||||
'quantity' => 1,
|
||||
'unit_price' => $payment->amount,
|
||||
'amount' => $payment->amount,
|
||||
],
|
||||
],
|
||||
'subtotal' => $payment->amount,
|
||||
'tax' => 0, // VAT 별도 시 계산 필요
|
||||
'total' => $payment->amount,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user