Privacy Policy
Last updated: September 8, 2026 · Version: 1.2 · Effective from: September 8, 2026
Under Articles 13 and 14 of Regulation (EU) 2016/679 ("GDPR"), this policy describes how personal data is processed by radioBros di Alberto Miconi, registered office at Via Ridolfino Venuti 30, 00162 Rome (Italy), Italian VAT number IT15127451001, operator of the TesserApp service (the "Controller").
Contact for any matter relating to the processing of personal data: privacy@tesserapp.eu.
The Italian-language version of this policy is the official version and prevails over translations in case of discrepancy.
TesserApp has two categories of data subjects, with separate processing regimes:
- customers using the mobile app to keep their own loyalty cards;
- shops using the web platform and the shop mobile app to operate their loyalty programs.
To these are added visitors to this website and to the dashboard, covered in §2 bis.
In its relationship with shops, with respect to the data of those shops' own customers, the Controller acts as a data processor under GDPR Art. 28; the relationship is governed by a separate Data Processing Agreement ("DPA") which shops accept upon signup.
1. For TesserApp app customers
1.1 What we collect
When you install and use the TesserApp consumer app:
- A random install identifier (a 256-bit token generated on your device at first launch). It is not derived from your name, your phone number, an account, your phone's serial number or any advertising identifier, and there is no login. It is held in the system keychain (iOS) or in the app's database (Android) and is sent to our servers to authenticate your cards, where it is stored only as a cryptographic hash. Because it travels with your Apple or Google account backup, it can survive an uninstall and follow you to a new phone: it is therefore durable over time, while remaining unconnected to your identity. See §1.7.
- Loyalty card identifiers for each card you activate (one UUID per card).
- Transaction events (stamps awarded, prizes redeemed, reversals, balance or points changes) with timestamp and shop location, the amount or number of stamps requested and, for a reversal, any free-text reason written by the shop.
- Apple Wallet / Google Wallet pass identifiers, only if you choose to add a card to the native wallet, together with the pass update token and the identifier the operating system assigns to your device's pass library.
- Your device system language, the platform (iOS or Android) and the app version: the first two to render the app and its notifications in your language, the third to know which builds are still in use when we diagnose a fault.
- A push notification token issued by Apple (APNs) or Google (FCM), stored so we can send you a notification. It is registered for the app installation itself — whether or not you hold any loyalty card — is meaningless outside our app, and is replaced by the operating system whenever it likes. It is not an advertising identifier and cannot be used to track you across other apps or websites.
- GPS location, only with your permission and only while you use the nearby-shops discovery feature or browse the catalogue sorted by distance. The coordinates travel in that single request and are not stored, by us or on the phone. On iOS the same feature also queries Overpass, a public service of the OpenStreetMap project, to which the coordinates are sent directly from your phone: see §4.
- Your email address, only if you choose to provide it (e.g. to request data deletion or contact support).
- Technical error reports. In released builds the app sends error and crash reports to a diagnostics system we run on our own infrastructure (
glitchtip.radiobros.com), not to a third-party analytics service. A report carries the device model, the operating system version and the app version, and may contain the technical identifier of a card or program involved in the error. It is configured not to collect user-identifying data, not to track sessions, not to record your interactions with the app and not to attach your IP address to the report. We use no analytics, attribution or advertising SDK. - For named cards (private, discount, access, prepaid): your name and email address, which the shop provides to us when it creates the card, and — if the shop uses our integration API — any customer reference of the shop's own (for example an employee or member number). See §1.6.
- For app-less web enrollment: an optional email address and name, if the form you are using asks for them and you choose to fill them in, together with a marketing-consent marker (the date and the source of the capture). See §1.6.
What we do NOT collect, for any kind of card: your postal address, your phone number, your web browsing history, biometrics, advertising identifiers or tracking cookies. There is no login, no account, no advertising, and we build no advertising or behavioural profile.
Name and email address: it depends on how you obtained the card, not only on its type.
- A stamp card or points card activated in the app (by scanning the shop's QR code, or from the catalogue): no name, no email. The card is anonymous and stays that way.
- Named cards — private, discount, access, prepaid: these are by definition issued to one individual, and name and email are required. The shop provides them; we never ask you for them and the app has no field to enter them.
- A stamp card obtained by enrolling from a web page without installing the app: name and email are optional. If you leave them out, the card is created anonymously exactly like one activated in the app.
- A card created by the shop through our integration API: in addition to name and email, the shop may attach its own customer reference (see the named-card bullet in §1.1).
1.2 Why we collect it
- To deliver the service: keep your stamps, prizes and balances, sync cards between your phone and the native wallets, generate Apple Wallet and Google Wallet passes when you ask for them, allow shops to award you stamps when they scan your barcode, and deliver the named cards a shop issues in your name.
- To deliver the shop's own messages about a program: when a shop composes an announcement for the holders of one of its programs, we send it as a push notification to those devices whose notifications for that card are switched on.
- For security: audit logs to detect suspicious stamping or abuse, and to establish who performed an operation.
- For service diagnostics: identify wallet pass delivery issues, sync errors and app crashes.
- To show you nearby shops, when you turn that feature on.
1.3 Legal basis (GDPR Art. 6)
- Legitimate interest (Art. 6.1.f) for service delivery, system security and technical diagnostics.
- Consent (Art. 6.1.a) for geolocation, push notifications, and emailing support. Notifications are governed at two levels: the phone's system permission, which you can withdraw at any time in your device settings, and — in the app, under Settings → Notifications — a switch for each card. A card's switch covers both alerts about that card's activity (a stamp awarded, a prize redeemed, a balance change) and messages the shop sends to the holders of that program: turning it off stops both, for that card only. We send no promotional announcements of our own: the channel exists on the server side but is switched off, and the app contains no control to turn it on.
- For named cards (see §1.6): your name, your email and any customer reference are processed on the instructions of the shop (controller) under GDPR Art. 28. The lawful basis — typically performance of the loyalty relationship (Art. 6.1.b) or your consent (Art. 6.1.a) — is the shop's responsibility.
- For the optional email at web enrollment: you provide it yourself, and it allows the shop to recognise you and contact you again in relation to the loyalty program. The marketing-consent marker recorded at that moment is, today, a stored field only: no promotional message is sent on its basis, by us or by the shop through our systems. If you want it removed, write to us.
1.4 Retention
The table distinguishes what an automated process deletes from what we remove on request: we would rather tell you how it actually works than quote deadlines that no process enforces.
| Data | Retention |
|---|---|
| Active loyalty cards | Until you delete them, or the shop does |
| Deleted cards | Deletion is immediate and cannot be undone. Your name, email and customer reference are erased at the moment you confirm, and the credential that bound the card to your phone is destroyed, so the card can never be read again: there is no recovery window and no way for us to bring it back. Within 30 days a nightly job removes the card's remaining rows, and the card row itself unless a retained transaction record refers to it — in which case what stays is a bare identifier that identifies nobody, removed in any event when the shop's account is anonymised (§2.3) |
| Name, email and customer reference on named cards | For as long as the card exists. They are removed on the shop's instruction or on your deletion request — a removal we perform manually today, not through an automated process — and are anonymised in any event when the shop's account is deleted (§2.3) |
| Account-binding identifier (pseudonymous) | Kept while the bound named card exists; removed together with the holder's other data |
| Install registration for notifications (token hash, push token, language, app version) | Kept until you ask for its removal. No automatic expiry is in place |
| Wallet pass identifiers | Until you remove the pass from your native wallet, or the card is deleted |
| Shop announcements sent to a program's holders (title, text, image, link, and the number of devices reached) | Kept as the record of the shop's communications. No automatic expiry is in place |
| Payloads of webhook calls sent to the shop (for named cards these contain the holder's name and email) | 30 days, deleted automatically. When a card is deleted, the name, email and customer reference are masked immediately in payloads already stored; the technical record of the call (event, outcome, date) remains |
| Audit events and access logs (with IP address and user-agent) | Kept with no predefined expiry: they are the record of what was done, including the proof that a deletion was carried out |
| Transaction ledger | Kept as the record of the shop's activity and not deleted along with an individual card; references to the holder are removed when the holder's data is erased |
| Emails sent (recipient address and the content of the variables) and support emails | Kept as long as needed to handle the request and to evidence delivery. No automatic expiry is in place |
| Technical error reports | Kept in our diagnostics system for as long as needed to fix the defect |
1.5 Your rights
You always have the right to:
- Access your data (Art. 15).
- Rectify it if inaccurate (Art. 16).
- Erase it (Art. 17). You can delete individual cards in-app or request full data deletion by writing to privacy@tesserapp.eu.
- Restrict processing (Art. 18).
- Receive your data in a portable format (Art. 20). The app lets you export the cards you created yourself to a file at any time; for the data we hold on our servers there is no automated export today: write to us and we will prepare it.
- Object to processing (Art. 21).
- File a complaint with your national data protection authority. You may contact the Italian Data Protection Authority (Garante — gpdp.it) as the supervisory authority for radioBros, or the authority in your country of residence.
To exercise a right, email privacy@tesserapp.eu. We respond within 30 days. For the name, email and customer reference on named cards, the shop is the controller: address access, rectification or erasure requests to the shop, and we (as processor) will assist and action the shop's instructions.
One important clarification about named cards. Deleting a named card in the app is not an erasure: it unbinds the card from your phone and unlocks it, so you can reinstall it on another device with your stamps or balance intact. The card, your name and your email continue to exist at the shop. To have them actually erased, ask the shop or ask us.
1.6 Named cards
Some programs are, by construction, issued to a single individual rather than open to the public. There are four: private card (a personal stamp card), discount card, access card and prepaid card. For all four:
- What the shop gives us about you: your name and email address, both mandatory, provided by the shop when it creates the card; and, if the shop uses our integration API, the customer reference it already uses in its own systems (for example an employee or member number).
- What we do with it: create your personal card, send you an email invitation (a link, QR code or one-time code) to install it in the TesserApp app, and bind the card to the device account — your iCloud account on iOS, your Google account on Android — on which you first install it, so that only your account can hold that card. Your name and email are also printed on the card itself and on the Wallet pass, and are shown to shop staff when they scan your card.
- Account-binding identifier: an opaque, pseudonymous reference to your iCloud/Google account (not your name or email). It is recorded, not enforced: it is asserted by the app, kept for audit and for future multi-device support, and it is not what protects the card — the install identifier above is. It is not used to identify you elsewhere or for any tracking.
- Roles: the shop is the data controller of your name, your email and the customer reference; TesserApp is the processor acting on the shop's instructions (see §3 and the DPA). The shop is responsible for having a lawful basis and, where required, your consent to share your details with us.
- Your choices: if you do not install the card, no account binding occurs. You can ask the shop (controller) to delete your card data at any time, and we will action that instruction.
App-less web enrollment. For stamp cards only it is possible to enrol from a web page and add the card straight to Apple Wallet or Google Wallet, without installing the app. On that path the form may ask for an optional name and email address and a marketing consent: if you leave them blank the card is created anonymously, just like one activated in the app; if you fill them in, that data is attached to the card and processed on the shop's behalf exactly as above. The enrollment page we publish ourselves asks for nothing at all today: enrollment is anonymous. The optional fields remain available to a shop that integrates the feature into its own tools.
1.7 Your device, your Wallet and your backup
Much of what the app holds is not ours and never passes through our servers. We describe it here because it is your data all the same.
- On the phone. The cards you create yourself (name, brand, barcode number, colour, and any photographs of the physical card) are held in the app's local database and files. We do not transmit them. The shop loyalty cards are held there too, including the holder's name and email on named cards, so that a card can be shown instantly and with no network.
- When you add a card to a Wallet. If you tap "Add to Apple Wallet" or "Add to Google Wallet" for a card you created yourself, the app sends our servers the data needed to generate the pass: the card's name, brand, barcode number, barcode type, colour and — on iOS — an image of the photograph you attached to the card. This is the only case in which the content of a personal card leaves the phone, and it happens only at your explicit request.
- In your backup. On iOS the install identifier is held in the iCloud-synchronised keychain, and the cards you create yourself — barcode numbers and photographs included — are synchronised into your own private iCloud storage. On Android the app's database and the card images are included in your Google account's automatic backup, which therefore also covers the shop loyalty cards and their holder name and email. These archives belong to your Apple or Google account and are governed by Apple's and Google's own notices: we cannot read them.
- On the Apple Watch. If you use the app on an Apple Watch, the watch receives a reduced list of your cards from the phone (name, brand, colour, barcode number, logo) and stores it locally so it can show them without the phone. The watch app makes no network connection at all.
2. For shops using the web platform
2.1 What we collect
- Legal name, trade name, VAT number of your business.
- Login email and contact email (can be the same).
- Public phone number, if you add it to your shop profile.
- Billing address and address of each shop location. For a sole trader the business address may be a home address.
- Payment data: handled by Stripe Payments Europe Ltd., who is the separate controller of payment instrument data. We only store the Stripe
customer_idandsubscription_idreferences, plus copies of the invoices issued, which by law name their recipient and address. - Password hash (argon2id; we never store plaintext passwords).
- TOTP secret if you enable two-factor authentication (encrypted with AES-256-GCM under a separate key), and recovery codes stored as argon2id hashes.
- Passkeys, if you use passwordless sign-in: the credential identifier and public key, the device type, the counter, and the name you choose for it.
- Sign-in with Google or Apple, if you use it: the provider, the identifier the provider assigns you and the email address it reports to us (for Apple this may be a private relay alias).
- Staff names and staff PINs you register for a location: the name in clear, the PIN as an argon2id hash. The PIN exists to attribute a stamp to the person who awarded it.
- Paired devices: the device model and operating system version (not the name you gave the device), the platform, a random install identifier and the push notification token.
- Access logs and sessions: timestamp, IP, user-agent, outcome.
- Audit events for every significant change to your profile, programs, locations and cards, with IP and user-agent.
- IP address, timestamp and version at the moment you accept the Terms of Service and the DPA, as proof of acceptance.
- API keys and MCP connector keys, if you enable the integration module: name, prefix, key hash, scopes, last IP address used.
- Support requests: the title, body and any attachments of the tickets you open from the dashboard, processed in our support system (see §4, section C).
2.2 Why we collect it
- Performance of contract (Art. 6.1.b): give you access to the platform, issue invoices, manage recurring payments, answer your support requests.
- Legal obligation (Art. 6.1.c): keeping invoices for 10 years, the period Art. 2220 of the Italian Civil Code sets for invoices themselves and for the accounting records that refer to them; applicable tax law (DPR 633/1972, D.Lgs. 127/2015) requires at least 7, so the longer civil-law period is the operative one.
- Legitimate interest (Art. 6.1.f) for security, fraud prevention, and diagnostics.
2.3 Shop retention
| Data | Retention |
|---|---|
| Shop profile, programs and locations while subscribed | For the whole duration of the subscription |
| After the subscription ends | A suspended subscription is cancelled after 60 days; 150 days after cancellation we send a notice that the data is about to be deleted; 180 days after cancellation the account is anonymised. Anonymisation removes the login name and email, password, second factor, passkeys, social identities, staff, devices, API keys, and the name, email and customer reference on every one of your customers' cards |
| Deletion requested by you | Carried out 30 days after the request, with the same anonymisation |
| What survives anonymisation | The shop row remains as a placeholder stripped of identifying data, because accounting records refer to it; the transaction ledger, the invoice copies (which by law name their recipient), the Stripe references and the audit events remain — the latter being themselves the proof that the deletion took place |
| Invoices | 10 years under Art. 2220 of the Italian Civil Code, which covers invoices themselves as well as the accounting records that refer to them; applicable tax law (DPR 633/1972, D.Lgs. 127/2015) requires at least 7, so the longer civil-law period is the one we apply. The DPA states the same period |
| Password hash, TOTP, recovery codes, passkeys | Erased on account closure |
| Access logs, sessions and audit events | No automatic expiry is in place; expired sessions are no longer valid but the row with its IP and user-agent remains |
| Support tickets | Kept in our support system; no automatic expiry is in place |
| Data export files you request from the dashboard | Produced as an archive and made available through a signed link valid for 48 hours. The archive stays in object storage until removed manually: no automatic expiry is in place |
2 bis. For visitors to this website and the dashboard
This website (tesserapp.eu) has no contact forms, collects no sign-ups and uses no statistics or tracking tool whatsoever: no Google Analytics, no Plausible, no Matomo, no pixel, no cookie. Every point of contact is an ordinary mailto: link.
What does get written into your browser, and why:
| Where | What | What it is for |
|---|---|---|
| This website | tesserapp-locale-redirect (session storage) | Remembering that you have already been routed to the right language version, so you are not bounced repeatedly |
| This website | tsa_promo_popup_dismissed (local storage) | Not showing you again a notice you have already closed |
| This website | vitepress-theme-appearance (local storage) | Remembering your light/dark theme choice |
| Shop dashboard | Session cookie tsa_sess (HttpOnly, SameSite=Lax, Secure in production, 30-day lifetime) | Keeping you signed in. It is the only cookie in the entire service |
| Shop dashboard | Local storage: language preference, table layout, notices already dismissed (two of these contain your shop's identifier), ticket read state | Remembering your interface preferences |
None of these serve to profile or track you, and none of them require prior consent.
The only network request this website makes from your browser is a read of our own API (api.tesserapp.eu/api/v1/app-config) to find out whether there is a notice to show: it sends nothing about you. The prices shown on the site are embedded at publication time, not requested by your browser.
The shop dashboard (app.tesserapp.eu), unlike this website, loads some third-party resources on every page: typefaces from Google Fonts and the Stripe.js payment library. Address autocompletion queries LocationIQ directly from the shop's browser. The detail is in §4.
3. Relationship between TesserApp and shops (GDPR)
When a customer activates a loyalty card at a shop, the shop is the data controller of that customer's data, and TesserApp is the data processor under GDPR Art. 28.
The relationship is governed by a Data Processing Agreement (DPA) which the shop accepts during signup. The DPA covers:
- Purposes and categories of data processed.
- Authorized sub-processors (see section 4).
- Technical and organizational security measures.
- Response times to data subject requests and to personal data breaches.
Shops that enable the integration module can extract their own customers' data from their programs, through our API or the MCP connector — including the name, email and customer reference on named cards — and carry it into their own systems or into third-party tools of their own choosing. From that point that processing is under their sole responsibility as controllers.
Customers can exercise their GDPR rights both with TesserApp and with the individual shop.
4. Who we share data with
We do not sell data to third parties. Ever. We do not share data for advertising purposes and we take part in no profiling network.
A. Sub-processors
Providers that process personal data on our behalf, under an agreement pursuant to GDPR Art. 28:
| Provider | Role | Data location |
|---|---|---|
| Contabo GmbH | VPS hosting of production systems | Germany |
| Stripe Payments Europe Ltd. | Shop payment processing and invoice issuance | EU / SCC |
| Cloudflare, Inc. | R2 object storage (program and access-card images, data-export files requested by shops), CDN | EU (explicit configuration) / SCC |
| Apple Inc. | Apple Wallet pass and push notification delivery (APNs); issuance of pass certificates and identifiers via App Store Connect | EU / SCC |
| Google LLC | Google Wallet pass and push notification delivery (Firebase Cloud Messaging) | EU / SCC |
| Unwired Labs (LocationIQ) | Address autocompletion in the shop dashboard. Engaged by us under Art. 28, but called directly from the shop's browser — see section B and §5 | see §5 |
B. Other third-party recipients
Services that receive data as the direct effect of a product feature, without passing through our servers:
| Recipient | What it receives, and when |
|---|---|
| Overpass (OpenStreetMap project) | On iOS, when you use the nearby-shops feature, the phone sends this public service your GPS coordinates to look up points of interest around you. It sends nothing else: no identifier, no card, no app data. On Android this code path is not currently reached by the app |
| LocationIQ (Unwired Labs) — also an Art. 28 sub-processor, listed in section A; it appears here because of HOW the data reaches it, not as a second relationship | When a shop types an address in the dashboard, the browser sends LocationIQ the text typed (and the country code, in the location forms). It does not send the shop's identity or any session data. The browser's IP address is implicit in every call |
| Google LLC (Google Fonts) | The shop dashboard's typefaces are loaded from fonts.googleapis.com and fonts.gstatic.com on every page: Google therefore receives the IP address and browser type of whoever opens the dashboard. This website loads no external fonts |
| Stripe, Inc. (Stripe.js) | The payment library is loaded on every page of the shop dashboard, not only on the billing pages: Stripe therefore receives the IP address and technical browser data even when no payment is under way. Payment card details are entered directly into Stripe-hosted fields and never pass through our systems |
| Apple Inc. and Google LLC (Sign in with Apple / with Google) | Only if a shop chooses to sign in with Apple or Google, and only for the sign-in operation |
| Apple Inc. and Google LLC (device backup, native wallets) | In their role as the providers of your account: see §1.7 |
C. Our own infrastructure
Components that may look like third-party services but are our own installations, on our own domains, with no data shared with the software's vendor:
| Component | Role |
|---|---|
glitchtip.radiobros.com | Collection of the apps' technical error reports |
helpdesk.radiobros.com | Support system (Zammad software) for shop tickets |
mail.tesserapp.eu | Sending of transactional email (invitations, alerts, service notices) |
cdn.woptima.com | Delivery of interface icons under our own licence, both to the browser and to our servers when they compose a Wallet pass. No personal data |
| Internal identity provider for administrative access | Authentication of the technical staff who access production systems |
| Central application-log collection | Diagnostics and security. Logs may contain IP addresses and the technical context of a request |
| Catalogue search index | Search over public programs. It holds shop program data, not customer data: no names, no emails, no cards |
The full list with addresses and contacts is in DPA Appendix A. Any new sub-processor is notified to shops at least 30 days in advance.
5. International transfers
All personal data we process on our own systems is hosted within the European Economic Area. Sub-processors with US operations (Stripe, Apple, Google, Cloudflare) have Standard Contractual Clauses (SCC) in place, approved by the European Commission.
For LocationIQ and for the Overpass service the request leaves the shop's browser or the customer's phone directly and reaches the provider without passing through our servers: the place of processing is the provider's own, and the transfer basis is stated in DPA Appendix A.
6. Security
Key technical and organizational measures:
- TLS 1.2+ in transit.
- AES-256 encryption at rest for objects stored on Cloudflare R2 (SSE). Application secrets (Wallet pass certificates, TOTP secrets) are encrypted with AES-256-GCM under a separate key.
- argon2id hashing for shop passwords, staff PINs and recovery codes. High-entropy random tokens (sessions, install tokens, invitations) are stored as SHA-256 hashes: their size makes a slower algorithm pointless. Push notification tokens and Wallet pass authentication tokens are stored as issued, because they must be replayed to the providers.
- Periodic database backups, kept on the production infrastructure with automatic rotation and an integrity check on every run.
- Role-based access control, with authentication through our internal identity provider, and audit logging on every administrative action.
- Annual penetration test — a commitment we have undertaken in our Data Processing Agreement (Appendix D.4), not a control already in place.
In case of a personal data breach we will notify affected data subjects and the competent supervisory authority (the Italian Data Protection Authority / Garante, as the authority for our establishment) within 72 hours of discovery, per GDPR Art. 33.
7. Changes to this policy
We may update this policy to reflect service or regulatory changes. The latest version is always posted here, with the last-updated date at the top. Material changes are notified by email to shops; for app customers the version published here is the one that applies.
Notice period. This policy sets no notice period of its own. Where a material change to this policy is also a material amendment to the DPA — because it concerns processing we carry out on a shop's behalf — the period and the procedure in DPA §15.2 apply: 30 days' notice by email and a request to re-accept. No individual notice is owed to app customers, and the app is not used as a channel for legal notices.
Entry into force of version 1.2. Version 1.2 takes effect on the publication date shown at the top of this page. The transitional provision at §15.2 bis of the DPA governs this policy as well: this revision corrects statements that were inaccurate and widens what is disclosed, rather than imposing new obligations. The 30 days' notice in DPA §15.2 remains intact for every future change.
8. Contact
- Controller: radioBros di Alberto Miconi
- Registered office: Via Ridolfino Venuti 30, 00162 Rome (Italy)
- VAT: Italian VAT number IT15127451001
- Email: privacy@tesserapp.eu (privacy and GDPR rights) · support@tesserapp.eu (general support)
- Lead supervisory authority: Italian Data Protection Authority (Garante per la protezione dei dati personali) — gpdp.it · Data subjects may also lodge complaints with their local supervisory authority.