wallets listing dedupe

This commit is contained in:
Stephan D
2026-02-20 13:52:09 +01:00
parent e23484ddff
commit 20cb057618
40 changed files with 3166 additions and 423 deletions

View File

@@ -30,6 +30,11 @@ func (s *QuotationServiceV2) singleResultFromRecord(record *model.PaymentQuoteRe
if err != nil {
return nil, err
}
intentRef := strings.TrimSpace(record.Intent.Ref)
if len(record.Intents) == 1 {
intentRef = firstNonEmpty(strings.TrimSpace(record.Intents[0].Ref), intentRef)
}
mapped.Quote.IntentRef = intentRef
return &QuotePaymentResult{
Response: &quotationv2.QuotePaymentResponse{
Quote: mapped.Quote,
@@ -67,6 +72,9 @@ func (s *QuotationServiceV2) batchResultFromRecord(record *model.PaymentQuoteRec
if err != nil {
return nil, err
}
if idx < len(record.Intents) {
mapped.Quote.IntentRef = strings.TrimSpace(record.Intents[idx].Ref)
}
quotes = append(quotes, mapped.Quote)
}

View File

@@ -67,6 +67,9 @@ func TestQuotePayment_USDTToRUB_EndToEnd(t *testing.T) {
if got, want := quote.GetQuoteRef(), "quote-single-usdt-rub"; got != want {
t.Fatalf("unexpected quote_ref: got=%q want=%q", got, want)
}
if got, want := quote.GetIntentRef(), "q-intent-single"; got != want {
t.Fatalf("unexpected intent_ref: got=%q want=%q", got, want)
}
if got, want := quote.GetState(), quotationv2.QuoteState_QUOTE_STATE_EXECUTABLE; got != want {
t.Fatalf("unexpected state: got=%s want=%s", got.String(), want.String())
}
@@ -175,6 +178,9 @@ func TestQuotePayment_USDTToRUB_EndToEnd(t *testing.T) {
if got := strings.TrimSpace(reused.Response.GetQuote().GetRoute().GetProvider()); got != "" {
t.Fatalf("expected idempotent route provider header to be empty, got=%q", got)
}
if got, want := reused.Response.GetQuote().GetIntentRef(), "q-intent-single"; got != want {
t.Fatalf("unexpected idempotent intent_ref: got=%q want=%q", got, want)
}
t.Logf("single request:\n%s", mustProtoJSON(t, req))
t.Logf("single response:\n%s", mustProtoJSON(t, result.Response))
@@ -290,6 +296,9 @@ func TestQuotePayments_USDTToRUB_ThreeItems_EndToEnd(t *testing.T) {
if quote == nil {
t.Fatalf("quote[%d] is nil", i)
}
if got := strings.TrimSpace(quote.GetIntentRef()); got == "" {
t.Fatalf("expected intent_ref for item %d", i)
}
if quote.GetQuoteRef() != "quote-batch-usdt-rub" {
t.Fatalf("unexpected quote_ref for item %d: %q", i, quote.GetQuoteRef())
}

View File

@@ -3,6 +3,7 @@ package quotation_service_v2
import (
"context"
"sort"
"strings"
"time"
"github.com/tech/sendico/payments/quotation/internal/service/quotation/batch_quote_processor_v2"
@@ -165,6 +166,10 @@ func (p *singleIntentProcessorV2) Process(
if mapped == nil || mapped.Quote == nil {
return nil, merrors.InvalidArgument("mapped quote is required")
}
mapped.Quote.IntentRef = firstNonEmpty(
strings.TrimSpace(planItem.Intent.Ref),
strings.TrimSpace(in.Item.Intent.Ref),
)
expiresAt := result.ExpiresAt
if quoteExpiresAt := mapped.Quote.GetExpiresAt(); quoteExpiresAt != nil {
expiresAt = quoteExpiresAt.AsTime().UTC()