Skip to main content

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.