Skip to content

Where this file lives

  • This path (docs/payments/stripe-existing-account-oauth.md) is inside the rakletv3 repo for review and maintenance.
  • This document describes the current implemented process for linking an existing Stripe account through Stripe Connect OAuth.

Stripe Existing Account OAuth

Generated: 2026-04-24 Repo: rakletadmin/rakletv3 Focus: Existing Stripe account linking from manager payment account settings.

Purpose

Managers can link an existing Stripe account from the payment accounts settings page. Raklet must know which organisation started the OAuth flow when Stripe redirects back, otherwise it cannot create the correct PaymentAccount.

Scope

This flow covers the "Add Existing Stripe Account" entry in the manager payment accounts screen:

  • Raklet.Backend/Content/scripts/core/manager/settings/settings-payment-accounts.controller.js
  • Application/Areas/Manager/Controllers/SettingsController.cs
  • Raklet.Admin/Controllers/SetupController.cs
  • Services/RakletStripeConnectStandardService.cs

Business Rules

Rule Current behavior
OAuth start URL SettingsController.StripeOAuthExistingPaymentAccount() starts the Stripe Connect OAuth request.
Stripe redirect_uri The flow does not send a redirect_uri; Stripe uses the first/default redirect URI configured in the Connect application settings.
Organisation identity state contains the Organisation.Id that started the flow.
Existing account callback SetupController.StripeOAuthCallback() detects a GUID state and routes to the existing-account handler.
Legacy setup callback Non-GUID state keeps the original SetupController.StripeOAuthCallback() behavior.

Stripe requires any redirect_uri sent to connect.stripe.com/oauth/authorize to exactly match an allowed redirect URI in the Stripe Connect application settings. Tenant URLs such as demo.raklet.com, unport.raklet.com, and custom domains are dynamic, so this flow omits the explicit redirect_uri, relies on the first/default Stripe redirect URI, and carries the tenant context in state.

Flow

  1. The manager opens payment account settings and clicks "Add Existing Stripe Account".
  2. SettingsController.StripeOAuthExistingPaymentAccount() reads the current organisation from session.
  3. Raklet builds the Stripe OAuth URL with:
  4. state = organisation.Id
  5. Stripe redirects back to the first/default redirect URI configured for the Connect application, which must route to SetupController.StripeOAuthCallback().
  6. If state is a GUID, Raklet resolves the organisation from that id.
  7. Raklet exchanges the authorization code through RakletStripeConnectService.AuthorizeStripeAccountAsync().
  8. Raklet creates a PaymentAccount with:
  9. OrganisationId = organisation.Id
  10. CreditCardProcessor = StripeWithDirectCharge
  11. SubMerchantId = stripeUserId
  12. Status = NeedToUpdate
  13. The manager is redirected to PathService.GetStripePaymentUpdateSuccesUrl() so the existing account continues through the normal Stripe payment account update success flow.

QA Checklist

  • Start the existing Stripe account flow from demo.raklet.com and confirm the generated Stripe authorize URL does not include a redirect_uri parameter.
  • Confirm the Stripe Connect application's first/default redirect URI routes to https://admin.raklet.com/Setup/StripeOAuthCallback in production.
  • Complete Stripe OAuth and confirm the new PaymentAccount.OrganisationId matches the organisation id sent in state.
  • Repeat from another tenant such as unport.raklet.com and confirm the created payment account belongs to that tenant.
  • Verify a non-GUID state still follows the legacy SetupController.StripeOAuthCallback() behavior and does not create a payment account automatically.