Payments setup guide
I.S.A.A.C uses Stripe for automatic recurring card subscriptions and HitPay for Malaysian local payment methods such as FPX, DuitNow, and Touch 'n Go style one-time monthly access payments. Paid access must be activated only by verified server-side webhooks.
Recommended payment architecture
Stripe
Use for Pro and Premium recurring subscriptions by card. Stripe hosts checkout, invoices, receipts, and the billing portal. The app stores subscription and receipt metadata after verified Stripe webhooks.
HitPay or local gateway
Use for Malaysian FPX, DuitNow QR, and Touch 'n Go/e-wallet style payments. These are best treated as one-time monthly access payments unless the gateway gives you a recurring billing product for the chosen method.
Stripe checklist
- Create or log in to a Stripe account and complete business verification.
- Create two monthly recurring products/prices in MYR: Pro RM29/month and Premium RM49/month.
- Copy each recurring Price ID into `STRIPE_PRICE_PRO_MYR` and `STRIPE_PRICE_PREMIUM_MYR`.
- Copy the Stripe secret key into `STRIPE_SECRET_KEY`. Use test keys for sandbox and live keys only in production.
- Add a webhook endpoint pointing to `https://your-domain.com/api/billing/webhook` and subscribe to invoice and subscription lifecycle events.
- Copy the webhook signing secret into `STRIPE_WEBHOOK_SECRET`.
- Use Stripe CLI locally if you want to test webhooks against localhost.
- Run a test card checkout, confirm the webhook records a receipt, then confirm the billing portal opens.
Malaysia local payments checklist
- Create a HitPay merchant account and complete Malaysian business verification.
- Enable the payment methods you want in the HitPay dashboard: FPX, DuitNow, Touch 'n Go/e-wallets, and cards if needed.
- Copy the sandbox API key into `HITPAY_API_KEY` and keep `HITPAY_MODE=sandbox` while testing.
- Add a webhook endpoint in HitPay pointing to `https://your-domain.com/api/billing/hitpay-webhook` and enable `payment_request.completed` at minimum.
- Copy the webhook endpoint salt into `HITPAY_WEBHOOK_SALT`.
- Run a sandbox payment request from Billing and confirm the app does not unlock paid access until the webhook is validated.
- Switch to production keys only after live merchant approval and a successful end-to-end sandbox test.
DuitNow payments are QR based and generally cannot be refunded through HitPay. FPX and e-wallet availability depends on gateway approval and activated methods in the merchant dashboard.
Environment variables
Paste real values only in `.env.local` for local testing and in your production host secret manager for live deployment. Never commit these values to GitHub.
# Required for production app URLs NEXT_PUBLIC_APP_URL=https://your-domain.com # Stripe recurring card subscriptions STRIPE_SECRET_KEY=sk_live_or_test_xxx STRIPE_WEBHOOK_SECRET=whsec_xxx STRIPE_PRICE_PRO_MYR=price_xxx STRIPE_PRICE_PREMIUM_MYR=price_xxx # HitPay local Malaysian one-time monthly access payments LOCAL_PAYMENT_PROVIDER=hitpay HITPAY_MODE=sandbox HITPAY_API_KEY=hitpay_sandbox_or_live_key HITPAY_WEBHOOK_SALT=webhook_endpoint_salt HITPAY_METHOD_DUITNOW= HITPAY_METHOD_TNG=
Payment security rules
- Never unlock a paid plan from a redirect URL alone.
- Always verify Stripe and HitPay signatures against the raw request body.
- Store receipt metadata, not raw card or banking credentials.
- Log failed webhook validation attempts without printing full secrets or raw payment credentials.
- Use separate sandbox and production keys.
- Rotate keys immediately if they are exposed in chat, screenshots, logs, or GitHub.