fixed tgsettle upsert logic

This commit is contained in:
Stephan D
2026-03-06 13:50:13 +01:00
parent 2b1b4135f4
commit 4295456f63
4 changed files with 278 additions and 22 deletions

View File

@@ -119,25 +119,30 @@ func (p *Payments) Upsert(ctx context.Context, record *model.PaymentRecord) erro
return merrors.InvalidArgument("intention reference key is required", "intent_ref")
}
filter := repository.Filter(fieldIdempotencyKey, record.IdempotencyKey)
err := p.repo.Insert(ctx, record, filter)
if errors.Is(err, merrors.ErrDataConflict) {
patch := repository.Patch().
Set(repository.Field(fieldOperationRef), record.OperationRef).
Set(repository.Field("paymentIntentId"), record.PaymentIntentID).
Set(repository.Field("quoteRef"), record.QuoteRef).
Set(repository.Field("intentRef"), record.IntentRef).
Set(repository.Field("paymentRef"), record.PaymentRef).
Set(repository.Field("outgoingLeg"), record.OutgoingLeg).
Set(repository.Field("targetChatId"), record.TargetChatID).
Set(repository.Field("requestedMoney"), record.RequestedMoney).
Set(repository.Field("executedMoney"), record.ExecutedMoney).
Set(repository.Field("status"), record.Status).
Set(repository.Field("failureReason"), record.FailureReason).
Set(repository.Field("executedAt"), record.ExecutedAt).
Set(repository.Field("expiresAt"), record.ExpiresAt).
Set(repository.Field("expiredAt"), record.ExpiredAt)
_, err = p.repo.PatchMany(ctx, filter, patch)
existing, err := p.FindByIdempotencyKey(ctx, record.IdempotencyKey)
if err != nil {
return err
}
if existing != nil {
record.ID = existing.ID
if record.CreatedAt.IsZero() {
record.CreatedAt = existing.CreatedAt
}
}
err = p.repo.Upsert(ctx, record)
if mongo.IsDuplicateKeyError(err) {
// Concurrent insert by idempotency key: resolve existing ID and retry replace-by-ID.
existing, lookupErr := p.FindByIdempotencyKey(ctx, record.IdempotencyKey)
if lookupErr != nil {
err = lookupErr
} else if existing != nil {
record.ID = existing.ID
if record.CreatedAt.IsZero() {
record.CreatedAt = existing.CreatedAt
}
err = p.repo.Upsert(ctx, record)
}
}
if err != nil {
if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) {