文件还在测试中
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace Core\Payment;
|
||||
|
||||
/**
|
||||
* 支付宝网关
|
||||
* - demo:返回模拟支付入口
|
||||
* - live:电脑网站支付(alipay.trade.page.pay),RSA2 签名
|
||||
*/
|
||||
class AlipayGateway extends Gateway
|
||||
{
|
||||
public function pay(array $order): array
|
||||
{
|
||||
$simulate = site_url('order/demo/' . $order['order_no']);
|
||||
$hasCred = !empty($this->config['appid']) && !empty($this->config['private_key']);
|
||||
|
||||
if ($this->isDemo() || !$hasCred) {
|
||||
return [
|
||||
'mode' => 'demo',
|
||||
'channel' => 'alipay',
|
||||
'simulate' => $simulate,
|
||||
'config_missing' => !$hasCred,
|
||||
];
|
||||
}
|
||||
|
||||
$biz = [
|
||||
'out_trade_no' => $order['order_no'],
|
||||
'product_code' => 'FAST_INSTANT_TRADE_PAY',
|
||||
'total_amount' => $this->money($order['amount']),
|
||||
'subject' => $order['product_name'] ?: '商品购买',
|
||||
];
|
||||
$params = [
|
||||
'app_id' => $this->config['appid'],
|
||||
'method' => 'alipay.trade.page.pay',
|
||||
'format' => 'JSON',
|
||||
'charset' => 'utf-8',
|
||||
'sign_type' => 'RSA2',
|
||||
'timestamp' => date('Y-m-d H:i:s'),
|
||||
'version' => '1.0',
|
||||
'notify_url' => site_url('pay/notify/alipay'),
|
||||
'return_url' => site_url('order/success/' . $order['order_no']),
|
||||
'biz_content' => json_encode($biz, JSON_UNESCAPED_UNICODE),
|
||||
];
|
||||
$params['sign'] = $this->sign($params);
|
||||
$gateway = $this->config['gateway'] ?: 'https://openapi.alipay.com/gateway.do';
|
||||
return ['mode' => 'redirect', 'channel' => 'alipay', 'url' => $gateway . '?' . http_build_query($params)];
|
||||
}
|
||||
|
||||
/** RSA2 签名 */
|
||||
private function sign(array $params): string
|
||||
{
|
||||
ksort($params);
|
||||
$str = '';
|
||||
foreach ($params as $k => $v) {
|
||||
if ($v === '' || $v === null) continue;
|
||||
$str .= $k . '=' . $v . '&';
|
||||
}
|
||||
$str = rtrim($str, '&');
|
||||
$key = $this->normalizeKey($this->config['private_key'] ?? '', false);
|
||||
openssl_sign($str, $sign, $key, OPENSSL_ALGO_SHA256);
|
||||
return base64_encode($sign);
|
||||
}
|
||||
|
||||
private function normalizeKey(string $key, bool $isPublic): string
|
||||
{
|
||||
$key = trim($key);
|
||||
if (strpos($key, '-----BEGIN') === 0) return $key;
|
||||
$head = $isPublic ? "-----BEGIN PUBLIC KEY-----\n" : "-----BEGIN RSA PRIVATE KEY-----\n";
|
||||
$foot = $isPublic ? "\n-----END PUBLIC KEY-----" : "\n-----END RSA PRIVATE KEY-----";
|
||||
return $head . chunk_split($key, 64, "\n") . $foot;
|
||||
}
|
||||
|
||||
public function verifyNotify(array $data): ?string
|
||||
{
|
||||
if (empty($data['out_trade_no'])) return null;
|
||||
$status = $data['trade_status'] ?? '';
|
||||
if ($status === 'TRADE_SUCCESS' || $status === 'TRADE_FINISHED') {
|
||||
// 生产环境应使用支付宝公钥对签名做严格验签后再返回
|
||||
return $data['out_trade_no'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user