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

Барьцаа (manual capture)

Энэ хуудсаар

Юу хийх: хүн баталмагц мөнгийг барьцаалж, бараа/үйлчилгээ өгсний дараа л авах (capture) эсвэл суллах (cancel). Хугацаа: ~30 мин. Хэрэгтэй: intent үүсгэдэг backend (вэб, QR, терминал эсвэл mini app).

1. Хэзээ manual

Тохиолдол Яагаад
Вендинг машин, locker, түлшний колонк бараа гарах эсэх төлбөрийн дараа мэдэгдэнэ (вендинг)
Захиалгаар хийх хоол, нөөцөөс хамаарах бараа бэлэн болох эсэх тодорхойгүй
Түрээс, барьцаа эцсийн дүн хожим

Бусад үед automatic (анхдагч): хүн баталмагц succeeded.

2. Урсгал

requires_confirmation ──хүн баталсан──▶ processing ──hold──▶ requires_capture ──capture──▶ succeeded
                                                                  │
                                                                  ├──cancel──▶ canceled   (hold суллагдана)
                                                                  └──capture_before өнгөрсөн──▶ expired
                                                                       (failure_code: authorization_expired, hold суллагдана)
{ "amount": 12000, "description": "Захиалга #5521", "reference": "5521", "presentment": "qr",
  "capture_method": "manual", "capture_within": 900 }
  • capture_within — баталснаас хойш хэдэн секундэд capture/cancel хийх: 60 – 604 800 (7 хоног), анхдагч 7 хоног. Зөвхөн manual-д (automatic-д өгвөл 400 validation_error). Mini app-ын (app) intent-д ч болно.
  • Баталмагц capture_before = баталсан агшин + capture_within; payment_intent.requires_capture webhook.

3. Capture, cancel, хэсэгчлэн

  • Capture — POST /payment-intents/{id}/capture (бие хоосон) → succeeded; live-д дэвтэр хариулаагүй бол 202 + processing (дараа нь GET). Аль хэдийн capture хийсэнийг дахин → 200 тэр intent. requires_capture биш бол 409 not_capturable (payment_intent-тэй); capture_before өнгөрсөн бол 409 expired.
  • Cancel — POST /payment-intents/{id}/cancel → canceled, hold суллагдана (буцаалт биш: хүнд юу ч хасагдаагүй). Дэвтрийн суллалт хоцорсон ч цуцлалт хүчинтэй — платформ мөнгийг буцаах хүртэл давтана.
  • Хэсэгчлэн — дүнтэй capture ({amount}) «удахгүй». Одоо: бүтэн capture → succeeded болтол хүлээх → POST …/refunds {"amount": <өгөөгүй хэсэг>} + өөрийн Idempotency-Key. Буцаалт зөвхөн succeeded / partially_refunded intent-д (409 not_refundable).

4. Автомат суллалт

Хариу өгөөгүй бол capture_before-д intent expired (authorization_expired) болж, hold хүнд автоматаар суллагдана (payment_intent.expired; mini app-ын intent-д payment_intent.canceled + status: "expired"). Дараа нь capture боломжгүй. Дэвтэр өөрөө hold-ыг capture_before + цонхны хагас (≥ 1 мин, ≤ 15 мин) дээр суллана — платформ суллаж чадаагүй үед л.

capture_within-ийг бараа өгөх + мэдээлэх хамгийн муу хугацаа-аас урт, гэхдээ хүний мөнгийг дэмий барихгүй байхаар сонго: машинд минут, захиалгын хоолонд цаг.

5. Код

const pi = await gerege.paymentIntents.capture(id);            // эсвэл .cancel(id)
if (pi.status === "processing") scheduleRecheck(id);            // 202
await gerege.refunds.create(id, { amount: 3000, reason: "out_of_stock" }, { idempotencyKey: `refund:${orderId}` });
pi, err := c.PaymentIntents.Capture(ctx, id) // эсвэл Cancel
var apiErr *miniapp.APIError
if errors.As(err, &apiErr) && apiErr.Code == "expired" { /* hold хүнд суллагдсан */ }
_, err = c.PaymentIntents.Refund(ctx, id, "refund:"+orderID, miniapp.RefundParams{Amount: 3000, Reason: "out_of_stock"})