mece request / payment economics

This commit is contained in:
Stephan D
2026-02-24 18:02:20 +01:00
parent 2e08ec9b9b
commit 4c5677202a
32 changed files with 704 additions and 223 deletions

View File

@@ -7,7 +7,6 @@ import 'package:pshared/data/dto/money.dart';
part 'payment.g.dart';
@JsonSerializable()
class PaymentIntentDTO {
final String? kind;
@@ -20,9 +19,6 @@ class PaymentIntentDTO {
@JsonKey(name: 'settlement_mode')
final String? settlementMode;
@JsonKey(name: 'settlement_currency')
final String? settlementCurrency;
@JsonKey(name: "fee_treatment")
final String? feeTreatment;
@@ -36,12 +32,12 @@ class PaymentIntentDTO {
this.amount,
this.fx,
this.settlementMode,
this.settlementCurrency,
this.attributes,
this.customer,
this.feeTreatment,
});
factory PaymentIntentDTO.fromJson(Map<String, dynamic> json) => _$PaymentIntentDTOFromJson(json);
factory PaymentIntentDTO.fromJson(Map<String, dynamic> json) =>
_$PaymentIntentDTOFromJson(json);
Map<String, dynamic> toJson() => _$PaymentIntentDTOToJson(this);
}

View File

@@ -7,7 +7,6 @@ import 'package:pshared/data/mapper/payment/intent/fx.dart';
import 'package:pshared/data/mapper/money.dart';
import 'package:pshared/models/payment/intent.dart';
extension PaymentIntentMapper on PaymentIntent {
PaymentIntentDTO toDTO() => PaymentIntentDTO(
kind: paymentKindToValue(kind),
@@ -16,7 +15,6 @@ extension PaymentIntentMapper on PaymentIntent {
amount: amount?.toDTO(),
fx: fx?.toDTO(),
settlementMode: settlementModeToValue(settlementMode),
settlementCurrency: settlementCurrency,
attributes: attributes,
customer: customer?.toDTO(),
feeTreatment: feeTreatmentToValue(feeTreatment),
@@ -31,7 +29,6 @@ extension PaymentIntentDTOMapper on PaymentIntentDTO {
amount: amount?.toDomain(),
fx: fx?.toDomain(),
settlementMode: settlementModeFromValue(settlementMode),
settlementCurrency: settlementCurrency,
attributes: attributes,
customer: customer?.toDomain(),
feeTreatment: feeTreatmentFromValue(feeTreatment),

View File

@@ -6,7 +6,6 @@ import 'package:pshared/models/payment/methods/data.dart';
import 'package:pshared/models/money.dart';
import 'package:pshared/models/payment/settlement_mode.dart';
class PaymentIntent {
final PaymentKind kind;
final PaymentMethodData? source;
@@ -15,7 +14,6 @@ class PaymentIntent {
final FxIntent? fx;
final FeeTreatment feeTreatment;
final SettlementMode settlementMode;
final String? settlementCurrency;
final Map<String, String>? attributes;
final Customer? customer;
@@ -26,7 +24,6 @@ class PaymentIntent {
this.amount,
this.fx,
this.settlementMode = SettlementMode.unspecified,
this.settlementCurrency,
this.attributes,
this.customer,
required this.feeTreatment,

View File

@@ -21,7 +21,6 @@ import 'package:pshared/provider/recipient/provider.dart';
import 'package:pshared/utils/currency.dart';
import 'package:pshared/utils/payment/fx_helpers.dart';
class QuotationIntentBuilder {
PaymentIntent? build({
required PaymentAmountProvider payment,
@@ -45,8 +44,10 @@ class QuotationIntentBuilder {
// TODO: adapt to possible other sources
currency: sourceCurrency,
);
final isCryptoToCrypto = paymentData is CryptoAddressPaymentMethod &&
(paymentData.asset?.tokenSymbol ?? '').trim().toUpperCase() == amount.currency;
final isCryptoToCrypto =
paymentData is CryptoAddressPaymentMethod &&
(paymentData.asset?.tokenSymbol ?? '').trim().toUpperCase() ==
amount.currency;
final fxIntent = FxIntentHelper.buildSellBaseBuyQuote(
baseCurrency: sourceCurrency,
quoteCurrency: 'RUB', // TODO: exentd target currencies
@@ -61,15 +62,13 @@ class QuotationIntentBuilder {
asset: PaymentAsset(
tokenSymbol: selectedWallet.tokenSymbol ?? '',
chain: selectedWallet.network ?? ChainNetwork.unspecified,
)
),
),
fx: fxIntent,
feeTreatment: payment.payerCoversFee ? FeeTreatment.addToSource : FeeTreatment.deductFromDestination,
feeTreatment: payment.payerCoversFee
? FeeTreatment.addToSource
: FeeTreatment.deductFromDestination,
settlementMode: SettlementMode.fixSource,
settlementCurrency: FxIntentHelper.resolveSettlementCurrency(
amount: amount,
fx: fxIntent,
),
customer: customer,
);
}
@@ -92,8 +91,9 @@ class QuotationIntentBuilder {
: name.trim().split(RegExp(r'\s+'));
final firstName = parts.isNotEmpty ? parts.first : null;
final lastName = parts.length >= 2 ? parts.last : null;
final middleName =
parts.length > 2 ? parts.sublist(1, parts.length - 1).join(' ') : null;
final middleName = parts.length > 2
? parts.sublist(1, parts.length - 1).join(' ')
: null;
return Customer(
id: id,
@@ -120,7 +120,9 @@ class QuotationIntentBuilder {
return iban.accountHolder.trim();
}
final bank = method?.bankAccountData ?? (data is RussianBankAccountPaymentMethod ? data : null);
final bank =
method?.bankAccountData ??
(data is RussianBankAccountPaymentMethod ? data : null);
if (bank != null && bank.recipientName.trim().isNotEmpty) {
return bank.recipientName.trim();
}

View File

@@ -54,7 +54,6 @@ void main() {
),
amount: MoneyDTO(amount: '10', currency: 'USD'),
settlementMode: 'fix_received',
settlementCurrency: 'USD',
),
);
@@ -68,7 +67,7 @@ void main() {
final intent = json['intent'] as Map<String, dynamic>;
expect(intent['kind'], equals('payout'));
expect(intent['settlement_mode'], equals('fix_received'));
expect(intent['settlement_currency'], equals('USD'));
expect(intent.containsKey('settlement_currency'), isFalse);
final source = intent['source'] as Map<String, dynamic>;
final destination = intent['destination'] as Map<String, dynamic>;

View File

@@ -13,7 +13,6 @@ import 'package:pshared/utils/payment/fx_helpers.dart';
import 'package:pweb/models/payment/multiple_payouts/csv_row.dart';
class MultipleIntentBuilder {
static const String _currency = 'RUB';
@@ -36,33 +35,27 @@ class MultipleIntentBuilder {
);
return rows
.map(
(row) {
final amount = Money(amount: row.amount, currency: _currency);
return PaymentIntent(
kind: PaymentKind.payout,
source: ManagedWalletPaymentMethod(
managedWalletRef: sourceWallet.id,
asset: sourceAsset,
),
destination: CardPaymentMethod(
pan: row.pan,
firstName: row.firstName,
lastName: row.lastName,
expMonth: row.expMonth,
expYear: row.expYear,
),
amount: amount,
feeTreatment: FeeTreatment.addToSource,
settlementMode: SettlementMode.fixReceived,
settlementCurrency: FxIntentHelper.resolveSettlementCurrency(
amount: amount,
fx: fxIntent,
),
fx: fxIntent,
);
},
)
.map((row) {
final amount = Money(amount: row.amount, currency: _currency);
return PaymentIntent(
kind: PaymentKind.payout,
source: ManagedWalletPaymentMethod(
managedWalletRef: sourceWallet.id,
asset: sourceAsset,
),
destination: CardPaymentMethod(
pan: row.pan,
firstName: row.firstName,
lastName: row.lastName,
expMonth: row.expMonth,
expYear: row.expYear,
),
amount: amount,
feeTreatment: FeeTreatment.addToSource,
settlementMode: SettlementMode.fixReceived,
fx: fxIntent,
);
})
.toList(growable: false);
}
}