WooCommerce订单支付成功触发SQL执行与邮件发送的实现问题
WooCommerce 虚拟产品订单自动生成授权信息实现方案
原有代码核心问题
- 产品ID判断逻辑错误:
$item->get_id()返回的是订单项ID,并非产品本身ID,导致目标产品无法被正确匹配 - 产品ID配置错误:你需要处理的产品ID为23、24、26,原代码配置的ID数组为18-23,完全不符合需求
- 数据库操作错误:
mysqli_query调用缺少必填的连接对象参数,且插入语句写死了测试数据,没有传入动态生成的用户、产品、密码、序列号信息,同时存在SQL注入风险 - 无唯一性校验:生成的密码、序列号没有和数据库已存数据做重复校验,会出现重复发放的问题
- 邮件逻辑错误:收件人写死为固定邮箱,没有发给实际下单用户,且内容无换行格式混乱
- 缺少虚拟产品校验:没有判断产品类型,可能误处理实物订单
修正后可运行代码
将以下代码放入子主题的functions.php文件即可:
<?php // 校验生成的值是否唯一,避免重复密码/序列号 function generate_unique_value($conn, $field_name) { do { if ($field_name == 'user_passwd') { // 生成10位不含特殊字符的密码,可根据需求调整长度和规则 $value = wp_generate_password(10, false); } else { // 生成8位随机序列号,可根据需求调整规则 $value = rand(10000000, 99999999); } // 查询是否已存在于数据库 $check_sql = "SELECT id FROM tableTest_v5 WHERE `$field_name` = '".mysqli_real_escape_string($conn, $value)."' LIMIT 1"; $check_res = mysqli_query($conn, $check_sql); } while (mysqli_num_rows($check_res) > 0); return $value; } // 订单支付完成触发逻辑 add_action( 'woocommerce_payment_complete', 'custom_virtual_product_process_after_payment' ); function custom_virtual_product_process_after_payment( $order_id ) { // 加载数据库连接配置,请确保connect.inc.php和子主题functions.php同目录 include_once ('connect.inc.php'); $conn = mysqli_connect($DBHost, $DBLogin, $DBPass, $DBName); // 连接失败直接跳过,不影响订单正常流程 if ($conn->connect_error) return; // 配置需要处理的专属虚拟产品ID,后续新增产品直接加在数组里即可 $target_product_ids = [23,24,26]; $order = wc_get_order( $order_id ); foreach ( $order->get_items() as $item ) { $product_id = $item->get_product_id(); // 只处理指定ID的虚拟产品 if ( !in_array($product_id, $target_product_ids) ) continue; $product = wc_get_product($product_id); if ( !$product->is_virtual() ) continue; $buy_qty = $item->get_quantity(); $customer_name = $order->get_billing_first_name().' '.$order->get_billing_last_name(); $customer_email = $order->get_billing_email(); $product_name = $product->get_name(); // 按购买数量循环生成独立的授权信息 for ($i=0; $i < $buy_qty; $i++) { // 生成唯一的密码和序列号 $password = generate_unique_value($conn, 'user_passwd'); $serial_number = generate_unique_value($conn, 'user_licensenumber'); // 插入数据到自定义表,字段值可根据你的表结构调整 $insert_sql = "INSERT INTO `tableTest_v5` ( `state_account`, `user_email`, `user_passwd`, `user_fullname`, `user_licensenumber`, `software_product`, `activation_cpt`, `superaccess` ) VALUES ( -1, '".mysqli_real_escape_string($conn, $customer_email)."', '".mysqli_real_escape_string($conn, $password)."', '".mysqli_real_escape_string($conn, $customer_name)."', '".mysqli_real_escape_string($conn, $serial_number)."', '".mysqli_real_escape_string($conn, $product_name)."', 3, 0 )"; mysqli_query($conn, $insert_sql); // 发送授权信息邮件给用户 $message = "Hi ".$customer_name.",\r\n"; $message .= "您购买的产品信息如下:\r\n"; $message .= "产品名称:".$product_name."\r\n"; $message .= "登录邮箱:".$customer_email."\r\n"; $message .= "登录密码:".$password."\r\n"; $message .= "产品序列号:".$serial_number."\r\n"; $headers = array('Content-Type: text/plain; charset=UTF-8'); wp_mail($customer_email, '您购买的虚拟产品授权信息', $message, $headers); } } mysqli_close($conn); } ?>
注意事项
- 请确保
connect.inc.php中正确配置了数据库连接的4个参数:$DBHost、$DBLogin、$DBPass、$DBName - 若你的
tableTest_v5表有其他必填字段,请自行调整插入语句的字段和对应值 - 密码、序列号的生成规则可根据业务需求在
generate_unique_value函数中修改 - 首次使用请先在测试环境或沙箱环境验证流程正常,再部署到生产环境
内容的提问来源于stack exchange,提问作者Nicolas SDL
相关产品推荐
相关产品推荐

