Open Closed

Stripe Integration Issues #4253


User avatar
0
darutter created
  • ABP Framework version: v5.3.0
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC): no

I am trying to integrate Stripe Payments in to my app and struggling to get things working. I have added the Volo Payment module to my app and put in the correct keys in the appsettings.json file for my Stripe account and webhook settings. I have two main problems:

The first is just getting the payment request for a subscription plan created in Stripe. Using the code sample in the documentation I modified the name and PlanId to match my subscription name and the PlanId GUID that I have in the database for the GateWayPlan. Here is the error I get when it goes to the redirect statement: An unhandled exception occurred while processing the request. StripeException: Not a valid URL Stripe.StripeClient.ProcessResponse<T>(StripeResponse response)

Stack Query Cookies Headers Routing
StripeException: Not a valid URL
Stripe.StripeClient.ProcessResponse<T>(StripeResponse response)
Stripe.StripeClient.RequestAsync<T>(HttpMethod method, string path, BaseOptions options, RequestOptions requestOptions, CancellationToken cancellationToken)
Stripe.Service<TEntityReturned>.RequestAsync<T>(HttpMethod method, string path, BaseOptions options, RequestOptions requestOptions, CancellationToken cancellationToken)
Volo.Payment.Stripe.StripePaymentGateway.StartAsync(PaymentRequest paymentRequest, PaymentRequestStartInput input)
Volo.Payment.Requests.PaymentRequestAppService.StartAsync(string gateway, PaymentRequestStartDto inputDto)
Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync()
Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync()
Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope)
Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync()
Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo)
Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue<TResult>.ProceedAsync()
Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter<TInterceptor>.InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
Volo.Payment.Stripe.Pages.Payment.Stripe.PrePaymentModel.OnPostAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory+NonGenericTaskHandlerMethod.Execute(object receiver, object[] arguments)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync()
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Volo.Abp.AspNetCore.Serilog.AbpSerilogMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Volo.Abp.AspNetCore.Auditing.AbpAuditingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)
IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
Volo.Abp.AspNetCore.Uow.AbpUnitOfWorkMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Volo.Abp.AspNetCore.ExceptionHandling.AbpExceptionHandlingMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Volo.Abp.AspNetCore.MultiTenancy.MultiTenancyMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Builder.ApplicationBuilderAbpJwtTokenMiddlewareExtension+<>c__DisplayClass0_0+<<UseJwtTokenMiddleware>b__0>d.MoveNext()
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<<UseMiddlewareInterface>b__1>d.MoveNext()
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

If I can get some direction on how to resolve this error and what additional pages I need to create in my app to successfully handle the subscription creation process I would appreciate it.

The second issue is with the webhook. Because this is a subscription I need to have the webhook monitor payment and cancellation activity and have code in my app to handle each event type. I have tried to execute stripe events in my local environment using Stripe's tool that generates stripe events and sends them to my local instance. There isn't any good documentation that I have found that addresses what URL to use for the webhook address or how to hook into the events that would be generated. Please provide some direction on these two webhook issues also.

In addition to the entries in the Payment section of the appsettings.json file for stripe, I also have a section for PaymentWebOptions as follows:

  "PaymentWebOptions": {
    "CallBackUrl": "http://localhost:44386/patriotpayment/success",
    "RootUrl": "http://localhost:44386",
    "PaymentGatewayWebConfigurationDictionary": {
      "Name": "Stripe",
      "PrePaymentUrl": "http://localhost:44386/patriotpayment",
      "PostPaymentUrl": "http://localhost:44386/patriotpayent/success",
      "ExtraInfos": "Club Name"
    }

These are the settings I use when running locally.


7 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You have PaymentWebOptions in appsettings.json, Do you have Configure code?

    var configuration = context.Services.GetConfiguration();
    Configure<PaymentWebOptions>(configuration.GetSection("PaymentWebOptions"));
    
    OR
    
    Configure<PaymentWebOptions>(options =>
    {
        options.RootUrl = configuration["AppSelfUrl"];
        options.CallbackUrl = configuration["AppSelfUrl"] + "/PaymentSucceed";
    });
    

    https://docs.abp.io/en/commercial/latest/modules/payment#enabling-webhooks

  • User Avatar
    0
    darutter created

    I added the Configure and it took me to the payment page in Stripe. However, once I entered payment info it tried to redirect me to /Payment/Stripe/PostPayment?SessionId=##################

    This generated an error page indicating the site can't be reached. What else am I missing?

    Again, the documentation on the pieces you need to have in place is very sparse.

  • User Avatar
    0
    darutter created

    Also, when I attempt to make a webhook call, I get the error that a connection was made but was forcibly closed by the remote host. I need to get the webhook working and understand how to respond to the events that are created by the Payment module.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    This generated an error page indicating the site can't be reached. What else am I missing? I get the error that a connection was made but was forcibly closed by the remote host.

    Can you share the error stack? Thanks

  • User Avatar
    0
    darutter created

    This is what gets written to the log file when it attempts to go to the PostPayment page:

    2023-01-04 13:33:01.382 -06:00 [INF] Executed page /Payment/Stripe/PrePayment in 1317.5135ms 2023-01-04 13:33:01.382 -06:00 [INF] Executed endpoint '/Payment/Stripe/PrePayment' 2023-01-04 13:33:01.383 -06:00 [DBG] Added 0 entity changes to the current audit log 2023-01-04 13:33:01.464 -06:00 [DBG] Added 0 entity changes to the current audit log 2023-01-04 13:33:01.465 -06:00 [DBG] Added 0 entity changes to the current audit log 2023-01-04 13:33:01.468 -06:00 [INF] Request finished HTTP/2 POST https://localhost:44386/Payment/Stripe/PrePayment?paymentRequestId=c88a7705-1efa-f4b8-6c0c-3a0890729b55 application/x-www-form-urlencoded 182 - 200 - text/html;+charset=utf-8 1422.9578ms 2023-01-04 13:33:01.481 -06:00 [INF] Request starting HTTP/2 GET https://localhost:44386/_framework/aspnetcore-browser-refresh.js - - 2023-01-04 13:33:01.484 -06:00 [INF] Request finished HTTP/2 GET https://localhost:44386/_framework/aspnetcore-browser-refresh.js - - - 200 12006 application/javascript;+charset=utf-8 2.3914ms 2023-01-04 13:33:01.489 -06:00 [INF] Request starting HTTP/2 GET https://localhost:44386/_vs/browserLink - - 2023-01-04 13:33:01.512 -06:00 [INF] Request finished HTTP/2 GET https://localhost:44386/_vs/browserLink - - - 200 - text/javascript;+charset=UTF-8 23.1619ms However the browser merely says "Site cannot be reached."

    Any ideas?

  • User Avatar
    0
    darutter created

    There are the settings I have in my appsettings.json file: "PaymentWebOptions": { "CallBackUrl": "/patriotpayment/success", "RootUrl": "http://localhost:44386", "PaymentGatewayWebConfigurationDictionary": { "Name": "Stripe", "PrePaymentUrl": "/patriotpayment", "PostPaymentUrl": "/patriotpayent/success", "ExtraInfos": "Club Name" }

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you create a new template project and reproduce the problem and share the project?

    liming.ma@volosoft.com

Made with ❤️ on ABP v9.1.0-preview. Updated on December 10, 2024, 06:38