Stripe Make.com Integration: Building a Webhook Reconciliation Ledger
Affiliate Disclosure: We review products independently. When you buy through our links, we may earn a commission or a compound recurring commission at zero extra cost to you. Read our editorial policy.
Updated: July 23, 2026. All tool behavior verified against Stripe documentation and Make.com platform testing.
The Stripe Make.com integration for payment reconciliation solves a problem that grows invisibly. In the first month of a new agency or SaaS product, a founder manually reconciles Stripe payouts against bank deposits in a spreadsheet. In month six, with 40 active clients and a mix of one-time invoices, subscription renewals, refunds, and a disputed charge, that spreadsheet is already broken. Stripe’s payout to the bank account bundles dozens of individual transactions minus fees into a single deposit. Matching that deposit to the correct client invoices manually is 3 to 5 hours of finance work per month that compounds with every new client added.
The Stripe Make.com integration documented here replaces that manual process with a running ledger that captures every payment event the moment it fires, logs it to a structured data store, and flags any transaction that does not reconcile cleanly before the payout lands. The ledger stays current as events are processed and gives the finance team a structured record for reconciliation. Stripe also retries failed webhook deliveries, reducing the risk of missed events during temporary endpoint outages.
Why a Reconciliation Ledger Requires More Than One Webhook Event
Most Stripe Make.com integration guides cover invoice.payment_succeeded and stop there. A ledger that only captures successful payments is missing three event types that change the financial picture:
Refunds. A charge.refunded event fires when a client requests a refund on a paid invoice. If the ledger only captures invoice.payment_succeeded, the refund does not appear. The ledger shows revenue that was collected and subsequently returned. Month-end reconciliation against the bank account will not tie out.
Disputes. A charge.dispute.created event fires when a client initiates a chargeback. Stripe immediately withdraws the disputed amount from the agency’s balance and holds it pending dispute resolution. A ledger without dispute tracking shows a positive balance that does not match Stripe’s actual available balance during the dispute window.
Payout events. Stripe batches individual transactions into periodic payouts to the bank account. A payout.paid event is sent when the payout is expected to be available in the destination account. For automatic payouts, Stripe also provides payout.reconciliation_completed when the associated balance transactions are ready to query.
For the subscription-invoice workflow described in this guide, the core event set is invoice.payment_succeeded, charge.refunded, charge.dispute.created, and a payout event. These events cover the main payment, refund, dispute, and payout stages needed for the reconciliation flow built below. Depending on the payment methods and Stripe products you use, additional events may be required.
The Architecture: Two Scenarios, One Data Store
The reconciliation ledger runs on two Make.com scenarios and one Make.com Data Store. Separating the webhook receiver from the ledger processing logic is the same async pattern documented in the Make.com webhook timeout article. The separation prevents a slow ledger write from delaying Stripe’s webhook acknowledgment.
Data Store structure:
Create a Make.com Data Store named stripe_ledger with the following fields:
| Field | Type | Description |
|---|---|---|
event_id | Text | Stripe event ID (unique, prevents duplicate processing) |
event_type | Text | invoice.payment_succeeded, charge.refunded, etc. |
transaction_id | Text | Stripe charge or invoice ID |
customer_id | Text | Stripe customer ID |
customer_name | Text | From Stripe customer object |
amount | Number | In smallest currency unit (cents) |
currency | Text | ISO currency code |
status | Text | received, reconciled, disputed, refunded |
payout_id | Text | Populated when transaction is matched to a payout |
timestamp | Date | Event timestamp from Stripe |
processed | Boolean | False on receipt, true after ledger processing |
Scenario 1: Webhook Receiver
Trigger: Make.com custom webhook.
Action 1: Validate the Stripe webhook signature (covered in detail below).
Action 2: Write the raw event to the stripe_ledger Data Store with processed: false. Use the Stripe event.id as the unique key to prevent duplicate records if Stripe retransmits the event.
Action 3: Return 200 immediately. No enrichment. No processing. No downstream API calls.
The receiver scenario has one job: capture the event payload durably before acknowledging Stripe. tripe recommends returning a successful 2xx response quickly, before performing complex downstream processing. A receiver that also processes the event, queries external systems, and writes to Google Sheets increases the risk of a delayed or failed webhook response.
Scenario 2: Ledger Processor
Trigger: Schedule the scenario to run periodically and process unprocessed ledger records.
Action 1: Search the stripe_ledger Data Store for records where processed: false.
Action 2: For each unprocessed record, route by event_type:
Route A (invoice.payment_succeeded): Set status to received. Extract and log customer_name, amount, transaction_id. Write a new row to the reconciliation Google Sheet or Airtable base.
Route B (charge.refunded): Find the original transaction record in the Data Store by transaction_id. Update its status to refunded. Log the refund amount as a negative entry in the reconciliation sheet.
Route C (charge.dispute.created): Update the original transaction status to disputed. Post a Slack alert to the #finance-ops channel with the customer name, disputed amount, and Stripe dispute dashboard link.
Route D (payout.paid): Query Stripe’s Balance Transaction API to retrieve all transactions included in the payout. Match each transaction ID to existing ledger records and update their payout_id field. Flag any payout amount that does not match the sum of matched transactions as a reconciliation exception.
Action 3: Set processed: true on each record after processing completes.
Stripe Webhook Signature Verification in Make.com
Stripe signs every webhook payload with an HMAC-SHA256 signature using the webhook endpoint’s signing secret. Verifying this signature before processing any event is mandatory for a production Stripe Make.com integration. An unverified webhook endpoint accepts any POST request from any source, including malicious payloads designed to inject false transaction records into the ledger.
Step 1: Get the signing secret.
In the Stripe Dashboard, navigate to Developers then Webhooks. Select the webhook endpoint. The signing secret is displayed as whsec_.... Copy it and store it in Make.com’s Secrets Manager under the name stripe_webhook_secret.
Step 2: Extract the signature from the request header.
Stripe sends the signature in the Stripe-Signature HTTP header. The header value has this format:
t=1720000000,v1=abc123def456...,v0=legacy_signature_optional
The t value is the timestamp. The v1 value is the HMAC-SHA256 signature to verify.
Step 3: Build the signed payload string.
The signed payload is constructed as: timestamp + "." + raw_request_body. The timestamp is the t value from the Stripe-Signature header. The raw request body is the exact JSON string Stripe sent, with no parsing or reformatting applied.
Step 4: Compute and compare the signature.
Configure the Make custom webhook so that the original request body needed for signature verification is preserved rather than reconstructed from parsed JSON. Compute the HMAC-SHA256 signature from Stripe’s timestamp and that original payload using the endpoint signing secret, then compare the computed signature with the v1 signature in the Stripe-Signature header. If verification fails, do not process the event.
Do not parse the JSON and then serialize it again to recreate the signed payload. Stripe requires the exact request body it originally sent, and even changes to whitespace or formatting can cause signature verification to fail.
Step 5: Check the timestamp.
Stripe includes the timestamp to prevent replay attacks. Reject any webhook where the timestamp is more than 300 seconds (5 minutes) older than the current time. This prevents an attacker from replaying a captured valid webhook payload after the window has closed.
TSA SCAR: Stripe Signature Verification Requires the Original Request Body
Stripe webhook signature verification depends on the exact request body that Stripe sent. This matters when using Make.com Custom Webhooks because incoming JSON can be parsed into structured data before subsequent modules process it. Reconstructing JSON from that parsed data is not a reliable substitute for the original payload because changes in formatting, character encoding or field representation can invalidate the signature.
If you use a Make custom webhook for Stripe, configure and test the webhook specifically to preserve the payload required for signature verification before building the reconciliation workflow around it. Verify the Stripe-Signature header against that original payload and your Stripe endpoint signing secret before allowing the event into the ledger.
If reliable raw-payload verification cannot be guaranteed in your Make configuration, use a small verification endpoint outside Make that validates the Stripe signature first and forwards only verified events to Make. Do not treat secrecy of the Make webhook URL as authentication.
Payout Reconciliation: Matching Bank Deposits to Individual Transactions
The payout.paid event is the most complex part of the Stripe Make.com integration ledger. A Stripe payout batches multiple individual transactions into a single bank transfer, net of Stripe’s processing fees. The payout amount on the bank statement does not equal the sum of invoice amounts. It reflects the net balance activity included in the payout after applicable Stripe fees, refunds, disputes and other balance adjustments.
Querying the Balance Transaction API:
When payout.paid fires, the event payload includes data.object.id — the payout ID. Use this ID to query Stripe’s Balance Transaction API:
GET https://api.stripe.com/v1/balance_transactions?payout=po_abc123&limit=100
This returns the balance transactions associated with the payout, including the underlying payments, refunds, disputes, fees and other applicable balance activity.
Matching transactions to ledger records:
For each charge in the balance transaction list, find the corresponding record in the stripe_ledger Data Store by transaction_id. Update that record’s payout_id field with the current payout ID. This creates the explicit link between every individual invoice payment and the bank deposit it contributed to.
Reconciliation exception flagging:
Use Stripe’s balance transactions associated with the payout as the source of truth for the reconciliation total. For each balance transaction, capture its gross amount, fee and net amount, and link it to the corresponding ledger record where applicable.
Compare the combined net balance activity associated with the payout against the payout amount. If a transaction cannot be mapped to an expected ledger record, flag it as a reconciliation exception for review rather than assuming it represents a missing invoice payment.
Log exceptions in a separate stripe_exceptions Data Store record and include the payout ID, unmatched transaction or adjustment, amount and relevant Stripe identifiers for investigation.
The Reconciliation Output: Google Sheets Ledger
The processing scenario writes every event to a Google Sheets reconciliation ledger in real time. The sheet serves as the human-readable view of the Data Store’s transactional log.
Recommended sheet structure:
| Column | Value |
|---|---|
| Date | Event timestamp formatted as YYYY-MM-DD |
| Client Name | From Stripe customer object |
| Transaction ID | Stripe charge or invoice ID |
| Event Type | payment, refund, dispute |
| Amount (USD) | Positive for payments, negative for refunds and disputes |
| Stripe Fee | Calculated from balance transaction fee field |
| Net Amount | Amount minus Stripe fee |
| Payout ID | Populated when transaction matches a payout |
| Status | received, reconciled, disputed, refunded, exception |
A running SUM formula on the Net Amount column provides a useful view of the net transaction activity captured by the ledger. A COUNTIF on the Status column shows how many transactions are still in received status (not yet matched to a payout) versus reconciled (matched to a payout).
Handling Failed Payments and Dunning
The reconciliation ledger covers completed financial events. Failed payment attempts require a parallel tracking layer for dunning management.
Add a fifth event listener to Scenario 1: invoice.payment_failed. When this event fires, Scenario 2’s router writes a failed_payment record to the Data Store and triggers a separate Make.com scenario that handles the dunning sequence: an immediate Slack alert to the account manager, an automated payment retry notification email to the client via HubSpot or Gmail, and a ClickUp task assigned to the account manager for follow-up if the retry fails.
The failed payment record does not enter the reconciliation ledger as a financial transaction. It enters a separate failed_payments Data Store for dunning tracking only. If the retry succeeds, the resulting invoice.payment_succeeded event creates a normal ledger record. If Stripe exhausts the configured payment retry schedule without collecting the invoice, move the record to a write_off_review status for manual finance review.
Cost to Build and Run
The ongoing software cost depends primarily on the Make.com plan and the number of credits the scenarios consume.
| Component | Cost |
|---|---|
| Make.com Core, 10,000 credits/month, annual billing | $9/month ($108/year) |
| Make.com Data Store | Included with Make |
| Google Sheets | Included with an existing Google Workspace account |
| Stripe webhook delivery | No separate webhook fee |
| Base automation cost | From $108/year, excluding existing software subscriptions |
Make charges credits based on the modules that execute in a scenario. Most non-AI modules consume one credit per operation, while routers, filters and certain other built-in modules do not consume credits. Actual usage for this reconciliation workflow therefore depends on transaction volume, the number of modules executed for each event, payout processing, exception handling and how frequently scheduled scenarios run.
For an agency already using Google Workspace and Stripe, Make may be the only additional software subscription required for this workflow. Before choosing a Make credit tier, build the scenarios and monitor their actual credit consumption using your own transaction volume.
Make currently lists its entry-level paid Core plan at $9/month for 10,000 credits on annual billing. Make also confirms that most non-AI apps consume one credit per operation, while routers, filters and error handlers don’t consume credits.
Buy / Skip Decision Matrix
| Agency Situation | Recommendation |
|---|---|
| Low transaction volume with simple payouts | Consider manual reconciliation first. Automation becomes more useful when manual matching starts consuming meaningful finance time or exceptions become difficult to track. |
| Multi-currency Stripe account | Build the ledger. Currency differences and payout-level matching make a structured reconciliation process more valuable. |
| Subscription business with recurring payments, refunds or disputes | Build the ledger. The workflow provides a consistent record of payment and reconciliation events. |
| Using Make’s native Stripe modules | Use native modules where they cover the required workflow, but keep the reconciliation logic separated from downstream processing where practical. |
| High transaction volume | Monitor Make credit usage and processing time. Adjust the processing schedule or scenario design based on actual volume rather than a fixed invoice threshold. |
| Agency requiring GAAP/IFRS accounting records | Do not use this ledger as the accounting system. Use it as an operational reconciliation layer and route finalized financial data into the agency’s accounting platform. |
| Already using Stripe Sigma | Evaluate whether you need both. Sigma can handle detailed Stripe data analysis, while Make is useful when reconciliation results need to trigger alerts, CRM updates or other operational workflows. |
FAQ
Why use a Make.com Data Store instead of writing directly to Google Sheets from the webhook?
The Data Store separates webhook receipt from downstream processing. The receiver can record the event and return a successful response quickly, while a separate scenario handles reconciliation and Google Sheets updates. This reduces the risk that a slow external API or spreadsheet operation delays webhook handling.
How does this handle Stripe Smart Retries?
Stripe Smart Retries can automatically reattempt failed invoice payments according to the retry policy configured in Stripe. Use the invoice.payment_failed event to track payment failures and retry activity. When a later payment succeeds, the successful payment event can update the workflow and create the corresponding financial record. The number and timing of retries depend on the Stripe retry configuration.
What happens if Make.com is down when Stripe sends a webhook?
Stripe automatically retries failed webhook deliveries for up to three days with exponential backoff in live mode. If the Make webhook endpoint is temporarily unavailable, Stripe can therefore retry delivery after it becomes available again. For longer outages or unresolved delivery failures, use Stripe’s event history/API to identify and backfill events that were not processed.
Can I build this with Zapier instead of Make.com?
Yes. The same general architecture can be built with Zapier using webhooks, Zapier Tables or another data store, and separate workflow steps for reconciliation and downstream actions. Zapier Tables steps do not currently count toward task usage, while other successful workflow actions generally consume tasks according to Zapier’s task-usage rules.
The actual task requirement depends on the number of events processed and the steps executed for each event, so compare expected workflow usage against Zapier’s current task tiers rather than assuming a fixed monthly task count. Zapier Professional currently starts at $19.99/month with annual billing.
Zapier confirms Tables and several other built-in tools consume zero tasks, while standard automation steps generally consume one task.
How are Stripe fee deductions handled?
Use Stripe’s balance transaction data rather than calculating fees from a published processing rate. Each relevant balance transaction provides the actual fee and net amount associated with that transaction. Store those values in the reconciliation ledger and use the payout-associated balance transactions when reconciling the final payout amount.
Is the Stripe Make.com integration ledger a replacement for accounting software?
No. The ledger is an operational finance tool that provides real-time visibility into Stripe transaction flow, payout matching, and exception alerting. It is not a general ledger, does not handle accrual accounting, and does not replace QuickBooks, Xero, or similar accounting platforms for compliance reporting. Route confirmed reconciled transactions from the Data Store to your accounting software via its Make.com integration for bookkeeping records. The operational ledger and the accounting record serve different purposes and should run in parallel.
