Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Created May 12, 2026 13:51
Show Gist options
  • Select an option

  • Save dcomartin/b516ffa62577e502da9b12c07e0e4f14 to your computer and use it in GitHub Desktop.

Select an option

Save dcomartin/b516ffa62577e502da9b12c07e0e4f14 to your computer and use it in GitHub Desktop.
public class CheckoutSaga :
Saga<CheckoutSagaData>,
IAmStartedByMessages<OrderPlaced>,
IHandleMessages<InventoryReserved>,
IHandleMessages<PaymentCaptured>,
IHandleTimeouts<PaymentCaptureTimeout>
{
protected override void ConfigureHowToFindSaga(
SagaPropertyMapper<CheckoutSagaData> mapper)
{
mapper.MapSaga(saga => saga.OrderId)
.ToMessage<OrderPlaced>(message => message.OrderId)
.ToMessage<InventoryReserved>(message => message.OrderId)
.ToMessage<PaymentCaptured>(message => message.OrderId);
}
public async Task Handle(
OrderPlaced message,
IMessageHandlerContext context)
{
Data.OrderId = message.OrderId;
await context.Send(new ReserveInventory(
message.OrderId,
message.ProductId,
message.Quantity));
}
public async Task Handle(
InventoryReserved message,
IMessageHandlerContext context)
{
Data.InventoryReserved = true;
await context.Send(new CapturePayment(
message.OrderId,
message.Amount));
await RequestTimeout<PaymentCaptureTimeout>(
context,
TimeSpan.FromMinutes(15));
}
public async Task Handle(
PaymentCaptured message,
IMessageHandlerContext context)
{
Data.PaymentCaptured = true;
await context.Send(new ConfirmOrder(message.OrderId));
MarkAsComplete();
}
public async Task Timeout(
PaymentCaptureTimeout timeout,
IMessageHandlerContext context)
{
if (Data.PaymentCaptured)
{
return;
}
await context.Send(new RequestPaymentReconciliation(Data.OrderId));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment