50% off SaaS Starter Kit — only for the first 100 buildersGrab it →
← Back to blog
best-practicesMay 19, 2026·10 min read

Legal Stuff for Indie Devs: Terms, Privacy, and Refund Policies Without a Law Degree

You don't need a lawyer on retainer to cover yourself legally. Here's what actually matters for indie devs shipping SaaS products.

Robert Seghedi

Robert Seghedi

Co-founder, peal.dev

Legal Stuff for Indie Devs: Terms, Privacy, and Refund Policies Without a Law Degree

At some point while building your SaaS, you'll realize you need a Terms of Service and a Privacy Policy. Then you'll Google 'free terms of service generator', paste something in, change the company name, and ship it. We've done this. You've probably done this. It mostly works — until it doesn't.

This post isn't legal advice. We're two developers from Romania, not lawyers. But we've shipped several products, dealt with Stripe disputes, handled GDPR complaints, and had users try to get refunds after consuming 90% of a product. We've learned enough to stop being completely naive about this stuff.

Why Bother? You're Small, Nobody Cares

This is what we told ourselves for the first two products. Then a user filed a chargeback with their bank claiming they 'never authorized' a charge — for a subscription they'd been on for four months. Without a clear Terms of Service that spelled out our billing terms, we had almost nothing to show Stripe. We lost that dispute.

The legal documents aren't just CYA paperwork. They're your evidence trail when things go sideways. A clear refund policy is what you point to when someone emails 'I want my money back' at 11pm. A Privacy Policy is what keeps you from getting flagged by Apple, Google, or ad platforms when you try to distribute or market your product.

The goal isn't to be legally bulletproof — that's impossible without an actual lawyer. The goal is to be clear, honest, and not obviously negligent.

Privacy Policy: What You Actually Need

If you're operating in the EU, collecting any data from EU residents, or just want to be on App Store / Play Store someday, you need a Privacy Policy. This is non-negotiable. The GDPR fine for not having one isn't the reason — enforcement for tiny indie products is rare. The reason is that without one, you can't use Google Analytics, Facebook Ads, or submit to most app stores.

Here's what a real Privacy Policy needs to cover for a typical SaaS:

  • What data you collect — email, name, payment info, usage data, IP addresses
  • How you collect it — forms, cookies, third-party SDKs
  • Why you collect it — account management, billing, analytics
  • Who you share it with — list your actual third parties: Stripe, Resend, Vercel, PostHog, etc.
  • How long you keep it — 'until account deletion plus 30 days' is fine
  • User rights — especially for EU users: right to access, delete, export their data
  • How to contact you — a real email address, not a form

The third-party section trips people up. You need to actually list the services you use. If you're using Stripe, they process payment data. If you're using PostHog or Mixpanel, they get usage events. If you're using Vercel, your users' requests hit their servers. List them, link to their privacy policies, and you're covered.

## Third-Party Services

We use the following third-party services to operate our product:

- **Stripe** — Payment processing. Stripe receives and stores payment information.
  Privacy Policy: https://stripe.com/privacy

- **Resend** — Transactional email delivery.
  Privacy Policy: https://resend.com/legal/privacy-policy

- **Vercel** — Hosting and infrastructure. Vercel processes request logs.
  Privacy Policy: https://vercel.com/legal/privacy-policy

- **PostHog** — Product analytics. We collect anonymized usage events.
  Privacy Policy: https://posthog.com/privacy

We do not sell your personal data to any third party.

That last line — 'we do not sell your personal data' — is important. If you're not selling data (you're not, you're building a real product), say so explicitly. It builds trust and it's required under CCPA for California users.

Terms of Service: Protect Yourself Without Being Evil

Your Terms of Service is basically a contract between you and your users. It sets the rules of the game. Most ToS documents are written by lawyers for corporations, which is why they read like they were generated by a machine trained on misery. You can do better.

The sections that actually matter for an indie SaaS:

  • Acceptance of terms — using the service means you agree
  • What the service does — brief description of what you're providing
  • Account responsibilities — users are responsible for their account security and actions
  • Prohibited uses — abuse, scraping, illegal activity, impersonation
  • Payment and billing terms — when you charge, what the subscription covers, how upgrades/downgrades work
  • Refund policy — covered separately below, but reference it here
  • Intellectual property — you own your product, users own their data
  • Limitation of liability — the service is provided 'as is', you're not liable for consequential damages
  • Termination — you can terminate accounts that violate terms
  • Governing law — which country/state's laws apply

The governing law clause matters more than people think. If you're in Romania and you specify Romanian law, a US user can't drag you into small claims court in California. If you're a solo dev and you don't specify, you're potentially subject to every jurisdiction your users are in. Pick your home jurisdiction and stick with it.

## Limitation of Liability

[Product Name] is provided "as is" without warranty of any kind. We do not
guarantee that the service will be uninterrupted, error-free, or that any
defects will be corrected.

To the maximum extent permitted by applicable law, [Company Name] shall not
be liable for any indirect, incidental, special, consequential, or punitive
damages, including but not limited to loss of profits, data, or business
opportunities, arising from your use of the service.

Our total liability to you for any claims arising from use of the service
shall not exceed the amount you paid us in the 12 months preceding the claim.

## Governing Law

These Terms are governed by the laws of Romania, without regard to conflict
of law principles. Any disputes shall be resolved in the courts of [City], Romania.

The limitation of liability clause is the one that actually saves you. If your app has a bug and someone loses data, you don't want to be on the hook for their 'lost business opportunities.' Cap your liability at what they paid you. Courts sometimes ignore these clauses, but having them is better than not.

Refund Policy: Write It Before You Need It

This is the one most indie devs skip until a user asks for a refund and they have to make up a policy on the spot. Bad idea. Your refund policy should be decided in advance, written down, and easy to find.

The main decision you need to make: are you offering refunds at all, and under what conditions? There's no universal right answer, but here's how we think about it:

  • No-questions-asked within 14 days — most customer-friendly, reduces chargebacks, Stripe loves it
  • No refunds, but cancel anytime — common for subscription products with free trials
  • Prorated refunds for annual plans — fair for users who pay upfront and change their mind
  • Case-by-case — sounds flexible, actually creates more headaches than it solves

We learned to love the 14-day refund policy the hard way. Chargebacks cost you $15 in dispute fees plus the refund anyway. If you offer an easy refund, most users take that instead of going to their bank. And users who would have charged back are usually the same ones who would leave a bad review, so you're not losing a customer you wanted to keep.

## Refund Policy

**Monthly subscriptions:** We offer a full refund within 14 days of your
initial purchase or any renewal charge. After 14 days, charges are
non-refundable. You can cancel at any time to prevent future charges.

**Annual subscriptions:** We offer a full refund within 30 days of purchase.
After 30 days, we offer a prorated refund for unused months, calculated
from the date of your refund request.

**How to request a refund:** Email us at support@yourproduct.com with
your account email and the reason for your request. We'll process it
within 5 business days.

**What we don't refund:**
- Accounts suspended for Terms of Service violations
- Partial months of service already consumed
- Add-on purchases unless they fail to deliver the described functionality

We reserve the right to issue refunds at our discretion in cases not
covered above.

That last paragraph — 'we reserve the right to issue refunds at our discretion' — gives you flexibility to be a human being when a user has a genuinely sympathetic situation. You don't want to be locked into 'no refunds after 14 days' when someone emails you explaining their startup shut down and they forgot to cancel. Let yourself make the call.

Where to Put These Documents and How to Get Acceptance

Having the documents is half the battle. Making sure users have actually agreed to them is the other half. For the Stripe chargeback story we mentioned earlier, part of our problem was we couldn't prove the user had seen and accepted our billing terms.

During signup, add an explicit checkbox. Not just a footer link — an actual checkbox that says 'I agree to the Terms of Service and Privacy Policy' with the relevant links. Make it required. This is slightly more friction but it's your evidence when a user claims they 'didn't know' about your billing terms.

// In your signup form component
import { useState } from 'react'

export function SignupForm() {
  const [agreedToTerms, setAgreedToTerms] = useState(false)

  return (
    <form>
      {/* other fields */}
      
      <div className="flex items-start gap-2 mt-4">
        <input
          type="checkbox"
          id="terms"
          checked={agreedToTerms}
          onChange={(e) => setAgreedToTerms(e.target.checked)}
          required
          className="mt-1"
        />
        <label htmlFor="terms" className="text-sm text-gray-600">
          I agree to the{' '}
          <a href="/terms" target="_blank" className="underline">
            Terms of Service
          </a>{' '}
          and{' '}
          <a href="/privacy" target="_blank" className="underline">
            Privacy Policy
          </a>
          , including the billing terms for paid subscriptions.
        </label>
      </div>

      <button type="submit" disabled={!agreedToTerms}>
        Create Account
      </button>
    </form>
  )
}

Store a record of when the user agreed and which version of your terms they agreed to. A simple timestamp and a version number in your users table is enough. If you update your terms, you'll want to know which users agreed to the old version.

// Add to your users table schema
// Using Drizzle ORM as an example
export const users = pgTable('users', {
  id: text('id').primaryKey(),
  email: text('email').notNull().unique(),
  // ...
  termsAcceptedAt: timestamp('terms_accepted_at'),
  termsVersion: text('terms_version').default('1.0'),
})

// In your signup handler
await db.update(users).set({
  termsAcceptedAt: new Date(),
  termsVersion: '1.0', // bump this when you make material changes
}).where(eq(users.id, newUser.id))

Tools for Getting This Done Without Losing a Week

You have a few options for generating the actual documents:

  • Termly or Iubenda — paid generators that give you reasonably solid documents and host them for you. Worth it if you want something that's actually maintained and updated when laws change.
  • Clerky or Stripe Atlas — if you've incorporated, they often include basic legal document templates.
  • Use an AI to generate a first draft — then read it line by line and actually understand what it says. Don't blindly publish something you haven't read.
  • Hire a lawyer for a one-time review — $200-500 from a startup-focused lawyer for a document review is genuinely worth it once you're making real money.

Our current approach: we use a generated base from Termly, customize it heavily to match what we actually do (not what a generic SaaS template says), and have a lawyer friend review it when we have something major at stake. Most of our products are under that threshold.

If you're using one of our peal.dev templates, we include a basic legal page structure with placeholder sections — you still need to fill in your actual policies, but the layout and linking is wired up so you don't forget to expose these pages.

The Stuff People Always Forget

A few things that are easy to miss:

  • Cookie consent banner — if you're targeting EU users and using any analytics or tracking cookies, you technically need one. Use a library like cookie-consent or a service like Cookiebot rather than building your own.
  • Update your policies when you add new tools — if you add a new third-party service, your Privacy Policy is now inaccurate. Add the service, update the policy, bump the version.
  • GDPR data deletion — if a user emails asking you to delete their data, you're obligated to do it within 30 days under GDPR. Have a plan for this before it happens.
  • Don't copy competitors' policies verbatim — they might be inaccurate, they might be copyrighted, and they might describe practices that don't match yours.
  • Link to your policies in every email you send — required under CAN-SPAM (US) and GDPR. Your transactional email footer should have an unsubscribe link and a link to your privacy policy.
The real takeaway: write policies that describe what you actually do, not what sounds good. Accurate and honest beats impressive and vague every time.

Get the documents done in an afternoon. They're not fun, they're not sexy, and nobody's going to congratulate you for having a solid refund policy. But when the first chargeback lands, or when a user demands their data under GDPR, or when you want to run ads and the platform asks for your privacy policy URL — you'll be very glad you did it before you needed it.

Newsletter

Liked this post? There's more where it came from.

Dev guides, honest build stories, and the occasional 2am debugging confession — straight to your inbox. No spam, unsubscribe anytime.

Browse templates
Written by humansWeekly dropsSubscriber perks

Join the Discord

Ask questions, share builds, get help from founders