# Integratorguide: Sådan læser du Pakkeshopper-data i Shopify

Pakkeshopper skriver oplysninger om fragt og pakkeshop til Shopify **to steder**:

1. **Feltet `code` på shipping line** er en kompakt, maskinlæsbar streng, der identificerer transportfirmaet, leveringstypen og (hvor det er relevant) den valgte pakkeshop.
2. **Ordreattributter** *(nyere, anbefalet)* er et sæt navngivne, læsbare `_pakkeshopper_*`-attributter på ordren med transportfirma, leveringstype og alle detaljer om pakkeshoppen.

For de fleste integrationer er **ordreattributterne den nemmeste og mest robuste kilde**. Feltet `code` findes stadig af hensyn til bagudkompatibilitet og som krydstjek.

---

## 1. Feltet `code` på shipping line

**Her finder du det**

| API | Felt |
|-----|------|
| REST Admin API | `order.shipping_lines[].code` |
| GraphQL Admin API | `order.shippingLines.edges[].node.code` |
| Carrier Service-callback | ratens `service_code` |

> Det ældre `order.shipping_method.code` er samme værdi under det gamle feltnavn.

### 1.1 Format (nuværende, "Pakkeshopper 2.0")

```
pakkeshopper:P{ID}_{carrier}_{type}[_{pickup_point_id}]
```

| Segment | Betydning |
|---------|-----------|
| `pakkeshopper` | Fast præfiks, der identificerer vores app. |
| `:P{ID}` | Vores interne id for fragtraten (`P` er bogstaveligt og sat på med kolon, fx `:P7`). |
| `{carrier}` | Transportfirmaets token med små bogstaver (se tabellen nedenfor). |
| `{type}` | Leveringstype: `droppoint`, `delivery_home`, `delivery_company` eller `other_other`. |
| `{pickup_point_id}` | Kun ved `droppoint`. Transportfirmaets eget id for pakkeshoppen, eller `*` (se afsnit 1.3). |

**Tokens for transportfirmaer**

| Token | Transportfirma | Token | Transportfirma |
|-------|----------------|-------|----------------|
| `gls` | GLS | `dhl` | DHL |
| `postnord` | PostNord | `instabox` | Instabox |
| `postnl` | PostNL | `budbee` | Budbee |
| `bring` | Bring | `helthjem` | Helthjem |
| `dao` | DAO | `hermes` | Hermes |
| `ups` | UPS | `evri` | Evri |
| `burd` | Burd | | |

### 1.2 Eksempler

```
pakkeshopper:P7_gls_droppoint_95218        Pakkeshop (GLS-shop nr. 95218)
pakkeshopper:P42_postnord_delivery_home    Hjemmelevering (PostNord)
pakkeshopper:P13_gls_delivery_company      Erhvervslevering (GLS)
pakkeshopper:P9_other_other_other_Express  Egen fragtmetode med navnet "Express"
```

Pakkeshoppens id er **transportfirmaets eget id** for den valgte shop og sendes uændret videre. Det er som regel numerisk, men kan være alfanumerisk hos nogle transportfirmaer, så behandl det som en streng.

### 1.3 Den nye form med `_*` (pakkeshops i "listetilstand")

Når en butik slår **listetilstand** til for pakkeshops (en checkout, hvor kunden vælger sin pakkeshop live fra en liste over de nærmeste), oprettes raten, **før** en bestemt pakkeshop er valgt. Så ender koden på `_*`:

```
pakkeshopper:P7_gls_droppoint_*
```

`*` er en pladsholder, der betyder *"ingen bestemt pakkeshop endnu, kunden vælger en i checkout."*

> **Vigtigt:** Når koden ender på `_droppoint_*`, skal du **ikke** forsøge at læse pakkeshoppen ud af koden. Kundens faktiske valg ligger i stedet i **ordreattributterne** (se afsnit 2). Det er hovedgrunden til, at vi tilføjede laget med ordreattributter.

### 1.4 Andre kodeformater, du kan støde på

| Kode | Hvornår den optræder |
|------|----------------------|
| `pakkeshopper_{carrier}_{type}[_{id}]` | **Ældre format ("Pakkeshopper 1.0")**: samme struktur, men **uden** segmentet `:P{ID}`. |
| `{cc}_{carrier}_service_point_{id}` | **Shipmondo-format** (fx `dk_gls_service_point_Z9`), bruges kun hvis butikken har valgt Shipmondos dataformat. `{cc}` er en ISO-landekode med små bogstaver. |
| `pakkeshopper_other_other_fallback` | Reserverate, der vises, når der ikke blev fundet pakkeshops i nærheden af kunden. |
| `pakkeshopper_combine_shipments_{orderId}` | Valgmuligheden "Send åbne ordrer samlet": henviser til en anden ordre, ikke et transportfirma. |
| *(butikkens eget)* | Har butikken sat et **eget format** op for en rate, er koden deres egen skabelon og går uden om alt ovenstående. |

> Ratens id kan også optræde i **shipping line-titlen** som et `[P{ID}]`-suffiks (fx `GLS Pakkeshop [P7]`).

---

## 2. Ordreattributter *(anbefalet kilde)*

For hver Pakkeshopper-ordre skriver vi et sæt navngivne attributter til ordren. De er den reneste måde at læse fragtvalget på: de er allerede afkodet, læsbare og (for pakkeshops) beriget med shoppens navn og adresse.

**Her finder du dem**

| API | Felt |
|-----|------|
| REST Admin API | `order.note_attributes[]`, et array af `{ name, value }` |
| GraphQL Admin API | `order.customAttributes[]`, et array af `{ key, value }` |

> Nøglerne begynder med en understreg (`_`), og det betyder, at Shopify behandler dem som **skjulte** attributter: de vises ikke på kundens ordrestatusside, men er fuldt tilgængelige gennem Admin API.

### 2.1 Attributnøgler

| Nøgle | Beskrivelse | Eksempel |
|-------|-------------|----------|
| `_pakkeshopper_carrier` | Transportfirma (visningsnavn) | `GLS` |
| `_pakkeshopper_transport_type` | Leveringstype (visning) | `Pickup point` |
| `_pakkeshopper_pickup_point_id` | Pakkeshoppens id (transportfirmaets eget id) | `95218` |
| `_pakkeshopper_pickup_point_name` | Pakkeshoppens navn | `Kiosk Nine` |
| `_pakkeshopper_pickup_point_address1` | Gadeadresse | `Vej 9` |
| `_pakkeshopper_pickup_point_address2` | Adresselinje 2 (valgfri) | `Suite B` |
| `_pakkeshopper_pickup_point_zip` | Postnummer | `9000` |
| `_pakkeshopper_pickup_point_city` | By | `Aalborg` |
| `_pakkeshopper_pickup_point_country_code` | ISO-landekode | `DK` |

Værdier for `_pakkeshopper_transport_type`: `Pickup point`, `Delivery Home`, `Delivery Company`, `Other`.

Nøglerne `_pakkeshopper_pickup_point_*` findes kun på **pakkeshop-ordrer**. Ordrer med hjemme- og erhvervslevering har kun `_pakkeshopper_carrier` og `_pakkeshopper_transport_type`.

### 2.2 Eksempel (en pakkeshop-ordre)

```
_pakkeshopper_carrier:                   GLS
_pakkeshopper_transport_type:            Pickup point
_pakkeshopper_pickup_point_id:           95218
_pakkeshopper_pickup_point_name:         Kiosk Nine
_pakkeshopper_pickup_point_address1:     Vej 9
_pakkeshopper_pickup_point_zip:          9000
_pakkeshopper_pickup_point_city:         Aalborg
_pakkeshopper_pickup_point_country_code: DK
```

> I listetilstand (afsnit 1.3) fanges kundens valg først i checkout som en kurvattribut (`_pakkeshopper_pickup_point_id` + `_pakkeshopper_pickup_carrier`) og udvides derefter af Pakkeshopper til det fulde sæt `_pakkeshopper_*`-attributter ovenfor på den færdige ordre.

---

## 3. Anbefalet fremgangsmåde

1. **Foretræk ordreattributterne.** Læs `_pakkeshopper_carrier`, `_pakkeshopper_transport_type` og felterne `_pakkeshopper_pickup_point_*` direkte. Det kræver ingen parsing af strenge og virker ens, uanset om listetilstand er i brug.
2. **Brug feltet `code` som reserve eller krydstjek**, hvis du har brug for det interne rate-id, eller til ældre integrationer, der allerede parser det.
3. **Parser du koden,** så split på `_`:
   - første segment er `pakkeshopper` eller `pakkeshopper:P{ID}`,
   - næste segment er transportfirmaet,
   - resten er typen (og pakkeshoppens id ved `droppoint`).
   - Behandl et afsluttende `_*` som "pakkeshop ikke valgt endnu, læs den fra ordreattributterne i stedet."

---

## 4. Tilpasning

Dataformatet kan indstilles pr. butik:

- Butikken kan skifte mellem formatet **Pakkeshopper 2.0** (med `:P{ID}`), det **ældre** format og **Shipmondo**-formatet.
- En butik kan også sætte et **helt eget `code`-format** op pr. fragtrate, hvis deres egne systemer kræver et bestemt layout.

Har du brug for et bestemt format på din side, så sig til, så finder vi ud af det sammen.

---

Passer noget her ikke med det, du ser på en bestemt ordre, så send os ordrenummeret på [hej@pakkeshopper.dk](mailto:hej@pakkeshopper.dk), så bekræfter vi præcis, hvad der blev skrevet.
