Skip to content

PRD: Mobayilo (web calling)

Mobayilo is a mobile-first, browser-based VoIP product that lets users buy credits and place international calls to mobile/landline numbers using WebRTC in the browser and Twilio as the PSTN gateway.

  • Place outbound browser-to-phone calls reliably (WebRTC → Twilio → PSTN).
  • Provide pay-as-you-go credits with transparent per-minute pricing.
  • Support both individual and company/team wallets (company is MVP).
  • Track call status and costs, show balance updates quickly.
  • Keep UX “phone-like” on mobile (thumb-friendly, responsive, fast).
  • Full UCaaS features (chat, meetings, deep CRM integrations).
  • Virtual numbers, recording, SMS (Phase 2+).
  • Carrier-grade fraud tooling (start with pragmatic guardrails).
  • Personal user: makes occasional international calls (travel/expat).
  • Freelancer/SMB: needs low-cost international calling from laptop/phone.
  • Sign up with email, buy credits, call an international number from the browser.
  • Look up price/minute for a destination before calling.
  • Review call history and spending.
  • Call connection success rate (answered or ringing) ≥ 98% for valid numbers.
  • Payment success rate ≥ 95% for supported cards (Stripe).
  • Time-to-dial: open dialer → start ringing < 3 seconds on good networks.
  • Support tickets: “charged incorrectly” < 1% of completed calls.
  1. User registers + confirms email (optional in MVP; recommended).
  2. User buys credits.
  3. User enters phone number (E.164) and sees estimated price/minute.
  4. User taps “Call” → browser mic permission → call connects.
  5. User ends call → call is logged → credits are deducted → receipt shown.
  1. User signs in.
  2. Dashboard shows balance + recent calls + quick dial.
  3. User places call; balance updates shortly after completion.
  • Individual accounts: email + password sign-up/login, password reset.
  • Company seats: passwordless login via magic link.
  • Account status: active/disabled (users and company seats).

Recommended Rails approach:

  • Devise for auth, with “confirmable” optional.
  • Balance stored in cents (integer).
  • Credit purchases via Stripe (one-time top-ups).
  • Ledger of all balance movements (purchases, call charges, refunds, bonuses).

Top-up rules:

  • Individual top-up: user can enter any amount, enforce minimum $5.
  • Company top-up: user can enter any amount, enforce minimum $100.

Auto top-up (optional, both individual + company):

  • Trigger: when wallet balance falls below a threshold.
  • Threshold: user-configurable, but provide a default suggestion (e.g. “auto top up when under $2”) so most users don’t think about it.
  • Auto top-up amount: user-configurable, but provide suggested minimums:
    • Individual: suggest $20 (user can change).
    • Company: suggest $100 (user can change).
  • Requires explicit opt-in and a saved payment method (Stripe).

Accounting rules (must be explicit):

  • Call cost calculation uses billable duration from Twilio webhooks.
  • Rounding policy (MVP): per-started-minute (ceil(duration_seconds / 60)).
  • Mobile-first dialer screen:
    • number input + dial pad
    • call button (primary)
    • mute + speaker toggle (where supported)
    • call status + timer
  • Twilio Voice JS SDK in browser for WebRTC.
  • Backend provides short-lived capability token for Twilio.
  • Backend provides TwiML / webhook endpoints for call routing and status updates.
  • Show recent numbers (last 8 unique per account) on the dialer for quick re-dial.
  • Attribute calls to the initiating user/seat via Twilio client identity.

Number handling (MVP):

  • Normalize and validate numbers server-side to E.164 before sending to Twilio.

Company calling (MVP):

  • Company can create unlimited seats (employees).
  • Company owns one or more Twilio purchased numbers managed by Mobayilo.
  • Seats can be assigned a number; multiple seats may share a number.
  • Usage tracking is per-seat (who placed the call), even when the caller ID number is shared.
  • Store rates by destination (country/prefix) and compute a pricePerMinute.
  • Show the computed price/minute before starting a call.
  • Enforce “insufficient balance” rules before token issuance / call start.
  • User sees paginated calls: to/from, status, start/end, duration, cost.
  • Filters: date range, status.
  • View users, balances, calls, transactions.
  • Ability to disable an account and issue a manual credit adjustment.
  • Company admin can manage seats and number assignments.
  • Backend: Ruby on Rails 8.1
  • Frontend: Hotwire (Turbo + Stimulus), Tailwind CSS (mobile-first)
  • DB: PostgreSQL

Rails runtime choices (MVP):

  • Monolith Rails app.
  • Background jobs: Solid Queue (Rails default).
  • Twilio Programmable Voice (PSTN gateway)
  • Stripe (credit purchases)
  • Email (transactional: receipts, password reset, optional verification)
  • Use Turbo Streams for call status changes (broadcast from webhook updates).
  • If needed later: Action Cable for more granular call events.
  • Rate-limit login, registration, token issuance, and call initiation.
  • Validate phone numbers to E.164; block obviously invalid destinations.
  • Stripe webhook signature verification; Twilio request validation for webhooks.
  • Idempotency for Stripe events and Twilio status callbacks (no double-charging).
  • First-purchase limit and “max call attempts per minute” limit.
  • Production blocker: remove any dev-only SMTP CRL bypass (SMTP_DISABLE_CRL_CHECK / VERIFY_NONE) before launch.
  • Terms + privacy policy (pre-launch).
  • Data retention policy for call logs and billing records.
  • Country-level restrictions: comply with Twilio Voice geographic permissions.
  1. Company seats allowlist: domain-based allowlist (implemented).
  2. Number provisioning (MVP): company admin can “add number” in-app (Mobayilo buys via Twilio API) vs manual/admin-only?