Skip to content

Affiliate Payouts (Manual CSV)

The baseline PayoutStrategy for affiliate commission payouts, shipped with core. It does not move money: each payout run appends a row to a monthly CSV manifest, and the operator fulfils the transfers through their own bank or ACH tooling before marking payouts paid.

At a glance

Extension id payout_csv
Category payment
Version 0.1.0
Provides Payout strategy (csv_manual)
External account None

What It Provides

  • Registers CSVPayoutStrategy under the name csv_manual for the core PayoutStrategy interface at activation.
  • Consumed by the core affiliate payout sweep: the Temporal PayoutSweepWorkflow (schedule vectis-payout-sweep, runs daily) builds pending payouts for every affiliate over threshold and hands each one to the resolved payout strategy.
  • Default by convention: when no provider name is specified, the strategy resolver picks the last-registered PayoutStrategy, so installing a real payout rail extension overrides CSV without further configuration.
  • Manifest writing: appends one row per payout to <data_dir>/vectis_payouts/<YYYY-MM>/manifest.csv (the month comes from the payout period's end date); the header row is written when the file is first created.

CSV columns: payout_id, affiliate_id, affiliate_email, payout_method, payout_account_ref, gross_amount, fees, net_amount, currency, period_start, period_end, memo.

Setup

  1. Nothing is required for the default behavior — the extension's strategy is registered at boot.
  2. Optionally set the VECTIS_PAYOUT_CSV_DIR environment variable to choose where manifests are written; without it, files go under the OS temp directory.
  3. Review and process payouts from the admin — see the Affiliates usage guide for the payout lifecycle and CSV export flow.

Configuration Reference

Key Type Required Secret Description
data_dir string No No Filesystem directory for generated CSV manifests

Note

The strategy instance registered at boot is constructed without arguments, so its directory resolves from the VECTIS_PAYOUT_CSV_DIR environment variable, falling back to the OS temp directory.

Permissions

  • affiliate.manage_payouts

Manifest permissions are upserted at boot; assigning them to roles remains a manual step.

Operational Notes

  • initiate returns status="pending" with external_ref="csv:<manifest path>"; the sweep then records the payout row as processing with that reference. A failed manifest write returns failed with the error message, and the payout is marked failed.
  • check_status always reports pending — CSV payouts are fulfilled manually and flipped to paid by an operator action (PayoutService.mark_paid), not by polling.
  • Every payout written in the same month shares the same external_ref (the manifest path), so the provider status webhook (POST /webhooks/affiliate/payout-status), which resolves payouts by unique external reference, is not a usable fulfillment channel for CSV payouts.
  • Rows are buffered in memory and appended per payout rather than holding an open file handle. A code comment scopes this approach to expected volume (under ~10k rows/month); beyond that, move to a real payout provider via the PayoutStrategy interface — which is exactly what this plugin point exists for.

See Strategy Pattern for how payout strategies resolve, and Building Extensions for the contribution surfaces.