complete MECE request
This commit is contained in:
@@ -4,7 +4,6 @@ import 'package:pshared/data/dto/money.dart';
|
||||
|
||||
part 'fx_quote.g.dart';
|
||||
|
||||
|
||||
@JsonSerializable()
|
||||
class FxQuoteDTO {
|
||||
final String? quoteRef;
|
||||
@@ -15,6 +14,7 @@ class FxQuoteDTO {
|
||||
final MoneyDTO? baseAmount;
|
||||
final MoneyDTO? quoteAmount;
|
||||
final int? expiresAtUnixMs;
|
||||
final int? pricedAtUnixMs;
|
||||
final String? provider;
|
||||
final String? rateRef;
|
||||
|
||||
@@ -30,11 +30,13 @@ class FxQuoteDTO {
|
||||
this.baseAmount,
|
||||
this.quoteAmount,
|
||||
this.expiresAtUnixMs,
|
||||
this.pricedAtUnixMs,
|
||||
this.provider,
|
||||
this.rateRef,
|
||||
this.firm = false,
|
||||
});
|
||||
|
||||
factory FxQuoteDTO.fromJson(Map<String, dynamic> json) => _$FxQuoteDTOFromJson(json);
|
||||
factory FxQuoteDTO.fromJson(Map<String, dynamic> json) =>
|
||||
_$FxQuoteDTOFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$FxQuoteDTOToJson(this);
|
||||
}
|
||||
|
||||
@@ -2,35 +2,36 @@ import 'package:pshared/data/dto/payment/fx_quote.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/models/payment/fx/quote.dart';
|
||||
|
||||
|
||||
extension FxQuoteDTOMapper on FxQuoteDTO {
|
||||
FxQuote toDomain() => FxQuote(
|
||||
quoteRef: quoteRef,
|
||||
baseCurrency: baseCurrency,
|
||||
quoteCurrency: quoteCurrency,
|
||||
side: side,
|
||||
price: price,
|
||||
baseAmount: baseAmount?.toDomain(),
|
||||
quoteAmount: quoteAmount?.toDomain(),
|
||||
expiresAtUnixMs: expiresAtUnixMs,
|
||||
provider: provider,
|
||||
rateRef: rateRef,
|
||||
firm: firm ?? false,
|
||||
);
|
||||
quoteRef: quoteRef,
|
||||
baseCurrency: baseCurrency,
|
||||
quoteCurrency: quoteCurrency,
|
||||
side: side,
|
||||
price: price,
|
||||
baseAmount: baseAmount?.toDomain(),
|
||||
quoteAmount: quoteAmount?.toDomain(),
|
||||
expiresAtUnixMs: expiresAtUnixMs,
|
||||
pricedAtUnixMs: pricedAtUnixMs,
|
||||
provider: provider,
|
||||
rateRef: rateRef,
|
||||
firm: firm ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
extension FxQuoteMapper on FxQuote {
|
||||
FxQuoteDTO toDTO() => FxQuoteDTO(
|
||||
quoteRef: quoteRef,
|
||||
baseCurrency: baseCurrency,
|
||||
quoteCurrency: quoteCurrency,
|
||||
side: side,
|
||||
price: price,
|
||||
baseAmount: baseAmount?.toDTO(),
|
||||
quoteAmount: quoteAmount?.toDTO(),
|
||||
expiresAtUnixMs: expiresAtUnixMs,
|
||||
provider: provider,
|
||||
rateRef: rateRef,
|
||||
firm: firm,
|
||||
);
|
||||
quoteRef: quoteRef,
|
||||
baseCurrency: baseCurrency,
|
||||
quoteCurrency: quoteCurrency,
|
||||
side: side,
|
||||
price: price,
|
||||
baseAmount: baseAmount?.toDTO(),
|
||||
quoteAmount: quoteAmount?.toDTO(),
|
||||
expiresAtUnixMs: expiresAtUnixMs,
|
||||
pricedAtUnixMs: pricedAtUnixMs,
|
||||
provider: provider,
|
||||
rateRef: rateRef,
|
||||
firm: firm,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:pshared/data/dto/payment/payment.dart';
|
||||
import 'package:pshared/data/mapper/payment/payment_quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote.dart';
|
||||
import 'package:pshared/models/payment/payment.dart';
|
||||
import 'package:pshared/models/payment/state.dart';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:pshared/data/dto/payment/payment_quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/fee_line.dart';
|
||||
import 'package:pshared/data/mapper/payment/fees/line.dart';
|
||||
import 'package:pshared/data/mapper/payment/fx_quote.dart';
|
||||
import 'package:pshared/data/mapper/money.dart';
|
||||
import 'package:pshared/data/mapper/payment/network_fee.dart';
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:pshared/data/dto/payment/quotes.dart';
|
||||
import 'package:pshared/data/mapper/payment/payment_quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote/aggregate.dart';
|
||||
import 'package:pshared/models/payment/quote/quotes.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:pshared/models/money.dart';
|
||||
|
||||
|
||||
class FxQuote {
|
||||
final String? quoteRef;
|
||||
final String? baseCurrency;
|
||||
@@ -10,6 +9,7 @@ class FxQuote {
|
||||
final Money? baseAmount;
|
||||
final Money? quoteAmount;
|
||||
final int? expiresAtUnixMs;
|
||||
final int? pricedAtUnixMs;
|
||||
final String? provider;
|
||||
final String? rateRef;
|
||||
final bool firm;
|
||||
@@ -23,6 +23,7 @@ class FxQuote {
|
||||
required this.baseAmount,
|
||||
required this.quoteAmount,
|
||||
required this.expiresAtUnixMs,
|
||||
required this.pricedAtUnixMs,
|
||||
required this.provider,
|
||||
required this.rateRef,
|
||||
this.firm = false,
|
||||
|
||||
@@ -12,7 +12,6 @@ import 'package:pshared/provider/resource.dart';
|
||||
import 'package:pshared/service/payment/multiple.dart';
|
||||
import 'package:pshared/utils/exception.dart';
|
||||
|
||||
|
||||
class MultiQuotationProvider extends ChangeNotifier {
|
||||
static const Duration _autoRefreshLead = Duration(seconds: 5);
|
||||
|
||||
@@ -87,10 +86,13 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
|
||||
_setResource(_quotation.copyWith(isLoading: true, error: null));
|
||||
try {
|
||||
final effectiveIdempotencyKey = previewOnly
|
||||
? ''
|
||||
: (idempotencyKey ?? const Uuid().v4());
|
||||
final response = await MultiplePaymentsService.getQuotation(
|
||||
organization.current.id,
|
||||
QuotePaymentsRequest(
|
||||
idempotencyKey: idempotencyKey ?? const Uuid().v4(),
|
||||
idempotencyKey: effectiveIdempotencyKey,
|
||||
metadata: metadata,
|
||||
intents: intents.map((intent) => intent.toDTO()).toList(),
|
||||
previewOnly: previewOnly,
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:pshared/api/requests/payment/quote.dart';
|
||||
import 'package:pshared/api/requests/payment/quotes.dart';
|
||||
import 'package:pshared/api/responses/payment/quotation.dart';
|
||||
import 'package:pshared/api/responses/payment/quotes.dart';
|
||||
import 'package:pshared/data/mapper/payment/payment_quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote.dart';
|
||||
import 'package:pshared/data/mapper/payment/quote/quotes.dart';
|
||||
import 'package:pshared/models/payment/quote/quote.dart';
|
||||
import 'package:pshared/models/payment/quote/quotes.dart';
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:test/test.dart';
|
||||
import 'package:pshared/api/requests/payment/initiate.dart';
|
||||
import 'package:pshared/api/requests/payment/initiate_payments.dart';
|
||||
import 'package:pshared/api/requests/payment/quote.dart';
|
||||
import 'package:pshared/api/responses/payment/quotation.dart';
|
||||
import 'package:pshared/data/dto/money.dart';
|
||||
import 'package:pshared/data/dto/payment/endpoint.dart';
|
||||
import 'package:pshared/data/dto/payment/intent/payment.dart';
|
||||
@@ -40,7 +41,7 @@ void main() {
|
||||
|
||||
test('quote payment request uses expected backend field names', () {
|
||||
final request = QuotePaymentRequest(
|
||||
idempotencyKey: 'idem-1',
|
||||
idempotencyKey: '',
|
||||
previewOnly: true,
|
||||
intent: const PaymentIntentDTO(
|
||||
kind: 'payout',
|
||||
@@ -60,7 +61,7 @@ void main() {
|
||||
final json =
|
||||
jsonDecode(jsonEncode(request.toJson())) as Map<String, dynamic>;
|
||||
|
||||
expect(json['idempotencyKey'], equals('idem-1'));
|
||||
expect(json['idempotencyKey'], equals(''));
|
||||
expect(json['previewOnly'], isTrue);
|
||||
expect(json['intent'], isA<Map<String, dynamic>>());
|
||||
|
||||
@@ -75,6 +76,34 @@ void main() {
|
||||
expect(destination['type'], equals('cardToken'));
|
||||
});
|
||||
|
||||
test('quote response parses backend fx quote pricedAtUnixMs', () {
|
||||
final response = PaymentQuoteResponse.fromJson({
|
||||
'accessToken': {'token': 'token', 'expiration': '2026-02-25T00:00:00Z'},
|
||||
'idempotencyKey': 'idem-1',
|
||||
'quote': {
|
||||
'quoteRef': 'q-1',
|
||||
'debitAmount': {'amount': '10', 'currency': 'USDT'},
|
||||
'expectedSettlementAmount': {'amount': '760', 'currency': 'RUB'},
|
||||
'fxQuote': {
|
||||
'quoteRef': 'fx-1',
|
||||
'baseCurrency': 'USDT',
|
||||
'quoteCurrency': 'RUB',
|
||||
'side': 'sell_base_buy_quote',
|
||||
'price': '76',
|
||||
'baseAmount': {'amount': '10', 'currency': 'USDT'},
|
||||
'quoteAmount': {'amount': '760', 'currency': 'RUB'},
|
||||
'expiresAtUnixMs': 1771945907749,
|
||||
'pricedAtUnixMs': 1771945907000,
|
||||
'provider': 'binance',
|
||||
'rateRef': 'rate-1',
|
||||
'firm': false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.quote.fxQuote?.pricedAtUnixMs, equals(1771945907000));
|
||||
});
|
||||
|
||||
test('initiate payment by quote keeps expected fields', () {
|
||||
final request = InitiatePaymentRequest(
|
||||
idempotencyKey: 'idem-2',
|
||||
|
||||
Reference in New Issue
Block a user