> ## Documentation Index
> Fetch the complete documentation index at: https://docs.elasticfunnels.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Fulfillment Integration

> Send orders to a 3PL provider (ShipOffers or Jetpack) and reconcile cost of goods automatically.

## Overview

The fulfillment integrations push completed orders to a 3PL (Third-Party Logistics) provider and pull cost-of-goods (COGS) data back so your conversions show real profit, not just revenue.

## Supported providers

<CardGroup cols={2}>
  <Card title="ShipOffers Fulfillment" icon="ship">
    Pick, pack, and ship through ShipOffers. Multi-hub network in Colorado, Tennessee, and the Netherlands; same-day shipping; real-time tracking.
  </Card>

  <Card title="Jetpack Fulfillment" icon="rocket">
    Multi-hub fulfillment across 65+ warehouses with intelligent inventory distribution (Multi-Hub IQ) and carrier selection (Carrier IQ).
  </Card>

  <Card title="ShipOffers COGS Reconciliation" icon="receipt">
    Automatic email-based ingestion of weekly ShipOffers cost CSVs. Updates each conversion with line-item costs so profit is correct.
  </Card>
</CardGroup>

## How fulfillment dispatch works

1. **Order received** — A customer completes a purchase on your funnel.
2. **Merchant resolution** — The merchant on the conversion is looked up.
3. **Fulfillment provider lookup** — The product's `fulfillment_provider_id` (or merchant default) decides where the order goes. Each product can route to a different provider.
4. **Job queued** — A fulfillment job is queued \~10 seconds after the conversion is finalized so refunds in the first window can short-circuit it.
5. **Order pushed** — Customer info, shipping address, line items (with mapped SKUs), shipping method, and order total are sent to the provider.
6. **Tracking sync** — When the provider returns shipment status and tracking, EF stores it on the conversion and surfaces it in the dashboard.

## Setup — ShipOffers

<Steps>
  <Step title="Get credentials">
    Contact your ShipOffers account manager and request your **Store ID**, **Username**, and **Password**.
  </Step>

  <Step title="Create the integration">
    Go to **Integrations** → **Operations** → **ShipOffers Fulfillment**. Enter the credentials and pick a default shipping service (Standard, Express, etc.).
  </Step>

  <Step title="Map SKUs">
    In ShipOffers, set up your products and copy the SKU codes. In ElasticFunnels, edit each product and ensure its SKU matches the ShipOffers SKU exactly. SKU is what the picker uses to fulfill — mismatched SKUs cause picking errors.
  </Step>

  <Step title="Assign to merchants or products">
    Either set ShipOffers as the **Fulfillment Provider** on a merchant (default for all products under that merchant) or override per product.
  </Step>

  <Step title="(Optional) Enable COGS reconciliation">
    Activate **ShipOffers COGS Reconciliation** as a separate integration, copy the dedicated reconciliation email address, and ask ShipOffers to email weekly cost CSVs to that address. EF parses each CSV and updates the matched conversions with line-item costs.
  </Step>
</Steps>

## Setup — Jetpack

<Steps>
  <Step title="Get credentials">
    Contact Jetpack at jetpackshipping.com or 1-844-4-JETPACK. You'll receive an **API Key ID** and **Secret Key**.
  </Step>

  <Step title="Create the integration">
    Go to **Integrations** → **Operations** → **Jetpack Fulfillment**. Enter your credentials and configure the primary warehouse and shipping preferences.
  </Step>

  <Step title="Map products and SKUs">
    Set up your product catalog inside Jetpack with the same SKU codes you use on each `BrandProduct` in EF.
  </Step>

  <Step title="Assign to merchants or products">
    Set Jetpack as the **Fulfillment Provider** at the merchant level, or override per product when only some products ship from Jetpack.
  </Step>
</Steps>

## SKU mapping

The SKU on every `BrandProduct` in EF must match the SKU your 3PL uses to identify the physical item. Without a match, the order will be rejected by the provider or filled with the wrong product. To set or update the SKU:

1. Go to **Products**.
2. Edit the product.
3. Set its **SKU** to the value from your 3PL catalog.
4. Save.

Re-saving a product does **not** retroactively re-fulfill old orders; only new orders use the updated SKU.

## Monitoring

Go to **Conversions → Fulfillment** to see every fulfillment attempt with its status:

* **Pending** — Queued, waiting for the dispatch window to elapse.
* **Sent** — Provider accepted the order.
* **Failed** — Provider rejected the payload (most often: missing SKU or invalid address). Use the failure detail to fix the data and retry.
* **Tracking** — Provider has shipped the order; the tracking number and carrier are surfaced inline.

<Info>
  If a fulfillment attempt fails because of a bad address, you can manually edit the conversion's shipping address and re-send. SKU mismatches require fixing the product first; orders already in flight are not re-keyed automatically.
</Info>
