SafaribidSafaribid Docs

Bidding and Dynamic Pricing Task List

Cross-project implementation checklist for system-priced and customer-bid rides and deliveries.

Bidding and Dynamic Pricing

This checklist tracks the implementation of configurable system pricing and driver bidding for rides, electric rides, and package deliveries.

Product rules

  • Read config.id = 1 and its settings.pricing values on the server.
  • Treat 1 as system pricing and 2 as bidding.
  • Support separate configuration for rides and deliveries.
  • Always calculate and retain the system price, including in bidding mode.
  • In bidding mode, validate the customer offer on the server:
    • Minimum: system price × 0.80.
    • Maximum: system price × 2.00.
  • Define rounding and currency rules for all comparisons and displayed amounts.
  • Keep the current system-priced flow unchanged when bidding is disabled.

Phase 1: Data model and migrations

  • Add pricing fields to deliveries (or the selected order record): pricing mode, system price, customer offer, and selected bid reference. The existing total_price remains the final-price field.
  • Create a dedicated delivery_bids table.
  • Add a unique constraint for (delivery_id, driver_id).
  • Store bid status, amount, timestamps, expiration, and rejection reason where needed.
  • Add indexes for open bids by delivery and active requests by driver.
  • Add migration rollback/documentation and deploy the migration to each environment.

Phase 2: API and business rules

  • Add a server-side config reader with safe fallback behavior when pricing settings are missing or invalid.
  • Extend price calculation to return both the system price and the applicable pricing mode.
  • Extend the existing request-creation endpoint to create a system-priced or bidding request.
  • Add reusable server-side validation for customer offers between 80% and 200% of the system price.
  • Dispatch a bidding request to up to five eligible nearby drivers.
  • Add driver bid submission with authorization, availability, amount, and expiration checks.
  • Add an endpoint for the customer to list current bids and their statuses.
  • Add an atomic endpoint for the customer to select one bid.
  • On selection, assign the driver, set the final price, accept one bid, and close the remaining bids in one transaction.
  • Prevent selection of expired, withdrawn, duplicate, or already-selected bids.
  • Define cancellation, no-response, driver rejection, and no-driver-found behavior.
  • Reuse the existing delivery status lifecycle after a bid is selected.
  • Preserve the existing payment timing: bid selection sets the final delivery amount and uses the existing payment flow.

Phase 3: Realtime events

  • Add initial request, bid received, and selection realtime events.
  • Define and document bid updated, bid expired, cancellation, and timeout events.
  • Send bidding requests only to the selected nearby-driver batch.
  • Make event handling idempotent after reconnects.
  • Persist enough state for clients to restore the bidding screen after app restart.
  • Add server-side expiry handling so a client timer cannot keep a bid open.

Phase 4: Customer app

  • Fetch pricing mode before showing the ride submission flow.
  • Continue fetching and displaying the calculated system price.
  • In bidding mode, show the allowed offer range and validate the entered amount locally.
  • Submit the customer offer with the request.
  • Add a live bid sheet showing driver, amount, and selection state.
  • Allow the customer to select one bid explicitly.
  • Show loading, empty, expired, rejected, cancellation, and no-response states.
  • Restore open requests and received bids after reconnecting or reopening the app.
  • Ensure the selected bid transitions into the existing tracking and activity flows.
  • Apply the same behavior to Rides, Electric, and Deliveries according to their config keys.

Phase 5: Driver app

  • Add a bidding request card for eligible nearby requests.
  • Show the route, package/ride details, customer offer, system reference price, and remaining time.
  • Allow the driver to submit a bid before expiry.
  • Prevent bidding while unavailable or already committed to another request.
  • Notify the driver when their bid is selected, rejected, expired, or cancelled.
  • Continue through the existing accepted-delivery flow after selection.

Phase 6: Concurrency, security, and operations

  • Make bid selection transactional and lock the delivery/request row during selection.
  • Ensure only the request owner can submit the customer offer or select a bid.
  • Ensure only the invited driver can submit a bid for a request.
  • Prevent duplicate dispatches and duplicate driver assignments.
  • Add rate limits for bid submission and selection.
  • Add structured logs for dispatch, bids, selection, expiry, and failures.
  • Add monitoring for requests with no bids and requests stuck in an open state.
  • Decide whether driver/customer pricing history is visible and how long it is retained.

Phase 7: Testing and rollout

  • Unit-test config parsing, price bounds, rounding, and status transitions.
  • Integration-test migrations, request creation, bid submission, selection, cancellation, and expiry.
  • Test concurrent selection of two bids and concurrent driver submissions.
  • Test socket reconnects, duplicate events, delayed events, and app restarts.
  • Test rides, electric rides, and deliveries independently.
  • Test system mode to confirm existing behavior is unchanged.
  • Test bidding mode with the minimum, maximum, below-range, and above-range offers.
  • Add feature-flag or staged rollout controls.
  • Deploy to staging and verify real nearby-driver dispatch before production rollout.
  • Document the final API contract and operational runbook.

Open decisions before implementation

  • Bid/request window: 120 seconds for the initial request; each submitted bid has its own 120-second server deadline.
  • Drivers see the customer offer and system reference price.
  • A driver may revise or withdraw a bid before expiry.
  • The customer offer is locked after dispatch; changing it requires cancelling and creating a new request.
  • Payment timing remains the existing post-selection payment flow.
  • The initial five eligible drivers are fixed; no replenishment occurs in the first release.
  • Final names for pricing modes, statuses, socket events, and database columns.

How is this guide?

On this page