---
title: "Payment + Booking Distributed Transaction"
description: "Travel booking'de payment ve supplier booking adımlarını distributed transaction olarak modelleyin; authorize, capture, compensation, UNKNOWN outcome ve reconciliation desenlerini uygulayın."
slug: "payment-booking-distributed-transaction"
translationKey: "architecture-payment-booking-distributed-transaction"
locale: "tr"
type: "guide"
category: "architecture"
tags: ["payment","booking","distributed-transaction","saga","reconciliation","idempotency"]
publishedAt: "2026-09-27"
updatedAt: "2026-09-27"
reviewedAt: "2026-09-27"
technicalVerifiedAt: "2026-09-27"
codeExampleStatus: "illustrative"
---

Travel booking'de payment gateway ve supplier booking API aynı ACID transaction içinde değildir. Bu nedenle **booking + payment akışı distributed transaction** olarak tasarlanmalı; her adımın success, failure ve unknown sonucu ayrı ele alınmalıdır.

## Temel problem

Şu iki işlem birlikte başarılı olmak zorundadır:

1. müşteri ödeme yükümlülüğü,
2. supplier rezervasyonu.

Ama bunlar farklı sistemlerde gerçekleşir. Dolayısıyla aşağıdaki ara durumlar normaldir:

- payment authorized, booking failed,
- booking confirmed, payment capture failed,
- payment request timeout, outcome unknown,
- booking request timeout, outcome unknown,
- cancellation succeeded ama refund başarısız,
- refund succeeded ama local booking state stale.

## Tek transaction yoktur

```mermaid
%% title: Payment and booking distributed transaction
%% description: Payment authorization, provider booking and payment capture adımlarının ayrı failure/compensation yolları.
flowchart LR
  A[Booking Intent] --> B[Payment Authorize]
  B -->|failed| C[Stop / Payment Failed]
  B -->|authorized| D[Provider Booking Create]
  D -->|confirmed| E[Payment Capture]
  D -->|failed| F[Void Authorization]
  D -->|unknown| G[Booking Reconciliation]
  G -->|confirmed| E
  G -->|failed| F
  E -->|captured| H[Booking Complete]
  E -->|failed/unknown| I[Payment Recovery / Ops]
```

## Neden authorize → book → capture?

Birçok modelde önce authorization yapıp booking confirmed olduktan sonra capture etmek riski azaltır:

- karttan para tahsil edilip booking oluşmaması önlenir,
- booking failed olursa authorization void edilebilir.

Ama bu her provider/payment modelinde mümkün değildir. Bazı akışlar full capture ister, bazıları pay-at-property veya virtual-card settlement kullanır.

## Diğer sequencing modelleri

### Book → pay

Supplier önce booking oluşturur, ardından ödeme alınır.

Risk: payment başarısız olursa confirmed booking'i iptal etmek gerekebilir.

### Pay/capture → book

Ödeme önce kesinleşir.

Risk: booking başarısız olursa refund/void compensation gerekir.

### Pay at property

Platform payment orchestration yapmayabilir; booking state ile payment liability yine ayrı tutulmalıdır.

## Canonical transaction state

Tek bir `transaction_status` yerine ayrı state machine'ler kullanın:

```text
PaymentState:
CREATED -> AUTHORIZING -> AUTHORIZED -> CAPTURING -> CAPTURED
                        -> FAILED
                        -> UNKNOWN
                        -> VOIDED
                        -> REFUNDED

BookingState:
REQUESTED -> CONFIRMED
          -> FAILED
          -> UNKNOWN
          -> CANCELLED
```

Üstte bir orchestration state olabilir:

```text
BookingTransaction:
STARTED
PAYMENT_READY
BOOKING_PENDING
BOOKING_CONFIRMED
PAYMENT_FINALIZING
COMPLETED
RECOVERY_REQUIRED
COMPENSATING
FAILED
```

## Saga yaklaşımı

Distributed transaction rollback yapılamadığı için compensation gerekir.

```mermaid
%% title: Travel booking compensation saga
%% description: Booking veya payment başarısız olduğunda uygulanabilecek compensation adımları.
flowchart TD
  A[Authorize Payment] --> B[Create Booking]
  B -->|confirmed| C[Capture Payment]
  B -->|failed| D[Void Authorization]
  C -->|capture failed| E[Retry / Alternative Capture]
  E -->|cannot recover| F[Cancel Booking]
  F --> G[Void or Refund Payment]
```

Compensation, gerçek rollback değildir. Supplier cancellation fee veya payment cost oluşturmuş olabilir.

## UNKNOWN outcome iki tarafta da mümkündür

### Booking UNKNOWN

Provider request timeout olur. Create çağrısını tekrar etmeyin; lookup/reconciliation yapın.

### Payment UNKNOWN

Gateway timeout olur. Aynı payment'ı yeni transaction ID ile tekrar başlatmak double charge yaratabilir. Payment provider idempotency key veya lookup mekanizması kullanılmalıdır.

## Idempotency sınırları

Her external operation için ayrı key kullanın:

- booking create idempotency key,
- payment authorize idempotency key,
- capture key,
- cancel key,
- refund key.

Aynı key'i farklı semantic operation'larda reuse etmeyin.

## Transaction log

Orchestrator yalnız current state değil immutable attempt history de saklamalıdır.

```json
{
  "bookingIntentId": "bi_123",
  "operation": "BOOK",
  "attempt": 1,
  "idempotencyKey": "book_bi_123_v1",
  "status": "UNKNOWN",
  "providerReference": null,
  "startedAt": "2026-09-27T10:00:00Z"
}
```

## Recovery policy

Recovery kararı operation tipine göre değişmelidir:

| Durum | İlk aksiyon |
|---|---|
| Payment authorize UNKNOWN | provider lookup / idempotent status query |
| Booking create UNKNOWN | booking lookup / reconciliation |
| Booking FAILED + payment AUTHORIZED | void authorization |
| Booking CONFIRMED + capture FAILED | capture retry / ops; gerekiyorsa cancel |
| Cancellation CONFIRMED + refund FAILED | refund retry/reconciliation |
| Refund UNKNOWN | payment lookup; blind retry yok |

## Outbox ve local consistency

Provider booking confirmed olduktan sonra local DB write başarılı ama event publish başarısız olabilir. Transactional outbox kullanın:

```text
local transaction:
  update booking state
  insert outbox event
commit

background publisher:
  publish outbox event
  mark published
```

Bu desen external booking call'ı ACID yapmaz; yalnız local state + event publication tutarlılığını iyileştirir.

## Retry politikası

Retry sadece "teknik olarak retryable" olduğu için yapılmamalıdır.

Güvenli retry için:

- operation idempotent olmalı veya idempotency key desteklemeli,
- önceki attempt'in outcome'u bilinmeli,
- exponential backoff + jitter kullanılmalı,
- retry budget sınırlandırılmalı,
- provider rate limit dikkate alınmalı.

Booking create, idempotency yoksa en riskli retry operation'larından biridir.

## Reconciliation worker

Reconciliation worker şu kayıtları taramalıdır:

- uzun süredir UNKNOWN booking,
- AUTHORIZED payment + terminal booking yok,
- CONFIRMED booking + payment incomplete,
- CANCELLED booking + refund incomplete,
- local/provider state mismatch.

Her kayıt için authoritative provider evidence alınır ve canonical state düzeltilir.

## Manual operations queue

Bazı divergence'lar otomatik çözülemez. Ops queue'da şu bilgiler olmalıdır:

- traveler-safe booking summary,
- provider reference,
- payment reference,
- current booking/payment states,
- attempt history,
- recommended next action,
- risk: duplicate charge / duplicate booking / cancellation fee.

## Failure modes

- booking confirmed ama capture başarısız,
- payment captured ama booking FAILED/UNKNOWN,
- compensation operation'ının kendisinin timeout olması,
- duplicate capture/refund retry,
- local outbox/state ile provider state'in ayrışması,
- manual ops sırasında ikinci booking veya ikinci refund yaratılması.

## Observability

Takip edin:

- authorization success rate,
- booking confirmation rate,
- capture success rate,
- compensation rate,
- void/refund latency,
- booking UNKNOWN rate,
- payment UNKNOWN rate,
- payment-booking divergence count,
- reconciliation age,
- manual intervention rate,
- duplicate prevention hits.

## Production checklist

- payment ve booking state machine'lerini ayırın,
- sequencing modelini provider/commercial contract bazında explicit seçin,
- her write operation için idempotency key kullanın,
- UNKNOWN outcome'u first-class state yapın,
- compensation policy tanımlayın,
- reconciliation worker ve manual ops queue sağlayın,
- transactional outbox ile local state/event tutarlılığını koruyun.

## Tasarım prensibi

**Payment ve Booking iki ayrı state machine; orchestration bunların koordinasyon katmanıdır.**

Bir tarafı diğerinin status alanına gömmek yerine intent, attempt, evidence ve compensation modelleri explicit tutulduğunda timeout ve partial failure senaryoları yönetilebilir hale gelir.
