4.9 KiB
4.9 KiB
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.
iduser_idplan_codetype(one_time,subscription)currency(IDR,USD)amountstatus(pending,paid,failed,expired,refunded)provider(qris,paypal)provider_refcreated_at,updated_at
payments (new)
iduser_idorder_idprovider(qris,paypal)type(one_time,subscription)plan_code(personal_monthly,personal_annual,personal_lifetime)currency(IDR,USD)amountstatus(pending,paid,failed,expired,refunded)provider_ref(invoice_id / order_id / subscription_id)raw_payload(json)created_at,updated_at
subscriptions (existing)
Extend with:
providerprovider_refstatus(active,pending,canceled,expired)started_at,expires_at,canceled_atnext_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
paymentswithpending - 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
paymentswithpending - 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, setusers.tier = personalBILLING.SUBSCRIPTION.CANCELLED→ mark subscription canceledPAYMENT.SALE.COMPLETED→ mark payment paidPAYMENT.SALE.DENIED→ mark payment failed
Pakasir / QRIS Events
payment.paid→ mark payment paid, grant accesspayment.expired→ mark payment failed/expired
5) License Activation Rules
When a payment or subscription is confirmed:
- Create or update a
subscriptionsrecord - 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_atexpires_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:
- Pakasir API docs (create invoice, webhook payload format)
- PayPal API credentials (client_id, secret, webhook signing key)
- Confirm plans & pricing:
- Monthly
- Annual
- Lifetime
9) Implementation Phases
Phase 1 — Schema + Core Models
- Add
orderstable - Add
paymentstable (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.