FreshBooks and Adyen integration
FreshBooks keeps your invoices, clients, and books. Adyen moves the money. Connecting the two records what Adyen actually settles back against the matching FreshBooks invoice, so an invoice is marked paid the moment the payment clears instead of being reconciled by hand. Refunds and processing fees from Adyen settlement are written into FreshBooks too, so the books reflect the net cash received. ml-connector handles the very different APIs on each side and keeps invoice status in step with real payment activity on the cadence you set.
What moves between them
The flow runs from Adyen into FreshBooks. When Adyen captures a payment, ml-connector matches it to the FreshBooks invoice by the merchant reference Adyen carries and posts an invoice payment, which moves that invoice toward Paid. Adyen refunds are recorded against the same invoice or client, and processing fees and net settlement amounts taken from the reconciliation report are written into FreshBooks so the books match the cash that arrived. Capture, refund, and report-available webhooks drive the work as activity settles, and a scheduled poll backfills anything a webhook missed. Adyen is treated as a read-only accounting source, so ml-connector never writes payment instructions back into Adyen.
How ml-connector handles it
ml-connector stores both credential sets encrypted. On the FreshBooks side it runs the OAuth Authorization Code grant, refreshes the access token when a call returns 401, and rotates the stored refresh token on each refresh since FreshBooks invalidates the prior one. It resolves the accountId and businessId from the identity endpoint so it can build the correct account-scoped paths. On the Adyen side it sends the X-API-Key and uses the merchant live URL prefix on every live call. Adyen capture, refund, and report-available webhooks are HMAC-SHA256 verified before processing, and because Adyen can deliver the same notification more than once, the pspReference is used to dedupe so a payment is never recorded twice. Matching is done on Adyen merchantReference against the FreshBooks invoice number, which is why supplying your own invoice number keeps creates and payment posts idempotent given FreshBooks has no idempotency-key header. Fees and net amounts come from the reconciliation report rather than the raw authorisation, since the report is the canonical settlement record. FreshBooks invoices created by API start as Draft and are not in reports until marked Sent, so the connector only posts payments against sent invoices. Adyen rate limits and FreshBooks 429 short-burst throttling both trigger exponential backoff, and every record carries a full audit trail and can be replayed if a downstream call fails.
A real-world example
A twelve-person design studio bills retainer and project work through FreshBooks and takes card payment through Adyen on a hosted checkout. Before the integration, a bookkeeper exported the Adyen payments list every week and manually marked the matching FreshBooks invoices as paid, then reconciled processing fees by hand at month end, which meant invoices sat open for days and the cash in the books rarely matched the bank. With FreshBooks and Adyen connected, each Adyen capture marks its invoice paid within minutes, refunds reverse cleanly against the original invoice, and the weekly reconciliation report posts the net settlement and fees automatically. The owner sees a true paid-versus-outstanding picture and the manual matching step is gone.
What you can do
- Record Adyen captured payments against the matching FreshBooks invoice so it moves to Paid without manual entry.
- Match payments by Adyen merchant reference to the FreshBooks invoice number and dedupe on pspReference.
- Post Adyen refunds and processing fees from the reconciliation report into FreshBooks so the books show net cash.
- Bridge the Adyen API key and live URL prefix with FreshBooks OAuth token and refresh-token rotation.
- Run on Adyen capture, refund, and report webhooks with a scheduled poll backfill, retries, and a full audit trail.
Questions
- Which direction does data move between FreshBooks and Adyen?
- Data moves from Adyen into FreshBooks. Settled payments, refunds, and fees flow from Adyen and are recorded against the matching FreshBooks invoices and accounts. Adyen has no invoice or GL objects and is treated as a read-only accounting source, so ml-connector never writes payment instructions back into Adyen.
- How does ml-connector match an Adyen payment to a FreshBooks invoice?
- It matches on the merchant reference Adyen carries against the FreshBooks invoice number. Because FreshBooks has no idempotency-key header, supplying your own invoice number keeps the match reliable, and the Adyen pspReference is used to dedupe so a duplicated webhook never records the same payment twice.
- Why does the integration use Adyen reconciliation reports instead of just the payment webhooks?
- The webhooks tell ml-connector that a capture or refund happened, but the reconciliation report is Adyen's canonical record of net settlement and processing fees. ml-connector posts the invoice payment from the capture event and then uses the report-available webhook to write fees and net amounts, so the FreshBooks books reflect the actual cash received rather than the gross authorised amount.
Related integrations
More FreshBooks integrations
Other systems that connect to Adyen
Connect FreshBooks and Adyen
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started