Factuarea APIDevelopers

Connect Stripe in white label

Let your clients connect their own Stripe account to a tax ID from your product. Register your return domains, start the authorization, send the person to Stripe and read the result when they come back.

If you build a product on top of Factuarea, your clients should not have to leave it to connect their Stripe account. This flow keeps them in your portal: you start the connection, the person finishes the onboarding on Stripe's own page, and when they come back Factuarea completes the connection and sends the browser to your site.

Factuarea creates a Standard Stripe account for the tax ID and keeps it with the authorization. The account that ends up connected is always that one: nothing in the return address can change it. Once connected, it behaves like any other connected account, so auto-invoicing stays off until you turn it on.

Live only. This flow does not run in the test environment. A fact_test_ key is rejected, also on the test accounts your own account provisions. A test key cannot even carry the stripe_autoinvoicing scopes, so the call answers insufficient_scope (or profile_not_found if the tax ID is not reachable from the sandbox), and a key that carried them anyway gets module_not_available_in_sandbox. Nothing reaches Stripe and nothing is written. Use a fact_live_ key from the first call.

What you need

  • A live key with stripe_autoinvoicing:write (and stripe_autoinvoicing:read to list). No new scope is involved.
  • The tax ID must be one of your own account, or belong to an account you manage with operate access. An account that only received access to a tax ID cannot start the connection and gets forbidden_action. A tax ID your key does not reach answers 404.
  • The Stripe module in the plan of the tax ID, available in the Empresario and Enterprise plans.
  • Return domains registered in your account. They are the only hosts Factuarea will send a person back to.

1. Register your return domains

A return domain is a host you allow as the destination of the return_url. They belong to the account that starts the connection, which is yours, not the account that owns the tax ID.

curl -X POST https://api.factuarea.com/v1/accounts/{account}/connected-accounts/return-domains \
  -H "Authorization: Bearer $FACTUAREA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "app.midominio.com"}'

It answers 201 with a connect_return_domain object. The rules:

  • Host only, up to 253 characters: no scheme, port, path, wildcard, IP address or localhost. It is lower-cased, so App.MiDominio.com and app.midominio.com are the same domain.
  • Exact match. Registering midominio.com does not allow app.midominio.com: each subdomain you use is its own entry.
  • An account can hold up to twenty domains. Registering one that already exists answers connect_return_domain_already_exists (409) and beyond the limit connect_return_domain_limit_reached (422).
  • {account} is your own account. Another account, one you manage or one that does not exist answers 404 account_not_found.
  • The key must have been issued by an owner or admin of the account and its tax ID scope must cover every tax ID of the account, otherwise forbidden_action.

List them with GET on the same path, with cursor pagination, and remove one with DELETE …/return-domains/{return_domain}, which answers 204. Removing a domain does not touch authorizations already started, but any new return_url on that host is rejected, and the return of one already in flight is no longer sent to it (see the return). If the domain does not exist or belongs to another account, the answer is connect_return_domain_not_found.

The same list is managed from the web app, in Developers, under the return domains tab.

2. Start the authorization

POST /v1/companies/{company}/connected-accounts/authorizations starts the connection of one tax ID. Two things are mandatory:

  • Idempotency-Key header. The call creates an account in Stripe, so a retry without the key could create a second one. A missing key answers idempotency_key_required once the transition window of the platform is closed, and until then the call is served with a Deprecation header. Send it from the first day.
  • return_url, an absolute https address of up to 2048 characters, without credentials or fragment and on port 443. Its host must be one of your return domains. Anything else answers connect_return_url_not_allowed (422) and creates nothing.
curl -X POST https://api.factuarea.com/v1/companies/{company}/connected-accounts/authorizations \
  -H "Authorization: Bearer $FACTUAREA_API_KEY" \
  -H "Idempotency-Key: connect-2026-0001" \
  -H "Content-Type: application/json" \
  -d '{"return_url": "https://app.midominio.com/stripe/vuelta"}'
{
  "data": {
    "id": "0199a1f0-1c22-7a10-b111-3a3b3c3d3e3f",
    "object": "connected_account_authorization",
    "url": "https://connect.stripe.com/setup/s/…",
    "return_url": "https://app.midominio.com/stripe/vuelta",
    "status": "pending",
    "expires_at": "2026-10-06T10:00:00+00:00",
    "company_id": "0199a1f0-1c22-7a10-b111-4a4b4c4d4e4f"
  }
}
  • url is the Stripe onboarding link. It is not a Factuarea page: open it in the browser of the person who owns the Stripe account. It is a short-lived Stripe Account Link: if it expires or has already been used, Stripe sends the person back to Factuarea, which renews it with a new link for the same Stripe account, so you do not need to start again.
  • The authorization stays pending for 24 hours (expires_at is the deadline to complete it, not the expiry of url). Starting again for the same tax ID from the same account while it is still valid reuses it: you get the same id and the same Stripe account back with a fresh link, and the state of the previous one stops being valid.
  • The response has no Location header: an authorization has no read of its own.
  • The call is limited to 10 per minute per key and company, and a rejection never reaches Stripe.

3. The return to your site

When the person finishes on Stripe, they land on Factuarea for a moment, Factuarea checks the account with Stripe and completes the connection, and the browser is redirected to your return_url keeping its own query and adding these parameters:

ParameterOn successOn error
statussuccesserror
providerstripestripe
authorization_idThe id of the authorizationThe id, when it is known
company_idThe tax ID, UUID v7
connected_account_idThe id of the connected account, UUID v7
accountThe Stripe acct_…
errorThe public error code
error_subcodeThe subcode, when there is one

These are the cases you will see in error:

  • business_rule_violation with error_subcode=onboarding_incomplete or onboarding_pending_review: the person left before Stripe accepted the account. The authorization stays pending until it expires: start again and you get the same authorization with a fresh link.
  • resource_already_exists with error_subcode=connected_account_in_use: that Stripe account is already connected to another company. Nothing is connected.
  • business_rule_violation with error_subcode=connect_authorization_expired or connect_authorization_already_used: start a new authorization.

Two situations never send the browser to your site. If you removed the domain of the return_url after starting, the connection still completes if it applies, but the person lands on the Factuarea app instead. The same happens if the return arrives with a value that identifies no authorization. In neither case does Factuarea redirect to a host outside your list.

Read the status and the other parameters as a hint for your screen, not as the source of truth: confirm the connection reading the account.

4. Read the connection

The connected account is then in GET /v1/companies/{company}/connected-accounts, identified by the connected_account_id of the return. It starts with auto-invoicing off and is the main account of the tax ID if there was none. From there it is managed with the usual operations.

What to keep in mind

On this page

Need a hand?Contact support