A Core dna store is a set of records and an API that moves a purchase from cart to order: products described in every language and priced in every currency the store sells in, a cart, a checkout that becomes an order, invoices, payments, tax and shipping. The site builds the storefront on top: the cart and checkout pages, their scripts, and the customer emails.
L2–L3
Unit 01 · Products, prices and catalogue pages
Wishlists and back-in-stock requests
Products, prices and catalogue pagesPage 4 of 31Updated
A wishlist is a signed-in member's saved products; a product interest is a request to hear when something is back in stock, open to guests if the site allows it. What each records, the requests and screens behind them, and the job that turns stock coming back into an email.
Who this is for. The theme developer adding "save for later" and "notify me" to product pages, and the implementer who builds the email behind them. Afterwards you know which of the two features fits, what the shopper must be, and which parts you build in the template and in a job.
Wishlists
A wishlist entry links a member's person record to a product (not a variant), with a copy of the product's name and SKU taken when it was added. A product is on a member's list at most once. The wishlist exists only for a signed-in visitor: there is no guest wishlist.
To
Request
Notes
Add a product
POST /cdna-api/products/wishlist with {"product": <product id>}
Signed in only; the entry is always the signed-in member's
Remove from a product page
DELETE /cdna-api/products/wishlist/<product id>
By product id
List
GET /my-account/wishlist, then /my-account/wishlist/2 and so on
Renders products/wishlist/index.html with wishlist and _pagination; you supply the template
Remove from the list
DELETE /my-account/wishlist/<entry id>, as a form post with _method and _csrf
By the entry's id; redirects to the list with "Product is removed from wishlist"
Send the CSRF token (X-Csrf-Token, or _csrf in a form) with every one of these writes, as with any request made on a signed-in member's behalf.
On a product page, $product->isInWishlist() says whether the signed-in member has saved the product, and is false for anyone signed out. It is personal, so it must not be printed into a page the page cache stores: render the heart icon's state in the browser instead, from the member's list, as The cart count on a cached page does for the cart.
The signed-out shopper
Decide what a guest's "save" button does before the design is signed off, since the wishlist belongs to signed-in members. Two patterns work: send the guest to sign in and come back, or keep their choices in the browser's storage and post them to the wishlist once they have signed in. The second keeps the button useful; clear the browser copy after posting it.
Back-in-stock requests
A product interest records that a person wants to hear about a product or a variant, with the date it was made and a completed date that is empty until someone has been told. It is the platform's "notify me when available" feature. The visitor registers it with one request:
JavaScript
// From the product page's script. A signed-in member is always registered as themselves;
// a guest sends an email address, and the captcha token when the site asks for one.
const body = { product: productId };
if (!signedIn) {
body.email = emailInput.value;
body['g-recaptcha-response'] = grecaptcha.getResponse();
}
const response = await fetch('/cdna-api/products/product-interest', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-Csrf-Token': csrfToken },
body: JSON.stringify(body)
});
const result = await response.json();
// result.result is "success", or "error" with result.message to show next to the form
Who may register is decided by the platform, not the page:
A signed-in visitor is always registered as their own person; any email address sent is ignored.
A guest may register only when Allow guests to register interest in products (Products.interest.allowGuests) is on, which it is not by default. Otherwise the answer is "Please log in to register your interest in this product".
A guest must send an email address ("An email address is required to register your interest" when missing). An address that belongs to an account is refused with "This email address belongs to an account, please log in to register your interest", so the visitor signs in instead. An address of a person with no account reuses that person; an unknown one creates a person with only the email address, added to the groups chosen in Groups for people registering interest.
For guests, a reCAPTCHA v2 check runs, checkbox by default (reCAPTCHA for guests registering interest, Products.interest.recaptcha). The product page receives the widget's settings as _recaptcha for guests; post the token as g-recaptcha-response. A missing or failed token is refused with "The reCAPTCHA verification failed, please try again". A signed-in visitor is never challenged.
Staff can list a product's requests with GET /cdna-api/products/product-interests/<product id>; members cannot, because the list holds other people's addresses. There are no member-area screens for interests.
When stock comes back
The email to the people who asked is sent by a job you build. When a stock change raises a product's or variant's available stock, summed across the account's warehouses, from at or below Stock threshold for back in stock notifications (Products.interest.stockThreshold, 0) to above it, the product fires a BackInStock event. It fires on the crossing only, so stock that rises from 5 to 7 is silent. Stock changes are inventory transactions (Stock and fulfilment), so the event depends on whatever writes them: the admin, an integration with the stock system, or the API.
The event carries the product, not the people. Build a job on it that retrieves the product's interests with no completed date, sends each person an email, and sets completed on each, so nobody is told twice. Product interests are among the records a job's retrieve and update actions can reach; Jobs and events covers building one.
Which one to offer
Offer the wishlist when shoppers want to come back to things they like, and it is worth asking them to sign in. Offer a back-in-stock request on sold-out products, where an email address is all you need and a guest should not be turned away. They can sit side by side on the same page.