Polyflight overview and launch
Polyflight overview and launch
Polyflight is a separate product inside the existing OpenPoly Mini App platform. It reuses the same operator identity, launch/session security, wallet adapter, webhook delivery, and dashboard. It does not use Opinion markets, shares, order pricing, or settlement formulas.
All participants join the same global flights. First-party Polynion users fund tickets with Credits; enabled Mini App users fund tickets directly in IDR through their operator wallet. A flight has one shared board, lock, result, and public proof.
For the player screens and a worked ticket example, see Player experience.
Adding Polyflight to an existing Opinion integration
Keep your existing launch endpoint, operator user IDs, Wallet Adapter URL and credentials, and signed webhook receiver. Add only the product-specific handling:
| Area | What to add |
|---|---|
| Onboarding | Ask Polynion to enable Polyflight for your IDR operator and confirm the settlement timezone and terms. |
| Launch | Send product: "polyflight" from your backend. Omitted product still launches Opinion. |
| Wallet | Accept the five Polyflight reasons and native metadata on the existing debit, credit, and debit-reversal paths, including exactly zero /credit for loss acknowledgement. |
| Webhooks | Subscribe to the eight Polyflight event types; continue deduplicating by event_id. |
| Staff and API keys | Assign the required Polyflight read scopes. Existing restricted access is not automatically expanded. |
| Reconciliation | Keep native-IDR tickets, liabilities, and Polyflight statements separate from Opinion reporting. |
Do not create a second player balance, convert the stake to Credits, or apply Opinion trading fees to a Polyflight purchase.
Enablement boundary
Polyflight must be enabled for the operator before it can be launched. Enablement records:
- native currency
IDR; - a settlement timezone copied from the operator's timezone at enablement and then fixed for Polyflight statements;
- the initial fee-share and position-share terms;
- the enabling administrator, reason, and time.
Only Polynion administrators can enable the product or schedule commercial-term changes. Operator staff and API keys have read-only access to terms and their history.
Launch request
Use the existing endpoint:
POST /api/operator/launch
Required scope: launch:write.
Select Polyflight with the additive product field:
{
"external_user_id": "operator-user-123",
"display_name": "Rina",
"locale": "id",
"product": "polyflight",
"metadata": {}
}
Allowed values are opinion and polyflight. Omitting product preserves the existing opinion default. A Polyflight launch is rejected when the product is not enabled for the authenticated operator; it never silently falls back to Opinion.
The response remains the existing launch response with a short-lived, single-use launch_url, expires_at, and the linked operator_user. The launch token is redeemed by the assigned Mini App host and creates the same host-bound, CSRF-protected session used by Opinion.
The URL first opens /launch?token=...&redirect=%2Fpolyflight; it does not bypass token redemption. Pass it to the player unchanged. See Launch API for a backend request example.
Product-aware launch and redeem/bootstrap responses expose validated product, operator enabled_products, and server-selected redirect_path. The Launch API selects /polyflight for Polyflight and / for Opinion. Server-generated portfolio Trade links can preserve an allowed Polyflight flight-detail or Opinion market-detail path. Missing, invalid, or absolute redirect metadata falls back to the product's root (/polyflight or /). Follow the returned path; caller-supplied metadata cannot select an arbitrary destination.
Product switching
An authenticated Mini App session may switch between enabled products without a new operator login. Product-specific routes keep wallet and ticket state separate:
- Opinion remains the default experience and keeps its existing behavior.
- Polyflight uses
/polyflightfor the live board and ticket panel,/polyflight/{flightCode}for details,/polyflight/history, and/polyflight/black-box/{flightCode}. - When separately available in the target environment, Polyflight Pro uses
/polyflight/pro,/polyflight/pro/{flightCode},/polyflight/pro/history, and/polyflight/pro/black-box/{flightCode}. It reuses the existing Polyflight product entitlement, operator IDR wallet and terms; no new launch-product value is required. Environment-level Pro availability and global entry controls also apply. Repository configuration is not evidence of live production activation. - A Polyflight ticket never creates an Opinion order or market position.
The interface uses the saved locale cookie first, then the operator's default_locale, then the Mini App's runtime language (English by default). The launch request's locale is stored as user metadata; it does not override the interface's saved-language precedence.
Pro offers origin/destination/date search over fictional game schedules, not airline timetables. Use the current catalogue rather than promising a fixed city count or departure frequency. Advance booking opens at origin-local midnight seven calendar dates before departure and closes five minutes before arrival. Native-IDR buying requires a polyflight-pro-v2 flight with a valid frozen comparison valuation; historical Pro v1 flights remain Credits-only. See Player experience for search and clock guidance.
Native-IDR ticket contract
| Rule | Value |
|---|---|
| Currency | IDR only |
| Minimum stake | 1,000 IDR |
| Stake step | 1,000 IDR |
| Technical maximum per ticket | 565,127,000 IDR |
| Ticket fee | 500 BPS (5%) included in the stake |
| Winning payout | 4 × net stake |
| Cancelled-flight refund | Full original debit, including fee |
IDR uses whole-rupiah integer minor units here: amount_minor: 10000 means 10,000 IDR, not 100 IDR. Do not multiply or divide these values by 100.
For stake $S$:
fee = 5% × S
net stake = S - fee
winning payout = 4 × net stake
A 10,000 IDR ticket therefore has a 500 IDR fee, 9,500 IDR net stake, and 38,000 IDR potential payout. The potential payout is the total winning credit, not 38,000 plus return of stake.
No purchase or payout conversion occurs. Polyflight does not apply the Opinion fx_fee_bps, buy/sell premiums, or operator_fee_bps to the user's ticket. The separately frozen Indodax rate is used only to compare IDR and Credits activity inside the shared flight; see Mixed-money proof and comparison.
Purchase failures and wallet reconciliation
The player-facing purchase state is separate from the internal wallet reconciliation state:
| Wallet outcome | Player message | Internal handling |
|---|---|---|
| Confirmed debit rejection | Purchase failed — ticket not issued | Purchase ends as failed |
| HTTP 5xx, timeout, or another unconfirmed debit outcome | Payment not confirmed — ticket not issued; check with the wallet provider before retrying | Wallet operation remains held for evidence-based reconciliation |
Failed and unconfirmed purchases appear as notices with a purchase reference, not as active tickets or pending ticket counts. Unconfirmed purchases continue refreshing so a later reconciliation is reflected in the Mini App.
An HTTP 500 alone is not proof that the user's wallet was not debited. Verify the operator ledger against the original debit idempotency key before confirming applied/not-applied or authorizing original-key resumption. Do not retry a closed flight's debit to recover an unissued ticket.
For staff debugging, balance-operation detail retains request evidence, the operator's JSON response (including any supplied diagnostics), non-JSON response bodies under evidence.responseJson.raw, failure reason, attempt count, and state version. Mutation responses are bounded to 1 MiB; oversized or incomplete responses remain uncertain rather than being accepted as wallet receipts. Use Polyflight → Wallet operations → Details or the operator balance-operations detail API for evidence.requestJson, evidence.responseJson, and evidence.failureReason. The request ID is a tracing aid, not the financial idempotency key. Keep sensitive diagnostic content out of player messages and redact it before sharing support evidence.
Operator launch checklist
- Confirm Polynion has enabled Polyflight and the current terms are visible under Polyflight → Commercial terms.
- Assign only the required read scopes to reporting integrations.
- Confirm the existing wallet adapter accepts all Polyflight reasons and additive metadata.
- Confirm the webhook receiver accepts all
mini_app.polyflight.*events and deduplicates byevent_id. - In staging, use Simulator → Users to create or select a dedicated simulator user, then Simulator to launch
polyflightthrough the real launch URL. - Do not change the operator-wide
rest_v1adapter to simulator mode. Simulation is user-scoped. - Treat simulator acceptance and real external-wallet certification as separate evidence.
Production enablement, production wallet activity, and production deployment require separate explicit authorization. A successful staging launch is not production approval.
