# Dewemoji Billing Integration Plan (QRIS + PayPal)

This document outlines a proper, production-grade billing flow for Dewemoji using **QRIS (Pakasir)** and **PayPal Subscriptions**, including webhooks, retries, and license activation.

---

## 1) Goals

- Replace primitive payment links with real provider integrations.
- Support **subscription** billing (monthly/annual) and **one-time lifetime**.
- Activate or revoke licenses based on webhook-confirmed payments.
- Log all webhook events and payment activity for audit.

---

## 2) Data Model

### `orders` (new)

Acts as the primary record of what the user is buying. Payments link back to orders.

- `id`
- `user_id`
- `plan_code`
- `type` (`one_time`, `subscription`)
- `currency` (`IDR`, `USD`)
- `amount`
- `status` (`pending`, `paid`, `failed`, `expired`, `refunded`)
- `provider` (`qris`, `paypal`)
- `provider_ref`
- `created_at`, `updated_at`

### `payments` (new)

- `id`
- `user_id`
- `order_id`
- `provider` (`qris`, `paypal`)
- `type` (`one_time`, `subscription`)
- `plan_code` (`personal_monthly`, `personal_annual`, `personal_lifetime`)
- `currency` (`IDR`, `USD`)
- `amount`
- `status` (`pending`, `paid`, `failed`, `expired`, `refunded`)
- `provider_ref` (invoice_id / order_id / subscription_id)
- `raw_payload` (json)
- `created_at`, `updated_at`

### `subscriptions` (existing)
Extend with:
- `provider`
- `provider_ref`
- `status` (`active`, `pending`, `canceled`, `expired`)
- `started_at`, `expires_at`, `canceled_at`
 - `next_renewal_at` (optional)

### `webhook_events` (existing)
Continue to log inbound payloads and processing status:
- `provider`, `event_type`, `status`, `payload`, `received_at`, `processed_at`, `error_message`

---

## 3) Payment Flow (User Journey)

### Pricing Page (Frontend)

Each plan shows:
- **Primary currency** (based on geo + user toggle)
- **Two payment buttons** (real provider flow):
  - **QRIS (IDR)** → subscription or one-time
  - **PayPal (USD)** → subscription or one-time

### Backend Endpoints

#### QRIS (Pakasir)
- `POST /billing/qris/create`
  - Creates invoice via Pakasir API
  - Stores `payments` with `pending`
  - Returns QR payment URL or QR code data
- `GET /billing/qris/return` (optional)
  - Shows “pending / processing” state

#### PayPal Subscriptions
- `POST /billing/paypal/create`
  - Creates PayPal subscription
  - Stores `payments` with `pending`
  - Returns approval URL
- `GET /billing/paypal/return`
  - Shows “pending / processing” state

---

## 4) Webhook Processing (Critical)

Webhook endpoint:
```
POST /webhooks/{provider}
```

Store inbound payloads in `webhook_events`, then process async (queue).

### PayPal Events
- `BILLING.SUBSCRIPTION.ACTIVATED` → mark subscription active, set `users.tier = personal`
- `BILLING.SUBSCRIPTION.CANCELLED` → mark subscription canceled
- `PAYMENT.SALE.COMPLETED` → mark payment paid
- `PAYMENT.SALE.DENIED` → mark payment failed

### Pakasir / QRIS Events
- `payment.paid` → mark payment paid, grant access
- `payment.expired` → mark payment failed/expired

---

## 5) License Activation Rules

When a payment or subscription is confirmed:
- Create or update a `subscriptions` record
- Set `users.tier = personal`
- Store provider refs (`provider_ref`)
- Log admin audit record

When revoked/expired:
- Update `subscriptions.status`
- Downgrade user if no active subscription remains

### Renewal Logic (QRIS manual renew)

- **If still active:** extend from current `expires_at`
  - `expires_at = expires_at + duration`
- **If expired:** start from now
  - `expires_at = now + duration`

---

## 6) Admin Dashboard Enhancements

Add or extend:
- **Payments list** (new screen)
  - filter by provider/status/currency
  - show raw provider ref
- **Subscriptions list** (already exists)
  - show provider + status
- **Webhook events** (already exists)
  - replay capability

---

## 7) Security & Reliability

- Validate webhook signatures (PayPal + Pakasir)
- Reject duplicate events (idempotency)
- Use queues for webhook processing
- Log all webhook failures

---

## 8) Required Inputs (From Owner)

Before implementation:

1. **Pakasir API docs** (create invoice, webhook payload format)
2. **PayPal API credentials** (client_id, secret, webhook signing key)
3. Confirm **plans & pricing**:
   - Monthly
   - Annual
   - Lifetime

---

## 9) Implementation Phases

**Phase 1 — Schema + Core Models**
- Add `orders` table
- Add `payments` table (link to orders)
- Extend `subscriptions`
- Update webhook model if needed

**Phase 2 — Provider APIs**
- Pakasir invoice create
- PayPal subscription create

**Phase 3 — Webhooks**
- Save raw events
- Process via queue + idempotency

**Phase 4 — UI**
- Pricing page buttons → real flows
- Admin payment + subscription tools

---

## 10) Notes

- This plan assumes **proper subscription lifecycle** with webhooks.
- PayPal.me / static links are **not sufficient** for subscriptions.
- All access control must be tied to **confirmed payment status**.
