private async Task <DomainValidationResult <ITransaction> > CreateChargeTransactionAsync( ITokenAccount account, Token token, TransactionMetadata?metadata = null, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); if (!account.HaveSufficientMoney(token)) { result.AddFailedPreconditionError("Insufficient funds."); } if (result.IsValid) { var transaction = account.Charge(token, metadata); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
private async Task <DomainValidationResult <ITransaction> > CreateDepositTransactionAsync( ITokenAccount account, Token token, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); var transactionBundles = await this.FetchTransactionBundlesAsync(EnumTransactionType.Deposit, EnumCurrencyType.Token); if (transactionBundles.All(deposit => deposit.Currency.Amount != token.Amount)) { result.AddFailedPreconditionError( $"The amount of {nameof(Token)} is invalid. These are valid amounts: [{string.Join(", ", transactionBundles.Select(deposit => deposit.Currency.Amount))}]."); } if (!account.IsDepositAvailable()) { result.AddFailedPreconditionError( $"Buying tokens is unavailable until {account.LastDeposit?.Add(TokenAccountDecorator.DepositInterval)}. For security reason we limit the number of financial transaction that can be done in {TokenAccountDecorator.DepositInterval.TotalHours} hours."); } if (result.IsValid) { var transaction = account.Deposit(token); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }
private async Task <DomainValidationResult <ITransaction> > CreateTransactionAsync( ITokenAccount account, Token token, TransactionType type, TransactionMetadata?metadata = null, CancellationToken cancellationToken = default ) { if (type == TransactionType.Deposit) { return(await this.CreateDepositTransactionAsync(account, token, cancellationToken)); } if (type == TransactionType.Charge) { return(await this.CreateChargeTransactionAsync( account, token, metadata, cancellationToken)); } if (type == TransactionType.Payout) { return(await this.CreatePayoutTransactionAsync( account, token, metadata, cancellationToken)); } if (type == TransactionType.Promotion) { return(await this.CreatePromotionTransactionAsync( account, token, metadata, cancellationToken)); } return(DomainValidationResult <ITransaction> .Failure("Unsupported transaction type for token currency.")); }
private async Task <DomainValidationResult <ITransaction> > CreatePromotionTransactionAsync( ITokenAccount account, Token token, TransactionMetadata?metadata = null, CancellationToken cancellationToken = default ) { var result = new DomainValidationResult <ITransaction>(); if (result.IsValid) { var transaction = account.Promotion(token, metadata); transaction.MarkAsSucceeded(); await _accountRepository.CommitAsync(true, cancellationToken); return(transaction.Cast <Transaction>()); } return(result); }