Sending the customer back to the store
A store can send its customer to a page Pixonaut hosts and get them back to
its own: to make a design on the hosted designer, to correct one they already
made, or to decide a proof. The store’s server hands out the page’s link,
with its secret key or a connected store’s integration key, naming where the
customer returns to and a state of its own. The page sends the customer
back with that state, and with the proof they approved when there is one.
| Page | Handed out with | Sends the customer back |
|---|---|---|
| Hosted designer | POST /v1/templates/{id}/designer-links |
On approving, with state and proofToken; on cancelling, with state |
| Hosted correction page | POST /v1/designs/{id}/correction-links |
On approving, with state and proofToken; on cancelling, with state |
| Proof page | POST /v1/share-links |
Once the customer asks for changes, with state |
The return address
returnUrl is where the page sends the customer, and state is carried
back to it untouched: Pixonaut never reads it. Put in state whatever lets
the store match the customer to its own session, a cart key or a signed
nonce, and check it when the customer arrives. state is taken only with a
returnUrl.
returnUrl must be on one of the origins the workspace’s publishable keys
are allowed on, so a connected store returns to its own site, and in
production it must be https. Otherwise the link is refused
400 return_url_off_store or 400 return_url_not_https. It is fixed when the
link is handed out, so the page can be made to send the customer nowhere
else.
The page adds its parameters to the store’s own query and keeps the rest of
the address as it was: state, and proofToken when it brings back a proof.
A proofToken already in returnUrl is dropped, and so is a state when
the link carries none; the link’s own state replaces one already there.
The hosted designer
A store that does not run the designer on its own page hands out a hosted designer for one of its templates, with what it sells the template on: the blank and placement, its size menu and its photos, as the SDK takes them on a store’s page.
POST /v1/templates/tshirt-basic/designer-links
Authorization: Bearer ik_live_...
Content-Type: application/json
{
"blankId": "blank_tshirt",
"placementId": "front",
"printSizes": [
{ "widthMm": 280, "heightMm": 360, "label": "Large" },
{ "widthMm": 200, "heightMm": 257, "label": "Medium" }
],
"returnUrl": "https://shop.acme.example/cart?add=tshirt-basic",
"state": "cart-10482",
"locale": "sv"
}
{
"id": "shl_9a8b7c6d5e4f3a2b1c0d9e8f",
"token": "EXAMPLE_designer_link_token_not_a_real_one",
"url": "https://app.pixonaut.example/h/design/EXAMPLE_designer_link_token_not_a_real_one?lang=sv",
"expiresAt": 1790086400000,
"name": null,
"brandId": null,
"designLimit": null,
"printAreaFrame": false,
"placementFrame": false,
"locale": "sv"
}
Send the customer to url. The link follows the template’s live version.
A link carrying state names one shopper’s visit and works for 24 hours after it is handed out; one without state works until it is withdrawn.
When the customer approves their design, the page makes a proof and sends
them to
https://shop.acme.example/cart?add=tshirt-basic&state=cart-10482&proofToken=….
Nothing is stored yet: the store’s server checks state, keeps the
proofToken with the cart line, and commits it with its key as a proof from
its own page is committed
(A connected store, from connect to delivery).
If the customer cancels, they are sent to the same address with state
alone.
A front and a back are one link with sides, which returns a proof for each
side under its key, proofToken[front]=…&proofToken[back]=…
(Front and back on one item). Without a
returnUrl, the page commits the design itself and shows the customer its
id, and nothing is sent back to the store.
Correcting a design from the store
A customer who wants to change a design they already made, from the cart or after asking for changes, corrects that design rather than making a new one. The store’s server hands out a correction link for it:
POST /v1/designs/6f1c8a2b-3d4e-4f5a-8b6c-7d8e9f0a1b2c/correction-links
Authorization: Bearer ik_live_...
Content-Type: application/json
{
"returnUrl": "https://shop.acme.example/account/designs?edit=6f1c8a2b",
"state": "edit-7c1e"
}
{
"id": "shl_5d0c9e3b7a1f2e4d6c8b0a91",
"token": "EXAMPLE_correction_link_token_not_a_real_one",
"url": "https://app.pixonaut.example/h/correct/EXAMPLE_correction_link_token_not_a_real_one",
"expiresAt": 1790007200000,
"name": null,
"brandId": null
}
A correction link works for 2 hours after it is handed out, for that one design only.
A design that takes no correction, because it was rejected or one of its
prints has an order, is refused 409 not_editable; duplicate an ordered one
instead (Design to order).
The link opens the design in one of two places:
-
On the store’s own page. Hand out the link with no
returnUrl, and mount the designer with itstoken, from an origin the store’s publishable key allows:const designer = await Pixonaut.mount('#pixonaut', { correctionLink: token, design: designId, }); const { proofToken } = await designer.approve();urlis thennull: the link opens no page of its own. -
On the hosted correction page. With a
returnUrl, send the customer tourl. When they approve, the page sends them tohttps://shop.acme.example/account/designs?edit=6f1c8a2b&state=edit-7c1e&proofToken=…; when they cancel, to the same address withstatealone.
Either way, approving makes a proof of the correction and changes nothing.
The store’s server makes it the design’s next revision with
PATCH /v1/designs/{id}, sending the proof’s token with its key:
{ "proofToken": "EXAMPLE_correction_proof_token_not_a_real_one" }
{
"revision": 2,
"edited": true,
"proofId": "prf_9c1e2d3f4a5b6c7d8e9f0a1b",
"printFloorDpi": 150,
"lowResolution": []
}
With edited: true, the store receives design.edited with the new
revision. The design is back to committed, its approval cleared, so the
store approves it again once the customer has agreed, with an edit consent
and the new revision as expectedRevision:
{
"consent": { "kind": "edit", "at": 1790000200000, "ref": "edit-7c1e" },
"expectedRevision": 2
}
A customer who approves without changing anything leaves the design as it
was: the answer is edited: false with the current revision and proof, no
design.edited is sent, and an approval the design had stands. Branch on
edited rather than waiting for the event.
A design corrected elsewhere since the customer opened it refuses the
correction 409 revision_changed: open it again, and the customer starts
from the design as it is now.
The proof page
A deciding proof page, handed out as the store’s server hands out any proof
page (A connected store, from connect to delivery),
can send the customer back to the store once they have asked for changes, so
the store opens the design for them to correct. Name the return address, the
state, and the language the page is shown in:
{
"kind": "proof-page",
"subjectId": "6f1c8a2b-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
"mayDecide": true,
"returnUrl": "https://shop.acme.example/account/designs?edit=6f1c8a2b",
"state": "edit-7c1e",
"locale": "sv"
}
Once the customer’s request is taken, the page sends them to
https://shop.acme.example/account/designs?edit=6f1c8a2b&state=edit-7c1e,
with nothing else; design.changes_requested carries what they asked. The
store then hands out a correction link, as above. Approving and rejecting
keep the customer on the page. A link with a return keeps a proof page’s own
lifetime: a customer may sit on a proof for weeks. Without returnUrl, the
page keeps the customer and says their request was sent. locale is any
customer-facing language, by its code, and the link’s url then carries
?lang=<locale>; absent, the page is in the workspace’s default language.
Questions? Write to [email protected].