TL;DR
- Context: Technical PM at a B2B packaging e-commerce scaleup, after Brexit hit.
- Problem: Direct Poland-to-UK shipping put customs duty on the customer; the workaround through a UK entity took ~20 days.
- What I did: Bridged the internal order system with the invoicing system and the logistics system (the courier) to auto-generate a three-party invoice and clear the shipment directly to the customer.
- Result: Delivery ~20 days → ~7–10 days (~50% faster), no duty on customers.
Diagnosis
The bottleneck wasn’t a truck — it was a document. After Brexit, shipping direct from Poland to a UK customer meant the customer got saddled with customs duty on top. The first workaround was shipping a container to the UK entity, then reshipping individual parcels to customers from there — but that took ~20 days. The fix was neither logistical nor political; it was a three-party invoice that named the right parties in the right fields, so the parcel could clear customs on a direct run. Once that document could be generated automatically — the internal order system firing API requests to the invoicing system (a modern API with templates) and to the logistics/courier system (legacy XML) — direct shipping opened up — ~20 days down to ~7–10, no duty on the customer.
flowchart TD
A1["Poland"] -->|"direct, blocked by customs"| B1["UK customer pays duty"]
A2["Poland"] -->|"container to UK entity, ~20 days"| B2["UK entity"] -->|"reship"| C2["UK customer"]
A3["Poland"] -->|"three-party invoice, ~7-10 days"| C3["UK customer, no duty"]
classDef good fill:#e6f2ea,stroke:none,color:#1f4d33,rx:14,ry:14
classDef bad fill:#faeaea,stroke:none,color:#5f2626,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class A1,B1 bad
class A2,B2,C2 bad
class A3 good
class C3 accent
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
What I did
- Owned the integration as a technical PM — specified the three-party invoice logic (shipper = the Poland entity, buyer = the UK entity, recipient = the UK customer) and bridged three systems.
- Bridged the internal order system with the invoicing system (a modern API with templates) and the logistics/courier system (a legacy XML API) — the internal system fired API requests to both, so three-party invoices auto-generated on shipment.
- Ran the integration conversations on both sides — two vendors, two very different APIs, hard negotiations.
- Enabled direct Poland→UK shipping that cleared customs without duty on the customer.
Results
- Delivery time ~20 days → ~7–10 days (~50% faster, ~10 days less).
- No customs duty on UK customers — the three-party invoice structure carried it.
- Direct shipping restored — the container-to-UK-entity-then-reship detour retired for these shipments.
The problem
What did Brexit do to UK shipping?
After Brexit, shipping a parcel direct from Poland to a UK customer meant customs duty got charged to that customer. The workaround the business had was to ship a container to the UK entity and reship from there — which took ~20 days. Slow, and a poor experience for a customer waiting on packaging.
Why not just ship direct anyway?
Because the customs structure penalized it. The duty wasn’t a logistics problem you could throw a courier at; it was a regulatory one. The unlock had to live in how the shipment was documented — specifically, in who the invoice said was shipping to whom.
My role / scope
- Technical PM — this was PM work, not design, and a different part of my range.
- Owned the integration end-to-end: the invoice logic, the system-to-system bridge, and the vendor conversations.
- Worked with the invoicing vendor, the courier, the team owning the internal order system, and the internal Poland and UK entities.
Process
- Identified that the duty was a document problem, not a logistics one — the invoice structure was the lever.
- Designed the three-party invoice logic: shipper = the Poland entity, buyer = the UK entity, recipient = the UK customer. That combination is what let the parcel clear customs on a direct run.
- Bridged the internal order system with the invoicing system (a modern API with templates) and the logistics/courier system (legacy XML), routing the internal system’s API requests to both, to auto-generate those invoices on shipment.
- Ran the integration on both sides — three systems, two external vendors, persistent conversations until it worked.
Key decisions & trade-offs
- Fix the document, not the logistics. The duty was real, but it was charged based on how the shipment was documented. A three-party invoice (shipper / buyer / recipient) satisfied customs and let the parcel go direct without loading the customer. The original workaround — bulk container shipping — was slower and never touched the root of the problem.
- Three named parties, in the right fields. Shipper = the Poland entity, buyer = the UK entity, recipient = the UK customer. Getting those roles into the right invoice fields was the whole game; customs reads the document, not the intent.
flowchart LR
F["Three-party invoice"] --> N["Shipper = Poland entity"]
F --> K["Buyer = UK entity"]
F --> O["Recipient = UK customer"]
classDef info fill:#e9eff8,stroke:none,color:#1e3a5f,rx:14,ry:14
class F,N,K,O info
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
- Bridge three systems, not two. The internal order system had to fire API requests to both the invoicing system (a modern API with templates) and the logistics/courier system (legacy XML) — neither was built for the other, and the internal system spoke natively to neither. The work was specifying the bridge across all three and persisting through hard integration conversations on both external sides until the document flowed automatically.
flowchart LR
W["Internal order system"] -->|"API request"| A["Invoicing system<br/>modern API + templates"]
W -->|"API request"| B["Logistics/courier system<br/>legacy XML"]
A --> P["Integration bridge"]
B --> P
P --> C["Three-party invoice auto-generated"]
classDef info fill:#e9eff8,stroke:none,color:#1e3a5f,rx:14,ry:14
classDef accent fill:#27272a,stroke:#3f3f46,stroke-width:1px,color:#fafafa,rx:14,ry:14
class W,A,B,P info
class C accent
linkStyle default stroke:#a8a8b3,stroke-width:1.5px
- Direct shipping over the container hub. Chose the faster path (~7–10 days vs ~20) and paid for it with integration complexity — the right trade for a customer waiting on an order.
| Route | Time | Duty on customer | Complexity |
|---|---|---|---|
| Container hub | ~20 days | none | low (standard logistics) |
| Direct (three-party invoice) | ~7–10 days | none | integrating two different APIs |
How it turned out
UK delivery dropped from ~20 days to ~7–10 (~50% faster), with no customs duty on the customer — the three-party invoice carried the parcel through customs on a direct run. The hardest part was the integration itself: the internal order system had to talk to a modern API on one side and legacy XML on the other, at the same time, with two vendors who weren’t built for each other or for it.
What I took away
- The bottleneck is sometimes a document, not a truck. Fix what the document says, and the logistics can unlock underneath it.
- Regulatory constraints are design problems. Brexit customs dictated the invoice structure; working back from the regulation told us what to build.
- Bridging mismatched APIs is real product work. A modern API and a legacy XML format don’t meet in the middle by themselves, and the internal order system spoke natively to neither — specifying that bridge, and persisting through the conversations, is where this shipped.