Drop dual-read payment runtime fallbacks, align PHP schema to Vue keys, read gateway credentials only from aksrt_settings with enable toggles, expose configured adapters at checkout, fix credits pay signatures, and apply order expiry settings. Wire orphan order/card-pass/withdrawal schema pages; delete unused Payment* wrappers.
197 lines
7.7 KiB
PHP
197 lines
7.7 KiB
PHP
<?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 {
|
||
if (class_exists('AKSRT_Settings_Payment_Runtime')
|
||
&& !AKSRT_Settings_Payment_Runtime::is_gateway_enabled('alipay')) {
|
||
return false;
|
||
}
|
||
$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 {
|
||
if (!class_exists('AKSRT_Settings')) {
|
||
return [];
|
||
}
|
||
$all = AKSRT_Settings::get_all();
|
||
return [
|
||
'app_id' => (string) ($all['alipay_appid'] ?? ''),
|
||
'private_key' => (string) ($all['alipay_privatekey'] ?? ''),
|
||
'alipay_public_key' => (string) ($all['alipay_publickey'] ?? ''),
|
||
'return_url' => (string) ($all['alipay_return_url'] ?? ''),
|
||
'notify_url' => (string) ($all['alipay_notify_url'] ?? ''),
|
||
'payment_type' => (string) ($all['alipay_payment_type'] ?? 'page'),
|
||
'sign_type' => (string) ($all['alipay_sign_type'] ?? 'RSA2'),
|
||
];
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|