Playbook

Simultaneidad optimista bajo Webhook (Simultaneidad Optimista Bajo Webhook)

¿Cómo resuelven el token de versión y el arrendamiento la carrera cuando la respuesta sincrónica con webhook toca el mismo pago al mismo tiempo? Secreto de cliente de lectura obsoleto en pago terminal...

Motor de pago distribuido

Parte 17 de 22

Una serie de arquitecturas de pago distribuidas que cierran la brecha entre la captura y la finalización.

Distributed payment engine architecture diagram

En la sección anterior vimos por qué la coherencia final es inevitable: PSP no puede participar en su protocolo de transacciones, la saga y la reconciliación son la verdadera respuesta. Esta sección se centra en el momento pico de esa ventana de discrepancia: el momento en que el webhook y la respuesta sincrónica tocan el mismo registro de pago simultáneamente.

El organizador de pago envía una solicitud de cargo; La puerta de enlace del proveedor recibe respuesta del PSP. Al mismo tiempo, a veces milisegundos antes, a veces más tarde, llega un webhook por el mismo pago. Ambos caminos pueden transportar información precisa; Si ambos intentan escribir al mismo tiempo, el resultado es una actualización perdida o, peor aún, una respuesta incorrecta del cliente basada en una lectura obsoleta en un pago terminal.```text Senkron yanıt ──► Payment #42 (version=3) ──► Captured Webhook ──► Payment #42 (version=3) ──► Captured (tekrar?) │ ▼ Version token + lease → tek kazanan yazar


## Conceptos en la primera mención```text
📦 Version Token (Optimistic Lock)
Her güncellemede artan sayaç; yazma yalnızca beklenen sürüm eşleşirse başarılı olur.

📦 Lease
Bir worker'ın belirli bir ödeme kaydını işleme hakkını süre sınırlı olarak alması.

📦 Stale Read
İşlem sırasında okunan ama yazma anında artık geçerli olmayan eski sürüm.

📦 Terminal Payment
Captured, Failed veya Refunded gibi geri dönüşü olmayan nihai statü.
```Arrendamiento es cuando un trabajador dice 'estoy procesando este registro'; El token de versión significa "Aún veo esta versión". Juntos, evitan que el webhook y la ruta sincrónica se sobrescriban entre sí.

## Dos caminos, un récord: donde comienza la carrera

En un pago basado en redireccionamiento, la ruta sincrónica generalmente devuelve `Pending`; El resultado real viene con webhook. Para el pago con tarjeta, ambas rutas pueden llevar `Captured` o `Failed` y ambas pueden llegar casi al mismo tiempo. El orquestador de pago intenta escribir la información de ambas rutas en la misma línea de pago.

Error clásico: ambos controladores leen el registro, actualizan el estado y guardan. La última persona en escribir gana; La actualización intermedia desaparece silenciosamente. Escenario más peligroso: el orquestador lee una versión anterior antes de cambiar al estado de terminal y devuelve un secreto de cliente o una URL de redireccionamiento al cliente que todavía parece válida; en realidad, el pago ya se completó o falló.```text
T=0  Orchestrator: charge gönder
T=1  Webhook gelir → Captured yaz (version 2→3)
T=2  Senkron yanıt gelir → Pending okudu (version 1)
     → client'a redirectUrl döner (bayat!)
T=3  Müşteri redirect'e gider → ödeme zaten Captured
```## Token de versión: escribe solo si la versión coincide

En cada registro de pago se mantiene un campo `version` que aumenta monótonamente. La actualización se realiza con la siguiente condición: `UPDATE ... WHERE id = ? AND version = ?`. Si no hay ninguna coincidencia, la actualización afecta a cero filas; esto es una señal de que otra ruta está interfiriendo.```text
Webhook handler
  READ payment (version=2, status=Processing)
  → status=Captured, version=3
  UPDATE WHERE version=2 ✓ (1 row)

Senkron handler (bayat okuma)
  READ payment (version=2, status=Processing)  ← webhook henüz commit olmadı
  → status=Captured, version=3
  UPDATE WHERE version=2 ✗ (0 rows — webhook zaten yazdı)
  → yeniden oku, terminal statüyü gör, client secret döndürme
```El token de versión por sí solo no es suficiente; También es necesario definir qué hacer después de detectar la lectura obsoleta: leer nuevamente, verificar el estado del terminal, devolver solo el estado actual al cliente.

## Arrendamiento: obtener el derecho al procesamiento de webhooks por un período de tiempo limitado

El controlador del webhook toma un breve periodo de tiempo antes de tocar el registro: "Estoy procesando el pago n.º 42 durante 30 segundos". Durante el período de arrendamiento, otro trabajador no puede procesar el mismo registro en el webhook o flujo de recuperación.```text
Webhook gelir
  → lease al (paymentId, ttl=30s)
  → lease alınamazsa → defer / retry
  → lease alındı → version token ile güncelle
  → lease bırak
```El arrendamiento evita que dos trabajadores procesen el mismo webhook simultáneamente. El token de versión resuelve conflictos entre diferentes rutas (síncrono frente a webhook). Los dos responden a problemas diferentes; Deben usarse juntos.

## Fuga de secreto del cliente en pago terminal

El escenario de lectura obsoleta más grave es devolver un secreto de cliente o una URL de redireccionamiento en estado de terminal. Aún devolver `Pending` + redirecciónUrl al cliente después de que el pago sea `Captured` resultará en un segundo intento de cargo innecesario o confusión.

La regla es simple: el secreto del cliente, la URL de redireccionamiento o el token de reintento nunca se devuelven para un pago que haya pasado al estado de terminal. El controlador vuelve a leer el registro cuando recibe un conflicto de versiones o si se sospecha una lectura obsoleta; Si ve el estado del terminal, solo devuelve el resultado final.

| Estado | Volviendo al Cliente |
| --- | --- |
| Procesando, se requiere redireccionamiento | URL de redirección (válida) |
| Capturado (terminal) | Resultado de éxito, no es ningún secreto |
| Fallido (terminal) | Resultado de error, ningún secreto |
| Conflicto de versión → releer → Capturado | Resultado de éxito, no es ningún secreto |

## Distinciones frecuentemente confusas```text
❌ Pessimistic lock her zaman daha güvenlidir
✓ Ödeme akışında kısa süreli lease + version token, throughput'u korurken yarışı çözer

❌ Version conflict = hata, exception fırlat
✓ Version conflict = başka yol kazandı; yeniden oku ve güncel duruma uy

❌ Lease ve version token aynı şeyi yapar
✓ Lease aynı kaydın eşzamanlı işlenmesini engeller; version token eşzamanlı yazmayı
```## Token de arrendamiento versus versión

| Criterio | Arrendamiento | Token de versión |
| --- | --- | --- |
| Bloqueado | Procesamiento paralelo del mismo registro | Actualización perdida |
| Duración | TTL limitado | Persistente, aumenta con cada escritura |
| Comportamiento conflictivo | Esperar/aplazar | Releer/reintentar |

## Lista de verificación de simultaneidad optimista

1. ¿Las actualizaciones de pagos se realizan con la condición `WHERE version = ?`?
2. Cuando se recibe un conflicto de versión, ¿el controlador vuelve a leer y verificar el estado del terminal?
3. ¿La devolución del secreto del cliente o la URL de redireccionamiento en el estado del terminal está bloqueada a nivel de código?
4. ¿Se alquila el controlador del webhook antes de iniciar la operación?
5. ¿El período de arrendamiento es superior a P99 del tiempo de procesamiento del webhook?
6. ¿El controlador de respuesta sincrónica y el controlador de webhook comparten la misma lógica de finalización?

## Lo que debes recordar de este artículo

1. La ruta sincrónica con webhook toca el mismo registro simultáneamente; la concurrencia optimista es la respuesta estándar a esta carrera.
2. La pérdida del token de versión impide la actualización; El arrendamiento impide el procesamiento paralelo del mismo registro.
3. El conflicto de versiones no es un error, sino una señal de relectura.
4. Devolver el secreto del cliente sin leerlo obsoleto en el pago del terminal es un error silencioso de seguridad y UX.

> No necesitas un bloqueo pesimista para resolver la carrera; Lo que necesita es una combinación disciplinada de token de versión y arrendamiento que evite que las lecturas obsoletas lleguen al cliente.

En la siguiente sección, pasamos a la observabilidad para ver estas carreras y finalizar los pasos: correlación con la identificación de pago, registro de eventos paso a paso y métricas de finalización diferida.

FAQ

Frequently asked questions

¿Qué es el token de versión (bloqueo optimista)?

Contador que aumenta con cada actualización; La escritura se realiza correctamente sólo si la versión esperada coincide.

¿Qué es un arrendamiento?

El derecho de un trabajador, por tiempo limitado, a procesar un registro de pago particular.

¿Es cierto que "el bloqueo pesimista siempre es más seguro"?

Arrendamiento corto + token de versión en el flujo de pago resuelve la carrera y preserva el rendimiento

¿Qué soluciona esta sección?

La concurrencia optimista aquí no es una optimización del rendimiento; Es el mecanismo de no devolver datos incorrectos en el estado del terminal. Con webhook, la ruta sincrónica toca el mismo registro simultáneamente; la concurrencia optimista es la respuesta estándar a esta carrera. En la sección anterior vimos por qué la coherencia final es inevitable: PSP no puede participar en su protocolo de transacciones, la saga y la reconciliación son la verdadera respuesta. Esta sección se centra en el momento pico de esa ventana de discrepancia: el momento en que el webhook y la respuesta sincrónica tocan el mismo registro de pago simultáneamente.

Principios de ingeniería aprendidos

  • La pérdida del token de versión impide la actualización; El conflicto es la señal de relectura.
  • El token de arrendamiento y versión resuelve diferentes carreras; ambos deben usarse juntos.
  • En el pago terminal, el secreto del cliente no debe devolverse sin leerlo como obsoleto.

Continuar leyendo

Continuar leyendo

Siguiente en la serie

ENSAYO

Observabilidad y correlación de pagos

¿Cómo correlacionar cada registro, métrica y seguimiento con la identificación de pago? ¿Cómo el registro de eventos paso a paso y las métricas de…

Siguiente en la serie

Misma serie

Paylaş