Skip to main content

PrestaShop Integration (early access)

Early access

The PrestaShop integration is in early access. It has not yet been verified on a live store in production. The data sync, storefront tracking, in-app messages, web push, coupon codes and website forms are built; the Addons marketplace listing comes later - see Not available yet.

Connect a PrestaShop 8 or 9 shop with the Joryio module. Customers, orders, refunds, products and carts sync to Joryio, abandoned carts get a restore link, newsletter consent follows the shop, shoppers' visits are tracked and attributed to your campaigns, in-app messages and web push reach your storefront, and coupon programs create personal codes in the shop.

What syncs​

DataDetails
CustomersRegistered customers, and guest checkouts by their email. A guest is never stored as a PrestaShop customer number on a contact.
OrdersStatus, totals, products, addresses, every coupon code with the discount it gave, campaign attribution and currency. Orders in a cancelled or payment error state send one Order Cancelled; each credit slip sends one Order Refunded with its amount.
ProductsName, description, price (tax included, with sale price), brand, GTIN, categories, images, features, combinations and stock. Stock and price changes feed catalog triggers.
CartsCarts as customers shop, and abandoned carts with a signed restore link.
Newsletter consentThe customer's newsletter subscription. See Marketing consent.
Storefront eventsPage, product, category, search and cart views, add to and remove from cart, checkout started and the email a shopper types. See Storefront tracking.
Website formsThe contact form and forms of other modules, mapped on the module page (module 1.2.0). See Website forms.

On connect, Joryio imports existing customers, products and orders (the last 90 days by default) through the PrestaShop Webservice. After that the module sends changes as they happen.

Not available yet​

The PrestaShop Addons marketplace listing comes in a later release. Until then, install the module from the zip in Joryio.

Requirements​

  • PrestaShop 8.0 or later, or 9.x (PrestaShop 1.7 is not supported)
  • The PHP version your PrestaShop version requires (PrestaShop 8: PHP 7.2.5 to 8.1; PrestaShop 9: PHP 8.1 or later)
  • The shop reachable from the internet over https at a public address, its final one (no redirect). Joryio always calls https:// and refuses private or internal addresses and redirects
  • Outbound HTTPS from your server to Joryio
  • A cron job on your server is recommended - see Cron

Setup​

Step 1: Get your Server URL and API key​

  1. In Joryio, go to Integrations → PrestaShop
  2. Copy the Server URL
  3. Click Generate API key and copy the key (it starts with jry_ps_)

Step 2: Install the module​

  1. Download the module with Download module on the PrestaShop page in Joryio (joryio-prestashop.zip)
  2. In your PrestaShop back office, go to Modules → Module Manager → Upload a module and drop the zip there

Step 3: Connect​

  1. Open the module (Configure)
  2. Paste the Server URL and the API key
  3. Click Connect

The module turns the PrestaShop Webservice on and creates a Webservice key for Joryio - you do not create one by hand. Joryio checks that the key really belongs to your shop before it connects: the key must open protected shop data, and the same request without the key must be refused. Then the initial import starts.

The module creates a fresh Webservice key on every Connect. It can only read (GET) the data Joryio syncs - never the shop's configuration - and, from module 1.1.0, create, change and delete cart rules, which is how Joryio makes the codes of your coupon programs. Nothing else can be written with it. If Joryio refuses the connection, the module deletes that key again and, if it was the module that turned the Webservice on, turns it back off.

Multistore​

With multistore, each shop connects on its own. Open the module with that shop selected in the shop context and use the API key of the Joryio workspace the shop belongs to. A shop can be connected to one workspace only: connecting it to a second one shows "This store is already connected to another Joryio workspace." Disconnect it there first.

A workspace also holds one shop: connecting a second shop with the same workspace's key is refused ("This Joryio workspace is already connected to another PrestaShop shop..."). Give each shop its own workspace and use that workspace's key.

Cron​

The module keeps events in a queue in your shop's database and sends them in the background. The module page shows a cron URL with a secret token. Add it to your server's crontab so it runs every minute, for example:

* * * * * curl -fsS "<cron URL from the module page>" > /dev/null

Without a cron job the module also sends during normal store traffic, so events still arrive - but on a quiet shop they can be delayed.

Delivery and retries​

An event is not lost when Joryio cannot be reached for a while:

  • Joryio unreachable or busy - the queue pauses and tries again after growing pauses (1 minute, doubling up to every hour) for up to 7 days, keeping the order of events for each order, cart and customer.
  • An event Joryio refuses (for example, invalid data) is set aside at once, so it never holds up the others.
  • Joryio refuses the API key - delivery stops and the module page shows a notice. The events are kept: paste the current key and click Connect.
  • Events that could not be delivered are kept for 30 days. The module page shows how many events are waiting and not delivered, with the last error, and Retry now sends them again.

Scheduled reconciliation​

Live updates (the module) can be lost - for example while the store is offline, or when a delivery fails too many times. Every 6 hours Joryio checks the store for what changed since its last check and fills in what live updates missed: orders, credit slips (refunds), order status changes, customers, products, and carts of the last 24 hours.

Nothing is counted twice: an item Joryio already holds at the same or a newer version is left alone, and an older copy never overwrites a newer one.

  • A missing order placed in the last 24 hours is recorded as if it had arrived live, so post-purchase journeys still start. An older missing order, and a refund or cancellation of an order Joryio already had, are recorded without starting journeys; Order Refunded and Order Cancelled are still recorded once each.
  • Each store is checked at its own time, so stores are not all read at once, and one check reads a limited number of changes; a store with more changes continues within half an hour.
  • Stores that are disconnected, in error or still syncing are skipped until they are connected again.

The result is shown in Settings → Integrations → PrestaShop: Last reconciliation: 22/10/2026 12:00 - items filled in: 3. If the checks keep finding changes that never arrived live, Joryio raises a Live updates from PrestaShop may be failing alert (bell, Logs & Monitoring, and an email to workspace admins). The missing data is filled in either way, but check the store connection: journeys that react to those changes start late.

The same page shows Last event received - when a live update from the store last reached Joryio (at most a minute behind) - and Last sync, the later of the last full sync and the last reconciliation. A store that sends live updates moves Last event received even when no sync has run.

Refunds and cancellations​

Each credit slip on an order becomes one Order Refunded event with the slip's amount. An order moved to a cancelled state (or payment error) becomes one Order Cancelled. Joryio reads which states mean "cancelled" and "refunded" in your shop when the module connects, so renamed states still count. See Refund and cancellation events.

The customer's PrestaShop newsletter subscription is applied to the contact's email subscription:

In PrestaShopIn Joryio
Subscribed (newsletter box at registration or in the account, the newsletter block, the back office)Subscribed to email, with the date PrestaShop recorded.
Unsubscribed after being subscribedUnsubscribed from email - unless Joryio recorded a later change for that contact.

Proof recorded (module 1.2.17): a newsletter box on an order or the registration form also records the shopper's IP address and the page (the checkout or the registration page) on the consent entry - for an order, the address PrestaShop recorded for the shopper's visit. The IP address is shown only to team members who can see personal data, is included when the person asks for their data, and is removed when their data is erased.

The initial import subscribes customers PrestaShop lists as subscribed; it never unsubscribes anyone, because "not subscribed" can also mean "never subscribed". The partner offers box (optin) is not marketing consent for Joryio and is ignored.

Someone who unsubscribed is not re-subscribed by a PrestaShop newsletter opt-in (the account, the registration form, the newsletter block or the back office): they can resubscribe themselves through the preference center. The one exception is the newsletter box ticked at a guest checkout, and only when Let checkout opt-ins re-subscribe people who unsubscribed is on (on the PrestaShop page in Joryio) - see What a store opt-in or opt-out does. Storefront tracking never changes consent: an email a shopper types is only used to recognise the visitor.

PrestaShop's own "Sign up for our newsletter" box is part of the checkout's personal information step. PrestaShop saves it on the customer when the shopper continues past that step, so the module sends it to Joryio then - before the order is placed. There is no "only when the order is placed" option, and nothing is sent when the page renders. The box and its text are PrestaShop's own; the module never pre-ticks it.

Module 1.2.8 or later - the same rule as Record consent immediately on Magento and WooCommerce:

ShopperWhat a tick before the order does
A known buyer (Joryio has an order from the contact) or someone already subscribed to email or SMSCounts at once: subscribed.
A new guest (also a shopper who creates an account on the checkout step)Held as pending: the tick is recorded (time, store, checkout, the shopper's IP address), but the contact is not subscribed and gets no marketing - an abandoned-cart reminder is skipped as Awaiting confirmation. Their own order with the box ticked subscribes them, and so does a click on the confirmation email if you turn it on.
Someone who unsubscribed and has not orderedStays unsubscribed. Their order then follows the store re-subscribe rules.
  • The order carries the box as it stood when the order was placed. Ticked: the buyer is subscribed, once. Unticked: nothing changes - an unticked order never subscribes and never unsubscribes, and a pending tick stays pending. With the optional An unticked box unsubscribes on, an unticked box on a placed order records an unsubscribe instead.
  • If the shopper goes back to the personal information step and unticks the box, that checkout's tick is withdrawn - only that one: a subscription they gave anywhere else stays.
  • The registration form, the account page, the newsletter block for a signed-in customer and the initial import follow the same rule: PrestaShop verifies no email address there either, so a newsletter subscription counts at once only for a known buyer or someone already subscribed. Anyone else is pending until they click the confirmation email (turn on Email new guests a confirmation link). Only a newsletter-block signup confirmed by PrestaShop's own verification email counts at once. An unsubscribe is always applied at once. To count them at once instead, see Opt-ins from new shoppers. A held registration tick is recorded with the reason registration_tick_pending_confirmation.

Why: at a guest checkout anyone can type anyone's email. Without this rule a bot could type strangers' emails at the personal information step and subscribe them without ever ordering.

Two safeguards in Integrations → PrestaShop → Settings (admins only; each change is recorded in the audit log):

  • Email new guests a confirmation link - off by default, because the address was typed at checkout and nobody has verified it yet. When on, a new guest held as pending gets one email; its link subscribes them (source double_opt_in). It uses your double opt-in confirmation template when you chose one.
  • Opt-in ticks per shopper per hour - default 3, counted per IP address, per checkout and per email address. Ticks over the limit are ignored; the order still records the choice. The module has the same limit (Opt-in ticks per shopper per hour in the module's settings, default 3) and does not send such a tick at all.

The module counts the connection's own IP address. If your shop sits behind a proxy or CDN that sets the visitor's address (X-Forwarded-For), turn on Behind a trusted proxy in the module's settings; otherwise leave it off, because a visitor can set that header themselves.

With module 1.2.7 or older, a new guest's tick is held as pending too, but their order cannot subscribe them (those versions do not send the box with the order) - only the confirmation email can. Update the module to 1.2.8.

Shown in Joryio​

PrestaShop has no "when a tick counts" setting, and Store checkout opt-in (set in your store) on Integrations → PrestaShop → Settings says so, read-only: the newsletter box is PrestaShop's own (the Newsletter subscription module, ps_emailsubscription, under Modules → Module Manager) and is sent before the order, so the safeguards on that page apply to it. Joryio changes nothing in PrestaShop.

Opt-ins from new shoppers​

Opt-ins from new shoppers (not yet buyers) in Integrations → PrestaShop → Settings (admins only; each change is recorded in the audit log) decides what an opt-in from someone who has not bought yet does:

OptionWhat happens
Hold until they order or confirm by email (default, recommended)A new shopper's opt-in is held as pending until their own order with the box ticked or a click on the confirmation email (if you turned Email new guests a confirmation link on).
Count immediately (less strict - any visitor can enter any email)It counts at once. Any visitor can type any email address, so someone can subscribe another person; they can unsubscribe with one click. This is how Joryio counted them before module 1.2.8.

It covers every opt-in that arrives without an order: the checkout's newsletter box, the registration form, the account page, the newsletter block for a signed-in customer and the initial import. Either way:

  • a known buyer or someone already subscribed counts at once, and so does a newsletter-block signup confirmed by PrestaShop's verification email;
  • a tick that comes with the shopper's own order always counts;
  • an unsubscribe always applies at once;
  • the Opt-in ticks per shopper per hour limit stays in force.

An unticked box unsubscribes (optional)​

For stores with a strict consent policy, module 1.2.15 or later has an optional setting in the module's consent settings: An unticked opt-in box at checkout or registration unsubscribes the person. It is off by default.

SettingWhat an unticked box does
Off (default)Nothing. An unticked box never changes anyone's status.
OnA box that was shown and submitted unticked - with a placed order, or on the registration form - records an unsubscribe for that box's channel (email or SMS). Only for signed-in customers, whom the store verified.
On, with Also for guest checkoutsThe same for guest checkouts and new account registrations. Anyone can type someone else's email at a guest checkout - a guest could unsubscribe another person. A new account registration counts as a guest: the store does not verify the email address.
  • The unsubscribe is recorded like any other: in the contact's subscription history (source prestashop_checkout / prestashop_registration, reason checkout_box_unticked, with the text shown next to the box) and as the message.unsubscribed event.
  • Also someone who never opted in: with the setting on, an unticked box unsubscribes the person even if they never opted in (Not Set becomes Unsubscribed). Like every unsubscribe, it applies to every contact with the same email or phone in the workspace, and undoing it needs a new opt-in.
  • Never for a box that was not shown (the SMS box only where it is shown), never from a sync of past orders, and never for a box unticked before the order is placed - unticking during the checkout only withdraws that checkout's own tick. It never subscribes or re-subscribes anyone and never changes a bounce or complaint suppression.
  • Integrations → PrestaShop → Settings shows the setting read-only. Older versions do not report it, and Joryio treats it as off.

The newsletter block​

The newsletter block (the ps_emailsubscription module) is a public form: anyone can type any email address into it. So Joryio treats it differently from the customer's own account:

  • Subscribe counts as consent only when PrestaShop proves the address belongs to the person: either the shopper is signed in to the registered account with that email, or email verification is on in the newsletter block's settings and the confirmation link was clicked (Joryio receives the subscription after the confirmation, on the next cron run). Anything else is not sent to Joryio. Turn on email verification in the newsletter block's settings so guest signups reach Joryio.
  • A confirmation counts only for an address that was not subscribed when the form was sent, and only when PrestaShop records the subscription after the form was sent. An address that was already subscribed is not sent again; if email verification is turned off before the link is clicked, the signup is dropped. Joryio receives the subscription date PrestaShop recorded (for a guest, PrestaShop keeps the signup time, not the confirmation time).
  • Unsubscribe from the block is always applied, by email address - an opt-out request is the safe direction. It never links the request to a customer account.
  • The initial import and Sync now subscribe a customer PrestaShop lists as subscribed only if the contact has never unsubscribed; they never re-subscribe anyone. With email verification off, PrestaShop itself marks a registered customer subscribed when anyone types their address into the block, and the import cannot tell those apart.
  • A newsletter change saved on the customer from the storefront by someone who is not signed in as that customer can unsubscribe, but never subscribes.

Storefront tracking​

From module 1.1.0 the module adds the Joryio tracker to your storefront (on by default - Storefront tracking on the module page). Each event is stored under its standard name, the same as on WooCommerce, Shopify and Magento:

EventStored asWhen it fires
Page ViewPage ViewedEvery page
Product ViewedProduct ViewedA product page, with the chosen combination, price, brand, category and the stock status: in_stock (true or false) and stock_status (in_stock, backorder or out_of_stock)
Category ViewedProduct List ViewedA category page, with category_id, category_name and the page address
SearchProducts SearchedThe search results page, with the query
Add to CartProduct AddedEvery add: the add-to-cart button, a product form that reloads the page, a quantity raised in the cart. PrestaShop records the add and the shopper's browser sends it once
Remove from CartProduct RemovedA quantity lowered or a product removed from the cart
Cart ViewedCart ViewedThe cart page
Checkout StartedCheckout StartedThe checkout page, once per cart. A reload of the checkout is not a second start
Identify$identifyThe signed-in customer, the email typed in the login, registration, checkout or newsletter forms, and the order email on the order confirmation page

The order itself is not a storefront event: Order Completed comes from the order the module sends, so revenue is counted once.

Identity and consent. For a signed-in registered customer (module 1.2.2 or later), the module signs the customer's PrestaShop customer number on the shop's server; Joryio checks that proof and joins the visitor's browsing to the contact that already holds that customer number - never to a contact found by email. Any other identify (a guest, a typed email) only adds the email to the visitor's own anonymous profile in Joryio (it never replaces an email the profile already has, and never merges two contacts by email). Older module versions identified a signed-in customer by email only, which could leave a second contact with just the email; after the update it is joined to the customer's contact the next time the customer signs in on the same browser. An identify never subscribes anyone - consent comes only from the customer's newsletter subscription, see Marketing consent.

Shared browsers (module 1.2.14 or later). Signing out of the store gives the browser a new anonymous visitor, so the next person on the same device is not shown as the one before. A different customer signing in on a browser another customer used gets a new visitor first, and when Joryio finds that the browser's visitor already belongs to someone else (for example the store admin who used it before), the module starts a new visitor and sends the sign-in proof again. The earlier person's profile and history stay as they are, and two people are never merged. While this is being worked out, a page's events wait a few seconds at most.

Themes. The tracker uses PrestaShop's standard hooks (displayHeader, actionFrontControllerSetMedia, displayOrderConfirmation) and the cart events PrestaShop itself records, so it works with the Classic and Hummingbird themes and most others. A theme that removes the displayHeader hook, or a one-page checkout module that replaces the order page, can stop page-specific events (for example Checkout Started); page views, cart events and attribution keep working. A page cache module stores only page-wide data from the tracker: the signed-in customer's email and the cart events are fetched by each visitor's browser and never cached.

Cookie consent. Like the WooCommerce and Magento integrations, the tracker does not wait for a cookie banner. If your shop needs consent before analytics cookies, turn Storefront tracking off or load it through your consent module.

Campaign attribution​

The tracker copies the Joryio click ids (jr_cid for a campaign, jr_jid for a journey) and the UTM parameters of the link a shopper arrived with into first-party cookies (joryio_jr_cid, joryio_jr_jid, joryio_utm_*, 30 days). The module attaches them to the order, so the sale is attributed to the campaign or journey - see Revenue Attribution. It also keeps them with the shopper's cart, so an order confirmed later by a payment provider's callback (without the shopper's browser) is still attributed. Orders from the initial import carry no attribution.

Recognise visitors by the email they type​

From module 1.2.10, the module's configuration page has Recognise visitors by the email they type. It is on by default, and an older module behaves as on.

  • On (default) - an email the visitor types at checkout or in a form identifies their browser as the contact with that email: the existing contact (the most recently active one, when several contacts share the email - see below) or a new one. The visitor's earlier browsing joins that contact, and no second contact with the same email is made. This is what most stores expect. The trade-off: anyone who types someone else's email is recognised as that person in that browser - for example, they could see that person's in-app messages and personalized content.
  • Off (strict identity) - a typed email never identifies the browser. The cart, the order and the form submission still go to the contact with that email, so abandoned cart emails still reach the address typed. Only a customer signed in to the store is recognised in the browser.

Joryio shows the setting read-only under Integrations → PrestaShop → Settings, with the module version and when it was last reported - it is set only in the module. Saving it reports it to Joryio at once, and a change applies within a few minutes.

The cart follows the email typed, and a corrected email. A guest's cart moves to the contact their checkout email names as soon as they type it, not only when the abandoned cart is reported. When a visitor corrects a mistyped email, the mistyped address is taken off again and the corrected one is matched like any other, so the visitor and the cart move to the right contact and no contact is left behind with the typo. A typed address is only taken off while nothing else names a person on that contact: an order, a phone number, a consent choice, a store account, or an address typed more than a day ago keeps it.

When several contacts share an email​

An email can belong to more than one contact in Joryio (for example a couple, or one person imported twice). When a guest's checkout email matches several contacts, the cart, the checkout and the order go to the contact that was most recently active - the same rule imports, the API and forms use, so one person's history is not split between two contacts. Once a checkout has picked a contact, it stays with it: later cart updates, consent, the abandoned cart, the order and its status updates all go to that same contact, even if the other contact changes in the meantime. A customer signed in to the store always goes to the contact that holds their store customer account. Contacts are never merged, and an unsubscribe still applies to every contact with the email.

In-app messages and web push​

From module 1.1.0 the tracker also loads the Joryio web SDK on your storefront, from https://sdk.joryio.com/web/1/joryio.min.js (the latest 1.x version). Its data calls go to the Server URL you connected with. The settings are on the module page:

SettingDefaultWhat it does
In-app messagesYesShows your Joryio in-app messages on the shop
Allow HTML in-app messagesYesAlso shows messages built with the HTML editor. They are shown in a protected frame: scripts written into them do not run, and the message can't reach your shop's pages or make network requests of its own
Web pushNoLets shoppers subscribe to browser notifications

The SDK is loaded by the tracker, so keep Storefront tracking on. Nothing is counted twice: the SDK uses the tracker's anonymous visitor id, emails are identified by the tracker only, and the SDK sends no page views or session starts of its own.

Web push setup​

A browser accepts the notification service worker only from your shop's own address, at https://your-shop/joryio-sw.js. Turn Web push on and save, then open the Web push panel on the module page:

  1. A single shop at the root of its domain: the module writes the file joryio-sw.js into the PrestaShop folder. The panel says so - nothing else to do. (If the folder is not writable, or a joryio-sw.js the module did not write is already there, the panel says that instead.)
  2. Otherwise (multistore, a read-only folder): the module answers /joryio-sw.js itself when your server passes unknown addresses to PrestaShop, which PrestaShop's .htaccess does with friendly URLs on. Click Check the service worker address on the panel: it must show a script starting with // Joryio web push.
  3. If the check shows a 404 page, add the one line the panel shows to your server configuration:
    • Apache, in .htaccess above the PrestaShop rules: RewriteRule ^joryio-sw\.js$ index.php?fc=module&module=joryio&controller=sw [QSA,L]
    • nginx: location = /joryio-sw.js { rewrite ^ /index.php?fc=module&module=joryio&controller=sw last; }

PrestaShop installed in a sub-folder (https://example.com/shop/) cannot use web push: browsers only accept the worker at the domain root.

Shoppers are asked for permission through a push opt-in in-app message you create in Joryio, so keep In-app messages on, and turn on web push for the app in Joryio too. Turning Web push off makes the same address serve a worker that removes itself from visitors' browsers.

Turn on web push in Joryio too. Connecting the store created an app for it in Joryio (Settings → Apps, named after the store). Open it, click the bell (Push) and Enable Web Push: that creates the store's own web push keys, which the SDK on your store reads by itself - there is nothing to copy. Then create an in-app message with a button set to Ask to enable notifications and show it in that app; shoppers who accept can receive your push campaigns and journey steps.

Coupon programs​

From module 1.1.0, coupon programs can use the shop: Joryio creates each person's code as a PrestaShop cart rule through the Webservice key (named Joryio - <program> (<variable> v<version>), its description says it was created by Joryio).

SettingOn PrestaShop
DiscountPercent off, a fixed amount off the cart (tax included, in the shop's default currency), or free shipping. A fixed amount off each product is not available: a PrestaShop cart rule takes one amount off the order
Minimum spendThe cart's products, tax included, without shipping
Applies toThe whole cart, chosen products or chosen categories (PrestaShop product and category ids). The module writes the product rules and only then activates the code; with an older module the code is not created
Uses per code / once per customerThe cart rule's total and per-customer quantities
Not combinableThe cart rule is not combinable with other cart rules that are also not combinable. A cart rule of your own that is compatible with all others can still be combined with it (a PrestaShop rule)
Lock to the personThe code is locked to the person's customer account in the shop: they sign in to use it. A person without a registered account in the shop (or with two accounts on one email) gets no code - the issue fails and the program's fallback applies
ExpiryEach code gets its own end date, in the shop's time zone

Apply link. {{ coupons.<variable>.apply_url }} opens index.php?fc=module&module=joryio&controller=coupon&code=... on your shop: the code goes into the shopper's cart, with PrestaShop's own checks (dates, uses, minimum, products, the account lock). With an empty cart the code is kept and applied when a product is added; a locked code asks the shopper to sign in first.

Redemptions. Every code on an order is sent with the discount it gave, so redemptions and revenue reach the program report. The initial import and Sync now read the codes too (module 1.1.0 or later).

Upgrading from 1.0.0. Upload the new module zip over the old one (Module Manager → Upload a module). The upgrade gives the existing Webservice key the cart rule permission - your connection stays as it is. Until then Joryio reports "PrestaShop refused coupon access" on the program.

Website forms​

From module 1.2.0, forms on your shop can send their submissions to Joryio, the same way as WordPress forms: each submission creates or updates the contact and records a Form Submitted event, and you choose per form whether it also subscribes the contact to lists.

FormWhen it is sent
Contact form (PrestaShop's contactform module)When PrestaShop saves the visitor's message. The contact chosen in the form needs Save messages on (Customers → Contacts); a message to a contact without it is only emailed by PrestaShop and does not reach Joryio
Other formsWhen a module or your theme calls the hook actionJoryioFormSubmit after accepting a submission (see below). The form appears on the module page the first time it is submitted, or you add it there by its ID

Set up a form. On the module page, under Website forms, tick Send this form to Joryio and map the form:

  • Email field, Phone field, First name field, Last name field - the name of the form field. The contact form's email field is from. Map at least an email or a phone field: a submission without either is not sent.
  • Custom attributes - one per line, attribute_key = field name (for example company = company).
  • Lists - the lists the form subscribes to. With no list the contact is only saved.
  • List subscription - Only when a consent checkbox is ticked (the default; enter the checkbox's name), or This is a signup form - always subscribe.
  • Consent wording (module 1.2.17) - the exact text shown next to the consent checkbox. The module cannot read your theme's label, so type it here. When the visitor ticks the box, Joryio records this wording on the consent entry as what they agreed to.

Then click Save form settings. Every form starts off: nothing is sent until you turn it on.

What is sent. Only the fields you map - the message itself is not sent unless you map it to an attribute. The email is the one the visitor typed: it is never linked to a customer account in the shop, and a visitor's form never changes the email or phone of an existing contact. A signed-in customer can update their phone (module 1.2.18): when a registered customer logged in to your shop submits a form and the form's email belongs to their own contact, the phone they typed replaces the contact's phone. The module proves who is logged in with a signed proof made on the shop's server, only for a form submitted on your own shop; the email is never changed this way. A list that needs double opt-in sends its confirmation email first; the contact is subscribed when they confirm. Form Submitted is recorded whether or not the visitor consented (properties: source - prestashop_contact or prestashop_form, formId, formName, pageUrl, consentGiven, consentText, listsSubscribed, listsPending, and the form's own email and phone (formatted the way the contact stores them, so a different phone a visitor typed is not lost) and phoneUpdated when the form's phone differed from the contact's - true when the contact now has it, false when the contact kept its own. Team members who cannot see personal data do not see the email and phone values, and they are erased with the person). When the form subscribes the contact to a list, the consent record in the subscription history keeps the proof of consent: the wording of the ticked box (Consent wording, or the consent_text the form passed), the page the form was submitted on (pageUrl), the time and the visitor's IP address (shown only to team members who can see personal data). An unticked box never sends its wording. With no list nothing is subscribed, so no consent entry is written: the wording stays on the Form Submitted event only (the IP address is never put on the event).

Consent on the contact form. PrestaShop's contact form has no marketing checkbox. To subscribe visitors who agree, add an unticked checkbox such as <input type="checkbox" name="joryio_consent" value="1"> to your theme's copy of the contact form, and enter joryio_consent as the consent field. A GDPR checkbox on the contact form is consent to handle the message, not to marketing - do not use it as the consent field.

Other forms. A developer adds one call where the form is accepted:

Hook::exec('actionJoryioFormSubmit', [
'form_id' => 'quote', // letters, digits and _ . : -
'form_name' => 'Quote request',
'values' => ['email' => $email, 'company' => $company, 'consent' => $consentTicked],
'consent_text' => 'Email me news and offers', // optional (1.2.17): the text next to the consent checkbox
]);

consent_text is optional; when given it is used instead of the form's Consent wording, and only when the consent checkbox was ticked.

Delivery. Submissions are queued and sent by the cron like every other event, with the same retries; a retried submission is never recorded twice.

Upgrading from 1.1.0. Upload the new module zip over the old one (Module Manager → Upload a module). The upgrade registers the two new hooks; your connection and settings stay as they are.

Recognising the visitor. An email typed into a form on the site also identifies the visitor's browser when Recognise visitors by the email they type is on (the default). The submission itself always goes to the contact with that email.

Abandoned cart recovery​

  1. The module tracks carts as customers shop
  2. After a period of inactivity (set on the module page), the cart is reported to Joryio as abandoned
  3. Joryio receives the cart with a signed restore link
  4. Use a journey to send recovery messages with that link

The restore link opens the shop with the cart's items back in the cart. For a guest's cart, products that can no longer be added are left out with "Some products are no longer available and were not added."; when none can be added the shopper sees "The products in this cart are no longer available." (module v1.2.5 or later).

Opening the link: a restore page, one cart per link​

From module 1.2.9, opening the link changes nothing by itself. Link previews in chat apps and email security scanners (Outlook Safe Links, Gmail and others) open links before the shopper does, and each of those openings used to copy a guest's cart once more - one link could leave several copies.

  • Opening the link shows a short page in your theme, "Restoring your saved cart...", that is never cached or indexed. When this browser's cart is empty, its script restores the saved cart and goes on to the cart page; without script the shopper clicks Restore my cart. When this browser's cart already has products, the page asks first, because restoring replaces the cart shown in this browser: Restore my cart or Keep my current cart. A preview or scanner that runs no script restores nothing.
  • One cart per link, per browser - for a guest's cart, the copy the link made is remembered together with the browser it was made in (the shop's visitor cookie). Opening the same link again in that browser (for example after its cart was lost) brings back that same copy instead of a new one, for 7 days (Restore link reuses its cart for (days) on the module page, 1-30), unless it has an address by then. Another browser or device - or a scanner that did run the page - never gets that copy, even when a customer is signed in there: it gets a new copy with the saved cart's products only, so nothing anyone typed at checkout in one browser ever shows in another. The link then remembers the newest browser's copy. Both copies still count as the same saved cart: an order from either is one recovery, and only one "left again" reminder is sent per original cart.
  • Already ordered - "An order was already placed from this cart.", and nothing is restored.
  • At most 10 restores per link per hour - after that, "Too many attempts with this cart link. Please try again later."

A guest's restored copy has no email (the link never copies it); from 1.2.9 it is still reported, without an email, and Joryio sends the one reminder to the contact of the original cart - see Carts.

From module 1.2.11, every cart event of a restored copy names the cart it was restored from (restoredFromSessionId), so a guest's copy shows on E-Commerce → Carts as a Restored copy of the original contact's cart instead of a "No contact" cart, and is not counted as another abandoned cart - see Carts.

From module 1.2.12, every cart event carries the cart's recovery link (valid for 30 days from that cart update) and whether it is a guest's cart, and the module reports Track guest carts and the abandonment time with every request, so a cart Joryio marks abandoned itself follows them - see Carts. With Track guest carts off the module no longer sends guest checkout carts at all (1.2.11 sent them but did not report them abandoned). A guest's email reaches the cart when the personal information step is submitted; an email typed before that identifies the browser only.

Attribution of recovery orders​

From module 1.2.6, the recovery link keeps the attribution parameters Joryio's click tracking adds (jr_cid, jr_jid, utm_*) when it sends the shopper on to the cart, so the order is credited to the message that sent the link. Only these parameters are carried, each checked for its format - never the link's token or anything else. When the shopper opens the link and checks out under a different email, Joryio credits the order to the click of the contact the message was sent to. See Carts.

Disconnecting and uninstalling​

  • Disconnect on the module page ends the connection and deletes the Webservice key the module created. The API key stays valid - click Connect again with the same key (module 1.2.1 or later).
  • Disconnect in Joryio revokes the API key at once: the next time the module sends an event it stops and shows a notice, and connecting with that key says "This key was revoked when the store was disconnected in Joryio". Generate a new key to connect again. Joryio deletes its copy of the Webservice key; the key itself stays in PrestaShop until you click Disconnect on the module page or uninstall the module.
  • Uninstall the module in Module Manager. It disconnects the shop, revokes the API key (module 1.2.1 or later), deletes the Webservice key it created, and removes the module's tables, its joryio-sw.js file and its settings. Coupon codes Joryio created stay in the shop as cart rules.

Troubleshooting​

Connect fails: Webservice​

  • The module turns the Webservice on when you connect. If it is turned off again (Advanced Parameters → Webservice), the initial import and Sync now stop working.
  • Some hosts remove the Authorization header before it reaches PHP. Joryio then sends the key as a ws_key parameter instead, which PrestaShop also accepts. If both are refused, check your server or security plugin rules for /api/.

Connect fails: store address​

  • Use the shop's final https address. A store URL that redirects (for example from http:// or to www.) is refused.
  • The address must be public. Local, private-network and .local addresses are refused.

Nothing arriving in Joryio​

  • Check the queue on the module page: events waiting, not delivered, and the last error.
  • Set up the cron job, especially on a quiet shop.

Web push: no permission prompt​

  • Open https://your-shop/joryio-sw.js: it must show a script starting with // Joryio web push. If not, follow Web push setup.
  • Keep Storefront tracking and In-app messages on, and create a push opt-in in-app message in Joryio.

Coupon codes are not created​

  • "PrestaShop refused coupon access": update the module to 1.1.0 or later, or click Connect again.
  • A program for chosen products or categories needs module 1.1.0 or later on the shop.

A form submission does not arrive​

Check that the form is turned on and has an email or phone field mapped with the field's exact name, that the contact chosen in the contact form has Save messages on, and that the cron runs (see Nothing arriving in Joryio). A list subscription also needs consent: in consent mode, the checkbox must be ticked.

"Invalid API key"​

  • The key must start with jry_ps_ and match the one shown on the PrestaShop page in Joryio.
  • Disconnect on the module page keeps the key (module 1.2.1 or later): click Connect again with it. A Disconnect in Joryio, or uninstalling the module, revokes it - Connect then says so; generate a new one and paste it before you click Connect again.