Sending transactional email from PrestaShop with Volanea does not require a native app or marketplace connector. The reliable approach is to intercept PrestaShop’s outgoing email event, pass the normalized message through a small server-side relay, and have that relay call Volanea using the credentials and request format in its API documentation.
This distinction matters: PrestaShop’s mail system is extensible through PHP hooks, but that is not the same thing as an outbound HTTP webhook supplied by PrestaShop. Likewise, Volanea can be your email delivery provider without being installed as a PrestaShop module. The integration point is code you control.
What this integration does—and does not do
This guide covers a custom integration for transactional email generated by a PrestaShop store. It is suitable for messages such as order confirmations, shipment notifications, password resets, customer-account emails, and internal store notifications.
It does not describe installing a Volanea app in PrestaShop, because there is no native Volanea PrestaShop integration or “install app” flow assumed here. It also does not assume that PrestaShop sends an HTTP webhook whenever an email is generated. In a standard PrestaShop installation, email sending is handled by its PHP mail layer; modules can participate through hooks around that process.
The architecture is:
- A PrestaShop module listens for the email-send hook.
- The module normalizes the hook parameters into a stable internal message object.
- The module sends that object to a relay endpoint you operate.
- The relay validates the request, applies routing and suppression checks, then calls Volanea’s REST API.
- The relay returns a controlled result to PrestaShop and records an audit trail.
A relay may seem like an extra moving part, but it provides useful separation. Your Volanea API credential stays out of the store code and database, email data can be validated before delivery, and a future provider migration affects one service rather than every PrestaShop deployment.
Why a PrestaShop hook is the honest trigger mechanism
PrestaShop exposes hooks that let modules run code when important application events occur. For outgoing messages, the relevant extension point is commonly documented as actionEmailSendBefore. It runs before PrestaShop sends the email and gives a module access to the data PrestaShop intends to use.
That data is a PHP parameter array, not a fixed JSON webhook payload. A module should therefore treat it as application input, normalize it, and avoid assuming that every field is always present or has one exact scalar type.
The email parameters you should expect
The actionEmailSendBefore hook is documented with parameters including:
template: the template name selected by PrestaShop.templateVars: variables used to render the template.subject: the message subject.idLang: the language identifier.to: recipient or recipients.ccandbcc: optional carbon-copy recipients.fromandfromName: the sender address and display name.fileAttachment: optional attachment information.modeSmtp: the mail mode selected by the store.templatePath: the path used for template lookup.die: an error-control value used by the mail flow.
The exact runtime contents depend on the PrestaShop version, the caller, installed modules, and the email type. For example, some callers may provide one recipient string while others provide an address-to-name array. Do not build a relay that assumes to is always one plain email address.
Why not call an API from a front-end automation
Order data, customer addresses, reset links, and authentication credentials are sensitive. A browser-side automation, a public webhook URL with no signature validation, or an API key embedded in theme JavaScript is the wrong trust boundary for transactional mail.
Keep the integration server-to-server:
- PrestaShop authenticates to your relay with a short-lived signed request or a dedicated secret.
- The relay holds the Volanea credential in its server-side secret store.
- The relay calls Volanea over HTTPS.
- Logs redact recipient data and never record authorization credentials.
That design is more operationally sound than trying to force a store event into a generic client-side automation.
Choose the delivery model before writing code
There are two valid patterns, and they serve different operational needs.
Model 1: PrestaShop renders, relay delivers
In this model, PrestaShop creates the final HTML and text content from its existing templates. Your module collects the rendered content or reconstructs it using the original template context, then the relay sends a finished message through Volanea.
Use this when your existing PrestaShop email templates are already localized and brand-approved. It reduces template duplication and lets non-developers continue editing email templates through the store’s established process.
The trade-off is that the integration must handle PrestaShop’s template rendering carefully. If a hook only exposes the template name and variables, the module needs to render in the same context as the regular mail path, or it needs a separate, tested renderer.
Model 2: PrestaShop sends an event, relay renders
In this model, the store sends a business event such as order.confirmed with identifiers and safe, minimal data. The relay loads the needed data from a trusted backend and asks Volanea to send a provider-side template or a fully assembled message.
Use this when you want template ownership outside PrestaShop, centralized email observability across multiple products, or strict control of which data can enter a template. It is also the better long-term model when the same event must notify more than one channel.
The trade-off is that you must maintain templates and localization outside the PrestaShop theme. Do not send an event containing every customer and order field simply because the hook has them available; build an explicit event contract instead.
A practical recommendation
Start with PrestaShop-rendered content for an existing store that needs a low-risk delivery change. Move to event-based rendering once you have a stable event catalog, template review process, and a source of truth for order data outside the request itself.
Whichever model you choose, test with order confirmation, payment failure, shipment, customer registration, and password reset messages. Those flows often use different templates, language contexts, and recipient shapes.
Normalize the hook data into your own payload
Do not expose PrestaShop’s raw PHP hook array as a public integration contract. It may contain values that are not JSON-serializable, internal paths, attachment objects, or fields that vary by version. Instead, convert it to a small versioned payload.
Here is an example payload for a relay. This is your relay contract, not a claim that PrestaShop natively posts this JSON and not a substitute for Volanea’s documented request schema.
{
"version": 1,
"event": "prestashop.email.requested",
"occurred_at": "2026-08-24T14:32:18Z",
"store_id": "eu-store-01",
"idempotency_key": "9c1d895e-65f3-4d32-9f84-0c7ac6d9e8ac",
"message": {
"template": "order_conf",
"language_id": 1,
"from": {
"email": "orders@example-store.test",
"name": "Example Store"
},
"to": [
{
"email": "customer@example.test",
"name": "A. Customer"
}
],
"cc": [],
"bcc": [],
"subject": "Your order has been confirmed",
"html": "<html><body>…</body></html>",
"text": "Your order has been confirmed"
},
"context": {
"order_reference": "XKBKNABJK",
"template_vars_present": ["{firstname}", "{order_name}"]
}
}
The payload deliberately avoids putting API credentials, database passwords, full payment details, or raw attachment file paths in the event. It also has an idempotency key. Retries happen in real systems: PHP workers can time out after the relay accepted a request, users can resubmit a checkout step, and queue jobs can be delivered more than once.
Recipient normalization rules
Normalize recipients before signing or sending the payload. A useful internal shape is always an array of {email, name} objects, even if the source began as a string.
Apply these rules:
- Trim whitespace and reject empty addresses.
- Validate basic address syntax before passing it onward.
- Preserve display names separately from email addresses.
- Deduplicate addresses within
to,cc, andbccaccording to your policy. - Never place
bccrecipients in provider-visible metadata or application logs. - Use a suppression list before delivery to prevent repeated sends to known bad or opted-out addresses where applicable.
For a quick preflight check during testing, use an email address verification tool. Verification is useful for catching obvious malformed or disposable test inputs, but it is not a replacement for bounce processing, consent controls, or provider-level delivery signals.
Attachment policy
Attachments are an area where integrations become unreliable or unsafe. PrestaShop may supply attachment information in a format intended for its own mail class, rather than a portable HTTP format.
For an initial launch, consider rejecting attachments at the relay and logging a clear attachments_not_supported result. If attachments are required, upload them to controlled storage, scan them, enforce size and type limits, and pass only the exact attachment representation required by Volanea’s current API documentation. Do not serialize local filesystem paths into JSON and expect a remote API to access them.
Build the PrestaShop module as a thin adapter
A module should be small, explicit, and easy to disable. Its job is not to become an email platform; it should gather the hook data, render or obtain final content, create a signed relay request, and interpret the relay response.
The module registration pattern varies by PrestaShop release, so use the hook name and module installation conventions documented for the version you run. The following PHP is intentionally focused on the normalization and relay request. It does not claim to be a complete installable module.
public function hookActionEmailSendBefore(array $params)
{
$message = $this->normalizer->fromPrestaShopMailParams($params);
// Configure this URL in your module settings; do not hard-code it.
$relayUrl = (string) Configuration::get('MYMAIL_RELAY_URL');
$secret = (string) Configuration::get('MYMAIL_RELAY_SIGNING_SECRET');
if ($relayUrl === '' || $secret === '') {
PrestaShopLogger::addLog('Mail relay is not configured', 3);
return;
}
$payload = [
'version' => 1,
'event' => 'prestashop.email.requested',
'occurred_at' => gmdate('c'),
'store_id' => (string) Context::getContext()->shop->id,
'idempotency_key' => $this->uuidV4(),
'message' => $message,
];
$json = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
$timestamp = (string) time();
$signature = hash_hmac('sha256', $timestamp . '.' . $json, $secret);
$response = $this->httpClient->request('POST', $relayUrl, [
'headers' => [
'Content-Type' => 'application/json',
'X-Relay-Timestamp' => $timestamp,
'X-Relay-Signature' => 'sha256=' . $signature,
],
'body' => $json,
'timeout' => 5,
]);
if ($response->getStatusCode() >= 300) {
PrestaShopLogger::addLog('Mail relay rejected a message', 3);
// Decide deliberately whether to allow PrestaShop's normal send path,
// queue a retry, or fail the initiating business action.
}
}
The fromPrestaShopMailParams() method is where you solve version and data-shape differences. Keep that logic covered by unit tests using representative arrays from your store’s own email flows.
Avoid accidentally sending twice
A pre-send hook is not automatically a replacement for PrestaShop’s default mail transport. If your module forwards a message to a relay and then allows the normal send path to continue, customers may receive two copies.
Before changing production behavior, determine exactly how your PrestaShop release and module architecture allow you to replace, cancel, or defer the default send. If the hook is observational only in your setup, use a supported transport override or mail service customization rather than assuming that returning from a hook cancels delivery.
This is a reason to test in a staging store with an inbox you control. For each test action, record whether the recipient received zero, one, or two messages and from which sending infrastructure.
Make the relay the only service that knows Volanea credentials
The relay is a small HTTP service. It verifies the request signature, checks timestamp freshness, validates the normalized payload, deduplicates the idempotency key, and then sends through Volanea.
A Node.js-style outline for request authentication looks like this:
import crypto from 'node:crypto';
function validSignature({ rawBody, timestamp, signature, secret }) {
const age = Math.abs(Math.floor(Date.now() / 1000) - Number(timestamp));
if (!Number.isFinite(age) || age > 300) return false;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const actual = Buffer.from(signature || '', 'utf8');
const expectedBuffer = Buffer.from(expected, 'utf8');
return actual.length === expectedBuffer.length &&
crypto.timingSafeEqual(actual, expectedBuffer);
}
Store the idempotency key before making the provider request, with a state such as processing. If another request presents the same key, return the previous completed result or a safe in-progress response. After Volanea accepts the message, store its provider message identifier alongside the internal key.
Do not guess Volanea’s endpoint or JSON fields
The final provider request must use Volanea’s currently documented endpoint, authentication header, and message schema. API providers differ on details such as whether recipients are strings or objects, how templates are addressed, whether text content is optional, attachment encoding, tag fields, and idempotency headers.
For that reason, do not copy a payload shape from another email provider and relabel it as Volanea. Use the Volanea API reference and setup guides as the source of truth for the actual REST call. Put the provider-specific call behind one function in the relay, such as sendWithVolanea(message), so the rest of the integration remains stable.
A safe relay boundary looks like this:
async function processTransactionalMessage(event) {
validateInternalEvent(event);
await assertNotSuppressed(event.message.to);
// Implement this function only with the current Volanea API contract
// from Volanea documentation and credentials stored in your secret manager.
const result = await sendWithVolanea(event.message, {
idempotencyKey: event.idempotency_key,
metadata: {
source: 'prestashop',
store_id: event.store_id,
template: event.message.template
}
});
return {
accepted: true,
provider_message_id: result.providerMessageId
};
}
This is preferable to publishing an unverified “working” provider call. A guessed URL, authorization scheme, or field name can fail silently, create duplicates, or send content with missing recipients.
Configure sender identity and deliverability first
A successful API response is not the same as inbox placement. Transactional messages should use a sender domain your organization controls and has authenticated according to your provider’s setup process.
At minimum, coordinate the following before routing production store mail through a new infrastructure:
- Authenticate the sending domain using the DNS records Volanea specifies.
- Align the visible From domain with the authenticated domain where possible.
- Publish a DMARC policy appropriate for your domain’s rollout stage.
- Keep order and account messages distinct from promotional campaigns.
- Use a monitored reply-to address for customer-facing mail.
- Keep subject lines and templates consistent during the migration so delivery changes are measurable.
Do not invent DNS record names or copy record values from another vendor. SPF, DKIM, return-path, tracking, and DMARC requirements are provider-specific and can change by sending configuration. Copy each hostname and value exactly from Volanea’s documented domain-authentication instructions or dashboard.
Separate transactional and marketing streams
An order confirmation is expected by a customer after a purchase; a sale announcement has a different consent basis, cadence, and complaint risk. Keeping them operationally separate helps you investigate delivery issues and prevents campaign volume from obscuring critical store events.
Include a message classification in relay metadata, for example transactional, but do not assume that metadata controls provider routing unless Volanea documents that behavior. It is still valuable for your own logs, queues, dashboards, and incident analysis.
Decide what happens when delivery infrastructure is unavailable
The most important integration decision is not the happy-path HTTP request. It is the failure policy.
For order confirmations, a short delay is often better than losing the message. For password reset messages, excessive delay can make the link useless. For internal alerts, it may be acceptable to fall back to a separate channel.
Suggested failure categories
Classify failures so your retry behavior is deliberate:
| Category | Example | Typical response |
|---|---|---|
| Validation failure | Missing recipient or invalid sender | Do not retry; log a structured error. |
| Authentication failure | Relay signature invalid | Reject immediately and alert operators. |
| Provider rejection | Suppressed recipient or malformed provider request | Do not blindly retry; inspect the cause. |
| Temporary network failure | Connection timeout | Retry with backoff and idempotency protection. |
| Provider service failure | 5xx response | Retry with bounded exponential backoff. |
| Store-side failure | Rendering error | Preserve context safely and alert the store team. |
Do not make the customer checkout wait indefinitely for a remote email API. If your business process allows it, write the transactional event to a durable queue and deliver asynchronously. The order can complete while the email worker retries in the background.
For flows where immediate feedback matters, such as account verification, use a short synchronous attempt and then enqueue a retry. Always show customers a neutral message rather than exposing provider errors or email addresses in the browser.
Test the integration with realistic PrestaShop scenarios
A single test email proves very little. Different PrestaShop mail templates can be called with different variables, language settings, sender identities, and recipient formats.
Build a test matrix before production rollout:
- Create a new account in each active storefront language.
- Submit a password-reset request and confirm the link survives rendering and delivery.
- Place an order using each payment path that changes the order state.
- Trigger shipment or status-change notifications.
- Send a customer-service message if your store uses that feature.
- Test a recipient with a display name containing punctuation or non-ASCII characters.
- Test duplicate relay requests using the same idempotency key.
- Test an invalid recipient, a suppressed recipient, and a deliberately unavailable relay.
- Confirm that one triggering action produces exactly one delivered email.
- Verify that no customer data or secrets appear in application logs.
Use a non-production recipient allowlist during early testing. A staging store can contain realistic templates and data shapes without risking emails to actual customers.
What to inspect in each test
Inspect more than whether an inbox received the message. Check the visible From name and address, Reply-To behavior, subject encoding, HTML rendering, plain-text alternative, links, language, tracking choices, and any attached files.
Also inspect the relay’s stored event record: creation time, normalized recipient count, idempotency key, result status, retry count, and provider message identifier. These fields let support staff answer “was it sent?” without searching raw logs or exposing private content.
Monitoring, privacy, and support operations
A transactional email pipeline needs monitoring because its failures are often customer-visible. A store can continue accepting orders while confirmation emails are delayed, making the problem easy to miss until support tickets appear.
Track at least these metrics:
- Relay requests accepted and rejected.
- Messages accepted by Volanea.
- Provider API latency and error rate.
- Queue age and retry count.
- Messages suppressed before send.
- Bounces, complaints, and delivery events where your Volanea configuration provides them.
- Duplicate events prevented by idempotency.
Set alerts on sustained provider errors, growing queue age, signature failures, and a sudden drop in accepted messages after a deployment. A drop can indicate a broken hook registration, an expired secret, a changed template path, or a store configuration change—not merely an email-provider problem.
Keep personal data out of diagnostics
Email events naturally include personal data. Use identifiers and hashes in ordinary logs rather than full message bodies, reset URLs, customer names, or recipient addresses. Restrict access to any delivery-event store that must retain addresses for operational reasons.
Define retention periods for relay events. The support value of a full payload usually declines quickly, while privacy and breach exposure increase the longer it remains available. Store a minimal audit record after the detailed troubleshooting window ends.
Alternatives and when to use them
The relay pattern is not the only possible architecture, but it is often the cleanest when you need application-level control.
Configure SMTP instead
If Volanea provides SMTP credentials and your PrestaShop version supports the required SMTP settings, SMTP may be the quickest path for a straightforward store. It uses PrestaShop’s existing mail flow and avoids custom event forwarding.
The downside is reduced control over idempotency, provider response handling, internal event metadata, and custom retries. SMTP can be ideal for a small store; an API relay is usually stronger for multi-store systems, strict observability requirements, or complex workflows.
Use a queue worker
A queue worker improves resilience when order volume is high or API latency varies. The PrestaShop module writes a compact event to durable storage, and the worker performs rendering and provider delivery outside the customer request.
This takes more engineering but protects checkout performance and makes retry behavior easier to control. It also creates a natural place to implement per-store rate limits and a dead-letter queue.
Use a generic automation platform carefully
An automation platform can be useful for non-sensitive follow-up workflows, reporting, or internal notifications. It is usually a poor primary transport for password resets and purchase confirmations because webhook retries, secrets, recipient privacy, and exact delivery guarantees require deliberate design.
If you do use an automation service, send it a minimal signed event from your relay rather than exposing a public automation URL directly from PrestaShop. Keep Volanea credentials in a trusted server-side environment.
Conclusion: treat email as a production system
To send transactional email from PrestaShop with Volanea honestly and reliably, do not look for a nonexistent native connector. Use PrestaShop’s documented mail hook or supported mail customization point, normalize the email request, send it to a secured relay, and make the provider-specific Volanea call from that relay using the current API documentation.
This approach gives you control over data handling, retries, duplicate prevention, delivery monitoring, and future changes. Most importantly, it avoids a fragile integration built on assumed webhooks or guessed API fields.
FAQ
Does Volanea have a native PrestaShop module?
This guide does not assume or claim a native Volanea PrestaShop module. It uses a custom server-side integration: a PrestaShop mail hook, a relay service, and Volanea’s REST API.
Does PrestaShop send a JSON webhook for every outgoing email?
PrestaShop’s mail extension mechanism is based on PHP hooks around its mail flow. The actionEmailSendBefore data is a PHP parameter array, so a custom module must convert it into JSON if it sends the information to an HTTP relay.
Can I put the Volanea API key in my PrestaShop module?
Avoid doing so. Keep the provider credential in a server-side relay or secret manager. That limits access, makes rotation safer, and prevents the store module from becoming the only place where delivery logic lives.
How do I prevent duplicate order confirmation emails?
Generate an idempotency key for each logical send, store its result in the relay, and make retries reuse that key. Also verify whether your PrestaShop customization replaces the default transport; forwarding from a pre-send hook without replacing the original path can produce duplicates.
Should I use SMTP or a REST API relay?
SMTP is often simpler for a basic store. A REST API relay is a better fit when you need structured logs, durable retries, centralized secrets, idempotency, multi-store routing, or richer delivery operations.