Gift Card

Customers buy a USD gift card at a store we link, then paste the activation code on checkout. We redeem the code and credit your invoice amount. By default the card face has to cover the invoice. An $8 product cannot use a $5 card or a $10 card.

Gift Card is on by default on hosted checkout. Turn it off in Settings if you do not want the tile. Hosted checkout only — direct is not supported.

To make Gift Card the method customers land on, pass "preferred_method": "gift_card" on POST /v1/payments: it is pre-selected and listed first, with your other methods still one tap away.

For a gift-card-only checkout — a "Pay with gift card" button where the customer must not switch to another method — pass "allowed_methods": ["gift_card"] instead. Every other method is hidden. Either way, record the method from the payment_method field of payment.completed, not from the button the customer clicked.

How checkout works

  1. Create a payment as usual. Optionally pass gift_card_amount to pin the face. That does not hide other methods — use allowed_methods for that.
  2. The customer opens Gift Card on hosted checkout, buys a USD card at the store we link, and pastes the 16-character activation code from the delivery email.
  3. The session stays pending until the codes the customer enters cover the invoice. A code worth less is credited and the customer is asked for another code for the rest; the session then stays open for 24 hours and completes at the received amount if they do not. You get payment.completed with payment_method: "gift_card". You are credited what was paid.
  4. Once the customer opens Gift Card, that session stays valid for 4 hours so they can finish buying the card and paste the code.

Denominations

USD only. Each face has a window from 90% of the face up to the face. Price inside a window, or gift card will not appear.

FaceInvoice windowgift_card_amount
$5$4.50 – $5.005
$10$9.00 – $10.0010
$15$13.50 – $15.0015
$20$18.00 – $20.0020
$25$22.50 – $25.0025
$30$27.00 – $30.0030
$40$36.00 – $40.0040
$50$45.00 – $50.0050
$75$67.50 – $75.0075
$100$90.00 – $100.00100
$250$225.00 – $250.00250
$500$450.00 – $500.00500

If the usual listing on the default store is sold out, checkout opens another in-stock listing on that store for the same face. It only switches stores when every listing there is gone and the other store has that face. If neither store has stock, the gift-card tile stays hidden.

A $14 invoice uses the $15 card. $12 and $8 sit in none of these windows, so the gift-card tile stays off. Pass gift_card_amount: 10 on that $8 invoice and the API returns GIFT_CARD_AMOUNT_MISMATCH. A pinned face always has to cover the invoice.

To take orders that fall between faces, turn on Accept the next smaller gift card under Settings → Payment Methods → Gift Card. Checkout then offers the next smaller face when it is at most $5 short: a $12 order is offered the $10 card, a $16 order the $15 card. Redeeming that card completes the order at the card's value. You get payment.completed with amount set to what was received and amount_requested set to the order amount. A $60 order is not offered the $50 card, because the gap is over $5, and a card below the offered face stays a part-payment. Only turn this on if your handler fulfils based on amount. Leave gift_card_amount unset so checkout can pick the face.

Create a payment

Same endpoint as every other hosted checkout rail. gift_card_amount picks which face to display. Leave it off and we pick a face when the invoice already fits a window, or the next smaller face within $5 if you turned on Accept the next smaller gift card.

ParameterTypeDescription
gift_card_amountnumberOne of 5, 10, 15, 20, 25, 30, 40, 50, 75, 100, 250, 500. currency must be "USD". Invoice amount must fall in that face's window.

Example

cURL
curl -X POST https://vexutopia.com/api/v1/payments \
  -H "X-API-Key: vex_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "10.00",
    "currency": "USD",
    "gift_card_amount": 10,
    "return_url": "https://yoursite.com/order/success",
    "webhook_url": "https://yoursite.com/api/webhooks/vexutopia"
  }'

Part-paid orders

A redeemed code is used up, so its value always counts toward the order even when it is worth less than the order. Offering gift cards means you deliver what was paid, including when that is less than the order. If the customer never adds another code, the order completes at the received amount when the 24-hour window ends.

  • Each time a code is credited while the order is still short you get payment.partial with status: "partially_paid", the order amount and amount_received in your currency. GET /api/v1/payments/{id} shows gift_card.last_result: "partially_paid" with gift_card.amount_received and gift_card.amount_remaining in USD.
  • The order stays open 24 hours after the last code so the customer can pay the rest. You can click Accept (owners and admins) before then. When the window ends, the order completes at the received amount on its own: your balance is credited that amount minus fees, and payment.completed fires with amount set to the received amount and amount_requested set to the order amount. Deliver what the received amount is worth.
  • Orders where less than $2 was received are not completed, because the fee would take all of it. Those expire with payment.expired and amount_received, and stay on your Payments page.
  • Fulfil only on payment.completed, for amount. payment.partial and payment.expired are information only: nothing has been credited to you yet, and the customer can still add a code within the 24 hours. Granting on the first notice and again on the later completion would give the customer the product twice.
  • The fee applies to the settled amount: on a $10 code accepted toward a $20 order you are credited $10 minus the gift card fee. Deliver for the $10 the customer paid. A code cannot be un-redeemed.

What to deliver

Deliver only from payment.completed, and deliver for amount. That field is what the customer paid and what your balance was credited for, before fees. amount_requested is present only when the payment was short, and it holds the original order amount. Log payment.partial and payment.expired if you want, and do not deliver on them.

On a checkout where the customer switched to a gift card from another method, settled_via.rail is GIFT_CARD and settled_via.amount is the redeemed card value in USD. Use that as the paid amount when your top-level amount includes tax on top of the product price. Otherwise use amount.

If each order is one product, deliver that product when amount covers it. When the payment is short, deliver a smaller product you sell at that price, or arrange the difference with the customer. Do not deliver the original product for a short payment unless that discount is one you are willing to give.

If you sell credits in packs, price the paid amount at the per-credit rate of the largest pack whose price fits inside it, and round down. Below your cheapest pack, use that pack's rate. Suppose your packs are 30 credits for $5, 70 credits for $8, and 150 credits for $15. A customer who pays $10 toward a $15 order does not get the 150-credit pack. The largest pack priced at or under $10 is 70 credits for $8, so you grant floor(10 × 70 / 8) = 87 credits.

text
on payment.completed:
  paid = amount
  if settled_via.rail is GIFT_CARD and settled_via.currency is USD:
    paid = settled_via.amount
  if amount_requested is set and paid is less than amount_requested:
    grant credits for paid, using the pack rate above
  else:
    grant the product the order was created for

on payment.partial or payment.expired:
  do not grant

The full flow and field reference is under Payments → Partial payments.

Fees and settlement

  • Fee is 14% + $1 per invoice. You are credited the invoice, not the card face, except when the order settles short: then you are credited the received amount.
  • Settles after the code redeems. Payouts are T+1 — one request per day. Completes when the redeemed codes cover the invoice, when a next-smaller card you opted into is redeemed (then at that card's value), or when a part-paid order's 24-hour window ends or you click Accept (then at the received amount).
  • $50 fee if an issuer later voids a redeemed code.

Errors

ParameterTypeDescription
GIFT_CARD_AMOUNT_UNSUPPORTED422gift_card_amount is not one of the catalog faces.
GIFT_CARD_AMOUNT_MISMATCH422The invoice is outside that face's window. Example: amount 8.00 with gift_card_amount 10.
GIFT_CARD_AMOUNT_USD_ONLY422gift_card_amount was sent with a non-USD currency.

Auth, rate limits, and other shared codes are on Error Codes.