Reporting & exports
Generate financial and operational reports.
Reports turn the raw stream of payments, invoices, payouts, and loyalty events into the summaries your finance and operations teams actually work from — reconciliation files, revenue rollups, and audit trails. VINR generates reports asynchronously: you request one, VINR builds it, and you download a signed file or stream rows over the API.
Available reportsAsk
Each report type covers one domain and accepts a date range plus optional filters. All amounts are integers in minor units (1000 = EUR 10.00) and respect the currency on each underlying object.
| Report type | What it contains | Common use |
|---|---|---|
payments | Every pay_ object with status, fees, and net. | Daily transaction review. |
balance_transactions | Ledger entries: charges, refunds, fees, adjustments. | Reconciling your VINR balance. |
payouts | po_ and setl_ records with bank reference. | Matching bank deposits. |
invoices | Finalized inv_ objects with tax and discount breakdown. | Revenue and AR reporting. |
subscriptions | Active, trialing, and churned sub_ snapshots. | MRR and churn analysis. |
loyalty | ptx_ and rdm_ activity per loy_ account. | Liability of outstanding points. |
The balance_transactions report is the source of truth for reconciliation. Every euro that moves through VINR — including fees and disputes — appears as a signed ledger entry there.
Generating a reportAsk
A report run is created against a type and an interval, then resolves from pending to succeeded (or failed). Poll the run or subscribe to the report.completed event rather than blocking.
import { Vinr } from '@vinr/sdk';
const vinr = new Vinr({ secretKey: process.env.VINR_SECRET_KEY });
// Request a payments report for April 2026.
const run = await vinr.reports.create({
type: 'payments',
interval: { start: '2026-04-01', end: '2026-04-30' },
columns: ['id', 'created', 'status', 'amount', 'fee', 'net', 'currency'],
format: 'csv', // or 'json'
});
// run.status === 'pending' — wait for completion, then fetch the file URL.
const ready = await vinr.reports.waitUntilDone(run.id);
console.log(ready.fileUrl); // signed, expires in 1 hourThe same call over raw REST:
curl https://api.vinr.com/v1/reports \
-H "X-Api-Key: $VINR_SECRET_KEY" \
-d type=payments \
-d interval[start]=2026-04-01 \
-d interval[end]=2026-04-30 \
-d format=csvFile URLs are short-lived signed links that expire one hour after issue. Download immediately, or re-fetch the report run to mint a fresh URL — do not store the URL itself.
Scheduling exportsAsk
For recurring delivery, attach a schedule to a report definition instead of calling create from a cron of your own. VINR runs it on the cadence you set and can push the result to a destination.
Define the schedule
Pick a frequency (daily, weekly, or monthly) and a delivery target — a webhook endpoint, an email group, or an SFTP/object-storage bucket you've registered under Integration.
VINR runs it
At each interval VINR builds the report for the just-closed period (e.g. yesterday for daily) and emits report.completed with the run id.
Deliver
The file is pushed to your destination, or you fetch it from the event payload. Failed deliveries retry with backoff and surface in Operations alerts.
const schedule = await vinr.reports.schedules.create({
type: 'balance_transactions',
frequency: 'daily',
format: 'csv',
delivery: { type: 'sftp', destination: 'finance-recon' },
});Report schemasAsk
The columns you request map to typed fields. For the payments report the core schema is:
Prop
Type
Omitting columns returns the full default schema for the type. Requesting a column that doesn't exist for a type fails the run with a report.invalid_column error.
API access to reportsAsk
Beyond file exports, list and inspect runs programmatically — useful for building an internal reporting dashboard or verifying that a scheduled run actually fired.
// Did last night's reconciliation report succeed?
const runs = await vinr.reports.list({
type: 'balance_transactions',
status: 'succeeded',
limit: 1,
});
for await (const row of vinr.reports.rows(runs.data[0].id)) {
// Stream JSON rows without downloading the whole file.
ledger.append(row);
}Reports are generated from settled, immutable data, so a run for a closed period always returns identical results. This makes them safe to re-pull for audits without risk of drift.
Financial reportsAsk
Financial reports are the authoritative source for reconciling VINR activity against your general ledger. Each covers one settlement period and is immutable once generated.
Settlement reconciliation
The settlement reconciliation report ties every captured payment to the net amount that landed in your bank account after fees, refunds, and adjustments. It is the primary tool for closing your books each period.
Two granularities are available:
| Granularity | Use |
|---|---|
| Transaction-level | One row per payment — precise, large files for high-volume merchants. |
| Batch-level | One row per settlement batch — compact, suitable for lower-volume or daily summary workflows. |
const run = await vinr.reports.create({
type: 'balance_transactions',
interval: { start: '2026-05-01', end: '2026-05-31' },
granularity: 'transaction', // or 'batch'
format: 'csv',
});Each row includes: payment id, capture date, gross amount, processing fee, interchange fee, scheme fee, net amount, settlement batch id, and payout id — enough to reconcile from gross revenue to the bank deposit line.
Invoice reconciliation
The invoice reconciliation report (type invoices) matches every finalized invoice to the payments that settled it — including partial payments, overpayments, and credit note applications. Finance teams use it to close accounts receivable.
const run = await vinr.reports.create({
type: 'invoices',
interval: { start: '2026-05-01', end: '2026-05-31' },
columns: ['id', 'number', 'customer', 'amountDue', 'amountPaid', 'tax', 'status'],
format: 'csv',
});The payment_accounting variant of this report is formatted for direct import into common accounting systems (QuickBooks, Xero, NetSuite) — contact support to enable it for your account.
Operational reportsAsk
Operational reports cover specific transaction types and authentication events, useful for debugging, compliance, and product analytics.
3D Secure authentication report
The 3DS authentication report gives a per-transaction view of authentication outcomes — authentication result, ECI code, exemption type applied, and challenge outcome. Use it to measure your SCA challenge rate and tune the Authenticate module.
const run = await vinr.reports.create({
type: '3ds_authentication',
interval: { start: '2026-05-01', end: '2026-05-31' },
columns: ['paymentId', 'authResult', 'eci', 'exemption', 'challengeOutcome'],
format: 'csv',
});| Column | Values |
|---|---|
authResult | authenticated, not_authenticated, exempted, not_required |
exemption | low_value, low_risk, trusted_beneficiary, none |
challengeOutcome | passed, failed, abandoned, n/a |
The conversion report (type 3ds_conversion) aggregates by BIN and shows authentication-to-capture conversion rates — the key metric for identifying issuers that over-challenge.
Balance transfers report
Covers all internal transfers in a period: source account, destination account, amount, currency, status, and reason. Use it to audit platform fund flows or reconcile sub-merchant balances.
const run = await vinr.reports.create({
type: 'balance_transfers',
interval: { start: '2026-05-01', end: '2026-05-31' },
format: 'csv',
});Dynamic Currency Conversion report
If DCC is enabled, the DCC report shows each transaction where a conversion was offered, whether the cardholder accepted, the original and presented currencies, and the exchange rate applied. Required for scheme compliance reporting.
const run = await vinr.reports.create({
type: 'dcc_transactions',
interval: { start: '2026-05-01', end: '2026-05-31' },
format: 'csv',
});Received payment details
The received payments report covers all authorizations received in the window, including declined and voided transactions — not just captured payments. Useful for authorization rate analysis and debugging soft-decline patterns.
const run = await vinr.reports.create({
type: 'received_payments',
interval: { start: '2026-05-01', end: '2026-05-31' },
columns: ['id', 'created', 'authCode', 'status', 'failureCode', 'amount', 'currency'],
format: 'csv',
});Closing your fiscal periodAsk
At month-end, the recommended close sequence is:
Pull the account receivable position
The AR position dashboard (Dashboard → Finance → Month-end close) shows open invoices, pending settlements, and any balance adjustments that haven't cleared. Review before generating final reports.
Generate the balance transactions report
Run the balance_transactions report for the full month at transaction granularity. This is the ledger-of-record for the period.
Cross-check payout reconciliation
List all payouts that arrived in the period and verify each one's net total matches the sum of its associated balance transactions. Any gap indicates a pending transaction that crossed the period boundary — check pending balance transactions dated before the close.
Export and archive
Download the final CSV and the per-payout transaction lists. VINR retains reports for 7 years; you should also archive locally per your retention policy.
// List payouts that settled in May
const payouts = await vinr.payouts.list({
arrivalDate: { gte: '2026-05-01', lte: '2026-05-31' },
status: 'paid',
});
// For each payout, fetch its balance transaction breakdown
for (const payout of payouts.data) {
const txns = await vinr.balanceTransactions.list({ payout: payout.id });
const net = txns.data.reduce((s, t) => s + t.net, 0);
console.assert(net === payout.amount, `Mismatch on ${payout.id}`);
}Monthly finance summary
The monthly finance report (Dashboard → Finance → Monthly summary) is a pre-built PDF covering: gross volume, refunds, disputes, fees, net revenue, and a settlement-to-payout waterfall. It is generated automatically on the 3rd of each month and emailed to users with the Finance or Owner role.
Daily finance reports are also available — useful for businesses that close their books daily. Enable them under Dashboard → Settings → Reporting → Daily summary.
Next stepsAsk
Payouts & settlement
Match report rows to bank deposits.
Webhooks
React to report.completed events.
Operations overview
Alerts, monitoring, and run health.
Last updated on