Payouts
Move settled balance to your bank account.
A payout (po_...) moves your settled VINR balance to your connected bank account. Charges, refunds, disputes, and fees all flow through your balance first; payouts are how that balance reaches you. This page explains the schedule, how status and timing work, what happens when a payout fails, and how to reconcile what landed.
Balance, then payoutAsk
Money does not move directly from a charge to your bank. Each captured payment lands in your VINR balance only after it settles (typically the funding delay for the method and currency). Refunds, dispute reversals, and platform fees are deducted from the same balance. A payout sweeps the available portion of that balance — never the pending portion.
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
const balance = await vinr.balance.retrieve();
// { available: [{ amount: 184250, currency: 'EUR' }],
// pending: [{ amount: 39000, currency: 'EUR' }] }Amounts are integers in minor units — 184250 is EUR 1,842.50. Each currency has its own balance and its own payouts; VINR never converts between currencies inside a balance.
Payout scheduleAsk
Most accounts use an automatic schedule: VINR sweeps the available balance for each currency on a fixed cadence and creates a payout for you. Configure it once in the Dashboard or via the API.
Prop
Type
await vinr.payouts.updateSchedule({
interval: 'weekly',
weeklyAnchor: 'friday',
delayDays: 4,
});Manual vs. automatic payoutsAsk
| Automatic | Manual | |
|---|---|---|
| Trigger | VINR, on the schedule above | You, via API or Dashboard |
| Best for | Steady cash flow, low operational effort | Treasury control, batching, holding reserve |
| What it sweeps | Full available balance per currency | An amount you specify (up to available) |
Set interval: 'manual' to stop the automatic sweep, then create payouts on your own terms. A manual payout never exceeds the available balance, and you may pay out less to retain a working reserve.
const payout = await vinr.payouts.create({
amount: 100000, // EUR 1,000.00
currency: 'EUR',
description: 'Weekly treasury sweep',
});
// payout.id === "po_...", payout.status === "pending"Payout status & timingAsk
A payout moves through a small state machine. Subscribe to the webhook events to drive reconciliation rather than polling.
| Status | Meaning | Typical event |
|---|---|---|
pending | Created; queued for the next bank transfer window. | payout.created |
in_transit | Submitted to the banking network. | payout.in_transit |
paid | Funds confirmed at your bank. | payout.paid |
failed | The bank rejected the transfer; balance is restored. | payout.failed |
canceled | Withdrawn before it left VINR (manual payouts only). | payout.canceled |
Bank settlement usually takes one to three business days after in_transit, depending on the destination country and rail. Weekends and bank holidays in the destination country do not count.
const verified = vinr.webhooks.verify(payload, signature); // x-vinr-signature
if (verified.type === 'payout.paid') {
const po = verified.data; // "po_..."
await ledger.markSettled(po.id, po.amount, po.arrivalDate);
}Failed payoutsAsk
When a bank rejects a transfer (closed account, wrong IBAN, mandate issue), VINR marks the payout failed, returns the funds to your available balance, and emits payout.failed with a failureCode and failureMessage.
Read the failure reason
Inspect failureCode (e.g. account_closed, invalid_account_number, bank_declined) to decide whether it is a data fix or a contact-your-bank issue.
Fix the destination
Update or re-verify the bank account under Settings → Payout accounts. VINR pauses automatic payouts for a currency after repeated failures until the account is re-verified.
Retry
Funds are already back in your balance. Create a new manual payout, or wait for the next scheduled run once the account is healthy.
Three consecutive failed payouts on the same account trigger an automatic hold and a payout.failed notification to account owners. Resolve the underlying bank issue before retrying to avoid extended holds.
Payout reports & reconciliationAsk
Every payout links to the individual balance transactions it covers — charges, refunds, dispute adjustments, and fees — so you can reconcile a single bank deposit line against gross activity. List a payout's contents, or export a CSV from the Dashboard for your accounting system.
const items = await vinr.balanceTransactions.list({
payout: 'po_3xK9...', // everything that made up this deposit
limit: 100,
});
for (const txn of items.data) {
console.log(txn.type, txn.amount, txn.fee, txn.net, txn.source);
// e.g. "payment" 2000 59 1941 "pay_..."
// "refund" -2000 0 -2000 "re_..."
}The sum of every transaction's net in a payout equals the payout amount. See Reporting & reconciliation for monthly statements and the financial report API.
Bank payoutsAsk
To receive payouts, you must have at least one verified bank account on file. Bank accounts are verified at onboarding, but you can add or update accounts any time in Dashboard → Settings → Payout accounts.
Supported rails and currencies
| Rail | Regions | Typical timing |
|---|---|---|
| SEPA Credit Transfer | EU / EEA | 1 business day |
| Faster Payments | UK | Same business day |
| ACH | US | 1–3 business days |
| SWIFT | Cross-border | 1–5 business days |
Each currency in your balance pays out independently. You cannot receive a EUR balance into a USD account — the destination account must match the currency of the payout.
Verify a bank account
New bank accounts are verified via a micro-deposit confirmation or, where the banking rail supports it, an instant account verification flow. Until verified, automatic payouts are queued but not released.
const account = await vinr.payoutAccounts.create({
currency: 'EUR',
bankAccount: {
country: 'DE',
iban: 'DE89370400440532013000',
accountHolderName: 'Example GmbH',
},
});
// account.status === 'pending_verification'
// VINR sends two micro-deposits; confirm the amounts to verify.
await vinr.payoutAccounts.verify(account.id, {
amounts: [12, 34], // micro-deposit amounts in cents
});
// account.status === 'verified'Counterparty name matching is enabled by default. VINR rejects payouts where the accountHolderName does not fuzzy-match the registered account holder at the destination bank. This prevents misdirected payouts under PSD2 VOP (Verification of Payee) rules.
Card payoutsAsk
In addition to bank transfers, VINR supports payouts directly to debit cards — useful for gig-economy platforms, insurance claim disbursements, and instant refunds to a customer's card.
Card payouts settle within 30 minutes for participating issuers using Visa Direct or Mastercard Send, or within 1–2 business days for standard processing.
const payout = await vinr.payouts.create({
amount: 7500, // EUR 75.00
currency: 'EUR',
destination: {
type: 'card',
card: { number: '4111111111111111', expMonth: 12, expYear: 2028 },
},
description: 'Earnings disbursement — week ending 2026-05-30',
});Card payouts are supported for Visa and Mastercard debit cards only. Credit cards are not eligible for push payouts. The payoutEligibility field on a saved card indicates whether it can receive funds.
Check card payout eligibility
const method = await vinr.paymentMethods.retrieve('pm_...');
console.log(method.card.payoutEligibility);
// 'eligible' | 'not_eligible' | 'unknown'Eligibility is determined by the issuer and BIN. Cards with unknown eligibility can be attempted — VINR surfaces a payout.failed with failureCode: 'card_not_eligible' if the issuer declines.
Internal transfersAsk
Internal transfers move funds between balance accounts within your VINR organization — for example, from a platform balance to a sub-merchant balance, or between your EUR and operations reserve accounts.
const transfer = await vinr.transfers.create({
amount: 50000, // EUR 500.00
currency: 'EUR',
source: 'ma_platform',
destination: 'ma_submrchnt_abc',
description: 'Weekly earnings sweep to sub-merchant',
});
// transfer.status === 'pending' | 'completed' | 'failed'Internal transfers are instant between accounts on the same rail and do not leave the VINR network — no banking delay, no transfer fee. They appear as ledger entries in both the source and destination balance transaction reports.
Scheduled internal transfers
Set a recurring transfer on a cron-like schedule rather than calling the API from your own job:
await vinr.transfers.schedules.create({
source: 'ma_platform',
destination: 'ma_submrchnt_abc',
amount: 50000,
currency: 'EUR',
frequency: 'weekly',
weeklyAnchor: 'friday',
description: 'Automated weekly sub-merchant earnings',
});Return a transfer
If a transfer was made in error, initiate a return within 30 days:
await vinr.transfers.return('tfr_...', {
reason: 'incorrect_destination',
});Returns debit the destination account and credit the source. If the destination account has insufficient funds, the return is queued until funds are available.
Transaction rulesAsk
Transaction rules gate whether a payout or transfer can proceed, independent of balance availability. Use them to enforce limits, require approvals, or block transfers to unapproved destinations.
await vinr.payoutRules.create({
name: 'Require approval above EUR 10,000',
condition: { field: 'amount', operator: 'gt', value: 1000000 },
action: 'require_approval',
approvers: ['mbr_finance_lead'],
});Payouts matching a require_approval rule are held in pending_approval status until an approver acts in the dashboard or via the API:
await vinr.payouts.approve('po_...'); // or .reject('po_...')Next stepsAsk
Settlements
How charges settle into your balance before payout.
Reporting & reconciliation
Statements and exports to close your books.
Webhooks
React to payout.paid and payout.failed events.
Last updated on