文章目录
-
- 在数字文创产业快速发展的今天,内容创作者需要一个灵活的系统来管理和交付他们的数字产品。本教程将指导您开发一个WordPress插件,实现文创数字产品的柔性交付与授权管理。 核心功能需求: 支持多种数字产品类型(电子书、图片、音频、视频等) 灵活的交付方式(直接下载、邮件发送、API接口) 授权管理(使用期限、设备限制、访问次数) 订单与用户管理 安全防护与防滥用机制
- 首先,我们创建插件的基本文件结构: <?php /** * Plugin Name: 文创数字产品交付与授权系统 * Plugin URI: https://yourwebsite.com/ * Description: 为WordPress网站提供文创数字产品的柔性交付与授权管理功能 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('CDPDA_VERSION', '1.0.0'); define('CDPDA_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('CDPDA_PLUGIN_URL', plugin_dir_url(__FILE__)); // 初始化插件 class CulturalDigitalProduct_DeliveryAuth { private static $instance = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->init_hooks(); } private function init_hooks() { // 激活/停用钩子 register_activation_hook(__FILE__, array($this, 'activate')); register_deactivation_hook(__FILE__, array($this, 'deactivate')); // 初始化 add_action('init', array($this, 'init')); // 管理菜单 add_action('admin_menu', array($this, 'add_admin_menu')); // 加载脚本和样式 add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts')); add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts')); } public function activate() { // 创建必要的数据库表 $this->create_database_tables(); // 设置默认选项 $this->set_default_options(); // 刷新重写规则 flush_rewrite_rules(); } public function deactivate() { // 清理临时数据 // 注意:不删除用户数据 flush_rewrite_rules(); } public function init() { // 注册自定义文章类型 $this->register_post_types(); // 注册短代码 $this->register_shortcodes(); } // 其他方法将在后续部分实现 } // 启动插件 CulturalDigitalProduct_DeliveryAuth::get_instance(); ?>
- 创建必要的数据库表来存储产品、订单和授权信息: <?php // 在activate方法中调用 private function create_database_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); // 产品表 $table_products = $wpdb->prefix . 'cdpda_products'; $sql_products = "CREATE TABLE IF NOT EXISTS $table_products ( id bigint(20) NOT NULL AUTO_INCREMENT, post_id bigint(20) NOT NULL, product_type varchar(50) NOT NULL, file_path text, file_size bigint(20), file_hash varchar(64), delivery_methods text, price decimal(10,2), created_at datetime DEFAULT CURRENT_TIMESTAMP, updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY post_id (post_id) ) $charset_collate;"; // 订单表 $table_orders = $wpdb->prefix . 'cdpda_orders'; $sql_orders = "CREATE TABLE IF NOT EXISTS $table_orders ( id bigint(20) NOT NULL AUTO_INCREMENT, order_number varchar(50) NOT NULL, user_id bigint(20) NOT NULL, product_id bigint(20) NOT NULL, amount decimal(10,2) NOT NULL, status varchar(20) DEFAULT 'pending', payment_method varchar(50), transaction_id varchar(100), customer_email varchar(100), customer_ip varchar(45), created_at datetime DEFAULT CURRENT_TIMESTAMP, completed_at datetime, PRIMARY KEY (id), UNIQUE KEY order_number (order_number), KEY user_id (user_id), KEY product_id (product_id) ) $charset_collate;"; // 授权表 $table_licenses = $wpdb->prefix . 'cdpda_licenses'; $sql_licenses = "CREATE TABLE IF NOT EXISTS $table_licenses ( id bigint(20) NOT NULL AUTO_INCREMENT, license_key varchar(64) NOT NULL, order_id bigint(20) NOT NULL, product_id bigint(20) NOT NULL, user_id bigint(20), expires_at datetime, max_devices int DEFAULT 1, usage_count int DEFAULT 0, max_usage int DEFAULT NULL, status varchar(20) DEFAULT 'active', created_at datetime DEFAULT CURRENT_TIMESTAMP, last_used datetime, PRIMARY KEY (id), UNIQUE KEY license_key (license_key), KEY order_id (order_id), KEY product_id (product_id), KEY user_id (user_id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql_products); dbDelta($sql_orders); dbDelta($sql_licenses); } ?>
- 创建自定义文章类型来管理数字产品: <?php private function register_post_types() { // 注册数字产品自定义文章类型 $labels = array( 'name' => '数字产品', 'singular_name' => '数字产品', 'menu_name' => '数字产品', 'add_new' => '添加产品', 'add_new_item' => '添加新数字产品', 'edit_item' => '编辑产品', 'new_item' => '新产品', 'view_item' => '查看产品', 'search_items' => '搜索产品', 'not_found' => '未找到产品', 'not_found_in_trash' => '回收站中无产品' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array('slug' => 'digital-product'), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => 30, 'menu_icon' => 'dashicons-products', 'supports' => array('title', 'editor', 'thumbnail', 'excerpt'), 'show_in_rest' => true ); register_post_type('digital_product', $args); // 添加产品类型分类 register_taxonomy( 'product_type', 'digital_product', array( 'label' => '产品类型', 'rewrite' => array('slug' => 'product-type'), 'hierarchical' => true, 'show_in_rest' => true ) ); } // 添加产品元数据框 public function add_product_meta_boxes() { add_meta_box( 'cdpda_product_details', '产品详情', array($this, 'render_product_meta_box'), 'digital_product', 'normal', 'high' ); } public function render_product_meta_box($post) { // 获取现有值 $product_type = get_post_meta($post->ID, '_cdpda_product_type', true); $price = get_post_meta($post->ID, '_cdpda_price', true); $file_url = get_post_meta($post->ID, '_cdpda_file_url', true); $delivery_methods = get_post_meta($post->ID, '_cdpda_delivery_methods', true); // 非ce字段 wp_nonce_field('cdpda_save_product_meta', 'cdpda_product_meta_nonce'); // 显示表单 ?> <div class="cdpda-meta-box"> <div class="cdpda-field"> <label for="cdpda_product_type">产品类型:</label> <select id="cdpda_product_type" name="cdpda_product_type"> <option value="ebook" <?php selected($product_type, 'ebook'); ?>>电子书</option> <option value="image" <?php selected($product_type, 'image'); ?>>图片</option> <option value="audio" <?php selected($product_type, 'audio'); ?>>音频</option> <option value="video" <?php selected($product_type, 'video'); ?>>视频</option> <option value="software" <?php selected($product_type, 'software'); ?>>软件</option> <option value="template" <?php selected($product_type, 'template'); ?>>模板</option> </select> </div> <div class="cdpda-field"> <label for="cdpda_price">价格(元):</label> <input type="number" id="cdpda_price" name="cdpda_price" value="<?php echo esc_attr($price); ?>" step="0.01" min="0"> </div> <div class="cdpda-field"> <label for="cdpda_file_url">文件URL:</label> <input type="url" id="cdpda_file_url" name="cdpda_file_url" value="<?php echo esc_url($file_url); ?>" style="width: 70%;"> <button type="button" class="button cdpda-upload-file">上传文件</button> </div> <div class="cdpda-field"> <label>交付方式:</label> <label><input type="checkbox" name="cdpda_delivery_methods[]" value="direct_download" <?php echo in_array('direct_download', (array)$delivery_methods) ? 'checked' : ''; ?>> 直接下载</label> <label><input type="checkbox" name="cdpda_delivery_methods[]" value="email" <?php echo in_array('email', (array)$delivery_methods) ? 'checked' : ''; ?>> 邮件发送</label> <label><input type="checkbox" name="cdpda_delivery_methods[]" value="api" <?php echo in_array('api', (array)$delivery_methods) ? 'checked' : ''; ?>> API接口</label> </div> </div> <?php } // 保存产品元数据 public function save_product_meta($post_id) { // 安全检查 if (!isset($_POST['cdpda_product_meta_nonce']) || !wp_verify_nonce($_POST['cdpda_product_meta_nonce'], 'cdpda_save_product_meta')) { return; } // 检查自动保存 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // 检查权限 if (!current_user_can('edit_post', $post_id)) { return; } // 保存字段 $fields = array( 'cdpda_product_type', 'cdpda_price', 'cdpda_file_url' ); foreach ($fields as $field) { if (isset($_POST[$field])) { update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field])); } } // 保存交付方式(数组) if (isset($_POST['cdpda_delivery_methods'])) { $delivery_methods = array_map('sanitize_text_field', $_POST['cdpda_delivery_methods']); update_post_meta($post_id, '_cdpda_delivery_methods', $delivery_methods); } else { delete_post_meta($post_id, '_cdpda_delivery_methods'); } } ?>
- 实现授权密钥生成和验证系统: <?php class CDPDA_License_Manager { /** * 生成授权密钥 * @param int $order_id 订单ID * @param int $product_id 产品ID * @param array $options 授权选项 * @return string 授权密钥 */ public static function generate_license_key($order_id, $product_id, $options = array()) { // 基础数据 $data = array( 'order_id' => $order_id, 'product_id' => $product_id, 'timestamp' => time(), 'rand' => wp_generate_password(8, false) ); // 合并选项 $data = array_merge($data, $options); // 创建字符串 $string = implode('|', $data); // 生成密钥(使用SHA256哈希) $license_key = hash('sha256', $string); // 格式化为分段显示 $formatted_key = implode('-', str_split($license_key, 8)); return $formatted_key; } /** * 验证授权密钥 * @param string $license_key 授权密钥 * @param int $product_id 产品ID(可选) * @return array|bool 验证结果 */ public static function validate_license($license_key, $product_id = null) { global $wpdb; // 清理密钥格式 $clean_key = str_replace('-', '', $license_key); $table_licenses = $wpdb->prefix . 'cdpda_licenses'; // 构建查询 $query = $wpdb->prepare( "SELECT * FROM $table_licenses WHERE license_key = %s AND status = 'active'", $clean_key ); if ($product_id) { $query .= $wpdb->prepare(" AND product_id = %d", $product_id); } $license = $wpdb->get_row($query, ARRAY_A); if (!$license) { return array( 'valid' => false, 'message' => '授权密钥无效或已过期' ); } // 检查过期时间 if ($license['expires_at'] && strtotime($license['expires_at']) < time()) { return array( 'valid' => false, 'message' => '授权已过期' ); } // 检查使用次数限制 if ($license['max_usage'] && $license['usage_count'] >= $license['max_usage']) { return array( 'valid' => false, 'message' => '已达到最大使用次数' ); } // 更新最后使用时间 $wpdb->update( $table_licenses, array( 'last_used' => current_time('mysql'), 'usage_count' => $license['usage_count'] + 1 ), array('id' => $license['id']) ); return array( 'valid' => true, 'license' => $license, 'message' => '授权验证成功' ); } /** * 创建授权记录 * @param array $data 授权数据 * @return int|bool 授权ID或false */ public static function create_license($data) { global $wpdb; $table_licenses = $wpdb->prefix . 'cdpda_licenses'; $defaults = array( 'license_key' => '', 'order_id' => 0, 'product_id' => 0, 'user_id' => 0, 'expires_at' => null, 'max_devices' => 1, 'max_usage' => null, 'status' => 'active' ); $data = wp_parse_args($data, $defaults); // 如果没有提供密钥,生成一个 if (empty($data['license_key'])) { $data['license_key'] = str_replace('-', '', self::generate_license_key($data['order_id'], $data['product_id']) ); } // 插入数据库 $result = $wpdb->insert($table_licenses, $data); if ($result) { return $wpdb->insert_id; } return false; } } ?>
- 实现多种交付方式: <?php class CDPDA_Delivery_System { /** * 交付数字产品 * @param int $order_id 订单ID * @param string $method 交付方式 * @return array 交付结果 */ public static function deliver_product($order_id, $method = 'direct_download') { global $wpdb; $table_orders = $wpdb->prefix . 'cdpda_orders'; <?php $wpdb->prefix . 'cdpda_products'; // 获取订单信息 $order = $wpdb->get_row($wpdb->prepare( "SELECT o.*, p.post_id, p.file_path, p.delivery_methods FROM $table_orders o LEFT JOIN $table_products p ON o.product_id = p.id WHERE o.id = %d", $order_id ), ARRAY_A); if (!$order) { return array( 'success' => false, 'message' => '订单不存在' ); } // 检查订单状态 if ($order['status'] !== 'completed') { return array( 'success' => false, 'message' => '订单未完成支付' ); } // 根据交付方式处理 switch ($method) { case 'direct_download': return self::direct_download($order); case 'email': return self::email_delivery($order); case 'api': return self::api_delivery($order); default: return array( 'success' => false, 'message' => '不支持的交付方式' ); } } /** * 直接下载交付 */ private static function direct_download($order) { $file_path = get_post_meta($order['post_id'], '_cdpda_file_url', true); if (!$file_path || !file_exists($file_path)) { return array( 'success' => false, 'message' => '文件不存在' ); } // 记录下载日志 self::log_download($order['id'], 'direct_download'); // 生成临时下载链接(带过期时间) $download_url = self::generate_download_url($order['id']); return array( 'success' => true, 'message' => '下载链接已生成', 'download_url' => $download_url, 'expires_in' => '24小时' ); } /** * 邮件交付 */ private static function email_delivery($order) { $customer_email = $order['customer_email']; $product_title = get_the_title($order['post_id']); $file_path = get_post_meta($order['post_id'], '_cdpda_file_url', true); // 生成下载链接 $download_url = self::generate_download_url($order['id']); // 邮件内容 $subject = '您的数字产品已准备就绪:' . $product_title; $message = " <html> <body> <h2>感谢您的购买!</h2> <p>您购买的产品 <strong>{$product_title}</strong> 已准备就绪。</p> <p>下载链接:<a href='{$download_url}'>{$download_url}</a></p> <p>链接有效期:24小时</p> <p>如需帮助,请联系客服。</p> </body> </html> "; // 设置邮件头 $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>' ); // 发送邮件 $sent = wp_mail($customer_email, $subject, $message, $headers); if ($sent) { // 记录邮件发送日志 self::log_delivery($order['id'], 'email'); return array( 'success' => true, 'message' => '产品已发送到您的邮箱' ); } return array( 'success' => false, 'message' => '邮件发送失败' ); } /** * API接口交付 */ private static function api_delivery($order) { // 生成API访问令牌 $api_token = self::generate_api_token($order['id']); // 创建API端点 $api_endpoint = home_url('/cdpda-api/v1/download/' . $order['id']); return array( 'success' => true, 'message' => 'API访问信息已生成', 'api_endpoint' => $api_endpoint, 'api_token' => $api_token, 'expires_in' => '72小时' ); } /** * 生成下载URL */ private static function generate_download_url($order_id) { $token = wp_hash($order_id . time()); // 存储临时令牌(24小时有效) set_transient('cdpda_download_' . $token, $order_id, 24 * HOUR_IN_SECONDS); return add_query_arg(array( 'cdpda_download' => $token, 'order_id' => $order_id ), home_url('/download/')); } /** * 记录下载日志 */ private static function log_download($order_id, $method) { global $wpdb; $table_logs = $wpdb->prefix . 'cdpda_download_logs'; $wpdb->insert($table_logs, array( 'order_id' => $order_id, 'delivery_method' => $method, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'downloaded_at' => current_time('mysql') )); } } ?>
- <?php class CDPDA_Order_Processor { /** * 创建新订单 */ public static function create_order($product_id, $user_id = null, $customer_data = array()) { global $wpdb; $table_orders = $wpdb->prefix . 'cdpda_orders'; // 获取产品信息 $product = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}cdpda_products WHERE id = %d", $product_id ), ARRAY_A); if (!$product) { return false; } // 生成订单号 $order_number = 'CDP' . date('Ymd') . strtoupper(wp_generate_password(8, false)); // 获取用户信息 if (!$user_id && is_user_logged_in()) { $user_id = get_current_user_id(); } $default_customer_data = array( 'email' => '', 'name' => '', 'ip' => $_SERVER['REMOTE_ADDR'] ); $customer_data = wp_parse_args($customer_data, $default_customer_data); // 创建订单数据 $order_data = array( 'order_number' => $order_number, 'user_id' => $user_id ?: 0, 'product_id' => $product_id, 'amount' => $product['price'], 'status' => 'pending', 'customer_email' => $customer_data['email'], 'customer_ip' => $customer_data['ip'], 'created_at' => current_time('mysql') ); // 插入数据库 $result = $wpdb->insert($table_orders, $order_data); if ($result) { $order_id = $wpdb->insert_id; // 记录订单创建日志 self::log_order_action($order_id, 'created', '订单已创建'); return array( 'order_id' => $order_id, 'order_number' => $order_number, 'amount' => $product['price'] ); } return false; } /** * 处理支付回调 */ public static function process_payment($order_id, $payment_data) { global $wpdb; $table_orders = $wpdb->prefix . 'cdpda_orders'; // 更新订单状态 $updated = $wpdb->update( $table_orders, array( 'status' => 'completed', 'payment_method' => $payment_data['method'], 'transaction_id' => $payment_data['transaction_id'], 'completed_at' => current_time('mysql') ), array('id' => $order_id) ); if ($updated) { // 创建授权密钥 $order = $wpdb->get_row($wpdb->prepare( "SELECT * FROM $table_orders WHERE id = %d", $order_id ), ARRAY_A); $license_id = CDPDA_License_Manager::create_license(array( 'order_id' => $order_id, 'product_id' => $order['product_id'], 'user_id' => $order['user_id'], 'expires_at' => date('Y-m-d H:i:s', strtotime('+1 year')) )); // 发送订单完成通知 self::send_order_complete_notification($order_id); // 记录日志 self::log_order_action($order_id, 'payment_completed', '支付完成'); return true; } return false; } /** * 发送订单完成通知 */ private static function send_order_complete_notification($order_id) { global $wpdb; $order = $wpdb->get_row($wpdb->prepare( "SELECT * FROM {$wpdb->prefix}cdpda_orders WHERE id = %d", $order_id ), ARRAY_A); if (!$order || !$order['customer_email']) { return; } $product_title = get_the_title($order['post_id']); $subject = '订单支付成功:' . $order['order_number']; $message = " <html> <body> <h2>订单支付成功!</h2> <p>订单号:{$order['order_number']}</p> <p>产品:{$product_title}</p> <p>金额:{$order['amount']}元</p> <p>支付时间:" . date('Y-m-d H:i:s') . "</p> <p>您可以在<a href='" . home_url('/my-account/orders/') . "'>我的账户</a>中查看和管理订单。</p> </body> </html> "; $headers = array( 'Content-Type: text/html; charset=UTF-8', 'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>' ); wp_mail($order['customer_email'], $subject, $message, $headers); } /** * 记录订单操作日志 */ private static function log_order_action($order_id, $action, $description) { global $wpdb; $table_logs = $wpdb->prefix . 'cdpda_order_logs'; $wpdb->insert($table_logs, array( 'order_id' => $order_id, 'action' => $action, 'description' => $description, 'ip_address' => $_SERVER['REMOTE_ADDR'], 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'created_at' => current_time('mysql') )); } } ?>
- <?php // 在插件主类中添加短代码注册 private function register_shortcodes() { // 产品购买按钮 add_shortcode('cdpda_buy_button', array($this, 'buy_button_shortcode')); // 用户订单列表 add_shortcode('cdpda_my_orders', array($this, 'my_orders_shortcode')); // 授权验证表单 add_shortcode('cdpda_license_check', array($this, 'license_check_shortcode')); } /** * 购买按钮短代码 */ public function buy_button_shortcode($atts) { $atts = shortcode_atts(array( 'product_id' => 0, 'text' => '立即购买', 'class' => 'cdpda-buy-button' ), $atts); if (!$atts['product_id']) { return '<p>错误:未指定产品ID</p>'; } $product = get_post($atts['product_id']); if (!$product || $product->post_type !== 'digital_product') { return '<p>错误:产品不存在</p>'; } $price = get_post_meta($atts['product_id'], '_cdpda_price', true); ob_start(); ?> <div class="cdpda-product-widget"> <h3><?php echo esc_html($product->post_title); ?></h3> <p class="price">价格:<?php echo esc_html($price); ?>元</p> <?php if (is_user_logged_in()): ?> <form method="post" action="<?php echo esc_url(home_url('/checkout/')); ?>"> <?php wp_nonce_field('cdpda_create_order', 'cdpda_order_nonce'); ?> <input type="hidden" name="product_id" value="<?php echo esc_attr($atts['product_id']); ?>"> <button type="submit" name="cdpda_buy_now" class="<?php echo esc_attr($atts['class']); ?>"> <?php echo esc_html($atts['text']); ?> </button> </form> <?php else: ?> <p>请<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>">登录</a>后购买</p> <?php endif; ?> </div> <?php return ob_get_clean(); } /** * 我的订单短代码 */ public function my_orders_shortcode() { if (!is_user_logged_in()) { return '<p>请<a href="' . wp_login_url(get_permalink()) . '">登录</a>后查看订单</p>'; } global $wpdb; $user_id = get_current_user_id(); $orders = $wpdb->get_results($wpdb->prepare( "SELECT o.*, p.post_id FROM {$wpdb->prefix}cdpda_orders o LEFT JOIN {$wpdb->prefix}cdpda_products p ON o.product_id = p.id WHERE o.user_id = %d ORDER BY o.created_at DESC", $user_id ), ARRAY_A); ob_start(); ?> <div class="cdpda-my-orders"> <h2>我的订单</h2> <?php if (empty($orders)): ?> <p>暂无订单</p> <?php else: ?> <table class="cdpda-orders-table"> <thead> <tr> <th>订单号</th> <th>产品</th> <th>金额</th> <th>状态</th> <th>下单时间</th> <th>操作</th> </tr> </thead> <tbody> <?php foreach ($orders as $order): ?> <tr> <td><?php echo esc_html($order['order_number']); ?></td> <td><?php echo esc_html(get_the_title($order['post_id'])); ?></td> <td><?php echo esc_html($order['amount']); ?>元</td> <td> <span class="order-status status-<?php echo esc_attr($order['status']); ?>"> <?php echo esc_html($order['status']); ?> </span> </td> <td><?php echo esc_html($order['created_at']); ?></td> <td> <?php if ($order['status'] === 'completed'): ?> <a href="<?php echo esc_url(home_url('/download/?order_id=' . $order['id'])); ?>" class="button">下载</a> <?php elseif ($order['status'] === 'pending'): ?> <a href="<?php echo esc_url(home_url('/checkout/pay/?order_id=' . $order['id'])); ?>" class="button">去支付</a> <?php endif; ?> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php endif; ?> </div> <style> .cdpda-orders-table { width: 100%; border-collapse: collapse; margin: 20px 0; } .cdpda-orders-table th, .cdpda-orders-table td { border: 1px solid #ddd; padding: 10px; text-align: left; } .cdpda-orders-table th { background-color: #f5f5f5; } .order-status { padding: 3px 8px; border-radius: 3px; font-size: 12px; } .status-completed { background-color: #d4edda; color: #155724; } .status-pending { background-color: #fff3cd; color: #856404; } </style> <?php return ob_get_clean(); } /** * 授权验证短代码 */ public function license_check_shortcode() { ob_start(); ?> <div class="cdpda-license-check"> <h2>授权验证</h2> <form id="cdpda-license-form" method="post"> <?php wp_nonce_field('cdpda_check_license', 'cdpda_license_nonce'); ?> <div class="form-group"> <label for="license_key">授权密钥:</label> <input type="text" id="license_key" name="license_key" placeholder="输入您的授权密钥" required>
在数字文创产业快速发展的今天,内容创作者需要一个灵活的系统来管理和交付他们的数字产品。本教程将指导您开发一个WordPress插件,实现文创数字产品的柔性交付与授权管理。
核心功能需求:
- 支持多种数字产品类型(电子书、图片、音频、视频等)
- 灵活的交付方式(直接下载、邮件发送、API接口)
- 授权管理(使用期限、设备限制、访问次数)
- 订单与用户管理
- 安全防护与防滥用机制
首先,我们创建插件的基本文件结构:
<?php
/**
* Plugin Name: 文创数字产品交付与授权系统
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站提供文创数字产品的柔性交付与授权管理功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CDPDA_VERSION', '1.0.0');
define('CDPDA_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CDPDA_PLUGIN_URL', plugin_dir_url(__FILE__));
// 初始化插件
class CulturalDigitalProduct_DeliveryAuth {
private static $instance = null;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('init', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载脚本和样式
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_scripts'));
}
public function activate() {
// 创建必要的数据库表
$this->create_database_tables();
// 设置默认选项
$this->set_default_options();
// 刷新重写规则
flush_rewrite_rules();
}
public function deactivate() {
// 清理临时数据
// 注意:不删除用户数据
flush_rewrite_rules();
}
public function init() {
// 注册自定义文章类型
$this->register_post_types();
// 注册短代码
$this->register_shortcodes();
}
// 其他方法将在后续部分实现
}
// 启动插件
CulturalDigitalProduct_DeliveryAuth::get_instance();
?>
创建必要的数据库表来存储产品、订单和授权信息:
<?php
// 在activate方法中调用
private function create_database_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 产品表
$table_products = $wpdb->prefix . 'cdpda_products';
$sql_products = "CREATE TABLE IF NOT EXISTS $table_products (
id bigint(20) NOT NULL AUTO_INCREMENT,
post_id bigint(20) NOT NULL,
product_type varchar(50) NOT NULL,
file_path text,
file_size bigint(20),
file_hash varchar(64),
delivery_methods text,
price decimal(10,2),
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY post_id (post_id)
) $charset_collate;";
// 订单表
$table_orders = $wpdb->prefix . 'cdpda_orders';
$sql_orders = "CREATE TABLE IF NOT EXISTS $table_orders (
id bigint(20) NOT NULL AUTO_INCREMENT,
order_number varchar(50) NOT NULL,
user_id bigint(20) NOT NULL,
product_id bigint(20) NOT NULL,
amount decimal(10,2) NOT NULL,
status varchar(20) DEFAULT 'pending',
payment_method varchar(50),
transaction_id varchar(100),
customer_email varchar(100),
customer_ip varchar(45),
created_at datetime DEFAULT CURRENT_TIMESTAMP,
completed_at datetime,
PRIMARY KEY (id),
UNIQUE KEY order_number (order_number),
KEY user_id (user_id),
KEY product_id (product_id)
) $charset_collate;";
// 授权表
$table_licenses = $wpdb->prefix . 'cdpda_licenses';
$sql_licenses = "CREATE TABLE IF NOT EXISTS $table_licenses (
id bigint(20) NOT NULL AUTO_INCREMENT,
license_key varchar(64) NOT NULL,
order_id bigint(20) NOT NULL,
product_id bigint(20) NOT NULL,
user_id bigint(20),
expires_at datetime,
max_devices int DEFAULT 1,
usage_count int DEFAULT 0,
max_usage int DEFAULT NULL,
status varchar(20) DEFAULT 'active',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
last_used datetime,
PRIMARY KEY (id),
UNIQUE KEY license_key (license_key),
KEY order_id (order_id),
KEY product_id (product_id),
KEY user_id (user_id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_products);
dbDelta($sql_orders);
dbDelta($sql_licenses);
}
?>
创建自定义文章类型来管理数字产品:
<?php
private function register_post_types() {
// 注册数字产品自定义文章类型
$labels = array(
'name' => '数字产品',
'singular_name' => '数字产品',
'menu_name' => '数字产品',
'add_new' => '添加产品',
'add_new_item' => '添加新数字产品',
'edit_item' => '编辑产品',
'new_item' => '新产品',
'view_item' => '查看产品',
'search_items' => '搜索产品',
'not_found' => '未找到产品',
'not_found_in_trash' => '回收站中无产品'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'digital-product'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 30,
'menu_icon' => 'dashicons-products',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'show_in_rest' => true
);
register_post_type('digital_product', $args);
// 添加产品类型分类
register_taxonomy(
'product_type',
'digital_product',
array(
'label' => '产品类型',
'rewrite' => array('slug' => 'product-type'),
'hierarchical' => true,
'show_in_rest' => true
)
);
}
// 添加产品元数据框
public function add_product_meta_boxes() {
add_meta_box(
'cdpda_product_details',
'产品详情',
array($this, 'render_product_meta_box'),
'digital_product',
'normal',
'high'
);
}
public function render_product_meta_box($post) {
// 获取现有值
$product_type = get_post_meta($post->ID, '_cdpda_product_type', true);
$price = get_post_meta($post->ID, '_cdpda_price', true);
$file_url = get_post_meta($post->ID, '_cdpda_file_url', true);
$delivery_methods = get_post_meta($post->ID, '_cdpda_delivery_methods', true);
// 非ce字段
wp_nonce_field('cdpda_save_product_meta', 'cdpda_product_meta_nonce');
// 显示表单
?>
<div class="cdpda-meta-box">
<div class="cdpda-field">
<label for="cdpda_product_type">产品类型:</label>
<select id="cdpda_product_type" name="cdpda_product_type">
<option value="ebook" <?php selected($product_type, 'ebook'); ?>>电子书</option>
<option value="image" <?php selected($product_type, 'image'); ?>>图片</option>
<option value="audio" <?php selected($product_type, 'audio'); ?>>音频</option>
<option value="video" <?php selected($product_type, 'video'); ?>>视频</option>
<option value="software" <?php selected($product_type, 'software'); ?>>软件</option>
<option value="template" <?php selected($product_type, 'template'); ?>>模板</option>
</select>
</div>
<div class="cdpda-field">
<label for="cdpda_price">价格(元):</label>
<input type="number" id="cdpda_price" name="cdpda_price"
value="<?php echo esc_attr($price); ?>" step="0.01" min="0">
</div>
<div class="cdpda-field">
<label for="cdpda_file_url">文件URL:</label>
<input type="url" id="cdpda_file_url" name="cdpda_file_url"
value="<?php echo esc_url($file_url); ?>" style="width: 70%;">
<button type="button" class="button cdpda-upload-file">上传文件</button>
</div>
<div class="cdpda-field">
<label>交付方式:</label>
<label><input type="checkbox" name="cdpda_delivery_methods[]"
value="direct_download" <?php echo in_array('direct_download', (array)$delivery_methods) ? 'checked' : ''; ?>> 直接下载</label>
<label><input type="checkbox" name="cdpda_delivery_methods[]"
value="email" <?php echo in_array('email', (array)$delivery_methods) ? 'checked' : ''; ?>> 邮件发送</label>
<label><input type="checkbox" name="cdpda_delivery_methods[]"
value="api" <?php echo in_array('api', (array)$delivery_methods) ? 'checked' : ''; ?>> API接口</label>
</div>
</div>
<?php
}
// 保存产品元数据
public function save_product_meta($post_id) {
// 安全检查
if (!isset($_POST['cdpda_product_meta_nonce']) ||
!wp_verify_nonce($_POST['cdpda_product_meta_nonce'], 'cdpda_save_product_meta')) {
return;
}
// 检查自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 检查权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存字段
$fields = array(
'cdpda_product_type',
'cdpda_price',
'cdpda_file_url'
);
foreach ($fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field]));
}
}
// 保存交付方式(数组)
if (isset($_POST['cdpda_delivery_methods'])) {
$delivery_methods = array_map('sanitize_text_field', $_POST['cdpda_delivery_methods']);
update_post_meta($post_id, '_cdpda_delivery_methods', $delivery_methods);
} else {
delete_post_meta($post_id, '_cdpda_delivery_methods');
}
}
?>
实现授权密钥生成和验证系统:
<?php
class CDPDA_License_Manager {
/**
* 生成授权密钥
* @param int $order_id 订单ID
* @param int $product_id 产品ID
* @param array $options 授权选项
* @return string 授权密钥
*/
public static function generate_license_key($order_id, $product_id, $options = array()) {
// 基础数据
$data = array(
'order_id' => $order_id,
'product_id' => $product_id,
'timestamp' => time(),
'rand' => wp_generate_password(8, false)
);
// 合并选项
$data = array_merge($data, $options);
// 创建字符串
$string = implode('|', $data);
// 生成密钥(使用SHA256哈希)
$license_key = hash('sha256', $string);
// 格式化为分段显示
$formatted_key = implode('-', str_split($license_key, 8));
return $formatted_key;
}
/**
* 验证授权密钥
* @param string $license_key 授权密钥
* @param int $product_id 产品ID(可选)
* @return array|bool 验证结果
*/
public static function validate_license($license_key, $product_id = null) {
global $wpdb;
// 清理密钥格式
$clean_key = str_replace('-', '', $license_key);
$table_licenses = $wpdb->prefix . 'cdpda_licenses';
// 构建查询
$query = $wpdb->prepare(
"SELECT * FROM $table_licenses WHERE license_key = %s AND status = 'active'",
$clean_key
);
if ($product_id) {
$query .= $wpdb->prepare(" AND product_id = %d", $product_id);
}
$license = $wpdb->get_row($query, ARRAY_A);
if (!$license) {
return array(
'valid' => false,
'message' => '授权密钥无效或已过期'
);
}
// 检查过期时间
if ($license['expires_at'] && strtotime($license['expires_at']) < time()) {
return array(
'valid' => false,
'message' => '授权已过期'
);
}
// 检查使用次数限制
if ($license['max_usage'] && $license['usage_count'] >= $license['max_usage']) {
return array(
'valid' => false,
'message' => '已达到最大使用次数'
);
}
// 更新最后使用时间
$wpdb->update(
$table_licenses,
array(
'last_used' => current_time('mysql'),
'usage_count' => $license['usage_count'] + 1
),
array('id' => $license['id'])
);
return array(
'valid' => true,
'license' => $license,
'message' => '授权验证成功'
);
}
/**
* 创建授权记录
* @param array $data 授权数据
* @return int|bool 授权ID或false
*/
public static function create_license($data) {
global $wpdb;
$table_licenses = $wpdb->prefix . 'cdpda_licenses';
$defaults = array(
'license_key' => '',
'order_id' => 0,
'product_id' => 0,
'user_id' => 0,
'expires_at' => null,
'max_devices' => 1,
'max_usage' => null,
'status' => 'active'
);
$data = wp_parse_args($data, $defaults);
// 如果没有提供密钥,生成一个
if (empty($data['license_key'])) {
$data['license_key'] = str_replace('-', '',
self::generate_license_key($data['order_id'], $data['product_id'])
);
}
// 插入数据库
$result = $wpdb->insert($table_licenses, $data);
if ($result) {
return $wpdb->insert_id;
}
return false;
}
}
?>
实现多种交付方式:
<?php
class CDPDA_Delivery_System {
/**
* 交付数字产品
* @param int $order_id 订单ID
* @param string $method 交付方式
* @return array 交付结果
*/
public static function deliver_product($order_id, $method = 'direct_download') {
global $wpdb;
$table_orders = $wpdb->prefix . 'cdpda_orders';
<?php
$wpdb->prefix . 'cdpda_products';
// 获取订单信息
$order = $wpdb->get_row($wpdb->prepare(
"SELECT o.*, p.post_id, p.file_path, p.delivery_methods
FROM $table_orders o
LEFT JOIN $table_products p ON o.product_id = p.id
WHERE o.id = %d",
$order_id
), ARRAY_A);
if (!$order) {
return array(
'success' => false,
'message' => '订单不存在'
);
}
// 检查订单状态
if ($order['status'] !== 'completed') {
return array(
'success' => false,
'message' => '订单未完成支付'
);
}
// 根据交付方式处理
switch ($method) {
case 'direct_download':
return self::direct_download($order);
case 'email':
return self::email_delivery($order);
case 'api':
return self::api_delivery($order);
default:
return array(
'success' => false,
'message' => '不支持的交付方式'
);
}
}
/**
* 直接下载交付
*/
private static function direct_download($order) {
$file_path = get_post_meta($order['post_id'], '_cdpda_file_url', true);
if (!$file_path || !file_exists($file_path)) {
return array(
'success' => false,
'message' => '文件不存在'
);
}
// 记录下载日志
self::log_download($order['id'], 'direct_download');
// 生成临时下载链接(带过期时间)
$download_url = self::generate_download_url($order['id']);
return array(
'success' => true,
'message' => '下载链接已生成',
'download_url' => $download_url,
'expires_in' => '24小时'
);
}
/**
* 邮件交付
*/
private static function email_delivery($order) {
$customer_email = $order['customer_email'];
$product_title = get_the_title($order['post_id']);
$file_path = get_post_meta($order['post_id'], '_cdpda_file_url', true);
// 生成下载链接
$download_url = self::generate_download_url($order['id']);
// 邮件内容
$subject = '您的数字产品已准备就绪:' . $product_title;
$message = "
<html>
<body>
<h2>感谢您的购买!</h2>
<p>您购买的产品 <strong>{$product_title}</strong> 已准备就绪。</p>
<p>下载链接:<a href='{$download_url}'>{$download_url}</a></p>
<p>链接有效期:24小时</p>
<p>如需帮助,请联系客服。</p>
</body>
</html>
";
// 设置邮件头
$headers = array(
'Content-Type: text/html; charset=UTF-8',
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>'
);
// 发送邮件
$sent = wp_mail($customer_email, $subject, $message, $headers);
if ($sent) {
// 记录邮件发送日志
self::log_delivery($order['id'], 'email');
return array(
'success' => true,
'message' => '产品已发送到您的邮箱'
);
}
return array(
'success' => false,
'message' => '邮件发送失败'
);
}
/**
* API接口交付
*/
private static function api_delivery($order) {
// 生成API访问令牌
$api_token = self::generate_api_token($order['id']);
// 创建API端点
$api_endpoint = home_url('/cdpda-api/v1/download/' . $order['id']);
return array(
'success' => true,
'message' => 'API访问信息已生成',
'api_endpoint' => $api_endpoint,
'api_token' => $api_token,
'expires_in' => '72小时'
);
}
/**
* 生成下载URL
*/
private static function generate_download_url($order_id) {
$token = wp_hash($order_id . time());
// 存储临时令牌(24小时有效)
set_transient('cdpda_download_' . $token, $order_id, 24 * HOUR_IN_SECONDS);
return add_query_arg(array(
'cdpda_download' => $token,
'order_id' => $order_id
), home_url('/download/'));
}
/**
* 记录下载日志
*/
private static function log_download($order_id, $method) {
global $wpdb;
$table_logs = $wpdb->prefix . 'cdpda_download_logs';
$wpdb->insert($table_logs, array(
'order_id' => $order_id,
'delivery_method' => $method,
'ip_address' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'downloaded_at' => current_time('mysql')
));
}
}
?>
<?php
class CDPDA_Order_Processor {
/**
* 创建新订单
*/
public static function create_order($product_id, $user_id = null, $customer_data = array()) {
global $wpdb;
$table_orders = $wpdb->prefix . 'cdpda_orders';
// 获取产品信息
$product = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}cdpda_products WHERE id = %d",
$product_id
), ARRAY_A);
if (!$product) {
return false;
}
// 生成订单号
$order_number = 'CDP' . date('Ymd') . strtoupper(wp_generate_password(8, false));
// 获取用户信息
if (!$user_id && is_user_logged_in()) {
$user_id = get_current_user_id();
}
$default_customer_data = array(
'email' => '',
'name' => '',
'ip' => $_SERVER['REMOTE_ADDR']
);
$customer_data = wp_parse_args($customer_data, $default_customer_data);
// 创建订单数据
$order_data = array(
'order_number' => $order_number,
'user_id' => $user_id ?: 0,
'product_id' => $product_id,
'amount' => $product['price'],
'status' => 'pending',
'customer_email' => $customer_data['email'],
'customer_ip' => $customer_data['ip'],
'created_at' => current_time('mysql')
);
// 插入数据库
$result = $wpdb->insert($table_orders, $order_data);
if ($result) {
$order_id = $wpdb->insert_id;
// 记录订单创建日志
self::log_order_action($order_id, 'created', '订单已创建');
return array(
'order_id' => $order_id,
'order_number' => $order_number,
'amount' => $product['price']
);
}
return false;
}
/**
* 处理支付回调
*/
public static function process_payment($order_id, $payment_data) {
global $wpdb;
$table_orders = $wpdb->prefix . 'cdpda_orders';
// 更新订单状态
$updated = $wpdb->update(
$table_orders,
array(
'status' => 'completed',
'payment_method' => $payment_data['method'],
'transaction_id' => $payment_data['transaction_id'],
'completed_at' => current_time('mysql')
),
array('id' => $order_id)
);
if ($updated) {
// 创建授权密钥
$order = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_orders WHERE id = %d",
$order_id
), ARRAY_A);
$license_id = CDPDA_License_Manager::create_license(array(
'order_id' => $order_id,
'product_id' => $order['product_id'],
'user_id' => $order['user_id'],
'expires_at' => date('Y-m-d H:i:s', strtotime('+1 year'))
));
// 发送订单完成通知
self::send_order_complete_notification($order_id);
// 记录日志
self::log_order_action($order_id, 'payment_completed', '支付完成');
return true;
}
return false;
}
/**
* 发送订单完成通知
*/
private static function send_order_complete_notification($order_id) {
global $wpdb;
$order = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}cdpda_orders WHERE id = %d",
$order_id
), ARRAY_A);
if (!$order || !$order['customer_email']) {
return;
}
$product_title = get_the_title($order['post_id']);
$subject = '订单支付成功:' . $order['order_number'];
$message = "
<html>
<body>
<h2>订单支付成功!</h2>
<p>订单号:{$order['order_number']}</p>
<p>产品:{$product_title}</p>
<p>金额:{$order['amount']}元</p>
<p>支付时间:" . date('Y-m-d H:i:s') . "</p>
<p>您可以在<a href='" . home_url('/my-account/orders/') . "'>我的账户</a>中查看和管理订单。</p>
</body>
</html>
";
$headers = array(
'Content-Type: text/html; charset=UTF-8',
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>'
);
wp_mail($order['customer_email'], $subject, $message, $headers);
}
/**
* 记录订单操作日志
*/
private static function log_order_action($order_id, $action, $description) {
global $wpdb;
$table_logs = $wpdb->prefix . 'cdpda_order_logs';
$wpdb->insert($table_logs, array(
'order_id' => $order_id,
'action' => $action,
'description' => $description,
'ip_address' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'created_at' => current_time('mysql')
));
}
}
?>
<?php
class CDPDA_Order_Processor {
/**
* 创建新订单
*/
public static function create_order($product_id, $user_id = null, $customer_data = array()) {
global $wpdb;
$table_orders = $wpdb->prefix . 'cdpda_orders';
// 获取产品信息
$product = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}cdpda_products WHERE id = %d",
$product_id
), ARRAY_A);
if (!$product) {
return false;
}
// 生成订单号
$order_number = 'CDP' . date('Ymd') . strtoupper(wp_generate_password(8, false));
// 获取用户信息
if (!$user_id && is_user_logged_in()) {
$user_id = get_current_user_id();
}
$default_customer_data = array(
'email' => '',
'name' => '',
'ip' => $_SERVER['REMOTE_ADDR']
);
$customer_data = wp_parse_args($customer_data, $default_customer_data);
// 创建订单数据
$order_data = array(
'order_number' => $order_number,
'user_id' => $user_id ?: 0,
'product_id' => $product_id,
'amount' => $product['price'],
'status' => 'pending',
'customer_email' => $customer_data['email'],
'customer_ip' => $customer_data['ip'],
'created_at' => current_time('mysql')
);
// 插入数据库
$result = $wpdb->insert($table_orders, $order_data);
if ($result) {
$order_id = $wpdb->insert_id;
// 记录订单创建日志
self::log_order_action($order_id, 'created', '订单已创建');
return array(
'order_id' => $order_id,
'order_number' => $order_number,
'amount' => $product['price']
);
}
return false;
}
/**
* 处理支付回调
*/
public static function process_payment($order_id, $payment_data) {
global $wpdb;
$table_orders = $wpdb->prefix . 'cdpda_orders';
// 更新订单状态
$updated = $wpdb->update(
$table_orders,
array(
'status' => 'completed',
'payment_method' => $payment_data['method'],
'transaction_id' => $payment_data['transaction_id'],
'completed_at' => current_time('mysql')
),
array('id' => $order_id)
);
if ($updated) {
// 创建授权密钥
$order = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $table_orders WHERE id = %d",
$order_id
), ARRAY_A);
$license_id = CDPDA_License_Manager::create_license(array(
'order_id' => $order_id,
'product_id' => $order['product_id'],
'user_id' => $order['user_id'],
'expires_at' => date('Y-m-d H:i:s', strtotime('+1 year'))
));
// 发送订单完成通知
self::send_order_complete_notification($order_id);
// 记录日志
self::log_order_action($order_id, 'payment_completed', '支付完成');
return true;
}
return false;
}
/**
* 发送订单完成通知
*/
private static function send_order_complete_notification($order_id) {
global $wpdb;
$order = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}cdpda_orders WHERE id = %d",
$order_id
), ARRAY_A);
if (!$order || !$order['customer_email']) {
return;
}
$product_title = get_the_title($order['post_id']);
$subject = '订单支付成功:' . $order['order_number'];
$message = "
<html>
<body>
<h2>订单支付成功!</h2>
<p>订单号:{$order['order_number']}</p>
<p>产品:{$product_title}</p>
<p>金额:{$order['amount']}元</p>
<p>支付时间:" . date('Y-m-d H:i:s') . "</p>
<p>您可以在<a href='" . home_url('/my-account/orders/') . "'>我的账户</a>中查看和管理订单。</p>
</body>
</html>
";
$headers = array(
'Content-Type: text/html; charset=UTF-8',
'From: ' . get_bloginfo('name') . ' <' . get_option('admin_email') . '>'
);
wp_mail($order['customer_email'], $subject, $message, $headers);
}
/**
* 记录订单操作日志
*/
private static function log_order_action($order_id, $action, $description) {
global $wpdb;
$table_logs = $wpdb->prefix . 'cdpda_order_logs';
$wpdb->insert($table_logs, array(
'order_id' => $order_id,
'action' => $action,
'description' => $description,
'ip_address' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
'created_at' => current_time('mysql')
));
}
}
?>
<?php
// 在插件主类中添加短代码注册
private function register_shortcodes() {
// 产品购买按钮
add_shortcode('cdpda_buy_button', array($this, 'buy_button_shortcode'));
// 用户订单列表
add_shortcode('cdpda_my_orders', array($this, 'my_orders_shortcode'));
// 授权验证表单
add_shortcode('cdpda_license_check', array($this, 'license_check_shortcode'));
}
/**
* 购买按钮短代码
*/
public function buy_button_shortcode($atts) {
$atts = shortcode_atts(array(
'product_id' => 0,
'text' => '立即购买',
'class' => 'cdpda-buy-button'
), $atts);
if (!$atts['product_id']) {
return '<p>错误:未指定产品ID</p>';
}
$product = get_post($atts['product_id']);
if (!$product || $product->post_type !== 'digital_product') {
return '<p>错误:产品不存在</p>';
}
$price = get_post_meta($atts['product_id'], '_cdpda_price', true);
ob_start();
?>
<div class="cdpda-product-widget">
<h3><?php echo esc_html($product->post_title); ?></h3>
<p class="price">价格:<?php echo esc_html($price); ?>元</p>
<?php if (is_user_logged_in()): ?>
<form method="post" action="<?php echo esc_url(home_url('/checkout/')); ?>">
<?php wp_nonce_field('cdpda_create_order', 'cdpda_order_nonce'); ?>
<input type="hidden" name="product_id" value="<?php echo esc_attr($atts['product_id']); ?>">
<button type="submit" name="cdpda_buy_now" class="<?php echo esc_attr($atts['class']); ?>">
<?php echo esc_html($atts['text']); ?>
</button>
</form>
<?php else: ?>
<p>请<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>">登录</a>后购买</p>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
/**
* 我的订单短代码
*/
public function my_orders_shortcode() {
if (!is_user_logged_in()) {
return '<p>请<a href="' . wp_login_url(get_permalink()) . '">登录</a>后查看订单</p>';
}
global $wpdb;
$user_id = get_current_user_id();
$orders = $wpdb->get_results($wpdb->prepare(
"SELECT o.*, p.post_id
FROM {$wpdb->prefix}cdpda_orders o
LEFT JOIN {$wpdb->prefix}cdpda_products p ON o.product_id = p.id
WHERE o.user_id = %d
ORDER BY o.created_at DESC",
$user_id
), ARRAY_A);
ob_start();
?>
<div class="cdpda-my-orders">
<h2>我的订单</h2>
<?php if (empty($orders)): ?>
<p>暂无订单</p>
<?php else: ?>
<table class="cdpda-orders-table">
<thead>
<tr>
<th>订单号</th>
<th>产品</th>
<th>金额</th>
<th>状态</th>
<th>下单时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo esc_html($order['order_number']); ?></td>
<td><?php echo esc_html(get_the_title($order['post_id'])); ?></td>
<td><?php echo esc_html($order['amount']); ?>元</td>
<td>
<span class="order-status status-<?php echo esc_attr($order['status']); ?>">
<?php echo esc_html($order['status']); ?>
</span>
</td>
<td><?php echo esc_html($order['created_at']); ?></td>
<td>
<?php if ($order['status'] === 'completed'): ?>
<a href="<?php echo esc_url(home_url('/download/?order_id=' . $order['id'])); ?>"
class="button">下载</a>
<?php elseif ($order['status'] === 'pending'): ?>
<a href="<?php echo esc_url(home_url('/checkout/pay/?order_id=' . $order['id'])); ?>"
class="button">去支付</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<style>
.cdpda-orders-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.cdpda-orders-table th,
.cdpda-orders-table td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
.cdpda-orders-table th {
background-color: #f5f5f5;
}
.order-status {
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
}
.status-completed {
background-color: #d4edda;
color: #155724;
}
.status-pending {
background-color: #fff3cd;
color: #856404;
}
</style>
<?php
return ob_get_clean();
}
/**
* 授权验证短代码
*/
public function license_check_shortcode() {
ob_start();
?>
<div class="cdpda-license-check">
<h2>授权验证</h2>
<form id="cdpda-license-form" method="post">
<?php wp_nonce_field('cdpda_check_license', 'cdpda_license_nonce'); ?>
<div class="form-group">
<label for="license_key">授权密钥:</label>
<input type="text" id="license_key" name="license_key"
placeholder="输入您的授权密钥" required>
<?php
// 在插件主类中添加短代码注册
private function register_shortcodes() {
// 产品购买按钮
add_shortcode('cdpda_buy_button', array($this, 'buy_button_shortcode'));
// 用户订单列表
add_shortcode('cdpda_my_orders', array($this, 'my_orders_shortcode'));
// 授权验证表单
add_shortcode('cdpda_license_check', array($this, 'license_check_shortcode'));
}
/**
* 购买按钮短代码
*/
public function buy_button_shortcode($atts) {
$atts = shortcode_atts(array(
'product_id' => 0,
'text' => '立即购买',
'class' => 'cdpda-buy-button'
), $atts);
if (!$atts['product_id']) {
return '<p>错误:未指定产品ID</p>';
}
$product = get_post($atts['product_id']);
if (!$product || $product->post_type !== 'digital_product') {
return '<p>错误:产品不存在</p>';
}
$price = get_post_meta($atts['product_id'], '_cdpda_price', true);
ob_start();
?>
<div class="cdpda-product-widget">
<h3><?php echo esc_html($product->post_title); ?></h3>
<p class="price">价格:<?php echo esc_html($price); ?>元</p>
<?php if (is_user_logged_in()): ?>
<form method="post" action="<?php echo esc_url(home_url('/checkout/')); ?>">
<?php wp_nonce_field('cdpda_create_order', 'cdpda_order_nonce'); ?>
<input type="hidden" name="product_id" value="<?php echo esc_attr($atts['product_id']); ?>">
<button type="submit" name="cdpda_buy_now" class="<?php echo esc_attr($atts['class']); ?>">
<?php echo esc_html($atts['text']); ?>
</button>
</form>
<?php else: ?>
<p>请<a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>">登录</a>后购买</p>
<?php endif; ?>
</div>
<?php
return ob_get_clean();
}
/**
* 我的订单短代码
*/
public function my_orders_shortcode() {
if (!is_user_logged_in()) {
return '<p>请<a href="' . wp_login_url(get_permalink()) . '">登录</a>后查看订单</p>';
}
global $wpdb;
$user_id = get_current_user_id();
$orders = $wpdb->get_results($wpdb->prepare(
"SELECT o.*, p.post_id
FROM {$wpdb->prefix}cdpda_orders o
LEFT JOIN {$wpdb->prefix}cdpda_products p ON o.product_id = p.id
WHERE o.user_id = %d
ORDER BY o.created_at DESC",
$user_id
), ARRAY_A);
ob_start();
?>
<div class="cdpda-my-orders">
<h2>我的订单</h2>
<?php if (empty($orders)): ?>
<p>暂无订单</p>
<?php else: ?>
<table class="cdpda-orders-table">
<thead>
<tr>
<th>订单号</th>
<th>产品</th>
<th>金额</th>
<th>状态</th>
<th>下单时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($orders as $order): ?>
<tr>
<td><?php echo esc_html($order['order_number']); ?></td>
<td><?php echo esc_html(get_the_title($order['post_id'])); ?></td>
<td><?php echo esc_html($order['amount']); ?>元</td>
<td>
<span class="order-status status-<?php echo esc_attr($order['status']); ?>">
<?php echo esc_html($order['status']); ?>
</span>
</td>
<td><?php echo esc_html($order['created_at']); ?></td>
<td>
<?php if ($order['status'] === 'completed'): ?>
<a href="<?php echo esc_url(home_url('/download/?order_id=' . $order['id'])); ?>"
class="button">下载</a>
<?php elseif ($order['status'] === 'pending'): ?>
<a href="<?php echo esc_url(home_url('/checkout/pay/?order_id=' . $order['id'])); ?>"
class="button">去支付</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<style>
.cdpda-orders-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.cdpda-orders-table th,
.cdpda-orders-table td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
.cdpda-orders-table th {
background-color: #f5f5f5;
}
.order-status {
padding: 3px 8px;
border-radius: 3px;
font-size: 12px;
}
.status-completed {
background-color: #d4edda;
color: #155724;
}
.status-pending {
background-color: #fff3cd;
color: #856404;
}
</style>
<?php
return ob_get_clean();
}
/**
* 授权验证短代码
*/
public function license_check_shortcode() {
ob_start();
?>
<div class="cdpda-license-check">
<h2>授权验证</h2>
<form id="cdpda-license-form" method="post">
<?php wp_nonce_field('cdpda_check_license', 'cdpda_license_nonce'); ?>
<div class="form-group">
<label for="license_key">授权密钥:</label>
<input type="text" id="license_key" name="license_key"
placeholder="输入您的授权密钥" required>


