purchaseGiftCard mutation to purchase your gift card. This mutation requires a PurchaseGiftCardInput input object.
Sample Mutation
Here’s the quickest way to start purchasing a gift card. You are able to customize your query from theUserPurchase object. See the API reference.
Fields
Required
idempotencyKey — A unique client-generated UUID to ensure a request is processed only once.
offerId or merchantSlug — Use the offerId or merchantSlug from the getOfferQuote query to get the best offer. Using the merchantSlug will automatically purchase the best offer rate for that merchant.
amount — The gift card amount you’d like to purchase.
Rate selection
exclusiveRateId — The unique identifier for a specific exclusive rate offer. When provided, this forces the purchase to use the specified exclusive rate. If not provided, the system will automatically select the best available rate. The exclusiveRateId can be found in the getMerchants query response for offers with type EXCLUSIVE_RATE_OFFER when you provide exclusiveRateId in your query request under offers.
minRewardRate — If you want to specify the minimum reward rate to purchase if the merchantSlug option is chosen.
Payment
At least one funding source is required. You may also choose to combine your Fluz balance with another funding source.balanceAmount — If you want to pay for your gift card with your Fluz balance, define the amount of balance here. You can use the getWallet query to check your balances.
userCashBalanceId — The spend account that balanceAmount is drawn from. Pass this explicitly whenever your account holds more than one spend account. If omitted, Fluz draws from the spend account flagged isDefault: true. This is a modifier on balanceAmount, not an alternative funding source — see Choosing a spend account.
bankAccountId — If you want to pay with an external linked bank account, define the bank account ID. This is not a spend account.
bankCardId — If you want to pay with a bank card, define the bank card ID.
paypalVaultId — If you want to pay with a PayPal account, define the PayPal account ID.
defaultToBalance — If you want to use your Fluz balance as the fallback payment method in case your other payment methods fail, set defaultToBalance to true. By default, this is set to true. If you change this setting to false, the system will not attempt to use your Fluz balance as a backup payment method.
Expense details
memo — If you want to attach a note to this transaction, provide a free-text memo here. Max 255 characters.
transactionCategory — If you want to categorize this transaction, provide a category name. Categories are created automatically on first use and reused if the same name is passed again.
attachmentId — If you want to attach a file to this transaction, provide the ID returned by the upload endpoint. See Add Expense Details.
See Add Expense Details for full details on uploading attachments and working with memos and categories.
PurchaseGiftCardInput
Choosing a spend account
A spend account is a cash balance account inside Fluz that holds the funds a purchase draws from. Your account can hold several of them — for example “Main account,” “Operations,” or “Client A” — each with its own nickname and its own balance. This section covers only what you need in order to fund a gift card purchase. For the full picture — how spend accounts work, the three balances each one tracks, and how to create, rename, and close them — see Spend Accounts in the Wallet documentation.“Spend account,” “cash balance,” and
UserCashBalance all refer to the same object.The product surfaces it as a spend account. The API names the type UserCashBalance, so the field on this mutation is userCashBalanceId — not accountId. Note that bankAccountId is unrelated: it refers to an external linked bank account, not a spend account.Which field does what
When you fund a purchase from your Fluz balance, two fields work together:
These are not mutually exclusive.
userCashBalanceId has no effect unless the purchase draws on balance — either through balanceAmount or through a defaultToBalance fallback.
Default behavior when userCashBalanceId is omitted
If you omit userCashBalanceId, Fluz draws from the spend account flagged isDefault: true.
To move funds between spend accounts — for example, to unblock an order drawing from the wrong account — see Transfer Funds Between Spend Accounts. Internal transfers settle immediately.
Step 1 — Retrieve your spend account IDs
Use thegetUserCashBalances query to list your spend accounts. This requires the LIST_PAYMENT scope.
userCashBalanceId of the account you intend to spend from. The ID is stable, so you can hold it in configuration rather than looking it up on every purchase — though you should check availableCashBalance before high-volume runs.
See Get Spend Accounts for the full field reference, filter options, and pagination.
Step 2 — Pass the spend account on the purchase
defaultToBalance: false prevents any implicit fallback, so the purchase either draws from the spend account you named or fails cleanly. In an automated ordering pipeline, this is usually the behavior you want.
Splitting a purchase across balance and another funding source
userCashBalanceId scopes only the balance portion of a purchase. To pay part from a spend account and the remainder from a linked bank card:
Learn more about spend accounts
Spend accounts are part of your Fluz wallet, and they are not limited to gift cards — virtual cards are funded from a spend account, and deposits land in one.- Spend Accounts — the full model: balances, the default account, the account lifecycle, and how to create, rename, and close accounts.
- Get Spend Accounts — look up your accounts and their IDs.
- Transfer Funds Between Spend Accounts — move balance between accounts instantly.
- Create Virtual Card — fund a virtual card from a spend account.
- Deposit Funds — add funds to a specific spend account.
Sample Response
Once your purchase is complete, you’ll get a response that looks something like this:Cashback rates are subject to change.
We do our best to always give our customers the best offers available. This means that our rates change regularly. Always confirm the rate before making a purchase.Buying more than one card
A singlepurchaseGiftCard call buys exactly one gift card, on one offer, at one rate. There is no quantity field, and a call is never split or blended across offers or rates. To buy several cards, send the mutation once per card, each with its own unique idempotencyKey.
Because each card is its own call, ordering more cards than a stocked offer has in inventory resolves per call:
offerId(pinned offer): once the stocked offer is depleted, the remaining calls fail withGC-0009. There is no automatic fallback to another offer or rate.merchantSlug(auto-select): the remaining calls auto-select the next-best available offer — often a variable offer at a lower reward rate — unlessminRewardRateblocks the lower rate.
minRewardRate rate-floor pattern, and the GC-0009 response, see Purchase in Bulk.
Ordering at volume: concurrency, timeouts, and retries
Purchases that draw on the same Fluz account are processed sequentially. When manypurchaseGiftCard calls are submitted at the same time against a single account, they queue behind one another, and individual calls can take longer to return — occasionally up to a few minutes under heavy load. Calls that aren’t queued typically return within seconds.
To keep latency predictable and avoid false failures when ordering at volume:
- Pace your concurrent requests. Instead of firing an entire batch simultaneously against one account, submit in smaller waves, or spread volume across multiple accounts. This keeps per-call latency low.
- Use a generous client timeout. Fluz does not abandon an in-flight purchase after a few seconds — a request can still be legitimately processing and will return a valid result. A short client-side timeout (for example, 30 seconds) may cause you to give up on a purchase that ultimately succeeds. Set your timeout high enough to absorb occasional multi-minute processing under load. We recommend 1 minute.
- A client timeout is not a cancellation. Closing your connection does not cancel a request that Fluz has already accepted; it continues processing to completion. Treat a timeout as an unknown outcome, not a failure.
- Resolve timeouts by retrying with the same
idempotencyKey. Reissue the identical request with the identicalidempotencyKey. Because the key guarantees the purchase is processed at most once, the retry returns the original purchase if it already succeeded — it will not create a duplicate or a second charge. Never issue a newidempotencyKeyfor a purchase you’ve already attempted; doing so is what produces duplicate orders.
idempotencyKey, or look up the purchase by its purchase ID, before refunding the end user. A timed-out request has often already succeeded on Fluz’s side, and the gift card code remains revealable until the purchase is refunded.