Modul subscription mengelola paket berlangganan merchant: pembelian, invoice, upgrade/downgrade, dan expired handling via cron.
File kunci
| File | Baris | Peran |
|---|---|---|
app/Http/Controllers/SubscriptionController.php | 487 | Checkout, invoice, payment, expired |
app/Models/SubscriptionInvoice.php | 57 | Invoice + accessor display_payment_status |
app/Models/SubscriptionPayment.php | 24 | Payment record |
app/Models/Package.php | 25 | Paket berlangganan |
app/Models/Addon.php | 26 | Add-on (fitur tambahan) |
app/Console/Commands/Downgrade.php | 452 | Cron app:downgrade tiap menit |
app/Console/Commands/AddonExpired.php | 83 | Cron app:addon-expired tiap menit |
app/Console/Commands/SubscriptionNotif.php | 142 | Cron notif:subscription harian |
Model
SubscriptionInvoice
Field: store_id, package_id, plan (bulan), total, unique_total (3 digit random), user (snapshot), package (snapshot), addon (snapshot), type ('package'), payment_status (unpaid/pending/confirmed/paid/failed), expired_at, bukti_transfer.
Accessor display_payment_status — return failed jika bank kosong atau created_at + payment_expire_period < now.
Cron — 3 command
| Command | Frekuensi | Fungsi |
|---|---|---|
app:downgrade | everyMinute | Disable device/product/team yang melampaui kuota paket baru |
app:addon-expired | everyMinute | Reset features ke main_features_exist saat addon expired |
notif:subscription | daily | Notif H-7/H-3/H-1 sebelum paket expired |
Route
Web (routes/web.php:299)
Prefix /subscription:
| Method | Path | Fungsi |
|---|---|---|
| GET | /subscription | Index |
| GET | /subscription/checkout-form/{id} | Checkout form |
| GET | /subscription/confirm/{id} | Confirm |
| GET | /subscription/pyment/{id} | Payment (typo pyment) |
| GET | /subscription/invoice/{id} | Invoice |
API (routes/api.php:386)
Prefix /subscription:
| Method | Path | Fungsi |
|---|---|---|
| POST | /subscription/buy | Beli (lama) |
| POST | /subscription/confirm_buy | Beli v2 |
| POST | /subscription/checkout_v2 | Checkout v2 + dispatch PaymentTimer |
| POST | /subscription/send | Upload bukti transfer |
| POST | /subscription/failed_transaction/{id} | Reset ke unpaid |
Temuan
list()pakai$idtidak terdefinisi (:94-100) — method juga tidak terdaftar di route. Kemungkinan matiget_featuresseluruhnya di-comment (:462-486) — routePOST /get_featuresaktif tapi return null. Endpoint matiSubscriptionNotifscope variabel salah (:33-72) — loop pertama assign$storeId&$teamRoledari UserStore terakhir, loop kedua pakai nilai itu untuk semua store → semua notif terkirim ke store/owner yang salah- Typo
pymentdi route (web.php:305) — user yang ketikpaymentakan 404 PaymentTimerjob dispatch tanpa queue worker —.envQUEUE_CONNECTION=sync→ job blocking dalam request, delay tidak berfungsiDowngradedead code —handleDowngradeAiAgent,handleDowngradeBroadcast,handleDowngradeOrderada tapi tidak dipanggil darihandle()Downgradeduplikasi eksekusi — downgrade dijalankan 2x untuk store yang masih dalam masa downgrade- Permission check tidak konsisten —
buy,send,failed_transactiontidak authorize