From f84d52ac140700f37c5120ecf2902481ceb39df7 Mon Sep 17 00:00:00 2001 From: Stephan D Date: Mon, 19 Jan 2026 12:14:54 +0100 Subject: [PATCH] enhanced paymemnt route handling error --- .../service/orchestrator/payment_executor.go | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/api/payments/orchestrator/internal/service/orchestrator/payment_executor.go b/api/payments/orchestrator/internal/service/orchestrator/payment_executor.go index ff82156e..3e94417a 100644 --- a/api/payments/orchestrator/internal/service/orchestrator/payment_executor.go +++ b/api/payments/orchestrator/internal/service/orchestrator/payment_executor.go @@ -49,6 +49,7 @@ func (p *paymentExecutor) executePayment(ctx context.Context, store storage.Paym } plan, err := builder.Build(ctx, payment, quote, routeStore, planTemplates, p.svc.deps.gatewayRegistry) if err != nil { + p.logPlanBuilderFailure(payment, err) return p.failPayment(ctx, store, payment, model.PaymentFailureCodePolicy, strings.TrimSpace(err.Error()), err) } if plan == nil || len(plan.Steps) == 0 { @@ -59,6 +60,55 @@ func (p *paymentExecutor) executePayment(ctx context.Context, store storage.Paym return p.executePaymentPlan(ctx, store, payment, quote) } +func (p *paymentExecutor) logPlanBuilderFailure(payment *model.Payment, err error) { + if p == nil || payment == nil { + return + } + intent := payment.Intent + sourceRail, sourceNetwork, sourceErr := railFromEndpoint(intent.Source, intent.Attributes, true) + destRail, destNetwork, destErr := railFromEndpoint(intent.Destination, intent.Attributes, false) + + fields := []zap.Field{ + zap.Error(err), + zap.String("payment_ref", payment.PaymentRef), + zap.String("org_ref", payment.OrganizationRef.Hex()), + zap.String("idempotency_key", payment.IdempotencyKey), + zap.String("source_rail", string(sourceRail)), + zap.String("destination_rail", string(destRail)), + zap.String("source_network", sourceNetwork), + zap.String("destination_network", destNetwork), + zap.String("source_endpoint_type", string(intent.Source.Type)), + zap.String("destination_endpoint_type", string(intent.Destination.Type)), + } + + missing := make([]string, 0, 2) + if sourceErr != nil || sourceRail == model.RailUnspecified { + missing = append(missing, "source") + if sourceErr != nil { + fields = append(fields, zap.String("source_rail_error", sourceErr.Error())) + } + } + if destErr != nil || destRail == model.RailUnspecified { + missing = append(missing, "destination") + if destErr != nil { + fields = append(fields, zap.String("destination_rail_error", destErr.Error())) + } + } + if len(missing) > 0 { + fields = append(fields, zap.String("missing_rails", strings.Join(missing, ","))) + p.logger.Warn("Payment rail resolution failed", fields...) + return + } + + routeNetwork, routeErr := resolveRouteNetwork(intent.Attributes, sourceNetwork, destNetwork) + if routeErr != nil { + fields = append(fields, zap.String("route_network_error", routeErr.Error())) + } else if routeNetwork != "" { + fields = append(fields, zap.String("route_network", routeNetwork)) + } + p.logger.Warn("Payment route missing for rails", fields...) +} + func (p *paymentExecutor) applyFX(ctx context.Context, payment *model.Payment, quote *orchestratorv1.PaymentQuote, charges []*ledgerv1.PostingLine, description string, metadata map[string]string, exec *model.ExecutionRefs) error { intent := payment.Intent source := intent.Source.Ledger