如何在WooCommerce中实现自动生成PDF的可售卖及下载功能
问题分析与解决方案
原代码失败的核心原因
- 严重安全漏洞:前端直接暴露WooCommerce REST API的
consumer_key和consumer_secret,任何人都可利用密钥篡改商店数据、删除订单,完全违背安全规范。 - 端点错误:WooCommerce REST API v3不存在
/wp-json/wc/v3/cart/add这个公开购物车操作端点,前端购物车交互应使用WooCommerce内置的Ajax机制。 - 逻辑偏差:动态生成的用户专属PDF无法绑定固定产品ID,必须通过购物车/订单元数据关联用户的专属文件,而非复用现有产品的下载链接。
完整实现步骤
步骤1:创建基础可下载产品模板
在WooCommerce后台新建一个简单产品,配置如下:
- 产品名称:自定义生成PDF
- 产品类型:简单产品
- 勾选「可下载」「虚拟」(无需实体发货)
- 设置产品价格,下载文件可临时填写一个占位文件(后续会动态替换)
- 记录该产品的ID(示例中用
123代替)
步骤2:前端Ajax代码(安全版)
表单生成PDF后,调用WordPress自定义Ajax动作传递PDF信息,避免直接操作REST API:
jQuery(document).ready(function($) { // 表单提交完成后,获取生成的PDF路径和文件名 var userPdfPath = '/wp-content/uploads/custom-pdfs/user-xxx-unique.pdf'; var userPdfName = '您的专属定制文件.pdf'; // 调用自定义Ajax接口加入购物车 $.ajax({ url: wc_add_to_cart_params.ajax_url, // 复用WooCommerce内置Ajax地址 method: 'POST', data: { action: 'add_custom_pdf_to_cart', product_id: '123', // 你的基础产品ID pdf_path: userPdfPath, pdf_name: userPdfName }, success: function(res) { res.success ? window.location.href = '/cart/' : alert('加入失败:' + res.data); }, error: function(xhr) { alert('请求出错:' + xhr.responseText); } }); });
步骤3:后端PHP处理代码
将以下代码添加到主题的functions.php或自定义插件中,处理购物车添加、订单关联PDF逻辑:
// 处理前端Ajax请求:添加定制PDF到购物车 add_action('wp_ajax_add_custom_pdf_to_cart', 'add_custom_pdf_to_cart'); add_action('wp_ajax_nopriv_add_custom_pdf_to_cart', 'add_custom_pdf_to_cart'); function add_custom_pdf_to_cart() { // 参数验证 if (!isset($_POST['product_id'], $_POST['pdf_path'], $_POST['pdf_name'])) { wp_send_json_error('缺少必要参数'); } $product_id = intval($_POST['product_id']); $pdf_path = sanitize_text_field($_POST['pdf_path']); $pdf_name = sanitize_text_field($_POST['pdf_name']); // 验证产品存在性 if (!wc_get_product($product_id)) { wp_send_json_error('产品不存在'); } // 添加产品到购物车 $cart_item_key = WC()->cart->add_to_cart($product_id); if (!$cart_item_key) { wp_send_json_error('加入购物车失败'); } // 把PDF信息存入购物车项元数据 WC()->cart->cart_contents[$cart_item_key]['custom_pdf'] = [ 'path' => $pdf_path, 'name' => $pdf_name ]; WC()->cart->set_session(); // 更新会话数据 wp_send_json_success('已成功加入购物车'); } // 订单完成后,将定制PDF绑定到用户下载权限 add_action('woocommerce_order_status_completed', 'attach_custom_pdf_to_order', 10, 1); function attach_custom_pdf_to_order($order_id) { $order = wc_get_order($order_id); foreach ($order->get_items() as $item) { $cart_item_key = $item->get_cart_item_key(); $session_cart = WC()->session->get('cart')[$cart_item_key] ?? []; if (isset($session_cart['custom_pdf'])) { $pdf_data = $session_cart['custom_pdf']; // 创建下载权限记录 $download_id = wc_add_download_id($order_id, [ 'name' => $pdf_data['name'], 'file' => $pdf_data['path'], 'downloads_remaining' => -1, // 无限制下载 'access_expires' => '' // 永不过期 ]); // 保存下载ID到订单元数据 $order->add_meta_data('_custom_pdf_download_id', $download_id, true); $order->save(); } } } // 在订单页面显示定制PDF的下载链接 add_filter('woocommerce_order_downloads', 'add_custom_pdf_to_order_downloads', 10, 2); function add_custom_pdf_to_order_downloads($downloads, $order) { $download_id = $order->get_meta('_custom_pdf_download_id'); if ($download_id) { $download = wc_get_download($download_id); if ($download) { $downloads[] = [ 'id' => $download_id, 'name' => $download->get_name(), 'file' => $download->get_file(), 'download_url' => $download->get_download_url($order), 'downloads_remaining' => $download->get_downloads_remaining(), 'access_expires' => $download->get_access_expires() ]; } } return $downloads; }
内容的提问来源于stack exchange,提问作者Steffan Jacobsen
相关产品推荐
相关产品推荐

