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:
2025-12-19 16:53:49 +09:00
parent 0d49e4cc75
commit abaff1286e
13 changed files with 868 additions and 1 deletions

View File

@@ -85,4 +85,14 @@ public function refund(PaymentActionRequest $request, int $id): JsonResponse
return ApiResponse::handle('message.payment.refunded', $result);
}
/**
* 결제 명세서 조회
*/
public function statement(int $id): JsonResponse
{
$result = $this->paymentService->statement($id);
return ApiResponse::handle('message.fetched', $result);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use App\Http\Requests\V1\Subscription\ExportStoreRequest;
use App\Http\Requests\V1\Subscription\SubscriptionCancelRequest;
use App\Http\Requests\V1\Subscription\SubscriptionIndexRequest;
use App\Http\Requests\V1\Subscription\SubscriptionStoreRequest;
@@ -95,4 +96,34 @@ public function resume(int $id): JsonResponse
return ApiResponse::handle('message.subscription.resumed', $result);
}
/**
* 사용량 조회
*/
public function usage(): JsonResponse
{
$result = $this->subscriptionService->usage();
return ApiResponse::handle('message.fetched', $result);
}
/**
* 내보내기 요청
*/
public function export(ExportStoreRequest $request): JsonResponse
{
$result = $this->subscriptionService->createExport($request->validated());
return ApiResponse::handle('message.export.requested', $result, 201);
}
/**
* 내보내기 상태 조회
*/
public function exportStatus(int $id): JsonResponse
{
$result = $this->subscriptionService->getExport($id);
return ApiResponse::handle('message.fetched', $result);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests\V1\Subscription;
use App\Models\Tenants\DataExport;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ExportStoreRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'export_type' => ['required', 'string', Rule::in(DataExport::TYPES)],
'options' => ['nullable', 'array'],
'options.format' => ['nullable', 'string', Rule::in(['xlsx', 'csv', 'json'])],
'options.include_deleted' => ['nullable', 'boolean'],
];
}
public function attributes(): array
{
return [
'export_type' => __('field.export_type'),
'options' => __('field.options'),
];
}
}