/// <inheritdoc /> public virtual IGateway Provide(string gatewayName) { var descriptors = _services.GetServices <GatewayDescriptor>(); var comparedDescriptors = descriptors .Where(descriptor => GatewayHelper.CompareName(descriptor.GatewayType, gatewayName)) .ToList(); if (comparedDescriptors.Count == 0) { throw new GatewayNotFoundException(gatewayName); } if (comparedDescriptors.Count > 1) { throw new InvalidOperationException($"More than one gateway with the name {gatewayName} found."); } var gateway = _services.GetService(comparedDescriptors[0].GatewayType); if (gateway == null) { throw new GatewayNotFoundException(gatewayName); } return((IGateway)gateway); }
public virtual IInvoiceBuilder SetGatewayType(Type gatewayType) { GatewayHelper.IsGateway(gatewayType, throwException: true); _gatewayType = gatewayType; return(this); }
/// <summary> /// </summary> /// <param name="gatewayProvider"></param> /// <param name="gatewayName"></param> /// <exception cref="GatewayNotFoundException"></exception> /// <exception cref="ArgumentNullException"></exception> public static IGateway Provide(this IGatewayProvider gatewayProvider, string gatewayName) { if (gatewayProvider == null) { throw new ArgumentNullException(nameof(gatewayProvider)); } return(gatewayProvider.Provide(GatewayHelper.FindGatewayTypeByName(gatewayName))); }
/// <inheritdoc /> public virtual IGateway Provide(Type gatewayType) { GatewayHelper.IsGateway(gatewayType, throwException: true); var gateway = _services.GetService(gatewayType); if (gateway == null) { throw new GatewayNotFoundException(GatewayHelper.GetNameByType(gatewayType)); } return((IGateway)gateway); }
/// <inheritdoc /> public virtual async Task <IPaymentRequestResult> RequestAsync(Invoice invoice, CancellationToken cancellationToken = default) { if (invoice == null) { throw new ArgumentNullException(nameof(invoice)); } _logger.LogInformation(LoggingEvents.RequestPayment, $"New payment request with the tracking number {invoice.TrackingNumber} is started." + $"{nameof(invoice.Amount)}:{invoice.Amount}" + $"GatewayName:{GatewayHelper.GetNameByType(invoice.GatewayType)}"); // Check the tracking number if (await _database.Payments .AnyAsync(model => model.TrackingNumber == invoice.TrackingNumber, cancellationToken) .ConfigureAwaitFalse()) { _logger.LogInformation(LoggingEvents.RequestPayment, _messagesOptions.Value.DuplicateTrackingNumber); return(new PaymentRequestResult { TrackingNumber = invoice.TrackingNumber, IsSucceed = false, Message = _messagesOptions.Value.DuplicateTrackingNumber, GatewayTransporter = new NullGatewayTransporter() }); } // Check the payment token var paymentToken = await _tokenProvider .ProvideTokenAsync(invoice, cancellationToken) .ConfigureAwaitFalse(); if (await _database.Payments .AnyAsync(model => model.Token == paymentToken, cancellationToken) .ConfigureAwaitFalse()) { var message = $"The payment token \"{paymentToken}\" already exists."; _logger.LogError(LoggingEvents.RequestPayment, message); throw new PaymentTokenProviderException(message); } var gateway = _gatewayProvider.Provide(invoice.GatewayType); // Add database var newPayment = new Payment { TrackingNumber = invoice.TrackingNumber, Amount = invoice.Amount, IsCompleted = false, IsPaid = false, Token = paymentToken, GatewayName = gateway.GetName(), CreatedOn = DateTime.UtcNow }; _database.Payments.Add(newPayment); if (await _database.SaveChangesAsync(cancellationToken).ConfigureAwaitFalse() == 0) { _logger.LogError(LoggingEvents.RequestPayment, "Nothing is saved into the database."); throw new DatabaseSaveRecordException(); } _logger.LogInformation(LoggingEvents.RequestPayment, $"The payment with tracking number {invoice.TrackingNumber} is about to processing." + $"{nameof(invoice.Amount)}:{invoice.Amount}" + $"GatewayName:{GatewayHelper.GetNameByType(invoice.GatewayType)}"); PaymentRequestResult requestResult; try { requestResult = await gateway .RequestAsync(invoice, cancellationToken) .ConfigureAwaitFalse() as PaymentRequestResult; if (requestResult == null) { throw new Exception($"Gateway {gateway.GetName()} returns null instead of a result."); } } catch (Exception exception) { string exceptionMessage; if (exception is OptionsValidationException) { exceptionMessage = $"Gateway {gateway.GetName()} is not configured or has some validation errors."; } else { exceptionMessage = exception.Message; } _logger.LogError(exception, exceptionMessage); newPayment.IsCompleted = true; newPayment.IsPaid = false; newPayment.UpdatedOn = DateTime.UtcNow; requestResult = PaymentRequestResult.Failed(exceptionMessage); } requestResult.TrackingNumber = invoice.TrackingNumber; requestResult.Amount = invoice.Amount; requestResult.GatewayName = gateway.GetName(); newPayment.Transactions.Add(new Transaction { Amount = invoice.Amount, Type = TransactionType.Request, IsSucceed = requestResult.IsSucceed, Message = requestResult.Message, AdditionalData = AdditionalDataConverter.ToJson(requestResult), CreatedOn = DateTime.UtcNow }); if (await _database.SaveChangesAsync(cancellationToken).ConfigureAwaitFalse() == 0) { _logger.LogError(LoggingEvents.RequestPayment, "Nothing is saved into database."); throw new DatabaseSaveRecordException(); } return(requestResult); }
/// <inheritdoc /> public virtual async Task <IPaymentRequestResult> RequestAsync(Invoice invoice, CancellationToken cancellationToken = default) { if (invoice == null) { throw new ArgumentNullException(nameof(invoice)); } _logger.LogInformation(LoggingEvents.RequestPayment, $"New payment request with the tracking number {invoice.TrackingNumber} is started." + $"{nameof(invoice.Amount)}:{invoice.Amount}" + $"GatewayName:{GatewayHelper.GetNameByType(invoice.GatewayType)}"); // Check the tracking number if (await _storageManager.DoesPaymentExistAsync(invoice.TrackingNumber, cancellationToken).ConfigureAwaitFalse()) { _logger.LogInformation(LoggingEvents.RequestPayment, _messagesOptions.Value.DuplicateTrackingNumber); return(new PaymentRequestResult { TrackingNumber = invoice.TrackingNumber, IsSucceed = false, Message = _messagesOptions.Value.DuplicateTrackingNumber, GatewayTransporter = new NullGatewayTransporter() }); } // Create a payment token var paymentToken = await _tokenProvider .ProvideTokenAsync(invoice, cancellationToken) .ConfigureAwaitFalse(); // Check the created payment token if (await _storageManager.DoesPaymentExistAsync(paymentToken, cancellationToken).ConfigureAwaitFalse()) { var message = $"The payment token \"{paymentToken}\" already exists."; _logger.LogError(LoggingEvents.RequestPayment, message); throw new PaymentTokenProviderException(message); } var gateway = _gatewayProvider.Provide(invoice.GatewayType); var newPayment = new Payment { TrackingNumber = invoice.TrackingNumber, Amount = invoice.Amount, IsCompleted = false, IsPaid = false, Token = paymentToken, GatewayName = gateway.GetName() }; await _storageManager.CreatePaymentAsync(newPayment, cancellationToken).ConfigureAwaitFalse(); _logger.LogInformation(LoggingEvents.RequestPayment, $"The payment with tracking number {invoice.TrackingNumber} is about to processing." + $"{nameof(invoice.Amount)}:{invoice.Amount}" + $"GatewayName:{GatewayHelper.GetNameByType(invoice.GatewayType)}"); PaymentRequestResult requestResult; try { requestResult = await gateway .RequestAsync(invoice, cancellationToken) .ConfigureAwaitFalse() as PaymentRequestResult; if (requestResult == null) { throw new Exception($"Gateway {gateway.GetName()} returns null instead of a result."); } } catch (Exception exception) { _logger.LogError(exception, exception.Message); newPayment.IsCompleted = true; newPayment.IsPaid = false; requestResult = PaymentRequestResult.Failed(exception.Message); } requestResult.TrackingNumber = invoice.TrackingNumber; requestResult.Amount = invoice.Amount; requestResult.GatewayName = gateway.GetName(); newPayment.GatewayAccountName = requestResult.GatewayAccountName; await _storageManager.UpdatePaymentAsync(newPayment, cancellationToken).ConfigureAwaitFalse(); var newTransaction = new Transaction { Amount = invoice.Amount, Type = TransactionType.Request, IsSucceed = requestResult.IsSucceed, Message = requestResult.Message, AdditionalData = AdditionalDataConverter.ToJson(requestResult), PaymentId = newPayment.Id }; await _storageManager.CreateTransactionAsync(newTransaction, cancellationToken).ConfigureAwaitFalse(); return(requestResult); }