Skip to content

Correlate asynchronous responses with stateful handlers

Remember a pending payment so a later confirmation can find the reservation it belongs to.

A payment provider returns its own reference. A small stateful handler remembers the connection between that reference and your reservation. The HTTP call itself belongs in the API integration.

public record PaymentStarted(String reservationId, String providerReference) {}
public record PaymentConfirmed(String providerReference) {}
public record ReservationPaid(String reservationId) {}
@Stateful
public record AwaitingPayment(@EntityId String reservationId,
@Association String providerReference) {
@HandleEvent
static AwaitingPayment start(PaymentStarted event) {
return new AwaitingPayment(event.reservationId(), event.providerReference());
}
@HandleEvent
AwaitingPayment complete(PaymentConfirmed event) {
Fluxzero.publishEvent(new ReservationPaid(reservationId));
return null;
}
}

Register AwaitingPayment.class as a handler (AwaitingPayment::class.java in Kotlin). Fluxzero stores the returned handler instance. @Association matches the later confirmation to it, including after an application restart. Returning null removes the completed process.

TestFixture.create(AwaitingPayment.class)
.givenEvents(new PaymentStarted("r1", "pay-42"))
.whenEvent(new PaymentConfirmed("pay-42"))
.expectEvents(new ReservationPaid("r1"));

This flow assumes PaymentStarted is stored before confirmation arrives. Real provider callbacks can arrive early or repeat: accept them at your integration boundary, and make the final business action safe to repeat. Publishing an event and removing process state do not form an external transaction.

See stateful handlers for the lifecycle and association API.


© 2026 Fluxzero