Files
wordpress-theme-aksrt/inc/classes/gateways/class-aksrt-alipay-gateway.php
T

198 lines
7.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* AKSRT Alipay Gateway — 支付宝支付网关
*
* 使用 yurunsoft/pay-sdk 实现电脑网站支付、手机网站支付。
*
* @package AKSRT
*/
defined('ABSPATH') || exit;
class AKSRT_Alipay_Gateway implements AKSRT_Payment_Gateway_Interface {
public function get_id(): string {
return 'alipay';
}
public function get_name(): string {
return __('支付宝', 'aksrt');
}
public function is_configured(): bool {
$config = $this->get_config();
return !empty($config['app_id']) && !empty($config['private_key']) && !empty($config['alipay_public_key']);
}
public function create_payment(array $order): array {
if (!$this->is_configured()) {
return ['success' => false, 'message' => __('支付宝未配置', 'aksrt')];
}
$config = $this->get_config();
$order_number = $order['order_number'] ?? '';
$amount = (float) ($order['amount'] ?? 0);
$subject = $order['subject'] ?? __('订单支付', 'aksrt');
$payment_type = $config['payment_type'] ?? 'page'; // page / wap
try {
$sdk = $this->create_sdk($config);
if ($payment_type === 'wap') {
// 手机网站支付
$request = new \Yurun\PaySDK\AlipayApp\Wap\Params\Pay\Request;
$request->notify_url = home_url('/wp-json/aksrt/v1/payment/alipay/notify');
$request->return_url = home_url('/wp-json/aksrt/v1/payment/alipay/return');
$request->businessParams->out_trade_no = $order_number;
$request->businessParams->total_amount = number_format($amount, 2, '.', '');
$request->businessParams->subject = $subject;
} else {
// 电脑网站支付
$request = new \Yurun\PaySDK\AlipayApp\Page\Params\Pay\Request;
$request->notify_url = home_url('/wp-json/aksrt/v1/payment/alipay/notify');
$request->return_url = home_url('/wp-json/aksrt/v1/payment/alipay/return');
$request->businessParams->out_trade_no = $order_number;
$request->businessParams->total_amount = number_format($amount, 2, '.', '');
$request->businessParams->subject = $subject;
}
// 构建支付跳转 URL(prepareExecute 已将查询参数追加到 $url)
$sdk->prepareExecute($request, $url, $data);
$payment_url = $url;
return [
'success' => true,
'payment_url' => $payment_url,
'payment_data' => ['order_number' => $order_number],
'message' => __('支付宝支付链接已生成', 'aksrt'),
];
} catch (\Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
}
public function verify_callback(WP_REST_Request $request): array {
$config = $this->get_config();
try {
$sdk = $this->create_sdk($config);
$params = $request->get_params();
if ($sdk->verifyCallback($params)) {
$trade_status = $params['trade_status'] ?? '';
return [
'success' => true,
'order_number' => $params['out_trade_no'] ?? '',
'amount' => (float) ($params['total_amount'] ?? 0),
'transaction_id' => $params['trade_no'] ?? '',
'status' => in_array($trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED']) ? 'paid' : 'pending',
];
}
return ['success' => false, 'message' => __('支付宝回调验证失败', 'aksrt')];
} catch (\Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
}
public function query_status(string $order_number): array {
if (!$this->is_configured()) {
return ['success' => false, 'message' => __('支付宝未配置', 'aksrt')];
}
$config = $this->get_config();
try {
$sdk = $this->create_sdk($config);
$request = new \Yurun\PaySDK\AlipayApp\Params\Query\Request;
$request->businessParams->out_trade_no = $order_number;
$result = $sdk->execute($request);
if ($sdk->checkResult()) {
$trade_status = $result['trade_status'] ?? '';
$status = 'pending';
if (in_array($trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
$status = 'paid';
} elseif ($trade_status === 'TRADE_CLOSED') {
$status = 'cancelled';
}
return [
'success' => true,
'status' => $status,
'transaction_id' => $result['trade_no'] ?? '',
];
}
return ['success' => false, 'message' => $sdk->getError() ?: __('查询失败', 'aksrt')];
} catch (\Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
}
public function refund(string $order_number, float $amount): array {
if (!$this->is_configured()) {
return ['success' => false, 'message' => __('支付宝未配置', 'aksrt')];
}
$config = $this->get_config();
try {
$sdk = $this->create_sdk($config);
$request = new \Yurun\PaySDK\AlipayApp\Params\Refund\Request;
$request->businessParams->out_trade_no = $order_number;
$request->businessParams->refund_amount = number_format($amount, 2, '.', '');
$request->businessParams->refund_reason = __('用户申请退款', 'aksrt');
$request->businessParams->out_request_no = $order_number . '_refund_' . time();
$result = $sdk->execute($request);
if ($sdk->checkResult()) {
return [
'success' => true,
'refund_id' => $result['trade_no'] ?? '',
'message' => __('退款成功', 'aksrt'),
];
}
return ['success' => false, 'message' => $sdk->getError() ?: __('退款失败', 'aksrt')];
} catch (\Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
}
private function get_config(): array {
// 优先从统一设置读取(schema 保存的 key)
if (class_exists('AKSRT_Settings')) {
$all = AKSRT_Settings::get_all();
if (!empty($all['alipay_appid'])) {
return [
'app_id' => $all['alipay_appid'] ?? '',
'private_key' => $all['alipay_privatekey'] ?? '',
'alipay_public_key' => $all['alipay_publickey'] ?? '',
'return_url' => $all['alipay_return_url'] ?? '',
'notify_url' => $all['alipay_notify_url'] ?? '',
'payment_type' => $all['alipay_payment_type'] ?? 'page',
'sign_type' => $all['alipay_sign_type'] ?? 'RSA2',
];
}
}
// 回退到独立 option
$settings = get_option('aksrt_payment_alipay', []);
return is_array($settings) ? $settings : [];
}
private function create_sdk(array $config): \Yurun\PaySDK\AlipayApp\SDK {
$params = new \Yurun\PaySDK\AlipayApp\Params\PublicParams;
$params->appID = $config['app_id'] ?? '';
$params->appPrivateKey = $config['private_key'] ?? '';
$params->appPublicKey = $config['alipay_public_key'] ?? '';
$params->sign_type = $config['sign_type'] ?? 'RSA2';
return new \Yurun\PaySDK\AlipayApp\SDK($params);
}
}