Stack guide

Python scripts for Stripe Connect reconciliation

Here is the complete reconciliation script most engineers write eventually — auto-pagination, proportional expectation, tolerance handling, zero-decimal awareness — followed by the maintenance reality that keeps such scripts honest: schema drift, rate limits, wall-clock costs, and the quarterly re-validation ritual that separates working tools from abandoned ones.

The script

Auto-pagination across charges with transfers, expanding what expands, computing expectations per refund event:

import stripe

ZERO_DECIMAL = {"JPY", "KRW", "VND", "CLP", "..."}  # full set in docs

def expected_reversal(charge, transfer):
    if charge.currency.upper() in ZERO_DECIMAL:
        pass  # minor units already
    ratio = min(charge.amount_refunded / charge.amount, 1)
    return round(transfer.amount * ratio)

def scan(days=90):
    shortfall = 0
    for charge in paginate(charges_list(since=days)):
        if not charge.get("transfer") or charge["amount_refunded"] == 0:
            continue
        t = stripe.Transfer.retrieve(charge["transfer"])
        owed = expected_reversal(charge, t) - (t.amount_reversed or 0)
        if owed > 2:
            shortfall += owed
            print(charge["id"], owed)
    print("total:", shortfall / 100)

Runtime honesty

Rate limits pace long scans; wall-clock time grows linearly with history. Ninety days on mid-volume platforms completes comfortably; multi-year backfills want chunked scheduling rather than heroic single runs.

Expiry date, stated plainly

Scripts rot via schema drift (new objects, renamed fields), new charge types escaping filters, and tolerance assumptions quietly breaking. Quarterly re-validation against known-good samples keeps the tool truthful; skipping it converts confidence into folklore.

Read-only key hygiene

Run against restricted read-only keys; rotate after audits complete. Script access should never exceed its ambition — reconciliation reads, never writes.

Common questions

Can this run against live keys?

Restricted read-only keys, yes — created for the purpose, rotated afterwards. Full platform secret keys belong nowhere near scripts.

Does this require a FeeGuard integration?

No — the page stands alone as stack guidance. FeeGuard observes your event stream externally rather than embedding in it.