# Go-live checklist & troubleshooting

> Everything to check before you switch Baziness on in production, and the fixes for the problems integrations run into most often.

## Before you go live
### Settings
- [ ] A **production** client id and secret (different from development), on the server only.
- [ ] `BAZINESS_PLATFORM_ENABLED=true`, `BAZINESS_PLATFORM_USE_PRODUCTION=true`, and the platform package name and game name set.
- [ ] `BAZINESS_PAY_ENABLED=true`, `BAZINESS_PAY_BASE_URL=https://pay.baziness.com`, and the Pay package name set; the local fake gateway off.
- [ ] Search your client build for the secret: it must **not** be there.
- [ ] `/api/platform/config` answers `enabled: true` with the **production** addresses.

### Login
On the dev platform you can test every case with made-up phone numbers and the code `111111`, because no SMS is sent ([details](login.md#testing-logins-on-the-dev-platform)).

- [ ] The splash asks «ورود با حساب بازینس» / «ادامه به عنوان مهمان» once per device.
- [ ] Closing the sign-in page without signing in brings the two buttons back.
- [ ] Signing in to an account used on another device **switches** to it, with its progress.
- [ ] Settings → connect account opens the profile page, and shows "connected" afterwards.
- [ ] Signing out inside a Baziness page resets the game to a brand-new visitor.
- [ ] Opening the game from the Baziness app (`?linkedToken=`) still runs the tutorial for new players.

### Coins & pages
- [ ] The Gita coin balance comes from the platform: `…` while unknown, never a made-up `0`.
- [ ] The balance refreshes when a page closes and when the game regains focus.
- [ ] Every one-off payout uses a `transactionId` built from what the payout is, and a `400` counts as paid.
- [ ] «انتخاب جایزه» opens `/shop?game_name=…` without a sign-in wall.
- [ ] (If you use it) the tutorial's first tap opens `/game-offer`, and closing it continues to the starter pack.
- [ ] The view closes by its handle, by a tap outside, and by the page's own button.

### Links
- [ ] Every page link has `packageName` and `sdkType=js`, and `linkedToken` when available.
- [ ] Campaign links carry all four `utm_*` in ASCII, and the address bar is clean after loading.
- [ ] The campaign survives a Baziness sign-in and an account switch.

### Baziness Pay
- [ ] Every SKU is registered under your Pay package name.
- [ ] A real production purchase is given **once**, then consumed.
- [ ] Buying the same pack twice in a row works, which proves `consume` ran.
- [ ] A payment finished after closing the game is given the next time the shop opens.

## Troubleshooting
| Symptom | Likely cause | Fix |
| --- | --- | --- |
| The page's close button does nothing | `sdkType=js` missing, or the message origin check uses the wrong origin | add `sdkType=js` to **every** page link; compare the message origin with the address you opened |
| The reward shop closes as soon as it opens | the `token` handshake is treated as a sign-in | ignore `token`; only `login` is a sign-in |
| The first sign-in hangs, or your server answers 400 | the sign-in started before the player had a Baziness user and token | call `/api/platform/token` first, and open the page with that token |
| Signed in, but the game still shows a guest | `/api/platform/login` wasn't called, or the profile wasn't reloaded | call it on `login`, then reload the player's profile |
| The sign-in page offers "continue as guest" | `allowGuest=false` missing | add it on the sign-in, profile and offer pages (not `/shop`) |
| The reward page asks the player to sign in | the site root was opened instead of `/shop` | open `{web}/shop?game_name=…` with `linkedToken` |
| Platform calls start failing after a while | the client token expired (`401`) | get a new one ([step 1](platform-api.md#step-1-get-a-client-token)) and retry once |
| A valid-looking token is rejected | `validate-user-token` answered `isValid: false` (HTTP 200) | check the `isValid` field, not only the HTTP status; the client signs in again |
| A player got the same coins twice | the `transactionId` was built from the time | build it from what the payout is ([step 5](platform-api.md#step-5-give-gita-coins)) |
| A claim fails forever after a crash | `add-coin` answered `400` and the claim treated it as an error | treat `400` as "already paid" |
| The payment tab stays blank | the tab was opened after waiting for the server, or with `noopener` | open an empty tab inside the tap, then set its address |
| The player paid but got nothing | they never came back, so the check never ran | check on focus and on «پرداخت کردم», and check pending payments when the shop opens |
| `verify_payment` always fails | it was sent as JSON | send a form body |
| Pay answers `no_required_params` | `uid` isn't numeric | send your numeric player id |
| A second purchase of the same pack is blocked | the purchase wasn't consumed | call `consume` after giving the item, with retries |
| Players from the Baziness app skip the tutorial | `?linkedToken=` was taken to mean "returning player" | decide "new player" from your own data |
| The campaign is lost after sign-in | the tags were read from the address only, and the game restarted | store them on the device before the sign-in |
| Persian campaign names are missing | UTM values are kept as ASCII only | use ASCII names (`shahrivar_1405`) |
| The sign-in view is invisible on the splash | the view sits below the splash screen | put it above everything |

## Getting help
- Credentials, your game's offer page and SKUs: ask the **Baziness platform team**.
- To see everything working together, read the [example game](example.md)'s code.
