Hi @dawoudaayoub,
Thanks for the clear breakdown - happy to map this to the Stripe Marketplace Express Pro setup in Bubble and what must exist on the Stripe side.
Prerequisites (once)
Stripe Dashboard
- Enable Connect (Express) for your platform and finish your platform’s verification.
- Copy Publishable / Secret keys (test & live) and Client ID.
- Add your Redirect URIs (e.g.,
https://yourapp.com/wallet
for live and version‑test for dev).
Bubble / Plugin
- Install the plugin and paste keys + Client ID in the plugin settings (both Dev & Live).
- Create two fields on
User
: stripe_account_id
(text) and payouts_enabled
(yes/no).
Step-by-step flow (matching your steps)
Step 1 - Onboarding (from your Wallet page)
-
Create (or update) a Connected Account
- Action: Create/Update Connected Account
- Type: express
- Save returned
account_id
(e.g., acct_...
) to Current User's stripe_account_id
.
-
Generate onboarding link and redirect
This shows Stripe’s hosted onboarding branded for your app.
Step 2 - Redirect back
On return to the Wallet page:
- Action (Page load): Retrieve Connected Account for
Current User's stripe_account_id
.
- Read (
details_submitted
, payouts_enabled
, requirements
) from the response.
- Optional but recommended: set up a Connect webhook for
account.updated
. Update user fields when payouts_enabled
becomes true and a bank/external account is attached.
Step 3 - Verification complete (show “Withdraw”)
Show the Withdraw button only if:
-
Current User's stripe_account_id
is not empty, and
-
payouts_enabled
is true (or Retrieve Connected Account’s payouts_enabled
is yes), and
- The account has an external bank account (Stripe shows this via
requirements
being empty for payouts).
Step 4 - Request a payout
Key concept: Funds must exist in the connected account’s balance.
Depending on how you charge:
-
Direct to connected account (recommended)
When creating the payment, set transfer_data[destination]=acct_xxx
(plugin action: Create PaymentIntent / Confirm Payment to Connected Account). Funds land directly in the connected account.
Then either:
- Let Stripe auto‑payout on schedule, or
- If you want manual payouts, set schedule to manual (via dashboard or plugin action if you prefer API) and use Create a Payout (on Connected Account) when the user presses Withdraw.
-
Charge on platform, then move funds
If you charged your platform account, first Create a Transfer to acct_xxx
(amount/currency). After transfer settles in the connected account, use Create a Payout (on Connected Account) or let auto‑payout run.
Actions you’ll use for a manual “Withdraw” button:
- (If needed) Create a Transfer →
destination = Current User's stripe_account_id
-
Create a Payout (Connected Account) →
account = Current User's stripe_account_id
, specify amount
& currency
.
Step 5 - Stripe executes payout
Stripe processes the payout to the bank account attached to the connected account. You can display payout status by retrieving the payout or listening to payout.paid / payout.failed
webhooks (Connect endpoint).
Common pitfalls to avoid
- Missing Client ID or Redirect URI in Stripe → onboarding link fails.
- Creating Standard instead of Express account.
- Not saving
acct_xxx
to the User and later calling actions without it.
- Trying to Create Payout when the connected account has no available balance (you must charge with
transfer_data
or transfer funds first).
-
Currency mismatch between charges, transfers, and payouts.
- Testing with Live keys on a dev page (or vice‑versa).
If you’d like, please share:
- A link to your Wallet page (dev),
- Screenshots of your relevant workflows (onboarding, retrieve account, withdraw), and
- The exact action where you’re stuck (error message or step that doesn’t return what you expect).
This could help us pinpoint the root of the issue.
Feel free to check the docs for reference: https://docs.zeroqode.com/plugins/stripe-marketplace-express-pro and the configuration of our demo editor
Best regards,
Support Team
Browse all Zeroqode Plugins for bubble
