On the storefronts ElevateActual builds, an order placed at checkout fires a record-triggered Flow on OrderSummary or a Platform Event. The Flow matches or creates the learner's Person Account, creates the CourseOfferingParticipant, writes the receipt, and hands the enrollment to the SIS integration. No Apex is involved, except where the platform requires it.
What Happens When an Order Is Placed?
On a Commerce on Core storefront, ElevateActual's term for B2B and D2C Commerce built on the Salesforce Platform with an LWR Experience Cloud storefront, checkout creates an Order, and Salesforce Order Management turns it into an OrderSummary with one OrderItemSummary per line. That OrderSummary exists whether the buyer was logged in or a guest, and whether payment ran through Salesforce Payments or a campus processor. It is therefore the right place to hang the automation. From there the work is four steps, in a fixed order.
- Match or create the learner. The Flow reads the buyer's email and name from the order and looks for an existing Person Account. If the storefront captured a student ID, that is matched first. If nothing matches, the Flow creates the Person Account.
- Create the enrollment. For each
OrderItemSummary, the Flow follows the product to itsCourseOfferingand creates aCourseOfferingParticipantwith a status ofEnrolled, orWaitlistedif the section is full and the waitlist is open. - Write the receipt. The Flow records what was sent and when, then sends the receipt as an email alert from an organization-wide address, with the order lines and section details in it.
- Hand off to the SIS. The Flow publishes a Platform Event, or writes a staging record, that the integration layer picks up to create the learner and the registration in Banner, Colleague, or Jenzabar. The storefront never writes to the SIS directly.
That sequence is the whole post-purchase story for most continuing education units, built on the standard objects described in our overview of Salesforce Commerce for higher education.
Why Flow and Not Apex?
The symptom we are solving is the one every campus Salesforce admin knows: a trigger written by a contractor three years ago that nobody dares touch. The root cause is that Apex is opaque to the people who inherit it. Flow is not, for four concrete reasons.
- Admins can see it. A record-triggered Flow is a diagram. The admin who owns the storefront after go-live can open it, read the decision elements, and say what happens to a guest order from a personal email address.
- It is versioned. Every Flow save is a version. You activate one, keep the previous ones, and roll back by activating an older version. There is no deploy and no release window to undo a mistake.
- It is testable in debug. Flow's debug mode runs the automation against a real record, shows every element's inputs and outputs, and can roll the transaction back.
- There is no coverage gate. Apex deploys to production only when the org's tests pass Salesforce's code coverage threshold. A Flow deploys without one. It means a one-line fix to the receipt wording does not require a test class run and a developer.
Flow has limits, and we design around them. Callouts from a record-triggered Flow run on an asynchronous path after the transaction commits, so a synchronous SIS write is the wrong design anyway. Within those limits, Flow and Platform Events cover everything between the order and the SIS.
Where Is Apex Still Required?
Three places, and all three are extension points where the platform asks for a class.
- The tax calculator extension. Salesforce Commerce computes tax through an extension interface. If a storefront needs real per-line tax, because some courses are taxable and some are not, the calculator is an Apex class. How it interacts with refunds and receipts is covered in tax, refunds, and receipts on a university storefront.
- The payment gateway adapter. Salesforce Payments with Stripe needs no custom adapter. A campus processor such as Transact CashNet or TouchNet does: a signed handoff to the hosted checkout page, and a post-authorization adapter that writes the result back to the order. That adapter is Apex.
- A custom login controller for single sign-on. When learners sign in with the campus identity provider, the registration handler that creates or matches the storefront user on first login is Apex. Its matching logic must agree with the Flow's, or the same learner ends up with two records.
Everything else is declarative, which is the boundary set out in our standard-objects-first stance: the front end may be custom, the extension points may be Apex, and record automation stays in Flow.
Which Tool Does Each Step Use?
| Automation step | Tool | Reason |
|---|---|---|
| Detect that an order has been placed | Record-triggered Flow on OrderSummary (after save) | The order summary exists for every order type and payment path. |
| Match or create the Person Account | Flow (Get Records, Decision, Create Records) | The matching rule is a business decision the unit will want to read and adjust. |
Create the CourseOfferingParticipant per line | Flow loop over OrderItemSummary | Standard objects and standard DML; seat and waitlist fields on CourseOffering update from the participant record. |
| Send the receipt | Flow email alert, with a sent flag written on the order | Visible, editable template; the flag makes resends deliberate and keeps the daily email cap in view. |
| Hand the enrollment to the SIS | Platform Event published from the Flow | Decouples the storefront from SIS availability; events retry and replay. |
| Compute tax per line | Apex (Commerce tax extension) | The platform's extension point requires a class; there is no declarative hook. |
| Take payment through a campus processor | Apex (hosted checkout handoff and post-authorization adapter) | Signed redirect and callback handling are code by nature. |
What Are the Traps?
Three traps account for nearly every post-purchase defect we have seen on university storefronts.
Order of Operations at Go-Live
Symptom. On launch day the payment processor reports a successful charge, the order shows paid, and the roster is empty. The SIS integration logs an error because the learner it was asked to register does not exist.
Root cause. Something posted before the learner existed. Usually the payment adapter wrote its result to the order and a separate automation fired on that update, ahead of the Flow that creates the Person Account and the participant.
Fix. One trigger point, the OrderSummary, and one Flow that does the four steps in order: learner, enrollment, receipt, handoff. Nothing downstream listens to the payment result directly. Then run a production hot test with a real card and a real course, and read the records in creation order.
Duplicate Person Accounts
Symptom. A learner who took a course last spring from her university address buys another this fall from her personal address. She now has two Person Accounts and two histories.
Root cause. The match was on email alone. Institutional and personal addresses are the most common split, followed by a name change between records.
Fix. Match on a student ID when the storefront captures one, then on email plus name, and search every email field on the Person Account, not just the primary. Add a duplicate rule on Person Accounts so the ones the Flow cannot resolve are flagged for a person rather than silently created. Decide in design who merges duplicates and which record survives.
The Daily Email Limit
Symptom. Receipts stop arriving mid-afternoon on the busiest registration day of the year. The inbox is quiet, and the phone is not.
Root cause. Salesforce caps the number of single emails an org can send through the API in a day, Flow email alerts count against the cap, and the cap resets on a fixed daily clock rather than a rolling one. A confirmation, a receipt, and an instructor notice per order spends the allowance three times as fast as anyone planned.
Fix. Send one receipt per order, not one per line. Record a sent flag on the order so retries are deliberate. Keep instructor and administrator notices in digests or in Salesforce itself. For a unit whose peak day exceeds the allowance, route receipts through the marketing platform or the payment processor's own confirmation.
How Does the Handoff to the SIS Work?
The Flow's last step publishes a Platform Event carrying the order ID, the learner's Person Account ID, and the participant IDs. A subscriber, either a Flow or an integration platform, does the SIS-specific work: creating the person if the SIS does not know her, then registering her in the section. The storefront never writes to a SIS table and never waits for the SIS to answer. The patterns for each system are in SIS integration patterns for Banner, Colleague, and Jenzabar, and our Commerce Accelerator ships this Flow, the event, and the subscriber scaffold as part of its fixed scope.
Questions We Hear
Can our own admins change the enrollment Flow after go-live?
Yes, and that is the point. The Flow is in the org, versioned, with each element labeled in plain language. We hand it over with a walkthrough, a debug run against a sample order, and a short list of the elements an admin will most often want to change: the matching rule, the receipt template, and the status a full section produces.
What happens when the Flow fails on an order?
The order and the payment are unaffected, because the Flow runs after the order summary is saved. The failure is reported to the address configured for Flow errors, with the element that failed and the record it was on. The cause is almost always data, such as a product missing its course offering link, and once it is corrected the Flow can be re-run for that order.
Why not use a Platform Event for the whole thing instead of a record-triggered Flow?
Either works, and we have built both. The record-triggered Flow is simpler to read and debug, and it has the order in hand with no extra lookup. The Platform Event earns its place at the edge, where the storefront hands off to the SIS, because that boundary benefits from retry and replay.
Does the pattern handle group registration, where one buyer pays for several learners?
It extends to it. The storefront captures each attendee's name and email per line, and the Flow's loop creates or matches a Person Account per attendee rather than per order, then creates each participant against the right person. The buyer's receipt lists everyone. The unit has to decide whether attendees get their own confirmation, which also matters for the email allowance.
Do refunds and drops run through the same Flow?
Through a sibling of it. A refund produces a change order against the order summary, and a drop changes the participant status. A second record-triggered Flow listens for those, updates the participant to Dropped or Withdrew, releases the seat so the waitlist can advance, and publishes an event so the SIS drops the registration.

