I tried the multi tiered MVC web app on both Mac and Windows, they have the same issue.
It's easy to setup saas features like tenant, edition in ABP, but I feel so frustrated to get the payment working. The documents are not clear enough and there is no working examples for it.
If I can't make the PoC working, I will refund the license for sure.
I managed to use Host Admin to create subscription (200). public async Task<IActionResult> OnPostAsync(Guid editionId) { var paymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, new Guid({{test-tenant-id}})); return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id); } But I got AbpRemoteCallException in LocalRedirectPreserveMethod.
[21:36:37 INF] Start processing HTTP request POST https://localhost:44330/api/saas/subscription?editionId=b6a600fd-dd26-5bd0-e685-3a14e2c059e7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0 [21:36:37 INF] Sending HTTP request POST https://localhost:44330/api/saas/subscription?editionId=b6a600fd-dd26-5bd0-e685-3a14e2c059e7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0 [21:36:38 INF] Received HTTP response headers after 323.6974ms - 200 [21:36:38 INF] End processing HTTP request after 323.9907ms - 200 [21:36:38 INF] Executed handler method OnPostAsync, returned result Microsoft.AspNetCore.Mvc.LocalRedirectResult. [21:36:38 INF] Executing LocalRedirectResult, redirecting to /Payment/GatewaySelection?paymentRequestId=1cdafd7e-c098-fd6c-da51-3a14e398c91d. [21:36:38 INF] Executed page /Payment in 351.8703ms [21:36:38 INF] Executed endpoint '/Payment' [21:36:38 INF] Request finished HTTP/2 POST https://localhost:44380/Payment - 307 0 null 358.6321ms [21:36:38 INF] Request starting HTTP/2 POST https://localhost:44380/Payment/GatewaySelection?paymentRequestId=1cdafd7e-c098-fd6c-da51-3a14e398c91d - application/x-www-form-urlencoded 272 [21:36:38 DBG] Get dynamic claims cache for user: 61316c80-2201-6007-5460-3a14e2c055fd [21:36:38 INF] Executing endpoint '/Payment/GatewaySelection' [21:36:38 INF] Route matched with {page = "/Payment/GatewaySelection", action = "", controller = "", area = ""}. Executing page /Payment/GatewaySelection [21:36:38 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [21:36:38 INF] Executing handler method Volo.Payment.Pages.Payment.GatewaySelectionModel.OnPostAsync - ModelState is Valid [21:36:38 INF] Start processing HTTP request GET https://localhost:44330/api/payment/requests/1cdafd7e-c098-fd6c-da51-3a14e398c91d?api-version=1.0 [21:36:38 INF] Sending HTTP request GET https://localhost:44330/api/payment/requests/1cdafd7e-c098-fd6c-da51-3a14e398c91d?api-version=1.0 [21:36:38 INF] Received HTTP response headers after 61.6867ms - 200 [21:36:38 INF] End processing HTTP request after 61.8489ms - 200 [21:36:38 INF] Start processing HTTP request GET https://localhost:44330/api/payment/gateways/subscription-supported?api-version=1.0 [21:36:38 INF] Sending HTTP request GET https://localhost:44330/api/payment/gateways/subscription-supported?api-version=1.0 [21:36:38 INF] Received HTTP response headers after 6.3861ms - 200 [21:36:38 INF] End processing HTTP request after 6.5586ms - 200 [21:36:38 INF] Executed handler method OnPostAsync, returned result Microsoft.AspNetCore.Mvc.LocalRedirectResult. [21:36:38 INF] Executing LocalRedirectResult, redirecting to /Payment/Stripe/PrePayment?paymentRequestId=1cdafd7e-c098-fd6c-da51-3a14e398c91d. [21:36:38 INF] Executed page /Payment/GatewaySelection in 83.7906ms [21:36:38 INF] Executed endpoint '/Payment/GatewaySelection' [21:36:38 INF] Request finished HTTP/2 POST https://localhost:44380/Payment/GatewaySelection?paymentRequestId=1cdafd7e-c098-fd6c-da51-3a14e398c91d - 307 0 null 91.3437ms [21:36:38 INF] Request starting HTTP/2 POST https://localhost:44380/Payment/Stripe/PrePayment?paymentRequestId=1cdafd7e-c098-fd6c-da51-3a14e398c91d - application/x-www-form-urlencoded 272 [21:36:38 DBG] Get dynamic claims cache for user: 61316c80-2201-6007-5460-3a14e2c055fd [21:36:38 INF] Executing endpoint '/Payment/Stripe/PrePayment' [21:36:38 INF] Route matched with {page = "/Payment/Stripe/PrePayment", action = "", controller = "", area = ""}. Executing page /Payment/Stripe/PrePayment [21:36:38 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [21:36:38 INF] Executing handler method Volo.Payment.Stripe.Pages.Payment.Stripe.PrePaymentModel.OnPostAsync - ModelState is Valid [21:36:38 INF] Start processing HTTP request POST https://localhost:44330/api/payment/stripe/start?api-version=1.0 [21:36:38 INF] Sending HTTP request POST https://localhost:44330/api/payment/stripe/start?api-version=1.0 [21:36:38 INF] Received HTTP response headers after 466.6814ms - 500 [21:36:38 INF] End processing HTTP request after 466.8602ms - 500 [21:36:38 ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": {}, "validationErrors": null }
[21:36:38 ERR] An internal error occurred during your request!
Volo.Abp.Http.Client.AbpRemoteCallException: An internal error occurred during your request!
at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.ThrowExceptionForResponseAsync(HttpResponseMessage response) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase
1.RequestAsync(ClientProxyRequestContext requestContext)
at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase
1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments)
at Volo.Payment.Requests.ClientProxies.PaymentRequestClientProxy.StartAsync(String paymentMethod, PaymentRequestStartDto input)
at Volo.Payment.Stripe.Pages.Payment.Stripe.PrePaymentModel.OnPostAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
[21:36:38 ERR] Code:
[21:36:38 ERR] Details:
[21:36:38 INF] Executed page /Payment/Stripe/PrePayment in 479.3708ms
[21:36:38 INF] Executed endpoint '/Payment/Stripe/PrePayment'
[21:36:38 ERR] An unhandled exception has occurred while executing the request.
Volo.Abp.Http.Client.AbpRemoteCallException: An internal error occurred during your request!
at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.ThrowExceptionForResponseAsync(HttpResponseMessage response) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase
1.RequestAsync(ClientProxyRequestContext requestContext)
at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase
1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments)
at Volo.Payment.Requests.ClientProxies.PaymentRequestClientProxy.StartAsync(String paymentMethod, PaymentRequestStartDto input)
at Volo.Payment.Stripe.Pages.Payment.Stripe.PrePaymentModel.OnPostAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Volo.Abp.AspNetCore.Security.Claims.AbpDynamicClaimsMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Volo.Abp.AspNetCore.Security.AbpSecurityHeadersMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Volo.Abp.Studio.Client.AspNetCore.AbpStudioMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<<CreateMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
I saw someone said Angular is not supported for payment, then I tried provisioning another solution using .NET Core MVC via CLI abp new MediBetter.Payment -m none --tiered --theme leptonx -csf --connection-string 'Server=.;Database=Test;User Id=sa;Password=Test!!!;TrustServerCertificate=true;'
Then I added payment module via CLI, it automatically added several nuget packages and updated module.cs in Application, Contracts, Domain, Domain.Shared, HttpApi, HttpApi.Client, HttpApi.Host, .Web projects.
Then I added this code to HTTP.API.Host and appsettings.json
Configure<AbpSaasPaymentOptions>(options =>
{
options.IsPaymentSupported = true;
});
"Payment": {
"Stripe": {
"PublishableKey": "pk_test_51P...",
"SecretKey": "sk_test_51P...",
"WebhookSecret": "whsec_sp...",
"Currency": "AUD",
"Locale": "auto",
"PaymentMethodTypes": ["card"]
}
}
Then I added a page in .Web to create subscription, however, when I login as Tenant Admin, I get 403 error, even with all the permissions granted "_Web" App in AuthServer OpenId > Applications.
public async Task<IActionResult> OnPostAsync(Guid editionId)
{
var paymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, CurrentTenant.GetId());
return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id);
}
I managed to invoke the /api/saas/subscription via Swagger to create subscription, but it is not able to LocalRedirectPreserveMethod with the correct paymentRequestId.