文章目录[隐藏]
实操指南:集成第三方支付接口的5个实用技巧
引言:为什么需要掌握第三方支付集成技巧
在当今数字化商业环境中,支付功能已成为网站和应用程序的核心组成部分。对于使用WordPress的开发者而言,无论是创建电子商务网站、会员订阅系统还是接受在线捐赠,集成第三方支付接口都是必不可少的一环。然而,对于行业新人和程序员来说,支付接口集成常常伴随着诸多挑战:安全性要求高、技术细节复杂、用户体验需优化等。
本文将从WordPress开发者的角度出发,深入探讨集成第三方支付接口的5个实用技巧。我们将结合具体代码示例,帮助您理解如何在WordPress环境中高效、安全地实现支付功能,同时确保良好的用户体验和系统稳定性。
技巧一:选择合适的支付网关插件或自定义开发
评估现有插件方案
WordPress生态系统中有众多支付网关插件可供选择,如WooCommerce支付插件、Easy Digital Downloads等。在选择前,请考虑以下因素:
- 支付网关支持:确保插件支持您目标市场的支付方式(支付宝、微信支付、PayPal、Stripe等)
- 费用结构:了解插件的许可费用和交易手续费
- 更新频率:活跃维护的插件能更好地适应支付API的变化
- 文档和支持:完善的文档和社区支持能节省大量开发时间
自定义开发的优势与实现
当现有插件无法满足特定需求时,自定义开发成为必要选择。以下是创建自定义支付模块的基本步骤:
/**
* WordPress自定义支付模块基础结构
*/
class Custom_Payment_Gateway {
private $api_key;
private $api_secret;
public function __construct() {
$this->api_key = get_option('payment_api_key');
$this->api_secret = get_option('payment_api_secret');
// 注册支付短代码
add_shortcode('custom_payment_form', array($this, 'render_payment_form'));
// 处理支付回调
add_action('init', array($this, 'handle_payment_callback'));
}
/**
* 渲染支付表单
*/
public function render_payment_form($atts) {
$atts = shortcode_atts(array(
'amount' => 0,
'product_id' => 0,
'description' => '产品购买'
), $atts);
// 生成唯一订单号
$order_id = uniqid('ORDER_');
// 创建支付表单HTML
$output = '<form id="custom-payment-form" method="POST" action="' . admin_url('admin-ajax.php') . '">';
$output .= '<input type="hidden" name="action" value="process_payment">';
$output .= '<input type="hidden" name="order_id" value="' . esc_attr($order_id) . '">';
$output .= '<input type="hidden" name="amount" value="' . esc_attr($atts['amount']) . '">';
$output .= '<input type="hidden" name="product_id" value="' . esc_attr($atts['product_id']) . '">';
$output .= '<button type="submit" class="payment-button">支付 ¥' . esc_html($atts['amount']) . '</button>';
$output .= '</form>';
return $output;
}
/**
* 处理支付请求
*/
public function process_payment() {
// 验证非ce和权限
if (!wp_verify_nonce($_POST['_wpnonce'], 'process_payment') || !is_user_logged_in()) {
wp_die('权限验证失败');
}
$order_id = sanitize_text_field($_POST['order_id']);
$amount = floatval($_POST['amount']);
$product_id = intval($_POST['product_id']);
// 调用支付API
$payment_result = $this->call_payment_api($order_id, $amount);
if ($payment_result['success']) {
// 支付成功,更新订单状态
$this->update_order_status($order_id, 'completed');
// 重定向到成功页面
wp_redirect(add_query_arg('payment', 'success', get_permalink($product_id)));
exit;
} else {
// 支付失败处理
wp_redirect(add_query_arg('payment', 'failed', get_permalink($product_id)));
exit;
}
}
}
混合方案:扩展现有插件
有时最佳方案是扩展现有插件而非从头开发。例如,为WooCommerce添加自定义支付网关:
/**
* 自定义WooCommerce支付网关
*/
class WC_Custom_Gateway extends WC_Payment_Gateway {
public function __construct() {
$this->id = 'custom_gateway';
$this->method_title = '自定义支付网关';
$this->method_description = '通过自定义支付网关接受支付';
// 初始化表单字段
$this->init_form_fields();
// 初始化设置
$this->init_settings();
// 保存设置
add_action('woocommerce_update_options_payment_gateways_' . $this->id,
array($this, 'process_admin_options'));
}
/**
* 初始化设置表单字段
*/
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => '启用/禁用',
'type' => 'checkbox',
'label' => '启用自定义支付网关',
'default' => 'yes'
),
'api_key' => array(
'title' => 'API密钥',
'type' => 'text',
'default' => ''
)
);
}
/**
* 处理支付
*/
public function process_payment($order_id) {
$order = wc_get_order($order_id);
// 调用支付API
$payment_result = $this->process_payment_request($order);
if ($payment_result['success']) {
// 标记订单为处理中
$order->update_status('processing', '等待支付确认');
// 返回成功结果
return array(
'result' => 'success',
'redirect' => $payment_result['payment_url']
);
} else {
// 返回错误
wc_add_notice('支付处理失败: ' . $payment_result['message'], 'error');
return;
}
}
}
技巧二:确保支付过程的安全性
数据传输加密
支付数据传输必须使用HTTPS加密。在WordPress中确保全站启用HTTPS:
/**
* 强制使用HTTPS
*/
function force_ssl_for_payment() {
if (!is_ssl() && (is_checkout() || is_account_page())) {
wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 301);
exit();
}
}
add_action('template_redirect', 'force_ssl_for_payment');
/**
* 在WordPress设置中强制HTTPS
*/
function force_ssl_in_wordpress() {
if (get_option('force_ssl') === 'yes') {
define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
$_SERVER['HTTPS'] = 'on';
}
}
add_action('init', 'force_ssl_in_wordpress');
敏感数据安全处理
/**
* 安全处理支付数据
*/
class Payment_Security {
/**
* 加密敏感数据
*/
public static function encrypt_data($data, $key) {
$method = 'AES-256-CBC';
$iv_length = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($iv_length);
$encrypted = openssl_encrypt(
$data,
$method,
$key,
OPENSSL_RAW_DATA,
$iv
);
// 返回base64编码的加密数据和IV
return base64_encode($iv . $encrypted);
}
/**
* 解密数据
*/
public static function decrypt_data($encrypted_data, $key) {
$data = base64_decode($encrypted_data);
$method = 'AES-256-CBC';
$iv_length = openssl_cipher_iv_length($method);
$iv = substr($data, 0, $iv_length);
$encrypted = substr($data, $iv_length);
return openssl_decrypt(
$encrypted,
$method,
$key,
OPENSSL_RAW_DATA,
$iv
);
}
/**
* 安全存储API密钥
*/
public static function store_api_key($key_name, $key_value) {
// 使用WordPress安全密钥加密
$encryption_key = defined('AUTH_SALT') ? AUTH_SALT : 'fallback_key';
$encrypted_key = self::encrypt_data($key_value, $encryption_key);
// 存储在数据库中
update_option($key_name . '_encrypted', $encrypted_key);
// 不存储原始密钥
delete_option($key_name);
}
/**
* 验证支付回调签名
*/
public static function verify_payment_callback($data, $signature, $secret_key) {
// 按支付平台要求排序参数
ksort($data);
// 生成待签名字符串
$sign_string = '';
foreach ($data as $key => $value) {
if ($key !== 'sign' && $key !== 'sign_type') {
$sign_string .= $key . '=' . $value . '&';
}
}
$sign_string = rtrim($sign_string, '&');
// 计算签名
$calculated_sign = hash_hmac('sha256', $sign_string, $secret_key);
// 比较签名
return hash_equals($calculated_sign, $signature);
}
}
防止CSRF攻击
/**
* 支付表单CSRF保护
*/
function add_payment_nonce() {
wp_nonce_field('process_payment', 'payment_nonce');
}
add_action('payment_form_start', 'add_payment_nonce');
/**
* 验证支付请求
*/
function validate_payment_request() {
if (!isset($_POST['payment_nonce']) ||
!wp_verify_nonce($_POST['payment_nonce'], 'process_payment')) {
wp_die('安全验证失败,请重试。');
}
// 验证用户权限
if (!is_user_logged_in()) {
wp_die('请先登录后再进行支付。');
}
}
技巧三:优化支付流程与用户体验
响应式支付表单设计
/**
* 响应式支付表单
*/
function responsive_payment_form($amount, $product_name) {
ob_start();
?>
<div class="payment-container">
<div class="payment-header">
<h3>支付详情</h3>
</div>
<div class="payment-body">
<div class="order-summary">
<p><strong>商品:</strong><?php echo esc_html($product_name); ?></p>
<p><strong>金额:</strong>¥<?php echo number_format($amount, 2); ?></p>
</div>
<form id="payment-form" class="payment-form" method="POST">
<?php wp_nonce_field('process_payment', 'payment_nonce'); ?>
<div class="form-group">
<label for="card-number">银行卡号</label>
<div class="input-with-icon">
<i class="icon-credit-card"></i>
<input type="text" id="card-number" name="card_number"
placeholder="1234 5678 9012 3456"
pattern="[0-9s]{13,19}"
required>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label for="expiry-date">有效期</label>
<input type="text" id="expiry-date" name="expiry_date"
placeholder="MM/YY"
pattern="(0[1-9]|1[0-2])/[0-9]{2}"
required>
</div>
<div class="form-group">
<label for="cvv">CVV</label>
<input type="text" id="cvv" name="cvv"
placeholder="123"
pattern="[0-9]{3,4}"
required>
</div>
</div>
<div class="payment-methods">
<p>选择支付方式:</p>
<div class="method-options">
<label class="method-option">
<input type="radio" name="payment_method" value="alipay" checked>
<img src="<?php echo get_template_directory_uri(); ?>/assets/alipay-logo.png" alt="支付宝">
</label>
<label class="method-option">
<input type="radio" name="payment_method" value="wechat">
<img src="<?php echo get_template_directory_uri(); ?>/assets/wechatpay-logo.png" alt="微信支付">
</label>
<label class="method-option">
<input type="radio" name="payment_method" value="unionpay">
<img src="<?php echo get_template_directory_uri(); ?>/assets/unionpay-logo.png" alt="银联">
</label>
</div>
</div>
<button type="submit" class="btn-pay" id="submit-payment">
<span class="btn-text">支付 ¥<?php echo number_format($amount, 2); ?></span>
<span class="loading-spinner" style="display:none;"></span>
</button>
<div class="payment-security-note">
<i class="icon-lock"></i>
<span>支付过程已加密,保障您的资金安全</span>
</div>
</form>
</div>
</div>
<script>
jQuery(document).ready(function($) {
// 表单提交处理
$('#payment-form').on('submit', function(e) {
e.preventDefault();
var $form = $(this);
var $submitBtn = $('#submit-payment');
var $btnText = $submitBtn.find('.btn-text');
var $spinner = $submitBtn.find('.loading-spinner');
// 显示加载状态
$btnText.hide();
$spinner.show();
$submitBtn.prop('disabled', true);
// 发送AJAX请求
$.ajax({
url: '<?php echo admin_url("admin-ajax.php"); ?>',
type: 'POST',
data: $form.serialize() + '&action=process_payment',
dataType: 'json',
success: function(response) {
if (response.success) {
// 支付成功,重定向
window.location.href = response.data.redirect_url;
} else {
// 显示错误信息
alert(response.data.message);
$btnText.show();
$spinner.hide();
$submitBtn.prop('disabled', false);
}
},
error: function() {
alert('网络错误,请重试');
$btnText.show();
$spinner.hide();
$submitBtn.prop('disabled', false);
}
});
});
// 信用卡号格式化
$('#card-number').on('input', function() {
var value = $(this).val().replace(/s+/g, '').replace(/[^0-9]/gi, '');
var formatted = value.replace(/(d{4})/g, '$1 ').trim();
$(this).val(formatted);
});
});
</script>
<?php
// 添加CSS样式
echo '<style>
.payment-container {
max-width: 500px;
margin: 0 auto;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
overflow: hidden;
}
@media (max-width: 600px) {
.payment-container {
margin: 0 15px;
}
}
.payment-header {
background: #4a6fa5;
color: white;
padding: 20px;
text-align: center;
}
.payment-body {
padding: 25px;
}
.form-group {
margin-bottom: 20px;
}
.form-row {
display: flex;
gap: 15px;
}
@media (max-width: 480px) {
.form-row {
flex-direction: column;
gap: 0;
}
}
.btn-pay {
width: 100%;
padding: 15px;
background: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
.btn-pay:hover {
background: #45a049;
}
.btn-pay:disabled {
background: #cccccc;
cursor: not-allowed;
}
</style>';
return ob_get_clean();
}
异步支付状态检查
/**
* 异步支付状态检查
*/
class Payment_Status_Checker {
/**
* 初始化状态检查
*/
public function init() {
// AJAX处理支付状态检查
add_action('wp_ajax_check_payment_status', array($this, 'ajax_check_status'));
add_action('wp_ajax_nopriv_check_payment_status', array($this, 'ajax_check_status'));
// 添加前端脚本
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
/**
* AJAX状态检查处理
*/
public function ajax_check_status() {
['order_id']);
$nonce = sanitize_text_field($_POST['nonce']);
// 验证nonce
if (!wp_verify_nonce($nonce, 'check_payment_' . $order_id)) {
wp_send_json_error('验证失败');
}
// 检查订单状态
$status = $this->get_order_status($order_id);
if ($status === 'completed') {
wp_send_json_success(array(
'status' => 'completed',
'message' => '支付成功',
'redirect_url' => $this->get_success_url($order_id)
));
} elseif ($status === 'failed') {
wp_send_json_success(array(
'status' => 'failed',
'message' => '支付失败'
));
} else {
wp_send_json_success(array(
'status' => 'pending',
'message' => '等待支付完成'
));
}
}
/**
* 获取订单状态
*/
private function get_order_status($order_id) {
// 这里应该从数据库或支付平台API获取实际状态
$status = get_transient('payment_status_' . $order_id);
return $status ?: 'pending';
}
/**
* 添加前端脚本
*/
public function enqueue_scripts() {
if (is_checkout() || is_page('payment')) {
wp_enqueue_script('payment-status-checker',
get_template_directory_uri() . '/js/payment-status.js',
array('jquery'), '1.0', true);
wp_localize_script('payment-status-checker', 'payment_vars', array(
'ajax_url' => admin_url('admin-ajax.php'),
'check_interval' => 3000 // 每3秒检查一次
));
}
}
}
// 前端JavaScript代码
function payment_status_checker_js() {
?>
<script>
(function($) {
'use strict';
class PaymentStatusChecker {
constructor(orderId, nonce) {
this.orderId = orderId;
this.nonce = nonce;
this.maxAttempts = 20; // 最多尝试20次
this.attempts = 0;
this.checkInterval = payment_vars.check_interval;
this.checking = false;
}
start() {
this.checking = true;
this.checkStatus();
}
stop() {
this.checking = false;
}
checkStatus() {
if (!this.checking || this.attempts >= this.maxAttempts) {
return;
}
this.attempts++;
$.ajax({
url: payment_vars.ajax_url,
type: 'POST',
data: {
action: 'check_payment_status',
order_id: this.orderId,
nonce: this.nonce
},
dataType: 'json',
success: (response) => {
if (response.success) {
const data = response.data;
switch(data.status) {
case 'completed':
this.onSuccess(data);
break;
case 'failed':
this.onFailure(data);
break;
case 'pending':
// 继续检查
setTimeout(() => this.checkStatus(), this.checkInterval);
break;
}
}
},
error: () => {
// 网络错误,继续尝试
if (this.attempts < this.maxAttempts) {
setTimeout(() => this.checkStatus(), this.checkInterval);
}
}
});
}
onSuccess(data) {
this.stop();
// 显示成功消息
this.showMessage('success', data.message);
// 3秒后重定向
setTimeout(() => {
window.location.href = data.redirect_url;
}, 3000);
}
onFailure(data) {
this.stop();
this.showMessage('error', data.message);
}
showMessage(type, text) {
// 移除现有消息
$('.payment-message').remove();
const messageClass = type === 'success' ? 'success-message' : 'error-message';
const message = $(`
<div class="payment-message ${messageClass}">
<p>${text}</p>
</div>
`);
$('#payment-form').before(message);
// 自动消失
if (type === 'success') {
setTimeout(() => message.fadeOut(), 5000);
}
}
}
// 初始化检查器
$(document).ready(function() {
const orderId = $('#payment-order-id').val();
const nonce = $('#payment-check-nonce').val();
if (orderId && nonce) {
const checker = new PaymentStatusChecker(orderId, nonce);
checker.start();
}
});
})(jQuery);
</script>
<?php
}
add_action('wp_footer', 'payment_status_checker_js');
## 技巧四:实现完善的错误处理与日志记录
### 结构化错误处理
/**
- 支付错误处理类
*/
class Payment_Error_Handler {
private $log_file;
private $notify_email;
public function __construct() {
$upload_dir = wp_upload_dir();
$this->log_file = $upload_dir['basedir'] . '/payment-errors.log';
$this->notify_email = get_option('admin_email');
// 注册错误处理函数
set_error_handler(array($this, 'handle_error'));
register_shutdown_function(array($this, 'handle_shutdown'));
}
/**
* 自定义错误处理
*/
public function handle_error($errno, $errstr, $errfile, $errline) {
// 只处理支付相关的错误
if (strpos($errfile, 'payment') !== false ||
strpos($errstr, 'payment') !== false) {
$error_type = $this->get_error_type($errno);
$error_message = sprintf(
"[%s] %s: %s in %s on line %d",
date('Y-m-d H:i:s'),
$error_type,
$errstr,
$errfile,
$errline
);
$this->log_error($error_message);
// 如果是严重错误,发送通知
if (in_array($errno, array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR))) {
$this->notify_admin($error_message);
}
}
// 继续执行标准错误处理
return false;
}
/**
* 处理致命错误
*/
public function handle_shutdown() {
$error = error_get_last();
if ($error && $error['type'] === E_ERROR) {
$error_message = sprintf(
"[%s] 致命错误: %s in %s on line %d",
date('Y-m-d H:i:s'),
$error['message'],
$error['file'],
$error['line']
);
$this->log_error($error_message);
$this->notify_admin($error_message);
}
}
/**
* 记录支付API错误
*/
public function log_api_error($api_name, $error_code, $error_message, $request_data = array()) {
$log_entry = sprintf(
"[%s] API错误 - %s: 代码=%s, 消息=%s, 请求数据=%sn",
date('Y-m-d H:i:s'),
$api_name,
$error_code,
$error_message,
json_encode($request_data, JSON_UNESCAPED_UNICODE)
);
$this->log_error($log_entry);
// 如果是关键错误,发送通知
$critical_errors = array('INSUFFICIENT_FUNDS', 'CARD_DECLINED', 'NETWORK_ERROR');
if (in_array($error_code, $critical_errors)) {
$this->notify_admin($log_entry);
}
}
/**
* 记录错误到文件
*/
private function log_error($message) {
// 确保日志目录存在
$log_dir = dirname($this->log_file);
if (!file_exists($log_dir)) {
wp_mkdir_p($log_dir);
}
// 写入日志文件
file_put_contents($this->log_file, $message . PHP_EOL, FILE_APPEND | LOCK_EX);
// 同时记录到WordPress调试日志
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log($message);
}
}
/**
* 通知管理员
*/
private function notify_admin($message) {
$subject = '支付系统错误通知 - ' . get_bloginfo('name');
$body = "检测到支付系统错误:nn" . $message . "nn请及时处理。";
wp_mail($this->notify_email, $subject, $body);
}
/**
* 获取错误类型
*/
private function get_error_type($errno) {
$types = array(
E_ERROR => '错误',
E_WARNING => '警告',
E_PARSE => '解析错误',
E_NOTICE => '通知',
E_CORE_ERROR => '核心错误',
E_CORE_WARNING => '核心警告',
E_COMPILE_ERROR => '编译错误',
E_COMPILE_WARNING => '编译警告',
E_USER_ERROR => '用户错误',
E_USER_WARNING => '用户警告',
E_USER_NOTICE => '用户通知',
E_STRICT => '严格标准',
E_RECOVERABLE_ERROR => '可恢复错误',
E_DEPRECATED => '弃用警告',
E_USER_DEPRECATED => '用户弃用警告'
);
return isset($types[$errno]) ? $types[$errno] : '未知错误';
}
/**
* 获取错误日志
*/
public function get_error_log($limit = 100) {
if (!file_exists($this->log_file)) {
return array();
}
$lines = file($this->log_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$lines = array_slice($lines, -$limit);
return array_reverse($lines);
}
}
/**
- 支付异常类
*/
class Payment_Exception extends Exception {
private $error_code;
private $user_message;
public function __construct($message, $code = 0, $user_message = null, Exception $previous = null) {
parent::__construct($message, $code, $previous);
$this->error_code = $code;
$this->user_message = $user_message ?: '支付处理过程中发生错误,请稍后重试。';
}
public function getErrorCode() {
return $this->error_code;
}
public function getUserMessage() {
return $this->user_message;
}
public function toArray() {
return array(
'error_code' => $this->error_code,
'internal_message' => $this->getMessage(),
'user_message' => $this->user_message,
'file' => $this->getFile(),
'line' => $this->getLine()
);
}
}
/**
- 支付API调用包装器,包含错误处理
*/
class Payment_API_Wrapper {
private $error_handler;
public function __construct() {
$this->error_handler = new Payment_Error_Handler();
}
/**
* 安全调用支付API
*/
public function call_api($api_name, $endpoint, $data, $method = 'POST') {
try {
// 验证数据
$this->validate_request_data($data);
// 准备请求
$args = array(
'method' => $method,
'timeout' => 30,
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->get_api_key($api_name)
),
'body' => json_encode($data, JSON_UNESCAPED_UNICODE)
);
// 发送请求
$response = wp_remote_request($endpoint, $args);
// 检查响应
if (is_wp_error($response)) {
throw new Payment_Exception(
'API请求失败: ' . $response->get_error_message(),
'NETWORK_ERROR',
'网络连接失败,请检查网络设置'
);
}
$status_code = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
$response_data = json_decode($body, true);
// 检查HTTP状态码
if ($status_code !== 200) {
$error_message = isset($response_data['message']) ?
$response_data['message'] : 'HTTP错误: ' . $status_code;
throw new Payment_Exception(
$error_message,
'HTTP_' . $status_code,
'支付服务暂时不可用,请稍后重试'
);
}
// 检查API返回的错误
if (isset($response_data['error']) && $response_data['error']) {
$this->error_handler->log_api_error(
$api_name,
$response_data['error_code'],
$response_data['error_message'],
$data
);
throw new Payment_Exception(
$response_data['error_message'],
$response_data['error_code'],
$this->get_user_friendly_message($response_data['error_code'])
);
}
return $response_data;
} catch (Payment_Exception $e) {
// 记录并重新抛出
$this->error_handler->log_api_error(
$api_name,
$e->getErrorCode(),
$e->getMessage(),
$data
);
throw $e;
} catch (Exception $e) {
// 处理其他异常
$this->error_handler->log_api_error(
$api_name,
'UNKNOWN_ERROR',
$e->getMessage(),
$data
);
throw new Payment_Exception(
'未知错误: ' . $e->getMessage(),
'UNKNOWN_ERROR',
'系统内部错误,请联系客服'
);
}
}
/**
* 验证请求数据
*/
private function validate_request_data($data) {
$required_fields = array('amount', 'order_id', 'currency');
foreach ($required_fields as $field) {
if (!isset($data[$field]) || empty($data[$field])) {
throw new Payment_Exception(
'缺少必要字段: ' . $field,
'VALIDATION_ERROR',
'支付信息不完整,请检查输入'
);
}
}
// 验证金额
if (!is_numeric($data['amount']) || $data['amount'] <= 0) {
throw new Payment_Exception(
'无效的金额: ' . $data['amount'],
'INVALID_AMOUNT',
'支付金额无效,请重新输入'
);
}
}
/**
* 获取用户友好的错误消息
*/
private function get_user_friendly_message($error_code) {
$messages = array(
'INSUFFICIENT_FUNDS' => '余额不足,请更换支付方式',
'CARD_DECLINED' => '银行卡被拒绝,请更换支付方式',
'INVALID_CARD' => '银行卡信息无效,请检查后重试',
'EXPIRED_CARD' => '银行卡已过期,请更换支付方式',
'NETWORK_ERROR' => '网络连接失败,请稍后重试',
'TIMEOUT' => '支付超时,请稍后重试',
'DUPLICATE_ORDER' => '订单已支付,请勿重复提交'
);
return isset($messages[$error_code]) ?
$messages[$error_code] : '支付失败,请稍后重试';
}
}
## 技巧五:测试与部署最佳实践
### 创建测试环境
/**
- 支付测试环境配置
*/
class Payment_Test_Environment {
private $is_test_mode;
public function __construct() {
$this->is_test_mode = defined('PAYMENT_TEST_MODE') && PAYMENT_TEST_MODE;
if ($this->is_test_mode) {
$this->setup_test_environment();
}
}
/**
* 设置测试环境
*/
private function setup_test_environment() {
// 使用测试API密钥
add_filter('payment_api_key', function($key) {
return defined('PAYMENT_TEST_API_KEY') ?
PAYMENT_TEST_API_KEY : 'test_' . $key;
});
// 使用测试API端点
add_filter('payment_api_endpoint', function($endpoint) {
return str_replace('api.', 'api-test.', $endpoint);
});
// 禁用实际支付
add_filter('payment_process_real_payment', '__return_false');
// 添加测试数据
add_action('init', array($this, 'add_test_data'));
// 注册测试工具页面
add_action('admin_menu', array($this, 'add_test_tools_page'));
}
/**
* 添加测试数据
*/
public function add_test_data() {
if (is_admin() && current_user_can('manage_options')) {
$this->create_test_products();
$this->create_test_orders();
}
}
/**
* 创建测试产品
*/
private function create_test_products() {
$test_products = array(
array(
'name' => '测试产品A',
'price' => 10.00,
'description' => '用于支付测试的虚拟产品A'
),
array(
'name' => '测试产品B',
'price' => 25.50,
'description' => '用于支付测试的虚拟产品B'
),
array(
'name' => '测试产品C',
'price'
