Төлбөрийн амьдралын мөчлөг¶
Payment intent (
pi_…) бол нэг төлбөрийн хүсэлт ба түүний төлөв. Энэ хуудас: бүх төлөв, шилжилт бүрийг хэн өдөөх, ямар webhook ирэх, барьцаа (hold) ба capture-ийн хугацаанууд.
1. Төлвийн диаграм¶
create — POST /payment-intents
│
▼
┌──────────▶ requires_confirmation ── expires_at өнгөрөв ───────────────▶ expired
│ │ │ (claimless: claim → хүн тодорхой; 90 с-д confirm хийхгүй бол claim суларна)
│ │ └────────── cancel (та эсвэл хүн) ────────────▶ canceled
│ confirm (хүн: данс + Face ID)
│ ▼
│ processing live: дэвтрийн дуудлага явж байна — дахин бүү төлүүл, дахин унш
│ ┌─────────┼──────────────────────────┐
│ дэвтэр automatic: manual:
│ татгалзав hold + capture hold
│ ▼ ▼ ▼
└──── failed succeeded ◀── capture ── requires_capture ── cancel ──▶ canceled (барьцаа буцна)
дахин confirm, │ (та) │
эсвэл expired / │ capture_before өнгөрөв ─────────▶ expired (authorization_expired)
canceled ▼ refund (та, 90 хоног)
partially_refunded ── refund ──▶ refunded
Test горимд processing алгасагдана: confirm шууд дүнгээр шийдэгдэнэ — …01 → failed (test_declined), …02 →
canceled, manual → requires_capture, бусад → succeeded.
2. Төлөв бүр¶
| Төлөв | Утга | Дараагийнх | Төгсгөл үү |
|---|---|---|---|
requires_confirmation |
Үүссэн, хүн төлөөгүй. Claimless бол claim хүртэл хүнгүй (user_ref: null) |
processing, canceled, expired (test: шууд үр дүн) |
— |
processing |
Live: Gerege дэвтэртэй (core banking) ярьж байна — барьцаа эсвэл capture. Хариу нь 202 байж болно |
requires_capture, succeeded, failed, expired |
— |
requires_capture |
Manual: мөнгө хүний дансанд барьцаалагдсан, capture_before хүртэл |
succeeded (capture), canceled (cancel), expired |
— |
succeeded |
Төлөгдсөн; мөнгө таны payout данс эсвэл клиринг руу орсон | partially_refunded, refunded |
бараг (буцаалт л) |
partially_refunded |
Хэсэгчлэн буцаасан (refunded_amount < amount) |
refunded |
бараг |
refunded |
Бүтэн буцаасан | — | ✓ |
failed |
Дэвтэр татгалзсан (failure_code: insufficient_funds, limit_exceeded, test_declined, …). Төлөгдөх боломжтой хэвээр — хүн өөр данс/дахин оролдоно |
processing, canceled, expired |
— |
canceled |
Та эсвэл хүн цуцалсан; manual бол барьцаа суллагдсан (буцаалт биш, шимтгэлгүй) | — | ✓ |
expired |
Хугацаа дууссан: төлөөгүй (expires_at) эсвэл capture хийгээгүй (capture_before, failure_code: "authorization_expired") |
— | ✓ |
Хүний сонгосон данснаас төлөх боломжгүй (account_unavailable) бол intent failed болохгүй — requires_confirmation
руу чимээгүй буцна (хүн буруу данс сонгосон, төлбөр бүтэлгүйтээгүй), webhook ирэхгүй.
3. Шилжилт ба webhook¶
| Шилжилт | Хэн | Webhook |
|---|---|---|
| үүсэх | таны backend | — |
| claim (claimless) | хүн (Gerege App) | payment_intent.claimed |
→ requires_capture |
хүн confirm (manual) | payment_intent.requires_capture |
→ succeeded |
хүн confirm (automatic) эсвэл та capture (manual) | payment_intent.succeeded |
→ failed |
дэвтэр | payment_intent.failed |
→ canceled |
та (POST …/cancel) эсвэл хүн |
payment_intent.canceled |
→ expired |
платформ (job) | claimless: payment_intent.expired; app: payment_intent.canceled + status: "expired" (OMAS-ын нийцэл) |
| буцаалт | та (POST …/refunds) |
refund.succeeded · refund.failed |
Webhook at-least-once, дараалал баталгаагүй: id-аар давхардлыг арилгаж, status-аар шийднэ; чухал алхмын
өмнө GET /payment-intents/{id}-ээр дахин уншина. Event бүрийн схем: Webhook.
4. Барьцаа ба capture¶
Gerege-д төлбөр бүр барьцаагаар явна: confirm хийхэд хүний Gerege Wallet дансанд мөнгө түгжигдэнэ (hold), дараа нь capture (авах) эсвэл release (буцаах).
capture_method |
Юу болох | Хэзээ |
|---|---|---|
automatic (анхдагч) |
confirm → барьцаа → шууд capture → succeeded |
бараа/үйлчилгээг шууд өгөх (онлайн дэлгүүр, касс) |
manual |
confirm → барьцаа → requires_capture; та capture эсвэл cancel |
мөнгийг зөвхөн өгсний дараа авах (вендинг, захиалга бэлдэх, түрээс) |
Яагаад вендинг manual вэ. Машин бараагаа гаргаж чадах эсэхээ төлбөрийн дараа л мэднэ (гацсан, дууссан, сүлжээ тасарсан). Automatic бол гараагүй бүрт буцаалт хийх ёстой — хүний мөнгө хэдэн минут хөдөлж, буцаалтын бичилт үлдэнэ. Manual бол:
- гарсан →
capture→succeeded; - гараагүй →
cancel→ барьцаа шууд суллагдана — мөнгө хэзээ ч хүний данснаас гараагүй, буцаалт биш; - хэсэгчлэн → бүтэн
capture+ гараагүй хэсгийн буцаалт (дүнтэй хэсэгчилсэн capture — «удахгүй»); - машин хариугүй →
capture_beforeөнгөрөхөд барьцаа хүнд өөрөө суллагдана (payment_intent.expired).
5. Хугацаанууд¶
| Хугацаа | Утга | Хязгаар | Анхдагч |
|---|---|---|---|
expires_in → expires_at |
Хүн төлөх (confirm) хугацаа | 60–1800 с | 600 с |
| claim-ийн хугацаа | Баталгаажаагүй claim өөр хүнд шилжих | 90 с (тогтмол) | — |
capture_within → capture_before |
Manual: confirm-оос хойш capture хийх хугацаа | 60–604 800 с (7 хоног) | 604 800 с |
| барьцааны нөөц хугацаа | Дэвтэр дэх hold-ын хугацаа = capture_before + цонхны хагас (≥ 1 мин, ≤ 15 мин); automatic: expires_at + 15 мин |
— | — |
| буцаалтын хугацаа | Төлбөрөөс хойш буцаах боломжтой | 90 хоног | — |
capture_within-ийг машины сүлжээний найдвартай байдлаар сонгоно: машин «гарлаа» гэдгээ таны backend-дcapture_before-оос өмнө хүргэх ёстой. Түүнээс хойш capture боломжгүй (409 expired) — бараа өгсөн ч мөнгө аваагүй үлдэнэ. Вендингт 60–300 с ердийн.- Нөөц хугацаа нь зөвхөн платформ барьцааг өөрөө суллаж чадаагүй (сүлжээ, гацаа) тохиолдолд дэвтэр өөрөө суллахад;
ердийн үед job
capture_beforeдээр суллана. Хүний мөнгө хэзээ ч хугацаагүй түгжигдэхгүй. failedintentexpires_atхүртэл дахин төлөгдөж болно.
6. processing ба давталт¶
Live-д дэвтрийн хариу тодорхойгүй (сүлжээ, timeout) бол intent processing-д үлдэж, хариу 202 Accepted байж болно.
Энэ нь алдаа биш: дуудлага нь intent-д бичигдсэн түлхүүртэйгээ, платформ өөрөө дахин асууж дуусгана. Та:
- хэзээ ч шинэ intent үүсгэж «дахин төлүүлэхгүй»;
GET /payment-intents/{id}-ээр (эсвэл webhook-оор) эцсийн төлвийг хүлээнэ;- capture, cancel, refund-ийг ижил хүсэлтээр давтаж болно — idempotent (Давталт).