HSRCPAY Dökümantasyon

Ö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):

StatusAnlam
CREATEDPayment kaydı oluşturuldu; confirm henüz çalışmadı
REQUIRES_PAYMENT_METHODYöntem eksik veya son confirm başarısız/decline; yeniden confirm edilebilir
REQUIRES_ACTION3DS, redirect veya kullanıcı aksiyonu gerekiyor
PROCESSINGProvider execution veya async sonuç bekleniyor
AUTHORIZEDAuth-only başarı (auto_capture: false)
SUCCEEDEDTahsilat tamamlandı (auto_capture: true ile capture dahil)
CANCELEDİşlem iptal edildi
REFUNDEDBaşarılı payment sonrası iade işlendi
EXPIREDSü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şamaNe yapar?Para hareketi?
Create Paymentİş niyetini ve ödeme kaydını hazırlarHayır
Confirm PaymentRouting plan, charge attempt ve provider adapter executionProduction'da evet, sandbox'ta simulated

Confirm ne yapar?

Confirm anında tipik olarak şu işlemler yürür:

  1. Payment confirm edilebilir status'te mi kontrol edilir.
  2. Yetki (payment:confirm) ve account sınırı doğrulanır.
  3. Payment Method normalize edilir (token, kayıtlı method veya inline kart verisi).
  4. Account routing policy veya istekteki routing_strategy ile aday havuzu çözülür.
  5. Routing plan oluşturulur; her aday için Charge oluşturulup provider adapter pay çağrılır.
  6. Sonuç normalized adapter result olarak döner; Payment status ve isteğe bağlı next_action güncellenir.
  7. Charge status (ör. CAPTURED, AUTHORIZED, REQUIRES_ACTION, DECLINED) güncellenir.
  8. 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://..."
      }
    }
  }
}
AlanMerchant davranışı
payment.statusOrder / iş akışı state'i; webhook ile mutabakat
confirmResult.oktrue ise son adım success veya requires_action
confirmResult.latestResultProvider adapter özeti (ham nextAction burada olabilir)
confirmResult.paymentNextActionPlatform 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/:id ile mevcut status ve charges kontrol edin.
  • REQUIRES_PAYMENT_METHOD veya REQUIRES_ACTION iken 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ık status).
  • 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_ACTION sonucunu edge case değil, normal lifecycle parçası kabul edin.
  • Decline'ı Payment status yerine Charge DECLINED ve REQUIRES_PAYMENT_METHOD kombinasyonuyla okuyun.
  • Provider raw response yerine payment.status ve normalized charge alanlarına göre karar verin.
  • auto_capture ve AUTHORIZED vs SUCCEEDED ayrı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.

Bu sayfada