Prescription Upload and Pharmacist Validation for PrestaShop: documentation
Install the module, define regulated products, set up the workflow and handle prescriptions, messages and QR codes in the back office.
How it works
You decide which products are regulated. When a customer adds one to the cart, a “Prescription and pharmacist validation” block appears under the cart. The customer uploads the prescription there, then orders. The order stays in the Awaiting pharmacist validation status until the pharmacist decides in the back office. Documents are encrypted on your server and never served directly by the web server.
- Prescription required: a document must be uploaded before ordering.
- Pharmacist review: no document required, but the order is checked before shipping.
- Free sale: no validation, only the maximum quantity per order applies. On a product, this mode also excludes it from the rule of its category.
Selling prescription medicines online is forbidden in several countries, France among them, and a prescription contains health data that may require certified hosting (HDS in France). The module provides the technical tools; sales authorisation and hosting remain your responsibility.
Requirements
- PrestaShop 8.0 to 9.x.
- PHP
opensslextension (checked at installation). - An hourly cron task, recommended for reminders, alerts and purge.
- HTTPS on the shop.
Installation
- In Modules > Module Manager, click Upload a module and send the ZIP.
- The module creates the Awaiting pharmacist validation order status, the encrypted storage folder and two menus: Orders > Prescriptions and Orders > Prescription rules.
- Open the module configuration: the Status panel tells you whether the storage folder is ready and protected against direct access.
Define regulated products
Menu Orders > Prescription rules, button Add a rule:
- Applies to: a product (search by name, reference, EAN or ID) or a category and its subcategories.
- Mode: prescription required, pharmacist review or free sale.
- Maximum quantity per order: per product, all combinations added up. Checkout is blocked above it. 0 means no limit.
A product rule always wins over category rules. When a product belongs to several regulated categories, “Prescription required” wins over “Pharmacist review”, and the smallest maximum quantity applies.
A product rule can also be set from the Modules tab of the product page. It is saved immediately, without saving the product.
Module settings
Validation workflow
- After the order (default): the customer pays, then the order waits for validation. A refusal means refunding the customer from the order page.
- Before payment: the signed-in customer sends the cart to the pharmacist and can only pay after approval. If the cart changes after approval, it has to be sent again.
Documents
- Accepted types: PDF, JPEG, PNG, WebP. The real type is checked from the file signature, and PDFs containing JavaScript, launch actions or attachments are rejected.
- Maximum file size (8 MB by default) and maximum files per request (5 by default).
- Reuse of validated prescriptions: a signed-in customer can attach an approved prescription to a new cart until its validity date.
- Default validity (90 days): prefilled in the validation form.
- Consent text, per language: the customer must tick the box before each upload.
Health questionnaire
When enabled, it asks for the patient (self or someone else), age, weight, height, sex, pregnancy or breastfeeding, allergies, current treatments and medical history. Checkout waits for the answers. They are encrypted and prefilled on the next order for a signed-in customer.
Reminders and delays
- Customer reminder (2 days): reminder email when the customer has not answered a request for information.
- Automatic cancelation (10 days): the request is refused with the reason “No answer from the customer”.
- Pharmacist alert (24 hours): summary of the requests and customer messages waiting longer than the delay.
0 disables each feature.
Notifications and statuses
- Pharmacist notification emails: one or more addresses separated by commas.
- Status of refused orders: Canceled by default, which restocks the products.
- Saved replies: one per line and per language, inserted in one click in a message or a decision.
Storage and retention
- Storage folder:
var/dfprescription/by default. An absolute path outside the web root is recommended. It can no longer be changed once documents are stored. - Document retention (365 days): files are deleted after this delay, except for requests still in progress and prescriptions still valid. Metadata and the audit log are kept.
Customer journey
- The product page shows a badge: prescription required, pharmacist review or limit per order.
- In the cart, the customer drops documents or takes a photo with a phone, ticks the consent box, fills in the questionnaire if needed and can leave a note for the pharmacist.
- While something is missing, links to the checkout are disabled and opening the order page directly sends the customer back to the cart with a message.
- After ordering, the confirmation page, the order detail and the My prescriptions page of the account show the request status. Guests follow their request through a private link sent by email.
Handle a request
Menu Orders > Prescriptions. The list shows the status, the number of documents and unread messages, with counters at the top. A request page brings together:
- the documents in a viewer (embedded PDF, images with rotation and zoom), with open and download buttons;
- the customer, the order or orders, the products concerned and their rule;
- the health questionnaire answers, with risk points highlighted;
- the message thread with the customer;
- the decision form and the audit log.
Decide
- Validate: set the prescription validity date. The order returns to the status it had before the hold, for example Payment accepted.
- Ask for information: the message is required. The customer receives an email and answers from the account or the private link.
- Refuse: choose a reason. The order moves to the status configured for refusals.
The pharmacist’s name and professional number (RPPS in France) are saved with each decision and remembered for the employee. An internal note, never shown to the customer, can be added to each request.
If a payment module changes the status of an order on hold (a payment webhook, for example), the module records that status and puts the order back on hold. A manual change by an employee is respected and logged.
Customer ↔ pharmacist messaging
Each request has its own message thread, encrypted like the documents. The pharmacist answers from the request page, inserting a saved reply if needed. The customer receives the text by email and replies from My prescriptions. The pharmacist is notified by an email that does not contain the message, only a link to the request. Customers are limited to 20 messages per day and per request.
QR code of electronic prescriptions
When a request is opened, the QR code of each document is read in your browser, from images and from the first 3 pages of PDFs. The E-prescription QR code box shows:
- the detected identifier and the full content of the QR code;
- an alert when the same prescription was already sent in another request of the shop, with “other customer” when relevant;
- a field to type the number manually when the QR code cannot be read, and a button to read it again.
Only certified pharmacy software can query the official e-prescription services. The module prepares the check and detects reuse; the pharmacist then verifies the identifier in the pharmacy software.
Scheduled task
The module configuration shows the cron URL. Call it every hour:
0 * * * * curl -s "https://your-shop.com/module/dfprescription/cron?key=YOUR_KEY" >/dev/null
It sends reminders and alerts, cancels unanswered requests and purges expired files. Without cron, these tasks run at most once an hour when the Prescriptions page is opened.
Security and compliance
- AES-256-GCM encryption of documents, questionnaire answers, messages and QR code content. The key is derived from a secret of the module and from the shop
_COOKIE_KEY_. - Audit log of each upload, view, download, message and decision, with the IP address.
- CSV export of the register from Orders > Prescriptions (button Export the register), without documents or health answers.
- Works with the official GDPR module: customer data export includes the requests, and deleting a customer erases documents and messages.
When migrating, keep the shop _COOKIE_KEY_ and the DFPRESCRIPTION_KEY configuration value. Without either of them, stored documents can no longer be decrypted.
Troubleshooting
The Status panel says the folder can be reached from the web
Files stay encrypted, but nginx ignores the .htaccess file. Add a deny all rule on the folder or choose a folder outside the web root.
The customer does not see the prescription block
Check that a rule covers the product or one of its categories, and that your theme displays the displayShoppingCartFooter hook on the cart page.
The QR code is not read
The QR code must be sharp and fully visible. Use Read again after receiving a better photo, or type the prescription number manually.
Uninstallation
Uninstalling permanently deletes all stored documents and the module tables. The dedicated order status is hidden but kept for the order history. Export the register before uninstalling if you need to keep a record.