Skip to content

Confirm a shop payment

POST
/api/shop/confirm
curl --request POST \
--url https://foxleague.ai/api/shop/confirm \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "player_nonce": 1, "player_nonces": [ 1 ], "product": "example", "quantity": 1, "tx_hash": "example", "wallet_address": "example" }'

Delivers a shop product after you paid for it with shopPay on the game contract, in FOXSY. Send the transaction hash: the server checks the payment on chain (sender, contract, function, token, amount) and delivers once per transaction.

  • xp_booster, training_slot (the price times quantity) and common_pack: the payment must equal the price.
  • condition_recovery: pay for the missing condition points of the selected players (player_nonce or player_nonces), in whole FOXSY. A player’s full recovery costs prices.condition_recovery from GET /api/shop/status, rounded up per player. The payment is spread over the selected players, the least drained first; whatever it does not use is refunded automatically.

Who: a signed-in player; wallet_address must be the session wallet and the payment must come from it.

Rate limit: Common packs: at most common_pack_per_wallet_per_week per wallet in any 7 days.

Refusals:

  • Wallet mismatch: sign with the correct wallet: wallet_address is not the session wallet.
  • Invalid product '<product>'. Valid: condition_recovery, xp_booster, training_slot, common_pack: unknown product.
  • The Common pack is not on sale right now.<refund note>: the Common pack is closed.
  • You already bought <n> Common packs in the last 7 days. The next pack unlocks when the oldest one leaves the window.<refund note>: you reached the weekly cap (pack when <n> is 1).
  • The Common pack is sold out: fewer than 5 Common players are left in the pool. Try again once the pool is restocked.<refund note>: the pool is too small for a pack.
  • The Common pack budget for this window is spent. Packs are on sale again once the budget window has room.<refund note>: the contract’s pack budget window cannot cover a pack.
  • Only a registered FoxLeague wallet can buy a Common pack: the players contract delivers packs to wallets that paid the registration or received their team. Please register first.<refund note>: the wallet neither paid the registration nor received its team.
  • Could not check your registration right now. Please retry in a moment. (tx_pending).
  • Could not check your weekly Common pack count right now. Please retry in a moment. (tx_pending).
  • Could not check the Common pool right now. Please retry in a moment. (tx_pending).
  • Could not check the Common pack budget right now. Please retry in a moment. (tx_pending).
  • Invalid quantity: training slots require a count of at least 1.: training_slot with quantity below 1.
  • condition_recovery requires player_nonce or player_nonces: no player selected.
  • The chain cannot be read right now. Your payment is kept: confirm again in a moment. (tx_pending): the chain cannot be read right now.
  • Chain is temporarily unavailable. Please retry shortly. (tx_pending): the server cannot read the chain right now.
  • Transaction already processed: this transaction already delivered a purchase.
  • This payment was already refunded and cannot be used for a purchase.: this transaction was refunded.
  • This payment is being refunded: the money has not been returned yet. It cannot be used for a purchase; if it does not arrive, contact support.: the refund of this transaction was claimed and has not landed yet.
  • This transaction was already used for a badge regeneration.: this transaction paid a badge regeneration.
  • Our support team is handling this payment and will return it to you, so it cannot be used here.: our support team holds this payment.
  • Could not verify the payment state right now. Please retry in a moment. (tx_pending).
  • Could not price the recovery right now. Please retry in a moment. (tx_pending).
  • Nothing to recover: the selected players are already at full condition.<refund note>: every selected player is at 100.
  • Transaction <status> on chain: cannot confirm shop purchase: the transaction failed on chain.
  • Your payment isn't confirmed on chain yet, but it may still settle. Please retry the shop purchase in a moment. (tx_pending): the transaction is not final yet.
  • Transaction was rejected on chain (<reason>) and refunded: shop purchase not confirmed: the call reverted on chain.
  • Transaction sender does not match your wallet: another wallet sent it.
  • Transaction was not sent to the shop purchase contract: it went to another contract.
  • Transaction is not a shop purchase call: it is not a shopPay call.
  • Transaction did not pay in FOXSY: shop purchase not confirmed: it paid another token.
  • Payment (<paid> FOXSY) is less than required (<price> FOXSY)<refund note>: you paid less than the price (for condition_recovery, less than one condition point).
  • Transaction paid <paid> but claimed product '<product>' costs <price> FOXSY.<refund note>: a fixed-price product was paid with another amount; <paid> reads like 2100 FOXSY.
  • Could not read the FOXSY amount from the transaction. Refresh and retry. (tx_pending): condition_recovery only.
  • Transaction verification timed out. The payment is not lost: <next step> (tx_pending): the transaction could not be read in time. <next step> is it is recognized when this same transaction is confirmed again within <m> minutes; after that it is refunded automatically. or it is recognized when this same transaction is confirmed again in the next few minutes; after that our support team takes it over and returns it to you.
  • Failed to record purchase. Your payment is kept: confirm again in a moment. (tx_pending).
  • None of the <n> selected players could be recovered. They may no longer be in your wallet. Your payment is being refunded automatically.: condition_recovery reached none of the selected players (player when <n> is 1).

Refusals ending in <refund note> add one of these sentences (nothing when no payment can be refunded): Your payment is being refunded automatically. / Your refund has been queued and will be issued by our team. / This payment was already applied to a completed purchase, so no refund is needed. / This payment was already used for a badge regeneration, so no refund is needed. / Our support team is handling this payment and will return it to you. / The automatic refund could not be issued. Our team has been notified and will return your payment.

Refusals marked (tx_pending) carry code: "tx_pending": the payment was not refused, it could not be checked or recorded yet. Keep the transaction hash and confirm again with the same hash; never pay twice.

Media type application/json

A shop payment to confirm.

object
player_nonce

condition_recovery: the card to recover. Use player_nonces for several.

integer | null format: int64
player_nonces

condition_recovery: the cards to recover.

Array<integer> | null
product
required

condition_recovery, xp_booster, training_slot or common_pack.

string
quantity

training_slot: how many slots you paid for, at least 1. Default 1.

integer | null format: int32
tx_hash
required

The hash of your shopPay transaction, 64 hexadecimal characters.

string
wallet_address
required

Your wallet; it must be the session wallet.

string
Example generated
{
"player_nonce": 1,
"player_nonces": [
1
],
"product": "example",
"quantity": 1,
"tx_hash": "example",
"wallet_address": "example"
}

Success or a refusal: read success (the refusals are in the description).

Media type application/json
object
code

A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.

string | null
data

The answer. Present when success is true.

object
message
required

What was delivered, in plain words, for example XP Booster activated: 2x XP for 24 hours!, Extra training slots purchased: +5, balance now 12 or 3 players condition recovered.

string
product
required

The product delivered.

string
purchase_id
required

The id of the purchase record.

integer format: int32
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
Example
{
"data": {
"message": "Extra training slots purchased: +5, balance now 15",
"product": "training_slot",
"purchase_id": 1288
},
"success": true
}

No valid session. The body is plain text: Missing Authorization header, Invalid Authorization format, Invalid session token or Session expired or invalid. Sign in again.

Media type text/plain
string
Example
Session expired or invalid

The body does not match the request schema, for example a tx_hash that is not 64 hexadecimal characters. The body is plain text.