文件
2026-08-16 17:03:10 +08:00

107 行
3.7 KiB
PHP

<?php
if (!defined('IN_APP')) exit('Forbidden');
class AlipayGateway implements PaymentGatewayInterface
{
private $appId;
private $privateKey;
private $publicKey;
private $gatewayUrl = '';
private $sandboxUrl = '';
public function __construct()
{
$this->appId = getSetting('pay_alipay_appid', '');
$this->privateKey = getSetting('pay_alipay_private_key', '');
$this->publicKey = getSetting('pay_alipay_public_key', '');
if (getSetting('pay_alipay_sandbox', '0') === '1') {
$this->gatewayUrl = $this->sandboxUrl;
}
}
public function getName()
{
return '支付宝';
}
public function createOrder(array $order)
{
$params = [
'app_id' => $this->appId,
'method' => 'alipay.trade.page.pay',
'format' => 'JSON',
'return_url' => $order['return_url'],
'notify_url' => $order['notify_url'],
'charset' => 'utf-8',
'sign_type' => 'RSA2',
'timestamp' => date('Y-m-d H:i:s'),
'version' => '1.0',
'biz_content' => json_encode([
'out_trade_no' => $order['order_no'],
'total_amount' => sprintf('%.2f', $order['amount']),
'subject' => $order['subject'],
'product_code' => 'FAST_INSTANT_TRADE_PAY',
], JSON_UNESCAPED_UNICODE),
];
$params['sign'] = $this->sign($params);
$url = $this->gatewayUrl . '?' . http_build_query($params);
return ['url' => $url, 'form' => ''];
}
public function verifyNotify(array $params)
{
if (empty($params['sign'])) return false;
$sign = $params['sign'];
unset($params['sign'], $params['sign_type']);
return $this->rsaVerify($this->buildSignData($params), $sign);
}
public function getTradeNo(array $params)
{
return $params['trade_no'] ?? '';
}
public function isPaid(array $params)
{
return ($params['trade_status'] ?? '') === 'TRADE_SUCCESS';
}
public function respondSuccess()
{
echo 'success';
}
private function sign($params)
{
ksort($params);
$data = $this->buildSignData($params);
$res = openssl_sign($data, $signature, $this->loadPrivateKey(), OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
private function rsaVerify($data, $sign)
{
$result = openssl_verify($data, base64_decode($sign), $this->loadPublicKey(), OPENSSL_ALGO_SHA256);
return $result === 1;
}
private function buildSignData($params)
{
$pairs = [];
foreach ($params as $k => $v) {
if ($v === '' || is_array($v)) continue;
$pairs[] = $k . '=' . $v;
}
return implode('&', $pairs);
}
private function loadPrivateKey()
{
$key = trim($this->privateKey);
$key = preg_replace('/-----BEGIN RSA PRIVATE KEY-----/', '', $key);
$key = preg_replace('/-----END RSA PRIVATE KEY-----/', '', $key);
$key = str_replace(["\r", "\n", " "], '', $key);
return "-----BEGIN RSA PRIVATE KEY-----\n" .
chunk_split($key, 64, "\n") .
"-----END RSA PRIVATE KEY-----";
}
private function loadPublicKey()
{
$key = trim($this->publicKey);
$key = preg_replace('/-----BEGIN PUBLIC KEY-----/', '', $key);
$key = preg_replace('/-----END PUBLIC KEY-----/', '', $key);
$key = str_replace(["\r", "\n", " "], '', $key);
return "-----BEGIN PUBLIC KEY-----\n" .
chunk_split($key, 64, "\n") .
"-----END PUBLIC KEY-----";
}
}