Агуулгыг алгасах

Өөрийн iOS / Android апп-аас төлүүлэх

Энэ хуудсаар

Юу хийх: таны мобайл апп хүнийг Gerege App руу төлөхөөр илгээж, төлсний дараа таны апп руу буцаана. Хугацаа: ~2 цаг. Хэрэгтэй: вэб checkout-ийн backend тал (яг ижил redirect intent), таны апп-ын Universal Link (iOS) / App Link (Android) host.

Мобайл апп бол вэб дэлгүүрийн нэг хувилбар: intent-ийг таны backend үүсгэнэ, апп зөвхөн pay_url-ийг нээж, буцаж ирэхэд backend-ээсээ үр дүнг асууна. Client secret апп-д хэзээ ч орохгүй — апп-ын binary-г хэн ч задалж уншина.

1. Урсгал

Таны апп            Таны backend              Gerege                 Gerege App
  │ «Төлөх»            │                          │                        │
  │─ POST /orders/7/pay▶│ POST /payment-intents    │                        │
  │                    │ redirect, return_url =   │                        │
  │                    │ https://app.shop.mn/paid │                        │
  │                    │─────────────────────────▶│                        │
  │◀── {pay_url} ──────│◀──── {id, pay_url} ──────│                        │
  │── open(pay_url) ── Universal Link ─────────────────────────────────────▶│ claim → Face ID → төлнө
  │◀────────── open(https://app.shop.mn/paid?pi=pi_…) — таны Universal Link ─│
  │─ GET /orders/7 ────▶│ GET /payment-intents/{id}│                        │
  │◀── {paid: true} ───│◀─────────────────────────│                        │

2. Тохиргоо

  1. Буцах хаяг = таны апп-ын Universal Link. return_url нь https:// байх ёстой (custom scheme shopapp://… зөвшөөрөгдөхгүй — ямар ч апп тэр scheme-ийг бүртгэж чаддаг). Тиймээс https://app.shop.mn/paid гэх мэт өөрийн host-ыг:
  2. iOS: apple-app-site-association-д applinks (/paid* зам) + апп-ын Associated Domains applinks:app.shop.mn;
  3. Android: assetlinks.json + intent-filter android:autoVerify="true".
  4. Тэр host-ыг апп-ын return_hosts-д нэмнэ (вэб checkout §2).
  5. Апп суугаагүй үед Universal Link таны вэб хуудсыг нээнэ — тэр хуудас нь вэб checkout-ийн done хуудастай адил серверээр шалгаж харуулна.

3. Backend: intent үүсгэх

Апп таны backend-ийн өөрийн route-ыг дуудна (POST /orders/{id}/pay, апп-ын хэрэглэгчийн session-оор). Backend нь вэб checkout §3-тай яг ижил redirect intent үүсгэж зөвхөн pay_url-ийг буцаана:

{ "amount": 45000, "description": "Захиалга ord_8812", "reference": "ord_8812", "expires_in": 900,
  "presentment": "redirect", "return_url": "https://app.shop.mn/paid?order=ord_8812" }

4. Апп: pay_url-ийг нээх

pay_url-ийг системийн нээлтээр нээнэ — Universal Link зөвхөн тэгэхэд Gerege App-ыг нээдэг. WKWebView, SFSafariViewController, апп доторх browser дотор нээвэл Gerege App нээгдэхгүй, вэб хуудас үлдэнэ.

iOS (Swift):

// Таны backend-ээс ирсэн pay_url. Gerege App суусан бол тэр нээгдэнэ, үгүй бол Safari (QR / суулгах хуудас).
UIApplication.shared.open(payURL)

Android (Kotlin):

// Gerege App-ын Android хувилбар түр зогссон: одоогоор браузер pay_url-ийн вэб хуудсыг нээнэ.
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(payUrl)))

5. Буцаж ирэх

Gerege App төлсний дараа return_url?…&pi=pi_…-ийг нээнэ → таны Universal Link → таны апп. Апп URL-ээс зөвхөн захиалгын дугаарыг уншаад backend-ээсээ асууна (URL-ийг хэн ч бичиж чадна):

.onOpenURL { url in
    guard url.host == "app.shop.mn", url.path == "/paid",
          let order = URLComponents(url: url, resolvingAgainstBaseURL: false)?
              .queryItems?.first(where: { $0.name == "order" })?.value else { return }
    Task { await model.refreshOrder(order) } // таны backend → GET /payment-intents/{id} → paid?
}

Backend-ийн шалгалт ба төлөв бүрт юу харуулах нь вэб checkout §5-тай ижил.

6. Апп руу гараар буцаж ирэхэд

Хүн Gerege App-аас таны апп руу app switcher-ээр буцаж магадгүй (return_url нээгдээгүй). Тиймээс захиалга «төлөгдөж байна» төлөвт байх үед апп foreground болох бүрт (scenePhase == .active, Android onResume) backend- ээсээ төлвийг асууна. Webhook-оор backend аль хэдийн мэдсэн байх магадлалтай.

7. Аюулгүй байдал

  • Client secret, webhook secret — зөвхөн backend-д. Апп таны backend-д өөрийн session-оор л хандана.
  • Дүнг апп илгээхгүй: апп «захиалга 7-г төлөх» гэнэ, дүнг backend каталогоос тооцно.
  • pay_url — тухайн хүнд л: push мэдэгдэл, share sheet, аналитик лог-д оруулахгүй.
  • Буцах URL-д итгэхгүй; pi зөвхөн сануулга.

8. Хэрэгжилтийн төлөв

Хэсэг Төлөв
Backend тал (redirect intent, return_url?pi=, webhook) ✓
Gerege App iOS: pay_url-ийг Universal Link-ээр нээх, төлсний дараа return_url-ийг UIApplication.open-оор нээх ✓ (Universal Link — цөмийн AASA /pay/* production-д гармагц)
Gerege App суугаагүй утсанд вэб хуудас (суулгах холбоостой) «удахгүй»
Android Gerege App түр зогссон