返回

WooCommerce 订单许可号生成: JavaScript 与 PHP 集成方案

php

生成 WooCommerce 订单许可号:JavaScript 与 PHP 集成方案

为 WooCommerce 订单生成许可号,并使其与 FileMaker 数据库中生成的许可号一致,是一个常见需求。尤其当需要在不同平台保持数据同步时,这一问题显得更为突出。本文将探讨如何利用 JavaScript 生成许可号,并通过 PHP 将其集成到 WooCommerce 订单完成邮件中。

问题分析

现有方案的问题在于 PHP 翻译的许可号生成算法与 FileMaker 或 JavaScript 版本不一致。这通常是因为不同编程语言在处理数值运算、字符串操作或字符编码时存在细微差异。因此,直接翻译算法难以保证结果一致。为了解决这个问题,核心思路是统一使用 JavaScript 生成许可号 ,然后在 WooCommerce 订单完成后,通过 PHP 调用 JavaScript 代码获取许可号并发送邮件。

解决方案

以下提供三种将 JavaScript 生成的许可号集成到 WooCommerce 的方案,分别适用于不同场景和技术水平的开发者。

方案一:利用 AJAX 在客户端生成许可号并发送至服务器

此方案在 WooCommerce 订单完成页面(感谢页面)利用 JavaScript 生成许可号,并通过 AJAX 将其发送到服务器端保存并触发邮件发送。

1. JavaScript 生成许可号 (reg-code.js):

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

    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 += '-[1]';  // Users is always 1

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

// 使用 WooCommerce 订单数据生成许可号
function generateAndSendLicense(orderData) {
  const regName = orderData.billing.first_name + orderData.billing.last_name; 
  const licenseCode = generateRegistrationCode(regName);
  const email = orderData.billing.email;
    if (!licenseCode) {
        console.error("Failed to generate registration code.");
        return;
    }

  jQuery.ajax({
    url: woocommerce_params.ajax_url, 
    method: 'POST',
    data: {
      action: 'send_license_email', 
      license_code: licenseCode,
      order_id: orderData.id,
      email: email
    },
    success: function(response) {
      if (response.success) {
        console.log('License code sent successfully!');
        // 可选:在页面上显示许可号
      } else {
        console.error('Failed to send license code:', response.data);
        // 可选:提示用户联系客服
      }
    },
    error: function(xhr, status, error) {
      console.error('AJAX error:', error);
        // 可选:提示用户联系客服
    }
  });
}

2. PHP 处理 AJAX 请求并发送邮件 (functions.php 或自定义插件):

// 加载 JavaScript 文件
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');
function enqueue_custom_scripts() {
    if(is_checkout()){
        wp_enqueue_script('custom-reg-code-js', get_stylesheet_directory_uri() . '/reg-code.js', array('jquery'), null, true);
         // 添加 WooCommerce ajax url 到页面
         wp_localize_script( 'custom-reg-code-js', 'woocommerce_params',
            array(
                'ajax_url' => admin_url( 'admin-ajax.php' )
            )
         );

    }

}
// 获取订单数据,并传递到 JavaScript 中
add_action( 'woocommerce_thankyou', 'custom_thankyou_page' );
function custom_thankyou_page( $order_id ) {

    $order = wc_get_order( $order_id );
    $order_data = $order->get_data();

    ?>
        <script>
        jQuery(document).ready(function($) {
          var orderData = <?php echo json_encode( $order_data ); ?>;
           generateAndSendLicense(orderData);

        });
        </script>
    <?php
}

// AJAX 处理函数
add_action('wp_ajax_send_license_email', 'send_license_email_handler');
add_action('wp_ajax_nopriv_send_license_email', 'send_license_email_handler');
function send_license_email_handler() {
  $license_code = sanitize_text_field($_POST['license_code']);
  $order_id = intval($_POST['order_id']);
    $email = sanitize_email($_POST['email']);

  if (empty($license_code) || empty($order_id)) {
    error_log("License code or order ID is empty.");
    wp_send_json_error('License code or order ID is empty.');
    return;
  }

    $order = wc_get_order($order_id);
    if (!$order){
      error_log("Order not found");
      wp_send_json_error('Order not Found.');
        return;
    }
    $name = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ;

    if(send_license_email($email, $name, $license_code)){
    error_log("License Email sent successfully.");
        wp_send_json_success("Email sent Successfully.");
        $order->add_order_note('License Code Email Sent Successfully to the customer'. $email  .' ,The Code is: '. $license_code );
        $order->save();
  }else {
      error_log("Failed to send License code Email.");
      wp_send_json_error('Failed to Send License code Email.');
  }

}

// 邮件发送函数
function send_license_email($to, $name, $license_code) {
    $subject = 'Your License Code';
    $message = "<html><body><h2>Thank you for your purchase!</h2><p>Dear {$name},</p><p>Your license code is: <strong>{$license_code}</strong></p><p>Please use this code to activate your product.</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);
}

3. 操作步骤:

  • reg-code.js 文件放置于你的主题目录下(或子主题目录下)。
  • 将上述 PHP 代码添加到 functions.php 文件或创建一个自定义插件。
  • 测试下单流程,确保订单完成后,可以在控制台看到许可号生成成功信息,并收到包含许可号的邮件。

4. 安全建议:

  • 在服务器端对 AJAX 请求进行校验,防止恶意请求。
  • 对许可号进行加密存储,保护用户数据安全。
  • 限制许可号的使用次数或时间,防止滥用。
    * 对输入的数据进行校验和清理,以防止代码注入攻击。

方案二:利用 Node.js 在服务器端生成许可号

此方案适用于有一定服务器管理经验的开发者。利用 Node.js 运行 JavaScript 代码,并通过 PHP 调用 Node.js 进程生成许可号。

1. 安装 Node.js:

*   在服务器上安装 Node.js