24 October 2026 · 5 min read · BlitzHash Team · SaaS & Product Engineering
Own the repo, the environments, and the billing when a product takes payment
The risky moment for a young product is not the first demo. It is the week the product starts taking payment and the only person who can deploy is a contractor using a personal login. Customers can pay. You cannot rotate a key, refund with a clear record, or hand the system to the next engineer without a scavenger hunt.
SaaS and product engineering engagements start from the opposite arrangement. The repository, the environments, and the vendor accounts are yours. This is the shape we leave behind when a product charges money.
The repository belongs to the company
Code should sit in an organization the company owns, not in a personal account that disappears when someone changes jobs. Invite the people who need access. Use pull requests so a change is visible before it is deployed. Protect the default branch enough that a Friday experiment does not go straight to customers.
The README, or a short runbook next to it, should answer how to run the app locally, which commands deploy, and where secrets live. Secrets do not belong in the repository. A .env file that was committed once is still in history. If that happened, rotate the keys. Do not only delete the file.
Dependencies and framework choices should be ones a later team can hire for. We default to ordinary tools, documented in the stack: Next.js, React, Node.js, PostgreSQL, and Supabase when that is the backend. Unusual glue needs a comment that says why it exists.
You should be able to remove our access in an afternoon and keep shipping. If the build only works on one laptop, the product is not yours yet.
Separate environments on purpose
Give the product at least two places to run, and preferably three. Local or development, a preview or staging environment, and production. Each one has its own database, its own auth URLs, and its own secrets. Production data does not get copied into a laptop database so someone can "just look." If you need realistic data, take a scrubbed sample on purpose and write down what you removed.
Preview deploys are for pull requests. They are not a second production with the live payment keys. Label them. A customer should never land on a preview hostname from a marketing email.
The hosting project should be in the company account as well. Domain names, DNS, and TLS follow the same rule. An owner can be the billing admin. A shared inbox should also be an owner, so a single lost phone is not an outage.
Write the promote path. What merges to the default branch, what runs in CI, and what still needs a person to approve. If there is no CI yet, say so, and start with the checks that catch a broken build. A green badge that runs nothing is worse than no badge, because people trust it.
Billing lives in your payment account
When the product takes payment, the payment account should be the company's. The integration we usually build is Stripe: Checkout or Billing, a customer record in your database, and webhooks your server verifies. Stripe is the payment product inside the app. It is not how you pay BlitzHash. Our invoices are a separate agreement, described in how we work.
A safe integration has a few habits. Test keys in non-production. Live keys only on the server that should charge cards. Webhook signatures checked, and unsigned bodies rejected. Handlers that can see the same event twice and still record one order. A way to refund that matches the ledger your support team will actually open. Customer emails that show the product name, not a placeholder from the tutorial.
Place one real purchase yourself before you invite customers. Use a card you control. Confirm the row in your database, the event in the payment dashboard, and the receipt. Then refund it. That single loop teaches you more than a diagram.
Tax, invoicing details, and which cards you accept are business decisions. The engineering scope should name what it will and will not configure. A webhook that updates a subscription status is in scope when we say so. Filing taxes is not an engineering task.
Access when something goes wrong
List the accounts and who holds them. Repository, host, database, payment dashboard, error tracking, email, and DNS. For each one, two people should be able to get in, or one person plus a break-glass owner on a shared company login. Store recovery codes somewhere that is not the same password manager entry as the daily password, if you can.
Error tracking, often Sentry for these products, should report to an inbox the company reads. Alerts that only reach a contractor's personal address fail the week that person is away. The same is true of uptime checks and certificate expiry.
Decide what support is allowed to do. View a customer, resend a receipt, and cancel a subscription are different powers. Put the dangerous ones behind an admin role, and keep the service-role key off the admin's browser. An internal screen that uses the public API with the admin's own session is easier to reason about than a page that sends the secret key to the client.
What the handover contains
Before we call the launch done, you should have the repository, the environment list, the secret locations, the deploy steps, the rollback steps, and the payment test we ran. You should have seen a backup restore if the database is part of the scope. You should be able to remove our users and still sign in yourselves.
The quote for that work comes after a look at the product. Milestones are written down. You accept the scope first. Payment for the project follows the schedule in the proposal: 30% upfront, 40% on completion, and 30% after user acceptance testing sign-off. The amounts are in USD and specific to that scope. They are not a rate card on the website.
If the product already takes payment and the access is scattered, the first job is often a rescue rather than a feature. We will say which one it is after the free technical assessment. Either way, the goal is the same. Customers can pay a product you can operate without asking us for the keys.
