A day in the life of an Optimizely OMVP: Commerce Connect 15 isn't an upgrade. It's a reset.
The version number is doing a lot of work to look harmless. Fourteen to fifteen. A nudge, surely. Bump the packages, run the build, ship it Friday.
It is not that. If you've shipped a few of these you can feel it coming, the kind of release where the changelog is mostly the word "removed" and the real project plan lives in everything that doesn't compile afterwards.
Here's the practitioner read on what actually changed, and where the work hides.
The headline nobody puts in the headline
Commerce Connect 15 doesn't travel alone. You can't take Commerce to 15 without taking CMS to 13 at the same time. They're welded together. So the moment you commit to 15, you've also signed up for .NET 10, mandatory Optimizely Graph, mandatory Opti ID, and Visual Builder replacing on-page editing.
That's the bit to land with stakeholders early. "We're upgrading Commerce" undersells it. You're moving the whole platform foundation in one go. Scope it as a programme, not a package update, and the rest of the conversation gets a lot easier.
Find is gone. Plan for it.
Search & Navigation → Find does not exist in this world. There's no .NET 8 escape hatch and no quiet "Find still works for now." It's replaced by a commerce-specific Graph search provider (Optimizely.Graph.Commerce) that powers the catalog panel, global search, and the order-management line-item lookup.
Think of it like swapping the engine while the car's still on the drive. The pedals are in the same place — the CMS 13 Graph SDK gives you a fluent Where() / SearchFor() / Limit() API that reads a lot like Find did, so the muscle memory transfers. But underneath, your indexing, your queries, and anything clever you built on EPiServer.Find.Commerce all need rethinking. If your catalog search is load-bearing, and on commerce it always is. This is your single biggest architectural item. Treat it as such.
Where the real hours go
Three places. Every time.
The workflow engine is gone. Mediachase.Commerce.Workflow and the old ActivityFlow engine have been pulled. Anything calling RunWorkflow(), OrderGroupWorkflowManager, or OrderStatusManager moves to the processor APIs — IPaymentProcessor, IPurchaseOrderProcessor, IShipmentProcessor. This is the work that passes the compiler and then bites you at runtime, because order state transitions are exactly the thing your test coverage tends to be thin on. Budget for it and test the full cart → promotion → checkout → payment → fulfilment path like your bonus depends on it.
Credit-card storage is gone. ICreditCardPayment, the CreditCard class, the lot, removed on PCI grounds. If you were storing card data (and you shouldn't have been), you're now tokenising through Stripe / Adyen / PayPal and hanging tokens off IPayment. Mostly a good-news story; occasionally a nasty surprise in an older codebase.
Serialization moved. Newtonsoft.Json out, System.Text.Json in, matching CMS 13. If you wrote custom converters into the Commerce pipeline, they need rewriting, ReadJson/WriteJson become Read/Write over Utf8JsonReader/Utf8JsonWriter. And Newtonsoft is no longer riding along as a transitive dependency, so if your own code leaned on it, reference it explicitly before it disappears out from under you.
There's also 50-odd deprecated methods finally being shown the door, plus the usual constructor-signature changes. None of it individually is hard. Collectively, on a mature build, it adds up.
The genuinely new bits
It's not all subtraction. IOrderRepository finally gets a proper async surface, LoadAsync, SaveAsync, SaveAsPurchaseOrderAsync, the lot, all with CancellationToken. Sync stays for compatibility, but new code should go async from day one.
And the direction of travel is obvious once you stand back. Catalog entries are now CMS content types, which means they inherit Visual Builder, Content Manager's search-first editing, and, the actual point of all this, Opal. There's already a Product Promotion agent that builds and configures promotions, assigns products and variants, and applies promotion types for you. Catalog data as content, delivered through Graph, operated by agents. That's the whole thesis. Fifteen is the version where it stops being a slide and starts being the product.
So what do you actually do
Same play we run every time, in order:
- Assess on 14. Inventory your .csproj files, every EPiServer.* reference, every add-on, and every deprecated API you're still calling. Fail the build on those warnings now.
- Clear the obsoletes while you're still on 14. Most of them are removed in 15, so fixing them early turns a wall of compiler errors into a handful.
- Do the coupled jump in a branch. .NET 10, CMS 13, Commerce 15, and pin to the latest 15.x patch, not 15.0.0. Wire up Graph and Opti ID. Rewrite the converters. Move order processing to the processor APIs.
- Test the order pipeline hardest. It's the thing that compiles clean and breaks live.
One more, and it's the one that quietly sinks timelines: the add-on long tail. At and just after GA, the connectors were still rolling out, ODP, Service API, PIM. Check the NuGet server for your specific add-ons before you commit a date to anyone. A green build on the core packages means nothing if the connector your client lives on hasn't shipped yet.
None of this is a reason to flinch. It's a reason to plan properly. The technical upgrade is increasingly a solved exercise, we're encoding chunks of it into agent skills already. The craft is in the content-model work, the order pipeline, and refusing to let "it's just a version bump" anywhere near the estimate.
Fifteen is a good release. Just give it the respect a reset deserves.

Comments