feat(docs, agents, risk): enhance documentation, API queries, and UI components

Updated the public documentation site with improved layout and accessibility, including new sections for client integration and admin guides. Enhanced API queries by adding 'active_only' and 'group_by' parameters for better data filtering in risk management. Refined UI components for agent management, ensuring consistent styling and improved user experience across the application. Added localization support for new documentation content in English and Nepali.
This commit is contained in:
2026-06-15 17:21:50 +08:00
parent 17335cb47a
commit 641c87ff50
107 changed files with 5114 additions and 943 deletions

View File

@@ -0,0 +1,636 @@
{
"shell": {
"title": "Admin Operations Guide",
"integrationDocs": "API Integration Docs",
"adminLogin": "Admin Console"
},
"nav": {
"gettingStarted": "Getting started",
"operations": "Core operations",
"management": "Management",
"finance": "Funds & tickets",
"platform": "Platform configuration",
"reference": "Reference",
"overview": "Overview",
"roles": "Roles & permissions",
"siteSetup": "Integration sites",
"draws": "Draws & results",
"settlementCenter": "Settlement center",
"agents": "Agent hierarchy",
"players": "Player management",
"tickets": "Ticket search",
"wallet": "Wallet & reconciliation",
"config": "Rules & risk control",
"reports": "Reports",
"fundOperations": "Fund operations guide",
"manualReview": "Manual review & payouts",
"faq": "FAQ"
},
"headers": {
"role": ["Role", "Primary responsibilities", "Typical access"],
"status": ["Status", "Meaning", "Available actions"],
"module": ["Module", "Description"],
"field": ["Field", "Description", "Example"],
"billStatusTable": ["Bill status", "Meaning", "Next step"],
"faq": ["Issue", "Resolution"],
"report": ["Report", "Purpose"],
"menu": ["Sidebar group", "Menu", "Typical users", "Description"],
"ledger": ["Ledger type", "When it occurs", "Effect on player funds", "Where to view"],
"walletTxn": ["Wallet ledger type", "When it occurs", "Description"],
"compare": ["Stage", "Wallet mode", "Credit mode"],
"reconcile": ["Situation", "Action", "Notes"],
"setting": ["System setting", "Location", "When enabled", "When disabled"],
"batchStatus": ["Batch status", "Meaning", "Available actions"]
},
"pages": {
"overview": {
"title": "Admin operations overview",
"description": "For your organization's super admins, site operators, and bound agent staff. This guide follows the actual admin menu and includes step-by-step instructions. For wallet-mode technical integration, see the API Integration Docs.",
"loginNote": "Admin console: https://lotteryadmin.tanumo.com/admin (use the operations account assigned by your organization or our team)",
"scope": "System capabilities",
"scopeItems": [
"Draw management: schedule generation, close, result review, and payout settlement",
"Players & tickets: search, freeze, view ledgers and ticket history",
"Rule configuration: play switches, odds, caps, jackpot (platform super admin)",
"Settlement center: credit-line period open/close, bill confirmation, payment recording",
"Agent hierarchy: agent tree, share/credit/rebate, downstream operator accounts",
"Wallet & reconciliation: main-site transfer ledger, missing-order handling (wallet mode)",
"Reports: P&L summary, risk occupancy, async export"
],
"menuMap": "Admin menu map",
"menuMapNote": "Visible menus depend on your account role. Bound agent accounts do not see platform finance menus such as Wallet ledger or Reconciliation.",
"menuMapRows": [
["Overview", "Dashboard", "All users", "Home after sign-in; current-period operations summary"],
["Agent organization", "Agent lines", "Super admin", "Provision independent sites and root agents for credit-line customers (wallet mode usually needs Integration sites only)"],
["Agent organization", "Agent list", "Site ops / agents", "Maintain agent tree, share/credit/rebate, downstream accounts"],
["Agent organization", "Settlement center", "Site finance / bound agents", "Credit-line periods, bill confirmation, record payments"],
["Daily operations", "Draw list", "Platform super admin", "Draw schedule, result review, redraw (shared by wallet and credit modes)"],
["Daily operations", "Ticket list", "Ops / support / agents", "Search tickets by player, draw, play type"],
["Daily operations", "Player list", "Site ops / agents", "Create profiles, freeze, view ledgers and tickets"],
["Daily operations", "Settlement", "Platform ops", "Post-draw payout settlement batches (not credit-line periods)"],
["Funds & reports", "Wallet ledger", "Platform / site finance", "Wallet mode: main-site transfers and in-lottery balance changes"],
["Funds & reports", "Reconciliation", "Platform / site finance", "Wallet mode: handle long-pending transfer orders"],
["Funds & reports", "Reports", "Ops / finance / agents", "P&L, player win/loss, risk, export"],
["Platform management", "Play rules / odds / limits / risk / jackpot", "Super admin", "Site-wide play and risk parameters (site operators usually do not see these menus)"],
["Platform management", "Integration sites / Admin users / Role management", "Super admin", "Site secrets, admin accounts, and permission assignment"]
],
"readingOrder": "Suggested reading order",
"readingItems": [
"Roles & permissions → confirm what your account can do",
"Wallet super admin: Integration sites → API Integration Docs → Draws & results → Wallet & reconciliation",
"Credit-line site ops: Agent hierarchy → Player management → Settlement center (open/close/payments)",
"Bound agent operator: Agent list → Player management → Settlement center (payments for own line only)",
"Fund semantics and ledger types → Fund operations guide",
"Draw review and payout batches → Manual review & payouts"
],
"modes": "Two player funding modes",
"modeRows": [
["Wallet mode", "Players enter via your main-site SSO; funds move through your wallet gateway; ops use Wallet ledger and Reconciliation. Technical details are in the API Integration Docs"],
["Credit mode", "Lottery-native accounts or agent-created profiles; bets use credit; wins settle in Settlement center periods; no main-site wallet involved"]
],
"note": "Share settlement bills use the share rate recorded at bet time. Closed historical periods are not recalculated when agent share rates change later."
},
"roles": {
"title": "Roles & permissions",
"description": "The admin console manages access as account → role → feature permissions. Bound agent operator accounts only see data within their agent line. Site admins are bound to a single site and do not get platform technical menus such as draw odds configuration.",
"matrix": "Common roles",
"matrixRows": [
["Super admin", "Highest access across the system: integration sites, draw intervention, agent line provisioning, global configuration", "Built-in super admin; not limited by site roles"],
["Site admin", "Single-site credit-line operations: agent tree, players, settlement, tickets, reports", "Bound to one site; no platform play rules/odds configuration"],
["Bound agent operator", "Manage downstream agents and players under this line; period payments (bills where this account is the payee only)", "Bound to a specific agent node; cannot open or close periods"],
["Risk / finance / support", "View or operate assigned menus by job function", "Assigned by super admin in Role management"]
],
"accountModel": "Account and permission model",
"accountItems": [
"Admin users (Platform management): create admin accounts; bind roles or site/agent scope",
"Role management (Platform management): select menus and actions; accounts do not hold permissions directly",
"Site admins must choose an owning agent when creating players; cannot default to the root agent",
"A bound agent's main account can record settlement payments; payee rules and direct-player/bill-party rules still apply",
"With view-only access, buttons such as record payment, confirm bill, and open/close period are hidden (not shown as errors)"
],
"accountSetup": "Create an operations account (super admin)",
"accountSetupSteps": [
"Sign in → Platform management → Admin users → Create account",
"Enter login name, initial password, and display name",
"Choose binding: ① site role (site admin) ② agent node (agent operator) ③ role only (platform role)",
"Site admin: select the target integration site under Site role",
"Agent operator: select the agent node under Agent binding (data scope = that node and downstream)",
"After saving, ask the user to change the initial password; if expected menus are missing, check Role management for the assigned role"
],
"note": "With no integration site, site-dependent write actions prompt you to create a site (super admin only)."
},
"siteSetup": {
"title": "Integration sites (super admin)",
"description": "Wallet mode requires an integration site first. Save SSO and wallet secrets and have your technical team configure them on your main-site server. Credit-line agent line provisioning also creates a site.",
"path": "Create and configure",
"pathItems": [
"Sign in at https://lotteryadmin.tanumo.com/admin → Platform management → Integration sites",
"Click Create site; enter site code (must match site_code in your JWT), name, and status",
"After creation, copy immediately the one-time SSO secret and wallet API key shown on screen (they cannot be viewed again after closing)",
"Edit the site: enter your wallet gateway URL (HTTPS root, no path), lottery H5 entry, iframe allowlist (one origin per line)",
"Click Connectivity test and confirm your balance query API returns success",
"Give secrets and site code to your technical team for main-site server configuration; field reference and curl examples are in the API Integration Docs"
],
"fieldRows": [
["Site code", "Written into site_code in JWTs your organization issues; must match on both sides", "demo"],
["Wallet gateway URL", "Your HTTPS root URL (no path)", "https://wallet.your-domain.com"],
["Lottery H5 entry", "Redirect or iframe entry URL", "https://front.tanumo.com"],
["Iframe allowlist", "Domains allowed to embed the lottery; one per line", "https://www.your-domain.com"],
["SSO secret", "Shown once at creation; your main site uses it to sign JWTs", "—"],
["Wallet API key", "Shown once at creation; lottery uses it when calling your wallet APIs", "—"]
],
"fields": "Key fields",
"caution": "Important notes",
"cautionItems": [
"Keep site codes, secrets, and domains fully isolated between test and production",
"Production wallet gateway must be a public HTTPS URL",
"Secrets must be configured on your main-site server by your technical team; the admin console does not auto-sync them to your systems",
"Integration and go-live checklist: API Integration Docs → Delivery"
],
"apiLinkNote": "Wallet gateway fields, curl self-tests, and iframe protocol are in",
"apiLinkLabel": "API Integration Docs → Setup"
},
"draws": {
"title": "Draws & results",
"description": "A draw is the basic betting unit. List times are shown in local timezone; the server stores UTC. Whether the hall accepts bets is determined live; the list shows database status, which may differ slightly from the player-side countdown.",
"lifecycle": "Draw statuses",
"statusRows": [
["Not started", "Before start time", "Edit, delete (no bets)"],
["Open", "Accepting bets", "Edit some times, cancel (no bets)"],
["Closing", "No longer accepting new bets", "Wait for draw"],
["Pending draw / drawing", "Waiting for or generating result", "Proceed to review and publish"],
["Pending review", "Cooling period for verification", "Approve, redraw/rollback"],
["Settling", "Calculating wins and payouts", "—"],
["Settled", "All tickets for this draw processed", "View finance and risk"],
["Cancelled", "Cancelled by admin", "Record kept; placed bets refunded"]
],
"workflow": "Daily workflow (platform super admin)",
"workflowItems": [
"Daily operations → Draw list → Batch generate draw plan: auto-create upcoming draws on configured intervals",
"Manually create a draw or edit times for not-started/open draws when needed",
"After close time the system closes automatically; draw flow: generate result → cooling review → publish → auto settlement",
"Draw detail page shows: finance summary, number occupancy, result batches, related tickets"
],
"publishWalkthrough": "Publish draw results step by step",
"publishSteps": [
"Draw list → open the target draw",
"Confirm status is Pending draw or Pending review",
"If no result yet: click Generate draw result",
"During cooling period verify numbers → click Approve and publish",
"After publish the system moves to Settling → Settled; wallet-mode players receive instant payouts, credit-mode players get credit release recorded in period ledger",
"If issues are found after publish: super admin may Redraw during cooling (see next section)"
],
"reopenWalkthrough": "Redraw and rollback (super admin only, during cooling)",
"reopenSteps": [
"Draw detail → Redraw/rollback",
"System rolls back payouts/credit releases → regenerate result → review and publish again → settle again",
"Actions are written to audit log; confirm with your finance team before proceeding"
],
"rules": "Rules & risk (related modules, super admin)",
"rulesItems": [
"Platform management → Play rules: play switches, min/max stake",
"Platform management → Odds & rebate: affects new tickets only",
"Platform management → Limit versions: per-number caps; sold-out numbers block betting",
"Platform management → Risk center: view occupancy and payout pools by number; occupancy ledger defaults to ticket aggregation"
],
"note": "Times cannot be changed after close. Cancel a draw only when open/closing with no bets.",
"manualReviewLinkNote": "Draw manual review, cooling period, and payout settlement batches are covered in",
"manualReviewLinkLabel": "Manual review & payouts"
},
"settlementCenter": {
"title": "Settlement center (credit line)",
"description": "Manage agent settlement periods: open → close and generate bills → confirm → record payments. Bound agents can only view and operate bills for their own line. Wallet-mode players are not part of this module.",
"entry": "Entry & permissions",
"entryItems": [
"Agent organization → Settlement center: period list",
"Open / close period: site finance accounts not bound to an agent only (usually your finance role)",
"Bound agents: cannot open or close periods; can only handle bills where they are the payee",
"Settlement write permission is required to show record payment, confirm bill, and similar actions; with view-only access the action area is hidden"
],
"periodFlow": "Period lifecycle",
"periodItems": [
"Open period: create an in-progress period; start accumulating share ledger and player credit moves",
"During period: player bets use credit, win releases, rebates, etc. are written to ledger",
"Close period: aggregate period data into player bills and agent bills; irreversible",
"Related draws for the period must be settled before close; warnings appear if unsettled tickets remain",
"After close: agents/finance confirm bills → record actual payments → bills reach settled status"
],
"openWalkthrough": "Open a period (site finance)",
"openSteps": [
"Settlement center → period list → Open period",
"Enter period name and start/end dates (per your agreement with agents)",
"Confirm no other in-progress period conflicts → submit",
"After open, new bets and credit releases count toward this period"
],
"closeWalkthrough": "Close a period (site finance)",
"closeSteps": [
"Confirm all draws for this period are Settled",
"Settlement center → select in-progress period → Close period",
"System aggregates share ledger into player bills (direct players) and agent bills (share at each level)",
"After close, bill status is Pending confirm; historical share uses bet-time snapshot, not current agent profile"
],
"paymentWalkthrough": "Confirm and record payments",
"paymentSteps": [
"Settlement center → period detail → Bills tab → open target bill",
"Payee account clicks Confirm bill (status: Pending confirm → Confirmed)",
"Click Record payment; enter actual received/paid amount, method, and notes",
"Multiple payments allowed until Settled; partial payment shows Partial paid",
"Bad debt write-off and top-up reversal: site finance only (not bound to an agent)"
],
"detailTabs": "Three tabs on period detail",
"detailTabItems": [
"Bills: player bills and agent bills; open a bill to confirm or record payment",
"Payments & adjustments: operation log for payments, bad debt, top-ups, etc. (by operation record)",
"Credit ledger: player credit limit moves (bet hold, win release, period payment entries, etc.)"
],
"billStatusSection": "Bill statuses",
"billStatusRows": [
["Pending confirm", "After close; awaiting agent or finance confirmation", "Confirm bill"],
["Confirmed", "Amount confirmed", "Record payment"],
["Partial paid", "Outstanding balance remains", "Continue payment"],
["Overdue", "Past due and not fully paid", "Collect or bad debt handling"],
["Settled", "Payments complete", "Archive for reference"]
],
"operations": "Permissions and scope notes",
"operationItems": [
"Record payment: payee only",
"Bound agents: player bills include direct players only; agent bills include bills where this node is bill party or counterparty",
"Bills have no currency_code field; display currency uses player default_currency"
],
"note": "Closed share bills settle using bet-time snapshot; history is not recalculated from current agent profiles.",
"fundOpsLinkNote": "For credit ledger types and how they differ from wallet mode, see",
"fundOpsLinkLabel": "Fund operations guide"
},
"agents": {
"title": "Agent hierarchy",
"description": "The agent layer controls which data you can see and credit limits for downstream players; menu permissions still come from roles. Credit-line sites must maintain the agent tree before creating players under it.",
"structure": "Organization",
"structureItems": [
"Super admin: Agent organization → Agent lines → Provision line: create independent site + root node for external agents",
"Site ops: Agent organization → Agent list: maintain agent tree under existing site",
"Select an agent node to edit profile: share, credit, rebate, delegation permissions",
"Root agent profile editable by super admin only; downstream maintained by parent agent or site admin",
"Agent operator admin accounts can be created (bind agent node in Admin users)"
],
"provisionWalkthrough": "Provision credit-line agent line (super admin)",
"provisionSteps": [
"Agent organization → Agent lines → Provision line",
"Enter site info, root agent name and code",
"Set initial share, credit, and rebate for root agent",
"Submit to auto-create integration site and root agent; record returned site code",
"Create site admin or root agent operator account for the partner (see Roles & permissions)"
],
"dailyWalkthrough": "Daily agent maintenance (site ops)",
"dailySteps": [
"Agent list → select parent node → Create downstream agent",
"Enter name, code, share/credit/rebate; whether further delegation is allowed",
"After save the node appears in the tree; continue creating downstream agents or players",
"Share/credit changes affect new tickets and future periods only; closed history unchanged"
],
"profile": "Agent profile fields",
"profileRows": [
["Share rate", "This level's share of downstream turnover", "After close, counted in this level's share profit (win/loss)"],
["Credit line", "Credit ceiling for downstream players", "Total bet holds for downstream players must stay within chain credit rules"],
["Rebate rate", "Rebate layered on play configuration", "Combined with platform Odds & rebate settings"],
["Delegation", "Whether creating downstream agents/players is allowed", "Site admins are not limited by this switch; they follow their own role permissions"]
],
"siteAdmin": "Site admin notes",
"siteAdminItems": [
"Site admins are not blocked by delegation switches on the selected agent profile; they follow their own role permissions",
"When creating players under an agent you must choose the owning agent (cannot default to root)",
"Open/close period and bad debt write-off require a site finance account not bound to an agent"
],
"note": "Agent profile changes affect new tickets and future periods only; closed history stays unchanged."
},
"players": {
"title": "Player management",
"description": "Manage wallet-mode and credit-mode players in one place. List and detail views show different balances and ledger tabs by funding mode.",
"list": "Player list",
"listItems": [
"Daily operations → Player list",
"Search: username, nickname, main-site player ID, owning agent",
"Funding mode column distinguishes wallet mode vs credit mode",
"Balance column: credit mode shows credit limit (major); wallet mode shows in-lottery balance (minor)"
],
"createWalkthrough": "Create credit-mode player (site ops / agent)",
"createSteps": [
"Player list → Create player",
"Owning agent is required (site admins cannot skip)",
"Enter login name, password, nickname, default currency",
"Set initial credit limit (credit mode)",
"After save the player can sign in with lottery-native credentials; wallet-mode players are usually auto-created on first valid main-site SSO entry"
],
"freezeWalkthrough": "Freeze / unfreeze",
"freezeSteps": [
"Player list or player detail → Freeze",
"Frozen players cannot bet; existing tickets settle per rules",
"Unfreeze restores normal betting"
],
"modes": "Funding mode differences",
"modeRows": [
["Wallet mode", "Enter via your main-site SSO; first valid JWT auto-creates profile. Detail tabs: wallet ledger, transfer orders"],
["Credit mode", "Lottery-native account or created in agent admin. Detail tab: credit ledger; wins settle in agent periods"]
],
"detail": "Player detail page",
"detailItems": [
"Credit ledger: bet hold, win release, period payment entries, etc.",
"Wallet ledger / transfer orders: wallet mode only; transfer orders map to main-site transfer records",
"Ticket history: jump to ticket detail (including combo play breakdown)",
"Adjust credit: requires player/agent management write permission"
],
"note": "Wallet-mode usernames are generated by the lottery (e.g. nlotto******); nicknames are not synced from your main site."
},
"tickets": {
"title": "Ticket search",
"description": "Search player tickets across dimensions for operations, support, and agent reconciliation. Bound agents only see tickets for players in their agent subtree.",
"entry": "Entry",
"entryItems": [
"Daily operations → Ticket list",
"Or from player detail → Ticket history for a single player"
],
"filter": "Common filters",
"filterItems": [
"Draw, player, play type, ticket number, time range",
"Status: pending draw / won / lost / cancelled, etc.",
"Agent scope: super admin can filter by site; site ops see own site; bound agents see own subtree"
],
"detail": "Ticket detail",
"detailItems": [
"Shows bet content, odds, amount, share snapshot (credit mode)",
"Combo plays (e.g. combination bets) show combo breakdown on detail page",
"Related links: player detail, draw detail",
"Excel export supported (export permission required)"
],
"note": "Ticket amounts are snapshotted at bet time; status updates automatically after draw; no manual ticket edits."
},
"wallet": {
"title": "Wallet & reconciliation (wallet mode)",
"description": "Applies to wallet-mode players only. Shows transfer records between your main site and the lottery. Bound agent accounts usually do not see this menu.",
"walletSection": "Wallet ledger",
"walletItems": [
"Funds & reports → Wallet ledger",
"Filter by player, type, time: transfer in, transfer out, bet, payout, etc.",
"Amounts are minor integers; consistent with wallet gateway definitions in API Integration Docs",
"Export filtered results (permission required)"
],
"transferSection": "Transfer orders",
"transferItems": [
"Wallet module includes Transfer orders list (main site ↔ lottery)",
"Status: success / failed / pending",
"Long-pending orders can be handled in Reconciliation"
],
"reconcileSection": "Reconciliation (missing orders)",
"reconcileSteps": [
"Funds & reports → Reconciliation",
"List shows long-pending or abnormal transfer orders",
"Open an order → verify actual debit/credit result with your main site",
"Per verification: post entry, reverse, or close; actions are audited",
"Technical team should also check your wallet gateway logs and API Integration Docs → Troubleshooting"
],
"note": "Credit-mode players do not use wallet ledger or reconciliation; their fund moves are in Settlement center credit ledger.",
"fundOpsLinkNote": "For wallet vs credit fund lifecycle comparison, see",
"fundOpsLinkLabel": "Fund operations guide"
},
"config": {
"title": "Rules & risk control (platform super admin)",
"description": "Site-wide play, odds, limits, and risk parameters. Usually visible only to platform super admins or your organization's super admins with platform access; site ops and agents typically do not see these menus.",
"plays": "Play rules",
"playsItems": [
"Platform management → Play rules",
"Switch plays on/off: disabled plays cannot be bet on player side",
"Set min/max stake per bet"
],
"odds": "Odds & rebate",
"oddsItems": [
"Platform management → Odds & rebate",
"Adjust odds and base rebate; affects new tickets only",
"Combined with rebate rate in agent profiles"
],
"riskCap": "Limit versions",
"riskCapItems": [
"Platform management → Limit versions",
"Set per-number caps; number is sold out when cap is reached",
"New version applies to future draws only; open draws use the version active at open"
],
"risk": "Risk center",
"riskItems": [
"Platform management → Risk center",
"View number occupancy, payout pools, high-risk numbers",
"Occupancy ledger defaults to ticket aggregation; only numbers with occupancy or high risk are shown",
"Combo play breakdown is on ticket detail, not expanded in risk list"
],
"jackpot": "Jackpot",
"jackpotItems": [
"Platform management → Jackpot",
"Maintain jackpot amount and payout rules (when jackpot play is enabled)"
],
"note": "If your site operator account does not see these menus, that is normal permission isolation; contact our team or your super admin to adjust play settings."
},
"reports": {
"title": "Reports",
"description": "View P&L and risk by draw, player, play type, and more; async export supported. Data scope narrows automatically by account role.",
"entry": "Entry & filters",
"entryItems": [
"Funds & reports → Reports",
"Choose report type first, then set time, site, agent, draw, and other filters",
"Bound agent reports include own agent subtree only"
],
"types": "Main reports",
"reportRows": [
["Per-draw P&L", "Stake, payout, and profit summary for one draw"],
["Daily summary", "Aggregated by business date"],
["Player win/loss", "Ranking and detail by player"],
["Play dimension", "Stake and payout structure by play type"],
["Hot number risk", "Bet concentration and payout pool occupancy by number"],
["Rebate commission", "Rebate and commission accrual"],
["Audit log", "Trace key admin actions (super admin)"]
],
"export": "Export",
"exportItems": [
"Report export permission required for async export; download when complete",
"Ticket list and wallet ledger also support Excel export",
"Export jobs run asynchronously; narrow time range for large data sets"
],
"scope": "Data scope",
"scopeItems": [
"Super admin: all sites or filter by site",
"Site admin: own site",
"Bound agent: own agent subtree"
]
},
"fundOperations": {
"title": "Fund operations guide",
"description": "Explains how funds move during betting, draw settlement, and payment in wallet mode vs credit mode. Confirm the player's funding mode first, then check the matching ledger.",
"twoSystems": "Two parallel systems (do not confuse them)",
"twoSystemsItems": [
"Per-draw settlement (Daily operations → Settlement): calculates win/loss for the draw; wallet mode pays out here, credit mode records release/period ledger here",
"Credit-line period settlement (Agent organization → Settlement center): credit mode only; aggregates share by period and generates bills for agent/player payments",
"Main-site wallet transfers (Funds & reports → Wallet): wallet mode only; transfer in/out between main site and lottery"
],
"creditModel": "Credit mode: credit limit model",
"creditModelItems": [
"Credit limit (credit_limit): ceiling set by agent or ops for the player",
"Used credit (used_credit): total of bet holds plus settled losses",
"Available credit = credit limit used credit frozen amount; betting blocked when available is insufficient",
"Balance shown in player list/detail for credit mode is credit-related, not cash balance"
],
"creditLifecycle": "Credit mode: fund lifecycle of one ticket",
"creditLifecycleSteps": [
"① Bet placed: credit hold (ledger shows Bet hold). This locks available credit, not final deduction",
"② Pending draw: hold remains; ledger shows hold only, no duplicate settlement charge",
"③ After draw settlement: system releases the hold, then posts Draw settlement — loss increases used credit; win releases credit (available rises), no instant cash",
"④ During period: win/loss also written to share ledger for period close and bills",
"⑤ After period close: confirm bills and record payments in Settlement center; player may see Period settlement confirm or Settlement payment entry ledger types",
"⑥ Players with overdue unpaid bills: betting blocked until period payment is completed"
],
"creditLedger": "Credit mode: credit ledger type reference",
"creditLedgerRows": [
["Bet hold", "Player bet succeeds", "Available credit down; used credit up", "Settlement center → Credit ledger; player detail → Credit ledger"],
["Draw settlement", "Draw payout settlement complete", "Release hold and adjust used credit by win/loss; win = release", "Same; pending draw shows hold only; one settlement line per ticket after draw"],
["Period settlement confirm", "Period bill payment recorded (some cases)", "Used credit decreases", "Settlement center → Credit ledger"],
["Settlement payment entry", "Period payment bookkeeping", "Bookkeeping only; available credit unchanged", "Settlement center → Credit ledger"],
["Top-up / reversal / bad debt", "Site finance adjustment", "Adjust bill and ledger per adjustment type", "Settlement center → Payments & adjustments"]
],
"creditBill": "Credit mode: what bills and payments mean",
"creditBillItems": [
"Player bill after close = net receivable/payable for that player's win/loss in the period",
"Agent bill = share receivable/payable at each agent level",
"Positive net: bill party pays payee; negative net: payee pays bill party (admin shows payer/payee)",
"Confirm bill: both sides agree on amount; record payment: log actual funds, multiple entries until settled",
"Bad debt write-off: confirm unrecoverable debt; site finance only (not bound to agent)"
],
"creditAdjust": "Credit mode: manual credit limit adjustment",
"creditAdjustSteps": [
"Player detail → Adjust credit (requires player/agent management write permission)",
"Change credit limit ceiling; does not erase historical used credit",
"If new limit is below current used credit, player cannot bet until used credit drops",
"Period payments, bad debt, top-ups belong in Settlement center; do not duplicate manual entries on player detail"
],
"walletLifecycle": "Wallet mode: fund lifecycle",
"walletLifecycleSteps": [
"① Player enters lottery H5 from your main site (SSO + JWT)",
"② Transfer in: player initiates in H5 → lottery calls your wallet debit → in-lottery balance up (transfer order + wallet ledger)",
"③ Bet: deducted from in-lottery balance (wallet ledger type Bet debit)",
"④ Draw settlement: win amount to in-lottery balance (Payout credit); credited after Daily operations → Settlement batch review/payout",
"⑤ Transfer out (optional): lottery calls your wallet credit → in-lottery balance down",
"⑥ Exception: long-pending transfer orders handled manually in Reconciliation"
],
"walletTxn": "Wallet mode: wallet ledger types",
"walletTxnRows": [
["Main-site transfer in", "Player transfers from main site to lottery", "In-lottery balance increases"],
["Main-site transfer out", "Player transfers from lottery to main site", "In-lottery balance decreases"],
["Bet debit", "Bet succeeds", "Balance decreases"],
["Payout credit", "Draw payout settlement complete", "Balance increases (when won)"],
["Bet reversal / transfer-out failure refund", "Ticket cancelled or transfer-out rollback", "Balance restored"]
],
"walletReconcile": "Wallet mode: transfer order exceptions",
"walletReconcileRows": [
["Pending reconciliation", "Main site and lottery status mismatch or timeout", "Verify your gateway logs first, then choose action below"],
["Complete missing credit", "Main site debited but lottery not credited (transfer in)", "Post transfer in on lottery side and mark success"],
["Reversal", "Need to undo lottery-side entry", "Reverse lottery wallet balance"],
["Mark closed", "Resolved outside the system", "Change order status only, no balance move; not for pending transfer-out reconciliation"]
],
"compare": "Same stage: wallet mode vs credit mode",
"compareRows": [
["Entry", "Main-site SSO; first JWT auto-creates profile", "Lottery account or agent admin creates profile"],
["Must have funds to bet", "In-lottery balance ≥ stake", "Available credit ≥ stake"],
["When betting", "Balance deducted immediately", "Credit hold (freeze), not final loss"],
["After win", "Payout to lottery balance", "Credit release; cash settled in period bills"],
["Daily reconciliation", "Wallet ledger + transfer orders", "Settlement center credit ledger + bills"],
["Agent payments", "Not applicable", "Settlement center period bills"]
],
"note": "Credit-mode player UI uses release and period payment wording, not wallet-mode payout wording. The two modes cannot share one account."
},
"manualReview": {
"title": "Manual review & payouts",
"description": "Covers draw result review, cooling period, per-draw payout settlement batches, and related system switches. This is separate from Settlement center credit-line periods.",
"distinction": "Difference from credit-line period settlement",
"distinctionItems": [
"This guide: per-draw payout settlement batches (Daily operations → Settlement) — wallet mode pays out, credit mode posts draw ledger; runs every draw",
"Settlement center: credit-line period open/close/bill payments — aggregated by week/month etc.; not one-to-one with each draw",
"Approve and publish on draw detail: whether draw numbers take effect; settlement batch: how funds move after numbers are effective"
],
"drawReview": "Manual draw result review",
"drawReviewItems": [
"When System settings → Require manual review of draw results is on: after RNG generates numbers the draw is Pending review until someone clicks Approve and publish",
"When off: RNG results auto-publish (cooling period may still apply, see below)",
"Manual number entry: after submit, pending review or auto-publish depending on review switch",
"Entry: Daily operations → Draw list → draw detail → draw batch"
],
"drawPublishSteps": "Publish draw results (step by step)",
"drawPublishStepItems": [
"Open draw detail; confirm status is Pending draw or Pending review",
"If no result: click Generate draw result or enter numbers",
"Verify numbers match draw and play rules",
"Click Approve and publish",
"After publish, enters cooling period or Settling directly (see system settings)"
],
"cooldown": "Cooling period",
"cooldownItems": [
"System settings → Cooling period (minutes): wait after publish before payout settlement runs",
"During cooling, super admin may Redraw: rollback payouts/releases → regenerate → review and publish again",
"Set to 0 minutes: settlement runs immediately after publish, no cooling window",
"Cooling is the last window to verify numbers; unrelated to credit-line periods"
],
"settlementBatch": "Per-draw payout settlement batch",
"settlementBatchItems": [
"After each draw is published, the system auto (or manually) creates a settlement batch summarizing all ticket win/loss for that draw",
"Entry: Daily operations → Settlement → batch list; also from draw detail",
"Batch status: In progress → Pending review → Reviewed → Paid/Complete (automation may skip steps)",
"Wallet mode: Execute payout writes win amounts to player lottery balance",
"Credit mode: Execute payout writes draw settlement and share ledger; no cash balance increase"
],
"batchStatusSection": "Settlement batch statuses",
"batchStatusRows": [
["In progress", "Calculating win/loss for this draw", "Wait for completion"],
["Pending review", "Amounts calculated; awaiting finance/ops confirmation", "Approve / Reject"],
["Reviewed", "Amounts confirmed; awaiting payout", "Execute payout"],
["Paid", "Payout written to player account or credit ledger", "View detail, export"],
["Rejected", "Review failed; tickets return to pending settlement", "Fix and rerun settlement"],
["Failed", "Settlement process error", "Contact technical support"]
],
"batchWalkthrough": "Manual review and payout (step by step)",
"batchWalkthroughSteps": [
"Daily operations → Settlement → filter Pending review batches",
"Open batch detail; verify draw, ticket count, total stake, total payout, platform P&L",
"If consistent with draw result, click Approve; if not, Reject with notes",
"On Reviewed batch, click Execute payout — wallet balance credited, credit draw ledger created",
"After payout there is no one-click undo; wrong numbers require redraw during cooling on the draw"
],
"settings": "Related system switches (platform super admin)",
"settingRows": [
["Require manual review of draw results", "Platform management → System settings → Draw rhythm & review", "RNG results need manual publish", "RNG results auto-publish"],
["Cooling period duration", "Same as above", "Wait N minutes after publish before settlement", "Settlement immediately after publish"],
["Auto-run settlement", "System settings → Settlement automation", "Settlement batch runs automatically when due", "Settlement must be triggered manually"],
["Auto-approve settlement batch", "Same as above", "Batch auto-moves to Reviewed after settlement", "Manual approve required"],
["Auto payout credit", "Same as above", "Execute payout automatically after review", "Manual Execute payout required"]
],
"settingsNote": "Common production setup: manual draw review + cooling period + auto settlement run + manual batch review + auto or manual payout. Follow your organization's risk policy.",
"rejectNote": "Rejecting a settlement batch returns linked tickets to pending settlement; it does not rollback published draw numbers. If numbers are wrong, use draw redraw.",
"note": "Before closing a credit-line period, ensure all related draws in the period are Settled and payout batches complete; otherwise close will warn about unsettled tickets."
},
"faq": {
"title": "FAQ",
"description": "Typical admin issues and how to handle them.",
"faqRows": [
["Credit ledger confusing", "See Fund operations guide; pending draw shows Bet hold only; after draw one Draw settlement per ticket — no double charge"],
["Settlement batch vs Settlement center", "See Manual review & payouts; former is per-draw payout, latter is credit-line period bills"],
["Wrong draw result", "Draw detail → super admin redraw during cooling → rollback → review and publish again → settle again"],
["Player hall accepts bets but admin shows closed", "List status is DB snapshot; player hall is authoritative; check close_time and timezone"],
["Transfer not received (wallet mode)", "Check wallet ledger status; handle pending in Reconciliation; verify your gateway logs"],
["Integration site connectivity failed", "Confirm your wallet gateway is public HTTPS and implements balance/debit/credit APIs"],
["Close period button unavailable", "Confirm no other in-progress period, all draws for period are settled, account is not bound to an agent"],
["No record payment button", "Need settlement write permission; bill must be confirmed/partial paid/overdue with unpaid_amount > 0; must be payee"],
["Agent cannot see wallet menus", "Bound agent accounts hide wallet/reconciliation; use site finance or super admin account"],
["Cannot choose agent when creating player", "Site admin must choose owning agent; create downstream agent in Agent list first"],
["Insufficient permission", "Contact your super admin or our support to assign menus in Role management"]
],
"integration": "Technical integration",
"integrationItems": [
"SSO, iframe, wallet gateway: see API Integration Docs",
"Error codes 80018005: API Integration Docs → Troubleshooting"
],
"integrationLinkLabel": "View API Integration Docs"
}
}
}

View File

@@ -132,6 +132,8 @@
"validation": {
"shareRange": "Share rate must be between 0 and 100",
"creditInvalid": "Credit limit cannot be negative",
"creditBelowAllocated": "Credit limit cannot be below allocated credit (minimum {{min}})",
"creditExceedsParentWithMax": "Credit limit cannot exceed {{max}}",
"rebateLimitRange": "Rebate ceiling must be between 0 and 100%",
"defaultRebateRange": "Default player rebate must be between 0 and 100%",
"defaultExceedsLimit": "Default player rebate cannot exceed the rebate ceiling"

View File

@@ -74,6 +74,7 @@
"riskPools": { "filename": "risk-pools", "sheetName": "Risk pools" },
"riskIndex": { "filename": "risk-draws", "sheetName": "Risk center" },
"riskPoolDetail": { "filename": "risk-pool-{{number}}", "sheetName": "Risk pool detail" },
"ticketCombinations": { "filename": "ticket-combinations", "sheetName": "Combinations" },
"auditLogs": { "filename": "audit-logs", "sheetName": "Audit logs" },
"currencies": { "filename": "currencies", "sheetName": "Currencies" }
},
@@ -141,8 +142,12 @@
"notifications": "Notifications",
"notificationsComingSoon": "Notifications are under development",
"accountSettings": "Account settings",
"relatedDocs": "Documentation",
"loggedOut": "Signed out"
},
"docs": {
"learnMore": "Read full guide"
},
"nav": {
"home": "Home",
"dashboard": "Dashboard",

View File

@@ -42,6 +42,7 @@
"integrationSites": {
"title": "Integration sites",
"description": "Maintain partner integration settings in admin. site_code cannot be changed after creation.",
"pageGuide": "Wallet-mode partners need an integration site and SSO/wallet secrets; see API docs for technical setup.",
"create": "New site",
"edit": "Edit",
"save": "Save",

View File

@@ -1,6 +1,7 @@
{
"title": "Draws",
"statusListTitle": "Draw list",
"pageGuide": "Manage draw lifecycle: batch plans, close, result review, and settlement. Times cannot change after close; super admins may redraw during cooling.",
"generatePlan": "Generate draw plan",
"generating": "Generating…",
"generateSuccess": "Generated {{created}} draws, buffer {{upcoming}}/{{target}}",

View File

@@ -1,371 +1,467 @@
{
"shell": {
"title": "Integration API",
"admin": "Admin"
"title": "Lottery Integration Docs",
"admin": "Admin Console",
"adminLogin": "Admin Console"
},
"nav": {
"overview": "Overview",
"api": "API",
"ship": "Ship",
"ship": "Release",
"home": "Overview",
"quickstart": "Quickstart",
"fundamentals": "Money model",
"setup": "Setup",
"sso": "SSO",
"iframe": "iframe protocol",
"wallet": "Wallet gateway",
"transfer": "Transfers (ref)",
"errors": "Errors",
"golive": "Go-live"
"delivery": "Integration Delivery",
"quickstart": "Quick Start",
"fundamentals": "Fund Model",
"setup": "Integration Setup",
"sso": "Single Sign-On",
"iframe": "iframe Protocol",
"wallet": "Wallet Gateway",
"transfer": "Transfers (Reference)",
"errors": "Error Codes",
"troubleshooting": "Integration Troubleshooting",
"golive": "Go-Live Checklist",
"operations": "Operations Guide",
"adminGuide": "Admin Guide",
"apiReference": "API Integration Reference"
},
"headers": {
"component": ["Component", "Role", "Owner"],
"component": ["Component", "Responsibility", "Owner"],
"convention": ["Item", "Rule"],
"claim": ["Claim", "Type", "Req", "Note"],
"claim": ["Field", "Type", "Required", "Description"],
"param": ["Parameter", "Purpose"],
"methodPath": ["Method", "Path", ""],
"query": ["Query", "Type", ""],
"field": ["Field", "Type", "Note"],
"code": ["Code", "Message"],
"http": ["Status", "message", "Cause"],
"message": ["Dir", "type", "Payload"],
"balance": ["Field", "Account", "Note"],
"call": ["Direction", "API", "Auth"],
"sequence": ["Step", "Actor", "Action"],
"envMap": ["Item", "Admin site", "Main-site .env", "Note"],
"account": ["User", "Password", "site_player_id"],
"contract": ["Scenario", "HTTP", "Body"],
"adminField": ["Field", "Note", "Example"]
"query": ["Parameter", "Type", ""],
"field": ["Field", "Type", "Description"],
"code": ["Error Code", "Description"],
"http": ["Status Code", "message", "Cause"],
"message": ["Direction", "Message Type", "Payload"],
"balance": ["Field", "Account", "Description"],
"call": ["Direction", "API", "Authentication"],
"sequence": ["Step", "Initiator", "Description"],
"envMap": ["Item", "Admin Integration Site", "Main-Site Config", "Description"],
"account": ["Account", "Password", "site_player_id"],
"contract": ["Scenario", "HTTP", "Response Body"],
"adminField": ["Field", "Description", "Example"],
"handoffTable": ["Item", "Description", "Owner"],
"env": ["Environment", "Example URL", "Description"],
"envelopeTable": ["Direction", "Message Fields", "Description"],
"faq": ["Symptom", "Troubleshooting Direction"]
},
"pages": {
"overview": {
"title": "Integration",
"description": "Main-site SSO + wallet gateway. Identity via JWT; funds split between main wallet and in-lottery balance.",
"roles": "Roles",
"flow": "Flow",
"e2eSequence": "End-to-end sequence",
"conventions": "Conventions",
"readingOrder": "Reading order",
"title": "Integration Overview",
"description": "For main-site developers and integration engineers. You implement: JWT issuance + wallet gateway; we provide H5 and API.",
"roles": "Responsibility Split",
"flow": "Business Flow",
"e2eSequence": "End-to-End Sequence",
"conventions": "General Conventions",
"readingOrder": "Recommended Reading Order",
"matrix": [
["Main site", "Issue JWT; implement wallet gateway", "Partner"],
["Lottery API", "Verify JWT, play, transfers, bets", "Us"],
["Lottery H5", "H5 / iframe shell", "Us"]
["Main Site (Partner)", "User login; server-side JWT issuance; wallet gateway implementation", "Partner"],
["Lottery API (Us)", "JWT verification, transfers, betting, draw, settlement", "Us"],
["Lottery H5 (Us)", "Player UI; iframe embed or URL redirect entry", "Us"]
],
"flowItems": [
"Main-site login → issue JWT",
"Enter lottery (URL or iframe)",
"transfer-in → debit main + credit lottery",
"Bet / settle (lottery balance)",
"transfer-out → debit lottery + credit main"
"User logs in on main site → main-site server issues short-lived JWT",
"Enter lottery H5 (iframe embed or URL ?token= redirect)",
"Player taps \"Transfer In\" in H5 → lottery callbacks main site to debit → credits lottery balance",
"Player bets / receives winnings in H5 (using in-lottery balance)",
"(Optional) Player taps \"Transfer Out\" in H5 → lottery callbacks main site to credit"
],
"e2eRows": [
["1", "Main site", "User logs in; server signs JWT"],
["2", "Main site", "Embed lottery H5 in iframe, or redirect ?token="],
["3", "Lottery H5", "Receives token; calls GET /api/v1/player/me"],
["4", "Player", "Taps transfer-in inside lottery H5"],
["5", "Lottery API", "Server calls POST /wallet/debit-for-lottery"],
["6", "Partner wallet", "Debits main_balance; returns success"],
["1", "Main Site", "User logs in; server issues JWT (includes site_code, site_player_id)"],
["2", "Main Site", "Embed lottery H5 in iframe, or redirect to lottery_h5_base_url/?token="],
["3", "Lottery H5", "Receives JWT; calls GET /api/v1/player/me to verify and auto-provision"],
["4", "Player", "Taps \"Transfer In\" in H5"],
["5", "Lottery API", "Server callbacks main site POST /wallet/debit-for-lottery"],
["6", "Main-Site Wallet", "Debits main_balance; returns success: true"],
["7", "Lottery API", "Credits in-lottery balance"],
["8", "Player", "Bets / settles in H5"],
["9", "Player", "(optional) transfer-out in H5"],
["10", "Lottery API", "Calls POST /wallet/credit-from-lottery"]
["8", "Player", "Bets / awaits winnings in H5"],
["9", "Player", "(Optional) Taps \"Transfer Out\" in H5"],
["10", "Lottery API", "Callbacks main site POST /wallet/credit-from-lottery"]
],
"conventionRows": [
["Amount", "Minor units (integer), e.g. 2000 = 20.00"],
["Amount", "Integer in minor currency units, e.g. 2000 = 20.00 NPR"],
["Encoding", "UTF-8 JSON"],
["Time", "JWT: Unix seconds (iat / exp)"],
["Auth", "Player API: Bearer JWT; gateway: Bearer wallet_api_key"]
["Time", "JWT uses Unix seconds (iat / exp); recommend exp - iat ≤ 300 seconds"],
["Player API Auth", "Authorization: Bearer {JWT} (issued by main site, verified by lottery)"],
["Wallet Gateway Auth", "Authorization: Bearer {wallet_api_key} (sent by lottery on callbacks)"]
],
"readingItems": ["Quickstart → Setup → SSO → iframe protocol → Wallet → Errors → Go-live"]
"readingItems": [
"Integration Delivery — confirm deliverables and environment URLs for both parties",
"Quick Start — complete first integration test step by step",
"Integration Setup — admin site provisioning and key mapping",
"Single Sign-On → iframe Protocol → Wallet Gateway",
"Integration Troubleshooting — common issues",
"Go-Live Checklist — production release checks"
]
},
"delivery": {
"title": "Integration Delivery",
"description": "Before integration testing begins, confirm the following deliverables with sales/technical support. Test and production environments must be fully isolated.",
"handoffScope": "Integration Scope (What You Need to Do)",
"weProvide": "We Provide",
"youProvide": "Partner Must Provide",
"environment": "Environment URLs",
"process": "Typical Integration Process",
"note": "Secrets (sso_jwt_secret, wallet_api_key) are shown only once at creation. Save them securely immediately. Secrets must be stored on the main-site server only — never in frontend or mobile apps. URLs below are Tanumos current defaults; partner-specific deployments follow sales delivery.",
"handoffRows": [
["JWT Issuance", "Main site issues HS256 JWT server-side after login; no \"login-for-token\" API", "Partner"],
["Wallet Gateway", "Implement three HTTPS endpoints: balance / debit / credit", "Partner"],
["iframe or URL Entry", "Embed lottery H5 or redirect with JWT", "Partner"],
["Lottery H5 + API", "Games, transfers, betting, draw", "Us"],
["Integration Site & Keys", "Create site_code and deliver secrets", "Us (Super Admin)"]
],
"provideRows": [
["site_code", "Site code, written into JWT"],
["sso_jwt_secret", "JWT signing secret (held and used by main site to sign)"],
["wallet_api_key", "Bearer secret when lottery callbacks wallet gateway"],
["lottery_h5_base_url", "Lottery H5 entry (iframe src or redirect); default https://front.tanumo.com"],
["lottery_api_base_url", "Lottery API base (curl); default https://lotterylaravel.tanumo.com"]
],
"submitRows": [
["wallet_api_url", "Partner wallet gateway HTTPS root URL (publicly reachable)"],
["iframe_allowed_origins", "Main-site origin allowlist (required for iframe mode, one per line)"],
["Test Accounts", "Several site_player_id values with initial main_balance (for integration testing)"],
["Egress IP (if needed)", "If gateway has IP allowlist, request lottery server egress IP"]
],
"environmentRows": [
["Lottery API", "https://lotterylaravel.tanumo.com", "curl: GET /api/v1/player/me"],
["Lottery H5 entry", "https://front.tanumo.com", "iframe / ?token=; wallet page example /wallet"],
["Integration docs", "https://lotteryadmin.tanumo.com/docs/integration", "This documentation (public)"],
["Admin console", "https://lotteryadmin.tanumo.com/admin", "Super admin; integration sites: Config → Integration sites"],
["Production Environment", "Separate domain and secrets", "site_code, secrets, and domains must not be shared with integration"]
],
"processSteps": [
"Sales enables integration → our super admin creates \"Integration Site\" and delivers secrets and H5 URL",
"Partner implements three wallet endpoints and deploys to public HTTPS (integration may use tunnel first)",
"Partner fills wallet_api_url and iframe_allowed_origins in admin, runs connectivity test",
"Partner implements JWT issuance and iframe postMessage (or URL redirect)",
"Complete integration testing per Quick Start acceptance checklist",
"Production: re-provision site, rotate secrets, full end-to-end retest before go-live"
]
},
"quickstart": {
"title": "Quickstart",
"description": "Local integration guide. The main-site/ package in the repo is a runnable reference; secrets must match the admin integration site or lottery .env.",
"title": "Quick Start",
"description": "Assumes Integration Delivery is complete and you have site_code, secrets, and H5 URL. Follow these steps for first integration test.",
"prereq": "Prerequisites",
"steps": "Integration steps",
"testAccounts": "Test accounts (main-site)",
"reference": "Reference implementation",
"note": "Production requires HTTPS and isolated site_code/secrets. Without wallet_api_url locally, lottery API may stub main-site debits (non-production only).",
"steps": "Integration Steps",
"acceptance": "Acceptance Checklist",
"note": "JWT must be issued on the main-site server — never hardcode sso_jwt_secret in frontend. Production wallet_api_url must be public HTTPS.",
"prereqItems": [
"Lottery API (lotterLaravel) and lottery H5 (lotteryfront) running",
"main-site running (default http://localhost:5173)",
"Integration site created in admin, or lottery .env MAIN_SITE_* aligned with main-site .env"
"Received site_code, sso_jwt_secret, wallet_api_key, lottery_h5_base_url",
"Main site implements GET /wallet/balance, POST /wallet/debit-for-lottery, POST /wallet/credit-from-lottery",
"Admin \"Integration Site\" has wallet_api_url and iframe_allowed_origins filled; connectivity test passed",
"At least one test site_player_id prepared with sufficient main_balance"
],
"stepItems": [
"Super admin creates integration site in admin (see Setup) and saves secrets",
"Copy secrets to main-site .env; set wallet_api_url and iframe_allowed_origins in admin",
"Log in on main-site → open lottery H5 in iframe (/player)",
"On LOTTERY_READY, send MAIN_INIT_TOKEN",
"Transfer-in inside lottery H5 → observe /wallet/debit-for-lottery callback",
"Place a bet in H5 after balance increases",
"(optional) transfer-out in H5 → observe /wallet/credit-from-lottery",
"Run acceptance curl checks for JWT and wallet gateway"
"Main-site server implements JWT issuance (see Single Sign-On jsonwebtoken example)",
"Self-test with curl: Bearer JWT call GET https://lotterylaravel.tanumo.com/api/v1/player/me, should return code=0",
"Main-site page embeds <iframe src=\"https://front.tanumo.com\">, listens for postMessage",
"After LOTTERY_READY, send MAIN_INIT_TOKEN (token at message top level; see iframe page example)",
"After H5 enters hall, initiate \"Transfer In\" in H5",
"Confirm main site receives POST /wallet/debit-for-lottery and returns success: true",
"Confirm in-lottery balance increases in H5, attempt a bet",
"(Optional) Transfer out in H5, confirm POST /wallet/credit-from-lottery is called back",
"Check off each item in the acceptance checklist below"
],
"accountRows": [
["alice", "alice123", "10001"],
["bob", "bob123", "10002"],
["demo", "demo123", "10003"]
],
"referenceItems": [
"Code: main-site/ in the monorepo (Next.js test shell)",
"Main site: http://localhost:5173; lottery H5: http://localhost:3800",
"See main-site README for env vars and postMessage protocol",
"Config mapping table on the Setup page"
],
"acceptance": "Acceptance checklist",
"acceptanceItems": [
"Sign JWT → curl GET /api/v1/player/me returns code=0",
"Self-test wallet debit: success:true and correct main_balance",
"Replay same idempotent_key: identical response, no double debit",
"iframe: after LOTTERY_READY receive MAIN_INIT_TOKEN and enter hall",
"H5 transfer-in: partner gateway logs show debit-for-lottery"
"JWT self-test: curl https://lotterylaravel.tanumo.com/api/v1/player/me returns code=0, data.site_player_id correct",
"Wallet self-test: curl POST /wallet/debit-for-lottery returns success:true, main_balance debited correctly",
"Idempotency: replay same idempotent_key, response identical to first call, no double debit",
"iframe: after LOTTERY_READY MAIN_INIT_TOKEN, can enter H5 hall",
"Transfer In: H5 transfer succeeds, main-site gateway logs show debit-for-lottery record",
"Token refresh: after JWT near expiry or LOTTERY_TOKEN_NEEDED triggered, MAIN_REFRESH_TOKEN succeeds"
]
},
"fundamentals": {
"title": "Money model",
"balances": "Two balances",
"calls": "Call directions",
"note": "All amounts use minor integers. Credit-line players are out of scope.",
"title": "Fund Model",
"balances": "Two-Tier Balances",
"calls": "Call Directions",
"note": "All amounts use minor integer units. Credit-line (agent credit) is out of scope for this document; this document covers main-site wallet mode only.",
"balanceRows": [
["main_balance", "Main wallet", "Partner gateway; lottery calls back"],
["lottery balance", "In-lottery balance", "Used for betting after transfer-in"]
["main_balance", "Main-Site Wallet", "Partner implements gateway; lottery server callbacks to debit/credit"],
["lottery balance", "In-Lottery Balance", "Used for betting after transfer-in; displayed and operated in lottery H5"]
],
"callRows": [
["Lottery → main", "balance / debit / credit", "wallet_api_key"],
["Lottery H5 → lottery API", "me / transfers / bets", "Player JWT (not main site)"]
["Lottery → Main Site", "GET balance / POST debit / POST credit", "Bearer wallet_api_key"],
["Lottery H5 → Lottery API", "me / transfers / bets / balance query", "Bearer player JWT (main site not involved)"]
]
},
"setup": {
"title": "Setup",
"description": "Secrets are shown once when the integration site is created. Store them immediately.",
"weProvide": "We provide",
"youProvide": "Partner provides",
"defaultPaths": "Default wallet paths",
"envMapping": "Config mapping",
"note": "Isolate test/prod site_code, secrets, and domains. Copy secrets into main-site .env manually. Local dev may use lottery .env MAIN_SITE_* as fallback.",
"title": "Integration Setup",
"description": "Our super admin creates an \"Integration Site\" in the admin console. Secrets are shown only once after creation — save them immediately.",
"weProvide": "Provided After Site Creation",
"youProvide": "Partner Must Fill In / Provide",
"defaultPaths": "Default Wallet Gateway Paths",
"envMapping": "Configuration Mapping Table",
"adminSop": "Admin Site Provisioning Steps (Our Super Admin)",
"network": "Network Requirements",
"note": "Test and production site_code, secrets, and domains must be fully isolated. Secrets are written to main-site server config — they are not auto-synced from admin to partner systems.",
"receiveRows": [
["site_code", "Site code"],
["site_code", "Site code, written into JWT"],
["sso_jwt_secret", "JWT signing secret (held by main site)"],
["wallet_api_key", "Wallet callback auth (validated by main site)"],
["lottery_h5_base_url", "Lottery entry URL"]
["lottery_h5_base_url", "Lottery H5 entry URL"]
],
"provideRows": [
["wallet_api_url", "HTTPS wallet base URL"],
["Test accounts", "site_player_id + initial balance"],
["iframe origin", "Parent origin when embedding"]
["wallet_api_url", "Partner wallet gateway HTTPS root URL (no path suffix)"],
["iframe_allowed_origins", "Main-site origin allowlist (iframe mode)"],
["Test Accounts", "site_player_id list + initial balance"]
],
"pathRows": [
["GET", "/wallet/balance", "Balance"],
["POST", "/wallet/debit-for-lottery", "Debit"],
["POST", "/wallet/credit-from-lottery", "Credit"]
["GET", "/wallet/balance", "Balance query"],
["POST", "/wallet/debit-for-lottery", "Debit (on transfer-in)"],
["POST", "/wallet/credit-from-lottery", "Credit (on transfer-out)"]
],
"envMappingRows": [
["site_code", "site_code", "MAIN_SITE_CODE", "JWT + player identity; must match"],
["SSO secret", "sso_jwt_secret", "MAIN_SITE_SSO_JWT_SECRET", "Main site signs; lottery verifies"],
["Wallet auth", "wallet_api_key", "MAIN_SITE_WALLET_API_KEY", "Lottery sends on callbacks; main site validates"],
["Wallet base URL", "wallet_api_url", "— (routes on main site)", "Partner HTTPS base; lottery appends /wallet/*"],
["Lottery entry", "lottery_h5_base_url", "NEXT_PUBLIC_LOTTERY_IFRAME_URL", "Redirect or iframe target"],
["iframe allowlist", "iframe_allowed_origins", "NEXT_PUBLIC_LOTTERY_ORIGIN", "Parent origin allowed to embed"],
["Lottery API", "—", "LOTTERY_API_BASE_URL", "Reference impl only"]
["site_code", "code", "MAIN_SITE_CODE", "JWT and player provisioning identifier; must match on both sides"],
["SSO Secret", "sso_jwt_secret", "MAIN_SITE_SSO_JWT_SECRET", "Main site signs JWT; lottery verifies"],
["Wallet Auth", "wallet_api_key", "MAIN_SITE_WALLET_API_KEY", "Lottery sends as Bearer on callbacks to main site"],
["Wallet Root URL", "wallet_api_url", "(Main-site deployment)", "Partner HTTPS root URL; lottery appends /wallet/*"],
["Lottery API", "—", "—", "Default https://lotterylaravel.tanumo.com; player/wallet API root"],
["Lottery H5", "lottery_h5_base_url", "(Main-site iframe src)", "Default https://front.tanumo.com"],
["iframe Allowlist", "iframe_allowed_origins", "(Main-site origin)", "Must match actual main-site origin"]
],
"adminSop": "Admin provisioning",
"adminSopSteps": [
"Super admin Config → Integration sites",
"Create site: code, name, currency",
"Set wallet_api_url (HTTPS root, no path), lottery_h5_base_url, iframe_allowed_origins (one origin per line)",
"Save sso_jwt_secret and wallet_api_key shown once at creation",
"Copy secrets to main-site .env; run connectivity test (probes GET /wallet/balance)",
"Local dev: use main-site/ reference; production wallet_api_url must be public HTTPS"
"Super admin logs into admin console → left sidebar \"Config\"\"Integration Sites\"",
"Click Create: fill site code (site_code), name, default currency",
"Fill wallet_api_url (HTTPS root), lottery_h5_base_url, iframe_allowed_origins",
"After creation, immediately save sso_jwt_secret and wallet_api_key shown on page",
"Securely deliver secrets to partner; partner configures on main-site server",
"Run \"Connectivity Test\" in site list (probes GET /wallet/balance)"
],
"adminFieldRows": [
["code", "Site code in JWT site_code", "demo"],
["wallet_api_url", "Partner wallet HTTPS base", "https://wallet.partner.com"],
["lottery_h5_base_url", "Lottery H5 entry URL", "https://lottery.partner.com"],
["iframe_allowed_origins", "Parent origins allowed to embed", "https://www.partner.com"],
["sso_jwt_secret", "Shown once at create", "—"],
["wallet_api_key", "Shown once at create", "—"]
["code", "Site code, written into JWT site_code", "partner_demo"],
["wallet_api_url", "Partner wallet gateway HTTPS root URL", "https://wallet.partner.com"],
["lottery_h5_base_url", "Lottery H5 entry", "https://front.tanumo.com"],
["iframe_allowed_origins", "Allowed main-site origins for embedding", "https://www.partner.com"],
["sso_jwt_secret", "Shown once at creation", "—"],
["wallet_api_key", "Shown once at creation", "—"]
],
"network": "Network",
"networkItems": [
"Wallet callbacks are server-to-server from lottery to partner — not from the browser",
"Production wallet_api_url: HTTPS public only (no localhost / private IP)",
"Default paths: /wallet/balance, /wallet/debit-for-lottery, /wallet/credit-from-lottery",
"Timeout ≤ 10s recommended; timeouts may enter pending reconcile"
"Wallet callbacks are initiated by lottery server (not player browser); partner gateway must be reachable from lottery servers",
"Production wallet_api_url must be public HTTPS (localhost / private IP not accepted)",
"Default paths /wallet/balance, /wallet/debit-for-lottery, /wallet/credit-from-lottery (path prefix configurable in admin)",
"Recommend endpoint timeout ≤ 10 seconds; timeout may cause transfer to enter pending reconciliation state"
]
},
"sso": {
"title": "SSO",
"description": "HS256 JWT. Main site signs; lottery verifies. Entry: URL redirect or iframe postMessage.",
"claims": "Claims",
"sign": "Sign",
"entryA": "Entry A — redirect",
"entryB": "Entry B — iframe",
"noExchangeNote": "Lottery has no token-exchange login API. After main-site login, sign a JWT and send Authorization: Bearer on player APIs. First valid call to GET /api/v1/player/me auto-provisions the player.",
"entryApi": "Entry API (lottery)",
"entryApiNote": "Optional: main site may call once server-side after login to verify JWT and provision (see main-site). Day-to-day play APIs are called by lottery H5.",
"publicApis": "Public APIs (no token)",
"h5ScopeNote": "Transfers, betting, and in-lottery balance are called by our H5 with the player JWT — out of scope for main-site integration. You only issue JWT and implement the wallet gateway.",
"partnerApis": "Main-site APIs (partner implements)",
"refreshNote": "iframe refresh: on LOTTERY_TOKEN_NEEDED, re-issue JWT and send MAIN_REFRESH_TOKEN. See main-site POST /api/auth/refresh.",
"authResponse": "Auth failure response",
"errors": "Errors",
"iframeNote": "Set iframe_allowed_origins. Do not resend LOTTERY_READY after token is delivered.",
"title": "Single Sign-On (SSO)",
"description": "HS256 JWT. Main-site server signs; lottery verifies. Entry: URL ?token= or iframe postMessage.",
"claims": "JWT Fields",
"sign": "Signing Example (Node.js)",
"entryA": "Method A: URL Redirect",
"entryB": "Method B: iframe postMessage",
"noExchangeNote": "Lottery does not provide a \"login-for-token\" API. After main-site login, sign JWT yourself; all subsequent player APIs use Authorization: Bearer with the same JWT. First valid JWT call to GET /api/v1/player/me auto-provisions the player — no separate login API required.",
"entryApi": "Verification and Provisioning",
"entryApiNote": "Optional: main-site server may call GET /api/v1/player/me once after login for JWT verification pre-check. Day-to-day business (transfers, betting) is called by lottery H5 with JWT — main site not involved.",
"publicApis": "Public APIs (No Token Required)",
"h5ScopeNote": "Transfers, betting, in-lottery balance queries, etc. are called by our H5 with player JWT — out of main-site integration scope. Main site only needs to: ① issue JWT implement wallet gateway.",
"refreshNote": "iframe token refresh: after LOTTERY_TOKEN_NEEDED or LOTTERY_TOKEN_REFRESH_REQUEST, re-issue JWT and send MAIN_REFRESH_TOKEN. See \"iframe Protocol\".",
"authResponse": "Authentication Failure Example",
"errors": "SSO Error Codes",
"iframeNote": "iframe_allowed_origins must be configured. Token is passed via postMessage top-level field token — do not nest inside payload.",
"claimRows": [
["site_code", "string", "Y", "Integration site code"],
["site_player_id", "string", "Y", "Stable main-site user ID"],
["iat", "number", "Y", "Issued at (seconds)"],
["exp", "number", "Y", "Expires (seconds); ≤ 300s"]
["site_code", "string", "Yes", "Integration site code, must match admin"],
["site_player_id", "string", "Yes", "Main-site user ID, stable and unique"],
["iat", "number", "Yes", "Issued at (Unix seconds)"],
["exp", "number", "Yes", "Expires at (Unix seconds); exp - iat ≤ 300"]
],
"messageRows": [
["→ main", "LOTTERY_READY", "Child ready"],
["→ main", "LOTTERY_TOKEN_NEEDED", "Refresh requested"],
["→ lottery", "MAIN_INIT_TOKEN", "{ token }"],
["→ lottery", "MAIN_REFRESH_TOKEN", "{ token }"]
["→ Main Site", "LOTTERY_READY", "Child page ready, requesting token"],
["→ Main Site", "LOTTERY_TOKEN_NEEDED", "Token expired, requesting refresh"],
["→ Lottery", "MAIN_INIT_TOKEN", "Top-level token field"],
["→ Lottery", "MAIN_REFRESH_TOKEN", "Top-level token field"]
],
"publicApiRows": [
["GET", "/api/v1/player/ping", "Player API connectivity probe"],
["GET", "/api/v1/integration/runtime-origins", "Allowed iframe parent origins"]
],
"partnerApiRows": [
["POST", "/api/auth/refresh", "(reference) Re-issue JWT for MAIN_REFRESH_TOKEN"]
["GET", "/api/v1/integration/runtime-origins", "Allowed iframe embed origin list"]
],
"errorRows": [
["8001", "Missing Authorization"],
["8002", "JWT invalid or expired"],
["8003", "Player not provisioned"],
["8004", "SSO secret not configured"],
["8005", "Account suspended"]
["8001", "Missing Authorization header"],
["8002", "JWT invalid or expired (secret mismatch, exp timeout, signature error)"],
["8003", "Player not provisioned (SSO first me call auto-provisions; this code mostly seen in internal testing)"],
["8004", "SSO secret not configured (site-side issue, contact us)"],
["8005", "Account suspended (site disabled or player frozen)"]
]
},
"iframe": {
"title": "iframe protocol",
"description": "postMessage contract when embedding lottery H5. Skip if using URL redirect only.",
"sequence": "Recommended sequence",
"envelope": "Message shape",
"childMessages": "Lottery → main",
"parentMessages": "Main → lottery",
"targetOrigin": "targetOrigin",
"envelopeNote": "JSON objects. Lottery sends LOTTERY_* types; main site sends MAIN_*. Include timestamp and source when possible.",
"targetOriginNote": "postMessage targetOrigin must be a specific origin (e.g. https://www.partner.com), never *. Main site validates event.origin against iframe_allowed_origins; lottery child validates parent origin against the allowlist.",
"timingNote": "After MAIN_INIT_TOKEN, do not send LOTTERY_READY again. Refresh: child sends LOTTERY_TOKEN_NEEDED or LOTTERY_TOKEN_REFRESH_REQUEST → parent replies MAIN_REFRESH_TOKEN.",
"title": "iframe Protocol",
"description": "postMessage contract when main site embeds lottery H5. Skip this chapter if using URL ?token= redirect only.",
"sequence": "Recommended Sequence",
"envelopeSection": "Message Format (Note Direction Differences)",
"childMessages": "Lottery → Main Site",
"parentMessages": "Main Site Lottery",
"example": "Main-Site Integration Example",
"targetOrigin": "targetOrigin Security",
"envelopeNote": "Common mistake: placing token in payload.token. Lottery H5 reads data.token at the message top level.",
"targetOriginNote": "postMessages second argument must be the lottery H5 origin (default https://front.tanumo.com), never *. Main site must validate event.origin; iframe_allowed_origins lists the main-site origin (not the lottery domain).",
"timingNote": "After MAIN_INIT_TOKEN, lottery child page no longer sends LOTTERY_READY. Refresh: LOTTERY_TOKEN_NEEDED → main site replies MAIN_REFRESH_TOKEN (top-level token).",
"sequenceSteps": [
"Embed <iframe src=\"{lottery_h5_base_url}\">",
"Lottery H5 loads allowlist then sends LOTTERY_READY",
"Parent validates origin and sends MAIN_INIT_TOKEN",
"H5 stores token and calls /api/v1/player/me",
"Before expiry: LOTTERY_TOKEN_NEEDED → parent sends MAIN_REFRESH_TOKEN"
"Main site embeds <iframe src=\"{lottery_h5_base_url}\">",
"Lottery H5 validates allowlist then sends LOTTERY_READY",
"Main site listens for message, validates origin, sends MAIN_INIT_TOKEN (top-level token)",
"Lottery H5 stores token, calls GET /api/v1/player/me to enter",
"JWT nearing expiry: lottery sends LOTTERY_TOKEN_NEEDED → main site refreshes and sends MAIN_REFRESH_TOKEN"
],
"envelopeRows": [
["Lottery → Main Site", "type + payload + timestamp", "e.g. LOTTERY_READY, business data in payload"],
["Main Site → Lottery", "type + token + timestamp", "token must be at top level, not nested in payload"]
],
"childMessageRows": [
["→ main", "LOTTERY_READY", "Child ready; request token"],
["→ main", "LOTTERY_TOKEN_NEEDED", "Token expired; request refresh"],
["→ main", "LOTTERY_TOKEN_REFRESH_REQUEST", "Active refresh request"],
["→ main", "LOTTERY_HEARTBEAT", "Heartbeat (optional)"],
["→ main", "LOTTERY_TOKEN_REFRESHED", "Refresh succeeded notice"]
["→ Main Site", "LOTTERY_READY", "Child page ready, requesting token"],
["→ Main Site", "LOTTERY_TOKEN_NEEDED", "Token expired, requesting refresh"],
["→ Main Site", "LOTTERY_TOKEN_REFRESH_REQUEST", "Active token refresh request"],
["→ Main Site", "LOTTERY_HEARTBEAT", "Heartbeat (may be ignored)"],
["→ Main Site", "LOTTERY_TOKEN_REFRESHED", "Refresh success notification (child → parent)"]
],
"parentMessageRows": [
["→ lottery", "MAIN_INIT_TOKEN", "{ token } initial"],
["→ lottery", "MAIN_REFRESH_TOKEN", "{ token } refresh"],
["→ lottery", "MAIN_REQUEST_STATUS", "Request child status"],
["→ lottery", "MAIN_NAVIGATE", "{ path } navigate"]
["→ Lottery", "MAIN_INIT_TOKEN", "Initial delivery; top-level token field"],
["→ Lottery", "MAIN_REFRESH_TOKEN", "Refresh; top-level token field"],
["→ Lottery", "MAIN_REQUEST_STATUS", "Request child page status"],
["→ Lottery", "MAIN_NAVIGATE", "Navigate to specified path"]
]
},
"wallet": {
"title": "Wallet gateway",
"description": "Partner implements. Lottery calls server-to-server. Auth: Bearer wallet_api_key.",
"balance": "GET balance",
"debit": "POST debit",
"credit": "POST credit",
"response": "Response",
"httpContract": "HTTP contract",
"httpErrors": "HTTP errors",
"creditNote": "Same body as debit; used for transfer-out or refund after failed transfer-in.",
"idempotentNote": "idempotent_key: same key + same operation must return the first JSON (HTTP 200); no double posting. Different operation/amount → success: false.",
"title": "Wallet Gateway",
"description": "Implemented by partner. Called by lottery server (not player browser). Auth: Authorization: Bearer {wallet_api_key}.",
"balance": "Query Balance",
"debit": "Debit (Transfer In)",
"credit": "Credit (Transfer Out)",
"response": "Response Example",
"httpContract": "HTTP Contract",
"httpErrors": "HTTP Errors",
"creditNote": "Request body same as debit; used for transfer-out or rollback credit on failure.",
"idempotentNote": "idempotent_key: same key + same amount must return first JSON (HTTP 200), no duplicate posting; same key different amount → success: false.",
"queryRows": [
["site_code", "string", ""],
["site_player_id", "string", ""],
["currency_code", "string", ""]
["site_code", "string", "Site code"],
["site_player_id", "string", "Main-site user ID"],
["currency_code", "string", "Currency code"]
],
"fieldRows": [
["site_code", "string", ""],
["site_player_id", "string", ""],
["player_id", "number", "Lottery player ID"],
["currency_code", "string", ""],
["amount_minor", "integer", "Positive minor units"],
["idempotent_key", "string", "Idempotency key"]
["site_code", "string", "Site code"],
["site_player_id", "string", "Main-site user ID"],
["player_id", "number", "Lottery player ID (reference)"],
["currency_code", "string", "Currency code"],
["amount_minor", "integer", "Positive minor integer"],
["idempotent_key", "string", "Idempotency key, globally unique"]
],
"httpErrorRows": [
["401", "unauthorized", "Invalid API key"],
["422", "invalid request", "Invalid fields/amount"],
["409", "main balance insufficient", "Business rejection; may include data.main_balance"]
["401", "unauthorized", "wallet_api_key incorrect or missing"],
["422", "invalid request", "Missing fields or invalid amount_minor"],
["409", "main balance insufficient", "Insufficient balance or other business rejection"]
],
"httpContractRows": [
["Debit/credit success", "200", "success: true; external_ref_no (recommended) + data.main_balance"],
["Balance success", "200", "success: true; data.main_balance + currency_code"],
["Invalid params", "422", "success: false; message: invalid request"],
["Unauthorized", "401", "success: false; message: unauthorized"],
["Business reject", "409", "success: false; message explains reason"],
["Idempotent replay", "200", "Identical JSON to first success/reject response"]
["Debit/credit success", "200", "success: true; includes external_ref_no (recommended) and data.main_balance"],
["Balance query success", "200", "success: true; data.main_balance + currency_code"],
["Invalid parameters", "422", "success: false; message: invalid request"],
["Authentication failure", "401", "success: false; message: unauthorized"],
["Business rejection", "409", "success: false; message explains reason"],
["Idempotent replay", "200", "Identical to first success/rejection response"]
]
},
"transfer": {
"title": "Transfers (reference)",
"description": "Internal: called by lottery H5, not a partner integration surface.",
"outOfScopeNote": "Partners do not implement these APIs. Transfer-in/out is invoked by our H5 with the player JWT; you only implement wallet gateway debit/credit. This page explains how funds move internally.",
"requestFields": "Request fields",
"transferIn": "transfer-in",
"transferOut": "transfer-out",
"transferResponse": "Success response",
"errors": "Common errors",
"inNote": "Flow: lottery calls debit-for-lottery → credits in-lottery balance.",
"outNote": "Flow: debits lottery balance → calls credit-from-lottery.",
"responseNote": "transfer-in and transfer-out share the same shape; direction is in / out. Idempotent replay returns the same data.",
"title": "Fund Transfers (Reference)",
"description": "This section explains how funds move between both sides — not a partner integration surface.",
"outOfScopeNote": "Partners do not implement APIs in this section. Transfer-in/out is called by our H5 with player JWT to lottery API; main site only implements wallet gateway debit/credit.",
"requestFields": "Request Fields",
"transferIn": "Transfer In (Main Site → Lottery)",
"transferOut": "Transfer Out (Lottery → Main Site)",
"transferResponse": "Success Response",
"errors": "Common Error Codes",
"inNote": "Flow: player H5 initiates transfer-in → lottery calls main site debit-for-lottery → credits in-lottery balance.",
"outNote": "Flow: player H5 initiates transfer-out → debits in-lottery balance → lottery calls main site credit-from-lottery.",
"responseNote": "Transfer-in and transfer-out share the same response structure; direction is in / out. Idempotent replay returns same data.",
"requestFieldRows": [
["amount", "integer", "Positive minor units"],
["amount", "integer", "Positive minor integer"],
["currency", "string", "Optional; defaults to player default_currency"],
["idempotent_key", "string", "Globally unique; retries return same result"]
["idempotent_key", "string", "Globally unique; retries must return same result"]
],
"errorRows": [
["1001", "Insufficient lottery balance (transfer-out)"],
["1009", "Main wallet operation failed"],
["1010", "Idempotency conflict (same key, different amount)"],
["1001", "Insufficient lottery balance (on transfer-out)"],
["1009", "Main-site wallet processing failed (gateway unreachable, 401, timeout, etc.)"],
["1010", "Idempotency key conflict (same key, different amount)"],
["2003", "Transfer in before betting"]
]
},
"errors": {
"title": "Errors",
"sso": "SSO",
"lotteryWallet": "Lottery wallet",
"gateway": "Wallet gateway (HTTP)",
"idempotentNote": "Idempotency: same idempotent_key must return the same result; different amount → 1010.",
"title": "Error Codes",
"sso": "SSO Authentication",
"lotteryWallet": "Lottery Wallet / Transfers",
"gateway": "Partner Wallet Gateway (HTTP)",
"idempotentNote": "Idempotency: same idempotent_key + same amount must return same result; same key different amount → 1010 or success:false.",
"ssoRows": [
["8001", "Missing Authorization"],
["8001", "Missing Authorization header"],
["8002", "JWT invalid or expired"],
["8003", "Player not provisioned"],
["8003", "Player not provisioned (SSO normal flow auto-provisions)"],
["8004", "SSO secret not configured"],
["8005", "Account suspended"]
],
"lotteryRows": [
["1001", "Insufficient lottery balance"],
["1009", "Main wallet operation failed"],
["1010", "Idempotency conflict"],
["2003", "Transfer in first"]
["1009", "Main-site wallet processing failed"],
["1010", "Idempotency key conflict"],
["2003", "Transfer in before betting"]
],
"gatewayRows": [
["401", "unauthorized", "Invalid API key"],
["422", "invalid request", "Invalid fields/amount"],
["409", "—", "Business rejection"]
["401", "unauthorized", "API Key incorrect"],
["422", "invalid request", "Invalid fields or amount"],
["409", "—", "Business rejection (e.g. insufficient balance)"]
]
},
"troubleshooting": {
"title": "Integration Troubleshooting",
"description": "Match symptoms below for troubleshooting. If unresolved, contact integration technical support with site_code, timestamp, and request ID.",
"faq": "Common Issues",
"jwt": "JWT / Entry",
"iframe": "iframe",
"wallet": "Wallet Gateway",
"note": "During integration, first verify JWT (/player/me) and wallet gateway (/wallet/balance) separately with curl, then test full iframe flow.",
"faqRows": [
["curl /player/me returns 8002", "Check sso_jwt_secret matches admin site; site_code matches; exp not expired (≤300 seconds)"],
["iframe blank screen / won't enter hall", "Check token is at postMessage top level; MAIN_INIT_TOKEN sent after LOTTERY_READY; iframe_allowed_origins includes main-site origin"],
["Transfer-in fails 1009", "Can lottery server reach wallet_api_url; wallet_api_key correct; debit returns 200 + success:true"],
["Connectivity test fails", "wallet_api_url must be public HTTPS; GET /wallet/balance reachable with Bearer wallet_api_key"],
["8005 account suspended", "Check integration site enabled in admin; site_player_id not frozen"]
],
"jwtRows": [
["8002 Token invalid", "Secret mismatch / exp expired / site_code wrong / algorithm not HS256"],
["8004 SSO not configured", "Contact us to confirm site sso_jwt_secret is configured"],
["me returns code=0 but H5 still fails", "iframe token differs from curl test token, or token nested in payload instead of top level"]
],
"iframeRows": [
["Not receiving LOTTERY_READY", "Is iframe src lottery_h5_base_url; has H5 finished loading"],
["postMessage no response", "Is targetOrigin lottery H5 origin (not main-site origin)"],
["Repeated token refresh loop", "After MAIN_INIT_TOKEN, child page should not send LOTTERY_READY again"],
["Refresh fails", "Is main site listening for LOTTERY_TOKEN_NEEDED and replying MAIN_REFRESH_TOKEN"]
],
"walletRows": [
["401 unauthorized", "wallet_api_key does not match admin site"],
["409 insufficient balance", "Test account main_balance insufficient; check amount_minor units"],
["Duplicate debit", "idempotent_key not idempotent; same key must return first response"],
["Lottery not calling debit", "wallet_api_url unreachable or connectivity test not passed"]
]
},
"golive": {
"title": "Go-live",
"checklist": "Checklist",
"title": "Go-Live Checklist",
"description": "Before production release, confirm integration testing passed with account manager and complete the following checks.",
"deliveryChecklist": "Delivery and Process",
"checklist": "Technical Checklist",
"deliveryItems": [
"Production integration site created independently (site_code, secrets isolated from integration)",
"Secrets securely written to main-site production config (not frontend)",
"wallet_api_url is production public HTTPS, connectivity test passed",
"iframe_allowed_origins configured with production main-site origin",
"Full integration test records archived (transfer-in → bet → winnings → transfer-out)"
],
"items": [
"Isolate test/prod site_code, secrets, domains",
"JWT server-side only, TTL ≤ 5min",
"Wallet HTTPS, timeout ≤ 10s",
"idempotent_key idempotency",
"iframe: configure iframe_allowed_origins",
"Full path: transfer-in → bet → settle → transfer-out"
"JWT issued server-side only, validity ≤ 5 minutes",
"Three wallet endpoints on HTTPS, timeout ≤ 10 seconds, idempotency implemented",
"iframe: postMessage token at top level, origin validation enabled",
"Test vs production: site_code, secrets, domains fully separated",
"Monitoring: wallet gateway 4xx/5xx and debit/credit log alerts",
"Rollback plan: integration site can be temporarily disabled"
]
}
}

View File

@@ -1,5 +1,6 @@
{
"title": "Players",
"pageGuide": "Wallet and credit players in one list; detail tabs adapt to funding_mode.",
"detailTitle": "Player details",
"listTitle": "Player list",
"viewDetail": "View details",

View File

@@ -1,6 +1,7 @@
{
"title": "Reports",
"subtitle": "Centralized operational, finance, risk, and audit reports with unified export filters.",
"pageGuide": "P&L and risk by draw, player, and play type; export permission enables async jobs.",
"exportPanel": "Export setup",
"chooseReport": "Choose a report to export",
"libraryTitle": "Report types",

View File

@@ -17,6 +17,8 @@
"allPoolsPageTitle": "All risk pools",
"sourceReasonOptions": {
"ticket_place": "Bet placement",
"ticket_rollback": "Ticket rollback",
"ticket_failed_line": "Failed bet release",
"admin_manual_close": "Manual close",
"admin_manual_recover": "Manual recover"
},
@@ -25,6 +27,7 @@
"riskFilter": "Risk filter",
"sort": "Sort",
"filterAll": "All",
"filterActive": "Active / high risk",
"filterSoldOut": "Sold out",
"filterHighRisk": ">80%",
"sortUsageDesc": "Usage ratio ↓",
@@ -73,6 +76,15 @@
"playCode": "Play",
"loadLogsFailed": "Failed to load lock logs",
"lockLogsTitle": "Risk lock logs",
"lockLogsGroupedHint": "Grouped by ticket by default. Expanded plays (e.g. 2A) show combination detail on the ticket page.",
"groupBy": "View",
"groupByTicket": "By ticket",
"groupByEntry": "By number",
"combinationCount": "Combinations",
"lockReleaseSummary": "Lock / release rows",
"viewDetail": "Detail",
"viewTicket": "Ticket",
"number": "Bet number",
"drawInfoLoadFailed": "Failed to load draw info",
"loadingDraw": "Loading draw…",
"headerTitle": "Risk · Draw {{drawNo}}",

View File

@@ -1,6 +1,7 @@
{
"title": "Settlement center",
"subtitle": "Period close, bill confirm, and payments",
"pageGuide": "Credit-line agent periods: site finance opens/closes; bound agents view own bills and record payments as payee only.",
"subtitleList": "Period list: open/close periods; summary columns included — use row actions for bills and bet ledger.",
"period": {
"title": "Period",

View File

@@ -47,5 +47,16 @@
"settled_lose": "Settled loss",
"refunded": "Refunded"
},
"allTickets": "All tickets"
"allTickets": "All tickets",
"detailTitle": "Ticket detail",
"detailLoadFailed": "Failed to load ticket detail",
"loadingDetail": "Loading…",
"backToList": "Back to ticket list",
"viewTicketDetail": "View ticket detail",
"combinationCount": "Expanded combinations",
"combinationsTitle": "Combination breakdown",
"combinationsHint": "One bet line may expand into multiple 4D numbers for risk and settlement.",
"number4d": "4D number",
"comboBetAmount": "Combo bet",
"comboEstimatedPayout": "Est. payout reserve"
}