Skip to content

A mini app inside Gerege App

What you will do: turn your web app into a mini app that opens inside Gerege App, get the person's sign-in (launch → token), and ask for a payment through the bridge. Time: about 30 minutes (if your web app is already on https). What you need: §0–§2 of the Quickstart (an organisation, «Mini апп-ууд», a console session), an https origin, a backend.

A mini app is your web app, listed in Gerege App's launcher and opened inside the app (WKWebView). How it differs from a merchant: Merchants and mini apps. The standard is Gerege's implementation of OMAS 1.0 — a backend written for OMAS works by changing its values only.

1. Register

curl -sS "$GEREGE/dev/apps" -H "Authorization: Bearer $GEREGE_SESSION" -H 'Content-Type: application/json' \
  -d '{"slug": "my-esim", "name": "My eSIM", "entry_url": "https://esim.example.mn/app",
       "category": "travel", "developer_name": "Example LLC"}' | tee app.json | jq '{id, slug, test_client_id, live_client_id, verification_token}'
export APP_ID=$(jq -r .id app.json)

The console's (/apps/miniapp) register sheet does the same. Registering issues mapp_… (live) and mapp_test_… (test) client ids and an omas-verify=… token. The app is a draft; its scope is profile.basic — to take payments, add payments with a PATCH (while it is a draft).

2. Publish and check the manifest

Publish /.well-known/gerege-miniapp.json on your origin (every field: Manifest):

{
  "omas_version": "1.0",
  "slug": "my-esim",
  "client_id": "mapp_…",
  "version": "1.0.0",
  "name": { "mn": "Миний eSIM", "en": "My eSIM" },
  "entry": "https://esim.example.mn/app",
  "origins": ["https://esim.example.mn"],
  "icons": [{ "src": "https://esim.example.mn/icon-512.png", "size": 512 }],
  "scopes": ["profile.basic", "payments"],
  "bridge": { "min_version": 1, "methods": ["getContext", "getLaunchCode", "requestPayment", "close"] },
  "legal": { "privacy_url": "https://example.mn/privacy", "terms_url": "https://example.mn/terms", "support_url": "https://example.mn/help" },
  "verification": "omas-verify=…"
}
curl -sS -X POST "$GEREGE/dev/apps/$APP_ID/manifest/check" -H "Authorization: Bearer $GEREGE_SESSION" | jq

The check proves the origin is yours (verification) and probes a 512×512 PNG icon and the three legal pages (answering 200). Before you deploy, POST /dev/manifest/validate checks a manifest sent as the body.

3. Test credentials and test users

curl -sS "$GEREGE/dev/apps/$APP_ID/keys" -H "Authorization: Bearer $GEREGE_SESSION" \
  -H 'Content-Type: application/json' -d '{"name": "backend", "environment": "test", "preset": "miniapp_backend"}' \
  | jq '{client_id, client_secret, scopes}'

The «Mini app backend» preset = oauth:token, payments:read, payments:write, refunds:write.

A draft app is seen and opened in Gerege App's launcher by the person who registered it and its test users (active members of your organisation, ≤ 50); their launch codes are redeemed with the test credential and no money moves. Add a test user: POST /dev/apps/{id}/test-users {"email"} (Developer sandbox).

4. Launch → token

Gerege App opens the app at entry?launch=<code>. The frontend reads launch from the URL, removes it from history and sends it to your backend; the backend exchanges the single-use code for tokens:

curl -sS "$GEREGE/oauth/token" -u "$GEREGE_CLIENT_ID:$GEREGE_CLIENT_SECRET" \
  -d grant_type=authorization_code -d code=gml_…
{ "token_type": "Bearer", "access_token": "gma_at_…", "expires_in": 1800, "refresh_token": "gma_rt_…",
  "scope": "profile.basic payments",
  "user": { "ref": "u_9f2c…", "sub": "u_9f2c…", "verified": true, "locale": "mn" } }

The code lives 60 seconds and works once; sub is a pseudonymous id that is stable for your app. Details (refresh rotation, /me, consent, requires_verified/min_age): Mini app launch and tokens.

5. Ask for a payment

The backend creates the intent with the person's token (presentment: "app" — the default) and the frontend opens the payment sheet through the bridge:

curl -sS "$GEREGE/payment-intents" -H "Authorization: Bearer gma_at_…" \
  -H 'Content-Type: application/json' -H 'Idempotency-Key: order-77' \
  -d '{"amount": 45000, "description": "eSIM 7 days", "reference": "order-77"}' | jq '{id, status}'
const res = await window.gerege.requestPayment({ intentId: "pi_…" });
// res.status: "succeeded" | "canceled" | "failed" — DO NOT TRUST IT: verify on the backend with GET or the webhook

The whole payments API, manual capture, refunds: Mini app payments. Every bridge method: Bridge. Webhooks: Webhooks (required for an app with the payments scope).

6. Review and publishing

POST /dev/apps/{id}/submit — needs a checked manifest, privacy/terms/support links, a live secret and (with payments) a webhook URL; during review the app is frozen. Once approved it is listed for everyone; where it appears on the launcher's home screen is the operator's layout. The full list: Review requirements. The states (draft → in_review → approved | rejected, suspended): Test and live.