Get Stripe Connect Status
Real-time pull from the Stripe API with DB sync. Falls back to stored DB values when Stripe SDK is unavailable. Returns charges/payouts enabled flags + onboarding completion flag.
GET /api/v1/creators/stripe-connect/status — 🔑 Bearer · Rate limit: 10 req / hour
Returns the current Stripe Connect account state. Pulls fresh from Stripe when an account exists — and syncs the result back to the database before returning, so the next read of CreatorProfile.stripe* fields is up-to-date even if the webhook is delayed. Falls back to stored DB values if Stripe SDK isn't configured or the API call fails.
detailsSubmitted is not stored in our DB. It comes only from the live Stripe API call. When the Stripe call fails (or no account is connected yet), the fallback path returns detailsSubmitted: false — that's "we don't know" rather than a definitive "no". Read chargesEnabled / payoutsEnabled for the actual gate decisions.
This endpoint mutates the DB on success. Every successful read also writes back stripeAccountStatus / stripeChargesEnabled / stripePayoutsEnabled from Stripe. Don't call it in tight loops; use /creators/payout-settings for the cached read and call this only when you need fresh-from-Stripe data.
Request
No body, no params. Identity comes from the bearer token.
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | ✓ | JWT from POST /auth/login |
Response
200 OK — ApiResponseOf<StripeConnectStatusResponseDto>
{
"success": true,
"data": {
"stripeAccountId": "acct_...",
"stripeAccountStatus": "ACTIVE",
"chargesEnabled": true,
"payoutsEnabled": true,
"detailsSubmitted": true
}
}| Field | Type | Notes |
|---|---|---|
stripeAccountId | string | null | Stripe Express account id; null until /initiate runs |
stripeAccountStatus | enum | One of NOT_STARTED / PENDING / ACTIVE / RESTRICTED / DISABLED (resolved by resolveAccountStatus() from Stripe's account flags) |
chargesEnabled | boolean | true once Stripe has approved charges. Required for marketplace flows. |
payoutsEnabled | boolean | true once Stripe has approved payouts. Required to actually receive money. |
detailsSubmitted | boolean | true once the account holder has submitted all required onboarding details. Live-only field; fallback returns false. |
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
401 | (guard) | Missing / invalid bearer token |
404 | creator.stripe.not_creator | No CreatorProfile for this user |
429 | (throttle) | Rate limit exceeded (10 req/hour) |
Side effects
- Lookup
CreatorProfile; thrownot_creatorif missing. - No Stripe account yet (
stripeAccountId === null) — short-circuit return: storedstripeAccountStatusfrom DB (typicallyNOT_STARTED), all booleansfalse,stripeAccountId: null. No mutations, no Stripe call. - Account exists — try
stripe.accounts.retrieve(stripeAccountId):- Success path: compute
status = resolveAccountStatus(account)(maps Stripe flags to our enum),update CreatorProfile { stripeAccountStatus, stripeChargesEnabled = account.charges_enabled, stripePayoutsEnabled = account.payouts_enabled }(DB sync), return live values. - Failure path (Stripe SDK unavailable, network failure, API error): log warning, return stored DB values with
detailsSubmitted: false. No DB write in this path.
- Success path: compute
Code samples
curl https://api.bio.re/api/v1/creators/stripe-connect/status \
-H "Authorization: Bearer $ACCESS_TOKEN"type StripeAccountStatus = 'NOT_STARTED' | 'PENDING' | 'ACTIVE' | 'RESTRICTED' | 'DISABLED';
type StripeConnectStatus = {
stripeAccountId: string | null;
stripeAccountStatus: StripeAccountStatus;
chargesEnabled: boolean;
payoutsEnabled: boolean;
detailsSubmitted: boolean;
};
async function getStripeConnectStatus(accessToken: string): Promise<StripeConnectStatus> {
const res = await fetch('https://api.bio.re/api/v1/creators/stripe-connect/status', {
headers: { Authorization: `Bearer ${accessToken}` },
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Stripe Connect status fetch failed'), {
code: json?.error?.code,
});
}
return json.data;
}import { useQuery } from '@tanstack/react-query';
export const creatorKeys = {
stripeConnectStatus: () => ['creators', 'stripe-connect', 'status'] as const,
};
export function useStripeConnectStatus() {
return useQuery({
queryKey: creatorKeys.stripeConnectStatus(),
queryFn: async () => {
const res = await fetch('/api/v1/creators/stripe-connect/status');
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Stripe Connect status fetch failed'), {
code: json?.error?.code,
i18nKey: json?.error?.i18nKey,
});
}
return json.data as StripeConnectStatus;
},
// Live API call — keep stale window long; refetch only on explicit user action
staleTime: 5 * 60_000,
});
}Try it
Authorization
bearer In: header
Response Body
application/json
application/json
curl -X GET "https://loading/api/v1/creators/stripe-connect/status"{
"success": true,
"data": {
"stripeAccountId": "string",
"stripeAccountStatus": "NOT_STARTED",
"chargesEnabled": false,
"payoutsEnabled": false,
"detailsSubmitted": false
}
}{
"success": false,
"error": {
"code": "AUTH_UNAUTHORIZED",
"message": "Invalid credentials",
"i18nKey": "auth.login.invalid_credentials",
"i18nVars": {
"field": "email"
},
"details": [
{
"message": "email must be an email"
}
],
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Source
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/creator/stripe-connect.controller.ts | 27–33 (status) |
| DTO (response) | apps/api-core/src/modules/creator/dto/stripe-connect-response.dto.ts | 20–35 (StripeConnectStatusResponseDto) |
| Service | apps/api-core/src/modules/creator/stripe-connect.service.ts | 103–162 (getStatus), resolveAccountStatus() (status mapping helper) |
| Stripe provider | apps/api-core/src/modules/payment/stripe.provider.ts | getStripe() (returns null if not configured) |
| Prisma model | packages/prisma/prisma/schema.prisma | CreatorProfile.stripeAccountId, CreatorProfile.stripeAccountStatus (enum), CreatorProfile.stripeChargesEnabled, CreatorProfile.stripePayoutsEnabled |
Initiate Stripe Connect
Create a Stripe Connect Express account and return a hosted onboarding URL. KYC must be APPROVED first. Idempotent — repeated calls return a fresh link for the same account.
Refresh Onboarding Link
Get a fresh hosted onboarding link for an existing Stripe Connect account. Use when the previous link expired or the user closed the tab without finishing.