Playbook

Procesamiento de pagos efectivo una sola vez (Procesamiento DE Pagos Efectivo Una Sola Vez)

Enviar mensajes exactamente una vez es una mentira. ¿Cómo lograr resultados comerciales efectivos cuando se combina la defensa en profundidad con idempotencia, deduplicación, bandeja de salida y reconciliación?

Motor de pago distribuido

Parte 20 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 que el proceso de recuperación funciona primero según el principio de automatización y que los runbooks basados ​​en evidencia entran en juego en los muros de unicidad. Esta sección profundiza en las garantías de mensajería que subyacen en el proceso y en el concepto erróneo más común de la industria: la entrega exactamente una vez.

Los vendedores de corredores prometen una "semántica exactamente una vez". El hecho es que en un sistema distribuido no está físicamente garantizado que un mensaje se procese exactamente una vez. La red se cae, el trabajador falla, el corredor reenvía. La pregunta no es "cuántas veces llegó el mensaje"; cuántas veces ocurrió el resultado del trabajo.```text Exactly-once messaging → imkansız (at-least-once + failure = duplicate) Effectively-once outcome → mümkün (defense in depth)


## Conceptos en la primera mención```text
📦 At-Least-Once Delivery
Mesaj en az bir kez ulaşır; ağ hatasında tekrar gönderilebilir.

📦 Effectively-Once
Mesaj birden fazla kez işlense bile iş sonucu (charge, refund, order) yalnızca bir kez gerçekleşir.

📦 Defense in Depth
Tek bir mekanizmaya güvenmek yerine, birden fazla bağımsız koruma katmanı.

📦 Idempotent Consumer
Aynı mesajı ikinci kez aldığında aynı sonucu üreten, yan etki yaratmayan tüketici.
```La mensajería exactamente una vez no es una función del corredor; Es un diseño de sistema efectivamente primero.

## Exactamente una vez por qué mentir

Un trabajador recibe el mensaje, lo procesa y envía un acuse de recibo, pero el acuse de recibo se pierde en la red. El corredor reenvía el mensaje. El trabajador procesa por segunda vez. Ésta es la naturaleza de la entrega al menos una vez; No importa cuán "exactamente una vez" afirme el corredor, la duplicación por parte del consumidor es inevitable.```text
Worker mesajı işler → sonuç: Captured
Ack ağda kaybolur
Broker mesajı tekrar gönderir
Worker tekrar işler → sonuç: ??? (çift charge riski)
```La cuestión no es cuántas veces llega el mensaje; es lo que sucederá en la segunda venida. Si no hay efectos secundarios en la segunda visita, significa que se ha logrado de manera efectiva, una vez.

## Defensa en profundidad: una capa no es suficiente

Efectivamente, el resultado empresarial es una combinación de capas complementarias. Ninguno de los dos por sí solo es suficiente; Todos juntos producen el resultado "un mensaje que llega al menos una vez tiene un efecto como máximo una vez".```text
Katman 1: Idempotency key (API)
  → aynı key ile ikinci charge isteği reddedilir

Katman 2: Consumer dedup (messaging)
  → aynı message id ikinci kez işlenmez

Katman 3: DB uniqueness constraint
  → aynı idempotency key ile ikinci satır yazılamaz

Katman 4: Outbox pattern
  → event yalnızca transaction commit ile birlikte yayınlanır

Katman 5: Reconciliation
  → katman 1-4'ün kaçırdığı drift'i periyodik olarak düzeltir
```Si una capa falla, la otra toma el relevo. Si se omite la clave de idempotencia, se mantiene la restricción de unicidad; La conciliación se corrige si se omite la restricción.

## La pregunta para cada capa es diferente.

| Capa | Pregunta | Protegido |
| --- | --- | --- |
| Clave de idempotencia | ¿La misma intención otra vez? | Doble carga a nivel API |
| Deduplicación del consumidor | ¿El mismo mensaje otra vez? | Doble transacción a nivel de mensajería |
| Restricción de unicidad | ¿Segunda línea con la misma clave? | Doble registro de nivel DB |
| Bandeja de salida | ¿Se publicó el evento sin compromiso? | Pérdida o evento anticipado |
| Reconciliación | ¿Son incompatibles Local y PSP? | Todo lo que se escapa |

## Cómo escribir consumidor idempotente

Regla del consumidor idempotente: mismo insumo, mismo resultado; Sin efectos secundarios en la segunda llamada.```text
PaymentCaptured webhook (messageId=wh_991)
  → dedup tablosuna bak: wh_991 işlendi mi?
  → evet → skip (log: duplicate suppressed)
  → hayır → finalize, dedup tablosuna yaz
```El paso de finalización en sí debe ser idempotente: si el pago ya es `Captured`, no se debe emitir ningún evento nuevamente ni se debe crear ninguna orden nuevamente. La tabla Dedup conserva la capa de mensajería; El control del estado del terminal protege la lógica empresarial.

## Bandeja de salida: evento y estado están en la misma transacción

El patrón de la bandeja de salida resuelve el dilema de "estado actualizado pero evento no publicado" o "evento publicado pero estado no actualizado". El evento se escribe en la tabla de la bandeja de salida junto con la transacción local; Un editor independiente lee la bandeja de salida y la envía al corredor.```text
BEGIN TRANSACTION
  UPDATE payment SET status=Captured
  INSERT INTO outbox (event=PaymentCaptured, paymentId=8812)
COMMIT
  → publisher outbox'ı okur → broker'a gönderir
  → gönderim başarılı → outbox satırını siler
```Outbox no proporciona mensajes exactamente una vez, pero garantiza la coherencia entre el estado y el evento. La reconciliación atrapa a quienes escaparon de la bandeja de salida.

## Distinciones frecuentemente confusas```text
❌ Broker exactly-once = sistem exactly-once
✓ Broker dedup + consumer idempotency + DB constraint = effectively-once

❌ Idempotency key her yerde yeterli
✓ Idempotency key API'yi korur; webhook ve async worker ayrı katman ister

❌ Effectively-once = perfect system
✓ Effectively-once = iş sonucu bir kez; tutarsızlık penceresi reconciliation ile kapanır
```## Garantía de entrega versus resultado comercial

| Garantía | ¿Qué promete? ¿Es suficiente para los pagos? |
| --- | --- | --- |
| Como máximo una vez | Una vez que se pierde el mensaje, es posible que se pierda | No: pago perdido |
| Al menos una vez | El mensaje puede duplicarse al menos una vez | No – solo |
| Exactamente una vez (corredor) | Teóricamente, prácticamente se rompe del lado del consumidor | No |
| Efectivamente una vez (sistema) | Resultado del trabajo una vez | Sí |

## Lista de verificación efectiva una vez

1. ¿Las solicitudes de cobro de API están protegidas con una clave de idempotencia?
2. ¿Existe una desduplicación de ID de mensaje en webhooks y consumidores asíncronos?
3. ¿Existe una restricción de unicidad en la clave de idempotencia en la tabla de pagos?
4. ¿El cambio de estado y el evento se transmiten en la misma transacción que el patrón de la bandeja de salida?
5. ¿El controlador de finalización se salta sin volver a operar en estado terminal?
6. ¿Reconciliación analiza periódicamente en busca de desviaciones omitidas por las capas 1 a 5?

## Lo que debes recordar de este artículo

1. Enviar mensajes exactamente una vez es mentira; al menos una vez + falla = duplicado es inevitable.
2. Efectivamente, una vez que sea posible obtener resultados comerciales con una defensa en profundidad, una capa no es suficiente.
3. Cada capa de protección responde a una pregunta diferente; todos deben trabajar juntos.
4. La reconciliación es la última capa; Complementa, no reemplaza, las capas anteriores.

> Incluso si su corredor promete exactamente una vez, su sistema de pago no debería creerlo; lo que debería creer es construir efectivamente el resultado comercial en profundidad.

En la siguiente sección, pasamos a la síntesis de este viaje de 22 partes: lista de verificación del diseño del motor de pago de producción.

FAQ

Frequently asked questions

¿Qué es la entrega al menos una vez?

El mensaje llega al menos una vez; Se puede enviar nuevamente en caso de error de red.

¿Qué es Efectivo una vez?

Incluso si el mensaje se procesa más de una vez, el resultado del trabajo (cargo, reembolso, pedido) ocurre sólo una vez.

¿Es correcto "Broker exactamente una vez = sistema exactamente una vez"?

Desduplicación del corredor + idempotencia del consumidor + restricción de base de datos = efectivamente una vez

¿Qué soluciona esta sección?

Los vendedores de corredores prometen una "semántica exactamente una vez". El hecho es que en un sistema distribuido no está físicamente garantizado que un mensaje se procese exactamente una vez. La red se cae, el trabajador falla, el corredor reenvía. La pregunta no es "cuántas veces llegó el mensaje"; **cuántas veces ocurrió el resultado del trabajo**. Enviar mensajes exactamente una vez es una mentira; al menos una vez + falla = duplicado es inevitable. En la sección anterior, vimos que el proceso de recuperación funciona primero según el principio de automatización y que los runbooks basados ​​en evidencia entran en juego en los muros de unicidad. Esta sección profundiza en las garantías de mensajería que subyacen en el proceso y en el concepto erróneo más común de la industria: la entrega exactamente una vez.

Principios de ingeniería aprendidos

  • Enviar mensajes exactamente una vez es una mentira; de manera efectiva, una vez que el resultado del trabajo es posible.
  • Defensa en profundidad: idempotencia, dedup, unicidad, bandeja de salida y reconciliación trabajan juntos.
  • Cada capa de protección responde a una pregunta diferente; Una capa no es suficiente.

Continuar leyendo

Continuar leyendo

Siguiente en la serie

Siguiente en la serie

Misma serie

Paylaş