Browse Source

Create initial mocking logic

enisn/payment-service-with-mock
enisn 5 years ago
parent
commit
c88171667b
  1. 5
      services/payment/src/EShopOnAbp.PaymentService.Application.Contracts/PaymentRequests/IPaymentRequestAppService.cs
  2. 2
      services/payment/src/EShopOnAbp.PaymentService.Application/PayPal/PayPalOptions.cs
  3. 62
      services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs
  4. 4
      services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs
  5. 7
      services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentOptions.cs
  6. 5
      services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentServiceDomainSharedModule.cs
  7. 11
      services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/Pages/MockCheckout.cshtml
  8. 9
      services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/Pages/MockCheckout.cshtml.cs
  9. 80
      services/payment/src/EShopOnAbp.PaymentService.HttpApi/PaymentRequests/PaymentRequestController.cs

5
services/payment/src/EShopOnAbp.PaymentService.Application.Contracts/PaymentRequests/IPaymentRequestAppService.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace EShopOnAbp.PaymentService.PaymentRequests
@ -12,5 +13,7 @@ namespace EShopOnAbp.PaymentService.PaymentRequests
Task<PaymentRequestDto> CompleteAsync(string token);
Task<bool> HandleWebhookAsync(string payload);
Task<string> CreateMockTokenAsync(Guid paymentRequestId, bool successfulResult = true);
}
}

2
services/payment/src/EShopOnAbp.PaymentService.Application/PayPal/PayPalOptions.cs

@ -4,6 +4,8 @@ namespace EShopOnAbp.PaymentService.PayPal
{
public class PayPalOptions
{
public bool IsEnabled { get; set; } = true;
public string ClientId { get; set; }
public string Secret { get; set; }

62
services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs

@ -1,4 +1,5 @@
using EShopOnAbp.PaymentService.PayPal;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using PayPalCheckoutSdk.Core;
using PayPalCheckoutSdk.Orders;
@ -6,20 +7,26 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
namespace EShopOnAbp.PaymentService.PaymentRequests
{
public class PaymentRequestAppService : PaymentServiceAppService, IPaymentRequestAppService
{
private const string MockFailureToken = "55F97E93";
private const string MockSuccessToken = "A8195146CA5A";
protected IPaymentRequestRepository PaymentRequestRepository { get; }
protected PayPalHttpClient PayPalHttpClient { get; }
public PaymentOptions Options { get; }
public PaymentRequestAppService(
IPaymentRequestRepository paymentRequestRepository,
PayPalHttpClient payPalHttpClient)
PayPalHttpClient payPalHttpClient,
IOptions<PaymentOptions> options)
{
PaymentRequestRepository = paymentRequestRepository;
PayPalHttpClient = payPalHttpClient;
Options = options.Value;
}
public async Task<PaymentRequestDto> CreateAsync(PaymentRequestCreationDto input)
@ -43,6 +50,14 @@ namespace EShopOnAbp.PaymentService.PaymentRequests
public async Task<PaymentRequestStartResultDto> StartAsync(PaymentRequestStartDto input)
{
if (Options.UseMock)
{
return new PaymentRequestStartResultDto
{
CheckoutLink = String.Empty
};
}
var paymentRequest = await PaymentRequestRepository.GetAsync(input.PaymentRequestId);
var totalCheckoutPrice = paymentRequest.Products.Sum(s => s.TotalPrice);
@ -101,6 +116,11 @@ namespace EShopOnAbp.PaymentService.PaymentRequests
public async Task<PaymentRequestDto> CompleteAsync(string token)
{
if (Options.UseMock)
{
return ObjectMapper.Map<PaymentRequest, PaymentRequestDto>(await HandleMockTokenAsync(token));
}
var request = new OrdersCaptureRequest(token);
request.RequestBody(new OrderActionRequest());
@ -130,6 +150,23 @@ namespace EShopOnAbp.PaymentService.PaymentRequests
return true;
}
public Task<string> CreateMockTokenAsync(Guid paymentRequestId, bool successfulResult = true)
{
if (Options.UseMock)
{
throw new InvalidOperationException("Mock token can't be genetared. UseMock has to be set as true in PaymentOptions.");
}
if (successfulResult)
{
return Task.FromResult(MockSuccessToken + "_" + paymentRequestId);
}
else
{
return Task.FromResult(MockFailureToken + "-" + paymentRequestId);
}
}
private async Task<PaymentRequest> UpdatePaymentRequestStateAsync(Order order)
{
var paymentRequestId = Guid.Parse(order.PurchaseUnits.First().ReferenceId);
@ -152,5 +189,28 @@ namespace EShopOnAbp.PaymentService.PaymentRequests
return paymentRequest;
}
private async Task<PaymentRequest> HandleMockTokenAsync(string token)
{
var isPaymentSuccessful = token.Contains($"{MockSuccessToken}_") ? true : token.Contains($"{MockFailureToken}_") ? false : throw new UserFriendlyException("Token is invalid!");
PaymentRequest paymentRequest = null;
if (isPaymentSuccessful)
{
paymentRequest = await PaymentRequestRepository.GetAsync(
Guid.Parse(token.Replace($"{MockSuccessToken}_", string.Empty)));
paymentRequest.SetAsCompleted();
}
else
{
paymentRequest = await PaymentRequestRepository.GetAsync(
Guid.Parse(token.Replace($"{MockFailureToken}_", string.Empty)));
paymentRequest.SetAsFailed("This payment has been mocked to be failed");
}
return paymentRequest;
}
}
}

4
services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs

@ -19,12 +19,16 @@ namespace EShopOnAbp.PaymentService
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
context.Services.AddAutoMapperObjectMapper<PaymentServiceApplicationModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<PaymentServiceApplicationModule>(validate: true);
});
Configure<PayPalOptions>(configuration.GetSection("Payment:PayPal"));
context.Services.AddTransient(provider =>
{
var options = provider.GetService<IOptions<PayPalOptions>>().Value;

7
services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentOptions.cs

@ -0,0 +1,7 @@
namespace EShopOnAbp.PaymentService
{
public class PaymentOptions
{
public bool UseMock { get; set; } = true;
}
}

5
services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentServiceDomainSharedModule.cs

@ -5,6 +5,7 @@ using Volo.Abp.Localization.ExceptionHandling;
using Volo.Abp.Validation;
using Volo.Abp.Validation.Localization;
using Volo.Abp.VirtualFileSystem;
using Microsoft.Extensions.DependencyInjection;
namespace EShopOnAbp.PaymentService
{
@ -15,6 +16,10 @@ namespace EShopOnAbp.PaymentService
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<PaymentOptions>(configuration.GetSection("Payment"));
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<PaymentServiceDomainSharedModule>();

11
services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/Pages/MockCheckout.cshtml

@ -0,0 +1,11 @@
@page
@model EShopOnAbp.PaymentService.Pages.MockCheckoutModel
<form action="/api/payment/requests/complete" method="post">
@*
TODO:
Discuss about that*@
</form>

9
services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/Pages/MockCheckout.cshtml.cs

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace EShopOnAbp.PaymentService.Pages
{
public class MockCheckoutModel : PageModel
{
}
}

80
services/payment/src/EShopOnAbp.PaymentService.HttpApi/PaymentRequests/PaymentRequestController.cs

@ -0,0 +1,80 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
namespace EShopOnAbp.PaymentService.PaymentRequests
{
[RemoteService(Name = PaymentServiceRemoteServiceConsts.RemoteServiceName)]
[Area("payment")]
[Route("api/payment/requests")]
public class PaymentRequestController : PaymentServiceController, IPaymentRequestAppService
{
protected IPaymentRequestAppService PaymentRequestAppService { get; }
public PaymentOptions Options { get; }
public IConfiguration Configuration { get; }
public PaymentRequestController(
IPaymentRequestAppService paymentRequestAppService,
IOptions<PaymentOptions> options,
IConfiguration configuration)
{
PaymentRequestAppService = paymentRequestAppService;
Options = options.Value;
Configuration = configuration;
}
[HttpPost]
[Route("complete")]
public Task<PaymentRequestDto> CompleteAsync(string token)
{
return PaymentRequestAppService.CompleteAsync(token);
}
[HttpPost]
public Task<PaymentRequestDto> CreateAsync(PaymentRequestCreationDto input)
{
return PaymentRequestAppService.CreateAsync(input);
}
[HttpPost]
[Route("mock-token")]
public Task<string> CreateMockTokenAsync(Guid paymentRequestId, bool successfulResult = true)
{
return PaymentRequestAppService.CreateMockTokenAsync(paymentRequestId, successfulResult);
}
[HttpPost]
[Route("webhook")]
public async Task<bool> HandleWebhookAsync(string payload)
{
var bytes = await Request.Body.GetAllBytesAsync();
payload = Encoding.UTF8.GetString(bytes);
return await PaymentRequestAppService.HandleWebhookAsync(payload);
}
[HttpPost]
[Route("start")]
public async Task<PaymentRequestStartResultDto> StartAsync(PaymentRequestStartDto input)
{
if (Options.UseMock)
{
var token = await CreateMockTokenAsync(input.PaymentRequestId, true);
var uri = new Uri(input.ReturnUrl);
return new PaymentRequestStartResultDto
{
CheckoutLink = .EndsWith("/") + $"?token={token}&returnUrl={input.ReturnUrl}"
};
}
return await PaymentRequestAppService.StartAsync(input);
}
}
}
Loading…
Cancel
Save