Google Sign-In Required

Use your company Google account to access the BetterFleet private content.

Back to private home

BetterFleet Support Private
Skip to content
BetterFleet Dev Wiki
Specification: Workspace-Owned Stripe Credentials for Roaming Payments
Initializing search
    bf-dev
    • Home
    • Product Capabilities
    • Process
    • Current Work
    • System Design
    • Software Reference
    • Operations
    bf-dev
    • Home
      • Overview
      • Manage
      • Overview
      • Product Engineering Workflow
      • Product Engineering Delivery
      • Product Engineering Workflow in Linear
        • GitLab Feature Flags
        • In-App Docs Authoring
        • Release Notes
      • Templates
      • Publishing
      • Workflow Companions
      • Overview
      • Active Artifacts
      • Backlog Artifacts
      • Archived Artifacts
      • Overview
      • Microgrid
      • OSCP
        • Challenge
        • Specification
        • Spec
        • Architecture
        • Overview
        • Script Runtime Model
        • Compose Profiles and Modes
        • Repo Topology
        • CI and Release Integration
        • Overview
        • Internal Application Diagrams
          • Overview
          • Web Model
          • Core Model
        • Service Interaction Flows
        • Data and State
          • Index
          • bf-manage-web
          • bf-manage-core
          • bf-manage-connect
          • bf-manage-sitepwrmon
          • bf-manage-incidents
          • bf-telematics
          • bf-depot-sim
          • bf-manage-roaming
          • bf-support-microsite
          • bf-digital-twin
          • bf-schedule-creator
        • Overview
        • Internal Application Diagrams
        • Migration and Flags
        • Simulation Request Lifecycle
          • Index
          • bf-bnl-ui
          • bf-bnl-settings
          • bf-bnl-schedule-analysis-compute
          • bf-route-modelling
          • bf-schedule-creator
          • bf-digital-twin
        • Overview
        • Secrets and Env Strategy
        • Vendors and Local Dependencies
        • ADRs
        • Service Matrix
        • Cloud Dependencies
        • Ports and URLs
      • Onboarding
      • Daily Operations Runbook
        • Overview
        • Staging Hotfix Release
        • Production Hotfix Release
        • Terraform Plan Dry Runs
      • Troubleshooting
      • Testing Guide
    • TLDR (Solution Summary)
    • 1. Summary
    • 2. Users and Use Cases
    • 3. Conceptual Model Terms and Decisions
      • Key Terms
      • Decision Ledger
    • 4. Domain Model and Eventstorming (Conceptual)
      • Interaction Flow
      • Event Timeline
      • Event Dictionary
    • 5. Requirements and Constraints
    • 6. Interaction and Flow
      • Flowchart: Workspace-Owned Roaming Checkout
      • Sequence Diagram: End-to-End Ownership Flow
    • 7. Non-Technical Implementation Approach
    • 8. Open Questions
    • 9. Appendices

    Specification: Workspace-Owned Stripe Credentials for Roaming Payments¶

    TLDR (Solution Summary)¶

    Move roaming payment ownership from Evenergi-managed Stripe credentials to workspace-owned Stripe credentials configured in Manage Workspace settings and used end-to-end in roaming checkout and payment authorization. - Research brief + implementation plan + run a Stripe-only best-practice discovery and define the agreed delivery plan (including webhook necessity) + implementation starts from an approved plan. - Workspace > Roaming access > Advanced configuration + add Stripe credential fields (publishable key, secret key, webhook signing secret) + workspace admins can configure their own payment account for roaming sessions. - GET/PATCH /api/permissions/workspace/{workspace_id}/ocpi-config + extend OCPI config contract with Stripe credential state + Manage Web can read/write credential configuration and show validation state. - POST /ocpi/create-payment-intent + resolve Stripe credentials by workspace instead of global environment keys + each paid roaming pre-authorization is created in the workspace's own Stripe account. - POST /ocpi/stripe/webhook + validate webhook signatures and intent ownership against workspace credential context + authorization/capture state changes only apply to the owning workspace. - GET /emsp/2.2.1/locations/{location_id}?show_ocpi_cfg=true + expose workspace publishable key in roaming OCPI configuration + Roaming Web initializes Stripe checkout with workspace-specific credentials. - bf-manage-roaming payment bootstrap (RegionProvider/AppRouter) + replace region-default Stripe key behavior for paid sessions with workspace-configured key behavior + drivers are charged against the customer workspace account rather than the Evenergi account. - Customer onboarding guide + define customer setup steps for Stripe keys and webhook configuration (if required) + customers can self-serve onboarding with support-ready guidance.

    1. Summary¶

    • Problem statement:
      • Roaming payments currently use platform-level Stripe credentials, so customers cannot run roaming payments under their own Stripe account ownership, reporting, payout, and compliance controls.
    • Goal and success criteria:
      • Allow each roaming-enabled workspace to configure and use its own Stripe account credentials for paid roaming sessions.
      • Success is measured by:
      • 100% of new paid roaming payment intents for configured workspaces being created under that workspace Stripe account.
      • 0 paid roaming sessions for configured workspaces using Evenergi default Stripe keys.
      • No regression to free-session roaming flows.
    • What will be built in this phase:
      • Research brief + implementation plan + assess Stripe-only best-practice architecture, credential lifecycle, and webhook necessity + implementation is sequenced from approved findings.
      • Workspace > Roaming access > Advanced configuration + credential fields + system admins save workspace Stripe credentials.
      • Workspace OCPI Config API + Stripe credential fields and validation state + Manage Web can load and patch credential config safely.
      • Roaming payment intent creation flow + workspace credential resolution + payment intents are created using workspace-owned Stripe account.
      • Roaming webhook authorization flow + workspace signature validation and ownership checks + webhook events cannot authorize another workspace's intents.
      • Roaming location bootstrap contract + workspace publishable key exposure + roaming checkout initializes the correct Stripe account.
      • Roaming checkout loader + workspace-key-based Stripe initialization and explicit error handling + payment cannot start when credentials are missing/invalid.
      • Customer onboarding guide + Stripe account setup, key entry, and webhook setup instructions (or explicit no-webhook path) + customers can complete setup with predictable outcomes.
    • Scope (in/out) for this phase:
      • In:
      • Research-first Stripe-only architecture decision and implementation plan.
      • Manage Web workspace-level Stripe credential management for roaming.
      • Core API contract updates for workspace OCPI config and roaming payment flow.
      • Roaming Web checkout key source change from region env to workspace config.
      • Customer-facing onboarding documentation for Stripe setup and webhook requirements.
      • Out:
      • Multi-provider payment support.
      • Non-roaming billing flows.
      • External partner OCPI settlement changes.
      • Finance reconciliation and accounting exports.
      • Backlog slicing and story-level acceptance criteria.
    • Current baseline (as of March 5, 2026):
      • bf-manage-roaming chooses Stripe publishable key from region environment variables (VITE_STRIPE_KEY_AU|EU|US|CA) via RegionProvider/getRegionData.
      • bf-manage-core roaming payment orchestration uses global Stripe environment configuration (STRIPE_SECRET / STRIPE_API_KEY and STRIPE_WH_SECRET) for payment intents and webhook verification.
      • bf-manage-web roaming advanced configuration currently manages only allow_guest_access, allow_user_registration, and pre_auth_cents through GET/PATCH /api/permissions/workspace/{workspace_id}/ocpi-config.
    • Future evolution guardrails:
      • This phase explicitly supports Stripe only for roaming payments.
      • This phase must follow Stripe credential and webhook security best practices.
      • This phase must not block future per-workspace key rotation without downtime.
      • This phase must preserve ability to support per-workspace regional key variants later.
    • Not in scope:
      • Database schema design details, infrastructure implementation details, and code-level API implementation specifics.

    2. Users and Use Cases¶

    • Primary personas:
      • Workspace system admin configuring roaming payment ownership.
      • Roaming driver paying for a charging session.
      • BetterFleet support/operations troubleshooting payment configuration issues.
    • High-level user stories:
      • As a workspace system admin, I want to configure workspace Stripe credentials in roaming settings so roaming payments are owned by my organization.
      • As a roaming driver, I want checkout to work consistently so I can start paid sessions without payment-account mismatches.
      • As support staff, I want clear ownership and configuration status so I can quickly diagnose payment failures.
    • Edge cases and failure modes:
      • Workspace enables roaming but has no valid Stripe credentials.
      • Workspace rotates keys while payment intents are in progress.
      • Webhook arrives with valid Stripe structure but wrong workspace context.
      • Workspace has free-session tariffs where Stripe should not be required.
      • Workspace submits malformed credentials or credentials from the wrong Stripe mode.

    3. Conceptual Model Terms and Decisions¶

    Key Terms¶

    Term Definition Notes
    Workspace Stripe Profile The payment credential set assigned to one workspace for roaming payments Canonical owner of roaming Stripe account context
    Publishable Key Client-safe key used by roaming checkout to initialize Stripe Elements Exposed to roaming UI
    Secret Key Server-side Stripe key used for payment intent and capture operations Never returned in plaintext after save
    Webhook Signing Secret Workspace secret used to verify Stripe webhook authenticity Server-side verification only
    Credential Health Current validity status of workspace Stripe profile for paid roaming sessions Used for configuration UI and roaming preconditions
    Payment Ownership The workspace Stripe account under which intents and charges are created Must match workspace operating the charger
    Roaming Checkout Context Combined location, tariff, and OCPI config data used to start checkout Includes workspace publishable key in this phase

    Decision Ledger¶

    ID Decision Rationale Alternatives Rejected Implications
    D-001 Stripe credentials are owned and configured per workspace Aligns billing ownership and payout control with customer Keep global platform keys for all workspaces Requires workspace-level config lifecycle
    D-002 Secret credentials are write-only in UI/API reads Reduces accidental exposure and leakage risk Return full secrets for edit convenience Requires masked status UX and explicit rotate action
    D-003 Paid roaming requires valid workspace Stripe profile Prevents paid-session startup on broken configuration Silent fallback to Evenergi account after workspace setup Introduces explicit error handling and admin remediation flow
    D-004 Webhook processing must verify both signature and workspace ownership Prevents cross-workspace authorization/capture mutation Signature-only validation with no workspace ownership checks Requires workspace identifiers in payment intent metadata and verification policy
    D-005 Workspace remains the primary ownership boundary in phase 1 Matches existing roaming/access configuration boundaries Per-depot credential ownership in this phase Keeps first rollout simpler, supports later per-depot extension
    D-006 Roaming payments remain Stripe-only in this initiative Keeps scope clear and avoids unnecessary abstraction Introduce payment-provider abstraction now Faster delivery and lower implementation risk

    4. Domain Model and Eventstorming (Conceptual)¶

    • Bounded context and ubiquitous language:
      • Workspace Configuration context: workspace roaming settings and payment ownership.
      • Roaming Checkout context: location/tariff bootstrap and checkout initialization.
      • Roaming Payment Orchestration context: pre-auth, authorization, capture lifecycle.
    • Aggregates and entities (abstract):
      • Workspace Stripe Profile aggregate: workspace, publishable key, secret credential references, credential health.
      • OCPI Charging Intent aggregate: authorization reference, payment intent identifier, workspace ownership, payment state.
      • OCPI Session aggregate: charging telemetry and final payment capture linkage.
    • Value objects (if relevant):
      • StripeCredentialSet, CredentialHealthStatus, PaymentOwnershipRef.
    • Domain events and their triggers:
      • WorkspaceStripeCredentialsUpdated when admin saves credentials.
      • WorkspaceStripeCredentialsValidated when validation passes.
      • WorkspaceStripeCredentialsValidationFailed when validation fails.
      • WorkspacePaymentIntentCreated when paid roaming pre-auth succeeds.
      • WorkspacePaymentIntentAuthorizationReceived when Stripe webhook confirms capturable funds.
      • WorkspaceSessionPaymentCaptured when session billing is finalized.
    • Commands, actors, and policies:
      • SaveWorkspaceStripeCredentials (workspace admin).
      • ValidateWorkspaceStripeCredentials (system policy).
      • RequestRoamingPreAuth (roaming app on driver action).
      • ProcessStripeAuthorizationWebhook (system policy on provider event).
    • Invariants and business rules enforced:
      • A paid roaming session references exactly one owning workspace Stripe profile.
      • Secret credentials are never exposed in read responses or logs.
      • Webhook authorization/capture state transitions are valid only when workspace ownership matches intent metadata.
      • Free sessions remain operational without Stripe credential requirement.
    • External systems and integrations:
      • Stripe checkout and webhook integration remains shared endpoint-based but workspace-context aware.
      • Manage Web and Roaming Web consume Workspace OCPI configuration via existing permissions/location APIs.

    Interaction Flow¶

    flowchart LR
      Admin["Workspace Admin"] --> Cmd1["Save Workspace Stripe Credentials"]
      Cmd1 --> E1["WorkspaceStripeCredentialsUpdated"]
      E1 --> P1{"Credentials Valid?"}
      P1 -->|"Yes"| E2["WorkspaceStripeCredentialsValidated"]
      P1 -->|"No"| E3["WorkspaceStripeCredentialsValidationFailed"]
      Driver["Roaming Driver"] --> Cmd2["Request Roaming Pre-Auth"]
      Cmd2 --> E4["WorkspacePaymentIntentCreated"]
      Stripe["Stripe Webhook"] --> Cmd3["Process Authorization Webhook"]
      Cmd3 --> E5["WorkspacePaymentIntentAuthorizationReceived"]
      E5 --> E6["WorkspaceSessionPaymentCaptured"]

    Event Timeline¶

    timeline
      title Workspace-Owned Roaming Payment Timeline
      WorkspaceStripeCredentialsUpdated: Admin saves workspace Stripe profile
      WorkspaceStripeCredentialsValidated: System marks profile ready for paid roaming
      WorkspacePaymentIntentCreated: Driver initiates paid roaming session
      WorkspacePaymentIntentAuthorizationReceived: Stripe webhook confirms pre-auth
      WorkspaceSessionPaymentCaptured: Final session charge captured

    Event Dictionary¶

    • WorkspaceStripeCredentialsUpdated: Workspace payment credentials changed | defines payment ownership boundary | workspaceId, credentialVersion, updatedBy | triggers credential validation.
    • WorkspaceStripeCredentialsValidated: Workspace profile is ready for paid sessions | allows paid roaming starts | workspaceId, validatedAt, mode | enables payment intent creation.
    • WorkspaceStripeCredentialsValidationFailed: Saved profile cannot be used | blocks paid roaming path | workspaceId, failureCode, validatedAt | triggers admin remediation state.
    • WorkspacePaymentIntentCreated: Pre-auth intent created in workspace Stripe account | starts payment lifecycle | workspaceId, paymentIntentId, authorizationReference | allows session authorization.
    • WorkspacePaymentIntentAuthorizationReceived: Stripe confirmed capturable amount | allows bind/start/capture flow | workspaceId, paymentIntentId, eventId | updates charging intent state.
    • WorkspaceSessionPaymentCaptured: Final charge captured at session completion | closes payment lifecycle | workspaceId, ocpiSessionId, capturedAmount | supports reconciliation/reporting.

    5. Requirements and Constraints¶

    • Functional requirements:
      • FR-001: Manage Web must provide workspace-level Stripe credential inputs in roaming advanced configuration for users with roaming update permission.
      • FR-002: Workspace OCPI config read/write APIs must support Stripe credential configuration and credential health status for a workspace.
      • FR-003: Secret key and webhook signing secret must be write-only in API/UI read paths and rotatable without exposing previous values.
      • FR-004: Credential save must run validation and return explicit success/failure outcomes consumable by UI messaging.
      • FR-005: Roaming location bootstrap payload must include workspace publishable key (or equivalent client initialization value) for paid sessions.
      • FR-006: Roaming checkout initialization must use workspace publishable key for paid sessions instead of region-default keys.
      • FR-007: Payment intent creation for paid roaming sessions must use workspace secret credentials and include workspace ownership metadata.
      • FR-008: Webhook authorization handling must validate signature and workspace ownership before mutating charging-intent state.
      • FR-009: System must block paid roaming session start when roaming is enabled but credential health is invalid.
      • FR-010: Free-session roaming flow must remain available and must not require Stripe credential checks.
      • FR-011: Credential changes and payment ownership decisions must be auditable by workspace and actor.
      • FR-012: Error responses for configuration and payment bootstrap failures must be explicit enough for admin/support triage.
      • FR-013: A research brief and implementation plan must be produced first, covering Stripe best-practice credential handling, webhook strategy, and rollout sequencing.
      • FR-014: Customer onboarding documentation must describe Stripe account setup, required keys, webhook setup steps (if required), and verification/troubleshooting checks.
    • Non-functional requirements:
      • NFR-001: Stripe secrets must not appear in plaintext in API read responses, client storage, or application logs.
      • NFR-002: Paid roaming payment-intent creation latency must not regress beyond acceptable current behavior for end users.
      • NFR-003: Credential updates must propagate to paid session creation paths within one minute.
      • NFR-004: Webhook processing must be idempotent by event identity to avoid duplicate authorization transitions.
      • NFR-005: Every paid roaming payment intent must be traceable to workspace ownership in operational diagnostics.
    • Constraints and assumptions:
      • One Stripe account per workspace in this phase.
      • Workspace is the ownership boundary in this phase, not depot-level ownership.
      • Existing roaming tariff and user-group behavior remains unchanged.
      • Free-session behavior remains independent of Stripe.
    • Build item coverage mapping:
      • Research brief + implementation plan build item -> FR-013.
      • Workspace > Roaming access > Advanced configuration build item -> FR-001, FR-003, FR-004, FR-012, NFR-001.
      • GET/PATCH /api/permissions/workspace/{workspace_id}/ocpi-config build item -> FR-002, FR-003, FR-004, FR-011, NFR-001, NFR-003.
      • POST /ocpi/create-payment-intent build item -> FR-007, FR-009, NFR-002, NFR-005.
      • POST /ocpi/stripe/webhook build item -> FR-008, FR-011, NFR-004, NFR-005.
      • GET /emsp/2.2.1/locations/{location_id}?show_ocpi_cfg=true build item -> FR-005, FR-012, NFR-003.
      • bf-manage-roaming payment bootstrap (RegionProvider/AppRouter) build item -> FR-006, FR-009, FR-010, FR-012, NFR-002.
      • Customer onboarding guide build item -> FR-014.
    • Verification notes:
      • FR-001-FR-004: Validate via workspace settings API/UI integration checks and permission checks.
      • FR-005-FR-010: Validate through end-to-end roaming paid/free session flows across configured and misconfigured workspaces.
      • FR-011-FR-012: Validate through audit/log review and typed error response checks.
      • FR-013: Validate by review/approval of the research brief and implementation plan before build execution.
      • FR-014: Validate by walkthrough of onboarding documentation with support/customer-success stakeholders.
      • NFR-001-NFR-005: Validate through security review, observability dashboards, webhook replay/idempotency checks, and latency benchmarks.

    6. Interaction and Flow¶

    • User journey or process steps:
      • Workspace admin opens Workspace > Roaming access > Advanced configuration and saves Stripe credential set.
      • System validates credentials and marks workspace credential health.
      • Driver starts paid roaming session; roaming app loads location OCPI config and initializes checkout with workspace publishable key.
      • Core creates payment intent using workspace secret credentials and records workspace ownership metadata.
      • Stripe webhook authorizes intent; core validates ownership and advances charging intent state.
      • Session ends and final capture is recorded against workspace-owned Stripe account.

    Flowchart: Workspace-Owned Roaming Checkout¶

    flowchart TD
      A["Admin saves workspace Stripe credentials"] --> B{"Credentials valid?"}
      B -->|"No"| C["Set credential health to invalid and show admin error"]
      B -->|"Yes"| D["Set credential health to valid"]
      D --> E["Driver requests paid roaming session"]
      E --> F["Roaming app reads workspace publishable key"]
      F --> G["Core creates payment intent using workspace secret key"]
      G --> H["Stripe webhook authorization received"]
      H --> I{"Workspace ownership matches intent metadata?"}
      I -->|"No"| J["Reject event and log security warning"]
      I -->|"Yes"| K["Authorize intent and continue session payment lifecycle"]

    Sequence Diagram: End-to-End Ownership Flow¶

    sequenceDiagram
      participant Admin as Workspace Admin
      participant Web as Manage Web
      participant Core as Manage Core
      participant Roam as Roaming Web
      participant Stripe as Stripe
    
      Admin->>Web: Save workspace Stripe credentials
      Web->>Core: PATCH workspace ocpi-config
      Core-->>Web: Credential health result
      Roam->>Core: GET location with ocpi config
      Core-->>Roam: Location + workspace publishable key
      Roam->>Core: POST create-payment-intent
      Core->>Stripe: Create PaymentIntent (workspace secret key)
      Stripe-->>Core: PaymentIntent created
      Core-->>Roam: clientSecret + charging_intent
      Stripe->>Core: Webhook authorization event
      Core-->>Core: Verify signature + workspace ownership
      Core-->>Roam: Payment authorized for session flow

    7. Non-Technical Implementation Approach¶

    • Approach overview:
      • Produce a research-first Stripe-only recommendation and implementation plan before engineering changes.
      • Align product, security, and support on workspace credential ownership policy.
      • Deliver in thin vertical slices across settings, API contract, and roaming payment runtime.
      • Pilot with selected roaming-enabled workspaces before broad rollout.
    • Delivery sequencing:
      • Phase 0: Research Stripe best practices, decide webhook necessity/responsibilities, and publish approved implementation plan.
      • Phase 1: Finalize credential model semantics and error taxonomy.
      • Phase 2: Introduce workspace credential management UX and API updates.
      • Phase 3: Switch payment-intent and webhook processing to workspace-owned credential resolution.
      • Phase 4: Switch roaming checkout bootstrap to workspace key source and remove region-default dependency for paid sessions.
      • Phase 5: Publish customer onboarding documentation for keys/webhooks and support troubleshooting.
      • Phase 6: Roll out with monitoring, support runbook, and fallback playbook for misconfiguration.
    • Design considerations:
      • Prioritize secure secret handling and operational diagnosability over rapid rollout breadth.
      • Preserve free-session continuity to avoid regressions for non-paid roaming paths.
    • Dependencies and prerequisites:
      • Security approval for credential handling policy.
      • Product decision on workspace credential validation behavior and admin UX states.
      • Support/operations alignment on incident response for invalid credentials and webhook failures.

    8. Open Questions¶

    • Should phase 1 accept raw Stripe secret keys or require restricted keys only?
    • Should paid roaming be hard-blocked when credential health is invalid, or should there be an explicit temporary fallback mode?
    • Is one publishable key per workspace sufficient, or is per-country/per-region key configuration required now?
    • What is the required key-rotation behavior for in-flight sessions (immediate cutover vs overlap window)?
    • Should webhook verification support multiple active signing secrets during rotation?
    • What credential validation signal is required at save time (format-only vs provider round-trip)?
    • Do customers need to register and manage webhooks in their own Stripe account for this design, or can webhook handling remain fully platform-managed?

    9. Appendices¶

    • Affected artifact references (current baseline):
      • bf-manage-web/src/pages/Settings/Workspace/RoamingAccess/AdvancedConfiguration.tsx
      • bf-manage-web/src/services/workspace.ts
      • bf-manage-web/src/interfaces/workspace.ts
      • bf-manage-core/src/api/permissions.py
      • bf-manage-core/src/workspace/workspace_service.py
      • bf-manage-core/src/OCPI/router.py
      • bf-manage-core/src/OCPI/payments/stripe_gateway.py
      • bf-manage-core/src/vemo_ocpi/emsp/locations/api_v_2_2_1.py
      • bf-manage-roaming/src/context/regionContext.tsx
      • bf-manage-roaming/src/router/AppRouter.tsx
      • bf-manage-roaming/src/services/locations.ts
      • bf-manage-roaming/src/types/ocpi.ts
    Made with Material for MkDocs