better logging + fixed tg messaging #400

Merged
tech merged 1 commits from wp-399 into main 2026-02-03 14:19:36 +00:00
7 changed files with 38 additions and 20 deletions
Showing only changes of commit 446d4d737c - Show all commits

View File

@@ -111,6 +111,8 @@ func (s *Service) SubmitOperation(ctx context.Context, req *connectorv1.SubmitOp
zap.String("amount", strings.TrimSpace(normalizedAmount.GetAmount())), zap.String("amount", strings.TrimSpace(normalizedAmount.GetAmount())),
zap.String("currency", strings.TrimSpace(normalizedAmount.GetCurrency())), zap.String("currency", strings.TrimSpace(normalizedAmount.GetCurrency())),
zap.String("quote_ref", quoteRef), zap.String("quote_ref", quoteRef),
zap.String("operation_ref", req.Operation.GetOperationRef()),
zap.String("intent_ref", op.GetIntentRef()),
zap.String("outgoing_leg", outgoingLeg), zap.String("outgoing_leg", outgoingLeg),
) )
logFields = append(logFields, transferDestinationLogFields(dest)...) logFields = append(logFields, transferDestinationLogFields(dest)...)
@@ -209,13 +211,15 @@ func transferToOperation(transfer *chainv1.Transfer) *connectorv1.Operation {
return nil return nil
} }
op := &connectorv1.Operation{ op := &connectorv1.Operation{
OperationId: strings.TrimSpace(transfer.GetTransferRef()), OperationId: strings.TrimSpace(transfer.GetTransferRef()),
Type: connectorv1.OperationType_TRANSFER, Type: connectorv1.OperationType_TRANSFER,
Status: transferStatusToOperation(transfer.GetStatus()), Status: transferStatusToOperation(transfer.GetStatus()),
Money: transfer.GetRequestedAmount(), Money: transfer.GetRequestedAmount(),
ProviderRef: strings.TrimSpace(transfer.GetTransferRef()), ProviderRef: strings.TrimSpace(transfer.GetTransferRef()),
CreatedAt: transfer.GetCreatedAt(), IntentRef: strings.TrimSpace(transfer.GetIntentRef()),
UpdatedAt: transfer.GetUpdatedAt(), OperationRef: strings.TrimSpace(transfer.GetOperationRef()),
CreatedAt: transfer.GetCreatedAt(),
UpdatedAt: transfer.GetUpdatedAt(),
} }
if source := strings.TrimSpace(transfer.GetSourceWalletRef()); source != "" { if source := strings.TrimSpace(transfer.GetSourceWalletRef()); source != "" {
op.From = &connectorv1.OperationParty{Ref: &connectorv1.OperationParty_Account{Account: &connectorv1.AccountRef{ op.From = &connectorv1.OperationParty{Ref: &connectorv1.OperationParty_Account{Account: &connectorv1.AccountRef{
@@ -287,6 +291,7 @@ func operationLogFields(op *connectorv1.Operation) []zap.Field {
zap.String("correlation_id", strings.TrimSpace(op.GetCorrelationId())), zap.String("correlation_id", strings.TrimSpace(op.GetCorrelationId())),
zap.String("parent_intent_id", strings.TrimSpace(op.GetParentIntentId())), zap.String("parent_intent_id", strings.TrimSpace(op.GetParentIntentId())),
zap.String("operation_type", op.GetType().String()), zap.String("operation_type", op.GetType().String()),
zap.String("intent_ref", strings.TrimSpace(op.GetIntentRef())),
} }
} }

View File

@@ -169,6 +169,8 @@ func (s *Service) SubmitTransfer(ctx context.Context, req *chainv1.SubmitTransfe
zap.String("rail", intent.OutgoingLeg), zap.String("rail", intent.OutgoingLeg),
zap.String("organization_ref", strings.TrimSpace(req.GetOrganizationRef())), zap.String("organization_ref", strings.TrimSpace(req.GetOrganizationRef())),
zap.String("source_wallet_ref", strings.TrimSpace(req.GetSourceWalletRef())), zap.String("source_wallet_ref", strings.TrimSpace(req.GetSourceWalletRef())),
zap.String("operation_ref", strings.TrimSpace(req.GetOperationRef())),
zap.String("intent_ref", strings.TrimSpace(req.GetIntentRef())),
} }
if intent.RequestedMoney != nil { if intent.RequestedMoney != nil {
logFields = append(logFields, logFields = append(logFields,
@@ -243,6 +245,10 @@ func (s *Service) onIntent(ctx context.Context, intent *model.PaymentGatewayInte
s.logger.Warn("Payment gateway intent rejected", zap.String("reason", "payment_intent_id is required"), zap.String("idempotency_key", intent.IdempotencyKey)) s.logger.Warn("Payment gateway intent rejected", zap.String("reason", "payment_intent_id is required"), zap.String("idempotency_key", intent.IdempotencyKey))
return merrors.InvalidArgument("payment_intent_id is required", "payment_intent_id") return merrors.InvalidArgument("payment_intent_id is required", "payment_intent_id")
} }
if intent.IntentRef == "" {
s.logger.Warn("Payment gateway intent rejected", zap.String("reason", "payment_intent_ref is required"), zap.String("idempotency_key", intent.IdempotencyKey))
return merrors.InvalidArgument("payment_intent_ref is required", "payment_intent_ref")
}
if intent.RequestedMoney == nil || strings.TrimSpace(intent.RequestedMoney.Amount) == "" || strings.TrimSpace(intent.RequestedMoney.Currency) == "" { if intent.RequestedMoney == nil || strings.TrimSpace(intent.RequestedMoney.Amount) == "" || strings.TrimSpace(intent.RequestedMoney.Currency) == "" {
s.logger.Warn("Payment gateway intent rejected", zap.String("reason", "requested_money is required"), zap.String("idempotency_key", intent.IdempotencyKey)) s.logger.Warn("Payment gateway intent rejected", zap.String("reason", "requested_money is required"), zap.String("idempotency_key", intent.IdempotencyKey))
return merrors.InvalidArgument("requested_money is required", "requested_money") return merrors.InvalidArgument("requested_money is required", "requested_money")
@@ -274,7 +280,8 @@ func (s *Service) onIntent(ctx context.Context, intent *model.PaymentGatewayInte
record := paymentRecordFromIntent(intent, confirmReq) record := paymentRecordFromIntent(intent, confirmReq)
if err := s.updateTransferStatus(ctx, record); err != nil { if err := s.updateTransferStatus(ctx, record); err != nil {
s.logger.Warn("Failed to persist payment record", zap.Error(err), zap.String("idempotency_key", confirmReq.RequestID)) s.logger.Warn("Failed to persist payment record", zap.Error(err),
zap.String("idempotency_key", confirmReq.RequestID), zap.String("intent_ref", record.IntentRef))
return err return err
} }
if err := s.sendConfirmationRequest(confirmReq); err != nil { if err := s.sendConfirmationRequest(confirmReq); err != nil {
@@ -397,6 +404,8 @@ func (s *Service) buildConfirmationRequest(intent *model.PaymentGatewayIntent) (
TimeoutSeconds: timeout, TimeoutSeconds: timeout,
SourceService: string(mservice.PaymentGateway), SourceService: string(mservice.PaymentGateway),
Rail: rail, Rail: rail,
OperationRef: intent.OperationRef,
IntentRef: intent.IntentRef,
}, nil }, nil
} }
@@ -562,6 +571,10 @@ func intentFromSubmitTransfer(req *chainv1.SubmitTransferRequest, defaultRail, d
if idempotencyKey == "" { if idempotencyKey == "" {
return nil, merrors.InvalidArgument("submit_transfer: idempotency_key is required") return nil, merrors.InvalidArgument("submit_transfer: idempotency_key is required")
} }
intentRef := strings.TrimSpace(req.GetIntentRef())
if intentRef == "" {
return nil, merrors.InvalidArgument("submit_transfer: intent_ref is required")
}
amount := req.GetAmount() amount := req.GetAmount()
if amount == nil { if amount == nil {
return nil, merrors.InvalidArgument("submit_transfer: amount is required") return nil, merrors.InvalidArgument("submit_transfer: amount is required")
@@ -609,6 +622,7 @@ func intentFromSubmitTransfer(req *chainv1.SubmitTransferRequest, defaultRail, d
OutgoingLeg: outgoingLeg, OutgoingLeg: outgoingLeg,
QuoteRef: quoteRef, QuoteRef: quoteRef,
RequestedMoney: requestedMoney, RequestedMoney: requestedMoney,
IntentRef: intentRef,
}, nil }, nil
} }

View File

@@ -9,7 +9,6 @@ import (
"github.com/tech/sendico/pkg/mservice" "github.com/tech/sendico/pkg/mservice"
"github.com/tech/sendico/pkg/mutil/mzap" "github.com/tech/sendico/pkg/mutil/mzap"
"github.com/tech/sendico/pkg/payments/rail" "github.com/tech/sendico/pkg/payments/rail"
gatewayv1 "github.com/tech/sendico/pkg/proto/common/gateway/v1"
"go.uber.org/zap" "go.uber.org/zap"
) )
@@ -35,15 +34,6 @@ func toOpStatus(t *model.PaymentRecord) rail.OperationResult {
} }
} }
func toError(t *model.PaymentRecord) *gatewayv1.OperationError {
if t.Status == model.PaymentStatusSuccess {
return nil
}
return &gatewayv1.OperationError{
Message: t.FailureReason,
}
}
func (s *Service) updateTransferStatus(ctx context.Context, record *model.PaymentRecord) error { func (s *Service) updateTransferStatus(ctx context.Context, record *model.PaymentRecord) error {
if err := s.repo.Payments().Upsert(ctx, record); err != nil { if err := s.repo.Payments().Upsert(ctx, record); err != nil {
s.logger.Warn("Failed to update transfer status", zap.String("payment_ref", record.PaymentIntentID), zap.String("status", string(record.Status)), zap.Error(err)) s.logger.Warn("Failed to update transfer status", zap.String("payment_ref", record.PaymentIntentID), zap.String("status", string(record.Status)), zap.Error(err))

View File

@@ -82,6 +82,10 @@ func (p *Payments) Upsert(ctx context.Context, record *model.PaymentRecord) erro
record.QuoteRef = strings.TrimSpace(record.QuoteRef) record.QuoteRef = strings.TrimSpace(record.QuoteRef)
record.OutgoingLeg = strings.TrimSpace(record.OutgoingLeg) record.OutgoingLeg = strings.TrimSpace(record.OutgoingLeg)
record.TargetChatID = strings.TrimSpace(record.TargetChatID) record.TargetChatID = strings.TrimSpace(record.TargetChatID)
record.IntentRef = strings.TrimSpace(record.IntentRef)
if record.PaymentIntentID == "" {
return merrors.InvalidArgument("intention reference is required", "payment_intent_ref")
}
if record.IdempotencyKey == "" { if record.IdempotencyKey == "" {
return merrors.InvalidArgument("idempotency key is required", "idempotency_key") return merrors.InvalidArgument("idempotency key is required", "idempotency_key")
} }

View File

@@ -295,7 +295,7 @@ func (p *paymentExecutor) executeSendStep(
} }
logger.Info("Sending provider settlement transfer", logger.Info("Sending provider settlement transfer",
zap.String("idempotency", req.IdempotencyKey), zap.String("idempotency", req.IdempotencyKey), zap.String("intent_ref", req.IntentRef),
) )
result, err := gw.Send(ctx, req) result, err := gw.Send(ctx, req)

View File

@@ -31,6 +31,10 @@ func (p *paymentExecutor) buildProviderSettlementTransferRequest(payment *model.
if requestID == "" { if requestID == "" {
return rail.TransferRequest{}, merrors.InvalidArgument("provider settlement: idempotency key is required") return rail.TransferRequest{}, merrors.InvalidArgument("provider settlement: idempotency key is required")
} }
intentRef := strings.TrimSpace(payment.Intent.Ref)
if intentRef == "" {
return rail.TransferRequest{}, merrors.InvalidArgument("provider settlement: intention ref is required")
}
paymentRef := strings.TrimSpace(payment.PaymentRef) paymentRef := strings.TrimSpace(payment.PaymentRef)
if paymentRef == "" { if paymentRef == "" {
return rail.TransferRequest{}, merrors.InvalidArgument("provider settlement: payment_ref is required") return rail.TransferRequest{}, merrors.InvalidArgument("provider settlement: payment_ref is required")
@@ -88,7 +92,7 @@ func (p *paymentExecutor) buildProviderSettlementTransferRequest(payment *model.
Metadata: metadata, Metadata: metadata,
PaymentRef: paymentRef, PaymentRef: paymentRef,
OperationRef: operationRef, OperationRef: operationRef,
IntentRef: payment.Intent.Ref, IntentRef: intentRef,
} }
if fromRole != nil { if fromRole != nil {
req.FromRole = *fromRole req.FromRole = *fromRole

View File

@@ -153,6 +153,7 @@ message Transfer {
google.protobuf.Timestamp updated_at = 14; google.protobuf.Timestamp updated_at = 14;
string intent_ref = 15; string intent_ref = 15;
string payment_ref = 16; string payment_ref = 16;
string operation_ref = 17;
} }
message SubmitTransferRequest { message SubmitTransferRequest {