Starts in:
2 DAYS
9 HRS
15 MIN
40 SEC
Starts in:
2 D
9 H
15 M
40 S

Activities of "jaylin"

Welcome back maliming, thanks for your reply.

I have resolved this issue referring to the others reply, similar to yours but ExposeService.

[ExposeServices(typeof(StripePaymentGateway))]
public class CustomStripeGateway : StripePaymentGateway
{
    public CustomStripeGateway(
        IPaymentRequestRepository paymentRequestRepository,
        IPurchaseParameterListGenerator purchaseParameterListGenerator,
        IPlanRepository planRepository,
        IOptions<StripeOptions> stripeOptions,
        ILogger<StripePaymentGateway> logger,
        IDistributedEventBus eventBus,
        IObjectMapper objectMapper
    )
        : base(
            paymentRequestRepository,
            purchaseParameterListGenerator,
            planRepository,
            stripeOptions,
            logger,
            eventBus,
            objectMapper
        )
    { }

    public override Task HandleWebhookAsync(string payload, Dictionary<string, string> headers)
    {
        if (!headers.ContainsKey("Stripe-Signature") && headers.ContainsKey("stripe-signature"))
        {
            headers["Stripe-Signature"] = headers["stripe-signature"];
            headers.Remove("stripe-signature");

            // Log the information
            Logger.LogInformation("Stripe-Signature header was missing, but stripe-signature was present. Converted stripe-signature to Stripe-Signature.");
        }

        // Volo Stripe Payment expects Stripe-Signature in the headers
        return base.HandleWebhookAsync(payload, headers);
    }
}

Is the header key case sensitive? I captured the header in the request, its lower case.

"stripe-signature": [ "t=1730242133,v1=decaaca94f84b9e6c0523c2f283945f52a8a2e6ce0ab654bade8aa51dc2a98a5,v0=08b2da9f09b998a63e483b36ee2cf7325769eeb650ab665ed42f3e14f4cfc69a" ],

I have Application Gateway (WAF_v2) in front of the API (webhook), even I disabled the Web Application Firewall, the issue still happened.

Problem Id System.Collections.Generic.KeyNotFoundException at Volo.Payment.Stripe.StripePaymentGateway+<HandleWebhookAsync>d__25.MoveNext Assembly Volo.Payment.Stripe.Domain, Version=8.2.2.0, Culture=neutral, PublicKeyToken=null ActionId 46ab5810-8ae3-4668-88ec-1dc6eb213d2b ConnectionId 0HN7NVU4BKI1E MessageTemplate The given key 'Stripe-Signature' was not present in the dictionary. RequestId 0HN7NVU4BKI1E:00000006 SourceContext Volo.Abp.AspNetCore.Mvc.ExceptionHandling.AbpExceptionFilter RequestPath /api/payment/stripe/webhook ActionName Volo.Payment.Requests.PaymentRequestController.HandleWebhookAsync (Volo.Payment.HttpApi)

It's similar to https://abp.io/support/questions/4386/Error-from-ABP-commercial-payments-module-stripe-webhook-callback-handling-bug#answer-df4c481c-cbb9-299f-b150-3a08fa8e68da, but it has been resolved 2 years ago, I am wondering how comes the key was missing in the header.

I have double checked the secrets, they are correct.

Thanks, so I have to create a new table to manage the User - Plan relation, once recurring payment comes, I need to extend the subscription expiry to next month (if recurring monthly)?

I didn't find any invoice ready "Distributed Events", how can I implement such event?

It's nearly a week now, nobody wants to reply my question?

I have made the Angular working. NOTE: The "subscribe" page is implemented in AuthServer (MVC Razor) because payment gateway (Stripe) prepayment is ABP's out-of-box feature, I don't want to reinvent the wheels, I did some reverse engineering though.

Similar to MVC, after installing Payment module, it added Volo.Payment.XXX and Volo.Payment.Admin.XXX nuget packages to these XXX projects and [DependsOn] in XXXModule.cs:

  1. Application
  2. Application.Contracts
  3. HttpApi
  4. HttpApi.Client

Volo.Payment.XXX and Volo.Payment.Stripe.XXX to these XXX projects and [DependsOn] in XXXModule.cs

  1. Domain
  2. Domain.Shared

As described in the document, @volo/abp.ng.payment package is needed to manage payment in Angular Admin UI.

  1. Include payment route in app-routing.module.ts
  2. Include PaymentAdminConfigModule in app.module.ts.

Volo.Payment.EntityFrameworkCore to EntityFrameworkCore project and some file changes:

  1. builder.ConfigurePayment() in DbContext.cs
  2. [DependsOn] in EntityFrameworkCoreModule
  3. EF Code First Migrations

Manual steps:

  1. Added IsPaymentSupported in XXXModule.cs to HttpApi.Host project Configure<AbpSaasPaymentOptions>(options => { options.IsPaymentSupported = true; });

  2. Added Payment Stripe in appsettings.json to HttpApi.Host project "Payment": { "Stripe": { "PublishableKey": "pk_xxxx", "SecretKey": "sk_xxx" , "WebhookSecret": "whsec_xxx", "PaymentMethodTypes": [] // card has already been added } }

  3. Added PaymentWebOptions to PreConfigureServices in XXXAuthServerModule to AuthServer project. public override void PreConfigureServices(ServiceConfigurationContext context) { ...... var configuration = context.Services.GetConfiguration(); Configure<PaymentWebOptions>(options => { options.RootUrl = configuration["App:SelfUrl"]; options.CallbackUrl = configuration["App:SelfUrl"] + "/PaymentSucceed"; }); }

  4. Added Volo.Payment.Stripe.Web and Volo.Payment.Web nuget packages to AuthServer project - to route to out-of-box prepayment. It added AbpPaymentStripeWebModule and AbpPaymentWebModule [DependsOn] in XXXAuthServerModule.

  5. Added HttpApi.Client.csproj and HttpApi.csproj projects to AuthServer project - to inject IPaymentRequestAppService in Subscribe page.

  6. Added Subscribe.cshtml to AuthServer project to allow Tenant subscribe to an Edition. However, Tenant Admin doesn't have permission to call create subscription API as per the above thread by ismcagdas.
    I did bypass "await SubscriptionAppService.CreateSubscriptionAsync(editionId, currentTenantId)" by calling PaymentRequestAppService.

    public class SubscribeModel : PageModel { private IPaymentRequestAppService PaymentRequestAppService { get; } private ICurrentTenant CurrentTenant { get; }

     public SubscribeModel(
         IPaymentRequestAppService paymentRequestAppService,
         ICurrentTenant currentTenant)
     {
         PaymentRequestAppService = paymentRequestAppService;
         CurrentTenant = currentTenant;
     }
    
     public virtual async Task&lt;IActionResult&gt; OnPost(Guid planId, Guid editionId)
     {
         // PaymentRequestProductDto can't edit ExtraProperties
         var paymentRequest = await PaymentRequestAppService.CreateAsync(
             new CustomPaymentRequestCreateDto(new ExtraPropertyDictionary() {
                 { "EditionId", editionId },
                 { "TenantId", CurrentTenant.Id }
             })
             {
                 Products =
                 {
                     new PaymentRequestProductCreateDto
                     {
                         PaymentType = PaymentType.Subscription,
                         Name = "Standard",
                         Code = $"{CurrentTenant.Id}_{planId}",
                         Count = 1,
                         PlanId = planId
                     }
                 }
             });
    
         return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id);
     }
    

    }

    public class CustomPaymentRequestCreateDto : PaymentRequestCreateDto { public CustomPaymentRequestCreateDto(ExtraPropertyDictionary extraProperties) { ExtraProperties = extraProperties; } }

Because PayPaymentRequests.ExtraProperties (e.g. TenantId) will be used by Stripe Webhook to update SaasTenants.EditionEndDateUtc.

Hope this thread is useful to someone in the future.

Thanks ismcagdas, really appreciated!!!

// 1. Run as Tenant Admin - still not working failed at CreateSubscriptionAsync (403 Fibidden) var currentTenantId = CurrentTenant.GetId(); var currentPaymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, currentTenantId);

// 2. Run as Host Admin - it works, but not ideal, Tenant Admin should pay the subscription var tenantId = new Guid("9374a261-f7c5-4c4c-ba88-3a14e2feb5d1"); var paymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, tenantId); // 3. Run as Tenant Admin - it works var planId = new Guid("158c0405-7d7b-782b-6134-3a14e2d52556"); var paymentRequest = await PaymentRequestAppService.CreateAsync(new PaymentRequestCreateDto() { ...... }); return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id);

Note for future, in case it can help someone who might face the same problem.

After install Payment module, it added Volo.Payment.XXX and Volo.Payment.Admin.XXX nuget packages to these projects and [DependsOn] in XXXModule.cs:

  1. Application
  2. Application.Contracts
  3. HttpApi
  4. HttpApi.Client

Volo.Payment.XXX and Volo.Payment.Stripe.XXX to these projects and [DependsOn] in XXXModule.cs

  1. Domain
  2. Domain.Shared

Volo.Payment.XXX, Volo.Payment.Admin.XXX and Volo.Payment.Stripe.XXX to the project and [DependsOn] in XXXModule.cs

  1. Web (MVC)

Volo.Payment.EntityFrameworkCore to EntityFrameworkCore project and some file changes:

  1. builder.ConfigurePayment() in DbContext.cs
  2. [DependsOn] in EntityFrameworkCoreModule
  3. EF Code First Migrations

Manual steps:

  1. Added IsPaymentSupported in XXXModule.cs to HttpApi.Host project Configure<AbpSaasPaymentOptions>(options => { options.IsPaymentSupported = true; });

  2. Added Payment Stripe in appsettings.json to HttpApi.Host project "Payment": { "Stripe": { "PublishableKey": "pk_xxxx", "SecretKey": "sk_xxx" , "WebhookSecret": "whsec_xxx", "PaymentMethodTypes": [] // card has already been added } }

  3. Added PaymentWebOptions to PreConfigureServices in XXXWebModule to Web project public override void PreConfigureServices(ServiceConfigurationContext context) { ......

     **var configuration = context.Services.GetConfiguration();
     Configure&lt;PaymentWebOptions&gt;(options =>
     {
         options.RootUrl = configuration["App:SelfUrl"];
         options.CallbackUrl = configuration["App:SelfUrl"] + "/PaymentSucceed";
     });**
    

    }

  4. Added Subscribe.cshtml to Web project to allow Tenant subscribe to an Edition.

I will work on Angular version, and post the configuration once done.

PaymentRequestService failed at /api/payment/stripe/start the same as above thread.

[13:28:06 INF] Sending HTTP request POST https://localhost:44330/api/payment/stripe/start?api-version=1.0 [13:28:07 INF] Received HTTP response headers after 968.9722ms - 500 [13:28:07 INF] End processing HTTP request after 969.1742ms - 500 [13:28:07 ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": {}, "validationErrors": null }

[13:28:07 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.ClientProxyBase1.RequestAsync(ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.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) [13:28:07 ERR] Code: [13:28:07 ERR] Details: [13:28:07 INF] Executed page /Payment/Stripe/PrePayment in 1007.7672ms [13:28:07 INF] Executed endpoint '/Payment/Stripe/PrePayment' [13:28:07 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.ClientProxyBase1.RequestAsync(ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.RequestAsync[T](ClientProxyRequestContext requestContext) at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase1.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 --- at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context) [13:28:07 INF] Request finished HTTP/2 POST https://localhost:44380/Payment/Stripe/PrePayment?paymentRequestId=a23c0f0e-62ca-9eab-78fc-3a14f14c5b60 - 500 null text/html; charset=utf-8 1097.2184ms

    public virtual async Task&lt;IActionResult&gt; OnPost()
    {
        var planId = new Guid("158c0405-7d7b-782b-6134-3a14e2d52556");
        var paymentRequest = await PaymentRequestAppService.CreateAsync(
            new PaymentRequestCreateDto()
            {
                Products =
                {
                    new PaymentRequestProductCreateDto
                    {
                        PaymentType = PaymentType.Subscription,
                        Name = "Enterprise Plan",
                        Code = "EP",
                        Count = 1,
                        // Place your created PlanId below.
                        PlanId = planId
                    }
                }
            });
            return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id);
    }
  1. POST TestPayModel using Host Admin - failed at LocalRedirectPreserveMethod

`using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Volo.Abp.MultiTenancy; using Volo.Saas.Subscription;

namespace MediBetter.Test.Web.Pages { public class TestPayModel : PageModel { protected ISubscriptionAppService SubscriptionAppService { get; }

    protected ICurrentTenant CurrentTenant { get; }

    public TestPayModel(
        ISubscriptionAppService subscriptionAppService,
        ICurrentTenant currentTenant)
    {
        SubscriptionAppService = subscriptionAppService;
        CurrentTenant = currentTenant;
    }

    public async Task<IActionResult> OnPostAsync(Guid editionId)
    {
        System.Console.Write($"Post Edition {editionId}");
        // 2. Run as Host Admin
        var tenantId = new Guid("9374a261-f7c5-4c4c-ba88-3a14e2feb5d1");
        var paymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, tenantId); // 200 OK but failed at /api/payment/stripe/start
        //2024-09-11 09:55:19.079 +10:00 [INF] Start processing HTTP request POST https://localhost:44330/api/saas/subscription?editionId=36689a17-f58a-53c1-989f-3a14e2c5bba7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0
        //            2024 - 09 - 11 09:55:19.079 + 10:00[INF] Sending HTTP request POST https://localhost:44330/api/saas/subscription?editionId=36689a17-f58a-53c1-989f-3a14e2c5bba7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0
        //            2024 - 09 - 11 09:55:19.543 + 10:00[INF] Received HTTP response headers after 463.6297ms - 200
        //2024 - 09 - 11 09:55:19.543 + 10:00[INF] End processing HTTP request after 463.9229ms - 200
        //2024 - 09 - 11 09:55:25.109 + 10:00[INF] Executed handler method OnPostAsync, returned result Microsoft.AspNetCore.Mvc.LocalRedirectResult.
        //2024 - 09 - 11 09:55:25.160 + 10:00[INF] Executing LocalRedirectResult, redirecting to / Payment / GatewaySelection ? paymentRequestId = 1fcdfc7f - 71e7 - b626 - c277 - 3a14f089cbb1.
        //2024 - 09 - 11 09:55:25.161 + 10:00[INF] Executed page / TestPay in 9610.8776ms
        //2024 - 09 - 11 09:55:25.161 + 10:00[INF] Executed endpoint '/TestPay'
        //2024 - 09 - 11 09:55:25.263 + 10:00[INF] Request finished HTTP / 2 POST https://localhost:44380/TestPay - 307 0 null 9819.4987ms
        //2024 - 09 - 11 09:55:25.358 + 10:00[INF] Request starting HTTP / 2 POST https://localhost:44380/Payment/GatewaySelection?paymentRequestId=1fcdfc7f-71e7-b626-c277-3a14f089cbb1 - application/x-www-form-urlencoded 272
        //2024 - 09 - 11 09:55:25.392 + 10:00[DBG] Get dynamic claims cache for user: 61316c80 - 2201 - 6007 - 5460 - 3a14e2c055fd
        //2024 - 09 - 11 09:55:25.493 + 10:00[INF] Executing endpoint '/Payment/GatewaySelection'
        //2024 - 09 - 11 09:55:25.547 + 10:00[INF] Route matched with { page = "/Payment/GatewaySelection", action = "", controller = "", area = "" }. Executing page / Payment / GatewaySelection
        //2024 - 09 - 11 09:55:25.547 + 10:00[INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
        //2024 - 09 - 11 09:55:25.560 + 10:00[INF] Executing handler method Volo.Payment.Pages.Payment.GatewaySelectionModel.OnPostAsync - ModelState is "Valid"
        //2024 - 09 - 11 09:55:25.566 + 10:00[INF] Start processing HTTP request GET https://localhost:44330/api/payment/requests/1fcdfc7f-71e7-b626-c277-3a14f089cbb1?api-version=1.0
        //2024 - 09 - 11 09:55:25.567 + 10:00[INF] Sending HTTP request GET https://localhost:44330/api/payment/requests/1fcdfc7f-71e7-b626-c277-3a14f089cbb1?api-version=1.0
        //2024 - 09 - 11 09:55:25.689 + 10:00[INF] Received HTTP response headers after 121.9586ms - 200
        //2024 - 09 - 11 09:55:25.689 + 10:00[INF] End processing HTTP request after 122.1607ms - 200
        //2024 - 09 - 11 09:55:25.692 + 10:00[INF] Start processing HTTP request GET https://localhost:44330/api/payment/gateways/subscription-supported?api-version=1.0
        //2024 - 09 - 11 09:55:25.692 + 10:00[INF] Sending HTTP request GET https://localhost:44330/api/payment/gateways/subscription-supported?api-version=1.0
        //2024 - 09 - 11 09:55:25.709 + 10:00[INF] Received HTTP response headers after 17.0123ms - 200
        //2024 - 09 - 11 09:55:25.709 + 10:00[INF] End processing HTTP request after 17.152ms - 200
        //2024 - 09 - 11 09:55:25.712 + 10:00[INF] Executed handler method OnPostAsync, returned result Microsoft.AspNetCore.Mvc.LocalRedirectResult.
        //2024 - 09 - 11 09:55:25.713 + 10:00[INF] Executing LocalRedirectResult, redirecting to / Payment / Stripe / PrePayment ? paymentRequestId = 1fcdfc7f - 71e7 - b626 - c277 - 3a14f089cbb1.
        //2024 - 09 - 11 09:55:25.713 + 10:00[INF] Executed page / Payment / GatewaySelection in 165.4734ms
        //2024 - 09 - 11 09:55:25.713 + 10:00[INF] Executed endpoint '/Payment/GatewaySelection'
        //2024 - 09 - 11 09:55:25.713 + 10:00[INF] Request finished HTTP / 2 POST https://localhost:44380/Payment/GatewaySelection?paymentRequestId=1fcdfc7f-71e7-b626-c277-3a14f089cbb1 - 307 0 null 355.0931ms
        //2024 - 09 - 11 09:55:25.765 + 10:00[INF] Request starting HTTP / 2 POST https://localhost:44380/Payment/Stripe/PrePayment?paymentRequestId=1fcdfc7f-71e7-b626-c277-3a14f089cbb1 - application/x-www-form-urlencoded 272
        //2024 - 09 - 11 09:55:25.768 + 10:00[DBG] Get dynamic claims cache for user: 61316c80 - 2201 - 6007 - 5460 - 3a14e2c055fd
        //2024 - 09 - 11 09:55:25.796 + 10:00[INF] Executing endpoint '/Payment/Stripe/PrePayment'
        //2024 - 09 - 11 09:55:25.799 + 10:00[INF] Route matched with { page = "/Payment/Stripe/PrePayment", action = "", controller = "", area = "" }. Executing page / Payment / Stripe / PrePayment
        //2024 - 09 - 11 09:55:25.799 + 10:00[INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
        //2024 - 09 - 11 09:55:25.800 + 10:00[INF] Executing handler method Volo.Payment.Stripe.Pages.Payment.Stripe.PrePaymentModel.OnPostAsync - ModelState is "Valid"
        //2024 - 09 - 11 09:55:25.803 + 10:00[INF] Start processing HTTP request POST https://localhost:44330/api/payment/stripe/start?api-version=1.0
        //2024 - 09 - 11 09:55:25.804 + 10:00[INF] Sending HTTP request POST https://localhost:44330/api/payment/stripe/start?api-version=1.0
        //2024 - 09 - 11 09:55:26.469 + 10:00[INF] Received HTTP response headers after 665.6427ms - 500
        //2024 - 09 - 11 09:55:26.469 + 10:00[INF] End processing HTTP request after 665.8016ms - 500
        //2024 - 09 - 11 09:55:26.492 + 10:00[ERR]---------- RemoteServiceErrorInfo----------
        //{
        //                    "code": null,
        //  "message": "An internal error occurred during your request!",
        //  "details": null,
        //  "data": { },
        //  "validationErrors": null
        //}

        //            2024 - 09 - 11 09:55:26.492 + 10:00[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.ClientProxyBase`1.ThrowExceptionForResponseAsync(HttpResponseMessage response)
        //   at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext)
        //   at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.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)
        return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + paymentRequest.Id);
    }
}

}`

To make it clear, I paste the TestPayModel (renamed from Payment) below. It's a multi layer .NET MVC project. I have tested 2 scenarios:

  1. POST TestPayModel using Tenant Admin - failed at CreateSubscriptionAsync

`using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Volo.Abp.MultiTenancy; using Volo.Saas.Subscription;

namespace MediBetter.Test.Web.Pages { public class TestPayModel : PageModel { protected ISubscriptionAppService SubscriptionAppService { get; }

    protected ICurrentTenant CurrentTenant { get; }

    public TestPayModel(
        ISubscriptionAppService subscriptionAppService,
        ICurrentTenant currentTenant)
    {
        SubscriptionAppService = subscriptionAppService;
        CurrentTenant = currentTenant;
    }

    public async Task<IActionResult> OnPostAsync(Guid editionId)
    {
        System.Console.Write($"Post Edition {editionId}");
        // 1. Run as Tenant Admin
        var currentTenantId = CurrentTenant.GetId();
        var currentPaymentRequest = await SubscriptionAppService.CreateSubscriptionAsync(editionId, currentTenantId);
        // CreateSubscriptionAsync threw exceptions:
        //2024 - 09 - 11 09:50:58.132 + 10:00[INF] Executing endpoint '/TestPay'
        //2024 - 09 - 11 09:50:58.133 + 10:00[INF] Route matched with { page = "/TestPay", action = "", controller = "", area = ""}. Executing page / TestPay
        //2024 - 09 - 11 09:50:58.134 + 10:00[INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy
        //2024 - 09 - 11 09:50:58.157 + 10:00[INF] Executing handler method MediBetter.Test.Web.Pages.TestPayModel.OnPostAsync - ModelState is "Valid"
        //2024 - 09 - 11 09:51:02.392 + 10:00[INF] Start processing HTTP request POST https://localhost:44330/api/saas/subscription?editionId=36689a17-f58a-53c1-989f-3a14e2c5bba7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0
        //2024 - 09 - 11 09:51:02.392 + 10:00[INF] Sending HTTP request POST https://localhost:44330/api/saas/subscription?editionId=36689a17-f58a-53c1-989f-3a14e2c5bba7&tenantId=9374a261-f7c5-4c4c-ba88-3a14e2feb5d1&api-version=1.0
        //            2024 - 09 - 11 09:51:02.413 + 10:00[INF] Received HTTP response headers after 21.4186ms - 403
        //2024 - 09 - 11 09:51:02.413 + 10:00[INF] End processing HTTP request after 21.6437ms - 403
        //2024 - 09 - 11 09:51:02.586 + 10:00[ERR]---------- RemoteServiceErrorInfo----------
        //{
        //                "code": "Forbidden",
        //    "message": "Forbidden",
        //    "details": null,
        //    "data": null,
        //    "validationErrors": null
        //}

        //            2024 - 09 - 11 09:51:02.586 + 10:00[ERR] Forbidden
        //Volo.Abp.Http.Client.AbpRemoteCallException: Forbidden
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.ThrowExceptionForResponseAsync(HttpResponseMessage response)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](ClientProxyRequestContext requestContext)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments)
        //    at Volo.Saas.Host.SubscriptionClientProxy.CreateSubscriptionAsync(Guid editionId, Guid tenantId)
        //    at MediBetter.Test.Web.Pages.TestPayModel.OnPostAsync(Guid editionId) in / Users / jay / MediBetter / source / MediBetter.Test / src / MediBetter.Test.Web / Pages / TestPay.cshtml.cs:line 48
        //    at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
        //    at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.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)
        //2024 - 09 - 11 09:51:02.586 + 10:00[ERR] Code: Forbidden
        //2024 - 09 - 11 09:51:02.587 + 10:00[ERR] Details:
        //            2024 - 09 - 11 09:51:02.588 + 10:00[INF] Executed page / TestPay in 4454.8638ms
        //2024 - 09 - 11 09:51:02.588 + 10:00[INF] Executed endpoint '/TestPay'
        //2024 - 09 - 11 09:51:02.593 + 10:00[ERR] An unhandled exception has occurred while executing the request.
        //Volo.Abp.Http.Client.AbpRemoteCallException: Forbidden
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.ThrowExceptionForResponseAsync(HttpResponseMessage response)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync(ClientProxyRequestContext requestContext)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](ClientProxyRequestContext requestContext)
        //    at Volo.Abp.Http.Client.ClientProxying.ClientProxyBase`1.RequestAsync[T](String methodName, ClientProxyRequestTypeValue arguments)
        //    at Volo.Saas.Host.SubscriptionClientProxy.CreateSubscriptionAsync(Guid editionId, Guid tenantId)
        //    at MediBetter.Test.Web.Pages.TestPayModel.OnPostAsync(Guid editionId) in / Users / jay / MediBetter / source / MediBetter.Test / src / MediBetter.Test.Web / Pages / TestPay.cshtml.cs:line 48
        //    at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
        //    at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.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 ---
        //    at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
        //2024 - 09 - 11 09:51:02.662 + 10:00[INF] Request finished HTTP / 2 POST https://localhost:44380/TestPay - 500 null text/html; charset=utf-8 4621.8362ms
        return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + currentPaymentRequest.Id);
    }
}

} `

If you can provide a working example, there will be great.

Showing 1 to 10 of 14 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06