Skip to content

Cart lifetimes and proof expiry

A customer approves a proof in the designer, and your storefront keeps it in the cart until checkout. A proof does not wait forever: this guide is about what to keep in the cart, when to commit the design, and what to do when a cart outlives its proof.

What a cart holds

approve() in the designer (or POST /v1/proofs) renders a proof and answers a proofToken and a proofUrl. Keep the proofToken with the cart line, and show the proofUrl to the customer as the picture of what they bought.

The token reaches you through the customer’s browser, so treat the browser’s copy as untrusted: a customer can swap in another live proof of yours, of a dearer template or product, and committing a token commits whatever proof it names. Keep the token with the cart line on your server once the line is priced, and commit that copy rather than one the browser sends at checkout.

A proof can be committed for 7 days after it is rendered. Its proofUrl lives as long.

Nothing is stored as a design yet. A proof that is never committed costs you nothing, and is cleaned up when it expires.

Commit at checkout

Commit the design at checkout, before you take payment, from your server with the secret key (a connected store, with its integration key), sending the proofToken and any order details your printshop needs:

{
  "proofToken": "eyJhdWQiOiJwcm9vZiIsImlkIjoicHJmXzljMWUyZDNmNGE1YjZjN2Q4ZTlmMGExYiIsInQiOiJhY21lIiwiZXhwIjoxNzkyNDkxMjQ3MDAwfQ.EXAMPLE_signature_not_a_real_one_0000000000",
  "fulfilmentPayload": { "variantSku": "TEE-BLACK-M" }
}

A committed design does not expire. It can still be corrected until it is ordered, each correction a new revision, and a revision never changes once made. Committing at checkout rather than when the line is added means a cart the customer abandons leaves no design behind.

Check the design before you charge

The proof is made in the customer’s browser, so a tampered page can make one at a print size, template version, blank or placement the product does not sell, and put it in a cheaper line. Once the design is committed, and before you take payment for the line, read it with GET /v1/designs/{id} (the secret or the integration key reads it) and check each of these against what the line was priced as:

  • printSize: the widthMm and heightMm the proof was made at.
  • templateBaseId and templateVersion: the template and its version.
  • blankId and placementId: the product and where on it the design prints.

When any of them differs, refuse the line and delete the design (DELETE /v1/designs/{id}) rather than approve it.

To refuse such a line as soon as it is added rather than at checkout, commit the design when the line is added instead, check it then, and keep the design’s id with the line in place of its proofToken. A cart the customer abandons then leaves its design behind: delete it when the cart is dropped.

Order details known only at checkout

A commit is refused with 422 missing_fulfilment_keys when its fulfilmentPayload lacks a key the printshop it goes to requires, and missing names the keys. A design committed when the line is added cannot carry what is known only once there is an order, such as Printful’s recipient: no one has said yet where it ships. A commit is not refused for those keys. Send the ones you know at commit, such as Printful’s placement; the order is refused with missing_fulfilment_keys when any required key is still missing when it is placed. A commit with no fulfilmentPayload is checked as one with an empty object.

The order itself can carry where it ships. Printful’s recipient is not needed in the payload for an order that sends its own recipient and shippingAddress, or ships to a saved address: Printful ships to the order’s.

When the cart outlives the proof

Committing a proof past its expiry is refused, and nothing is committed:

  • 410 proof_expired — the token’s time ran out, whether or not the proof has been cleaned up since.
  • 404 unknown_proof — the token is not a live proof of yours: it is not one Pixonaut signed for your account, or its proof is gone.

Either way the customer approves again: open the designer on the same template with what they entered, and replace the cart line’s proofToken with the new one. To avoid asking at checkout, keep cart lines no longer than a proof lives, or check a line’s age when the customer returns to the cart and ask them to approve it again then.

Questions? Write to [email protected].

Status · Terms of service · Privacy policy · Subprocessors