Marketplaces
Marketplaces allow merchants that operate as intermediaries between buyers and sellers to process payments and settle funds to sellers automatically and securely.
Authentication and isolation
Use a Secret API Key from the standard primary account that manages the marketplace:
Authorization: Bearer <YOUR_SECRET_API_KEY>
The key determines the primary account and the immutable test or live mode. Publishable API Keys are not allowed for these operations.
Every read and mutation validates the connected account ID together with the primary account, mode, and account type. A missing ID, an ID owned by another primary account, or an ID from another mode returns the same 404 error without revealing whether the resource exists.
Connected accounts do not receive their own API keys. To charge on behalf of the seller, keep using the primary account key and send the connected account ID in onBehalfOf.
Create a connected account
You can create the account from the Marketplace section in the ONVO Dashboard or with POST /v1/connected-accounts.
curl https://api.onvopay.com/v1/connected-accounts \
-X POST \
-H "Authorization: Bearer <YOUR_SECRET_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"businessName": "Connected Store",
"marketplaceAppFee": 5
}'
businessName is required, trimmed, and must contain 1 to 50 characters. marketplaceAppFee is an optional percentage from 0 through 100 with at most two decimal places. For example, 5 represents 5%. If you omit it, ONVO stores and returns 0.
Creation returns HTTP 201:
{
"id": "cl502zv0d0127ebdp3zt27651",
"mode": "test",
"status": "pending_onboarding",
"businessName": "Connected Store",
"marketplaceAppFee": 5,
"createdAt": "2026-07-25T17:00:00.000Z",
"onboardingUrl": "https://onvopay.com/setup/account_onboarding_test_example"
}
onboardingUrl is returned only when creating the account or regenerating the link. Treat this value as sensitive: give it to the correct seller and do not write it to logs.
List, retrieve, and update
List the accounts in the authenticated mode with GET /v1/connected-accounts. limit accepts 1 through 100 and defaults to 10. startingAfter and endingBefore are mutually exclusive, and the cursor must belong to the same primary account, mode, and filter.
You can filter by pending_onboarding, awaiting_approval, active, inactive, temporally_suspended, permanently_suspended, or deleted. The restricted value is not part of the Secret API Key contract.
curl "https://api.onvopay.com/v1/connected-accounts?status=pending_onboarding&limit=10" \
-H "Authorization: Bearer <YOUR_SECRET_API_KEY>"
The list returns the same public object in the { data, meta } envelope:
{
"data": [
{
"id": "cl502zv0d0127ebdp3zt27651",
"mode": "test",
"status": "pending_onboarding",
"businessName": "Connected Store",
"marketplaceAppFee": 5,
"createdAt": "2026-07-25T17:00:00.000Z"
}
],
"meta": {
"total": 1,
"pages": 1,
"limit": 10,
"cursorNext": "cl502zv0d0127ebdp3zt27651",
"cursorBefore": "cl502zv0d0127ebdp3zt27651"
}
}
GET /v1/connected-accounts/{id} returns exactly the same public object. On legacy accounts without a business profile, businessName can be null; when marketplace fee settings are missing, marketplaceAppFee returns 0.
Update businessName, marketplaceAppFee, or both with POST /v1/connected-accounts/{id}. You must send at least one:
curl https://api.onvopay.com/v1/connected-accounts/cl502zv0d0127ebdp3zt27651 \
-X POST \
-H "Authorization: Bearer <YOUR_SECRET_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"businessName": "Updated Connected Store",
"marketplaceAppFee": 6.25
}'
This generic endpoint does not allow updates to status, onboarding, payout frequency, weekly fees, bank data, or processor configuration. List, retrieve, and update responses never include onboardingUrl.
Configure a weekly fee
Create or update the fixed weekly fee with POST /v1/connected-accounts/{id}/weekly-fees. Send at least one of marketplaceWeeklyFeeEnabled, marketplaceWeeklyFeeAmount, or marketplaceWeeklyFeeCurrency:
curl https://api.onvopay.com/v1/connected-accounts/cl502zv0d0127ebdp3zt27651/weekly-fees \
-X POST \
-H "Authorization: Bearer <YOUR_SECRET_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"marketplaceWeeklyFeeEnabled": true,
"marketplaceWeeklyFeeAmount": 1000,
"marketplaceWeeklyFeeCurrency": "CRC"
}'
marketplaceWeeklyFeeAmount is an integer expressed in the currency's minor unit, from 1 through 2147483647. The weekly fee is available for connected accounts in Costa Rica, Guatemala, and Peru. Supported currencies are USD, CRC for Costa Rica, GTQ for Guatemala, and PEN for Peru.
To enable the fee, the effective configuration must have an amount and currency. The primary account and connected account must also have a payout bank account in that same currency. You can save the amount and currency while the fee is disabled before meeting those requirements; to disable it later, send marketplaceWeeklyFeeEnabled: false.
null values are not allowed. To preserve a field's current value, omit it from the payload. Each request is applied atomically: the first creates the configuration, and later requests update only the supplied values.
The response returns only the public configuration:
{
"id": "cl502zv0d0127ebdp3zt27651",
"marketplaceWeeklyFeeEnabled": true,
"marketplaceWeeklyFeeAmount": 1000,
"marketplaceWeeklyFeeCurrency": "CRC"
}
Cutoff and collection
The fixed weekly fee is separate from marketplaceAppFee: it is created once per week, not once per payment.
Every Friday at 02:00 in America/Costa_Rica, ONVO snapshots the effective configuration. If the fee is enabled and the connected account is active, ONVO creates the full obligation in the configured currency. A change made after the cutoff applies to the following Friday. If the connected account is not active at the cutoff, ONVO does not create that week's fee.
Disabling the fee before the cutoff prevents a new obligation, but disabling it does not remove pending obligations. ONVO deducts them from future payouts in the same currency, after other deductions, and preserves at least 100 minor units in the payout. If the available balance is insufficient, ONVO collects a partial amount and carries the remainder to future payouts, applying the oldest obligations first.
ONVO credits the primary account only for the amount collected when the payout reaches paid. If a paid payout is reversed, ONVO reverses the corresponding credit and reopens the obligation balance. The test and live modes are processed separately.
The weekly fee configuration reference includes complete payloads for null values, an invalid amount, incomplete configuration, unsupported currency, missing bank accounts, a disabled feature, and a connected account that was not found.
Seller onboarding
The seller must complete ONVO-hosted onboarding before receiving payments. During this process, they provide the IBAN accounts where settlements should be sent.
The link expires after 7 days. You can regenerate it from the Dashboard or with POST /v1/connected-accounts/{id}/onboarding-link; when you do, the previous link expires:
curl https://api.onvopay.com/v1/connected-accounts/cl502zv0d0127ebdp3zt27651/onboarding-link \
-X POST \
-H "Authorization: Bearer <YOUR_SECRET_API_KEY>"
{
"id": "cl502zv0d0127ebdp3zt27651",
"onboardingUrl": "https://onvopay.com/setup/account_onboarding_test_example"
}
Regeneration is available only before onboarding is complete. If the account is already active, ONVO returns 409 with marketplaces.onboarding_already_completed.
Once onboarding is complete, the connected account is enabled to accept payments on its behalf.
Errors
Marketplace domain errors use a typed payload with statusCode, type, code, message, path, and timestamp; validation and authentication errors use their own payloads. The POST /v1/connected-accounts, GET /v1/connected-accounts, POST /v1/connected-accounts/{id}, and POST /v1/connected-accounts/{id}/weekly-fees references show the 400 and 401 cases. GET /v1/connected-accounts/{id} shows the 404 response, while POST /v1/connected-accounts/{id}/onboarding-link includes the operation-specific 409 and 500 responses.
Here is a complete example payload for a domain error:
{
"statusCode": 404,
"type": "OnvoAPIError",
"code": "marketplaces.connected_account_not_found",
"message": "The connected account was not found",
"path": "/v1/connected-accounts/cl502zv0d0127ebdp3zt27651",
"timestamp": "2026-07-25T17:00:00.000Z"
}
Handle at least these cases:
| HTTP | Stable code | Meaning |
|---|---|---|
400 | marketplaces.parent_configuration_invalid | The primary account is missing required configuration. |
400 | marketplaces.invalid_cursor | The cursor is invalid, foreign, or does not match the filter. |
400 | marketplaces.invalid_status | The status filter is unsupported. |
400 | marketplaces.unsupported_public_field | The payload includes a field outside the public contract. |
400 | marketplaces.weekly_fee.configuration_required | No weekly configuration field was provided. |
400 | marketplaces.weekly_fee.feature_disabled | The feature is not enabled for the primary account. |
400 | marketplaces.weekly_fee.amount_required | The effective amount is missing when enabling the fee. |
400 | marketplaces.weekly_fee.currency_required | The effective currency is missing when enabling the fee. |
400 | marketplaces.weekly_fee.currency_not_supported | The currency is not supported for the connected account's country. |
400 | marketplaces.weekly_fee.child_bank_account_required | The connected account has no bank account in the configured currency. |
400 | marketplaces.weekly_fee.parent_bank_account_required | The primary account has no bank account in the configured currency. |
401 | — | The key is invalid or publishable, or a live key belongs to an inactive primary account. |
404 | marketplaces.connected_account_not_found | The ID does not belong to the authenticated primary account and mode. |
409 | marketplaces.onboarding_already_completed | The account has already completed onboarding. |
500 | marketplaces.error_creating_onboarding_link | ONVO could not persist the link; no partial writes remain. |
Payment flow
Always use the API keys from the primary account, meaning the account that created the marketplace.
Payment methods, customers, products, and prices must also be created in the primary account. Send onBehalfOf with the seller's Account ID when the charge should belong to a marketplace account.
You can use marketplace with payment intents, one-time Checkout Sessions, and subscriptions.
Payment intents
- Create a payment intent with the
onBehalfOfattribute, using theidreturned when you create the connected account.
{
"amount": 10000,
"currency": "USD",
"onBehalfOf": "cl502zv0d0127ebdp3zt27651"
}
- Confirm the payment intent with the
paymentMethodIdreturned when you create the payment method in the primary account.
{
"paymentMethodId": "cl502zv0d0127ebdp3zt27652"
}
Checkout Sessions
Create the Checkout Session with onBehalfOf. ONVO stores that account on the session and uses it on the payment intent generated for the charge.
{
"redirectUrl": "https://example.com/success",
"cancelUrl": "https://example.com/cancel",
"onBehalfOf": "ma502zv0d0127ebdp3zt27651",
"lineItems": [
{
"quantity": 1,
"unitAmount": 10000,
"currency": "USD",
"description": "Order #1001"
}
]
}
Subscriptions
Create the subscription with onBehalfOf. ONVO uses that marketplace account on the payment intent for the first period and on future renewals.
{
"customerId": "cus502zv0d0127ebdp3zt27651",
"paymentMethodId": "pm502zv0d0127ebdp3zt27651",
"description": "Monthly Pro Plan",
"onBehalfOf": "ma502zv0d0127ebdp3zt27651",
"items": [
{
"priceId": "price502zv0d0127ebdp3zt27651",
"quantity": 1
}
]
}
Checkout Session and subscription lists can also be filtered by seller with the onvo-on-behalf-of header.
If the charge succeeds, ONVO calculates ONVO fees, withholdings, and the marketplace commission on the gross amount.
You can then retrieve a payment intent by ID or list payment intents for the account.
Example for a 100.00 USD transaction:
| Concept | Amount |
|---|---|
| Gross amount | 100.00 USD |
| ONVO fee 3.5% | 3.50 USD |
| Withholding 2% | 2.00 USD |
| Net amount | 94.50 USD |
| Marketplace commission 5% | 5.00 USD |
| Amount settled to seller | 89.50 USD |
The marketplace commission is deposited into the primary account and the net amount is deposited to the seller.
Test and live mode
You can create connected accounts in test or live mode based on the Secret API Key or the active Dashboard mode.
Accounts created in test mode only work with test keys. Accounts created in live mode only work with live keys. You cannot change an account's mode after it is created.