Variables are not being populated in triggered email

I’m having trouble with
I have created a custom order form on my website. The frontend code is working, the backend code is working, but whenever the submit button is hit, the email is triggered but the variables aren’t populated correctly. They just show up as Sample ().

Working in
Wix Editor Dev Mode

Site link

What I’m trying to do
Once the form is submitted, I want the trigger email sent to the customer email with their full data input (I want their full order replicated in the trigger email).

What I’ve tried so far
I’ve run this through AI (ChatGPT, Perplexity, CoPilot) trying to figure out where things have gone awry, and am coming up with nothing. I can confirm that all the IDs are correct and correctly formatted. This is a new-ish world for me, so I don’t know what I’m missing.

**
Front End Code**

import { sendCustomerEmail, sendAdminEmail } from ‘backend/email’;
import { contacts } from ‘wix-crm’;

$w.onReady(() => {
console.log(“Page loaded! Testing button listener…”);
$w(“#submitbutton”).onClick(() => console.log(“Submit button clicked!”));

// Prices for products
const prices = {
macDozen: 21,
macSeasonal: 12,
macBestseller: 12,
macClassic: 12,
macFruit: 12,
macMaple: 12,
merSeasonal: 5,
merBerries: 5,
merMaple: 5,
merVanilla: 5
};

const fieldMap = {
macDozen: “macDozenSub”,
macSeasonal: “macSeasonalSub”,
macBestseller: “macBestsellerSub”,
macClassic: “macClassicSub”,
macFruit: “macFruitSub”,
macMaple: “macMapleSub”,
merSeasonal: “merSeasonalSub”,
merBerries: “merBerriesSub”,
merMaple: “merMapleSub”,
merVanilla: “merVanillaSub”
};

const allFields = Object.keys(prices);

allFields.forEach(id => {
const input = $w(#${id});
if (input) input.onChange(updateTotals);
});

function updateTotals() {
let grandTotal = 0;
allFields.forEach(id => {
const qty = Number($w(#${id}).value);
const safeQty = isNaN(qty) ? 0 : qty;
const subtotal = safeQty * prices[id];
$w(#${fieldMap[id]}).value = $${subtotal.toFixed(2)};
grandTotal += subtotal;
});
$w(“#totalAmount”).value = $${grandTotal.toFixed(2)};
}

updateTotals();

$w(“#submitbutton”).onClick(async () => {
try {
const name = $w(“#Name”).value.trim();
const email = $w(“#Email”).value.trim();
const business = $w(“business”).value.trim();

  if (!name || !email) {
    showError("Please enter your name and email.");
    return;
  }

  // Prepare variables for triggered email, converting all to strings
  const variables = {
    name: String(name),
    email: String(email),
    business: String(business),
    macDozen: String($w("#macDozen").value),
    macDozenSub: String($w("#macDozenSub").value),
    macSeasonal: String($w("#macSeasonal").value),
    macSeasonalSub: String($w("#macSeasonalSub").value),
    macBestseller: String($w("#macBestseller").value),
    macBestsellerSub: String($w("#macBestsellerSub").value),
    macClassic: String($w("#macClassic").value),
    macClassicSub: String($w("#macClassicSub").value),
    macFruit: String($w("#macFruit").value),
    macFruitSub: String($w("#macFruitSub").value),
    macMaple: String($w("#macMaple").value),
    macMapleSub: String($w("#macMapleSub").value),
    merSeasonal: String($w("#merSeasonal").value),
    merSeasonalSub: String($w("#merSeasonalSub").value),
    merBerries: String($w("#merBerries").value),
    merBerriesSub: String($w("#merBerriesSub").value),
    merMaple: String($w("#merMaple").value),
    merMapleSub: String($w("#merMapleSub").value),
    merVanilla: String($w("#merVanilla").value),
    merVanillaSub: String($w("#merVanillaSub").value),
    totalAmount: String($w("#totalAmount").value),
  };

  // Create or update contact in Wix CRM (company is a string)
  const contact = await contacts.appendOrCreateContact({
    name: { first: name },
    emails: [{ email }],
    company: business || ""
  });

  if (!contact || !contact.contactId) {
    throw new Error("Contact creation or retrieval failed.");
  }

  await sendCustomerEmail(contact.contactId, variables);
  await sendAdminEmail(variables);

  showSuccess("Thank you! Your order has been submitted and confirmation emails have been sent.");
} catch (error) {
  console.error(error);
  showError("There was an error submitting your order. Please try again.");
}

});

function showSuccess(msg) {
if ($w(“#successMessage”)) {
$w(“#successMessage”).text = msg;
$w(“#successMessage”).show(“fade”);
}
if ($w(“#errorMessage”)) {
$w(“#errorMessage”).hide(“fade”);
}
}

function showError(msg) {
if ($w(“#errorMessage”)) {
$w(“#errorMessage”).text = msg;
$w(“#errorMessage”).show(“fade”);
}
if ($w(“#successMessage”)) {
$w(“#successMessage”).hide(“fade”);
}
}
});

**
Back End Code (email.jsw)**

import { triggeredEmails } from ‘wix-crm-backend’;
import { contacts } from ‘wix-crm-backend’;

/**

  • Retrieve admin contact ID dynamically
    */
    async function getAdminContactId() {
    try {
    const result = await contacts.queryContacts()
    .eq(‘info.emails.email’, ‘yum@smallovenpastries.com’)
    .find();

    if (result.items.length > 0) {
    const adminId = result.items[0]._id;
    console.log(“Admin contact found:”, adminId);
    return adminId;
    } else {
    console.error(“No contact found for yum@smallovenpastries.com”);
    return null;
    }
    } catch (err) {
    console.error(“Error fetching admin contact ID:”, err);
    return null;
    }
    }

/**

  • Send confirmation email to customer
    */
    export async function sendCustomerEmail(contactId, variables) {
    try {
    console.log(“Sending customer email with variables:”, variables);

    const CUSTOMER_EMAIL_ID = ‘V0Z6NLW’; // Replace with your ID

    await triggeredEmails.emailContact(CUSTOMER_EMAIL_ID, contactId, variables);
    console.log(“:white_check_mark: Customer confirmation email sent successfully.”);
    } catch (err) {
    console.error(“:cross_mark: Error sending customer email:”, err);
    }
    }

/**

  • Send notification email to admin
    */
    export async function sendAdminEmail(variables) {
    try {
    console.log(“Preparing to send admin email with variables:”, variables);

    const adminContactId = await getAdminContactId();
    if (!adminContactId) {
    console.error(“:cross_mark: Admin email aborted: contact not found.”);
    return;
    }

    const ADMIN_EMAIL_ID = ‘V0Z72cX’; // Replace with your ID

    await triggeredEmails.emailContact(ADMIN_EMAIL_ID, adminContactId, variables);
    console.log(“:white_check_mark: Admin notification email sent successfully.”);
    } catch (err) {
    console.error(“:cross_mark: Error sending admin email:”, err);
    }
    }

Triggered Email Code

Order Summary

Name: ${Name}

Business: ${Business}

Email: ${Email}

Notes: ${Notes}

Dozen Macarons: ${macDozen} (${macDozenSub})

Seasonal Macarons: ${macSeasonal} (${macSeasonalSub})

Bestseller Macarons: ${macBestseller} (${macBestsellerSub})

Classic Macarons: ${macClassic} (${macClassicSub})

Fruit Macarons: ${macFruit} (${macFruitSub})

Maple Macarons: ${macMaple} (${macMapleSub})

Seasonal Meringues: ${merSeasonal} (${merSeasonalSub})

Berries Meringues: ${merBerries} (${merBerriesSub})

Maple Meringues: ${merMaple} (${merMapleSub})

Vanilla Meringues: ${merVanilla} (${merVanillaSub})

Total Amount: ${totalAmount}