idempotency key delivery fix

This commit is contained in:
Stephan D
2026-01-21 16:50:47 +01:00
parent 87f99be01d
commit bd5dfb4f26
11 changed files with 63 additions and 24 deletions

View File

@@ -11,8 +11,9 @@ part 'quotation.g.dart';
class PaymentQuoteResponse extends BaseAuthorizedResponse {
final PaymentQuoteDTO quote;
final String idempotencyKey;
const PaymentQuoteResponse({required super.accessToken, required this.quote});
const PaymentQuoteResponse({required super.accessToken, required this.idempotencyKey, required this.quote});
factory PaymentQuoteResponse.fromJson(Map<String, dynamic> json) => _$PaymentQuoteResponseFromJson(json);
@override

View File

@@ -9,6 +9,7 @@ part 'quotes.g.dart';
@JsonSerializable()
class PaymentQuotesDTO {
final String quoteRef;
final String idempotencyKey;
final PaymentQuoteAggregateDTO? aggregate;
final List<PaymentQuoteDTO>? quotes;
@@ -16,6 +17,7 @@ class PaymentQuotesDTO {
required this.quoteRef,
this.aggregate,
this.quotes,
required this.idempotencyKey,
});
factory PaymentQuotesDTO.fromJson(Map<String, dynamic> json) => _$PaymentQuotesDTOFromJson(json);

View File

@@ -9,11 +9,13 @@ extension PaymentQuotesDTOMapper on PaymentQuotesDTO {
quoteRef: quoteRef,
aggregate: aggregate?.toDomain(),
quotes: quotes?.map((quote) => quote.toDomain()).toList(),
idempotencyKey: idempotencyKey
);
}
extension PaymentQuotesMapper on PaymentQuotes {
PaymentQuotesDTO toDTO() => PaymentQuotesDTO(
idempotencyKey: idempotencyKey,
quoteRef: quoteRef,
aggregate: aggregate?.toDTO(),
quotes: quotes?.map((quote) => quote.toDTO()).toList(),

View File

@@ -1,3 +1,4 @@
import 'package:pshared/api/responses/payment/quotation.dart';
import 'package:pshared/models/payment/fees/line.dart';
import 'package:pshared/models/payment/fx/quote.dart';
import 'package:pshared/models/payment/money.dart';
@@ -23,3 +24,29 @@ class PaymentQuote {
required this.fxQuote,
});
}
class PaymentQuoteX extends PaymentQuote {
final String idempotencyKey;
const PaymentQuoteX({
required super.quoteRef,
required super.debitAmount,
required super.expectedSettlementAmount,
required super.expectedFeeTotal,
required super.feeLines,
required super.networkFee,
required super.fxQuote,
required this.idempotencyKey,
});
factory PaymentQuoteX.build({required PaymentQuote quote, required String idempotencyKey}) => PaymentQuoteX(
quoteRef: quote.quoteRef,
debitAmount: quote.debitAmount,
expectedSettlementAmount: quote.expectedSettlementAmount,
expectedFeeTotal: quote.expectedFeeTotal,
feeLines: quote.feeLines,
networkFee: quote.networkFee,
fxQuote: quote.fxQuote,
idempotencyKey: idempotencyKey,
);
}

View File

@@ -4,6 +4,7 @@ import 'package:pshared/models/payment/quote_aggregate.dart';
class PaymentQuotes {
final String quoteRef;
final String idempotencyKey;
final PaymentQuoteAggregate? aggregate;
final List<PaymentQuote>? quotes;
@@ -11,5 +12,6 @@ class PaymentQuotes {
required this.quoteRef,
required this.aggregate,
required this.quotes,
required this.idempotencyKey,
});
}

View File

@@ -28,10 +28,11 @@ import 'package:pshared/provider/recipient/pmethods.dart';
import 'package:pshared/provider/resource.dart';
import 'package:pshared/service/payment/quotation.dart';
import 'package:pshared/utils/currency.dart';
import 'package:pshared/utils/exception.dart';
class QuotationProvider extends ChangeNotifier {
Resource<PaymentQuote> _quotation = Resource(data: null, isLoading: false, error: null);
Resource<PaymentQuoteX> _quotation = Resource(data: null, isLoading: false, error: null);
late OrganizationsProvider _organizations;
bool _isLoaded = false;
@@ -162,7 +163,7 @@ class QuotationProvider extends ChangeNotifier {
return recipientName?.isNotEmpty == true ? recipientName : null;
}
void _setResource(Resource<PaymentQuote> quotation) {
void _setResource(Resource<PaymentQuoteX> quotation) {
_quotation = quotation;
notifyListeners();
}
@@ -181,11 +182,7 @@ class QuotationProvider extends ChangeNotifier {
_isLoaded = true;
_setResource(_quotation.copyWith(data: response, isLoading: false, error: null));
} catch (e) {
_setResource(_quotation.copyWith(
data: null,
error: e is Exception ? e : Exception(e.toString()),
isLoading: false,
));
_setResource(_quotation.copyWith(data: null, error: toException(e), isLoading: false));
}
notifyListeners();
return _quotation.data;

View File

@@ -16,14 +16,15 @@ class QuotationService {
static final _logger = Logger('service.payment.quotation');
static const String _objectType = Services.payments;
static Future<PaymentQuote> getQuotation(String organizationRef, QuotePaymentRequest request) async {
static Future<PaymentQuoteX> getQuotation(String organizationRef, QuotePaymentRequest request) async {
_logger.fine('Quoting payment for organization $organizationRef');
final response = await AuthorizationService.getPOSTResponse(
_objectType,
'/quote/$organizationRef',
request.toJson(),
);
return PaymentQuoteResponse.fromJson(response).quote.toDomain();
final resp = PaymentQuoteResponse.fromJson(response);
return PaymentQuoteX.build(quote: resp.quote.toDomain(), idempotencyKey: resp.idempotencyKey);
}
static Future<PaymentQuotes> getMultiQuotation(String organizationRef, QuotePaymentsRequest request) async {