You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WooCommerce订单邮件中加入与FileMaker匹配的JS生成许可证号?

问题

我需要在WordPress(WooCommerce)站点上生成与独立无服务器FileMaker数据库完全一致的许可证号,并在订单完成时通过邮件发送给客户。Web端与FileMaker唯一通用的语言是JavaScript,我已在FileMaker中通过网页视图抓取客户姓名生成许可证号,但在网站上实现匹配流程的尝试全部失败。

核心疑问:能否用JavaScript生成许可证号,并将结果纳入WooCommerce订单完成邮件?

已尝试的方案及问题
  • 将FileMaker的许可证生成逻辑转译为PHP并添加到主题functions.php:能生成并发送许可证号,但生成的号码与FileMaker内JS或原生生成的完全不匹配。
  • 尝试通过PHP调用JavaScript生成许可证号再发送邮件(使用functions.php、代码片段或自制插件):完全无效,且无法生成调试文件排查问题。
现有代码片段

PHP代码(用于调用JS的后端逻辑)

add_action('wp_enqueue_scripts', 'enqueue_custom_js');

function enqueue_custom_js() {
    wp_enqueue_script('custom-reg-code-js', plugin_dir_url(__FILE__) . 'reg-code.js', array('jquery'), null, true);
    wp_localize_script('custom-reg-code-js', 'customData', array(
        'ajaxUrl' => admin_url('admin-ajax.php'),
    ));
}

add_action('wp_ajax_custom_send_email', 'custom_send_email');
add_action('wp_ajax_nopriv_custom_send_email', 'custom_send_email');

function custom_send_email() {
    $regName = sanitize_text_field($_POST['regName']);
    $users = intval($_POST['users']);
    $email = sanitize_email($_POST['email']);
    $regCode = sanitize_text_field($_POST['regCode']);

    error_log("Received AJAX: RegName - $regName, Users - $users, Email - $email, RegCode - $regCode");

    if (empty($regCode) || empty($email)) {
        error_log("Registration code or email is empty.");
        wp_send_json_error('Registration code or email is empty.');
        return;
    }

    $email_sent = send_registration_email($email, $regName, $regCode);
    if ($email_sent) {
        error_log("Email sent successfully.");
        wp_send_json_success('Email sent successfully.');
    } else {
        error_log("Failed to send email.");
        wp_send_json_error('Failed to send email.');
    }
}

function send_registration_email($to, $name, $registration_code) {
    $subject = 'Your Registration Code New';
    $message = "<html><body><h2>Thank you for your purchase!</h2><p>Dear {$name},</p><p>Your registration code is: <strong>{$registration_code}</strong></p><p>Please use this code to activate your new software.</p><p>If you have any questions, please don't hesitate to contact our support team.</p><p>Best regards,<br>Your Company Name</p></body></html>";
    $headers = array('Content-Type: text/html; charset=UTF-8');

    return wp_mail($to, $subject, $message, $headers);
}

JavaScript代码(许可证生成逻辑)

function generateRegistrationCode(regName, users) {
    const solutionKey = 'tcuXd6A4WQ';
    
    if (!regName || !solutionKey) {
        console.error('Registration name or solution key is empty.');
        return '';
    }

    // Always append users (which is set to 1)
    regName += users;

    let len = regName.length;
    let chr = 0, pos = 0;

    for (let loop = 0; loop < len; loop++) {
        const ascii = regName.charCodeAt(loop);
        chr += ascii;
        pos += (ascii * (loop + 1));
    }

    const sum = chr + pos + len;
    const numString = `${sum}${pos}${chr}${len}${sum * sum}`;
    let codePreFormatted = '';

    let loop = 0;
    while (loop < numString.length) {
        const convertNum = (parseInt(numString.substr(loop, 2)) > 56) ? parseInt(numString.substr(loop, 1)) : parseInt(numString.substr(loop, 2));
        codePreFormatted += (convertNum == 0) ? solutionKey[0] + solutionKey[1] : solutionKey[convertNum];
        loop += convertNum.toString().length;
    }

    let codeFormatted = '';
    for (let loop = 0; loop < codePreFormatted.length; loop += 4) {
        if (codeFormatted) codeFormatted += '-';
        codeFormatted += codePreFormatted.substr(loop, 4);
    }

    // Append users (always 1) to the final code
    codeFormatted += `-[${users}]`;

    console.log(`Generated registration code: ${codeFormatted}`);

    // Append the registration code to the checkout page
    document.getElementById('registration-code-display').innerText = codeFormatted || 'Registration code generation failed.';
    
    return codeFormatted;
}

// Send registration code via AJAX
function sendRegistrationCode(email, regName, users) {
    const regCode = generateRegistrationCode(regName, users);

    if (!regCode) {
        alert("Registration code generation failed. Please check the input.");
        console.error("Failed to generate registration code.");
        return;
    }

    // Perform AJAX request to send the email
    jQuery.ajax({
        url: customData.ajaxUrl,
        method: 'POST',
        data: {
            action: 'custom_send_email',
            regName: regName,
            users: users,
            email: email,
            regCode: regCode,
        },
        success: function(response) {
            if (response.success) {
                alert('Registration code sent successfully!');
            } else {
                alert('Failed to send the registration code: ' + response.data);
                console.error('Failed to send the registration code:', response.data);
            }
        },
        error: function(xhr, status, error) {
            alert('An error occurred: ' + error);
            console.error('AJAX error:', error);
        }
    });
}
额外说明
  • JavaScript代码中的users参数可移除,因为当前始终仅1个用户。
  • 客户付款后订单会自动完成。
可行解决方案

由于PHP转译逻辑无法匹配FileMaker的结果,建议直接复用已验证的JavaScript生成逻辑,通过以下两种方式实现:

方案1:使用PHP的V8JS扩展(服务器支持时优先)

若服务器安装了v8js扩展,可直接在PHP后端执行JS生成逻辑,确保与FileMaker结果一致:

add_action('woocommerce_order_status_completed', 'generate_and_send_license_on_completion', 10, 1);

function generate_and_send_license_on_completion($order_id) {
    $order = wc_get_order($order_id);
    $email = $order->get_billing_email();
    $regName = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name();
    $users = 1; // 固定为1,可移除

    // 复用FileMaker验证过的JS逻辑
    $js_code = <<<JS
    function generateRegistrationCode(regName, users) {
        const solutionKey = 'tcuXd6A4WQ';
        
        if (!regName || !solutionKey) {
            return '';
        }

        regName += users;

        let len = regName.length;
        let chr = 0, pos = 0;

        for (let loop = 0; loop < len; loop++) {
            const ascii = regName.charCodeAt(loop);
            chr += ascii;
            pos += (ascii * (loop + 1));
        }

        const sum = chr + pos + len;
        const numString = `${sum}${pos}${chr}${len}${sum * sum}`;
        let codePreFormatted = '';

        let loop = 0;
        while (loop < numString.length) {
            const convertNum = (parseInt(numString.substr(loop, 2)) > 56) ? parseInt(numString.substr(loop, 1)) : parseInt(numString.substr(loop, 2));
            codePreFormatted += (convertNum == 0) ? solutionKey[0] + solutionKey[1] : solutionKey[convertNum];
            loop += convertNum.toString().length;
        }

        let codeFormatted = '';
        for (let loop = 0; loop < codePreFormatted.length; loop += 4) {
            if (codeFormatted) codeFormatted += '-';
            codeFormatted += codePreFormatted.substr(loop, 4);
        }

        codeFormatted += `-[${users}]`;
        
        return codeFormatted;
    }
    generateRegistrationCode('{$regName}', {$users});
JS;

    $v8 = new V8Js();
    $regCode = $v8->executeString($js_code);

    // 发送邮件并保存许可证到订单备注
    if (!empty($regCode) && !empty($email)) {
        send_registration_email($email, $regName, $regCode);
        $order->add_order_note('Generated license code: ' . $regCode);
        $order->save();
    }
}

方案2:前端订单完成页面触发(适合无法安装V8JS的情况)

修改前端逻辑,在订单完成页面自动触发许可证生成和邮件发送:

  1. 更新JavaScript代码,监听订单完成页面加载:
jQuery(document).ready(function() {
    // 检测是否为订单完成页面
    if (jQuery('body').hasClass('woocommerce-order-received')) {
        // 从页面获取订单信息
        const email = jQuery('.woocommerce-customer-details .email').text().trim();
        const regName = jQuery('.woocommerce-customer-details .name').text().trim();
        const users = 1;

        // 生成并发送许可证号
        sendRegistrationCode(email, regName, users);
    }
});
  1. 在PHP中添加订单完成页面的必要数据支持:
add_action('woocommerce_thankyou', 'add_order_data_for_license_generation', 10, 1);

function add_order_data_for_license_generation($order_id) {
    $order = wc_get_order($order_id);
    // 确保页面元素包含订单信息
    echo '<div class="woocommerce-customer-details">
            <p class="name">' . esc_html($order->get_billing_first_name() . ' ' . $order->get_billing_last_name()) . '</p>
            <p class="email">' . esc_html($order->get_billing_email()) . '</p>
          </div>';
}

内容的提问来源于stack exchange,提问作者Richard Morley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:12:03