GnothiGnothi
SeriesFieldsCommunityPublishing
Sign inGet started free

8. The First Paid Trial

Summary

Taking the first payment

The chapter's customer is invented: the heating engineer from the interview record, with made-up money, dates and enquiries. A pretend payment says nothing about real demand. It is used to show how the process works. The chapter only goes ahead because the owner made a written, dated change to the commitment rule after the answers were in. Without that change the digest is parked.

Before sending the $135 two-week trial request, the owner checks three things personally: the recipient, the amount, and the bank account the payouts go to. The engineer pays. Stripe shows the payment as Succeeded, with a gross of $135, a fee of about $4.22 and a net of about $130.78 for a domestic card. Claude Code adds the first row to the payments record. It confirms that gross minus fee equals net and leaves the payout cell blank. The chapter explains Stripe's chain of identifiers: payment intent, charge, balance transaction, payout. Onboarding uses a Google Drive folder the customer shares as Viewer. It is reached through the existing read-only MCP server, using a test account rather than a personal one. Digests go to a delivery folder in the project and are reviewed before they are sent.

A gate before the model runs

A script handles the steps that have one right answer: whether the folder can be read, how many files arrived that day, and whether the run is late. It runs as a UserPromptSubmit hook, because a hook that runs at session start cannot block the session. The script's exit code controls the outcome, as described in the Claude Code hooks reference. Exit 0 lets the run go ahead. Exit 2 stops it with a stated reason. If the run is late it still goes ahead, with a note that the late-day credit applies.

The run's permissions are settled in advance and limited to Drive list and read plus writes to the delivery folder. The chapter separates three things: the model, Claude Code acting as the agent runtime, and the system of record, which is the payments file and a new customer file. The first invented Monday brings seven files and the digest passes all five criteria.

Tracing the cash

A new Stripe account holds its first payout for about one to two weeks. After that, card funds usually become available in two business days, as the payout schedules FAQ describes. The bank deposit shows only a lump sum. The itemized payout reconciliation report links each payout to its transactions, so Claude Code can fill in the payout identifier. Any mismatch is brought to the owner along with the evidence.

Cash received is kept separate from what has been earned: each of the ten digests earns a tenth of the fee. Three things remain open:

  • Desktop tasks skip their run when the laptop is asleep. Cloud scheduled tasks avoid this.
  • A failed run doesn't alert anyone.
  • The trial's end date is coming, and the owner needs to decide what to offer before it arrives.

This chapter covers the moment an offer stops being prepared and becomes a promise someone has paid for. Everything about the customer here is illustrative. The owner who pays is the invented heating engineer from the interview record, and the money, the dates and the enquiries are made up to show the work. An invented payment proves nothing about whether real trade owners want the digest. What it can show is the machinery: how a payment gets traced into the books, how the digest gets pointed at a customer's real enquiries, and how every fact ends up in a record instead of in a chat.

One condition comes first. Going ahead at all depends on the owner's written, dated change to the commitment rule, recorded as a change made after the answers were in. If you choose not to make that change, the digest is parked and this chapter is a rehearsal. Here it goes ahead.

Sending the request and opening the trial

Last time, the Stripe payment request was left prepared and unsent. It is a one-time request for a hundred and thirty-five dollars, labeled "two-week trial", and it collects the customer's email. Before it goes anywhere, you do three checks yourself. These checks stay with you because each one is about money moving, and a mistake there cannot be taken back by editing a file.

First, the recipient. Is this request going to the heating engineer, at the email address they gave you, and not to someone else in your contacts? Second, the amount. Does the request say a hundred and thirty-five dollars, the price written into the scope file and the agreement, and not two hundred and seventy, or thirteen fifty from a slipped decimal? Third, the destination. When Stripe pays out, where does the money go? In the Stripe dashboard, the payout settings show the bank account Stripe sends your money to. It should be the business account you set up, with the last few digits you expect. If any of the three is wrong, you fix it before sending. If all three are right, you send the link along with the agreement.

In this invented run, the heating engineer opens the link the same afternoon and pays by card. In the Stripe dashboard, under Payments, a new line appears. It shows a status of Succeeded, the customer's email, and a breakdown into three figures. The gross amount is what the customer paid: a hundred and thirty-five dollars. The Stripe fee is what Stripe keeps for processing. The net amount is what is left for you.

You already worked out what to expect. Say the card is a standard domestic United States card. Stripe's standard fee is two point nine percent plus thirty cents. Two point nine percent of a hundred and thirty-five is a little under four dollars, about three ninety-two. Add the thirty cents and the fee is about four twenty-two. Take that from a hundred and thirty-five and the net is about a hundred and thirty dollars and seventy-eight cents. If the dashboard shows those figures, the card was domestic and the fee came out as planned. If the fee is larger, the card was probably international, which adds one and a half percent, plus another one percent if the currency had to be converted. Either way the dashboard figure is the true one, and your earlier sum was only a prediction.

Now the payments record gets its first row. This is the file in your project folder with columns for date, customer, related agreement, gross, fee, net, transaction identifier and payout identifier. Until today it had headings and nothing under them. You don't type the row in yourself. You open Claude Code in the project folder, paste the details from the Stripe payment page, and ask it to add one row to the payments record using only what you pasted.

Two of those columns need explaining, because they are what will let you trace this money later. Stripe gives each object in a payment its own identifier, a short code that starts with a few letters telling you what kind of thing it is. When someone pays through a payment link, Stripe creates a payment intent, whose identifier starts with p-i. That intent produces a charge, starting with c-h, which is the actual debit from the customer's card. The charge then posts an entry in your Stripe balance. That entry is called a balance transaction, and its identifier starts with t-x-n. The balance transaction is where Stripe records the gross, the fee and the net together, and it points back to the charge it came from. Later, Stripe groups balance transactions into a payout, starting with p-o, which is the transfer to your bank.

So the row you write today has a date, the customer as "heating engineer, illustrative trial", the agreement it relates to, a gross of a hundred and thirty-five, a fee of four twenty-two, a net of a hundred and thirty point seven eight, and the balance transaction identifier starting with t-x-n. The payout identifier column stays empty. No payout exists yet. Leaving the cell blank is the honest entry, because it says the money is in Stripe and not yet in your bank.

Ask Claude Code to check one thing before it saves: does gross minus fee equal net? A hundred and thirty-five minus four twenty-two is a hundred and thirty point seven eight. If the pasted figures didn't add up, that would mean a copying mistake, and you would want to know now, not at the end of the month.

The money is in. Now the promise starts.

The agreement gives the customer one duty, and the digest cannot work without it. They route their enquiries, meaning voicemail transcripts, website form messages and emails, into one shared Google Drive folder. Onboarding means making that happen and pointing your run at it. In this invented trial, the heating engineer creates a folder in their own Drive and shares it with your business's Google account as a Viewer. Viewer means that account can open and list what is in the folder but cannot change it. How they get their voicemail transcripts and form messages into it is their side of the arrangement. Your job is to check that files actually arrive.

You already have most of what you need. Two chapters ago you registered a Google Drive server in Claude Code using the Model Context Protocol, the standard Claude Code uses to talk to outside services. You registered it with the claude mcp add command, signed in as a test Google account, with Drive's read-only permission and Viewer access on one test folder. That server offers only two tools, list and read. A test listing matched the folder exactly, and a request to rename a file could not be carried out.

For the trial, the same arrangement extends to the customer's folder. The account your server signs in as is the one the customer shared their folder with. Do not use your personal Google account, because a mistake there would reach your own files. The scope stays read-only. Before anything is scheduled, you run the same smallest test as before: ask Claude Code to list the files in the customer's folder, then open Drive in your browser and compare. Same file names, same count? Then ask it to read one file and check the words against what Drive shows. If both match, the connection reaches the right folder with the right limits.

Then the scheduled task changes. Until now, the Digest Prototype task ran each weekday evening over a folder on your laptop full of invented days. Now its instructions name the customer's Drive folder as the source, to be reached through the Drive server's list and read tools. The laptop folder of invented data stays where it is, untouched, as your test bench.

There is one thing to settle about where the digest goes. The Drive server can only read, and that limit is enforced, so the run cannot write the digest into the customer's folder. For this trial the digest is written into a delivery folder for this customer inside your project, which you review each day, as the scope already requires, before it goes to them. Giving the run write access to the customer's Drive would be a separate decision with its own risks. Nothing about this trial needs it yet.

A script that checks the run before the model writes

There is a weak spot in the scheduled task as it stands. When it runs, the model does everything, including things that are not really judgment. It works out whether the folder could be reached. It decides which files belong to today. It counts them. It notices, or doesn't, whether it is running too late. Each of those has one right answer that ordinary code can get every time. Asking a language model to do them means asking it for a careful guess at something you could simply measure.

Counting shows the difference clearly. The first acceptance criterion says the number of enquiries listed must match the number of files, and the count line has to state both. If the model does the counting and writes the count line, then the model is checking its own work. If it misses a file, it can also miscount the files and report a perfect match. A count made by a separate piece of code, before the model starts, is a second witness the model cannot influence. That is why the counting and the time check belong in a script. The model's job is reading messy voicemail transcripts and writing a clear page, the part with no single right answer.

Claude Code has a feature for exactly this, called hooks. A hook is a command that Claude Code runs automatically at a set point in a session. You list it in the project's settings file, the one in the hidden claude folder inside your project. Several hook points exist, and choosing the right one matters. The useful one here is called UserPromptSubmit. It runs the moment a prompt is submitted, which in a scheduled task is the moment the run's instructions are handed in, before the model has done any work. The obvious-sounding choice, a hook that runs when a session starts, would be wrong. Claude Code does not let a session-start hook block the session, so a failed check there would be reported while the run carried on anyway.

A hook tells Claude Code what to do through its exit code, a number every program hands back when it finishes. An exit code of zero means the check passed and the run goes ahead. An exit code of two means stop. Claude Code blocks the prompt, and whatever message the script printed to its error output becomes the stated reason. That is a limit the surrounding software enforces, not an instruction the model is asked to follow. You met that difference earlier in the course, and here it decides the design. If the folder cannot be read, you don't want a model that has been told "please stop if the folder is missing". You want a run that cannot start.

The script itself is short. It does three things in order.

First, it checks that the customer's folder can be read. The model reaches Drive through the Drive server, but the script cannot borrow the model's tools. It asks Google Drive directly for a listing of that one folder, using the same read-only test account. If the request fails, because the share was removed, the sign-in expired or Google is down, the script writes a note into today's delivery folder. The note says the run stopped, the time, and that the customer folder could not be read. Then it exits with two. Tomorrow morning you find a clear explanation instead of an empty folder, or worse, a digest that says nothing came in today.

Second, it counts today's files: those that arrived since the last weekday run. It writes that number into a small file in today's delivery folder. The task's instructions then tell the model to read that number and put it in the count line beside its own count. Now the first criterion compares two counts from two sources.

Third, it checks the clock against the seven o'clock deadline in the customer's local time. Suppose the run starts late, perhaps because the laptop woke up after the scheduled moment. A late digest is still useful to the customer, so the script does not stop the run. It writes a line in the note saying the run began after the deadline and that the late-digest credit in the agreement applies to that day. Then it exits with zero. Stopping is kept for the case where there is nothing reliable to write from.

Notice what the script does not do. It doesn't read the enquiries, judge them or write anything the customer sees. It is a gate and a measuring tape. Each part has one right answer, and you can test it by pointing it at your invented laptop folder: a folder that is missing, a day with nine files, a run started at a quarter past seven.

One more setting matters for unattended work. During a normal session, Claude Code asks you before using a tool. A scheduled run has nobody to ask, so a run that hits an approval prompt simply stalls. Its tool permissions have to be settled in advance. Here you pre-approve only what the job needs: the Drive server's list and read tools, and writing files in this customer's delivery folder. You don't open everything up. The run can do its job and nothing else, and an unexpected request fails visibly instead of quietly succeeding.

With this in place, you can name the pieces of the operation precisely. They are easy to blur together.

The model is Claude, the trained system that takes in text and writes text. On each run it receives the task's instructions, the evidence-checked-drafting skill, the script's count and the contents of the files it reads. From those it writes the digest and its claim-check list. It keeps nothing between runs. Tomorrow's model knows nothing about today's run except what is put in front of it again.

Claude Code is the application around the model, and here it also acts as the agent runtime. That means it is the software that actually carries out the work. It starts the run on schedule. It loads the instructions and the skill. It connects to the Drive server and passes the model's tool requests through to it. It runs the hook and obeys its exit code. It enforces the pre-approved permissions and writes the files. The model decides what to ask for. Claude Code decides whether that request is allowed and makes it happen.

The third piece is the business system of record: the files that hold the facts of the business, whatever happens to any chat or run. Right now there are two. The payments record says what was paid, when, with which identifiers. Next to it you add a customer record, a small file with one row per customer. This one holds the owner, as the invented heating engineer; the trial start date and the trial end date, two weeks later; the shared folder; and the agreement it falls under. As the trial runs, it also gains a running tally of digests delivered and any late-day credits. If you closed every chat today and opened Claude Code fresh next month, these two files would still tell you who is a customer, what they paid and what you owe them. That is the test of whether something belongs in the system of record. If you would need it after the conversation is gone, it goes in a file.

Then the first trial day runs. Say seven files arrive in the customer's folder during an invented Monday. At the scheduled time the hook runs. The folder reads. The script counts seven, notes the time as comfortably before seven, and exits with zero. The model writes the page, and you check it against the five criteria one at a time.

The count line says seven listed, seven files, and the seven files are the script's count, not the model's. Every enquiry is marked for contact details. One form message gives a name and a street but no number and no email, so it sits first, under unanswered, marked unreachable. Each name, number, time and detail in the digest appears word for word in a file named in the claim-check list. You spot-check two against Drive. Where a voicemail gives no address, the digest says "not reported" and does not guess. And the file's timestamp in the delivery folder is before seven. Five out of five. You review it, it goes to the customer, and the customer record now shows one digest delivered.

Following the money into the bank

The payments row from the day the trial was paid still has an empty payout cell. The money has not reached your bank yet, and it is worth understanding why before you go looking for it.

When the charge succeeded, Stripe recorded the balance transaction with a date on which the funds become available. Until then they are pending: Stripe holds them and you cannot pay them out. For standard United States card payments on an established account, funds become available two business days after the charge, so a Monday payment matures on Wednesday and a weekend pushes it later. A brand-new account is different. Stripe holds the first payout for roughly one to two weeks while it reviews the new business. After that it moves to the normal schedule. Payouts are daily and automatic by default, and you can change them to weekly or monthly. Since this is your first payment, expect to wait the longer period. A week without the money in your bank is not, on its own, a sign that something is wrong.

When the payout comes, look in three places, in this order. In the Stripe dashboard, under Balances, the Payouts view shows a new payout with an identifier starting with p-o, an amount, the bank account it went to, and a status. The status moves from pending to in transit to paid, with an expected arrival date. In the balance activity view, the original balance transaction now carries that payout's identifier. That link is what ties the customer's payment to that transfer. And on your bank statement, a few days into the process, a deposit appears with a description along the lines of "Stripe payout".

The bank line will not mention the heating engineer, the trial or a hundred and thirty-five dollars. Banks show one lump sum per payout, and a payout is the net total of everything it grouped together. Here that is one payment, so the deposit should be a hundred and thirty dollars and seventy-eight cents. Once you have several customers, one deposit could cover five payments, and no single figure on the bank statement would match any single customer.

That is the problem the identifiers solve, and matching works the same way at one payment or fifty. In the Stripe dashboard, under Reports, the payout reconciliation report lists each payout and the transactions inside it. As a summary, it gives each payout's net total and the date it should hit your bank. As an itemized download, a spreadsheet file with one row per transaction, it gives the charge identifier, the payment intent identifier, the gross, the fee, the net, and a category saying whether the row is a charge, a refund or something else.

You hand that download and your bank statement line to Claude Code and ask it to do three things. Find the payout whose net total and date match the bank deposit. Confirm that the transactions inside that payout include the one in your payments row. Then fill in the payout identifier on that row, change nothing else, and report what matched. In this invented case the answer is short. One payout, one transaction, a net of a hundred and thirty point seven eight. The deposit matches it to the cent and arrived on the expected date. The payments row now has both identifiers, and the money can be followed from the customer's card to your bank account without a gap.

Suppose the deposit did not match, say it was a dollar fifty short, or arrived without a payout you could pair it with. That is an exception, and it comes to you with the evidence: the bank line, the payout, the transactions and the difference. Don't let it be quietly smoothed over. If a transfer goes missing altogether, the itemized report also carries a trace number for the bank transfer, which your bank can use to find it. Most of the time nothing is wrong. The check exists because the one month it is wrong, you want to find out from a record and not from an empty account.

There is one more idea to hold onto from this payment, and it is about what the money means rather than where it went.

You have a hundred and thirty-five dollars of the customer's money, less the fee. You have not done a hundred and thirty-five dollars of work. The trial is two weeks of weekday digests, which is ten digests. On the day the payment arrived, you had delivered none of them. The cash came first and the work comes after.

So two numbers go in separate places. Cash received is what landed: the hundred and thirty-five, now traced to your bank as a hundred and thirty point seven eight after the fee. What you have earned is the part of the promise you have kept. After the first digest, that is one tenth of the trial, about thirteen dollars fifty. After five digests it is half. Only after the tenth digest have you earned the full hundred and thirty-five. Until then, the rest is money held against work you still owe.

This is why the customer record keeps a tally of digests delivered and credits applied. That tally lets you say at any moment how much of the cash you have actually earned. The payments record tells you what came in. The customer record tells you how much of it is yours yet. A business can feel flush with cash it has not earned. Keeping the two apart is how you avoid spending the refund you might owe.

The first paid trial is running, with a paper trail from the customer's card to your bank and a daily run that checks itself before it writes. Three things are still open, and each one is a risk to the promise you just took money for.

The run still needs the laptop awake. A desktop scheduled task only fires while the computer is on and the Claude Code desktop app is running. If the laptop is asleep at the scheduled time, that run is skipped and does not catch up when the machine wakes. The desktop app has a setting to keep the computer awake, but closing the lid puts it to sleep regardless. Anthropic offers cloud scheduled tasks that run on its own machines for exactly this case.

A failed run alerts no one. The hook writes a clear note when the folder cannot be read, but the note sits in a folder until you open it. If you are on a job all day, the customer's evening passes without a digest and you learn about it the next morning.

And the trial has an end date, two weeks from its start, written in the customer record. The agreement does not renew by itself. Before that date arrives, you need to decide what to offer: the monthly digest at two hundred and seventy dollars, a different arrangement, or a clean stop. You also need to work out what the customer will receive from you on that last day. That decision is the start of the next stretch: keeping a paying customer through every handoff that follows the first one.