AffiliateWP can create valuable referral events, but it does not include a native Volanea connection. This guide shows how to send email from AffiliateWP by using AffiliateWP’s WordPress hooks and a small server-side integration that calls the Volanea REST API.

What this integration does

The practical event in this integration is a newly created AffiliateWP referral. AffiliateWP creates a referral record when one of its supported ecommerce, membership, form, or custom integrations records a commissionable conversion. The WordPress action used below is affwp_insert_referral.

That action is important because it is a server-side event. It runs in WordPress after AffiliateWP has inserted the referral, giving your code a referral ID and the referral arguments. Your integration can then retrieve the complete referral record, identify the affiliate, and ask Volanea to deliver an email.

This is a useful pattern for messages such as:

  • An affiliate notification that a referral has been recorded.
  • An internal operations alert for a high-value referral.
  • A message to an account manager when a specific campaign produces a referral.
  • A follow-up email that is sent only after a referral reaches a business-approved status.

Do not treat “referral created” as identical to “commission payable.” In many AffiliateWP setups, a referral may begin in a pending state and later be marked unpaid, paid, or rejected. The appropriate email trigger depends on what the message promises. A “we recorded your referral” message can be triggered at creation; a “commission approved” message should be tied to the relevant status transition instead.

The AffiliateWP capability this uses

AffiliateWP does not need a native marketplace app or a browser-side API integration for this workflow. The direct route is its WordPress developer hook system: a PHP callback runs inside the same WordPress installation that runs AffiliateWP.

For referral creation, the relevant hook is:

do_action( 'affwp_insert_referral', $referral_id, $args );

Your callback receives two arguments:

  1. $referral_id: the ID of the referral AffiliateWP just inserted.
  2. $args: the referral data supplied during creation.

AffiliateWP is not posting a prebuilt JSON webhook payload to Volanea in this route. Instead, it provides PHP values to WordPress. That distinction is useful: your WordPress code can retrieve the canonical referral object before constructing the email payload, rather than assuming every value in the initial arguments is present or formatted for email.

A representative referral argument array has fields such as this:

array(
    'affiliate_id' => 42,
    'visit_id'     => 317,
    'description'  => 'Order #1843',
    'status'       => 'pending',
    'amount'       => '12.50',
    'currency'     => 'USD',
    'reference'    => '1843',
    'context'      => 'woocommerce',
    'campaign'     => 'spring-launch',
    'custom'       => ''
)

The exact set of populated fields varies by the integration that generated the referral. For example, a referral from an ecommerce integration may include an order reference and description, while a custom integration may use a different description, context, or reference. Treat optional values as optional in both code and copy.

Choose the right event before sending

The affwp_insert_referral trigger has a major operational implication: it can run during a customer-facing conversion request. A slow remote API call can make that request slower, and a hard failure should not prevent the referral from being recorded.

For a simple, low-volume notification, the direct hook can be acceptable when the request timeout is conservative and failures are recorded for later handling. For production stores, membership sites, and busy affiliate programs, it is better to make delivery asynchronous.

Referral-created messages

Use creation-time email when the message is informational and does not make a payment promise. Good examples include:

  • “A referral has been recorded and is pending review.”
  • “Your campaign generated a new conversion.”
  • “A new referral needs an internal review.”

This guide’s code uses that model. It tells the affiliate that the referral was recorded and includes the current status.

Approval and payment messages

If the email says a commission is approved or has been paid, do not send it merely because a referral exists. AffiliateWP referral statuses carry business meaning. A pending referral can still be rejected; an unpaid referral can be part of an approval process; paid indicates that payment has been recorded.

In that case, use the AffiliateWP hook that corresponds to your status-update workflow, test the old and new state, and persist a message ID or event marker against the referral. The same Volanea request structure below still applies; only the event that starts it changes.

Keep the Volanea API key on the server

The Volanea API key belongs in server-side configuration, never in a JavaScript bundle, WordPress page setting exposed to visitors, form markup, or an AffiliateWP creative. A key in client-visible configuration can be copied by any visitor and used to send mail under your account.

A practical WordPress approach is to put the key in wp-config.php, ideally from an environment variable managed by your host:

define( 'VOLANEA_API_KEY', getenv( 'VOLANEA_API_KEY' ) );
define( 'VOLANEA_FROM_EMAIL', 'Affiliate Team <affiliates@example.com>' );

Set VOLANEA_API_KEY in the host’s secret or environment-variable manager. On a local development machine, use a local secret file that is excluded from Git. Do not commit the key to a theme, plugin repository, deployment artifact, or database export.

Your sending domain must also be configured and authenticated in Volanea before production delivery. Use an address at that authenticated domain in the from field. The email API reference and setup guides are the right place to confirm the current sending endpoint, authentication requirements, and domain setup before deployment.

Why not put the key in AffiliateWP settings?

AffiliateWP settings are designed for AffiliateWP configuration, not as a general-purpose secret vault for a custom mail integration. A custom setting can also create access-control, export, backup, and accidental-display concerns. A server environment secret makes the security boundary clearer: PHP can use it, while a site visitor cannot retrieve it.

Use a restricted API key where your Volanea account supports scopes or key restrictions. Rotate the key if it is ever exposed, and update the server secret rather than editing multiple code files.

Install a small WordPress integration plugin

Put the integration in a small site-specific plugin, not in the active theme’s functions.php. A plugin is easier to version, deploy, test, and keep active when the theme changes.

Create wp-content/plugins/affiliatewp-volanea-email/affiliatewp-volanea-email.php, paste the following code, and activate it in WordPress. Replace the example sender domain before using it.

<?php
/**
 * Plugin Name: AffiliateWP referral email via Volanea
 * Description: Sends an affiliate notification after AffiliateWP creates a referral.
 * Version: 1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'affwp_insert_referral', 'mysite_send_affiliatewp_referral_email', 10, 2 );

function mysite_send_affiliatewp_referral_email( $referral_id, $args ) {
    // Do not send twice if WordPress or an upstream integration retries this event.
    if ( affwp_get_referral_meta( $referral_id, '_volanea_referral_email_sent', true ) ) {
        return;
    }

    if ( ! defined( 'VOLANEA_API_KEY' ) || ! VOLANEA_API_KEY ) {
        error_log( 'Volanea email was not sent: VOLANEA_API_KEY is missing.' );
        return;
    }

    $referral = affwp_get_referral( $referral_id );
    if ( ! $referral ) {
        error_log( 'Volanea email was not sent: AffiliateWP referral was not found.' );
        return;
    }

    $affiliate = affwp_get_affiliate( $referral->affiliate_id );
    $user      = $affiliate ? get_userdata( $affiliate->user_id ) : false;

    // AffiliateWP affiliates can exist without a usable WordPress user email.
    if ( ! $user || ! is_email( $user->user_email ) ) {
        error_log( sprintf( 'Volanea email was not sent: no recipient for referral %d.', $referral_id ) );
        return;
    }

    $reference   = ! empty( $referral->reference ) ? $referral->reference : 'not supplied';
    $description = ! empty( $referral->description ) ? $referral->description : 'A new referral';
    $campaign    = ! empty( $referral->campaign ) ? $referral->campaign : 'None';
    $currency    = ! empty( $referral->currency ) ? $referral->currency : '';
    $amount      = isset( $referral->amount ) ? $referral->amount : '';

    $subject = sprintf( 'New referral recorded: %s', $reference );
    $html    = sprintf(
        '<p>Hello %s,</p><p>A referral has been recorded in your affiliate account.</p><ul><li><strong>Reference:</strong> %s</li><li><strong>Description:</strong> %s</li><li><strong>Amount:</strong> %s %s</li><li><strong>Status:</strong> %s</li><li><strong>Campaign:</strong> %s</li></ul><p>This referral is currently %s. Please sign in to your affiliate area for details.</p>',
        esc_html( $user->display_name ),
        esc_html( $reference ),
        esc_html( $description ),
        esc_html( $amount ),
        esc_html( $currency ),
        esc_html( $referral->status ),
        esc_html( $campaign ),
        esc_html( $referral->status )
    );

    // Map AffiliateWP referral data to Volanea's email-send JSON payload.
    $payload = array(
        'from'    => VOLANEA_FROM_EMAIL,
        'to'      => array( $user->user_email ),
        'subject' => $subject,
        'html'    => $html,
        'text'    => wp_strip_all_tags( $html ),
        'tags'    => array(
            array( 'name' => 'source', 'value' => 'affiliatewp' ),
            array( 'name' => 'referral_id', 'value' => (string) $referral_id ),
            array( 'name' => 'context', 'value' => (string) $referral->context ),
        ),
    );

    $response = wp_remote_post(
        'https://api.volanea.com/v1/emails',
        array(
            'timeout' => 10,
            'headers' => array(
                'Authorization' => 'Bearer ' . VOLANEA_API_KEY,
                'Content-Type'  => 'application/json',
                'Accept'        => 'application/json',
            ),
            'body'    => wp_json_encode( $payload ),
        )
    );

    if ( is_wp_error( $response ) ) {
        error_log( 'Volanea API request failed: ' . $response->get_error_message() );
        return;
    }

    $status_code = wp_remote_retrieve_response_code( $response );
    $body        = wp_remote_retrieve_body( $response );

    if ( $status_code < 200 || $status_code >= 300 ) {
        error_log( sprintf( 'Volanea API returned HTTP %d for referral %d: %s', $status_code, $referral_id, $body ) );
        return;
    }

    // Store a durable idempotency marker only after Volanea accepts the request.
    affwp_update_referral_meta( $referral_id, '_volanea_referral_email_sent', gmdate( 'c' ) );
    affwp_update_referral_meta( $referral_id, '_volanea_referral_email_response', $body );
}

The code makes the mapping explicit. The recipient is the WordPress user attached to the AffiliateWP affiliate. The email subject uses the referral reference. The message body uses the referral’s description, amount, currency, status, and campaign when those fields are available. Finally, the tags make it easier to identify AffiliateWP-originated sends in delivery analytics.

Understand the Volanea request mapping

The API call uses WordPress’s HTTP API through wp_remote_post(). That is preferable to a browser fetch() call because it is server-to-server, keeps the API key private, and allows the request to be logged with the WordPress application.

The essential request is:

POST /v1/emails HTTP/1.1
Host: api.volanea.com
Authorization: Bearer YOUR_VOLANEA_API_KEY
Content-Type: application/json

{
  "from": "Affiliate Team <affiliates@example.com>",
  "to": ["affiliate@example.com"],
  "subject": "New referral recorded: 1843",
  "html": "<p>Hello Alex...</p>",
  "text": "Hello Alex...",
  "tags": [
    {"name":"source","value":"affiliatewp"},
    {"name":"referral_id","value":"123"}
  ]
}

Do not copy referral descriptions into HTML without escaping them. Referral text can originate with another plugin, an order, product data, or custom integration code. The example uses esc_html() for every inserted value and creates the text alternative from the resulting HTML.

Also decide whether an affiliate should see the referral amount. Some programs hide amounts until review or use amounts that are not final. If you do not want to disclose it, remove the amount line entirely rather than relying on a frontend setting to conceal it.

Test the workflow safely

Start with a test affiliate account and a sending domain that is already authenticated in Volanea. Create a real test conversion through the same ecommerce or membership flow that normally creates referrals; manually calling the endpoint tests only half of the integration.

Use this test checklist:

  1. Confirm the conversion creates exactly one AffiliateWP referral.
  2. Confirm the referral has the expected affiliate, status, reference, and context.
  3. Confirm WordPress sends one API request and Volanea accepts it with a 2xx response.
  4. Inspect the delivered message on desktop and mobile, including the text alternative.
  5. Repeat the event or refresh the relevant request only in a staging environment and verify the idempotency marker prevents a duplicate message.
  6. Check that the message’s sender is an authenticated domain and that no API key appears in page source, logs, or browser network requests.

A development log can help while testing. WordPress can write PHP errors to wp-content/debug.log when debug logging is enabled. Do not leave raw API responses in public output, and avoid logging full recipient addresses or email content indefinitely in production.

When this breaks

This hop has two systems with different retry and failure behavior: AffiliateWP/WordPress creates the referral, then WordPress asks Volanea to send an email. Design for uncertainty between those two actions.

A retry causes duplicate sends

A conversion integration, a payment provider callback, a background job, or an administrator action may repeat a request. A remote request can also succeed at Volanea while the WordPress process times out before receiving the response. If your code blindly sends on every affwp_insert_referral callback, affiliates can receive duplicates.

The example stores _volanea_referral_email_sent as referral metadata after a successful 2xx API response. That handles ordinary repeat callbacks. It cannot perfectly resolve the narrow case where Volanea accepted the send but WordPress lost the response before saving the marker. For stronger protection, use a queue and an API-level idempotency mechanism if your Volanea API configuration supports one, using a stable key such as affiliatewp-referral-123-created.

Do not set the “sent” marker before the API accepts the request. Doing that would suppress legitimate retry attempts after a network failure.

The webhook-style request times out

Although this implementation is a WordPress hook rather than a native AffiliateWP webhook, the operational issue is the same: a remote HTTP call is happening in the path of an event. The code uses a 10-second timeout so a stalled connection does not run indefinitely. That is still too long for some busy checkout paths.

For higher reliability, have the hook enqueue only the referral ID and let Action Scheduler, WP-Cron, or your own worker send the email shortly afterward. The job should fetch the referral again, verify the event is still eligible, check the marker, send, and retry transient failures with backoff. A queue also provides a durable place to inspect failures instead of relying solely on PHP error logs.

Payload fields are missing or have different meanings

Do not assume campaign, reference, description, currency, or visit_id is populated for every AffiliateWP integration and plan configuration. A direct referral inserted by custom code can have fewer values than a WooCommerce-generated referral. An affiliate record can also lack a usable associated WordPress user email.

The code supplies fallbacks for display values and stops when there is no valid recipient. For critical internal alerts, send to a fixed operational address instead of using the affiliate’s account email. For affiliate-facing mail, make missing fields a product decision: omit the row, use a neutral phrase, or direct the recipient to the affiliate area.

Volanea rejects the request

A non-2xx response is not a successful send request. Common categories are an invalid or revoked key, a sender domain that has not been authenticated, malformed JSON, an invalid recipient, or an account-level sending restriction. The example writes the HTTP status and response body to the server error log, but production teams should route those failures to monitored logging.

Never automatically retry all 4xx responses. Authentication and malformed-payload failures need configuration or code changes. Network errors and many 5xx responses are generally candidates for bounded retries.

Deliverability and message design

A successful API response means Volanea accepted the message for processing; it does not guarantee an inbox placement outcome. Affiliate messages should use a clear sender identity, a stable authenticated domain, and content that matches the affiliate’s expectations.

Avoid turning an operational referral notice into a promotional blast. If it is transactional in purpose, keep the message focused on the referral event, its current state, and the next action. If you later add marketing content, apply the consent and unsubscribe rules appropriate to your jurisdiction and audience.

Tags such as source=affiliatewp and a referral ID are operationally valuable. They let you correlate delivery events, support tickets, and referral records without putting sensitive transaction data into the subject line. Keep tag values compact and avoid placing customer names, full order contents, or other personal data there.

Alternatives to a direct WordPress hook

The direct hook is usually the most precise option because it has access to AffiliateWP’s referral ID and object at the moment of creation. It also avoids routing affiliate and order information through another automation provider. However, it requires PHP deployment and monitoring.

A middleware route can make sense when your team does not maintain WordPress code. In that design, send AffiliateWP-related event data from a controlled WordPress endpoint or automation connector to a service such as Zapier or Make, then have that service call Volanea. Keep the Volanea key in that service’s encrypted connection settings, not in a frontend field.

The trade-offs are clear:

  • Direct hook: fewer systems, richer referral access, but requires code ownership.
  • Queued WordPress worker: more reliable under load, but requires job monitoring.
  • Middleware automation: easier for non-developers to edit, but adds latency, task usage, and another place where data and retries must be governed.

Whichever route you choose, retain the same principles: send only after a meaningful AffiliateWP event, map optional referral fields defensively, protect secrets, use stable duplicate protection, and observe failures.

Conclusion

To send email from AffiliateWP with Volanea, use AffiliateWP’s affwp_insert_referral action as the event, retrieve the referral and affiliate data in WordPress, and make the authenticated Volanea REST request on the server. This avoids pretending there is a native connector while giving you full control over who receives the message and what it says.

Before production, decide whether a newly created referral is truly the right business event, move sending to a queue if the site handles meaningful volume, and test duplicate behavior as seriously as the happy path. Those choices turn a short code snippet into a reliable affiliate-notification system.

FAQ

Does AffiliateWP have a native Volanea plugin?

No. This integration uses AffiliateWP’s WordPress hook system and a server-side PHP plugin to call Volanea’s API. It does not require a native marketplace listing or browser-side connection.

What AffiliateWP event sends the email in this example?

The example uses affwp_insert_referral, which runs when AffiliateWP inserts a referral record. It is best for “referral recorded” notifications, not necessarily payment-confirmation messages.

Can I send an email only when a referral is approved?

Yes. Use the appropriate referral status-update point in your AffiliateWP workflow, check the transition you care about, and reuse the same Volanea payload construction. Store a per-referral marker so a repeated status update does not produce duplicate mail.

Where should I store the Volanea API key?

Store it as a server environment secret and expose it to WordPress through wp-config.php or your host’s secret manager. Never put it in JavaScript, public WordPress settings, page markup, or an AffiliateWP creative.

Why did an affiliate receive two referral emails?

A repeated conversion callback, a process retry, or an ambiguous timeout can trigger the handler more than once. Save an idempotency marker after a successful API response and use a queued worker plus stable event keys for stronger duplicate protection.