How MiFinanz handles your data
This policy explains what MiFinanz actually does with personal data. It is written for the Swiss revised Federal Act on Data Protection (nFADP / revDSG) and the EU General Data Protection Regulation (GDPR), and for people who use the website, the web app, or the iOS app.
MiFinanz is a personal budget tracker. You type records yourself, or you import a JSON or CSV file you choose. It does not connect to your bank, it does not move money, and it does not pull transactions from a financial institution.
1. Who is responsible
The controller is Omar Tamasna, an individual developer in Frauenfeld, Switzerland (not a company).
- Postal address: Hasenbühlstrasse 9, 8500 Frauenfeld, Switzerland
- Email: support@mifinanz.com
If you are in the EU or EEA, you can still contact the controller at the address above. No EU representative has been appointed under GDPR Article 27.
2. Data we collect
We collect only what the product needs to run an account and store the records you enter.
Account and profile
- Email address and password. The password is handled by Supabase Auth. It is not stored in the app’s own tables.
- Display name (also stored as your username).
- Whether the email address has been confirmed, and the time the account was created or updated.
- Language, main currency, and the invoice-reminder setting (how many days before a due date the app should highlight an invoice). That reminder is inside the app. We do not collect a push-notification token.
- Plan (Free or Pro), whether Pro was granted without payment, and, if you have started web checkout, a Stripe customer id.
- If you subscribe on iOS, subscription status in the
revenuecat_entitlementstable: whether Pro is active, the product, the store, the period type, when access expires, and related renewal flags. Purchase events are written to therevenuecat_webhook_eventslog, which stores the event id, the event type, and your user id.
Creating an account can send a confirmation email. “Forgot password” sends a reset email. Both are sent by Supabase Auth. This project does not name a separate email company. If a custom email provider is connected in the Supabase dashboard, that provider processes the recipient address and the message.
Records you enter
These stay in your account until you delete them, reset the app data, or delete the account:
- Money accounts: the name you give them, a label of “bank” or “cash” (a label only — there is no bank connection), currency, and display order.
- Transactions: description, optional details, amount, category, subcategory, income or expense, date, account, and a link when one transaction is a refund of another.
- Transfers between your money accounts, and transfers into or out of goals: amounts, dates, descriptions, and currencies.
- Categories and subcategories you create.
- Budgets by month, category, and type.
- Invoices: title, details, amount, due date, paid status, recurrence, and installment schedules.
- Goals (called vaults in the database): name, optional target amount, optional due date, currency, and display order.
- Assets and liabilities: name, value, category, an icon name, type, and currency.
JSON import and CSV export are files on your device. After a successful import, the contents are stored in your account like anything you typed. We do not send those files to an analytics service.
Sharing an account
If you invite someone to a money account, we store the email address you type, the role (view only or editor), and whether the invite is still pending. We do not send an invitation email. If a MiFinanz account already uses that email, or one is created later with the same email, that person can see the pending invite inside the app.
After they accept, a viewer can read that money account’s transactions. An editor can add and change them. The records stay on the owner’s account. You should invite only someone who expects to receive that access.
Feedback
If you use Send Feedback, we store the kind of message (bug, feature, or other), the text you write, the time, and a status our staff set (open, read, or done). The message is tied to your account, so the stored row includes your user id. We also email that message to support@mifinanz.com through Resend, with your email address as the reply-to address. That email includes your user id, the app version, the platform (web or iOS), the language, and the device or browser string (the user agent).
Technical and security data
- On the website, a sign-in session stored in the browser under the key
mifinanzas-auth. If you save more than one account on a device, that device also stores those accounts’ access and refresh tokens undermifinanzas-accountsso you can switch without typing the password each time. - Theme and language preferences on the device (
finance_app_theme,finance_app_lang). - A cached table of exchange rates on the device (
mifinanz_fx_eur). - A short-lived flag in session storage so an upgrade notice is not shown again in the same visit.
- Supabase Auth can process your IP address and the time of sign-in to protect the account. The website host (Vercel) can process IP address, user agent, and the time of a request in order to deliver the site. We do not add our own analytics on top of that.
iOS app
- The sign-in session for the current login is stored in the iOS Keychain, not in the browser key above. Saved extra accounts can still sit in local storage under
mifinanzas-accounts. - If you turn on the app lock, the Face ID, Touch ID, or device passcode check happens on the device only. The app receives only pass or fail. It does not receive your biometric data or your passcode.
- Bill reminders are local notifications on the device. The app schedules them on that phone. We do not send them through a push service, and we do not collect a push-notification token.
Exchange rates
The app asks https://api.frankfurter.dev/v1/latest for public rates with a base of EUR and a fixed list of currency codes (GBP, USD, CHF, DKK, SEK, NOK, PLN, CZK, HUF, RON). The request does not include your email, account id, or any amount you entered. Your device’s IP address can still be seen by the API operator and by Cloudflare, which sits in front of that API, for delivery and abuse protection. Frankfurter’s own documentation says the public API does not keep request logs. We cache the rates on your device and refresh them about every 12 hours.
3. What we do not do
- We do not sell personal data.
- We do not use it for advertising, and the app does not include an advertising or analytics SDK. The dependencies are the app framework, Supabase, RevenueCat, Capacitor device plugins, dates, animation, icons, and translations.
- We do not connect to banks or payment accounts, and we do not receive your card number.
- We do not use tracking cookies. On the website, sign-in uses local storage, not a third-party advertising cookie. On iOS, the current sign-in session is in the Keychain.
- We do not make automated decisions that produce legal effects. Budgets and totals are calculations on the numbers you entered.
4. Why we use it, and the legal basis
| Purpose | Legal basis |
|---|---|
| Create your account, keep you signed in, send confirmation and password-reset emails, and store the records you enter so you can use them on your devices. | Contract (GDPR Art. 6(1)(b); the equivalent ground under the nFADP). |
| Show exchange rates, remember language, currency, theme, and reminder settings, and import or export a file you ask for. | Contract, as part of providing the app. |
| Store an invite email and give the invited person the access you chose. | Contract with you. For the invited person’s email, our legitimate interest in carrying out the invite you requested, and theirs in seeing an invite addressed to them. |
| Read feedback, keep the service secure, suspend abuse, and let authorised staff support an account (including opening the app as that user). | Legitimate interests (GDPR Art. 6(1)(f)): running, securing, and supporting the service. The audit log and the staff-only limit are the safeguards. You can object; see below. |
| If you later pay for Pro: create a subscription, record that the plan is active, and keep payment records. | Contract, and legal obligation where tax or accounting law requires us to keep a record. |
We do not ask you to consent to advertising. The checkbox at sign-up is acceptance of the Terms of Use, not a consent for extra uses of your data.
5. Who else processes it
These providers process data so we can run MiFinanz. We do not give them data to use for their own advertising.
| Provider | Role |
|---|---|
| Supabase | Database, login, and the server functions that delete an account, run admin actions, and (when enabled) talk to Stripe. Your account and financial records are stored in the Supabase project. The project is hosted in the EU, on AWS eu-north-1 (Stockholm, Sweden). |
| Vercel | Hosts the website and the web app files. It can process connection data (such as IP address and browser type) to deliver pages and protect the site. Your budget records are not stored in the Vercel project; they are stored in Supabase. |
| Stripe | Used only if web billing is turned on and you start checkout or open the billing portal. Billing is off unless an administrator enables it. Checkout sends Stripe your email address and account id, and Stripe processes the payment. We store the Stripe customer id. A webhook then marks the plan Free or Pro. We do not receive your full card number. The iOS app uses Apple In-App Purchase instead of Stripe. Apple processes that payment under Apple’s terms. Apple does not receive your budget entries as part of the payment. Subscription status for the iOS purchase is handled by RevenueCat, in the next row. |
| RevenueCat, Inc. (United States) |
Processes subscription purchase and entitlement status for Apple In-App Purchase on the iOS app. We send RevenueCat the app account user id. RevenueCat receives the purchase history for that customer and tells our server whether Pro is active. We store that status in the revenuecat_entitlements table. Incoming purchase events are written to the revenuecat_webhook_events log, which includes the user id. This is a transfer to the United States. Where that transfer is not covered by an adequacy decision, we rely on the same safeguards as the other providers in the international-transfers section, in particular Standard Contractual Clauses. RevenueCat does not receive your budget entries.
|
Frankfurter (api.frankfurter.dev) and Cloudflare |
Public exchange rates. The request contains currency codes only. Cloudflare provides caching and abuse protection in front of that API. No account data is attached. |
| Resend | Delivers feedback email in the EU (Ireland, AWS eu-west-1). When you send feedback, the message is emailed to support@mifinanz.com through Resend, with your email address as the reply-to address. |
| Zoho Mail | Hosts the support mailbox support@mifinanz.com in an EU data center. Feedback messages delivered through Resend, and other mail sent to that address, are stored there so we can read and reply to them. |
| Someone you invite | A viewer or editor of a money account can see, and an editor can change, the transactions on that account. That is sharing you start, not a sale of data. |
6. International transfers
The controller is in Switzerland. The European Commission has an adequacy decision for Switzerland, so EU data-protection law treats Switzerland as providing an adequate level of protection.
Supabase, Vercel, Stripe, Apple, Cloudflare, and RevenueCat, Inc. are companies that can process data in the United States and in other countries. RevenueCat, Inc. is in the United States: the app account user id and purchase history are transferred there so it can report entitlement status. Where a transfer is not covered by an adequacy decision, we rely on appropriate safeguards, in particular Standard Contractual Clauses, and on any extra measure the provider applies (including certification under the Swiss-US or EU-US Data Privacy Framework, where that provider is certified).
The database itself is hosted in the EU, on AWS eu-north-1 (Stockholm, Sweden). Feedback email is sent through Resend in the EU (Ireland, AWS eu-west-1), and the support mailbox is hosted by Zoho Mail in an EU data center. Even when a provider’s region is in the EEA, that provider’s support or sub-processor staff can still be elsewhere under the safeguards above.
7. How long we keep it
- Account data and the records you enter are kept while the account exists.
- Feedback stored in the account is kept with the account and is deleted when the account is deleted. Resetting the financial data does not delete feedback. The copy emailed to the support mailbox is kept only as long as needed for support.
- An invite is kept until it is removed or the owner’s account is deleted.
- Admin audit log entries are kept only as long as needed for security and support purposes. The application does not set a fixed retention period and does not delete them on its own. They can include the email address that was on the account when a staff action was taken, and they can remain after the account is deleted unless the law requires otherwise.
- If a Stripe customer was created, Stripe can keep billing records for as long as its own terms and tax or accounting rules require. Deleting your MiFinanz account does not, in the current code, also delete the Stripe customer.
- The
revenuecat_entitlementsrow is kept while the account exists and is removed when the account is deleted. The webhook event log (revenuecat_webhook_events) keeps the user id. The application does not set a fixed retention period for that log and does not delete those rows on its own. They can remain after the account is deleted. - The RevenueCat customer record is kept by RevenueCat, Inc. Deleting your MiFinanz account does not, in the current code, also delete that customer. The record can keep the app account user id and purchase history for as long as RevenueCat’s terms require. You can ask us to request deletion of that customer record, and of webhook log entries that still have your user id, at support@mifinanz.com.
- After deletion, backups are managed by our hosting provider and overwritten on a rolling basis.
- Exchange-rate cache, theme, and language stay on the device until you clear site data. They are not your financial records.
8. Security
We protect the service in these ways:
- The database uses row-level security so a signed-in person can read and write their own rows, plus a money account that an owner has shared with them.
- Passwords are handled by Supabase Auth. Plan and Stripe fields cannot be changed by the app itself; only the server functions can change them.
- The service-role key used to delete an account or run admin actions stays on the server. It is not in the app.
- The site is served over HTTPS. Supabase encrypts the hosted database at rest and uses TLS for connections.
- Staff actions are written to an audit log.
This is not end-to-end encryption. We can access account data as described in the next section, because the product stores your records on the server so they can sync. No method of transmission or storage is perfectly secure.
9. Staff access and “open as user”
Authorised staff (an owner role or a support role on a MiFinanz account) can use an admin panel. In that panel they can see your email, display name, plan, currency, Stripe customer id if there is one, whether the account is suspended and why, and counts of your records (accounts, goals, transactions, budgets, invoices, assets, and shares). They can read the text of feedback you send. They can change a plan, grant Pro, suspend or unsuspend a login, and the owner role can delete a user.
The admin panel does not list the contents of your transactions or invoices. A separate action, “open as user”, creates a one-time Supabase sign-in link and opens MiFinanz as you. The staff member then sees the same records you see, so they can help with a support problem. That action is written to the audit log together with the email address on the account at the time.
We use this access to operate the service, answer a request for help, investigate abuse, and meet a legal duty. We do not use it to advertise, and we do not sell what we see. You can object to access that is based on legitimate interests. If you object to support access, we may not be able to look into a problem on that account. We may still need to access data where the law requires it, or where a remaining legitimate ground overrides the objection (for example, to keep the service secure).
10. Deleting your account, and resetting data
In the app, open Settings and choose Delete Account. That calls the delete-user function, which deletes the login. The database then removes the rows tied to that login: profile, settings, money accounts, transactions, transfers, categories, budgets, invoices and installments, goals, assets and liabilities, sharing records, feedback, any staff role, moderation status, per-user plan overrides, and the subscription status row in revenuecat_entitlements.
The same action does not automatically remove:
- Admin audit log entries (see the retention section).
- A Stripe customer, if web checkout had created one.
- The RevenueCat customer record. It keeps the app account user id. The webhook event log (
revenuecat_webhook_events) also keeps the user id. You can ask us to request deletion of that customer record and of those log entries at support@mifinanz.com. - Backup copies held by the hosting provider until they are overwritten on a rolling basis.
- Records on someone else’s account that you changed while you were an editor. Those belong to the owner.
On the device you use to delete the account, that saved login is removed. Sessions on other devices stop working because the login no longer exists.
Settings also has Reset Application. That deletes the financial records on the account and keeps the login. It does not delete feedback, and it does not delete the audit log.
You can download a JSON backup or a CSV of transactions from Settings before you delete anything. Export of a backup can be limited when paid plans are enforced; the current configuration still allows export unless an administrator turns that limit on.
11. Your rights
Under the nFADP and, where it applies, the GDPR, you can ask us to:
- confirm whether we process data about you, and for a copy of it (access);
- correct inaccurate data (you can also edit most records in the app);
- delete data (you can delete the account yourself, or ask us);
- restrict processing in the cases the law allows;
- receive the financial records you provided in a portable form (JSON or CSV export is the practical way; you can also ask us);
- object to processing based on legitimate interests;
- lodge a complaint with a supervisory authority, without affecting any other remedy.
We will respond within 30 days. We may ask you to prove that you control the account before we disclose or change it. If a request is manifestly unfounded or excessive, we may refuse it or ask for a reasonable fee, where the law allows that.
Switzerland: Federal Data Protection and Information Commissioner (FDPIC), www.edoeb.admin.ch. EU and EEA: the authority in your country. A list is published by the European Data Protection Board at edpb.europa.eu.
12. Children
MiFinanz is not directed at children under 16. We do not knowingly create an account for anyone under 16. If you believe a child under 16 has given us personal data, email support@mifinanz.com and we will delete the account.
13. Changes
We will post any new version at this same address and change the effective date. The app does not email policy updates, because it has no mailing list. If a change is one the law says we must tell you about directly, we will use the email on your account.
14. Contact
Omar Tamasna
Hasenbühlstrasse 9, 8500 Frauenfeld, Switzerland
support@mifinanz.com
The rules for using the product are in the Terms of Use.