# REST API Reference All endpoints are prefixed with wherever you mount the subscription URLs (e.g., `/api/subscriptions/`). ## Authentication Most endpoints require authentication via session or basic auth. The webhook endpoint is unauthenticated. ## Plans ### `GET /plans/` List all active plans. **Public** (no auth required). **Query Parameters:** - `status` — Filter by status (`active`, `inactive`, `archived`) - `interval_unit` — Filter by interval (`day`, `week`, `month`) - `currency` — Filter by currency code - `search` — Search in name and description - `ordering` — Order by `price`, `sort_order`, `created_at` **Response:** ```json { "count": 3, "results": [ { "id": "uuid", "name": "Basic", "slug": "basic", "description": "Basic plan", "price": "49000.00", "currency": "IDR", "interval": 1, "interval_unit": "month", "trial_period_days": 7, "max_cycles": 0, "status": "active", "features": {"max_projects": 5}, "sort_order": 0 } ] } ``` ### `GET /plans/{slug}/` Retrieve a single plan by slug. **Public**. --- ## Subscriptions ### `GET /subscriptions/` List the current user's subscriptions. **Query Parameters:** - `status` — Filter by status - `payment_type` — Filter by payment type - `ordering` — Order by `created_at`, `next_billing_date` ### `GET /subscriptions/{id}/` Retrieve subscription details. ### `POST /subscriptions/` Create a new subscription. **Request Body:** ```json { "plan_id": "plan-uuid-or-slug", "payment_type": "bank_transfer", "token": "", "customer_details": { "first_name": "John", "last_name": "Doe", "email": "john@example.com", "phone": "08123456789" }, "metadata": {"bank": "bca"} } ``` **Response (201):** ```json { "subscription": { "id": "uuid", "status": "pending", "...": "..." }, "payment": { "order_id": "SUB-A1B2C3D4E5F6", "status": "pending", "payment_details": { "bank": "bca", "va_number": "1234567890" } } } ``` ### `POST /subscriptions/{id}/cancel/` Cancel a subscription. ```json { "reason": "Too expensive", "immediate": false } ``` ### `POST /subscriptions/{id}/pause/` Pause an active subscription (no request body). ### `POST /subscriptions/{id}/resume/` Resume a paused subscription (no request body). ### `POST /subscriptions/{id}/change-plan/` Change subscription plan. ```json { "plan_id": "new-plan-uuid-or-slug", "immediate": true } ``` ### `GET /subscriptions/{id}/sync/` Sync subscription status from Midtrans API. ### `GET /subscriptions/active/` Get the current user's active subscription. Returns 404 if none found. --- ## Payments ### `GET /payments/` List the current user's payments. **Query Parameters:** - `status` — Filter by status - `payment_type` — Filter by payment type - `ordering` — Order by `created_at`, `gross_amount` ### `GET /payments/{id}/` Retrieve payment details including `payment_details` (VA numbers, QR URLs). ### `POST /payments/charge/` Create a new charge for a subscription. ```json { "subscription_id": "subscription-uuid" } ``` ### `POST /payments/{id}/refund/` Refund a settled payment. ```json { "amount": 50000, "reason": "Customer request", "direct": false } ``` ### `GET /payments/{id}/check-status/` Check payment status directly from Midtrans API. **Response:** ```json { "local_status": "pending", "midtrans_status": { "transaction_status": "settlement", "status_code": "200", "...": "..." } } ``` --- ## Invoices ### `GET /invoices/` List the current user's invoices. **Query Parameters:** - `status` — Filter by status - `ordering` — Order by `issue_date`, `due_date`, `total_amount` ### `GET /invoices/{id}/` Retrieve invoice details with line items. --- ## Webhook ### `POST /webhook/notification/` Midtrans payment notification endpoint. **No authentication required.** Midtrans sends POST requests here with payment status updates. The system: 1. Logs the webhook in `WebhookLog` 2. Verifies the SHA-512 signature 3. Updates payment status 4. Triggers subscription lifecycle events **Request Body** (from Midtrans): ```json { "order_id": "SUB-A1B2C3D4E5F6", "transaction_status": "settlement", "status_code": "200", "gross_amount": "49000.00", "signature_key": "sha512hash...", "fraud_status": "accept", "payment_type": "bank_transfer", "transaction_id": "midtrans-txn-id" } ``` **Response:** ```json { "status": "ok", "webhook_log_id": "uuid" } ``` --- ## Notifications ### `GET /notifications/` List the current user's notification logs. **Query Parameters:** - `notification_type` — Filter by type - `channel` — Filter by channel (`email`, `webhook`, `in_app`) - `status` — Filter by status ### `GET /notifications/{id}/` Retrieve notification detail. ### `GET /notifications/unread/` Get unread (queued) notifications (max 50). ### `POST /notifications/{id}/mark-read/` Mark a notification as read. --- ## Wallet ### `GET /wallet/me/` Get or create the current user's wallet. **Response:** ```json { "id": "uuid", "balance": "150000.00", "currency": "IDR", "is_active": true } ``` ### `GET /wallet/transactions/` List wallet transactions (paginated). --- ## Top-Ups ### `GET /topups/` List the current user's top-ups. **Query Parameters:** - `status` — Filter by status - `payment_type` — Filter by payment type ### `GET /topups/{id}/` Retrieve top-up detail (includes `payment_details` with VA/QR). ### `POST /topups/` Create a new wallet top-up. ```json { "amount": 100000, "payment_type": "bank_transfer", "bank": "bca" } ``` **Response (201):** ```json { "id": "uuid", "order_id": "TOPUP-A1B2C3D4E5F6", "amount": "100000.00", "status": "pending", "payment_type": "bank_transfer", "payment_details": { "bank": "bca", "va_number": "1234567890" } } ```