Integrations. Stripe
Stripe integration that ties every payment back to the record it belongs to.
Stripe is very good at taking money and very quiet about what the money was for. A payment arrives. The job it belongs to, the invoice it settles, and the customer who still owes the rest all live in another system. Left alone, the two drift apart, and someone spends the start of every month matching the Stripe dashboard against a spreadsheet.
We connect Stripe to the system where your work is recorded, in whichever direction your process runs. Quotes become Stripe invoices, customers pay by card or bank debit inside a portal, subscriptions open and close service records, and payouts reconcile to the deposits in your bank feed. Stripe stays your payment processor. The integration makes everything around it agree.
What we connect
What gets connected between Stripe and your other systems?
The flows below are the ones we build most often. The scope for your integration names exactly which of them apply, in which direction, and which system wins when the two disagree.
- Customers created in Stripe the moment they're created in your CRM or portal, with the Stripe customer ID stored on your side, so every later charge lands on the right account.
- Invoices and payment links raised from a signed quote, a milestone, or an order, sent from Stripe under your branding, payable by card or ACH, and marked paid in your system the moment Stripe says so.
- Subscriptions and recurring billing, with plan changes, trials, and cancellations kept in step with the access or service the customer is paying for.
- Payments, refunds, and disputes recorded on the customer and the job as they happen, so nobody finds out about a chargeback by scrolling the Stripe dashboard.
- Payouts broken into the charges, refunds, and fees inside them, so the deposit in your bank matches a list of invoices and the processing fee is booked where your accountant wants it.
- The accounting handoff, with paid invoices, fees, and payouts passed to QuickBooks Online so the books close without an export.
How it works
How does a Stripe integration work?
Stripe's API creates customers, invoices, and payments. Its webhooks tell us the moment a payment succeeds, an invoice is paid, a subscription changes, or a payout lands. Nothing gets trusted until it's been verified against your signing secret. Stripe can also deliver the same event more than once, or out of order, so every handler is written to survive a repeat.
Every request we send to Stripe carries an idempotency key, which Stripe supports natively, so a retry after a timeout returns the original result and nobody gets charged or invoiced twice. Failed calls back off and try again. Events we couldn't process are kept with their payload and replayed once the cause is fixed. Stripe retries deliveries your endpoint doesn't acknowledge, and we log every attempt.
A reconciliation report lists Stripe payments with no matching record on your side, records marked paid with no Stripe payment behind them, and payouts that don't sum to the deposits you received. It runs on a schedule and goes to a person. All of it gets built in Stripe test mode with test cards and test bank accounts, and it moves to live keys only after you've walked the flows yourself.
The stakes
What does a bad Stripe integration cost you?
More than the build, because integrations fail without setting off an alarm. Nobody gets a message saying the numbers stopped agreeing. Somebody notices at month end, and then nobody trusts either system until it is proven again. The failures below are the ones worth designing against from the start.
- A payout lands in the bank and nothing ties it to the orders inside it. Stripe nets charges, refunds, and fees into one deposit, so without the balance transaction detail there's no way to say which invoices that number came from.
- A webhook arrives twice and the handler applies it twice. Stripe repeats events by design, so one paid-invoice event can credit an account, grant access, or release a fulfillment a second time. Nobody notices until a customer says something.
- ACH gets treated like a card. A bank debit stays open while it settles, so an integration that marks it paid on submission shows money you don't have yet. Call it failed and you send a dunning email to a customer who already paid.
The order of work
What happens, in what order, on a Stripe integration?
In this order, every time. The mapping comes before the code, and the reconciliation comes before we call it done. Nothing here is a date. The sequence is fixed, and the runway is set in your written scope once we have seen your actual data.
- 01
Agree what a payment means
First we settle what each Stripe object maps to on your side. Which record a customer belongs to, whether a quote becomes an invoice or a payment link, what a subscription grants, and which side wins when the two disagree. Refunds, partial refunds, and disputes each get a defined outcome, written down before anyone opens an editor.
- 02
Build in test mode
Everything is built against Stripe test mode with test cards, test bank accounts, and the specific numbers that force a decline, a dispute, or a failed ACH debit. Your restricted API key and webhook signing secret go straight into a secrets vault. Live keys don't get created until you've clicked through the flows yourself.
- 03
Make repeats harmless
Then the failure paths. Every webhook is checked against your signing secret and recorded by its event ID, so the second copy of an event gets ignored. Every request we send carries an idempotency key, which Stripe supports natively, so a retry after a timeout returns the original charge and the money is only taken once. Events we can't process are kept for replay.
- 04
Reconcile before go-live
Next the reconciliation pass, run in test mode and again on the first live payouts. It lists Stripe payments with no record behind them, records marked paid with no Stripe payment, and payouts whose balance transactions don't sum to the bank deposit. Fees are split out where your accountant wants them booked. That report is the sign-off.
- 05
Go live and watch it
Live keys go in, and the endpoint is watched from the first event. Stripe shows failed deliveries in the dashboard and retries them. We alert on those same failures from our side, plus a stalled queue, an expiring key, or a quiet day when there should have been traffic. Silence gets treated as a fault.
Limits
What we will not do
Cheaper to hear now than to discover halfway through. If one of these is what you are actually after, we will say so on the first call rather than take the work.
- We won't take a live secret key pasted into a chat message. If one has already been sent that way, we'll ask you to roll it in the Stripe dashboard before we touch anything. A key that has landed in an inbox is already spent.
- We won't build card fields into your own forms when Stripe's hosted pages or payment elements will do. Handling raw card numbers on your servers pulls your whole system into PCI scope, and that's a compliance burden you didn't ask for.
- We won't have the integration issue a refund, cancel a subscription, or close a dispute on its own. Those actions move money or end a relationship. The integration prepares them and a person confirms, in Stripe or in your system.
Questions
What people ask about Stripe integrations
Can customers pay by ACH as well as by card?
Yes. Stripe supports ACH debits from US bank accounts alongside cards. Bank debits take several business days to settle, and the invoice stays open in Stripe until the funds clear, so the integration shows that payment as pending until it really is paid. Card payments confirm immediately.
Do you support subscriptions and usage-based billing?
Yes. Stripe Billing handles subscriptions, trials, proration on plan changes, and usage-based pricing. The integration maps each of those events to whatever it means in your system, whether that's access granted, a service record opened or closed, or a usage figure reported to Stripe out of your own data.
How do payouts get reconciled?
Stripe records every payout as a set of balance transactions, the charges, refunds, and fees that make it up. We pull that list for each payout and tie every charge back to the invoice and customer on your side. What comes out is a report where the payout total equals the bank deposit and the fees sit on their own line for accounting.
Do you build the checkout screens or use Stripe's hosted pages?
Usually Stripe's hosted invoice page, Checkout, or Payment Links. Stripe handles the card data and the compliance that comes with it, and card numbers never touch your servers. Where the flow calls for paying inside your own portal, we embed Stripe's payment elements, which keep that boundary where it is.
Do you need access to our Stripe account?
No login, no password. Only a restricted API key that you create, limited to the permissions the integration needs, plus the signing secret for the webhook endpoint. Both live in a secrets vault in your infrastructure. The account, the balance, and the payouts stay yours, and you can revoke the key from your Stripe dashboard whenever you want.
How do you handle refunds and partial refunds?
A refund is recorded against the original payment and the record it belongs to, at the amount that was returned. Stripe supports partial refunds, so an invoice can be part paid and part returned, and the integration keeps both of those as facts instead of flipping one status. Fees follow Stripe's own rules. The processing fee on a refunded card payment generally doesn't come back, so the reconciliation report shows it on its own line and your revenue and your bank balance don't quietly drift apart. The integration doesn't issue refunds. A person does.
What happens if the sync fails overnight?
Nothing is lost, and somebody is told. Stripe keeps retrying a webhook your endpoint doesn't acknowledge, so events raised while a server is down arrive once it's back. Anything that fails for another reason, a bad mapping or a record that no longer exists, is stored with its full payload in a queue for replay. A separate monitor watches for the absence of traffic. An error at three in the morning is easy to catch. The dangerous one is the sync that stops sending anything and looks calm from the outside.
Does this lock us into you, or into Stripe?
Neither. The Stripe account is yours, opened in your name, with the balance and the payouts under your control, and we work through a restricted key you create and can revoke. The integration code lives in your repository, and any developer can read it. Moving to a different processor later means rewriting the part that talks to Stripe, and that's real work. But the customer records, invoices, and payment history stay in your own system where you can get at them. That's the point of keeping your side as the record.
Related
Where this fits
An integration is rarely the whole job. Usually it is one part of a CRM, an operations system, or a client portal that needs Stripe to agree with it.
Tell us which two systems disagree
Book a strategy call, or send a short note about what gets retyped today and where the numbers stop matching.
