支付宝扫码支付
官方文档:https://docs.open.alipay.com/194/105072
在开发之前需要申请应用的APPID,并设置密钥
密钥生成方法:https://docs.open.alipay.com/291/106103/
需要PHP支持openssl扩展
在php.ini中找到:
extension=php_openssl.dll 去掉前面的注释
请求预下单接口(官方文档)
class AliPay{
$private $_appId; // 应用ID
$private $_privateKey;// 应用私钥,加密使用
$private $_publicKey;// 支付宝公钥,验签使用。ps:注意分清应用公钥和支付宝公钥
public function __construct($appId, $privateKey, $publicKey){
$this->_appId = $appId;
$this->_privateKey = $privateKey;
$this->_publicKey = $publicKey;
}
// 创建支付请求接口,返回生成二维码的链接
public function createPay($order_code, $amount, $title){
$param = array(
"app_id" => $this->_appId,
"method" => 'alipay.trade.precreate',
"notify_url" => 'xxxxxx', // 异步回调地址
"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_code, // 商户订单号,唯一
"total_amount" => $amount, // 订单总金额,单位为元,精确到小数点后两位
"subject" => $title, // 订单标题
"timeout_express" => "60m" // 该笔订单允许的最晚付款时间
])
);
$sign = $this->RSA2($param);
if(!$sign){
reuturn false;
}
$param['sign'] = $sign;
$url = 'https://openapi.alipay.com/gateway.do';
$response = $this->curl($url, $param);
// response :{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"6141161365682511","qr_code":"https:\/\/qr.alipay.com\/bax03206ug0kulveltqc80a8"},"sign":"VrgnnGgRMNApB1QlNJimiOt5ocGn4a4pbXjdoqjHtnYMWPYGX9AS0ELt8YikVAl6LPfsD7hjSyGWGjwaAYJjzH1MH7B2/T3He0kLezuWHsikao2ktCjTrX0tmUfoMUBCxKGGuDHtmasQi4yAoDk+ux7og1J5tL49yWiiwgaJoBE="}
$response = json_decode($response, true);
if(is_array($response) && $response['alipay_trade_precreate_response']['msg'] == 'Success'){
$result = $this->checkSign($response['alipay_trade_precreate_response'], $response['sign']);
if(!$result){
return false; // 验证签名失败
}
// 返回二维码链接,生成二维码
return $response['alipay_trade_precreate_response'];
}
}
// RSA2加密,
public function RSA2($data){
//将请求的参数进行排序
ksort($data);//ksort()函数 根据参数的键进行升序排序
reset($data);
$signStr = '';
foreach ($data as $key => $value) {
if ($key == 'sign' || $value == '') continue;
$signStr .= $key . '=' .$value .'&';
}
$signStr = trim($signStr, '&');
$secretKey = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($this->_privateKey, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----";
// 请注意密钥 是不是有带 -----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
$secretKey = openssl_pkey_get_private($secretKey);
if ($secretKey) {
$res = openssl_get_privatekey($secretKey);
openssl_sign($signStr, $sign, $res, 'SHA256');
$sign = base64_encode($sign);
openssl_free_key($secretKey);
return $sign;
}
return null;
}
public function curl($url, $postFields = null) {
//创建curl资源
$curl = curl_init();
//设置URL和相应的选项
curl_setopt($curl, CURLOPT_URL, $url);
if(!empty($postFields)){
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
//执行curl
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
/**
* 验证签名
* @param $data 待验签字符串/数组
* @param $sign 支付宝返回的签名
* @return bool
*/
public function checkSign($data, $sign){
if(is_array($data)){
$data = json_encode($data);
}
$public_key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($this->_publicKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
$res=openssl_get_publickey($public_key);
return (bool)openssl_verify(
$data,
base64_decode($sign),
$res,
OPENSSL_ALGO_SHA256
);
}
}