Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ object PaymentMessages {
// Story 13.7 — every payment command carries `var correlationId` + `withCorrelationId` via
// AuditableCommand (zero constructor churn). The checkout endpoints stamp it from the inbound
// X-Correlation-Id; the handlers thread it onto the persisted payment events (the durable hop).
trait PaymentCommand extends AuditableCommand
trait PaymentCommand extends AuditableCommand {
override type T = PaymentCommand
}

trait PaymentCommandWithKey extends PaymentCommand {
def key: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@ trait BasicPaymentService extends Service[PaymentCommand, PaymentResult] {
super.run(command.key, command)
}

/** Story 13.7 — keyed convenience over the shared `Service.runCorrelated`: tapir `serverLogic`
* reads the cid as DATA via `HttpCorrelation.correlationInput` (MDC does not survive the
* `serverLogic` `Future` — C14) and dispatches through here, so every keyed command stamps the
* id in one place instead of an inline `cmd.withCorrelationId(cid); run(cmd)` per endpoint.
*/
def runCorrelated(command: PaymentCommandWithKey, correlationId: String)(implicit
tTag: ClassTag[PaymentCommand]
): Future[PaymentResult] =
runCorrelated(command.key, command, correlationId)

def error(result: PaymentResult): ApiErrors.ErrorInfo =
result match {
case PaymentAccountNotFound => ApiErrors.NotFound(PaymentAccountNotFound.message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1028,10 +1028,14 @@ trait PaymentBehavior
case Some(paymentAccount) =>
val recurringPaymentRegistrationId = key.split("#").last
Effect.none.thenRun(_ => {
context.self ! ExecuteNextRecurringPayment(
val next = ExecuteNextRecurringPayment(
recurringPaymentRegistrationId,
paymentAccount.externalUuid
)
// Story 13.7 (DN3) — carry the schedule's correlation id onto the renewal charge so
// the cid set at registration propagates to the scheduled "next recurring" events.
cmd.schedule.correlationId.filter(_.nonEmpty).foreach(next.withCorrelationId)
context.self ! next
Schedule4PaymentTriggered(cmd.schedule) ~> replyTo
})
case _ =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ trait BankAccountEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
clientId = client.map(_.clientId).orElse(session.clientId),
bankTokenId = bankTokenId
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case r: BankAccountCreatedOrUpdated => Right(r)
case other => Left(error(other))
}
Expand All @@ -71,8 +70,7 @@ trait BankAccountEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(session),
clientId = client.map(_.clientId).orElse(session.clientId)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case r: BankAccountLoaded => Right(r.bankAccount.view)
case other => Left(error(other))
}
Expand All @@ -92,8 +90,7 @@ trait BankAccountEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(principal._2),
Some(false)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case BankAccountDeleted => Right(BankAccountDeleted)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ trait BillingPortalEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
req.returnUrl,
clientId = client.map(_.clientId).orElse(session.clientId)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case r: BillingPortalSessionCreated => Right(r)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
paymentMethodId = paymentMethodId,
registerMeansOfPayment = registerMeansOfPayment
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case result: PaymentPreAuthorized => Right(result)
case result: PaymentRedirection => Right(result)
case result: PaymentRequired => Right(result)
Expand Down Expand Up @@ -150,8 +149,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
val printReceipt = params.get("printReceipt").getOrElse("false").toBoolean
val cmd =
PreAuthorizeCallback(orderUuid, preAuthorizationId, registerMeansOfPayment, printReceipt)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case result: PaymentPreAuthorized => Right(result)
case result: PaymentRedirection => Right(result)
case other => Left(error(other))
Expand Down Expand Up @@ -215,8 +213,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
)
// Story 13.7 — stamp the origin correlation id (from X-Correlation-Id, generated if absent)
// so it rides the command → the persisted PaidInEvent → the licensing pod.
cmd.withCorrelationId(correlationId)
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case result: PaidIn => Right(result)
case result: PaymentRedirection => Right(result)
case result: PaymentRequired => Right(result)
Expand Down Expand Up @@ -259,8 +256,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
params.get("registerMeansOfPayment").getOrElse("false").toBoolean
val printReceipt = params.get("printReceipt").getOrElse("false").toBoolean
val cmd = PayInCallback(orderUuid, transactionId, registerMeansOfPayment, printReceipt)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case result: PaidIn => Right(result)
case result: PaymentRedirection => Right(result)
case result: PaymentRequired => Right(result)
Expand Down Expand Up @@ -310,8 +306,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
browserInfo,
statementDescriptor
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case result: FirstRecurringPaidIn => Right(result)
case result: PaymentRedirection => Right(result)
case other => Left(error(other))
Expand Down Expand Up @@ -347,8 +342,7 @@ trait CheckoutEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.serverLogic { case (recurringPayInRegistrationId, transactionId, cid) =>
val cmd =
RecurringPaymentCallback(recurringPayInRegistrationId, transactionId)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case result: PaidIn => Right(result)
case result: PaymentRedirection => Right(result)
case other => Left(error(other))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ trait KycDocumentEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
case Some(kycDocumentType) =>
val cmd =
LoadKycDocumentStatus(externalUuidWithProfile(principal._2), kycDocumentType)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: KycDocumentStatusLoaded => Right(r.report)
case other => Left(error(other))
}
Expand Down Expand Up @@ -85,8 +84,7 @@ trait KycDocumentEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
case Some(kycDocumentType) =>
val cmd =
AddKycDocument(externalUuidWithProfile(principal._2), pages.bytes, kycDocumentType)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd)
runCorrelated(cmd, cid)
.map {
case r: KycDocumentAdded => Right(r)
case other => Left(error(other))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ trait MandateEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
iban = maybeIban.map(_.iban),
clientId = principal._1.map(_.clientId).orElse(principal._2.clientId)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case MandateCreated => Right(MandateCreated)
case r: MandateConfirmationRequired => Right(r)
case other => Left(error(other))
Expand All @@ -70,8 +69,7 @@ trait MandateEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(session),
clientId = client.map(_.clientId).orElse(session.clientId)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case MandateCanceled => Right(MandateCanceled)
case other => Left(error(other))
}
Expand All @@ -90,8 +88,7 @@ trait MandateEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.description("Update mandate status web hook")
.serverLogic { case (mandateId, cid) =>
val cmd = UpdateMandateStatus(mandateId)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: MandateStatusUpdated => Right(r.result)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ trait PaymentAccountEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
userAgent = userAgent,
tokenId = tokenId
)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: UserPaymentAccountCreatedOrUpdated => Right(r)
case other => Left(error(other))
}
Expand All @@ -105,8 +104,7 @@ trait PaymentAccountEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(session),
clientId = client.map(_.clientId).orElse(session.clientId)
)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: PaymentAccountLoaded => Right(r.paymentAccount.view)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
cid => {
val cmd =
LoadPaymentMethods(externalUuidWithProfile(principal._2))
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: PaymentMethodsLoaded => Right(PaymentMethodsView(r.paymentMethods).cards)
case other => Left(error(other))
}
Expand All @@ -54,8 +53,7 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
cid => {
val cmd =
LoadPaymentMethods(externalUuidWithProfile(principal._2))
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: PaymentMethodsLoaded => Right(PaymentMethodsView(r.paymentMethods))
case other => Left(error(other))
}
Expand All @@ -77,7 +75,6 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.serverLogic(principal =>
args => {
val cmd = args._1
cmd.withCorrelationId(args._2) // Story 13.7 — origin stamp
var updatedUser =
if (cmd.user.externalUuid.trim.isEmpty) {
cmd.user.withExternalUuid(principal._2.id)
Expand All @@ -89,12 +86,13 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
updatedUser = updatedUser.withProfile(profile)
case _ =>
}
run(
runCorrelated(
cmd.copy(
user = updatedUser,
paymentType = Transaction.PaymentType.CARD,
clientId = principal._1.map(_.clientId).orElse(principal._2.clientId)
)
),
args._2
).map {
case r: PaymentMethodPreRegistered => Right(r.preRegistration)
case other => Left(error(other))
Expand All @@ -117,7 +115,6 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.serverLogic(principal =>
args => {
val cmd = args._1
cmd.withCorrelationId(args._2) // Story 13.7 — origin stamp
var updatedUser =
if (cmd.user.externalUuid.trim.isEmpty) {
cmd.user.withExternalUuid(principal._2.id)
Expand All @@ -129,11 +126,12 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
updatedUser = updatedUser.withProfile(profile)
case _ =>
}
run(
runCorrelated(
cmd.copy(
user = updatedUser,
clientId = principal._1.map(_.clientId).orElse(principal._2.clientId)
)
),
args._2
).map {
case r: PaymentMethodPreRegistered => Right(r.preRegistration)
case other => Left(error(other))
Expand All @@ -156,8 +154,7 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(principal._2),
args._1
)
cmd.withCorrelationId(args._2) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, args._2).map {
case PaymentMethodDisabled => Right(PaymentMethodDisabled)
case other => Left(error(other))
}
Expand All @@ -179,8 +176,7 @@ trait PaymentMethodEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
externalUuidWithProfile(principal._2),
args._1
)
cmd.withCorrelationId(args._2) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, args._2).map {
case PaymentMethodDisabled => Right(PaymentMethodDisabled)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ trait RecurringPaymentEndpoints[SD <: SessionData with SessionDataDecorator[SD]]
debitedAccount = externalUuidWithProfile(session),
clientId = client.map(_.clientId).orElse(session.clientId)
)
updated.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(updated).map {
runCorrelated(updated, correlationId).map {
case r: RecurringPaymentRegistered => Right(r)
case r: MandateConfirmationRequired => Right(r)
case other => Left(error(other))
Expand Down Expand Up @@ -101,8 +100,7 @@ trait RecurringPaymentEndpoints[SD <: SessionData with SessionDataDecorator[SD]]
)
.serverLogic(principal => { case (cmd, correlationId) =>
val updated = cmd.copy(debitedAccount = externalUuidWithProfile(principal._2))
updated.withCorrelationId(correlationId) // Story 13.7 — origin stamp (after copy)
run(updated).map {
runCorrelated(updated, correlationId).map {
case r: RecurringCardPaymentRegistrationUpdated => Right(r.result)
case other => Left(error(other))
}
Expand All @@ -128,8 +126,7 @@ trait RecurringPaymentEndpoints[SD <: SessionData with SessionDataDecorator[SD]]
None,
Some(RecurringPayment.RecurringCardPaymentStatus.ENDED)
)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case r: RecurringCardPaymentRegistrationUpdated => Right(r.result)
case other => Left(error(other))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ trait UboDeclarationEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
val correlationId = args._2
val cmd =
CreateOrUpdateUbo(externalUuidWithProfile(principal._2), ubo)
cmd.withCorrelationId(correlationId) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, correlationId).map {
case r: UboCreatedOrUpdated => Right(r.ubo)
case other => Left(error(other))
}
Expand All @@ -61,7 +60,7 @@ trait UboDeclarationEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
.serverLogic(principal =>
cid => {
val cmd = GetUboDeclaration(externalUuidWithProfile(principal._2))
run(cmd).map {
runCorrelated(cmd, cid).map {
case r: UboDeclarationLoaded => Right(r.declaration.view)
case other => Left(error(other))
}
Expand Down Expand Up @@ -95,8 +94,7 @@ trait UboDeclarationEndpoints[SD <: SessionData with SessionDataDecorator[SD]] {
userAgent,
tokenId
)
cmd.withCorrelationId(cid) // Story 13.7 — origin stamp
run(cmd).map {
runCorrelated(cmd, cid).map {
case UboDeclarationAskedForValidation => Right(UboDeclarationAskedForValidation)
case other => Left(error(other))
}
Expand Down
Loading