The offer’s shipping profile
An offer stores its profile inshipping_profile_id, a required field on the Offer row. A read-only link on that field exposes the profile as offer.shipping_profile in query.graph.
You set the profile when you create the offer and can change it with updateOffersWorkflow:
offer.updated. The offer workflows don’t check that the profile belongs to the offer’s store, so validate that in your route when the input comes from a seller.
Shipping profiles on master products
Master products don’t carry a shipping profile of their own, but Medusa’s cart refresh keeps a shipping method only when a product in the cart matches the option’s profile. Without a profile on the product, multi-store carts would lose their shipping methods on every refresh.createOffersWorkflow closes that gap. For each master product in the run, it links the product to the offer’s shipping profile when the product has no profile yet:
- Product without a profile: the first offer in the run sets it
- Product that already has a profile: the link is skipped, even when another store’s offer names a different profile
- Several offers on one product in one run: only the first offer’s profile is linked
The product to profile link is one-to-one and exists only for the cart refresh. Each offer’s own
shipping_profile_id is still what decides how that store ships.updateOffersWorkflow doesn’t touch the product link, so changing an offer’s profile later leaves the product’s profile as it was.