Class: SpreeDoordash::DeliveryStatusMapper
- Inherits:
-
Object
- Object
- SpreeDoordash::DeliveryStatusMapper
- Defined in:
- app/services/spree_doordash/delivery_status_mapper.rb
Overview
Applies a DoorDash delivery webhook event to the mapped Spree order — the DoorDash analog of SpreeSquare::OrderStatusMapper.
DoorDash's own event_name vocabulary (verified against developer.doordash.com/en-US/docs/drive/reference/webhooks/, not assumed): DASHER_CONFIRMED, DASHER_CONFIRMED_PICKUP_ARRIVAL, DASHER_PICKED_UP, DASHER_CONFIRMED_DROPOFF_ARRIVAL, DASHER_DROPPED_OFF, DELIVERY_CANCELLED, plus return-to-pickup-only events (DELIVERY_RETURN_INITIALIZED, DASHER_CONFIRMED_RETURN_ARRIVAL, DELIVERY_RETURNED) and DELIVERY_BATCHED for pre-staged batches.
No version/sequence field exists in DoorDash's payload the way Square's does, so — like OrderStatusMapper — this doesn't attempt to gate on ordering. Safety against duplicate delivery instead comes entirely from WebhookEvent's idempotency key (a genuine redelivery never reaches this class a second time) and from the state-guarded, idempotent operations below. DoorDash's own docs note events are sent "as soon as the event takes place," in the natural lifecycle order, but that ordering guarantee (or lack of one) across concurrent webhook workers is unverified until seen live — flagged here rather than assumed, same precedent as OrderStatusMapper's own comment.
Constant Summary collapse
- SHIP_EVENTS =
%w[DASHER_DROPPED_OFF].freeze
- CANCEL_EVENTS =
%w[DELIVERY_CANCELLED].freeze
- LABEL_ONLY_EVENTS =
Real, DoorDash-lifecycle events with no Spree shipment_state equivalent — recorded as a friendly last_status label only, same "label vs. state transition" split as OrderStatusMapper's FULFILLMENT_LABEL_STATES. DELIVERY_RETURNED (the order came back to the store, never reached the customer) arguably deserves the same treatment as a cancellation, but is left label-only until this extension has actually observed one live — not assumed.
%w[ DASHER_CONFIRMED DASHER_CONFIRMED_PICKUP_ARRIVAL DASHER_CONFIRMED_DROPOFF_ARRIVAL DELIVERY_RETURN_INITIALIZED DASHER_CONFIRMED_RETURN_ARRIVAL DELIVERY_RETURNED DELIVERY_BATCHED ].freeze
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.call ⇒ Object
38 |
# File 'app/services/spree_doordash/delivery_status_mapper.rb', line 38 def self.call(...) = new.call(...) |
Instance Method Details
#call(payload) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'app/services/spree_doordash/delivery_status_mapper.rb', line 40 def call(payload) mapping = SpreeDoordash::DeliveryMapping.find_by(external_delivery_id: payload['external_delivery_id']) return unless mapping event_name = payload['event_name'] order = mapping.order case event_name when *SHIP_EVENTS ship!(order) when *CANCEL_EVENTS cancel!(order) when *LABEL_ONLY_EVENTS # No Spree-side transition — last_status below is the only effect. end mapping.update!( last_status: event_name || mapping.last_status, tracking_url: payload['tracking_url'].presence || mapping.tracking_url, dasher_name: payload['dasher_name'].presence || mapping.dasher_name, dasher_phone: payload['dasher_dropoff_phone_number'].presence || mapping.dasher_phone ) end |