nobody writes the indie hacker post about compliance, so here is mine. every item below is something i either got wrong or nearly shipped wrong on my own products.
selling to the world from one country
the moment you take money from strangers on the internet, you are potentially dealing with sales tax in dozens of jurisdictions. eu vat has no minimum threshold for digital goods sold to consumers. one customer in germany is enough to create an obligation.
you have two options. register and file everywhere, which is not a thing one person does alongside a job. or use a merchant of record, where a company sells your product to the customer as the seller of record, collects the tax, remits it, and pays you.
i use dodo payments as merchant of record on mypage.cc for exactly this reason. it costs a percentage. that percentage buys me not being personally responsible for tax compliance in countries i have never visited, and i consider it the single best money i spend on that product.
if you are pre-revenue this feels like a problem for later. it is, right up until it is not, and the transition happens without a notification.
the consent banner is not decorative
if you serve eu, uk or swiss visitors and you run analytics or ads, consent is not a design element you copy from another site.
what i ended up with: google consent mode v2, geo gated so eea, uk and swiss visitors get the banner and default to denied, and everything that drops a cookie stays off until they say yes.
the specific mistake i made first: my referral attribution cookie was being set before consent. the whole attribution system is a feature i was proud of, and it was quietly writing a cookie to visitors who had not agreed to anything. that is not a grey area.
your privacy policy is a description, not a template
the generated ones are worse than useless because they describe a product that is not yours. they list data you do not collect and omit the data you do.
what mine needed once i actually read it against the product: what is collected, why, where it is stored and in which region, how long it is kept, who it is shared with by name, and the actual rights language for gdpr and ccpa including how someone exercises them and how quickly you will respond.
i shipped one of my apps with a thin terms of service and a privacy policy below that bar. it took an audit of my own product to notice, months after launch, on something people were already paying for.
the refund window that broke my own promise
this one is my favourite because it is so stupid and so easy to make.
my free trial ran longer than my refund window. so a person could pay, pass the refund cutoff, and still be inside the period where the marketing told them they could change their mind.
that is not a legal edge case, it is a chargeback generator. and chargebacks do not just take the money back, they damage your standing with the payment processor, which is a much more expensive thing to lose than one refund.
check the two numbers against each other. it takes thirty seconds and i did not do it for weeks.
app stores add their own layer
if you ship on ios, the store wants a live privacy url before review, an accurate age rating, and a privacy nutrition label that matches what your app actually does. the label is not marketing. mismatches between what you declare and what your code does are a review problem and, later, a bigger problem.
i needed a 17+ rating on one app for content reasons and i gated it harder than strictly required, because being wrong in that direction costs a rejection and being wrong in the other direction costs your account.
the order i would do it in now
before you take a single payment: merchant of record or a tax plan. refund policy that agrees with your trial length. a privacy policy written from your actual data flows.
before you drive any traffic from europe: consent mode, geo gated, with nothing firing before consent, including your own attribution.
before you submit to a store: live privacy and terms urls, age rating, privacy labels that match the code.
after launch, on a schedule: re-read all of it against the product as it now exists. this is where mine drifted. the policy described the product from launch day and the product had moved.
none of this is fun. all of it takes maybe two days total, spread out, and every hour of it protects money that already exists rather than chasing money that might.