Open Closed

Stripe integration questions #10163


User avatar
0
Bryan-EDV created

Hello ABP Support Team,

I’m encountering an issue when trying to install the Volo.Payment module via the ABP CLI. Below is the command and output:

[12:32:03 INF] Press Enter to open your browser to login...
[12:32:52 INF] Successfully logged in as 'lexarius'

$ abp add-module Volo.Payment

[12:32:58 INF] You are running the second generation of the ABP CLI.
If you're interested in the legacy CLI, see https://abp.io/new-cli

System.Exception: Remote server returns '403-Forbidden'.
Message: PRO modules require a commercial license! Should be member of an organization with an active license.

Based on the error, it appears that Volo.Payment is a PRO module, and my account may not currently be associated with an organization that has an active commercial license. Could you help verify whether my account is correctly linked to the organization, or if there is anything else I need to configure?

I logged in with app-access@lexarius.com account


In addition, I’m planning to implement the following workflow:

  1. A customer browses available courses/modules.

  2. They add selected items to a shopping cart.

  3. They proceed to checkout and make payment.

  4. Upon successful payment:

    • The customer is added to a join table (e.g., UserCourse or Enrollment).
    • This grants them access to the course(s) they purchased.

Could you advise on the best practices to implement this in ABP?


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

    hi

    Can you share the output of the abp login-info command?

    Thanks.

  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Solution
    • About the 403 error and licensing
      • Volo.Payment is a Commercial (PRO) module. Installing it with abp add-module requires your ABP account to be a member of an organization with an active Commercial license (Team or higher). Otherwise, the CLI returns 403 Forbidden with the ā€œPRO modules require a commercial licenseā€ message.
      • Verify your current CLI session and organization:
        1. Run: abp login-info
        2. Check that:
          • Logged in: True
          • Email matches app-access@lexarius.com
          • OrganizationName and LicenseType show your company and an active license (Team/Business/Enterprise). If Organization is empty or LicenseType is not active, the CLI won’t allow adding Volo.Payment.
        3. If the login is stale or points to a wrong org, refresh: abp logout abp login app-access@lexarius.com abp login-info
        4. If you indeed have a Commercial license but your user is not linked to the org, ask your organization owner/admin to invite this email to the licensed organization from the ABP account portal. If you don’t have a Commercial license, you need to obtain one (Team or higher) to use Volo.Payment.
        5. If you still see licensing errors after confirming membership and license, clear local session and retry:
          • abp logout
          • Delete the ABP CLI auth cache folder on the machine (if any), then abp login again.
    • Implementing cart, checkout, payment, and access granting in ABP
      • Recommended building blocks:
        • Domain entities: Course, Order, OrderItem, PaymentRecord (or Payment), Enrollment (UserCourse)
        • Application services: CartAppService, OrderAppService, PaymentAppService, EnrollmentAppService
        • Integration with Payment: Prefer ABP’s Payment Module (PRO) for Stripe/PayPal/etc. If you don’t/can’t use it, you can integrate Stripe SDK directly in your app service following ABP’s layered architecture and unit of work.
      • High-level flow (with ABP Payment Module)
        1. Cart:
          • Persist cart items per user (e.g., a Cart aggregate or transient client-side cart sent at checkout).
          • Validate availability/prices via application service.
        2. Create Order (domain-driven):
          • In an application service method, map cart items to an Order aggregate and OrderItems; calculate totals; save Order with status PendingPayment.
        3. Create Payment Request:
          • Use the Payment Module to create a payment request associated with the Order ID and total amount; select the gateway (Stripe).
          • Redirect the user to Stripe checkout (hosted) or collect payment method and confirm on the server, depending on gateway flow.
        4. Handle payment success callback/webhook:
          • Implement the gateway callback/webhook endpoint. In the handler:
            • Verify signature/intent status.
            • Update PaymentRecord to Succeeded and Order to Paid in a single unit of work.
            • Publish a domain event like OrderPaidEvent.
        5. Grant access on success:
          • Handle OrderPaidEvent (or subscribe to the PaymentSucceeded event if using the Payment Module) to create Enrollment rows per purchased Course: repository.InsertAsync(new Enrollment(userId, courseId));
          • Optionally, assign permissions/roles or feature flags if access is permission-based, but a simple Enrollment join table is typical.
        6. Authorization:
          • In course access queries/controllers, filter by current user’s enrollments to authorize content access.
      • Example skeleton
        • Domain event after payment success:
    public class OrderPaidEvent : EntityEventData<Order>
          {
              public OrderPaidEvent(Order entity) : base(entity) {}
          }
    
    - Event handler to grant access:
    
    public class OrderPaidEventHandler : ILocalEventHandler<OrderPaidEvent>, ITransientDependency
          {
              private readonly IRepository<Enrollment, Guid> _enrollmentRepo;
    
              public OrderPaidEventHandler(IRepository<Enrollment, Guid> enrollmentRepo)
              {
                  _enrollmentRepo = enrollmentRepo;
              }
    
              public async Task HandleEventAsync(OrderPaidEvent eventData)
              {
                  var order = eventData.Entity;
                  foreach (var item in order.Items)
                  {
                      await _enrollmentRepo.InsertAsync(new Enrollment(order.UserId, item.CourseId), autoSave: true);
                  }
              }
          }
    
    - Guarding course content:
    
    public class CourseAppService : ApplicationService
          {
              private readonly IRepository<Enrollment, Guid> _enrollmentRepo;
              private readonly IRepository<Course, Guid> _courseRepo;
    
              public async Task<CourseDto> GetAsync(Guid courseId)
              {
                  var isEnrolled = await _enrollmentRepo.AnyAsync(e => e.UserId == CurrentUser.GetId() && e.CourseId == courseId);
                  if (!isEnrolled) throw new AbpAuthorizationException("Not enrolled");
    
                  var course = await _courseRepo.GetAsync(courseId);
                  return ObjectMapper.Map<Course, CourseDto>(course);
              }
          }
    
    • If you cannot use the PRO Payment Module:
      • Keep the same domain flow (Order, PaymentRecord, events).
      • Integrate Stripe Checkout/Payment Intents in your application service and controller. Persist PaymentRecord with external transaction IDs. On webhook, update Order and raise the same OrderPaidEvent to centralize the access granting logic.
    • Multi-tenancy and consistency:
      • Use ABP UnitOfWork in application services and event handlers.
      • Use background jobs only if post-payment steps are long-running; otherwise handle synchronously inside the same UoW triggered by the webhook/event.
    1. Sources
    • ABP Module System basics:
      • https://abp.io/docs/latest/framework/architecture/modularity/basics
    • ABP Payment Module (Commercial/PRO) overview:
      • https://abp.io/docs/latest/modules/payment
    • ABP new CLI reference page mentioned in your log:
      • https://abp.io/new-cli
    • ABP Commercial and PRO modules/licensing references (context on PRO modules and access):
      • https://github.com/abpframework/abp

    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
    Bryan-EDV created

    [maliming] said: hi

    Can you share the output of the abp login-info command?

    Thanks.

    $ abp login-info
    [09:59:39 INF] You are running the second generation of the ABP CLI. If you're interested in the legacy CLI, see https://abp.io/new-cli
    šŸ“Œ ABP CLI 0.9.26
    šŸ“Œ A newer version of the ABP CLI is available: 2.0.2
    šŸ”¼ dotnet tool update -g Volo.Abp.Studio.Cli
    [09:59:41 INF] 
    Login info:
    Name: Lexarius Limited
    Surname: 
    Username: lexarius
    Email Address: app-access@lexarius.com
    Organization: 
    
  • User Avatar
    0
    AI-Bot created
    Support Team ABP Agent
    1. Solution
    • Why the 403 happens

      • Volo.Payment is a Commercial (PRO) module. The ABP CLI only allows installing PRO modules if your logged-in user belongs to an organization that has an active Commercial license.
      • Your login-info shows Organization is empty, so the CLI treats you as not licensed for PRO modules.
    • Fix your account/organization linkage

      1. Ask your organization owner/admin to invite app-access@lexarius.com to the licensed organization from the ABP account portal. Once accepted, re-run:
        • abp logout
        • abp login app-access@lexarius.com
        • abp login-info // Organization should now show your company name
      2. If you believe you already have a valid Commercial license but still see Organization empty, please contact ABP Support to link your user to the organization.
      3. Optionally update your CLI (you’re on 0.9.26, latest is 2.x):
        • dotnet tool update -g Volo.Abp.Studio.Cli
        • abp login-info
    • Implementing cart → checkout → payment → access granting

      • If you use the ABP Payment Module (Commercial):

        1. Create an Order aggregate (Order + OrderItems) from the cart and persist it with status PendingPayment.
        2. Create a payment request via the Payment Module for the Order total and gateway = Stripe.
        3. Redirect to Stripe Checkout or confirm Payment Intent as required by the gateway.
        4. Handle Stripe webhook/callback to mark payment Successful and set Order to Paid within a Unit of Work.
        5. On success, create Enrollment (UserId, CourseId) rows for each purchased item, or publish a domain event (e.g., OrderPaidEvent) and handle it to insert enrollments.
        6. Enforce access by checking Enrollment before serving course content.
      • If you can’t use the Commercial module:

        • Keep the same domain flow (Order, PaymentRecord, events) and integrate Stripe SDK directly. Use a secured webhook endpoint, verify signatures, then update Order and create Enrollment in a single UoW.
      • Example event handler to grant access after payment:

    public class OrderPaidEventHandler : ILocalEventHandler<OrderPaidEvent>, ITransientDependency
      {
          private readonly IRepository<Enrollment, Guid> _enrollmentRepo;
    
          public OrderPaidEventHandler(IRepository<Enrollment, Guid> enrollmentRepo)
          {
              _enrollmentRepo = enrollmentRepo;
          }
    
          public async Task HandleEventAsync(OrderPaidEvent eventData)
          {
              var order = eventData.Entity;
              foreach (var item in order.Items)
              {
                  await _enrollmentRepo.InsertAsync(new Enrollment(order.UserId, item.CourseId), autoSave: true);
              }
          }
      }
    
    1. Sources
    • ABP CLI login-info command:
      • https://abp.io/docs/latest/cli/
    • ABP Module System:
      • https://abp.io/docs/latest/framework/architecture/modularity/basics
    • ABP Payment Module (Commercial):
      • https://docs.abp.io/en/commercial/latest/modules/payment
    • ABP new CLI page:
      • https://abp.io/new-cli
    • For licensing or organization membership issues, please contact:
      • https://abp.io/contact

    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
    maliming created
    Support Team Fullstack Developer

    hi

    There is no organization info for your current user.

    Can you check and share the Lexarius Limited account info from https://abp.io/my-organizations Lexarius Limited should be in the Developers section.

    Login info:
    Name: Lexarius Limited
    Surname: 
    Username: lexarius
    Email Address: app-access@lexarius.com
    Organization: 
    

    Thanks.

  • User Avatar
    0
    Bryan-EDV created

    Seems to be outdated

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try logging in to the Bryan-EDV account in the CLI?

    Thanks.

  • User Avatar
    0
    Bryan-EDV created

    i think Bryan-EDV was renamed to app-access@lexarius.com aka lexarius

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share your organization's developers list?

    https://abp.io/my-organizations/

  • User Avatar
    0
    Bryan-EDV created

    Hi

    Strangely can't see that screen.

    just this one.

    Also my user is Bryan-EDV here:

    But when i click on my account, it is lexarius

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Logging out and logging in again from https://abp.io may help.

    Can you try that?

    Thanks.

  • User Avatar
    0
    Bryan-EDV created

    Oh i realised its a different account. Bryan-EDV is not Lexarius

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can log in to one of these developer accounts.

    Thanks.

  • User Avatar
    0
    Bryan-EDV created

    Sure, thanks.

    For the other part of the qn,

    In addition, I’m planning to implement the following workflow:

    1. A customer browses available courses/modules.
    2. They add selected items to a shopping cart.
    3. They proceed to checkout and make payment.
    4. Upon successful payment:
    5. The customer is added to a join table (e.g., UserCourse or Enrollment).
    6. This grants them access to the course(s) they purchased.

    Could you advise on the best practices to implement this in ABP?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    You can use the repository and app service to query for and display courses on the UI page.

    And then add a new entity to store the shopping cart items for the current user.

    Use the ABP payment module for the payment feature(download the source code of the payment module to check the demo apps).

    After that, you can get the courses that users have purchased.

    The features provided by ABP, such as entities, repository, application services, and UI, are more than sufficient

    Thanks.

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.1.0-preview. Updated on December 03, 2025, 13:19
1
ABP Assistant
šŸ” You need to be logged in to use the chatbot. Please log in first.