Gift cards
Buy an X3D Studios gift card, send it by email or as a printed card, check a balance, and redeem the code against an order in the cart.
A gift card is a balance somebody else can spend at x3dstudios.com — on a custom print, on anything in the store, or on postage. You buy it at /gift-cards for between $10 and $500, and it arrives by email or as a printed card in the post. The recipient enters the code in the cart, and whatever is left over stays on the card for next time.
Buying one#
You have to be signed in to buy — we need somewhere to send the receipt and someone to talk to about a refund. The recipient needs no account at all, which is the point of a gift.
| Field | What you can choose |
|---|---|
| Amount | $25, $50, $100 or $250 in one click, or any custom amount from $10 to $500. |
| Delivery | By email, or a printed card posted to a US address. |
| Design | Classic, Birthday, Festive, Thank you, or Layer lines. The design shows on the email and on the printed card. |
| Recipient name | Optional for an emailed card. Required for a posted one — it goes in the address window. |
| Message | Up to 400 characters, shown with the code. |
| Send date | Email only. Pick a future date and the card is held back until that date. |
A posted card costs $3 more than its face value. That is card stock, colour printing and US delivery, and it is charged as its own line on the checkout page so the card itself is worth exactly what you paid for it — a $50 card posted is $53 charged and $50 of balance. The fee is shown on the buy form before you reach Stripe.
- 1Fill in the form at /gift-cards
Amount, delivery method, design, recipient and message. Everything about the recipient except a posted card's delivery address is collected here rather than on Stripe's page, because Stripe only knows how to ask about the person paying.
- 2Pay on Stripe
Checkout opens as a one-off payment. A posted card also collects a US delivery address there. Card details never reach X3D.
- 3The card is created when the payment lands
Nothing exists until Stripe confirms the payment — an abandoned checkout mints no balance. The code is generated at that moment, so it does not appear on the checkout page.
- 4It is delivered, and you get a receipt
An emailed card goes out immediately unless you set a send date. A posted one goes to the print-and-mail vendor. Your receipt does not contain the code: for an emailed gift so a forwarded receipt cannot spend it, for a posted one so the card stays a surprise.
The purchase endpoint#
/api/gift-cards/purchaseSigned inStart a gift card checkout. Returns a Stripe Checkout URL — no card is created yet.
amountCentsintegerrequired- Face value in cents. Must be between 1000 and 50000 — outside that range the request is refused with 400.
deliverystringoptionaldefaultemail- Anything other than the literal string physical is treated as email.
emailphysical recipientEmailstringoptional- Where an emailed card goes. Required when delivery is email.
recipientNamestringoptional- Truncated to 120 characters. Required for a posted card and must be at least 2 characters — the mail vendor prints it verbatim in the address window.
messagestringoptional- Note from you, trimmed to 400 characters, shown with the code.
sendOnstringoptional- YYYY-MM-DD. Email delivery only, and it cannot be in the past. A date in any other shape is ignored and the card sends immediately.
stylestringoptional- Card design. An unrecognised id is dropped rather than rejected, and the card is issued in the Classic design.
classicbirthdayfestivethankslayers
const res = await fetch("https://x3dstudios.com/api/gift-cards/purchase", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
amountCents: 5000,
delivery: "email",
recipientEmail: "[email protected]",
recipientName: "Alex",
message: "Print something ridiculous.",
style: "birthday",
}),
});
const { url } = await res.json();
window.location.href = url; // Stripe CheckoutThese are session endpoints on the website, not part of the developer API — they read your sign-in cookie and there is no API key that reaches them. A signed-out request answers 401. Twenty purchase attempts per account per hour are allowed; past that the response is 429 with a Retry-After header.
The code#
Every card carries a code in the same shape: the prefix X3D and twelve random symbols in three groups of four.
X3D-4K7M-9QRT-2WXYThe alphabet is the digits plus the letters, minus I, L, O and U. Dropping those means nothing on a printed card can be misread as a 1 or a 0, and no four-letter group spells anything unfortunate. That leaves 60 bits of entropy, so a code cannot be guessed.
Checking a balance#
The cart checks the code for you when you press Apply, but the endpoint is there directly if you want it. You must be signed in.
/api/gift-cards/checkSigned inReport whether a code is spendable, and how much is on it.
codestringrequired- The code in any form. Formatting is normalised before the lookup.
{
"valid": true,
"code": "X3D-4K7M-9QRT-2WXY",
"availableCents": 7000
}availableCents is what is spendable right now, which is the remaining balance minus anything held by a checkout you have open in another tab. Abandon that checkout and the hold comes back within 24 hours.
Spending it#
Gift cards are redeemed in the cart, and nowhere else. Put whatever you want in the cart — store products, custom prints, or both — then enter the code before you check out.
- 1Fill the cart
Go to /store or /print and add items. A print has to finish being weighed before checkout will open; see /docs/studio/checkout.
- 2Enter the code and press Apply
The cart checks it against the server and shows the balance. An invalid code says so there rather than on Stripe's page.
- 3Check out
The card is applied to the total after any first-order discount, and it can settle postage as well as goods. Stripe allows one discount per session, so a gift card and the first-order discount arrive as a single amount and the split is recorded on the Stripe checkout session.
- 4The balance is taken when the payment lands
Until then it is only held. If the card covers the whole order the checkout completes at $0, and you still confirm a delivery address.
Balances and holds#
| Situation | What happens to the balance |
|---|---|
| You enter a code and reach Stripe | The amount needed is held, not spent. The rest of the card stays spendable. |
| You pay | The held amount is deducted. A card that reaches zero is marked depleted. |
| You abandon the checkout | The hold is released when the Stripe session expires, and in any case within 24 hours. |
| You reload the checkout page | The same hold is returned rather than a second one being taken. |
| The order is more than the card | The card covers what it can and you pay the difference by card. |
| The card is voided | It stops working immediately and reads as an invalid code. The recorded balance is kept for the books. |
One card, one order at a time: the cart takes a single code, so two cards cannot be stacked on one checkout. If you want to spend both, split the order.
Printed cards#
A printed card is posted within the United States only — the address form at checkout accepts US addresses and nothing else. It is printed and posted by a mail vendor rather than by hand, and the code is on the card itself.
Delivery is the part we do not control. If the vendor cancels a letter after accepting it — an address it cannot verify is the usual reason — the card goes back on the operator's list and is posted by hand instead. The balance is never affected by any of that: it exists from the moment the payment lands, whatever happens to the envelope. If a card has not arrived, ask at /contact and we will resend the code by email.
Limits at a glance#
| Limit | Value |
|---|---|
| Minimum amount | $10 |
| Maximum amount | $500 |
| Printed card fee | $3, charged as a separate line |
| Posted delivery | United States only |
| Expiry | None |
| Message length | 400 characters |
| Purchases | 20 per account per hour |
| Balance checks | 20 per account per hour |
| Hold released after | 24 hours |