文章目录[隐藏]
一步步教你,在WordPress中集成支付网关功能,通过WordPress程序的代码二次开发实现常用互联网小工具功能
引言:为什么要在WordPress中集成支付功能?
在当今数字化时代,网站已经不仅仅是信息展示的平台,更是商业交易的重要渠道。无论是个人博主希望开通读者打赏功能,还是企业网站需要实现在线销售,支付功能的集成都成为了网站建设的核心需求之一。WordPress作为全球最流行的内容管理系统,占据了互联网上超过40%的网站份额,其强大的扩展性使得开发者能够通过二次开发实现各种复杂功能。
支付网关的集成是WordPress网站商业化的重要一步。通过自主开发支付功能,网站所有者可以摆脱对第三方平台的依赖,降低交易成本,提升用户体验,并更好地控制交易流程和数据安全。本文将详细讲解如何在WordPress中通过代码二次开发集成支付网关功能,并实现一些常用的互联网小工具,帮助您打造功能完备的商业化网站。
第一章:准备工作与环境配置
1.1 选择合适的支付网关
在开始开发之前,首先需要选择合适的支付网关。国内常用的支付网关包括支付宝、微信支付、银联支付等,国际常用的有PayPal、Stripe等。选择支付网关时需要考虑以下因素:
- 费率结构:不同支付网关的交易费率不同,需要根据预期交易量选择
- 结算周期:资金到账的时间周期
- 技术支持:API文档的完整性和技术支持响应速度
- 合规要求:是否符合行业监管要求
以支付宝为例,它提供了电脑网站支付、手机网站支付、APP支付等多种接入方式,适合不同类型的网站需求。
1.2 开发环境搭建
为了进行WordPress支付功能的二次开发,需要搭建合适的开发环境:
- 本地开发环境:推荐使用XAMPP、MAMP或Local by Flywheel等集成环境
- 代码编辑器:VS Code、PHPStorm等支持PHP开发的编辑器
- 版本控制:Git用于代码版本管理
- 调试工具:WordPress Debug插件、浏览器开发者工具
确保您的开发环境满足以下要求:
- PHP 7.4或更高版本
- MySQL 5.6或更高版本
- WordPress 5.0或更高版本
- SSL证书(支付功能必须使用HTTPS)
1.3 创建WordPress插件框架
我们将通过创建一个独立插件的方式集成支付功能,这样可以确保代码的独立性和可移植性。创建插件的基本步骤如下:
- 在WordPress的
wp-content/plugins/目录下创建新文件夹,命名为custom-payment-gateway - 在该文件夹中创建主插件文件
custom-payment-gateway.php - 添加插件头部信息:
<?php
/**
* Plugin Name: 自定义支付网关
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站添加自定义支付网关功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: custom-payment
*/
第二章:支付网关API对接基础
2.1 理解支付流程
一个完整的在线支付流程通常包括以下步骤:
- 订单创建:用户在网站下单,系统生成订单记录
- 支付请求:网站将订单信息发送给支付网关
- 用户支付:用户在支付网关页面完成支付
- 支付回调:支付网关将支付结果返回给网站
- 订单更新:网站根据支付结果更新订单状态
- 结果展示:向用户展示支付结果
2.2 支付宝API对接示例
以支付宝电脑网站支付为例,对接流程如下:
- 申请支付宝开放平台账号:创建应用并获取APPID
- 配置密钥:生成应用公钥和私钥
- 集成SDK:下载支付宝官方SDK或使用Composer安装
- 实现支付接口:创建支付请求和回调处理
首先,通过Composer安装支付宝SDK:
composer require alipaysdk/easysdk
然后,在插件中创建支付处理类:
class Alipay_Payment_Gateway {
private $appId;
private $privateKey;
private $alipayPublicKey;
public function __construct() {
// 从数据库或配置文件中读取配置
$this->appId = get_option('alipay_app_id');
$this->privateKey = get_option('alipay_private_key');
$this->alipayPublicKey = get_option('alipay_public_key');
}
/**
* 创建支付订单
*/
public function create_payment($order_data) {
require_once dirname(__FILE__) . '/vendor/autoload.php';
$config = new AlipayEasySDKKernelConfig();
$config->protocol = 'https';
$config->gatewayHost = 'openapi.alipay.com';
$config->signType = 'RSA2';
$config->appId = $this->appId;
$config->merchantPrivateKey = $this->privateKey;
$config->alipayPublicKey = $this->alipayPublicKey;
try {
$client = AlipayEasySDKKernelFactory::setOptions($config);
$result = $client->payment()->page()->pay(
$order_data['subject'],
$order_data['out_trade_no'],
$order_data['total_amount'],
$order_data['return_url']
);
return $result->body;
} catch (Exception $e) {
error_log('支付宝支付创建失败: ' . $e->getMessage());
return false;
}
}
/**
* 处理支付回调
*/
public function handle_callback() {
// 验证签名
$params = $_POST;
if ($this->verify_signature($params)) {
$out_trade_no = $params['out_trade_no'];
$trade_status = $params['trade_status'];
// 根据交易状态更新订单
if ($trade_status == 'TRADE_SUCCESS') {
$this->update_order_status($out_trade_no, 'completed');
return true;
}
}
return false;
}
/**
* 验证签名
*/
private function verify_signature($params) {
// 实现签名验证逻辑
// ...
}
}
2.3 微信支付API对接
微信支付的对接流程与支付宝类似,但有一些特殊注意事项:
- 需要配置授权目录和支付目录
- 需要处理微信浏览器的特殊环境
- 需要实现JSAPI支付和H5支付的不同处理
微信支付的核心代码结构:
class Wechat_Payment_Gateway {
private $appId;
private $mchId;
private $apiKey;
public function __construct() {
$this->appId = get_option('wechat_app_id');
$this->mchId = get_option('wechat_mch_id');
$this->apiKey = get_option('wechat_api_key');
}
/**
* 统一下单接口
*/
public function unified_order($order_data) {
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
$params = [
'appid' => $this->appId,
'mch_id' => $this->mchId,
'nonce_str' => $this->generate_nonce_str(),
'body' => $order_data['body'],
'out_trade_no' => $order_data['out_trade_no'],
'total_fee' => $order_data['total_fee'],
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'notify_url' => home_url('/wechat-notify'),
'trade_type' => $this->get_trade_type(),
'openid' => isset($order_data['openid']) ? $order_data['openid'] : ''
];
// 生成签名
$params['sign'] = $this->generate_sign($params);
// 将数组转换为XML
$xml = $this->array_to_xml($params);
// 发送请求
$response = $this->post_xml_curl($xml, $url);
// 解析响应
$result = $this->xml_to_array($response);
return $result;
}
/**
* 生成随机字符串
*/
private function generate_nonce_str($length = 32) {
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 生成签名
*/
private function generate_sign($params) {
// 按照参数名ASCII码从小到大排序
ksort($params);
$string = "";
foreach ($params as $key => $value) {
if ($key != "sign" && $value != "" && !is_array($value)) {
$string .= $key . "=" . $value . "&";
}
}
$string = trim($string, "&");
$string = $string . "&key=" . $this->apiKey;
// MD5加密并转为大写
$sign = strtoupper(md5($string));
return $sign;
}
}
第三章:订单管理系统开发
3.1 数据库表设计
为了管理支付订单,需要在WordPress数据库中创建专门的订单表。虽然可以使用WordPress的自定义文章类型来存储订单,但为了更好的性能和灵活性,建议创建独立的数据表。
class Payment_Database {
/**
* 创建订单表
*/
public static function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'payment_orders';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
order_number varchar(100) NOT NULL,
user_id bigint(20) DEFAULT 0,
payment_method varchar(50) NOT NULL,
amount decimal(10,2) NOT NULL,
status varchar(20) DEFAULT 'pending',
product_id bigint(20) DEFAULT 0,
product_type varchar(50) DEFAULT '',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
paid_at datetime NULL,
transaction_id varchar(100) DEFAULT '',
payment_data text,
PRIMARY KEY (id),
UNIQUE KEY order_number (order_number),
KEY user_id (user_id),
KEY status (status)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
/**
* 插入新订单
*/
public static function insert_order($order_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
$defaults = [
'order_number' => self::generate_order_number(),
'user_id' => get_current_user_id(),
'created_at' => current_time('mysql'),
'status' => 'pending'
];
$order_data = wp_parse_args($order_data, $defaults);
$wpdb->insert($table_name, $order_data);
return $wpdb->insert_id;
}
/**
* 生成订单号
*/
private static function generate_order_number() {
return date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}
/**
* 更新订单状态
*/
public static function update_order_status($order_id, $status, $transaction_id = '') {
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
$data = ['status' => $status];
if ($status == 'completed' && empty($data['paid_at'])) {
$data['paid_at'] = current_time('mysql');
}
if (!empty($transaction_id)) {
$data['transaction_id'] = $transaction_id;
}
$where = ['id' => $order_id];
return $wpdb->update($table_name, $data, $where);
}
}
3.2 订单管理后台界面
在WordPress后台创建订单管理页面:
class Payment_Admin {
/**
* 添加管理菜单
*/
public static function add_admin_menu() {
add_menu_page(
'支付订单',
'支付订单',
'manage_options',
'payment-orders',
[__CLASS__, 'render_orders_page'],
'dashicons-cart',
30
);
add_submenu_page(
'payment-orders',
'订单设置',
'订单设置',
'manage_options',
'payment-settings',
[__CLASS__, 'render_settings_page']
);
}
/**
* 渲染订单列表页面
*/
public static function render_orders_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
// 处理批量操作
if (isset($_GET['action']) && isset($_GET['order_id'])) {
self::handle_order_action($_GET['action'], $_GET['order_id']);
}
// 分页查询
$per_page = 20;
$current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
$offset = ($current_page - 1) * $per_page;
$where = '1=1';
$query_params = [];
// 搜索条件
if (!empty($_GET['s'])) {
$search = sanitize_text_field($_GET['s']);
$where .= " AND (order_number LIKE %s OR transaction_id LIKE %s)";
$query_params[] = "%{$search}%";
$query_params[] = "%{$search}%";
}
if (!empty($_GET['status'])) {
$status = sanitize_text_field($_GET['status']);
$where .= " AND status = %s";
$query_params[] = $status;
}
// 查询订单
$query = "SELECT * FROM {$table_name} WHERE {$where} ORDER BY created_at DESC LIMIT %d OFFSET %d";
$query_params[] = $per_page;
$query_params[] = $offset;
if (!empty($query_params)) {
$query = $wpdb->prepare($query, $query_params);
}
$orders = $wpdb->get_results($query);
// 查询总数
$count_query = "SELECT COUNT(*) FROM {$table_name} WHERE {$where}";
if (!empty($query_params)) {
$count_query = $wpdb->prepare($count_query, array_slice($query_params, 0, count($query_params) - 2));
}
$total_items = $wpdb->get_var($count_query);
?>
<div class="wrap">
<h1 class="wp-heading-inline">支付订单</h1>
<form method="get" action="">
<input type="hidden" name="page" value="payment-orders">
<div class="tablenav top">
<div class="alignleft actions">
<select name="status">
<option value="">所有状态</option>
<option value="pending" <?php selected($_GET['status'] ?? '', 'pending'); ?>>待支付</option>
<option value="completed" <?php selected($_GET['status'] ?? '', 'completed'); ?>>已完成</option>
<option value="cancelled" <?php selected($_GET['status'] ?? '', 'cancelled'); ?>>已取消</option>
</select>
<input type="text" name="s" value="<?php echo esc_attr($_GET['s'] ?? ''); ?>" placeholder="搜索订单号或交易号">
<button class="button" type="submit">筛选</button>
</div>
<div class="tablenav-pages">
<?php
$total_pages = ceil($total_items / $per_page);
echo paginate_links([
'base' => add_query_arg('paged', '%#%'),
'format' => '',
'prev_text' => '«',
'next_text' => '»',
'total' => $total_pages,
'current' => $current_page
]);
?>
</div>
</div>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>订单号</th>
<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
if ($order->user_id) {
$user = get_user_by('id', $order->user_id);
echo $user ? esc_html($user->display_name) : '用户不存在';
} else {
echo '游客';
}
?>
</td>
<td><?php echo esc_html($order->payment_method); ?></td>
<td><?php echo number_format($order->amount, 2); ?>元</td>
<td>
<span class="order-status status-<?php echo esc_attr($order->status); ?>">
<?php echo self::get_status_label($order->status); ?>
</span>
</td>
<td><?php echo esc_html($order->created_at); ?></td>
<td>
<a href="<?php echo admin_url('admin.php?page=payment-orders&action=view&order_id=' . $order->id); ?>" class="button button-small">查看</a>
<?php if ($order->status == 'pending'): ?>
<a href="<?php echo admin_url('admin.php?page=payment-orders&action=cancel&order_id=' . $order->id); ?>" class="button button-small" onclick="return confirm('确定要取消此订单吗?');">取消</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</form>
</div>
<?php
}
/**
* 获取状态标签
*/
private static function get_status_label($status) {
$labels = [
'pending' => '待支付',
'completed' => '已完成',
'cancelled' => '已取消',
'refunded' => '已退款'
];
return $labels[$status] ?? $status;
}
/**
* 处理订单操作
*/
private static function handle_order_action($action, $order_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
switch ($action) {
case 'view':
// 显示订单详情
self::render_order_detail($order_id);
break;
case 'cancel':
$wpdb->update(
$table_name,
['status' => 'cancelled'],
['id' => $order_id]
);
wp_redirect(admin_url('admin.php?page=payment-orders'));
exit;
case 'refund':
// 处理退款逻辑
break;
}
}
}
### 第四章:前端支付界面与用户体验优化
#### 4.1 创建支付短代码
为了让用户能够在前端页面使用支付功能,我们需要创建短代码:
class Payment_Shortcodes {
/**
* 初始化短代码
*/
public static function init() {
add_shortcode('payment_button', [__CLASS__, 'render_payment_button']);
add_shortcode('payment_history', [__CLASS__, 'render_payment_history']);
add_shortcode('donation_form', [__CLASS__, 'render_donation_form']);
}
/**
* 支付按钮短代码
*/
public static function render_payment_button($atts) {
$atts = shortcode_atts([
'product_id' => 0,
'amount' => 0,
'text' => '立即支付',
'class' => 'payment-button',
'gateway' => 'alipay'
], $atts);
// 生成订单
$order_data = [
'product_id' => $atts['product_id'],
'amount' => $atts['amount'],
'payment_method' => $atts['gateway']
];
$order_id = Payment_Database::insert_order($order_data);
ob_start();
?>
<form method="post" action="<?php echo admin_url('admin-ajax.php'); ?>" class="payment-form">
<input type="hidden" name="action" value="create_payment">
<input type="hidden" name="order_id" value="<?php echo esc_attr($order_id); ?>">
<input type="hidden" name="gateway" value="<?php echo esc_attr($atts['gateway']); ?>">
<button type="submit" class="<?php echo esc_attr($atts['class']); ?>" data-amount="<?php echo esc_attr($atts['amount']); ?>">
<?php echo esc_html($atts['text']); ?>
</button>
<div class="payment-loading" style="display: none;">
正在跳转到支付页面...
</div>
</form>
<script>
jQuery(document).ready(function($) {
$('.payment-form').on('submit', function(e) {
e.preventDefault();
var form = $(this);
var button = form.find('.payment-button');
var loading = form.find('.payment-loading');
button.prop('disabled', true);
loading.show();
$.ajax({
url: form.attr('action'),
type: 'POST',
data: form.serialize(),
dataType: 'json',
success: function(response) {
if (response.success) {
if (response.data.redirect_url) {
window.location.href = response.data.redirect_url;
} else if (response.data.qr_code) {
// 显示二维码
form.html('<img src="' + response.data.qr_code + '" alt="支付二维码">');
}
} else {
alert(response.data.message);
button.prop('disabled', false);
loading.hide();
}
},
error: function() {
alert('请求失败,请重试');
button.prop('disabled', false);
loading.hide();
}
});
});
});
</script>
<?php
return ob_get_clean();
}
/**
* 支付历史短代码
*/
public static function render_payment_history() {
if (!is_user_logged_in()) {
return '<p>请先登录查看支付历史</p>';
}
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
$user_id = get_current_user_id();
$orders = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM {$table_name} WHERE user_id = %d ORDER BY created_at DESC LIMIT 20",
$user_id
));
ob_start();
?>
<div class="payment-history">
<h3>支付历史</h3>
<?php if (empty($orders)): ?>
<p>暂无支付记录</p>
<?php else: ?>
<table class="payment-history-table">
<thead>
<tr>
<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 number_format($order->amount, 2); ?>元</td>
<td>
<span class="status-badge status-<?php echo esc_attr($order->status); ?>">
<?php echo Payment_Admin::get_status_label($order->status); ?>
</span>
</td>
<td><?php echo esc_html($order->payment_method); ?></td>
<td><?php echo esc_html($order->created_at); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<style>
.payment-history-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
.payment-history-table th,
.payment-history-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.payment-history-table th {
background-color: #f2f2f2;
}
.status-badge {
padding: 2px 8px;
border-radius: 3px;
font-size: 12px;
}
.status-pending {
background-color: #ffc107;
color: #333;
}
.status-completed {
background-color: #28a745;
color: white;
}
.status-cancelled {
background-color: #dc3545;
color: white;
}
</style>
<?php
return ob_get_clean();
}
/**
* 捐赠表单短代码
*/
public static function render_donation_form($atts) {
$atts = shortcode_atts([
'title' => '支持我们',
'description' => '您的支持是我们前进的动力',
'default_amounts' => '5,10,20,50,100',
'custom_amount' => true
], $atts);
$default_amounts = array_map('intval', explode(',', $atts['default_amounts']));
ob_start();
?>
<div class="donation-form">
<h3><?php echo esc_html($atts['title']); ?></h3>
<p><?php echo esc_html($atts['description']); ?></p>
<form method="post" class="donation-form-content">
<div class="amount-selection">
<h4>选择捐赠金额</h4>
<div class="amount-buttons">
<?php foreach ($default_amounts as $amount): ?>
<button type="button" class="amount-button" data-amount="<?php echo esc_attr($amount); ?>">
<?php echo esc_html($amount); ?>元
</button>
<?php endforeach; ?>
</div>
<?php if ($atts['custom_amount']): ?>
<div class="custom-amount">
<label for="custom_amount_input">自定义金额:</label>
<input type="number" id="custom_amount_input" name="custom_amount" min="1" step="1" placeholder="输入金额">
</div>
<?php endif; ?>
</div>
<div class="payment-methods">
<h4>选择支付方式</h4>
<div class="gateway-buttons">
<label class="gateway-option">
<input type="radio" name="gateway" value="alipay" checked>
<span class="gateway-icon">支付宝</span>
</label>
<label class="gateway-option">
<input type="radio" name="gateway" value="wechat">
<span class="gateway-icon">微信支付</span>
</label>
</div>
</div>
<div class="donor-info">
<h4>捐赠信息(可选)</h4>
<div class="form-group">
<label for="donor_name">姓名:</label>
<input type="text" id="donor_name" name="donor_name" placeholder="您的姓名">
</div>
<div class="form-group">
<label for="donor_message">留言:</label>
<textarea id="donor_message" name="donor_message" rows="3" placeholder="想对我们说的话"></textarea>
</div>
</div>
<input type="hidden" name="donation_amount" id="donation_amount" value="">
<input type="hidden" name="action" value="process_donation">
<button type="submit" class="donation-submit-button" disabled>
确认捐赠
</button>
</form>
</div>
<script>
jQuery(document).ready(function($) {
// 金额选择
$('.amount-button').on('click', function() {
$('.amount-button').removeClass('selected');
$(this).addClass('selected');
$('#donation_amount').val($(this).data('amount'));
$('.donation-submit-button').prop('disabled', false);
});
// 自定义金额输入
$('#custom_amount_input').on('input', function() {
var amount = $(this).val();
if (amount && amount > 0) {
$('.amount-button').removeClass('selected');
$('#donation_amount').val(amount);
$('.donation-submit-button').prop('disabled', false);
} else {
$('.donation-submit-button').prop('disabled', true);
}
});
// 表单提交
$('.donation-form-content').on('submit', function(e) {
e.preventDefault();
var amount = $('#donation_amount').val();
if (!amount || amount <= 0) {
alert('请选择或输入捐赠金额');
return;
}
var formData = $(this).serialize();
$.ajax({
url: '<?php echo admin_url("admin-ajax.php"); ?>',
type: 'POST',
data: formData,
dataType: 'json',
beforeSend: function() {
$('.donation-submit-button').prop('disabled', true).text('处理中...');
},
success: function(response) {
if (response.success) {
if (response.data.redirect_url) {
window.location.href = response.data.redirect_url;
}
} else {
alert(response.data.message);
$('.donation-submit-button').prop('disabled', false).text('确认捐赠');
}
},
error: function() {
alert('请求失败,请重试');
$('.donation-submit-button').prop('disabled', false).text('确认捐赠');
}
});
});
});
</script>
<style>
.donation-form {
max-width: 500px;
margin: 0 auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
background-color: #f9f9f9;
}
.amount-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin: 15px 0;
}
.amount-button {
padding: 10px 20px;
border: 2px solid #ddd;
background: white;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.amount-button:hover {
border-color: #007cba;
}
.amount-button.selected {
border-color: #007cba;
background-color: #007cba;
color: white;
}
.custom-amount {
margin: 15px 0;
}
.custom-amount input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.gateway-buttons {
display: flex;
gap: 15px;
margin: 15px 0;
}
.gateway-option {
display: flex;
align-items: center;
cursor: pointer;
}
.gateway-icon {
padding: 10px 20px;
border: 2px solid #ddd;
border-radius: 4px;
background: white;
}
.gateway-option input:checked + .gateway-icon {
border-color: #007cba;
background-color: #f0f8ff;
}
.form-group {
margin: 10px 0;
}
.form-group label {
display: block;
margin-bottom: 5px;
}
.form-group input,
.form-group textarea {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.donation-submit-button {
width: 100%;
padding: 12px;
background-color: #007cba;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
}
.donation-submit-button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
.donation-submit-button:hover:not(:disabled) {
background-color: #005a87;
}
</style>
<?php
return ob_get_clean();
}
}
#### 4.2 AJAX支付处理
处理前端AJAX支付请求:
class Payment_Ajax_Handler {
/**
* 初始化AJAX处理
*/
public static function init() {
// 创建支付
add_action('wp_ajax_create_payment', [__CLASS__, 'handle_create_payment']);
add_action('wp_ajax_nopriv_create_payment', [__CLASS__, 'handle_create_payment']);
// 处理捐赠
add_action('wp_ajax_process_donation', [__CLASS__, 'handle_process_donation']);
add_action('wp_ajax_nopriv_process_donation', [__CLASS__, 'handle_process_donation']);
// 支付状态查询
add_action('wp_ajax_check_payment_status', [__CLASS__, 'handle_check_payment_status']);
add_action('wp_ajax_nopriv_check_payment_status', [__CLASS__, 'handle_check_payment_status']);
}
/**
* 处理创建支付请求
*/
public static function handle_create_payment() {
// 验证nonce
if (!wp_verify_nonce($_POST['_wpnonce'] ?? '', 'create_payment')) {
wp_send_json_error(['message' => '安全验证失败']);
}
$order_id = intval($_POST['order_id'] ?? 0);
$gateway = sanitize_text_field($_POST['gateway'] ?? 'alipay');
if (!$order_id) {
wp_send_json_error(['message' => '订单ID无效']);
}
// 获取订单信息
global $wpdb;
$table_name = $wpdb->prefix . 'payment_orders';
$order = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM {$table_name} WHERE id = %d",
$order_id
));
if (!$order) {
wp_send_json_error(['message' => '订单不存在']);
}
// 根据网关创建支付
switch ($gateway) {
case 'alipay':
$alipay = new Alipay_Payment_Gateway();
$payment_data = [
'subject' => '商品购买',
'out_trade_no' => $order->order_number,
