POST /transactions/cancel
Moonshot requests reversal of an accepted stake. Use a new transactionId and the
original betId, player, game, currency and session. amount is the stake to reverse.
Every callback uses canonical signed headers and responses.
sessionId echoes the partner reference from /launch; operatorId is the
Moonshot-issued operator UUID. operatorSlug identifies the configured signing
relationship. Never substitute your local provider ID for operatorId.
The JSON request body is unwrapped; successful responses use { "data": ... }.
Amounts and balances are decimal strings in asset units, not atomic integers.
This example reverses a separate 0.01 bet from a starting balance of 10.
Do not send win and cancel for the same final bet as two independent credits.
Request
{
"operatorId": "8e563380-2a27-41b1-8be5-2cdd7d1ec271",
"operatorSlug": "your-partner-slug",
"sessionId": "partner-session-123",
"transactionId": "ac1acc1c-6175-4661-81e8-9344536ba7f5",
"playerId": "fd63c560-f443-49b5-a721-c40c0e06b7be",
"betId": "c7456ca2-b302-42f1-96bf-3f9e5fe35086",
"isFree": false,
"amount": "0.01",
"currency": "SOL",
"gameSlug": "rusty-ring"
}
Validate the original debit before reversing it; a cancel is not a standalone credit. Do not reverse more than the outstanding stake or refund an already-settled bet. Replay the stored response on duplicates. Freeplay cancellation restores the play according to the grant rules and must not credit the regular wallet.
Response
{
"data": {
"balance": "10",
"operatorTransactionId": "a3d3e769-c7c4-47e5-b188-1b3293016458",
"statusCode": 1000
}
}
1000 means accepted. For business rejection, return HTTP 200 with a non-success
statusCode, unchanged balance, transaction ID and errorMessage; 5100 denotes
insufficient/invalid balance, 5000 denotes server error. An identical duplicate
returns the original stored response (including 1000 for an accepted operation),
not a new debit/credit or a 3000 rejection. HTTP 200 with 5000 is a business
response, not a transport 5xx; it does not trigger the HTTP client's server-error retry.
If a temporary error needs an HTTP retry, return a signed HTTP 5xx before committing;
if committed, replay the stored result on the next attempt.
For an authenticated protocol/state conflict, return a signed HTTP 409, for example:
{
"error": {
"code": "CONFLICT",
"message": "Original accepted bet does not match the callback",
"retryable": false
}
}
Do not include tokens, secrets or internal diagnostics. Failed transport/server attempts may be retried using the same transaction ID and payload. A timeout does not prove the transaction failed: replay the stored result after commit.