Payment providers
Runledger never holds money. Your payment providers collect it, under your accounts in live and under Runledger’s in the sandbox, and Runledger decides which provider takes each payment, records it the same way for every provider, and reconciles it each day. An account can connect several providers, so a partner can take US dollars through one and Australian dollars through another without changing how it integrates.
Runledger works with Stripe, Adyen and Airwallex. The provider name in the API is an open string, so an integration doesn’t change when a provider is added.
Connect a provider
POST /v1/payment_providers starts a connection. What happens next depends on the environment:
- Sandbox. The connection is
connectedstraight away.stripehere is Runledger’s own Stripe sandbox, shared by every account, or a fake when the deployment has no Stripe key; it isn’t your Stripe account’s test mode. - Live. Connecting a provider in live isn’t open yet: the request answers
409withinvalid_state. When it opens, the response carries aconnect_sessionwith a hostedurl. A person opens it and signs in at the provider. Provider credentials never pass through the API, the MCP server or a chat with an agent.- First live provider. After it is connected at the provider, the connection waits in
awaiting_confirmationuntil an Admin confirms it in the dashboard. An Admin can confirm it only once the going-live review is approved, which needs a test payment through a provider in the sandbox. Until then it takes no payments. An agent can start the connection and can’t confirm it.
- First live provider. After it is connected at the provider, the connection waits in
Each connection lists its currencies, countries and capabilities. Capabilities are what Runledger can do through the provider: hosted_payment_page, saved_payment_method, reporting and dispute_signals. Runledger collects by card and provider payment links. One connection is the account default, shown as is_default, and the first one you connect starts as the default.
Remove a provider
DELETE /v1/payment_providers/{id} removes a connection and keeps its history. The connection stays retrievable with status: removed, so payments, reconciliations and disputes that name it still resolve. It takes no new payments.
The call returns 409 with invalid_state in five cases:
- It’s the only live provider. Connect another one first.
- It has open disputes. These are payments at that provider that a chargeback still holds in
disputed. Try again once they close. - It’s the account default. The message is “Choose another default provider first”. Make another provider the default with
PATCH /v1/payment_providers/{id}andis_default: true, then remove this one. Runledger never hands the default over by itself. - A routing rule uses it. The error lists the rules in
blocked_by, at most 50 of them, so remove what it lists and try again until the removal goes through. An Admin changes those rules to another provider, or deletes them, withPATCHorDELETE /v1/routing_rules/{id}, then removes the provider. - A customer’s own override names it. A customer with
payment_providerset to this provider is listed inblocked_bytoo, as{ "object": "customer", "id": "cus_..." }, in the same list as any blocking rules. Move each one to another provider withPATCH /v1/customers/{id}, or clear the override withnull, then remove the provider.
Here a routing rule and two customers are in the way:
Who can remove one. Only an Admin can remove a live provider. An agent key, and a Collaborator, is refused with 403 and permission_denied. In the sandbox, a key with providers:connect can remove one. The call accepts Runledger-Dry-Run: true, like other configuration changes, so you can check the outcome first.
Saved payment methods. Payment methods that customers saved at the removed provider are kept on record and marked unusable. Runledger doesn’t charge them, and the customer shows as needing a new payment method: payment_method_status on the customer is unusable, and so is the customer’s row in the dashboard. The customer saves a new method on a hosted page with another provider. Removal doesn’t wait for any of this, so it goes through while customers still hold methods at the provider.
Which provider takes a payment
For each checkout and each invoice collection, Runledger picks the provider in this order:
- The customer’s own
payment_provider, if set, or the provider that holds their saved payment method. - The first routing rule that matches. A rule has
whenconditions oncurrency,billing_country,planand checkoutmode, and aprovider. Rules are ordered, and the first match wins. Manage them withPOST /v1/routing_rulesand itsGET,PATCHandDELETEcalls, or in therouting_rulessection of a configuration document. - The account default.
POST /v1/payment_providers/resolve answers “which provider would this use?” for a customer, currency and plan, and says which step decided and which rule matched. It creates nothing.
checkout() also takes an optional payment_provider to force one for a session.
A customer stays with their provider
Once a customer saves a payment method, they stay with the provider that holds it. Editing routing rules changes where new customers and new checkout sessions go, and moves nobody who already saved a method. Runledger can’t use a card that another provider holds, so moving a customer means they save a card again on a hosted page. When a provider is removed, the methods saved there stay on record as unusable and the customer needs a new one.
The payment record
Providers name payments differently: Adyen identifies one by pspReference and your own merchantReference, Stripe by a payment intent. Every top-up and invoice payment therefore has a provider-neutral payment (GET /v1/payments) that holds the provider, the provider_reference, your merchant_reference, the kind (top_up or invoice), the amount, the status, and once it is paid out, the payout_reference and settled_at. A checkout session links to its payment, and a top-up payment links to the credit grant it created.
Reconciliation per provider
Runledger runs one reconciliation per provider per day, each with its own status and totals per currency. A break names the provider, and GET /v1/reconciliations?payment_provider= filters by it. reconciliation.breaks_found fires when one doesn’t match, and a notification rule can email the people who look into it.
Chargebacks on top-ups
A card chargeback on a top-up or an invoice payment is handled at your payment provider, not in Runledger. It is also different from an outcome dispute, which is about whether a charge for a result stands. Runledger keeps the two apart.
What Runledger does when a provider reports a chargeback:
- It sends
payment.disputed, with the provider’s reference and name, and marks the paymentdisputed. - It changes no credits. A top-up’s credits that were already spent stay spent.
- It reports the damage, so you can watch it.
GET /v1/reports/topup_chargebacksreturns, per provider or for the account, the number of top-ups, the number charged back, the rate (charged back over all top-ups in the range), the value in each currency, and the credits at risk: the unspent part of the grants those top-ups created. - It counts them with the other payments.
GET /v1/reports/paymentsshows payments that succeeded, failed and were disputed over time, with an optional split by provider. - It tells you when the numbers cross a line you draw. A notification rule with the event
topup_chargeback.threshold_exceededtakes athresholdon the rate, optionally a threshold on credits at risk, and optionally one provider. You set the threshold. There is no default, so no alert fires until you set one, and the right level depends on your own history.
A person can void the remaining credits of a charged-back top-up with POST /v1/credit_grants/{id}/void. Runledger doesn’t void credits, freeze the customer or block top-ups automatically.
Limits
- Collection methods. Runledger collects by card and by the payment links your provider hosts. It doesn’t support PayTo, BECS direct debit or other bank debits.
- Routing. Rules are ordered and the first match wins. There is no automatic failover between providers and no routing by cost or authorization rate.
- Saved cards. A customer stays with the provider that holds their payment method. Moving them means saving a card again on a hosted page.
- Chargebacks on top-ups. A chargeback is recorded as a
payment.disputedevent and flags the payment and customer, as described above. Runledger doesn’t claw credits back by itself. - Tax. Runledger doesn’t issue GST tax invoices or adjustment notes, send Peppol e-invoices or sync to Xero.
Next steps
- Configuration covers connecting providers and routing rules as configuration.
- Going live lists what to check for providers before real billing starts.