Ödeme Yaşam Döngüsü ve Confirm
HSRC Pay'de payment oluşturma, confirm etme, requires_action, succeeded, authorized ve charge attempt ilişkisini anlayın.
Bu sayfa Payment oluşturmak ile Payment confirm etmek arasındaki farkı, Confirm adımının neden ayrı tutulduğunu ve bir Payment'ın nasıl birden fazla Charge attempt üretebildiğini açıklar.
Confirm, payment kaydını gerçek provider execution sürecine taşıyan kontrollü geçiştir.
Payment lifecycle nedir?
Payment lifecycle, merchant'ın ödeme niyetinin oluşturulmasından terminal sonuca kadar geçen state modelidir. HSRC Pay için önemli olan nokta şudur: Payment iş hedefidir; Charge provider seviyesindeki işlem denemesidir.
Public API status alanı Prisma PaymentStatus enum'u ile aynıdır (büyük harf, snake_case değil):
| Status | Anlam |
|---|---|
CREATED | Payment kaydı oluşturuldu; confirm henüz çalışmadı |
REQUIRES_PAYMENT_METHOD | Yöntem eksik veya son confirm başarısız/decline; yeniden confirm edilebilir |
REQUIRES_ACTION | 3DS, redirect veya kullanıcı aksiyonu gerekiyor |
PROCESSING | Provider execution veya async sonuç bekleniyor |
AUTHORIZED | Auth-only başarı (auto_capture: false) |
SUCCEEDED | Tahsilat tamamlandı (auto_capture: true ile capture dahil) |
CANCELED | İşlem iptal edildi |
REFUNDED | Başarılı payment sonrası iade işlendi |
EXPIRED | Süre veya iş kuralı nedeniyle geçersiz |
Decline ve teknik hata Payment'ta ayrı DECLINED / FAILED status üretmez; orchestrator sonucu declined veya error olduğunda Payment çoğunlukla REQUIRES_PAYMENT_METHOD olur. Reddetme detayı ilgili Charge kaydında (DECLINED, FAILED) tutulur.
Confirm öncesi tekrar confirm edilebilir status'ler: CREATED, REQUIRES_ACTION, REQUIRES_PAYMENT_METHOD.
Create ve Confirm ayrımı
Payment oluşturmak, parayı çekmek anlamına gelmez. Create aşaması merchant'ın iş niyetini, tutarı, currency bilgisini, auto_capture, secure_mode, customer bağlamını ve metadata'yı hazırlar; kayıt CREATED ile açılır.
Confirm ise payment_method, isteğe bağlı routing_strategy ve payer_identity ile routing plan oluşturup provider execution (charge attempt) sürecini başlatır.
| Aşama | Ne yapar? | Para hareketi? |
|---|---|---|
| Create Payment | İş niyetini ve ödeme kaydını hazırlar | Hayır |
| Confirm Payment | Routing plan, charge attempt ve provider adapter execution | Production'da evet, sandbox'ta simulated |
Confirm ne yapar?
Confirm anında tipik olarak şu işlemler yürür:
- Payment confirm edilebilir status'te mi kontrol edilir.
- Yetki (
payment:confirm) ve account sınırı doğrulanır. - Payment Method normalize edilir (token, kayıtlı method veya inline kart verisi).
- Account routing policy veya istekteki
routing_strategyile aday havuzu çözülür. - Routing plan oluşturulur; her aday için Charge oluşturulup provider adapter
payçağrılır. - Sonuç normalized adapter result olarak döner; Payment status ve isteğe bağlı
next_actiongüncellenir. - Charge status (ör.
CAPTURED,AUTHORIZED,REQUIRES_ACTION,DECLINED) güncellenir. - Domain event ve webhook delivery tetiklenir.
Confirm HTTP yanıtı
Confirm tek bir kind alanı döndürmez. Standart v1 envelope içinde data.payment (güncel Payment DTO) ve data.confirmResult (orchestrator özeti) gelir.
{
"data": {
"payment": {
"object": "payment",
"id": "pay_123",
"status": "REQUIRES_ACTION",
"amount": 12500,
"currency": "TRY"
},
"confirmResult": {
"ok": true,
"results": [],
"latestResult": { "kind": "requires_action" },
"paymentNextAction": {
"action": "redirect_user_to_url",
"url": "https://..."
}
}
}
}| Alan | Merchant davranışı |
|---|---|
payment.status | Order / iş akışı state'i; webhook ile mutabakat |
confirmResult.ok | true ise son adım success veya requires_action |
confirmResult.latestResult | Provider adapter özeti (ham nextAction burada olabilir) |
confirmResult.paymentNextAction | Platform next_action: şu an redirect_user_to_url + url |
auto_capture: false ile başarılı confirm Payment'ı AUTHORIZED yapar; capture ayrı endpoint ile SUCCEEDED / charge CAPTURED hedefine gider.
Requires Action / 3DS
Secure mode veya provider/issuer davranışı ek kullanıcı aksiyonu gerektirirse Confirm direkt SUCCEEDED / AUTHORIZED dönmeyebilir. Payment REQUIRES_ACTION olur; merchant tarafında yönlendirme için confirmResult.paymentNextAction (ve kayıtta payment.next_action) kullanılır.
Hosted Checkout bu aksiyonu kullanıcı deneyimi içinde yönetebilir. API-only entegrasyonda merchant paymentNextAction.url ile yönlendirir; challenge sonrası gateway callback URL'i (charge'a bağlı) resume akışını tamamlar.
Provider adapter içindeki nextAction (ör. render_html) ile platform paymentNextAction farklı katmanlardır; entegrasyonda kullanıcıyı yönlendirmek için platform alanını esas alın.
Resume / 3DS callback
Resume, resumePayment(paymentId) diye ayrı bir public payment endpoint değildir. 3DS tamamlandığında provider, HSRC Pay gateway üzerindeki three-d-secure-callback-urls/:id adresine döner; bu id charge ile ilişkilidir.
const { payment, confirmResult } = await confirmPayment(paymentId, {
payment_method: { id: "pm_123" },
payer_identity: { ip_address: clientIp, user_agent: ua },
});
if (payment.status === "REQUIRES_ACTION" && confirmResult.paymentNextAction?.url) {
redirectUser(confirmResult.paymentNextAction.url);
// Kullanıcı challenge sonrası gateway callback otomatik işlenir;
// ardından GET payment veya webhook ile nihai status doğrulanır.
}Detaylı sandbox senaryoları için 3DS Simulation sayfasına bakın.
Charge attempt ilişkisi
Bir Payment birden fazla Charge üretebilir. Her routing adayı için yeni charge oluşturulur; attempt_no routing plan indeksini yansıtır.
Örnek: Merchant 1000 TRY Payment oluşturur. İlk provider soft decline döner (Charge DECLINED). Routing bir sonraki adaya geçer; ikinci charge attempt success olursa Payment SUCCEEDED veya AUTHORIZED olur. Merchant tek Payment görür; operasyon ekibi charge listesi üzerinden attempt trace eder.
Routing, success veya requires_action görünce durur; declined tipi error'da genelde durur, diğer error'larda sonraki aday denenebilir (motor kuralları aday havuzuna bağlıdır).
Idempotency ve tekrar confirm
Confirm için ayrı Idempotency-Key zorunluluğu tanımlı değildir; yine de ağ timeout veya çift tıklamada aynı payment için gereksiz yeni execution riski vardır.
Best practice:
- Timeout sonrası yeni payment açmak yerine
GET /payments/:idile mevcutstatusvechargeskontrol edin. REQUIRES_PAYMENT_METHODveyaREQUIRES_ACTIONiken kontrollü yeniden confirm planlayın; terminal status'lerde confirm 400 döner.- Webhook event'lerini duplicate delivery için idempotent işleyin.
Webhook beklentileri
Frontend veya confirm response nihai muhasebe kaydı kabul edilmemelidir. Payment state değişiklikleri webhook/event sistemiyle doğrulanmalıdır.
Beklenen yaklaşım:
- Confirm response kullanıcı deneyimini yönlendirir (
paymentNextAction, anlıkstatus). - Webhook merchant backend state'ini kapatır (
payment.succeeded,payment.requires_action,payment.authorized, vb.). - Server-side status query mutabakat ve incident çözümü için kullanılır (
include_charges=trueönerilir).
Best practices
- Payment ve Charge kavramlarını ekip içinde aynı dille kullanın.
- Confirm'i execution boundary olarak ele alın.
REQUIRES_ACTIONsonucunu edge case değil, normal lifecycle parçası kabul edin.- Decline'ı Payment
statusyerine ChargeDECLINEDveREQUIRES_PAYMENT_METHODkombinasyonuyla okuyun. - Provider raw response yerine
payment.statusve normalized charge alanlarına göre karar verin. auto_captureveAUTHORIZEDvsSUCCEEDEDayrımını capture/cancel akışlarıyla birlikte test edin.- Sandbox'ta success dışındaki sonuçları da test edin.
Örnek confirm isteği
{
"payment_method": {
"id": "pm_123"
},
"routing_strategy": {
"mode": "merchant_direct",
"payment_provider_config_id": "ppc_123"
},
"payer_identity": {
"ip_address": "203.0.113.10",
"user_agent": "Mozilla/5.0 ...",
"ip_address_details": null
}
}Endpoint: POST /v1/payments/:id/confirm. Tam şema için API Reference: confirmPayment kullanın.