v1.0 Dashboard Public Profile GitHub
Stripe + Razorpay Wallet Top-Up

Stripe & Razorpay Payments

KaiVox supports two payment gateways: Stripe for global users and Razorpay for Indian users. Both are used exclusively for wallet top-ups. Subscription billing is tracked internally — no recurring charges via Stripe/Razorpay yet.

Environment Variables

KeyValueRequired For
STRIPE_KEYPublishable key — starts with pk_live_ or pk_test_Stripe wallet top-up
STRIPE_SECRETSecret key — starts with sk_live_ or sk_secret_Stripe server-side charges
RAZORPAY_KEYKey ID — starts with rzp_live_ or rzp_test_Razorpay wallet top-up
RAZORPAY_SECRETKey Secret from Razorpay DashboardRazorpay signature verification
.env — test credentials
# Stripe (test mode — use pk_test / sk_test for local dev)
STRIPE_KEY=pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
STRIPE_SECRET=sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

# Razorpay (test mode)
RAZORPAY_KEY=rzp_test_xxxxxxxxxxxxxxxxxxxx
RAZORPAY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Never commit live Stripe or Razorpay keys to git. Use .env only — .env is in .gitignore. For staging use test keys. Only switch to live keys on production.

Wallet Top-Up Flow

Stripe Flow

  1. Tenant selects Stripe and enters amount At Billing → Top Up Wallet, they choose an amount (e.g. $50) and select "Pay with Card (Stripe)".
  2. Stripe Checkout Session created BillingController::topupStripe() creates a Stripe Checkout Session via the Stripe API. The session has success_url and cancel_url pointing back to KaiVox.
  3. Tenant completes payment on Stripe's hosted page They are redirected to Stripe's secure checkout. On success, Stripe redirects to /billing/topup/stripe/success?session_id=....
  4. KaiVox verifies and credits wallet BillingController::stripeSuccess() retrieves the session from Stripe API, verifies payment_status = paid, then credits the tenant's wallet and creates a wallet_transactions record.

Razorpay Flow

  1. Tenant selects Razorpay and enters amount At Billing → Top Up Wallet, they choose an amount (in INR) and select "Pay with Razorpay".
  2. Razorpay order created BillingController::topupRazorpay() creates a Razorpay order via the Razorpay API. The order ID is returned to the frontend.
  3. Razorpay JS checkout modal opens The tenant completes payment in Razorpay's modal (UPI, net banking, card, etc.).
  4. KaiVox verifies signature and credits wallet On payment success, Razorpay returns razorpay_payment_id, razorpay_order_id, and razorpay_signature. KaiVox verifies the HMAC signature using RAZORPAY_SECRET, then credits the wallet.

Wallet System Architecture

Table / ColumnPurpose
tenants.wallet_balanceCurrent prepaid balance (decimal, in USD or INR depending on plan currency)
tenants.wallet_low_thresholdBalance below which the low_wallet automation trigger fires
wallet_transactionsEvery debit and credit — type (topup/call_charge/refund), amount, balance_before, balance_after, reference

How Calls Deduct from Wallet

// Called at call hangup (VobizService + TwilioService):
BillingService::chargeForCall($tenant, $durationSeconds);

// Logic inside BillingService::chargeForCall():
1. Convert seconds to minutes (round up)
2. Check tenant's remaining monthly quota
3. If quota remaining → deduct from quota (free)
4. If quota exhausted → deduct from wallet at tenant's plan per-minute rate
5. If wallet insufficient → log failure, flag account
6. Record wallet_transaction entry

Subscription Plan Management

Plans are created and managed by the Super Admin at Super Admin → Subscription Plans. Each plan has:

  • Name — Starter / Pro / Enterprise
  • Monthly price — charged manually or via future Stripe subscription
  • Monthly call quota — free minutes per billing cycle
  • Per-minute rate — rate charged from wallet after quota
  • Features list — shown on pricing page

Tenants can upgrade or downgrade at Billing → Change Plan. The subscriptions table records the current plan, start date, and status.

Invoice / Billing History

Tenants can view their billing history at Billing → History. This shows all wallet top-ups, call charges, and phone number billing deductions from wallet_transactions and phone_number_billing.

Super Admin Billing Controls

Super Admins can at Super Admin → Tenants → [Tenant] → Billing:

  • Manually adjust wallet balance (add/deduct with a reason note)
  • View all wallet transactions for the tenant
  • Override plan assignment
  • See low-balance alerts (flagged tenants whose wallet is below threshold)

Troubleshooting Payments

ProblemCauseFix
Stripe redirect failsWrong STRIPE_KEY or missingCheck key in Stripe Dashboard → Developers → API Keys
Stripe payment not creditedSuccess URL not reached or session not verifiedCheck Laravel logs for stripeSuccess errors
Razorpay signature mismatchWrong RAZORPAY_SECRETRegenerate secret in Razorpay Dashboard → Settings → API Keys
Wallet not deducting for callsBillingService not wired or quota still activeCheck wallet_transactions table and monthly quota column on subscriptions
Test payments going through as liveUsing live keys in devUse pk_test_ / sk_test_ for Stripe, rzp_test_ for Razorpay