X3DStudios

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.

It is a balance, not a coupon
A gift card carries a running balance rather than a one-shot discount. Spend $30 of a $100 card and $70 remains against the same code. There is no expiry date and no dormancy fee.

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.

FieldWhat you can choose
Amount$25, $50, $100 or $250 in one click, or any custom amount from $10 to $500.
DeliveryBy email, or a printed card posted to a US address.
DesignClassic, Birthday, Festive, Thank you, or Layer lines. The design shows on the email and on the printed card.
Recipient nameOptional for an emailed card. Required for a posted one — it goes in the address window.
MessageUp to 400 characters, shown with the code.
Send dateEmail 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.

  1. 1
    Fill 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.

  2. 2
    Pay on Stripe

    Checkout opens as a one-off payment. A posted card also collects a US delivery address there. Card details never reach X3D.

  3. 3
    The 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.

  4. 4
    It 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#

POST/api/gift-cards/purchaseSigned in

Start a gift card checkout. Returns a Stripe Checkout URL — no card is created yet.

Body
amountCentsintegerrequired
Face value in cents. Must be between 1000 and 50000 — outside that range the request is refused with 400.
deliverystringoptionaldefault email
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
From the browser, signed in at x3dstudios.com
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 Checkout

These 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.

text
X3D-4K7M-9QRT-2WXY

The 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.

Typing it does not have to be exact
Case and punctuation are stripped before the lookup, so x3d 4k7m-9qrt 2wxy finds the same card as X3D-4K7M-9QRT-2WXY. Spaces, dashes and lower case are all fine.

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.

POST/api/gift-cards/checkSigned in

Report whether a code is spendable, and how much is on it.

Body
codestringrequired
The code in any form. Formatting is normalised before the lookup.
{
  "valid": true,
  "code": "X3D-4K7M-9QRT-2WXY",
  "availableCents": 7000
}
A wrong code and an empty one answer identically
A code that does not exist, a card that has been voided and a card with nothing left all return the same 404 and the same sentence. Telling someone that a code exists but is empty confirms a guess, which is exactly the signal an enumeration attack is looking for. Checks are capped at 20 per account per hour for the same reason.

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.

  1. 1
    Fill 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.

  2. 2
    Enter 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.

  3. 3
    Check 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.

  4. 4
    The 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.

Buy Now skips the gift card field
The Buy Now button on a store product page goes straight to Stripe with that one item, and the Print & Ship button on /print does the same for a print. Neither has anywhere to enter a code. To pay with a gift card, use Add to Cart and check out from /cart. Gift cards also do not apply to subscriptions or credit packs on /pricing.

Balances and holds#

SituationWhat happens to the balance
You enter a code and reach StripeThe amount needed is held, not spent. The rest of the card stays spendable.
You payThe held amount is deducted. A card that reaches zero is marked depleted.
You abandon the checkoutThe hold is released when the Stripe session expires, and in any case within 24 hours.
You reload the checkout pageThe same hold is returned rather than a second one being taken.
The order is more than the cardThe card covers what it can and you pay the difference by card.
The card is voidedIt 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#

LimitValue
Minimum amount$10
Maximum amount$500
Printed card fee$3, charged as a separate line
Posted deliveryUnited States only
ExpiryNone
Message length400 characters
Purchases20 per account per hour
Balance checks20 per account per hour
Hold released after24 hours