Data processing agreement
Version 1.10, in force from 31 August 2026.
This is an agreement, and you enter into it by installing the app. It sets out what Ovation Upsell does with personal data on your behalf, and what it owes you in return. It is required by Article 28 of the GDPR, which says that a business processing personal data for another business has to do it under a contract rather than under a promise.
If you would rather read the plain-language version of what is stored and why, that is the privacy policy. This page is the contract. If the two ever disagree, clause 13.4 says this one wins.
Between
(1) Lucas Reygrobellet, entrepreneur individuel, established in Bernin (38190), France, registered under SIREN 853340305 (the Processor), who builds and runs Ovation Upsell. The full registered address is available on request under clause 13.7.
(2) You, the merchant who has installed the Ovation Upsell application in your Shopify store (the Controller).
Recitals
(A) The Controller operates an online store on the Shopify platform.
(B) The Processor makes available a Shopify application, Ovation Upsell, which presents an additional product offer to a shopper who has completed a purchase in the Controller’s store, and reports to the Controller on what those offers did (the Service).
(C) In providing the Service the Processor processes a limited quantity of personal data on behalf of the Controller. This agreement governs that processing and is entered into under Article 28(3) of Regulation (EU) 2016/679.
(D) This agreement is the whole of the agreement between the parties in respect of the processing of personal data. It stands on its own and does not depend on any other contract between the parties.
1. Definitions
1.1 Applicable Data Protection Law means Regulation (EU) 2016/679 (the GDPR); the UK GDPR and the Data Protection Act 2018, where the Controller is established in the United Kingdom or the processing is subject to them; and the Swiss Federal Act on Data Protection, where the Controller is established in Switzerland or the processing is subject to it.
1.2 Controller, Processor, Data Subject, Personal Data, Personal Data Breach, Processing and Supervisory Authority have the meanings given to them in the GDPR.
1.3 Merchant Personal Data means Personal Data that the Processor processes on behalf of the Controller in providing the Service, as described in Annex 1.
1.4 Sub-processor means a third party engaged by the Processor to process Merchant Personal Data on the Processor’s behalf.
1.5 Shopify means the operator of the Shopify platform, being the Shopify entity that contracts with the Controller for that platform.
2. Roles of the parties
2.1 The parties agree that, in respect of Merchant Personal Data, the Controller is the controller and the Processor is a processor.
2.2 The Processor does not determine the purposes of the processing. It processes Merchant Personal Data only to provide the Service to the Controller and for no purpose of its own. In particular the Processor does not sell, share or otherwise make Merchant Personal Data available to any third party for that third party’s own purposes, does not use Merchant Personal Data to build any profile of any Data Subject, does not use it to train any model, and does not aggregate it across merchants for any purpose.
2.3 Shopify is not a Sub-processor of the Processor. Shopify processes the Controller’s data under the Controller’s own agreement with Shopify, and the Processor receives Merchant Personal Data from Shopify at the Controller’s direction, given when the Controller installs the Service and grants it access scopes.
3. Subject matter and duration
3.1 The subject matter, duration, nature and purpose of the processing, the types of Personal Data and the categories of Data Subject are set out in Annex 1, as required by Article 28(3).
3.2 This agreement applies for as long as the Service is installed in the Controller’s store, and thereafter for as long as the Processor retains any Merchant Personal Data under clause 10.
4. Processing on documented instructions
4.1 The Processor processes Merchant Personal Data only on documented instructions from the Controller, including as regards transfers to a third country, unless required to do otherwise by Union or Member State law to which the Processor is subject. Where such a law applies, the Processor informs the Controller of that legal requirement before processing, unless that law prohibits the informing on important grounds of public interest.
4.2 The Controller’s documented instructions are: this agreement, the configuration the Controller makes in the Service (the offers it writes, the settings it chooses, the access scopes it grants at installation), and any further instruction the parties agree in writing.
4.3 The Processor informs the Controller if, in its opinion, an instruction infringes Applicable Data Protection Law.
5. Confidentiality
5.1 The Processor ensures that any person authorised to process Merchant Personal Data is bound by an obligation of confidentiality, whether by contract or by a statutory duty of confidentiality.
6. Security
6.1 The Processor implements appropriate technical and organisational measures to ensure a level of security appropriate to the risk, taking into account Article 32(1)(a) to (d). The measures in place are described in Annex 2.
6.2 Annex 2 describes the measures actually in place. It is not aspirational, and it names the measures that are not in place.
6.3 The Processor may update the measures in Annex 2 provided the level of security is not reduced.
7. Sub-processors
7.1 The Controller gives the Processor general written authorisation to engage Sub-processors, subject to this clause.
7.2 The Sub-processors engaged today are listed in Annex 3 below, which is dated, so that the Controller can see the list change.
7.3 The Processor gives the Controller at least 30 days’ notice of any intended addition or replacement of a Sub-processor, by updating Annex 3 on this page and by a notice on the Service’s home screen in the Controller’s Shopify admin. Notice is not given by email, because the Service does not hold a contact address for the Controller and asking for one would add personal data the Service does not otherwise need.
7.4 The Controller may object to a new Sub-processor on reasonable data protection grounds, in writing to support@rgbl.dev, within those 30 days. The parties will then discuss the objection in good faith. If it is not resolved within 30 days of the objection, the Controller may terminate this agreement by uninstalling the Service, and the Processor will refund any prepaid subscription covering the period after uninstallation.
7.5 Where the Processor engages a Sub-processor, it imposes on that Sub-processor, by contract, data protection obligations no less protective than those in this agreement, and remains fully liable to the Controller for that Sub-processor’s performance. The Processor holds each current Sub-processor’s own data processing addendum and provides it on request.
8. Assistance with data subject rights
8.1 Taking into account the nature of the processing, the Processor assists the Controller by appropriate technical and organisational measures, insofar as possible, in fulfilling the Controller’s obligation to respond to requests to exercise Data Subject rights under Chapter III of the GDPR.
8.2 The Service implements Shopify’s mandatory privacy webhooks, and they are the Controller’s primary route because they run without the Controller having to write to the Processor at all. On customers/data_request the Processor describes what it holds for the orders the request names. On customers/redact the Processor erases the identifiers it holds for the orders the request names, and removes the checkout reference from the records behind them, leaving a count with nothing in it that points at anybody; where the Controller has approved read_all_orders, that includes an order the Processor holds no identifier for, whose checkout it asks Shopify for at that moment. On shop/redact the Processor erases everything it holds for the Controller’s store.
8.3 The Processor promptly notifies the Controller of any request it receives directly from a Data Subject relating to the Controller’s data, and does not respond to that request itself except to direct the Data Subject to the Controller.
9. Security incidents, breaches and impact assessments
9.1 The Processor assists the Controller in ensuring compliance with Articles 32 to 36 of the GDPR, taking into account the nature of the processing and the information available to the Processor.
9.2 The Processor notifies the Controller of a Personal Data Breach affecting Merchant Personal Data without undue delay and in any event within 48 hours after becoming aware of it, and provides the Controller with the information it has, so that the Controller can meet its own obligation under Article 33. Forty-eight hours is deliberately shorter than the Controller’s own 72 hour deadline, so that a notification from the Processor does not consume the Controller’s window.
9.3 The Processor provides the Controller, on request, with the information reasonably necessary for a data protection impact assessment relating to the Service.
10. Deletion and return
10.1 At the Controller’s choice, the Processor deletes or returns all Merchant Personal Data at the end of the provision of the Service, and deletes existing copies, unless Union or Member State law requires storage.
10.2 In practice: on uninstall the access token is deleted at once, the Controller’s offers are turned off and kept until shop/redact, and its plan row is reset to the free plan, keeping only the store’s date of first installation and whether it is a development store. Forty-eight hours after an uninstall Shopify sends shop/redact and everything else the Processor holds for that store, the plan row included, is deleted. Independently of both, the record of a post-purchase page and the order reference beside it are deleted 730 days after they are written, by a job that runs daily whether or not anybody asks.
10.3 Backups. The server on which the Service runs is subject to an automated snapshot taken by OVHcloud once a day, of which one is retained at a time. A deletion under clause 10.1 or 10.2 removes data from the live database immediately, and a copy may persist in the most recent snapshot until that snapshot is replaced by the next one, ordinarily within 24 hours. The Processor does not restore a snapshot other than to recover from a failure of the server, and where it does, it re-applies any deletion that had taken effect before the snapshot was restored.
11. Information and audit
11.1 The Processor makes available to the Controller all information necessary to demonstrate compliance with Article 28.
11.2 The Processor answers a written security and data protection questionnaire from the Controller once in any twelve month period, within 30 days of receiving it, and provides on request the data processing addenda and any certifications or audit reports it holds from its Sub-processors.
11.3 An on-site inspection is available where a Supervisory Authority requires one, or where a Personal Data Breach affecting the Controller has occurred. Such an inspection takes place on 30 days’ written notice, during business hours, no more than once in any twelve month period, under an obligation of confidentiality, and at the Controller’s cost.
12. International transfers
12.1 Merchant Personal Data is stored and processed on a single virtual server located in Strasbourg, France, in the European Union.
12.2 The Processor does not transfer Merchant Personal Data outside the European Economic Area. No standard contractual clauses and no adequacy decision are relied on for the Service itself. No UK international data transfer addendum and no Swiss addendum are attached, because none is needed: the United Kingdom’s adequacy regulations recognise the EEA states and the Swiss Federal Council’s list of countries with adequate protection includes them, so France is not a restricted destination from either.
12.3 Correspondence sent to support@rgbl.dev, which is the address given in this agreement for data protection questions and requests, is delivered through Cloudflare’s email routing and may transit outside the EEA. Cloudflare’s own data processing addendum, including its transfer terms, applies to that routing. The Processor asks that Personal Data not be sent to that address beyond what is necessary to identify a request.
12.4 The Processor informs the Controller before any change to clauses 12.1 to 12.3.
13. General
13.1 Formation. This agreement takes effect between the parties when the Controller installs the Service in its Shopify store, and applies to all processing of Merchant Personal Data by the Processor from that moment. It is published at this address, is linked from the Service’s privacy policy and from its Shopify App Store listing, and installing or using the Service constitutes the Controller’s acceptance of it. A Controller who requires a signed counterpart may request one at support@rgbl.dev.
13.2 Liability. Each party’s total aggregate liability arising out of or in connection with this agreement is limited to the greater of (a) the total fees paid by the Controller for the Service in the twelve months preceding the event giving rise to the claim, and (b) one hundred euros. This limit does not apply to liability for wilful misconduct or gross negligence, and nothing in this agreement limits or excludes any liability that cannot be limited or excluded by law, including a Data Subject’s rights under Article 82 of the GDPR or either party’s liability to a Supervisory Authority.
13.3 Governing law and jurisdiction. This agreement is governed by French law. The parties submit to the exclusive jurisdiction of the French courts.
13.4 Precedence. In the event of a conflict between this agreement and the privacy policy, this agreement prevails as between the parties. The privacy policy remains the plain-language description of what the Service stores and is written to be read rather than construed.
13.5 Changes. The Processor may amend this agreement where required by a change in Applicable Data Protection Law or in the Service, on 30 days’ notice given the way clause 7.3 gives notice. A Controller that does not accept the change may terminate by uninstalling the Service, with the same refund as clause 7.4. The version number and the date at the top of this page are what say which version is in force.
13.6 Supervisory authority and representative. The Processor’s lead Supervisory Authority is the Commission nationale de l’informatique et des libertés (CNIL), 3 place de Fontenoy, 75007 Paris, France. No representative is appointed under Article 27, and none is required, because the Processor is established in the European Union.
13.7 Contact, and the Processor’s full address. Everything in this agreement that asks the Controller to write to the Processor is answered at support@rgbl.dev. The Processor’s full registered address is provided to any Controller who requests it at that address.
Annex 1. Details of the processing
Required by Article 28(3).
Subject matter. Provision of the Ovation Upsell application to the Controller.
Duration. For as long as the Service is installed, plus the retention periods in clause 10.2.
Nature of the processing. Collection, storage, structuring, consultation, use and erasure, by automated means, for the purposes below.
Purposes.
- Presenting a post-purchase product offer to a shopper in the Controller’s store, and recording what that offer did.
- Reporting to the Controller, on the Analytics page, on what its offers did.
- Allowing the Controller to look up one of its own orders by its number and see whether the Service offered anything on it, and why.
- Keeping the Controller’s own test orders out of the Controller’s figures.
- Choosing, for each order, the product a best-pairing offer presents on the post-purchase page, from how often the Controller’s products are bought together in its own paid orders, the complementary products its Search & Discovery settings list, the related products Shopify recommends where the Controller has granted that permission, and the products the shopper who placed the order bought in that store over the last year (the last sixty days where the Controller has not approved Shopify’s
read_all_orderspermission), with the dates they bought them, and how long the Controller’s shoppers usually wait before buying a product again.
Categories of Data Subject. Shoppers who complete a purchase in the Controller’s store and are shown, or could have been shown, a post-purchase offer. Also the Controller’s own staff, to the extent a Shopify session identifies them.
Types of Personal Data. The Processor holds no direct identifier of any shopper. It has not requested, and Shopify therefore redacts, the four protected customer fields: name, address, email and phone. What it holds that could relate to a person, however indirectly, is:
| What | Stored or read live | Why |
|---|---|---|
| The post-purchase page’s own reference, being the Shopify checkout token | Stored | Ties a page the Service answered to the order it belonged to |
| The order number and the confirmation number Shopify’s Thank you page shows | Stored | So the Controller can find an order in the app by its number |
| The Shopify order id, as it appears in the address of the order’s page in the Controller’s admin | Stored | Written when the Controller looks an order up itself |
| The date the order was placed, and whether the Controller marked it a test order; what it came to before any upsell, and what it came to in all; its subtotal after discounts, its shipping, the price of each shipping line before and after its discounts, any tip, any additional fees, its taxes and whether its prices include tax, and whether duties were charged on it; which of the Controller’s products were on it, which variant, how many of each, at what price, and whether each was bought on a subscription; the tags the Controller gave it, whether it has been paid, and the sales channel it came through; the payment providers it was paid through, and whether payment was made with a wallet, in installments or by a manual method; the store’s currency and the currency it was paid in; and the note the Service’s own button adds to an order placed through it | Read live, not stored | Shown on the Orders page while the Controller is looking at that order, to say whether the Service offered anything on it and why (purpose 3) |
| The shopper’s country and IP address, only where the Controller has turned on Exact prices in other currencies | Read live, passed to Shopify, not stored | Shopify prices a one-product cart in the shopper’s market with the offer’s code, so a fixed-amount offer on an order paid in another currency shows the price checkout charges; Shopify asks for the address to protect the store from bots |
The customer reference Shopify gives the post-purchase page, and the products and dates of that shopper’s orders in the store from the last year (the last sixty days until the Controller approves read_all_orders), only when the post-purchase page reaches a best-pairing offer, or an A/B test in which either version sells the best pairing (on both versions’ pages, so the two are judged on the same orders), and the free plan has not put the Controller’s offers on hold | Read live from Shopify; the reference, those orders and the list of their products are not stored | To choose again, as the post-purchase page opens, the products the offer presents (purpose 5); the products on the first five lines of up to twenty of those orders, and the date of each order, are read, and if Shopify does not answer within 400 milliseconds, nothing is changed and the page shows the products it was first given, chosen without them |
| Which of the Controller’s products a best-pairing offer chose for a post-purchase page, and the signal that chose it, which can be that it came from that shopper’s earlier orders | Stored, on the page’s record and on its accept | So a page asked twice, and its accept, are served the same product, and so the Controller can see what the offer did and why (purposes 1, 2, 3 and 5) |
| Which of the Controller’s products a post-purchase page left out as it opened because that shopper had bought them before, each of which says that shopper bought it; and, where the products changed as the page opened, which products and terms the page had been given first | Stored, on the page’s record | So the Thank you and Order status pages do not offer those products either, and so a page that did not wait for the change can still be paid for at the terms it showed (purposes 1 and 5) |
| The checkout reference of the order whose Thank you or Order status page carried the Service’s button, with a signature by the Service, in the note that button adds to the order it opens; and, once that order is paid and the signature checks out, which of the Controller’s offers and which variant were bought through it, filed under that earlier checkout reference, with no amount | Stored: the note by Shopify, on the order in the Controller’s store; the record by the Service | So the earlier order’s Thank you and Order status pages do not offer again a product just bought through the button (purpose 1) |
| Whether Shopify cancelled the order, and when, from Shopify’s notice of the cancellation, kept beside the order’s checkout reference and order id | Stored | So the Thank you and Order status pages offer nothing on a cancelled order (purpose 1) |
| The Controller’s shop domain and its Shopify access token | Stored | So the Service can read products when nobody is signed in |
Also stored, and not personal data of a shopper, but listed so the annex is complete: the Controller’s offers and a cached copy of the product details in them, its settings and styling, the mapping of its products to its collections and to the tags and product types its offers name, the results of its ended A/B tests, its plan and any discount code, one counted row per post-purchase page the Service answered, and, for purpose 5, how many of its paid orders held each of its products and each two of them together (product ids, counts and the date of the last such order, a weight that ranks recent orders higher, and how many of its paid orders were counted in all, with no order identifier and nothing about a person), how long its shoppers usually wait before buying each of its products again (product ids, numbers of days and counts, with no shopper, order or checkout), a copy of its products (title, handle, picture, the first 500 characters of the description, type, vendor, status, up to twenty variants with price and availability, the products its Search & Discovery settings list as complementary, and, where the Controller has granted the optional product listings permission, the products Shopify recommends as related), and the delivery reference of each paid-order notice Shopify sends, so that a notice sent twice is counted once.
Retention. As set out in clause 10.2. The record of a post-purchase page and the order reference beside it are deleted 730 days after they are written. The access token goes on uninstall, the offers are turned off then, and the plan row is reset then. A count of products bought together is deleted once the last order it counts was placed 730 days ago, the usual wait before a product is bought again 730 days after its last repeat purchase was counted, and with its product, and the delivery reference of a paid-order notice after seven days. Everything else is kept while the Service is installed and for the forty-eight hours after an uninstall, and goes on shop/redact.
Annex 2. Technical and organisational measures
Article 32. This annex describes what is in place, and names what is not. A security annex that promises a control the server does not have is worse than one that omits it, because it is a representation the Controller relies on.
In place
- Encryption in transit. The Service is reachable only over HTTPS, on a certificate issued by Let’s Encrypt. Calls to Shopify’s Admin API are over HTTPS. The post-purchase and Thank you page extensions reach the Service over HTTPS and authenticate with a Shopify-signed token.
- Authentication. The admin side of the Service is reachable only through Shopify’s embedded app framework, and authenticates every request with Shopify’s own session tokens. The Service sets no sign-in cookie of its own.
- Minimisation by design. The Service holds four read-only access scopes (the customer one used for a customer’s id alone), plus two optional Storefront scopes only where the Controller grants them, and has never requested a protected customer field, so Shopify redacts name, address, email and phone from every reply and every webhook it sends.
- No third party in the runtime path. The Service loads no analytics, no advertising, no error-reporting service and no third-party embed, in the Controller’s admin or on any page a shopper sees.
- Single tenant server. The Service runs on one virtual server dedicated to it. The database is a file on that server’s disk, readable only by the application’s own process user, and is not exposed on any network port.
- Erasure that runs whether or not anybody asks. A job inside the application deletes expired rows daily, and Shopify’s three privacy webhooks are implemented.
Encryption at rest, item by item
Four things could be encrypted where they are stored. This is which of them are, today, and what stands in the way of the rest.
- Shopify access tokens: encrypted. The access token and refresh token the Service holds for each store are encrypted with AES-256-GCM before they are written, using a key held outside the application directory in a file readable only by the server's administrator.
- Order identifiers: encrypted. The order number, the confirmation number and the order id the Service keeps so that you can look an order up are encrypted with AES-256-GCM before they are written, using the same key. They are encrypted in a way that still lets the Service find an exact match, so looking an order up by its number works as it did.
- Checkout references: encrypted. The reference that ties a post-purchase page to its order is encrypted the same way. One thing changed for you when it was: the Orders page used to find an order from a fragment of a reference, and now it needs the whole one. Every other way of finding an order, by its number, its confirmation number or the address of its page in your admin, works as it did.
- The disk the database sits on: not encrypted. The volume itself is not encrypted. Whether OVHcloud encrypts the underlying storage beneath its hypervisor is OVHcloud's to state.
Where something above is encrypted, the key that decrypts it is held on the same server as the data. That protects a copy of the database that leaves the server on its own, and it does not protect a disclosure of the whole server, because a snapshot of the server contains the key alongside the data.
Not in place, stated rather than omitted
- Encrypted backups. The daily snapshot is taken by OVHcloud and its encryption at rest is OVHcloud’s to state, not the Processor’s.
- An access log to personal data. There is none.
Annex 3. Sub-processors
This list is current as of 31 August 2026. Clause 7.3 is how it changes.
| Party | What it does | Where | Sub-processor? |
|---|---|---|---|
| OVHcloud | Hosts the single virtual server the Service runs on, and takes its daily automated snapshot | Strasbourg, France | Yes |
| Cloudflare | DNS for the rgbl.dev zone, and the email routing that delivers mail sent to support@rgbl.dev | Global | Yes, for support and rights correspondence only. No request to the Service passes through it: the DNS records are unproxied on purpose |
| OVHcloud (MX Plan) | The mailbox that Cloudflare’s routing forwards support@rgbl.dev into | Per OVHcloud | Yes, for support and rights correspondence only |
| Shopify | The platform the Controller uses, the source of every piece of data the Service receives, and the host of the extension bundles a shopper’s browser loads | Per the Controller’s own agreement with Shopify | No. Shopify processes the Controller’s data under the Controller’s own contract with Shopify. It is not appointed by the Processor. See clause 2.3 |
| Let’s Encrypt | Issues the TLS certificate | Global | No. It sees a hostname and no personal data |
There is nothing else. No analytics provider, no advertising network, no data broker, no error-reporting service, no model provider, and no content delivery network in front of the Service.