# Putting Bid-Lawn.com on Cloudflare: step by step

Everything runs on ONE Cloudflare Worker: the website, the database (D1), the accounts, bidding, payments logic, email, and an hourly background job. You only add three outside services: **Stripe** (payments), **Resend** (email), and your **domain**.

Follow the parts in order. Do everything in Stripe TEST mode first (Part 8), and only go live in Part 9.

---
## Part 1. Accounts and tools (30 minutes)
1. **Cloudflare** account (free): dash.cloudflare.com
2. **Stripe** account: stripe.com (use your LLC's details)
3. **Resend** account (free tier): resend.com
4. **Domain name** (bid-lawn.com) from any registrar (Cloudflare Registrar is easiest)
5. Install **Node.js** (the LTS download, version 20 or newer): nodejs.org
6. Unzip this package. Open a terminal inside the folder (Mac: right-click the folder > New Terminal at Folder. Windows: open the folder, type `cmd` in the address bar, press Enter. Use "Git Bash" if you want to run `bash setup.sh`).

## Part 2. Put your domain on Cloudflare (skip if you registered it at Cloudflare)
1. Cloudflare dashboard > **Add a domain** > enter `bid-lawn.com` > choose the Free plan.
2. Cloudflare shows two nameservers. Log in at your registrar and replace the domain's nameservers with those two. Wait until Cloudflare says the domain is **Active** (minutes to a few hours).

## Part 3. Publish the site and database
1. In the terminal: `npx wrangler login` (a browser window opens; click Allow).
2. Run `bash setup.sh`. It asks for your admin email, domain and support email, creates the database and tables, and publishes the site. Copy the `https://bid-lawn.....workers.dev` address it prints.
   - No bash? Do it by hand: `npx wrangler d1 create bid-lawn`; paste the `database_id` and your four values (`ADMIN_EMAIL`, `SITE_URL`, `EMAIL_FROM`, `SUPPORT_EMAIL`) into `wrangler.toml`; then `npx wrangler d1 execute bid-lawn --remote --file=schema.sql`; then `npx wrangler deploy`.
3. Open the workers.dev address. You should see the Bid-Lawn.com banner and a sign-in box.

## Part 4. Connect your domain to the site
1. Cloudflare dashboard > **Workers & Pages** > **bid-lawn** > **Settings** > **Domains & Routes** > **Add** > **Custom domain**.
2. Enter `bid-lawn.com`, then repeat for `www.bid-lawn.com`. (Needs Part 2 finished.)
3. Visit https://bid-lawn.com to confirm it loads. Cloudflare provides the HTTPS certificate automatically.

## Part 5. Plug in Stripe (test mode)
1. Stripe Dashboard: turn **Test mode** on.
2. **Connect > Get started**. Choose the marketplace/platform option and complete the platform profile. Bid-Lawn uses **Express** accounts (Stripe hosts each provider's identity and bank forms).
3. **Developers > API keys**: copy the **Secret key** (`sk_test_...`). In the terminal run `npx wrangler secret put STRIPE_SECRET_KEY` and paste it.
4. **Developers > Webhooks > Add endpoint**:
   - URL: `https://bid-lawn.com/api/webhook`
   - Events (select exactly these three): `checkout.session.completed`, `charge.dispute.created`, `charge.refunded`
   - After creating it, click **Reveal** on the Signing secret (`whsec_...`), then run `npx wrangler secret put STRIPE_WEBHOOK_SECRET` and paste it.
5. (Optional) Stripe Settings > **Customer emails**: turn on "Successful payments" so homeowners get receipts.

## Part 6. Plug in email (Resend)
1. Resend > **Domains > Add Domain** > `bid-lawn.com`. Add the DNS records it shows in Cloudflare > your domain > **DNS** (or use Resend's Cloudflare connect button). Wait for **Verified**.
2. Resend > **API Keys > Create** (Sending access). Copy the key (`re_...`), then run `npx wrangler secret put RESEND_API_KEY`.
3. Make sure `EMAIL_FROM` in `wrangler.toml` uses your domain (setup.sh already did this).

## Part 7. Publish the final settings
Run `npx wrangler deploy` once more so the secrets take effect.
Check it: `npx wrangler secret list` should show STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET and RESEND_API_KEY.

## Part 8. Test everything (test mode, no real money)
Use three browser windows (one normal, two private) so you have three accounts.
1. **You (admin):** create an account with your ADMIN_EMAIL, click the verification link in your email. The **Admin** tab should appear.
2. **Business:** create a second account, verify email, Business portal > apply (any insurance text, future expiry date). In your Admin tab, click **Approve**. Check the "you are approved" email arrived.
3. **Business:** click **Set up payouts**. In Stripe test mode you can use test data (Stripe's form offers a "use test details" option) and finish.
4. **Homeowner:** create a third account, verify, post a job in the zip the business serves. The business should get a "New lawn job" email.
5. **Business:** place a bid. **Homeowner:** gets an email, clicks **Accept**, then **Pay** and uses card `4242 4242 4242 4242`, any future date, any CVC.
6. **Business:** gets "customer paid" email; clicks **Mark job done**. **Homeowner:** clicks **Job complete**.
7. Check Stripe Dashboard > **Connect > Transfers**: the provider got 90%. Check your Admin tab for the 10% fee. Leave a rating.
8. Try the failure paths: report a problem (then resolve it in Admin), "Forgot your password", cancel a job, and unsubscribe from a job alert email.

## Part 9. Go live with real money
1. Finish Stripe account activation (business details, your bank account for your fee income).
2. Switch the Stripe Dashboard to **Live mode**. Run `npx wrangler secret put STRIPE_SECRET_KEY` with the live key (`sk_live_...`).
3. In live mode create the webhook again (same URL, same three events) and update `STRIPE_WEBHOOK_SECRET` with its new signing secret.
4. `npx wrangler deploy`. Make one small real payment yourself, release it, then refund what you can from the Stripe Dashboard.
5. Cloudflare dashboard > your domain > **Security > WAF > Rate limiting rules**: optional extra protection. (Sign-in attempts are already limited in the code.)

## Part 10. Running the business day to day
- **Approve businesses** in Admin: open their insurance certificate (ask them to email it to your support address) and check name, coverage and expiry before you click Approve. The site suspends a business automatically when its insurance expiry date passes and emails them 14 days before.
- **Disputes:** homeowner reports appear in Admin. Release to the provider or refund the homeowner. Card **chargebacks** appear as "Card dispute"; answer them in Stripe Dashboard > Disputes.
- **Auto-release:** payments are released to the provider 7 days after payment unless the homeowner reports a problem. (This is stated in the on-site text; change the number in `src/index.js` `AUTO_RELEASE_MS` AND the wording if you want a different period.)
- **Logs and errors:** `npx wrangler tail` shows live errors. Cloudflare > Workers > bid-lawn > **Observability** keeps history.
- **Backups:** `npx wrangler d1 export bid-lawn --remote --output=backup.sql` (do this weekly and keep copies). D1 also keeps 30 days of point-in-time recovery.
- **Updating the site:** change files, then run `npx wrangler deploy`. Rollback: Workers > bid-lawn > **Deployments** > pick an earlier version.
- **Existing database from an earlier package?** Run `migrate-email.sql` then `migrate-v2.sql` once each (only the ones you haven't run).
- **Run the automated tests anytime:** `npm test` (needs Node 22.5+).

## Part 11. Before you tell the public (business and legal checklist)
- [ ] LLC formed, EIN obtained, business bank account opened, Stripe account in the LLC's name.
- [ ] Attorney reviewed: Terms of Service (homeowner and provider), Privacy Policy, the 100% liability and indemnity wording, the 7-day auto-release rule, and whether holding customer funds needs a license in your state.
- [ ] Contact email in `SUPPORT_EMAIL` is a real inbox. Add your business name and mailing address to the Privacy tab text.
- [ ] Platform insurance for yourself (general liability and cyber) and a business license if your city requires one.
- [ ] Check whether your state requires a contractor or home-services broker registration, and whether your fee is subject to sales tax.
- [ ] Accountant set up for 1099 reporting and sales tax.
- [ ] Trademark and domain check for "Bid-Lawn" done.
- [ ] Add a data-deletion process (e.g. "email support to delete your account") and promise it in the Privacy text if you serve California or EU residents.
- [ ] Do the full Part 8 test again in live mode with a small real payment.

## Troubleshooting
- **"Sign in required" or blank page after deploy:** hard refresh; make sure `npx wrangler deploy` finished without errors.
- **Payments stay "Awaiting payment" after paying:** the webhook isn't reaching you. In Stripe > Webhooks check the delivery log; the URL must match your live domain and the signing secret must match STRIPE_WEBHOOK_SECRET.
- **"The provider has not finished payout setup yet":** the business must finish Stripe onboarding (Business portal > Set up payouts), then come back to the site.
- **No emails:** Resend domain not verified yet, or RESEND_API_KEY missing. Check Resend > Logs. Check spam.
- **Admin tab missing:** sign in with exactly the ADMIN_EMAIL address, and verify that email.
- **Wrangler says a setting is unknown:** update it with `npm install -g wrangler@latest` and run `npx wrangler --version` (version 4 or newer).
