Back to case studies

Nonprofit · Fundraising A US nonprofit educational institution

Recurring donation billing that knows when not to run

Salesforce / SOLA / Hebcal Hundreds of charges a day About six months in production

0

technical failures across 18,578 charge attempts, July to September 2026

55

consecutive days the process ran, with no missed day and no failure

How we tell these stories

We tell every case the same way: not just the challenge and the result, but how we designed the flow and solved it step by step. In automation, the "how" is what holds up in production. So it's the part worth reading.

The challenge

Before the process existed, collecting recurring donations was manual end to end.

Hundreds of donors a day, one card at a time, one amount at a time, against a payment terminal screen. This was not an hour of work: it ran for hours, sometimes across days, and every additional day pushed collection further away from the due date that had been set.

The real cost was not the time, it was the exposure. Each of those three points is a place where a donor can be charged twice, charged the wrong amount, or not charged at all. In an institution that lives on recurring giving, a billing error is not an operational glitch. It is a breach of donor trust.


The constraint that isn't technical

The institution does not carry out commercial transactions on Shabbat or on Jewish holidays. A manual process protects that on its own, because the person running it is not at the office. An automated process does not protect it on its own, which is why this was an explicit requirement from day one, ahead of every operational requirement.

How we thought about it

The approach

One daily scenario that pulls every payment now due from Salesforce, sends it to SOLA for processing, and writes the full result back to the record. The first action of every run is not a data operation: it is a single question put to the Hebrew calendar.

The idea behind the build was that automation inside a religious institution has to keep the same commandments as the people it serves. This was not a requirement bolted on at the end, and not a line item in acceptance testing. It is the first step in the scenario, ahead of every query and ahead of every data operation.

01 · Before anything is charged

Every payment is marked pending on the record before it goes out. A failure mid run cannot produce a double charge.

02 · After a decline

One decline is not the end of the road. The payment returns to a retry cycle with a ceiling that lives in configuration rather than in code, and can be changed without touching the scenario.

03 · When something is missing from the setup

A record with no matching merchant account is closed with an explicit error code, rather than being quietly skipped.

The sentence that captures the approach: a process that collects money instead of people has to be more conservative than they are, not faster.

How we built the logic

Inside the scenario

The institution collects recurring credit card donations against due dates set in advance in Salesforce. The scenario runs once a day at a fixed hour and handles everything that has come due. This is not a webhook: it is a full financial process, with a conditional gate at the entrance and a separate decision for every payment.

The three systems in the scenario

The gate and the routing

What happens to every payment

Payments do not run in sequence but in parallel, and every charge attempt takes the transaction id as its own execution name. Two months back, any single donation can be opened to see exactly what happened to it, when, and how many times.

The full Make scenario - two collection routes

Why this couldn't be built easily any other way

Simple trigger-action tools break here

A conditional gate that depends on an external service before the flow even begins, routing by day of week, a query that unifies two different sets of records, a separate decision for every record, and a retry ladder that holds state across days. Point-to-point automation handles one step. This is a process.

Custom code would lock every change behind a deployment

The retry ceiling, the list of merchant accounts and the campaign-to-account mapping all change in the real world. Here they sit as records in Salesforce, and the logic itself is edited in a visual builder. None of them needs a developer.

The religious rule would not have survived as a comment in code

The requirement that the process not run on Shabbat or holidays is not an addition, it is the first module. Make Enterprise allows a code block to be placed as a module inside the scenario, so the Hebrew calendar check is a single bubble that anyone opening the scenario can see, rather than logic buried in a side service.

With money, visibility is not a nicety

Every charge attempt is a separate execution named after the transaction id, with a full log of what was sent and what came back. When you are collecting from donors, being able to open a single case and show exactly what happened in it is part of the product, not a debugging tool.

The results

The process has been in production for about six months. The numbers here are the measurement window of the last two months, not the whole story.

Why Make Enterprise

Have an internal process like this?

A process that eats people's time but has no clear owner to build for it. That's exactly what Make Enterprise solves.