Report Payment Results (CSV)
Upload the outcomes of your debits so Rightfoot can match and act on them
Report Payment Results (CSV)
Upload a CSV of debit outcomes: which debits settled, which were returned, and why. Use it for debits Rightfoot cannot read from your payment processor itself, such as debits run from your LMS or through a processor you have not connected. Each row is matched to a borrower and recorded as if Rightfoot had read it from your payment processor. Results you upload show up in Retrieve Payment Results, and a return you report affects that borrower’s monitoring.Key Information
multipart/form-data, with the file in a part named filedryRun=true returns the full report and writes nothingCSV Format
One row per debit. Headers are case-insensitive, and spaces and punctuation are read as underscores, soPayment Date is the same column as payment_date.
The file must have an amount, status, date and return code column, plus at least one of authorizer_unique_id or reference. A cell can be blank when it does not apply. For example, return_code and returned_at are blank on a settled debit.
#N/A, N/A or - are read as blank.
Statuses
problems.
Return codes
On areturned or late_return row, return_code must be a NACHA R-code. R01, r01, R1 and R01 - Insufficient Funds are all read as R01. The text insufficient funds is also read as R01, and payment stopped as R08. A return with any other text, a blank cell or 0 is rejected: without the code, Rightfoot cannot tell whether the borrower may be debited again.
A settled row must not have a return code. On other statuses, a code is stored as you sent it.
Validation
Each row is checked on its own. A row that fails is rejected and every reason is listed inproblems. The rest of the file is still recorded, so fix the rejected rows and upload them again. A row is rejected when:
- a required value is missing or can’t be read: amount, status,
submitted_at, an identifier, or the outcome date and return code its status requires settled_atorreturned_atis earlier thansubmitted_at, or more than a day in the future- a
late_returnhas areturned_atearlier than itssettled_at - a
settledrow has areturn_code
What a reported return does
A return you report counts the same as one Rightfoot reads from your payment processor:R01andR09(insufficient or uncollected funds): the borrower stays eligible, and Rightfoot can retry the debit when there is enough in the account.- Any other return code stops monitoring for that borrower. NACHA does not allow a debit to be re-presented after these codes without corrective action, such as a new authorization or a different account.
Matching
A row with anauthorizer_unique_id is matched to that borrower. A row with only a reference is matched when the reference identifies the borrower, for example when it contains their authorizer_unique_id. If a reference does not clearly identify one borrower, Rightfoot leaves the row unmatched rather than guessing.
An unmatched row is still stored. It is counted in needsAttention and listed in problems as a warning. To match it, upload the row again with the authorizer_unique_id filled in.
Re-sending a file
Re-uploading is safe. Rows are keyed onreference, so the same debit is never recorded twice:
- A row whose status differs from the last one recorded for that
referencerecords the new status. A debit can therefore go fromsenttosettledtolate_returnover successive files. - A row identical to what is already recorded changes nothing. If Rightfoot recorded the status without a date, the row’s
settled_atorreturned_atfills it in. A date already recorded is never changed. - A row whose outcome date is earlier than the latest recorded outcome for its
referenceis ignored and listed as a warning, so an old export cannot overwrite newer results. A row with an undated status, such assent, never replaces a settled or returned outcome.
reference are counted once. If two rows for the same reference disagree, all rows for that reference are rejected.
Reading the report
A file that can be parsed always returns200. Check the report rather than the status code:
dataRowCountis the number of data rows found in the file.rowCountis how many of those were accepted, andmatchedandneedsAttentionsplit the accepted rows by whether a borrower was found.- Each entry in
problemshas aseverity. Anerrorrow was not recorded, andwarningmeans the row was recorded but something was ignored, or it is unmatched. A row can have severalerrorentries, one per issue. Arowof0is a problem with the file as a whole, such as missing columns.
400 is returned only when the file is rejected before any row is read: it is over 10 MB, or it is not UTF-8 text.Authorizations
Authentication to the API is performed via Bearer Token Authentication. Provide your API key as the bearer token in the Authorization header.
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
Query Parameters
Validate and match the file without writing anything.
Body
CSV of debit outcomes, one row per debit. See the column reference on this page.
Response
The file was processed. Check needsAttention and problems: a row can
be stored but unmatched, or skipped entirely.
How the file was read. annotated_export is a Rightfoot balance export
with your outcome columns added; anything else is generic.
generic, annotated_export Rows accepted for matching and recording.
Data rows found in the file, excluding blank and summary rows.
Accepted rows matched to a borrower.
Accepted rows Rightfoot could not match to a borrower. They are stored,
and re-uploading them with an authorizer_unique_id matches them.
Echoes the dryRun parameter. When true, nothing was written.
One entry per accepted row.
Everything that needs your attention. An error row was not recorded; a
warning row was recorded, but something was ignored or it is unmatched.
row is 0 for a problem with the file as a whole.
