public async Task <PaymentDto> CreatePaymentAsync(CreatePaymentDto create) { Logger.LogInformation("About to call External Provider"); string status = "failed"; if (create.Amount < 20) { status = CheapPaymentGateway.MakePayment(create); } else if (create.Amount > 21 && create.Amount < 500) { status = ExpensivePaymentGateway.MakePayment(create); if (status == "failed") { status = CheapPaymentGateway.MakePayment(create); } } else { for (var i = 0; i < 3; i++) { status = PremiumPaymentService.MakePayment(create); if (status != "failed") { break; } } } if (status == "failed") { return(null); } Logger.LogInformation("About to Insert new payment entry"); var paymentInfo = await PaymentRepo.InsertAsync(new Payment() { CreditCardNumber = create.CreditCardNumber, CardHolder = create.CardHolder, ExpirationDate = create.ExpirationDate, SecurityCode = create.SecurityCode, Amount = create.Amount }); var commitResult = await UnitOfWork.CommitAsync(); var paymentStatus = await PaymentStatusService.CreatePaymentStatusAsync(new CreatePaymentStatusDto() { PaymentId = paymentInfo.Entity.Id, Status = status }); return(commitResult == 1 ? new PaymentDto() { Id = paymentInfo.Entity.Id, Amount = paymentInfo.Entity.Amount, Status = paymentStatus != null ? paymentStatus.Status : null } : null); }
public virtual async Task CreateAsync(CreatePaymentDto input) { var orders = new List <OrderDto>(); foreach (var orderId in input.OrderIds) { orders.Add(await _orderAppService.GetAsync(orderId)); } var extraProperties = new Dictionary <string, object> { { "StoreId", orders.First().StoreId } }; await _payableChecker.CheckAsync(input, orders, extraProperties); // Todo: should avoid duplicate creations. await _distributedEventBus.PublishAsync(new CreatePaymentEto { TenantId = CurrentTenant.Id, UserId = CurrentUser.GetId(), PaymentMethod = input.PaymentMethod, Currency = orders.First().Currency, ExtraProperties = extraProperties, PaymentItems = orders.Select(order => new CreatePaymentItemEto { ItemType = PaymentsConsts.PaymentItemType, ItemKey = order.Id, Currency = order.Currency, OriginalPaymentAmount = order.TotalPrice }).ToList() }); }
public async Task <CreatePaymentResponse> CreatePayment(CreatePaymentDto input) { var targetEdition = (SubscribableEdition)await _editionManager.GetByIdAsync(input.EditionId); var tenant = AbpSession.TenantId == null ? null : await TenantManager.GetByIdAsync(AbpSession.GetTenantId()); var amount = await CalculateAmountForPaymentAsync(targetEdition, input.PaymentPeriodType, input.EditionPaymentType, tenant); using (var paymentGatewayManager = _paymentGatewayManagerFactory.Create(input.SubscriptionPaymentGatewayType)) { var createPaymentResult = await paymentGatewayManager.Object.CreatePaymentAsync(CalculatePaymentDescription(input, targetEdition), amount); await _subscriptionPaymentRepository.InsertAsync( new SubscriptionPayment { PaymentPeriodType = input.PaymentPeriodType, EditionId = input.EditionId, TenantId = tenant == null ? 0 : tenant.Id, Gateway = input.SubscriptionPaymentGatewayType, Amount = amount, DayCount = input.PaymentPeriodType.HasValue ? (int)input.PaymentPeriodType.Value : 0, PaymentId = createPaymentResult.GetId(), Status = SubscriptionPaymentStatus.Processing } ); return(createPaymentResult); } }
private async Task <CreatePaymentResponse> UnifiedCreatePayment(CreatePaymentDto input, bool jsPayment = false) { var paymentId = _paymentIdCache.GetCacheItem(AbpSession.GetTenantId(), input.EditionId, input.EditionPaymentType, input.PaymentPeriodType); var targetEdition = await _editionCache.GetAsync(input.EditionId); var tenant = AbpSession.TenantId == null ? null : await TenantManager.GetByIdAsync(AbpSession.GetTenantId()); var amount = await CalculateAmountForPaymentAsync(targetEdition, input.PaymentPeriodType, input.EditionPaymentType, tenant); var paymentGatewayManager = _paymentGatewayProviderFactory.Create(input.SubscriptionPaymentGatewayType); CreatePaymentResponse createPaymentResult; if (jsPayment) { createPaymentResult = await paymentGatewayManager.CreateJsPaymentAsync(new CreatePaymentRequest() { PaymentId = paymentId, Description = GetPaymentDescription(input, targetEdition), Amount = amount, UserId = AbpSession.GetUserId() }); } else { createPaymentResult = await paymentGatewayManager.CreatePaymentAsync(new CreatePaymentRequest() { PaymentId = paymentId, Description = GetPaymentDescription(input, targetEdition), Amount = amount }); } var cacheItem = await _subscriptionPaymentCache.GetCacheItemOrNullAsync(paymentId); if (cacheItem == null) { await _subscriptionPaymentCache.AddCacheItemAsync( new SubscriptionPaymentCacheItem { PaymentPeriodType = input.PaymentPeriodType, EditionId = input.EditionId, TenantId = tenant == null ? 0 : tenant.Id, Amount = amount, DayCount = input.PaymentPeriodType.HasValue ? (int)input.PaymentPeriodType.Value : 0, PaymentId = paymentId, Status = SubscriptionPaymentStatus.Processing, EditionPaymentType = input.EditionPaymentType }); } createPaymentResult.Amount = amount; createPaymentResult.PaymentId = paymentId; return(createPaymentResult); }
public virtual async Task CheckAsync(CreatePaymentDto input, List <OrderDto> orders, CreatePaymentEto createPaymentEto) { var providers = _serviceProvider.GetServices <IPayableCheckProvider>(); foreach (var provider in providers) { await provider.CheckAsync(input, orders, createPaymentEto); } }
public virtual async Task CheckAsync(CreatePaymentDto input, List <OrderDto> orders, Dictionary <string, object> paymentExtraProperties) { var providers = _serviceProvider.GetServices <IPayableCheckProvider>(); foreach (var provider in providers) { await provider.CheckAsync(input, orders, paymentExtraProperties); } }
public async Task Should_Be_Able_To_Preform_A_Payment_And_Recieve_A_Successful_Transaction() { var mockedIdentifier = new DateTimeOffset().ToUnixTimeMilliseconds().ToString(); var createPaymentDto = new CreatePaymentDto { Issuer = "amazon-issuer-id", CardHolder = "John Cage", Value = 199.99m, Currency = "Euro", CardNumber = "1234-1234-1234-1235", ExpiryMonth = 13, ExpiryYear = 2099, CCV = "12e2", }; var bankResponse = new BankResponse { id = mockedIdentifier, successful = true, message = "very nice", statusCode = 1 }; var paymentResponse = new PaymentResponse { paymentRequest = new PaymentModel { Id = "mocked-id", Issuer = "amazon-issuer-id", CardHolder = "John Cage", Value = 199.99m, Currency = "Euro", CardNumber = "1234-1234-1234-1235", ExpiryMonth = 13, ExpiryYear = 2099, CCV = "12e2", response = bankResponse, }, paymentResponse = bankResponse, }; var mockPaymentService = new Mock <IPaymentService>(); var mockLogger = new Mock <ILoggerService>(); mockPaymentService.Setup <PaymentResponse>(paymentService => paymentService.Create(createPaymentDto)).Returns(paymentResponse); var controller = new PaymentController(mockLogger.Object, mockPaymentService.Object); var result = controller.Create(createPaymentDto); Assert.IsType <ActionResult <PaymentResponse> >(result); Assert.IsType <PaymentResponse>(result.Value); Assert.IsAssignableFrom <PaymentModel>(result.Value.paymentRequest); Assert.IsAssignableFrom <BankResponse>(result.Value.paymentResponse); Assert.Equal(result.Value.paymentRequest.response.id, result.Value.paymentResponse.id); }
public virtual Task CheckAsync(CreatePaymentDto input, List <OrderDto> orders, CreatePaymentEto createPaymentEto) { foreach (var order in orders.Where(order => order.PaymentId.HasValue || order.PaidTime.HasValue)) { throw new OrderPaymentAlreadyExistsException(order.Id); } if (orders.Select(order => order.Currency).Distinct().Count() != 1) { // Todo: convert to a single currency. throw new MultiCurrencyNotSupportedException(); } return(Task.CompletedTask); }
public async Task CreateAsync(CreatePaymentDto input) { var orders = new List <OrderDto>(); foreach (var orderId in input.OrderIds) { var order = await _orderAppService.GetAsync(orderId); orders.Add(order); if (order.PaymentId.HasValue || order.PaidTime.HasValue) { throw new OrderPaymentAlreadyExistsException(orderId); } } if (orders.Select(order => order.Currency).Distinct().Count() != 1) { throw new MultiCurrencyNotSupportedException(); } if (orders.Select(order => order.StoreId).Distinct().Count() != 1) { throw new MultiStorePaymentNotSupportedException(); } // Todo: should avoid duplicate creations. var extraProperties = new Dictionary <string, object> { { "StoreId", orders.First().StoreId } }; await _distributedEventBus.PublishAsync(new CreatePaymentEto { TenantId = CurrentTenant.Id, UserId = CurrentUser.GetId(), PaymentMethod = input.PaymentMethod, Currency = orders.First().Currency, ExtraProperties = extraProperties, PaymentItems = orders.Select(order => new CreatePaymentItemEto { ItemType = PaymentsConsts.PaymentItemType, ItemKey = order.Id, Currency = order.Currency, OriginalPaymentAmount = order.TotalPrice }).ToList() }); }
public async Task <IActionResult> ProcessPayment(CreatePaymentDto createPaymentDto) { var createpaymentcommand = new CreatePaymentCommand { Amount = createPaymentDto.Amount, CardHolder = createPaymentDto.CardHolder, CreditCardNumber = createPaymentDto.CreditCardNumber, ExpirationMonth = createPaymentDto.ExpirationMonth, ExpirationYear = createPaymentDto.ExpirationYear, SecurityCode = createPaymentDto.SecurityCode }; var response = await _mediator.Send(createpaymentcommand); return(Ok(response)); }
public async Task Should_Publish_Create_Payment_Event() { // Arrange var request = new CreatePaymentDto { OrderIds = new List <Guid> { PaymentsTestData.Order1 }, PaymentMethod = "Free" }; // Act & Assert await _paymentAppService.CreateAsync(request); _testCreatePaymentEventHandler.IsEventPublished.ShouldBe(true); }
public virtual async Task CreateAsync(CreatePaymentDto input) { // Todo: should avoid duplicate creations. (concurrent lock) var orders = new List <OrderDto>(); foreach (var orderId in input.OrderIds) { orders.Add(await _orderAppService.GetAsync(orderId)); } await AuthorizationService.CheckAsync( new PaymentCreationResource { Input = input, Orders = orders }, new PaymentOperationAuthorizationRequirement(PaymentOperation.Creation) ); var paymentItems = orders.Select(order => { var eto = new CreatePaymentItemEto { ItemType = PaymentsConsts.PaymentItemType, ItemKey = order.Id.ToString(), OriginalPaymentAmount = order.ActualTotalPrice }; eto.SetProperty(nameof(PaymentItem.StoreId), order.StoreId); return(eto); }).ToList(); var createPaymentEto = new CreatePaymentEto( CurrentTenant.Id, CurrentUser.GetId(), input.PaymentMethod, orders.First().Currency, paymentItems ); input.MapExtraPropertiesTo(createPaymentEto); await _distributedEventBus.PublishAsync(createPaymentEto); }
private string CalculatePaymentDescription(CreatePaymentDto input, SubscribableEdition targetEdition) { switch (input.EditionPaymentType) { case EditionPaymentType.NewRegistration: case EditionPaymentType.BuyNow: return(L("Purchase")); case EditionPaymentType.Upgrade: return(L("UpgradedTo", targetEdition.DisplayName)); case EditionPaymentType.Extend: return(L("ExtendedEdition", targetEdition.DisplayName)); default: throw new ArgumentException(nameof(input.EditionPaymentType)); } }
public async Task <long> CreatePayment(CreatePaymentDto input) { if (!AbpSession.TenantId.HasValue) { throw new AbpException("A payment only can be created for a tenant. TenantId is not set in the IAbpSession!"); } decimal amount; string targetEditionName; using (UnitOfWorkManager.Current.SetTenantId(null)) { var targetEdition = (SubscribableEdition)await _editionManager.GetByIdAsync(input.EditionId); targetEditionName = targetEdition.DisplayName; var tenant = await TenantManager.GetByIdAsync(AbpSession.GetTenantId()); amount = await CalculateAmountForPaymentAsync(targetEdition, input.PaymentPeriodType, input.EditionPaymentType, tenant); if (tenant != null && input.RecurringPaymentEnabled) { tenant.SubscriptionPaymentType = SubscriptionPaymentType.RecurringAutomatic; await _tenantManager.UpdateAsync(tenant); } } var payment = new SubscriptionPayment { Description = GetPaymentDescription(input.EditionPaymentType, input.PaymentPeriodType, targetEditionName), PaymentPeriodType = input.PaymentPeriodType, EditionId = input.EditionId, TenantId = AbpSession.GetTenantId(), Gateway = input.SubscriptionPaymentGatewayType, Amount = amount, DayCount = input.PaymentPeriodType.HasValue ? (int)input.PaymentPeriodType.Value : 0, Status = SubscriptionPaymentStatus.NotPaid, IsRecurring = input.RecurringPaymentEnabled, SuccessUrl = input.SuccessUrl, ErrorUrl = input.ErrorUrl }; return(await _subscriptionPaymentRepository.InsertAndGetIdAsync(payment)); }
public virtual Task CheckAsync(CreatePaymentDto input, List <OrderDto> orders, Dictionary <string, object> paymentExtraProperties) { foreach (var order in orders.Where(order => order.PaymentId.HasValue || order.PaidTime.HasValue)) { throw new OrderPaymentAlreadyExistsException(order.Id); } if (orders.Select(order => order.Currency).Distinct().Count() != 1) { throw new MultiCurrencyNotSupportedException(); } if (orders.Select(order => order.StoreId).Distinct().Count() != 1) { throw new MultiStorePaymentNotSupportedException(); } return(Task.CompletedTask); }
public virtual async Task CreateAsync(CreatePaymentDto input) { // Todo: should avoid duplicate creations. (concurrent lock) var orders = new List <OrderDto>(); foreach (var orderId in input.OrderIds) { orders.Add(await _orderAppService.GetAsync(orderId)); } await AuthorizationService.CheckAsync( new PaymentCreationResource { Input = input, Orders = orders }, new PaymentOperationAuthorizationRequirement(PaymentOperation.Creation) ); var createPaymentEto = new CreatePaymentEto { TenantId = CurrentTenant.Id, UserId = CurrentUser.GetId(), PaymentMethod = input.PaymentMethod, Currency = orders.First().Currency, ExtraProperties = new Dictionary <string, object>(), PaymentItems = orders.Select(order => new CreatePaymentItemEto { ItemType = PaymentsConsts.PaymentItemType, ItemKey = order.Id.ToString(), OriginalPaymentAmount = order.ActualTotalPrice, ExtraProperties = new Dictionary <string, object> { { "StoreId", order.StoreId.ToString() } } }).ToList() }; await _distributedEventBus.PublishAsync(createPaymentEto); }
public PaymentResponse Create(CreatePaymentDto createPaymentDto) { var bankResponse = new BankResponse { id = "", successful = false, statusCode = 0, message = "this request never made it to the bank", }; var paymentModel = new PaymentModel { Issuer = createPaymentDto.Issuer, CardHolder = createPaymentDto.CardHolder, Value = createPaymentDto.Value, Currency = createPaymentDto.Currency, CardNumber = createPaymentDto.CardNumber, ExpiryMonth = createPaymentDto.ExpiryMonth, ExpiryYear = createPaymentDto.ExpiryYear, CCV = createPaymentDto.CCV, transactionDate = System.DateTimeOffset.Now.UtcDateTime, response = bankResponse }; var bankRequest = new BankRequest { Issuer = createPaymentDto.Issuer, CardHolder = createPaymentDto.CardHolder, Value = createPaymentDto.Value, Currency = createPaymentDto.Currency, CardNumber = createPaymentDto.CardNumber, ExpiryMonth = createPaymentDto.ExpiryMonth, ExpiryYear = createPaymentDto.ExpiryYear, CCV = createPaymentDto.CCV, }; _paymentModelCollection.InsertOne(paymentModel); try { bankResponse = _acquiringBank.processPayment(bankRequest); paymentModel.response = bankResponse; this.Update(paymentModel.Id, paymentModel); } catch (System.Exception ex) { var exceptionMetric = new ExceptionMetric { origin = nameof(PaymentService), exception = new AcquiringBankNotAvailable(ex.Message), time = new DateTimeOffset().Date, stack = ex.StackTrace }; _logger.Log <ExceptionMetric>(LogLevel.Error, new EventId { }, exceptionMetric, ex); } paymentModel.CardNumber = this.HideCreditCardNumber(paymentModel.CardNumber); paymentModel.CCV = this.HideCCV(); return(new PaymentResponse { paymentRequest = paymentModel, paymentResponse = bankResponse, }); }
private Task <AuthorizationHandlerContext> CreateAuthorizationHandlerContextAsync() { var orderLine1 = new OrderLineDto { Id = BookingTestConsts.OrderLine1Id, ProductId = BookingTestConsts.BookingProduct1Id, ProductSkuId = BookingTestConsts.BookingProduct1Sku1Id, Quantity = 1, ExtraProperties = new ExtraPropertyDictionary() }; orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingPeriodSchemeId, BookingTestConsts.PeriodScheme1Id); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingPeriodId, BookingTestConsts.Period1Id); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingAssetId, BookingTestConsts.Asset1Id); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingDate, BookingTestConsts.BookingDate); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingStartingTime, BookingTestConsts.Period1StartingTime); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingDuration, BookingTestConsts.Period1Duration); orderLine1.SetProperty(BookingOrderProperties.OrderLineBookingVolume, BookingTestConsts.Volume); var orderLine2 = new OrderLineDto { Id = BookingTestConsts.OrderLine2Id, ProductId = BookingTestConsts.BookingProduct1Id, ProductSkuId = BookingTestConsts.BookingProduct1Sku1Id, Quantity = 1, ExtraProperties = new ExtraPropertyDictionary() }; orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingPeriodSchemeId, BookingTestConsts.PeriodScheme1Id); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingPeriodId, BookingTestConsts.Period1Id); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingAssetCategoryId, BookingTestConsts.AssetCategory1Id); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingDate, BookingTestConsts.BookingDate); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingStartingTime, BookingTestConsts.Period1StartingTime); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingDuration, BookingTestConsts.Period1Duration); orderLine2.SetProperty(BookingOrderProperties.OrderLineBookingVolume, BookingTestConsts.Volume); var currentPrincipalAccessor = ServiceProvider.GetRequiredService <ICurrentPrincipalAccessor>(); return(Task.FromResult(new AuthorizationHandlerContext( new[] { new PaymentOperationAuthorizationRequirement(PaymentOperation.Creation) }, currentPrincipalAccessor.Principal, new PaymentCreationResource { Input = new CreatePaymentDto { PaymentMethod = "Free", OrderIds = new List <Guid> { BookingTestConsts.Order1Id } }, Orders = new List <OrderDto> { new() { Id = BookingTestConsts.Order1Id, OrderLines = new List <OrderLineDto> { orderLine1, orderLine2 } } } })));
/// <summary> /// 创建支付 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task <CreatePaymentResponse> CreatePayment(CreatePaymentDto input) { return(await UnifiedCreatePayment(input)); }
public string MakePayment(CreatePaymentDto payment) { return("processed"); }
public ActionResult <PaymentResponse> Create(CreatePaymentDto payment) { var response = _paymentService.Create(payment); return(response); }
public Task CreateAsync(CreatePaymentDto input) { return(_service.CreateAsync(input)); }
public async Task We_Are_Able_To_Go_Through_The_Whole_Payment_Process() { var createPaymentDto = new CreatePaymentDto { Issuer = "amazon-issuer-id", CardHolder = "John Cage", Value = 199.99m, Currency = "Euro", CardNumber = "0000-0000-0000-0000", ExpiryMonth = 13, ExpiryYear = 2099, CCV = "12e2", }; var bankResponse = new BankResponse { id = "fake-id", successful = true, message = "very nice", statusCode = 1 }; var paymentModelDocument = new PaymentModel { Id = "mocked-id", Issuer = "amazon-issuer-id", CardHolder = "John Cage", Value = 199.99m, Currency = "Euro", CardNumber = "0000-0000-0000-0000", ExpiryMonth = 13, ExpiryYear = 2099, CCV = "12e2", response = bankResponse, }; var bankRequest = new BankRequest { Issuer = "amazon-issuer-id", CardHolder = "John Cage", Value = 199.99m, Currency = "Euro", CardNumber = "0000-0000-0000-0000", ExpiryMonth = 13, ExpiryYear = 2099, CCV = "12e2", }; var loggerMock = new Mock <ILoggerService>(); loggerMock.Setup(logger => logger.Log <ExceptionMetric>(LogLevel.Error, new EventId { }, new ExceptionMetric { }, null, null)); var mongoCollectionMock = new Mock <IMongoCollection <PaymentModel> >(); mongoCollectionMock.Setup(col => col.InsertOne(paymentModelDocument, new InsertOneOptions { }, default)); mongoCollectionMock.Setup(col => col.ReplaceOne("mocked-id", paymentModelDocument, new ReplaceOptions { }, default)); var mockedBank = new Mock <IAcquiringBank>(); mockedBank.Setup(bank => bank.processPayment(bankRequest)).Returns(bankResponse); var paymentService = new PaymentService(mongoCollectionMock.Object, mockedBank.Object, loggerMock.Object); var result = paymentService.Create(createPaymentDto); Assert.Equal(2, mongoCollectionMock.Invocations.Count); Assert.Equal(1, mockedBank.Invocations.Count); }
public IActionResult Post([FromBody] CreatePaymentDto createModel) => _mapper.Map <PaymentInsertModel>(createModel) .Map(_commandRepo.Insert) .Map(x => Created(new { id = x })) .Reduce(_ => BadRequest(), error => error is ArgumentNotSet) .Reduce(_ => InternalServerError(), x => _logger.LogError(x.ToString()));