# Tax Gateway Service Documentation

## 1. Ringkasan

Dokumen ini menyimpan status implementasi awal project `tax_gateway_service` (Coretax Bridge) yang dibuat berdasarkan `TAX_GATEWAY_SPEC.md`, dengan penyesuaian kompatibilitas legacy environment.

Tanggal dokumentasi: 23 April 2026

## 2. Lokasi Project

- Root service: `tax_gateway_service/`
- Spesifikasi acuan: `TAX_GATEWAY_SPEC.md`

## 3. Catatan Kompatibilitas

Spesifikasi awal meminta PHP 8.2+ typed, tetapi implementasi saat ini disesuaikan agar kompatibel dengan lingkungan legacy:

- PHP 5.6 compatible
- MariaDB/MySQL (PDO)
- Redis (phpredis extension) untuk queue/circuit breaker
- OpenSSL untuk PKCS#12 signature

## 4. Struktur Folder

```text
tax_gateway_service/
  config/
    .env.example
  migrations/
    20260423_000001_create_tax_configs.sql
    20260423_000002_create_tax_idempotency.sql
    20260423_000003_create_tax_transactions.sql
    20260423_000004_create_tax_queue.sql
  public/
    index.php
  scripts/
    migrate.php
    dispatch_worker.php
  src/
    Autoload.php
    Bootstrap/Application.php
    Client/
    Config/
    Controller/
    Database/
    Http/
    Module/
    Queue/
    Repository/
    Security/
    Service/
    Support/
  composer.json
  README.md
```

## 5. Endpoint yang Tersedia

1. `POST /v1/tax/process`
2. `GET /v1/tax/status/{ref_no}`
3. `POST /v1/config/nitku`
4. `GET /v1/health`

## 6. Core Engine yang Sudah Diimplementasikan

### 6.1 Digital Signature Engine

- Class utama: `TaxGateway\Security\SignatureService`
- Loader sertifikat: `TaxGateway\Security\P12CertificateLoader`
- Header injector: `TaxGateway\Security\SignatureHeaderInjector`
- Mekanisme:
  - baca `.p12` via `openssl_pkcs12_read`
  - sign payload JSON dengan SHA-256 (`openssl_sign`)
  - inject signature ke header `X-DJP-Signature`

### 6.2 Idempotency Guard

- Middleware: `TaxGateway\Http\Middleware\IdempotencyMiddleware`
- Request hash: `sha1(raw_request_body)`
- Rule:
  - reject duplicate dalam window 24 jam
  - hanya jika status existing `Success` atau `Processing`
- Table pendukung: `tax_idempotency`

### 6.3 Reliability, Retry, Circuit Breaker

- Retry policy: `TaxGateway\Queue\RetryPolicy`
  - Retry 1: 30 detik
  - Retry 2: 5 menit
  - Retry 3: 30 menit
- Queue utama: Redis (`tax_gateway:outgoing`)
- Delay queue: Redis sorted set (`tax_gateway:outgoing:delayed`)
- Circuit breaker: `TaxGateway\Queue\CircuitBreaker`
  - jika HTTP 503 sebanyak 5 kali, buka circuit 10 menit
  - webhook alert melalui `TaxGateway\Client\WebhookAlertClient`
- Fallback queue: table `tax_queue` jika Redis tidak tersedia

## 7. Modul Bisnis Kompleks

### 7.1 Retail Module

Class: `TaxGateway\Module\Retail\RetailTaxModule`

Logic yang di-handle:
- Deteksi mode PPN: centralized vs decentralized
- Jika centralized:
  - internal transfer dibuat VAT journal 0%
  - tetap log mutasi untuk laporan mutasi barang
- Jika decentralized:
  - generate Faktur Pajak untuk inter-branch movement
- Peak-hour handler:
  - jam 07:00-10:00 diberi `high_concurrency` dan priority queue tinggi

### 7.2 Manufacturing Module

Class: `TaxGateway\Module\Manufacturing\ManufacturingTaxModule`

Logic yang di-handle:
- Validasi dokumen BC: tipe 2.3, 4.0, 2.7
- Switch tax code:
  - `01` (standard)
  - `07` (fasilitas tidak dipungut) jika destination zone bonded/export
- Penambahan metadata payload:
  - `keterangan_bebas_pajak` otomatis saat tax code `07`

### 7.3 Services Module

Class: `TaxGateway\Module\Services\ServicesTaxModule`

Logic yang di-handle:
- Withholding tax PPh 23 / PPh 4(2)
- Multi-rate:
  - NPWP rate default 2%
  - Non-NPWP rate default 4%
- Mendukung mode kalkulasi:
  - `gross_up`
  - `nett`
- Saat settlement:
  - generate dokumen Bukti Potong (Bupot) per vendor item

## 8. Skema Database (Migrations)

### 8.1 `tax_configs`

Untuk data konfigurasi pajak per company + branch:
- NPWP perusahaan
- branch code
- NITKU
- flag pemusatan PPN
- sertifikat P12 (base64)
- passphrase sertifikat (base64)
- flags JSON

### 8.2 `tax_idempotency`

Untuk mencegah double filing:
- `request_hash` (unique)
- `ref_no`
- status (`Processing` / `Success` / `Failed`)
- response body

### 8.3 `tax_transactions`

Main log transaksi tax filing:
- `ref_no` (unique)
- `request_hash`
- `industry_type`
- request/response body
- status
- QR URL
- attempts
- last error

### 8.4 `tax_queue`

Fallback queue saat Redis unavailable:
- queue name
- payload
- attempt number
- execute_after
- status

## 9. Alur Proses Utama

1. ERP kirim request ke `POST /v1/tax/process`
2. Middleware idempotency hitung SHA-1 hash request body
3. Service validasi payload header + detail transaksi
4. Engine jalankan modul sesuai `industry_type`
5. Payload ditandatangani pakai sertifikat `.p12`
6. Transaksi dicatat ke `tax_transactions` status `Processing`
7. Job dimasukkan ke Redis queue (atau fallback `tax_queue`)
8. Worker kirim payload ke DJP, update status `Success`/`Failed` atau retry

## 10. Komponen Kunci

- Bootstrap app: `src/Bootstrap/Application.php`
- Tax process service: `src/Service/TaxProcessService.php`
- Dispatch worker: `src/Service/TaxDispatchWorker.php`
- Health check: `src/Service/HealthCheckService.php`
- Tax controller: `src/Controller/TaxController.php`
- Config controller: `src/Controller/ConfigController.php`
- Health controller: `src/Controller/HealthController.php`

## 11. Cara Menjalankan (Ringkas)

1. Copy env:

```bash
copy tax_gateway_service\config\.env.example tax_gateway_service\config\.env
```

2. Jalankan migration:

```bash
php tax_gateway_service\scripts\migrate.php
```

3. Arahkan web server ke:
- `tax_gateway_service/public/index.php`

4. Jalankan worker async (opsional):

```bash
php tax_gateway_service\scripts\dispatch_worker.php
```

## 12. Catatan Penting Lanjutan

- Sertifikat dan passphrase saat ini disimpan base64 (belum encrypted-at-rest).
- Worker saat ini fokus antrean Redis; fallback DB queue sudah disiapkan di level penyimpanan.
- Untuk production hardening berikutnya disarankan:
  - encryption-at-rest untuk secret
  - dead-letter queue
  - monitoring metrics dan dashboard operasional
  - penguatan otorisasi endpoint (role/permission)

