The bulk of the day. The system previously took payments into one account; it now operates as a platform where each restaurant holds its own Stripe connected account and receives funds directly, with the platform retaining its fee.
Payments service grew by around 500 lines covering the full Connect surface: connected account creation and onboarding links, embedded account sessions, capability management, persons (the beneficial owners Stripe requires for KYC), external bank accounts, transfers and transfer reversals, application fees and fee refunds, balance settings, country specifications, and the Stripe secret store. Each write path has a matching webhook handler so local state stays aligned with Stripe.
Two failure modes were handled deliberately. Charges use on_behalf_of, which requires the card_payments capability — accounts created before that capability was requested would have failed outright, so the code detects the gap, falls back to transfer_data alone, and requests the capability so subsequent charges succeed. Separately, a stored account ID can become unreachable if the platform key rotates or a restaurant revokes access; the code verifies accessibility and provisions a fresh account rather than failing repeatedly against a dead reference.
Superadmin control was extended to match — around 950 lines across the controller and service so the platform operator can list all connected accounts, inspect and update account details, manage capabilities and bank accounts, reject an account for fraud or terms violations, and clear a stale connection. Account rejections and detail changes are attributed to the acting admin.
Frontend work covered the tenant detail page, which gained a Stripe Connect panel — start onboarding, check status, open the Stripe dashboard, disconnect, and manual entry as a fallback — plus a delivery credentials section for Uber Direct and DoorDash Drive.
Uber Eats gained business location creation and pickup location linking, with tenant resolution by Uber customer ID for superadmin operations. Uber rejects address changes while orders are in progress, so the code retries with address fields stripped — name, phone and external ID are always accepted.
Built-in delivery settings were added as a configuration block: enable flag, minimum and maximum range, base fee, included miles, and per-mile rate — the groundwork for in-house delivery pricing alongside the third-party providers.