Open Closed

How to configure success URL for Stripe? #9808


User avatar
0
cstobler created

Hi, I am attempting to setup self-service registration and subscription for customers. I am having an issue where when I try to go to the payment screen, it throws an error saying "Invalid URL", and when I go to Stripe, it shows a relative URL that I cannot seem to adjust.

For context, here is my register page model OnPostAsync:

public async Task<IActionResult> OnPostAsync()
{
    if (!ModelState.IsValid)
    {
        await OnGetAsync(); // reload editions
        return Page();
    }

    // Confirm we are NOT in tenant context
    if (_currentTenant.Id != null)
    {
        throw new Exception("Cannot register a tenant while already in a tenant context.");
        //return Forbid(); // Registration should only be done as host
    }

    StartSubscriptionResultDto resultDto = await _multiTenancyAppService.RegisterAndSubscribeAsync(new SaasTenantCreateDto
    {
        Name = Input.TenantName,
        AdminEmailAddress = Input.Email,
        AdminPassword = Input.Password,
        EditionId = Input.EditionId,
        ActivationState = Volo.Saas.TenantActivationState.Passive
    });

    return LocalRedirectPreserveMethod("/Payment/GatewaySelection?paymentRequestId=" + resultDto.PaymentRequestId);
}

And here is my RegisterAndSubscribeAsync method:

public async Task<StartSubscriptionResultDto> RegisterAndSubscribeAsync(SaasTenantCreateDto input)
{
    if (input.EditionId == null || input.EditionId == Guid.Empty)
    {
        throw new UserFriendlyException("Please select a valid edition.");
    }

    // 1) Create tenant via domain layer (no host permission needed)
    var tenant = await _tenantManager.CreateAsync(input.Name, editionId: input.EditionId);

    tenant.SetActivationState(input.ActivationState); // keep passive until payment succeeds
    await _tenantRepository.InsertAsync(tenant, autoSave: true);

    // 2) Publish TenantCreatedEto to seed admin user (same as TenantAppService does)
    await _eventBus.PublishAsync(new TenantCreatedEto
    {
        Id = tenant.Id,
        Name = tenant.Name,
        Properties =
    {
        {"AdminEmail", input.AdminEmailAddress},
        {"AdminPassword", input.AdminPassword}
    }
    });

    // 3) Start subscription (creates PaymentRequest with TenantId/EditionId extra props)
    PaymentRequestWithDetailsDto paymentRequest = await _subscriptionAppService.CreateSubscriptionAsync(input.EditionId ?? Guid.Empty, tenant.Id);

    return new StartSubscriptionResultDto
    {
        TenantId = tenant.Id,
        PaymentRequestId = paymentRequest.Id,
    };
}

I have tried to set the callbackurl, prepaymenturl, and postpaymenturl in appsettings, but that doesn't seem to do anything (stripe keys redacted for security):

"PaymentWebOptions": {
  "RootUrl": "https://armadasoftware.io",
  "CallBackUrl": "https://armadasoftware.io/Payment/Stripe/PostPayment",
  "PaymentGatewayWebConfigurationDictionary": {
    "Stripe": {
      "PrePaymentUrl": "https://armadasoftware.io/Payment/Stripe/PrePayment",
      "PostPaymentUrl": "https://armadasoftware.io/Payment/Stripe/PostPayment"
    }
  }
},
"Payment": {
  "Stripe": {
    "PublishableKey": "",
    "SecretKey": "",
    "WebhookSecret": ""
  }
},

When I get this error, I go to Stripe Webhook logs, and I find this: So it is saying the URL is invalid, and the success URL is a relative URL, which seems problematic, but I cannot seem to find a configuration or anything in the documentation that allows me to set a success URL such that it overrides this. I tried setting the success url in the stripe section of appsettings, but that didn't work either. Please advise me on how to set this so it overrides whatever default URL is being sent to Stripe here.


4 Answer(s)
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent

    To configure the Stripe success URL in ABP's Payment Module, you must ensure that the PaymentWebOptions are set up correctly with absolute URLs. Stripe requires absolute URLs for success and cancel URLs; relative URLs (like "/Payment/Stripe/PostPayment") will cause the "Not a valid URL" error you are seeing.

    Here's how to resolve this:

    1. In your appsettings.json, set the PaymentWebOptions with absolute URLs:
    "PaymentWebOptions": {
      "RootUrl": "https://armadasoftware.io",
      "CallbackUrl": "https://armadasoftware.io/Payment/Stripe/PostPayment"
    }
    
    1. In your module's PreConfigureServices (e.g., in your WebModule or AuthServerModule), configure PaymentWebOptions using the configuration:
    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetConfiguration();
        Configure<PaymentWebOptions>(options =>
        {
            options.RootUrl = configuration["PaymentWebOptions:RootUrl"];
            options.CallbackUrl = configuration["PaymentWebOptions:CallbackUrl"];
        });
    }
    
    1. Do not use relative URLs in PaymentGatewayWebConfigurationDictionary for Stripe. The Payment Module will use RootUrl + CallbackUrl to generate the absolute success_url for Stripe.

    2. Make sure your Stripe webhook and dashboard are also configured to use absolute URLs.

    After these changes, the success_url sent to Stripe will be something like:

    https://armadasoftware.io/Payment/Stripe/PostPayment?SessionId={CHECKOUT_SESSION_ID}
    

    This should resolve the "Invalid URL" error.

    Sources:

    • https://abp.io/docs/latest/modules/payment

    This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.

  • User Avatar
    0
    cstobler created

    That section in PreConfigureServices did the trick. However, I am having another related issue.

    I am getting this error: So it is treating my Stripe product ID as if it were a price. However, I was under the impression I could use the Stripe product id when configuring the gateway plan:

    Am I doing this incorrectly? Is there some other way to tie my plan in to a Stripe product?

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi,

    It depends on a couple of different cases:

    • First make sure you have a "default" price. If you have multiple prices for a specific prroduct, you should choose one of them as default.

    If still doesn't help, you can use directly price ID that starts with price_xx

    Both product and price id works as ExternalId in payment module.

    My suggestion, you can directly try copying price id and using it, if it doesn't work please let us know.

    Stripe or any other 3rd party service UIs are changing constanly, so we cannot mantain screenshots in our documentation, but here is the latest dashboard design of Stripe that I shared in this post

  • User Avatar
    0
    cstobler created

    Thanks for the follow-up. It was indeed the price id. I thought you passed the product id in and it would let them select which price to use (since I am using annual and monthly), but looks like I will need to setup separate plans for each price then.

    Thanks for your help.

    Charlie

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.0.0-preview. Updated on September 01, 2025, 08:37