Blog US Shopware Agency

UPS ship-to-account on Shopware 6: session, cart conversion, and order fields

· 8 min read · By Irish Titan

B2B merchants often need freight moved under the buyer’s commercial UPS agreement—what warehouse teams loosely call “ship to collect” or bill-to-receiver—instead of prepaid rates baked into the website. Shopware’s checkout still has to quote carriers, tax, and totals honestly: the storefront should not pretend UPS is free; it should show $0 to the merchant while capturing the account number and legal consent operations need to tender the shipment correctly.

What we built

We shipped UPS Bill To Account as a static Shopware 6 plugin (UpsBillToAccount): a checkout block where the customer can enable “ship on my UPS account”, enter the account number, and accept terms. When enabled, published shipping charges go to zero in the cart and order math (UPS invoices the account holder directly for transportation, fuel, corrections, etc.—the legal copy in the UI spells that out).

Checkout: UPS Account Billing section with Ship On My UPS Account checked, account number field, terms checkbox, and Save UPS Account button.
Collect-style billing on the buyer’s UPS account: explicit account number, terms acceptance, and save—before shipping is zeroed for the merchant’s totals.

How it works in the cart pipeline

State is carried in session (enabled flag, account number, terms) and mirrored to customer custom fields when logged in so repeat buyers do not re-key data every visit. A lightweight custom line item (ups-account-info) rides in the basket with payload metadata so other extensions can detect the mode without scraping Twig.

A dedicated CartProcessorInterface implementation zeros per-delivery shippingCosts when the session toggle is on, after normal rating has run—so you still get the correct selected method and delivery structure, but the customer-facing price is stripped. Event subscribers on cart loaded / changed / line items re-apply the override and persist the cart so refreshes and AJAX fragments stay consistent.

Why order conversion needed its own pass

Zeroing shipping in the live cart is only half the story. Shopware persists orders from the converted cart representation, so we subscribe to CartConvertedEvent (late priority) to normalize delivery shipping costs and cart price totals again—both object and array-shaped payloads—before the order row is written. That avoids “checkout looked right, order still shows freight” surprises in the admin and in ERP exports.

Downstream: ERP, WMS, and the edge

On CheckoutOrderPlacedEvent, we copy the UPS account number onto an order custom field (with session-first read and customer-field fallback) so pack/ship tools and integrations see the tender account without opening notes. Storefront routes under /ups-account/… power AJAX toggle/save flows; we allow-list those paths at the CDN the same way as other checkout-adjacent POST endpoints.

Plugin discipline next to other checkout fees

The same storefront may carry synthetic line items (warranties, fees) from sibling plugins. UPS subscribers explicitly skip known non-freight ids so a protection-fee line never triggers a shipping override path. That keeps behavior grep-friendly and composable as the merchant adds more Irish Titan extensions.

Our approach in one line

Treat third-party freight as session + cart contract + order custom fields, hook at both cart calculation and cart conversion, document the money flow in the UI, and wire explicit storefront APIs so ops and compliance can audit what the customer authorized.

Irish Titan is a Shopware Platinum partner—see our profile on Shopware. US checkout and carrier work ships Titan-only from our headquarters.

Talk with the team

Share your stack, timeline, and what “success” looks like for US Shopware Agency. We read every message and respond quickly—routing to Irish Titan employees at our headquarters (Titan-only; no contractor inbox).

Message received

Open for business: in office hours and responding. Open

You are writing to real people—not a bot or a ticket void. On weekdays during business hours (9:00 am–5:00 pm CDT), we aim to reply within about an hour. Outside those times we still respond by hand; it may take a little longer.

Tired of forms? Text us.

Email us (info@irishtitan.com)