Class: SpreeDoordash::Quote
- Inherits:
-
Object
- Object
- SpreeDoordash::Quote
- Defined in:
- app/services/spree_doordash/quote.rb
Overview
Requests a live DoorDash Drive delivery-fee quote for an order — the storefront-facing half of this extension (called from Spree::Calculator::Shipping::DoordashQuote during checkout, M3) and again at order.completed if the original quote expired (M4).
order.total at whichever moment this is called is what's sent as
order_value — Spree recalculates on every checkout step already, and
DoorDash isn't in the money path (Spree's own payment method still
charges the customer; DoorDash only uses this for delivery-fee/
insurance math).
Defined Under Namespace
Classes: Result
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.call ⇒ Object
15 |
# File 'app/services/spree_doordash/quote.rb', line 15 def self.call(...) = new.call(...) |
Instance Method Details
#call(order) ⇒ Object
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/services/spree_doordash/quote.rb', line 17 def call(order) location_mapping = location_mapping_for(order) return nil unless location_mapping && order.ship_address client = SpreeDoordash::Client.for_store(order.store || Spree::Store.default) # A random suffix per attempt, not just order.number — confirmed live # against a real Sandbox quote: DoorDash rejects a *second* # /drive/v2/quotes call reusing the same external_delivery_id with a # 409 duplicate_delivery_id, even though the first quote is still open # (not yet accepted or expired). Checkout recalculates shipping rates # on essentially every step, so calling this twice for the same order # is the normal case, not an edge case — a stable per-order id made # the DoorDash rate silently vanish (RequestError is rescued below, # same as any other unserviceable-rate case) after the very first # quote. QuoteMapping upserts on order, so only the most recent # attempt's id is kept — the one that matters for accept (M4). external_delivery_id = "spree-doordash-#{order.number}-#{SecureRandom.hex(4)}" response = client.create_quote(build_payload(order, location_mapping, external_delivery_id)) mapping = persist_quote!(order, external_delivery_id, response) Result.new( fee_cents: mapping.quoted_fee_cents, currency: mapping.currency, external_delivery_id: mapping.external_delivery_id, expires_at: mapping.quote_expires_at ) rescue SpreeDoordash::Client::MissingCredentialsError, SpreeDoordash::RequestError => e # Unserviceable address, no credential connected, DoorDash-side # rejection — none of these should ever raise into checkout. The # calculator (M3) treats a nil Result as "this rate isn't available", # Spree's normal shape for "can't quote this," same as a carrier # simply not covering an address. Rails.logger.info("[SpreeDoordash] quote skipped for order #{order.number}: #{e.}") nil end |