支付宝app支付单文件类-php版(证书签名)
<?php class AlipayApp { public $appId; public $notifyUrl; protected $charset; //私钥值 public $rsaPrivateKey; protected $totalFee; protected $outTradeNo; protected $orderName; public function __construct() { $this->charset = 'utf-8'; } public function setAppid($appid) { $this->appId = $appid; } public function setRsaPrivateKey($saPrivateKey) { $this->rsaPrivateKey = $saPrivateKey; } public function setNotifyUrl($notifyUrl) { $this->notifyUrl = $notifyUrl; } public function setTotalFee($payAmount) { $this->totalFee = $payAmount; } public function setOutTradeNo($outTradeNo) { $this->outTradeNo = $outTradeNo; } public function setOrderName($orderName) { $this->orderName = $orderName; } /** * 获取orderStr * @return array */ public function getOrderStr($appPrivateKeyPath,$alipayRootPath,$app_public_cert_path) { //请求参数 $requestConfigs = array( 'out_trade_no'=>$this->outTradeNo, 'total_amount'=>$this->totalFee, //单位 元 'subject'=>$this->orderName, //订单标题 'product_code'=>'QUICK_MSECURITY_PAY', //销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY 'timeout_express'=>'10m', //该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。 ); $commonConfigs = array( //公共参数 'app_id' => $this->appId, 'method' => 'alipay.trade.app.pay', //接口名称 'format' => 'JSON', 'charset'=>$this->charset, 'sign_type'=>'RSA2', 'timestamp'=>date('Y-m-d H:i:s'), 'version'=>'1.0', 'notify_url' => $this->notifyUrl, 'biz_content'=>json_encode($requestConfigs), 'alipay_root_cert_sn' => $this->getRootCertSN($alipayRootPath),//支付宝根证书SN(alipay_root_cert_sn) 'app_cert_sn' => $this->getCertSN($app_public_cert_path), //应用公钥证书SN(app_cert_sn) ); $commonConfigs["sign"] = $this->generateSignWithCert($commonConfigs, $commonConfigs['sign_type'],$appPrivateKeyPath); $result = $this->buildOrderStr($commonConfigs); return $result; } /** * 从证书中提取*** * @param $cert * @return string */ public function getCertSN($certPath) { $cert = file_get_contents($certPath); $ssl = openssl_x509_parse($cert); $SN = md5($this->array2string(array_reverse($ssl['issuer'])) . $ssl['serialNumber']); return $SN; } /** * 提取根证书*** * @param $cert 根证书 * @return string|null */ public function getRootCertSN($certPath) { $cert = file_get_contents($certPath); $array = explode("-----END CERTIFICATE-----", $cert); $SN = null; for ($i = 0; $i < count($array) - 1; $i++) { $ssl[$i] = openssl_x509_parse($array[$i] . "-----END CERTIFICATE-----"); if (strpos($ssl[$i]['serialNumber'], '0x') === 0) { $ssl[$i]['serialNumber'] = $this->hex2dec($ssl[$i]['serialNumber']); } if ($ssl[$i]['signatureTypeLN'] == "sha1WithRSAEncryption" || $ssl[$i]['signatureTypeLN'] == "sha256WithRSAEncryption") { if ($SN == null) { $SN = md5($this->array2string(array_reverse($ssl[$i]['issuer'])) . $ssl[$i]['serialNumber']); } else { $SN = $SN . "_" . md5($this->array2string(array_reverse($ssl[$i]['issuer'])) . $ssl[$i]['serialNumber']); } } } return $SN; } /** * 0x转高精度数字 * @param $hex * @return int|string */ protected function hex2dec($hex) { $dec = 0; $len = strlen($hex); for ($i = 1; $i <= $len; $i++) { $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i)))); } return $dec; } protected function array2string($array) { $string = []; if ($array && is_array($array)) { foreach ($array as $key => $value) { $string[] = $key . '=' . $value; } } return implode(',', $string); }/** * 使用证书生成签名 */ protected function generateSignWithCert($params, $signType = "RSA2",$appPrivateKeyPath) { $signContent = $this->getSignContent($params); $res = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($appPrivateKeyPath, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----"; ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); if ("RSA2" == $signType) { openssl_sign($signContent, $sign, $res, version_compare(PHP_VERSION, '5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持 } else { openssl_sign($signContent, $sign, $res); } $sign = base64_encode($sign); return $sign; } /** * 校验$value是否非空 * if not set ,return true; * if is null , return true; **/ protected function checkEmpty($value) { if (!isset($value)) return true; if ($value === null) return true; if (trim($value) === "") return true; return false; } public function getSignContent($params) { ksort($params); $stringToBeSigned = ""; $i = 0; foreach ($params as $k => $v) { if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { // 转换成目标字符集 $v = $this->characet($v, $this->charset); if ($i == 0) { $stringToBeSigned .= "$k" . "=" . "$v"; } else { $stringToBeSigned .= "&" . "$k" . "=" . "$v"; } $i++; } } unset ($k, $v); return $stringToBeSigned; } /** * 转换字符集编码 * @param $data * @param $targetCharset * @return string */ function characet($data, $targetCharset) { if (!empty($data)) { $fileType = $this->charset; if (strcasecmp($fileType, $targetCharset) != 0) { $data = mb_convert_encoding($data, $targetCharset, $fileType); //$data = iconv($fileType, $targetCharset.'//IGNORE', $data); } } return $data; } public function buildOrderStr($data) { return http_build_query($data); } }
滴水成冰,世间不存在毫无意义的付出,时间终会给你答案。

浙公网安备 33010602011771号