Skip to content

Payments

Vidivo uses a platform-managed payment model. The platform collects all payments directly via Stripe. Hosts add bank accounts and request payouts, which are transferred via Stripe Payouts API. A 7% platform fee is deducted from each payment.

The billing model pre-authorizes funds before they are spent, preventing unpayable debts at call end.

Time: 0 10 20 30 min
| | | |
v v v v
Holds: [--W1----][--W2----][--W3---]
^ ^
W1 captured W2 captured
At call end (e.g. 24 min):
+-- W3 partial: 4 min x rate = captured
+-- Remainder of W3 hold: released
  1. Guest submits payment method. Stripe hold placed for Window 1 (window_size x rate).
  2. At window_size - 60 seconds, hold for Window 2 is placed.
  3. At the window_size boundary, Window 1 is captured (charged permanently).
  4. This repeats for every subsequent window.
  5. When the call ends, the partial final window is captured at ceil(elapsed_minutes) x rate and remaining holds are released.

Host rate: $3.00/min, window size: 10 minutes.

TimeActionStripe Operation
T+0sCall startsHold $30.00 (W1)
T+9m60s before W1 endsHold $30.00 (W2)
T+10mW1 boundaryCapture $30.00 (W1)
T+19m60s before W2 endsHold $30.00 (W3)
T+20mW2 boundaryCapture $30.00 (W2)
T+23m30sGuest ends callCapture $12.00 (4 min rounded up x $3), Release $18.00

Total charged: $72.00 | Host receives: $72.00 x 0.93 = $66.96


Create a Stripe SetupIntent for saving a card for future payments.

POST /v1/payments/setup-intent
Content-Type: application/json
{
"email": "alex@example.com"
}
HTTP/1.1 201 Created
{
"client_secret": "seti_1OqBuv2eZvKYlo2C_secret_XXXX"
}

Create a Stripe SetupIntent for a guest caller. Returns the client secret and the Stripe publishable key needed to initialize Stripe.js on the frontend.

POST /v1/payments/guest/setup-intent
Content-Type: application/json
{
"email": "guest@example.com"
}
HTTP/1.1 201 Created
{
"client_secret": "seti_1OqBuv2eZvKYlo2C_secret_XXXX",
"publishable_key": "pk_live_XXXX"
}

Retrieve payment history for the authenticated user. Hosts see earnings; guests see charges.

Authentication: Bearer token required.

GET /v1/payments/history?page=1&per_page=20&start_date=2026-03-01&end_date=2026-03-31&status=succeeded
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Query ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 20)
start_datestringFilter: only transactions after this date (YYYY-MM-DD)
end_datestringFilter: only transactions before this date (YYYY-MM-DD)
statusstringFilter by status
{
"success": true,
"data": [
{
"id": "01JN2X8O2R7J1UDVY0AB1BFMJK",
"call_session_id": "01JN2X6M0P5H9SRBTXY8ZDKEFG",
"window_number": 1,
"type": "capture",
"amount": 30.00,
"currency": "usd",
"status": "succeeded",
"created_at": "2026-03-15T14:10:00Z"
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 5,
"total_pages": 1
}
}

Export payment history as CSV, XLSX, or PDF.

Authentication: Bearer token required.

GET /v1/payments/history/export?format=csv&start_date=2026-03-01&end_date=2026-03-31
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Query ParameterTypeDescription
formatstringcsv (default), xlsx, or pdf
start_datestringFilter start date (YYYY-MM-DD)
end_datestringFilter end date (YYYY-MM-DD)
statusstringFilter by status

Returns a file download with appropriate Content-Type and Content-Disposition headers.


Retrieve earnings summary for the authenticated host.

Authentication: Bearer token required (role: host or admin).

GET /v1/payments/earnings
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
{
"total_earned": 1250.00,
"total_paid_out": 980.00,
"pending_balance": 270.00,
"currency": "usd",
"total_calls": 47,
"total_minutes": 623
}

Retrieve daily aggregated earnings data for charting.

Authentication: Bearer token required (role: host or admin).

GET /v1/payments/earnings/chart?period=30d
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Query ParameterTypeDescription
periodstring7d, 30d (default), or 90d
{
"period": "30d",
"data": [
{ "date": "2026-03-01", "amount": 45.00 },
{ "date": "2026-03-02", "amount": 32.50 },
{ "date": "2026-03-03", "amount": 0 }
]
}

Add a bank account for receiving payouts. Creates a Stripe Custom connected account.

Authentication: Bearer token required (role: host or admin).

POST /v1/payments/bank-account
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json
{
"bank_token": "btok_1XXXXXXXXXXXXXXXXX"
}
FieldTypeRequiredDescription
bank_tokenstringYesStripe bank account token from Stripe.js
HTTP/1.1 201 Created
{
"bank_name": "Chase",
"bank_last_four": "6789",
"payout_enabled": true
}

Retrieve the host’s saved bank account information.

Authentication: Bearer token required (role: host or admin).

GET /v1/payments/bank-account
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
{
"bank_name": "Chase",
"bank_last_four": "6789",
"payout_enabled": true
}

Request a payout to the host’s bank account.

Authentication: Bearer token required (role: host or admin).

POST /v1/payments/payout
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json
{
"amount": 100.00
}
FieldTypeRequiredDescription
amountnumberYesPayout amount in USD
HTTP/1.1 201 Created
{
"id": "01JN2X9P3S8K2VEWZ1BC2CGNLM",
"amount": 100.00,
"currency": "usd",
"status": "pending",
"created_at": "2026-03-15T14:00:00Z"
}
CodeStatusDescription
validation_error400Amount exceeds available balance
forbidden403Payouts not enabled (bank account not added)
stripe_error402Stripe payout creation failed

Retrieve payout history for the host.

Authentication: Bearer token required (role: host or admin).

GET /v1/payments/payouts?page=1&per_page=20&start_date=2026-03-01&end_date=2026-03-31
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Query ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 20)
start_datestringFilter start date
end_datestringFilter end date
statusstringFilter by status

Export payout history as CSV, XLSX, or PDF.

Authentication: Bearer token required (role: host or admin).

GET /v1/payments/payouts/export?format=xlsx
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

Create a Stripe Custom connected account and return an onboarding URL where the host completes identity verification and bank account setup.

Authentication: Bearer token required (role: host or admin).

POST /v1/payments/connect/onboard
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json
{
"refresh_url": "https://vidivo.app/settings/payments",
"return_url": "https://vidivo.app/settings/payments?onboarded=true"
}
HTTP/1.1 201 Created
{
"onboarding_url": "https://connect.stripe.com/setup/e/acct_XXXX/..."
}

Download an invoice PDF for a captured payment. Returns a presigned URL to the invoice file stored in Cloudflare R2.

Authentication: Bearer token required.

GET /v1/payments/invoices/01JN2X8O2R7J1UDVY0AB1BFMJK/download
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
{
"download_url": "https://r2.vidivo.app/invoices/2026/03/01JN2X8O2R7J1UDVY0AB1BFMJK.pdf?sig=..."
}

Stripe webhook endpoint. Receives and processes Stripe events. The endpoint verifies the Stripe-Signature header using the webhook signing secret.

Authentication: None (verified via Stripe signature).

EventDescription
payment_intent.succeededPayment hold or capture succeeded
payment_intent.payment_failedPayment failed --- triggers notification
payout.paidHost payout sent to bank
payout.failedHost payout failed --- triggers notification

Terminal window
# Get payment history with date filter
curl "https://api.vidivo.app/v1/payments/history?start_date=2026-03-01&end_date=2026-03-31" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."
# Export payments as CSV
curl "https://api.vidivo.app/v1/payments/history/export?format=csv" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
-o payments.csv
# Get earnings summary
curl https://api.vidivo.app/v1/payments/earnings \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."
# Request payout
curl -X POST https://api.vidivo.app/v1/payments/payout \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..." \
-H "Content-Type: application/json" \
-d '{"amount": 100.00}'
# Download invoice
curl https://api.vidivo.app/v1/payments/invoices/01JN2X8O2R7J1UDVY0AB1BFMJK/download \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9..."