Files
webstatement/app/Enums/ResponseCode.php
Daeng Deni Mardaeni 00681a8e30 feat(auth): implementasi autentikasi HMAC dan standardisasi format respons API
- Tambah validasi HMAC (X-Signature, X-Timestamp, X-Api-Key) pada setiap request.
- Standarkan format respons sesuai ResponseCode; hapus `response_description` (gabung ke `response_message`).
- `BalanceSummaryRequest`: validasi header + `validateHmac512`, pakai secret dari config, logging detail, bedakan invalid API key vs invalid signature.
- `AccountBalanceController`: sederhanakan pesan error “Rekening tidak ditemukan”.
- Konfigurasi baru: `webstatement.api_key`, `webstatement.secret_key`; pastikan helper `validateHmac512` tersedia.
- Breaking: Bearer token tidak didukung; gunakan HMAC headers.
- Validasi nomor rekening di database sebelum proses bisnis.
- Logging terstruktur untuk setiap percobaan validasi HMAC (header & hasil verifikasi).
- Konsistensi kode error via ResponseCode enum untuk semua kasus gagal.
2025-08-28 13:44:58 +07:00

141 lines
5.1 KiB
PHP

<?php
namespace Modules\Webstatement\Enums;
use Illuminate\Support\Str;
/**
* Response Code Enum untuk standarisasi response API
*
* @category Enums
* @package Modules\Webstatement\Enums
*/
enum ResponseCode: string
{
// Success Codes
case SUCCESS = '00';
// Data Error Codes
case INVALID_FIELD = '01';
case MISSING_FIELD = '02';
case INVALID_FORMAT = '03';
case DATA_NOT_FOUND = '04';
case DUPLICATE_REQUEST = '05';
case ACCOUNT_ALREADY_EXISTS = '06';
case ACCOUNT_NOT_FOUND = '07';
// Auth Error Codes
case INVALID_TOKEN = '10';
case UNAUTHORIZED = '11';
// System Error Codes
case SYSTEM_MALFUNCTION = '96';
case TIMEOUT = '97';
case SERVICE_UNAVAILABLE = '98';
case GENERAL_ERROR = '99';
/**
* Mendapatkan pesan response berdasarkan kode
*
* @return string
*/
public function getMessage(): string
{
return match($this) {
self::SUCCESS => 'Success',
self::INVALID_FIELD => 'Invalid Field',
self::MISSING_FIELD => 'Missing Field',
self::INVALID_FORMAT => 'Invalid Format',
self::DATA_NOT_FOUND => 'Data Not Found',
self::DUPLICATE_REQUEST => 'Duplicate Request',
self::ACCOUNT_ALREADY_EXISTS => 'Account Already Exists',
self::ACCOUNT_NOT_FOUND => 'Account Not Found',
self::INVALID_TOKEN => 'Invalid Token',
self::UNAUTHORIZED => 'Unauthorized',
self::SYSTEM_MALFUNCTION => 'System Malfunction',
self::TIMEOUT => 'Timeout',
self::SERVICE_UNAVAILABLE => 'Service Unavailable',
self::GENERAL_ERROR => 'General Error',
};
}
/**
* Mendapatkan deskripsi response berdasarkan kode
*
* @return string
*/
public function getDescription(): string
{
return match($this) {
self::SUCCESS => 'Permintaan berhasil',
self::INVALID_FIELD => 'Field tertentu tidak sesuai aturan',
self::MISSING_FIELD => 'Field wajib tidak dikirim',
self::INVALID_FORMAT => 'Format salah',
self::DATA_NOT_FOUND => 'Data yang diminta tidak ditemukan',
self::DUPLICATE_REQUEST => 'Request ID sama, sudah pernah diproses',
self::ACCOUNT_ALREADY_EXISTS => 'Nomor rekening / username / email sudah terdaftar',
self::ACCOUNT_NOT_FOUND => 'Nomor rekening / akun tidak ditemukan',
self::INVALID_TOKEN => 'Token tidak valid',
self::UNAUTHORIZED => 'Tidak punya akses',
self::SYSTEM_MALFUNCTION => 'Gangguan teknis di server',
self::TIMEOUT => 'Request timeout',
self::SERVICE_UNAVAILABLE => 'Layanan tidak tersedia',
self::GENERAL_ERROR => 'Kesalahan umum',
};
}
/**
* Mendapatkan HTTP status code berdasarkan response code
*
* @return int
*/
public function getHttpStatus(): int
{
return match($this) {
self::SUCCESS => 200,
self::INVALID_FIELD,
self::MISSING_FIELD,
self::INVALID_FORMAT => 400,
self::DATA_NOT_FOUND,
self::ACCOUNT_NOT_FOUND => 404,
self::DUPLICATE_REQUEST,
self::ACCOUNT_ALREADY_EXISTS => 409,
self::INVALID_TOKEN,
self::UNAUTHORIZED => 401,
self::SYSTEM_MALFUNCTION,
self::GENERAL_ERROR => 500,
self::TIMEOUT => 408,
self::SERVICE_UNAVAILABLE => 503,
};
}
/**
* Membuat response array standar
*
* @param mixed $data
* @param string|null $message
* @return array
*/
public function toResponse($data = null, ?string $message = null): array
{
$response = [
'status' => $this->value == '00' ? true : false,
'response_code' => $this->value,
'response_message' => $this->getMessage() . ($message ? ' | ' . $message : ''),
];
if (isset($data['errors'])) {
$response['errors'] = $data['errors'];
} else {
$response['data'] = $data;
}
$response['meta'] = [
'generated_at' => now()->toDateTimeString(),
'request_id' => request()->header('X-Request-ID', uniqid('req_'))
];
return $response;
}
}