Skip to content

Billing & Subscription

Documentation for Data Explorer’s real billing layer: Pro plans, checkout flow, subscription states, MoMo/ZaloPay, webhook confirmation, and production deployment notes.

Free and Pro plans

Billing is no longer mocked. Users can stay on Free or purchase time-based Pro access, and that state flows back into the user profile.

Real provider checkout

MoMo and ZaloPay are not cosmetic buttons. Each checkout creates a real provider flow, returns a payment session, and waits for webhook confirmation before Pro access is granted.

Activation after webhook

The app should not activate Pro just because the user clicked pay. Access is upgraded only after the backend receives and validates the completion signal from the provider.

What users see in the UI

Inside the profile dialog, users see the current plan, subscription state, expiration date when active, and checkout options by cadence. The current copy treats VND as the real charge currency, while USD remains reference copy only.

Current plan card

This card tells the user whether they are on Free or Pro, whether the subscription is active, and which date matters next.

Refresh billing state

The refresh action lets the user pull billing state again after payment or after returning from a provider, without needing to sign out and back in.

The checkout lifecycle from click to activation

1. Choose a plan and provider

The user selects a Pro duration and a provider such as MoMo or ZaloPay. The app creates a checkout request with an explicit plan code and provider.

2. The backend creates a payment session

The backend uses the appropriate provider adapter to build a payment request in the format expected by that gateway, then returns the redirect/session data to the client.

3. The provider handles payment

The user completes the MoMo or ZaloPay flow. This is where wallet auth, QR confirmation, or the real payment step actually happens.

4. Webhook confirms and the app upgrades access

Only after the backend receives a valid webhook or verifies a successful payment state does the account move into active Pro. That is the critical difference between real billing and a demo checkout.

Billing return page and post-payment status

The client includes a billing return page to receive users after the provider redirects them back. That page should not declare victory on its own if the webhook or final status check has not completed yet.

Why this matters

In real billing, a user can return to the app before the background system has finished processing everything. The return page is a UX bridge, but the final source of truth must still be the backend and the verified payment state.

Environment variables for real billing

Billing provider envs

# MoMo

MOMO_PARTNER_CODE=...

MOMO_ACCESS_KEY=...

MOMO_SECRET_KEY=...

MOMO_CREATE_URL=https://test-payment.momo.vn/v2/gateway/api/create

# ZaloPay

ZALOPAY_APP_ID=...

ZALOPAY_KEY1=...

ZALOPAY_KEY2=...

ZALOPAY_CREATE_URL=https://sb-openapi.zalopay.vn/v2/create

# Public return / webhook context

FRONTEND_URL=http://localhost:5173

API_PUBLIC_URL=http://localhost:3001/api

When testing billing on a public environment, do not stop at “the payment button opens the provider.” Test the whole loop: create checkout, return to the app, webhook confirmation, user-state refresh, and the final expiration date once Pro is active.

Billing in Data Explorer is not isolated from auth. Pro access eventually lands back on the user profile, so auth, billing, webhook handling, and profile refresh form one connected chain.

Ready to explore data?

Join the community on GitHub to contribute to the smartest local database IDE.

Launch App