Skip to main content

Integration Process

Moonshot is the game provider. Your backend is the operator and owns player wallets. The same signed HTTP contract applies to every partner and every game. Use the API overview for the complete endpoint list, call directions and links to each request/response contract.

A complete game session​

Read the normal flow from top to bottom. The backend verifies signed responses before trusting them; the browser never receives the shared HMAC secret.

1. Configure the partner​

Use the onboarding handoff to collect exact base URLs, credentials, allowed game origins and enabled game/currency settings. Follow the integration quickstart from callback implementation to sandbox launch and wallet settlement.

Receive a stable operatorSlug, a provider-issued operatorId (UUID), a callback base URL registration, and a separate shared HMAC secret for each environment. Enable the agreed games, currencies, and limits. Keep the secret on your backend.

2. Keep identity namespaces separate​

FieldOwner and meaning
operatorSlugAgreed partner routing key, bound to the signing secret.
operatorIdOperator UUID issued by Moonshot, also returned in the signed launch response. It is not your database's provider ID.
playerIdYour player UUID, sent at launch and echoed in callbacks.
sessionIdYour session reference, sent at launch and echoed unchanged in bet, win, and cancel callbacks. Nonempty string, at most 256 characters.
betIdMoonshot's bet UUID, shared by the bet and its settlements.
transactionIdMoonshot's UUID for one wallet operation; the callback idempotency key.

Authenticate the agreed operatorSlug with its registered secret and resolve your local integration from that verified identity. operatorId is informational for the operator backend; no additional database ID mapping or pinning is required. Do not use it to choose a wallet or bypass session ownership checks. Internal IDs remain local to each system. Never use a provider's internal player-session credential as sessionId.

3. Launch a game​

Call POST /launch from your backend, using the canonical request signature. Verify the response signature and echoed slug/idempotency key before embedding data.url in an iframe. A reload creates a fresh launch request and session. A launch timeout is an unknown outcome: do not invent a successful session or replay gameplay against it.

4. Implement wallet callbacks​

Expose these paths beneath your registered callback base URL:

Verify signatures on raw request bytes before handling the callback. Atomically record the transaction and mutate the wallet, keyed by (authenticated operatorSlug, transactionId). A repeated identical operation returns its stored response without another debit or credit. Reject reuse of an ID with changed request content. Win and cancel must refer to an accepted original bet, with the same player, currency, game, and session. Settlements can arrive after a session expires; resolve them from the original bet.

Follow the money​

This regular-wallet example starts at 10 asset units and stakes 0.01. The branches below are alternative outcomes for one accepted bet.

A win is the gross credit amount, including any returned stake. A zero payout settles the bet without adding money. A final settlement must not also receive an independent refund.

Handle a repeated callback​

Authenticate first. Keep the idempotency decision and money mutation inside the same database transaction and wallet lock, including across backend instances.

Look up transactions by (authenticated operatorSlug, transactionId). "Same request" means the same endpoint and exact payload. Replay and conflict branches never mutate the wallet. For a new operation, validate the bet and atomically store either its wallet/state changes and result, or its business rejection without a wallet change. A later identical retry returns that stored outcome.

On an identical wallet callback retryKeep or regenerate?
Endpoint, transactionId and exact body bytesKeep unchanged.
x-request-id, timestamp and request signatureRegenerate for each HTTP attempt.
Response data and operatorTransactionIdReplay the original stored result.
Response signature and echoed x-request-idRegenerate for the current attempt.

Launch is different: its current key correlates requests and does not guarantee session replay. Follow the launch retry rules.

5. Test before enabling traffic​

Prove launch → bet → win and launch → bet → cancel using different IDs in both systems. Check insufficient funds, wrong operator/player/session, malformed signatures, sequential and concurrent duplicate callbacks, changed-payload retries, and retries after a response is lost. An HTTP conflict must include a signed, actionable error message. Verify that rejected callbacks do not change balances. Use independent test credentials and wallets; repeat the agreed checks for production. The sandbox test matrix lists expected results, recovery checks and go-live evidence. See Troubleshooting for common failures.

Freeplays use the separate freebet contract and must be enabled and tested explicitly. Contact [email protected] for onboarding.