A Stripe connector that cannot move money — and the scope argument that got it shipped
Stripe is the other side of every ROAS claim: an ad platform reports the conversion value it was paid to produce, and Stripe records the charge that actually succeeded. The connector reads charges, refunds and disputes per currency and ships no write tool at all. It is not connectable today, and the reason is worth publishing rather than hiding.
What was built
- Reads that settle the argument. Charges, refunds, disputes, balance transactions and payouts, with amounts converted out of Stripe's minor currency unit in the tool so a figure is never off by a factor of 100.
- No write MOVES MONEY, and that is the fence. A refund, a charge, a payout and a transfer are all absent from the tool family by construction. What the writes do reach is the catalogue — customers, products, prices, coupons, promotion codes and payment links — created inactive and switched on by a person.
- Connect OAuth rather than a pasted key. An
sk_livekey is a full-power credential that cannot be scoped down after the fact, and it travels through a form and a clipboard to get where it is going. Connect authorizes on Stripe's own domain and revokes from your own dashboard.
The scope Stripe will not grant
Stripe's OAuth reference carries one line saying the read_only scope can only be specified for extensions. We read that as a documentation inconsistency, requested read_only anyway, and shipped.
The first real authorization request settled it. Stripe answered with a raw error page: "Please use the read_write scope, or contact support in order to use read-only connections." Every Connect click, test or live, ended there with no way back into the product.
- Widening the scope was the decision, and it was not taken lightly. This entry originally said the opposite: that read_write would mean holding a credential able to issue refunds, so it would not be requested. rev808 requested it, by an explicit operator opt-in, after establishing that the fence belongs in the tool family rather than in the scope — no refund, charge, payout or transfer tool exists, whatever the credential permits.
- A status now sits ahead of the others.
scope_pendingholds before test, review and live. The integrations card says Waiting on Stripe with the reason; the authorization route refuses before building a redirect. - It clears by an operator switch, not by detection. Stripe enabling read-only connections for a platform is an account-level change with no API that reports it, so the gate is a declared flag rather than a probe.
Why it is worth the wait
Every ROAS figure in an ads dashboard is reported by the platform that was paid to produce it. Refunds land days or weeks after the click that earned the credit, and most platforms never subtract them. A conversion value passed back from a pixel is an estimate of a payment; a Stripe charge is the payment.
That is the comparison the connector exists to make — per currency, with refunds and disputes netted out — and it is the one number an ad platform structurally cannot give you about itself.
Update, later on 2026-09-24 (rev808): connected, with catalogue writes — still nothing that moves money
Stripe finished reviewing the platform, and the operator opted into the scope Stripe actually grants (STRIPE_CONNECT_SCOPE=read_write). The door above is open. What did not change is the rule the whole post is about: no call that moves money exists on any lane — charges, payment intents, refunds, payouts, transfers, subscriptions, invoices, disputes and account settings are refused everywhere, typed, raw or over MCP.
What did change: the family now manages the catalogue — customers, products, prices, coupons, promotion codes and payment links. Every create is inactive and tagged created_by=agent_planners; making one active, and every delete, waits for a person on every lane. Disconnecting revokes Agent Planners' access in Stripe once no workspace still uses the account.
Frequently asked questions
- Can I connect Stripe to Agent Planners today?
- Yes, since rev808 (later on 2026-09-24): the platform review passed and the connection requests the read_write scope Stripe grants, while the tools never move money. The original answer, kept for the record: Not yet. Stripe does not currently allow a normal Connect platform to request the read-only scope, and read-only is the only scope this connector asks for, so authorization is held rather than attempted. The Connect control is disabled with the reason shown rather than sending you to an error page.
- Why not just request the read_write scope?
- rev808 did, by an explicit operator opt-in after the review, and with the money rule intact: no refund, charge, payout, transfer or subscription call exists on any lane, and disconnect deauthorizes. The original reasoning: Because it would work. read_write is a credential that can issue refunds and move money on your account, and this connector exists so that is structurally impossible rather than merely disallowed. Widening the scope to make the button work would delete the reason for building it. It stays a product decision, not a workaround.
- Can the agent refund a payment or move money in Stripe?
- No. Since rev808 the family manages the catalogue (customers, products, prices, coupons, promotion codes, payment links — creates inactive, activation and deletes approved by a person), and still contains no money-moving call: no refund, charge, payout, transfer or subscription change exists on any lane. Before rev808 it had no write path at all, so there is no code that could issue a refund even with a wider credential. Two independent things would have to be wrong at once, and one of them does not exist.
- What does Stripe show that an ad platform cannot?
- The charge that actually succeeded, net of refunds and disputes, in the currency it settled in. An ad platform reports the conversion value it was paid to produce and books it at click time; refunds land weeks later and are usually never subtracted. Stripe is the other side of that claim.
- Why does Stripe refuse read-only connections?
- Its OAuth reference states that read_only can only be specified for extensions, and a live authorization request returns: "Please use the read_write scope, or contact support in order to use read-only connections." Enabling read-only for a platform appears to be an account-level change on Stripe's side.