支付宝PC端支付model、调用及前台页面
#### 调用: class AlipaypcApp extends PaybaseApp { private $wabapp; public function __construct() { parent::__construct(); $this->wabapp = new WebAPP(); } /** * 创建支付 * @return [type] [description] */ public function index() { header('Content-type:text/html; Charset=utf-8'); // 获取订单信息 $model_order =& m('order'); $order_info = $model_order->get('order_id='.$this->oid); if (empty($order_info)) { return $this->wabapp->error('无此订单'); } //订单已支付 if ($order_info['status'] > ORDER_PENDING) { return $this->wabapp->error('该订单已支付', '查看订单', $this->ORDER_INFO_URL); } // 获取支付方式的相关配置信息 $model_payment =& m('payment'); $payment_info = $model_payment->get('payment_code="pay3in1"'); $payment_config = unserialize($payment_info['config']); if(empty($payment_config)){ return $this->wabapp->error('未获取到相关配置信息'); } //实例化支付操作模型 $pay_class =& m('pay_do'); /*** 请填写以下配置信息 ***/ $appid = $payment_config['alipay_appid']; //https://open.alipay.com 账户中心->密钥管理->开放平台密钥,填写添加了电脑网站支付的应用的APPID $returnUrl = $pay_class->_create_paynotify_url($this->oid, 'alipaypc'); //付款成功后的同步回调地址 不能有 ? & 符号 $notifyUrl = $pay_class->_create_notify_url('alipaypc'); //付款成功后的异步回调地址 不能有 ? & 符号 $outTradeNo = $order_info['order_sn']; //你自己的商品订单号,不能重复 $payAmount = $order_info['order_amount']; //付款金额,单位:元 $orderName = $order_info['order_sn']; //订单标题 $signType = 'RSA2'; //签名算法类型,支持RSA2和RSA,推荐使用RSA2 $rsaPrivateKey = $payment_config['alipay_rsaPrivateKey']; //商户私钥,填写对应签名算法类型的私钥,如何生成密钥参考:https://docs.open.alipay.com/291/105971和https://docs.open.alipay.com/200/105310 /*** 配置结束 ***/ $aliPay =& m('alipaypc'); $aliPay->setAppid($appid); $aliPay->setReturnUrl($returnUrl); $aliPay->setNotifyUrl($notifyUrl); $aliPay->setRsaPrivateKey($rsaPrivateKey); $aliPay->setTotalFee($payAmount); $aliPay->setOutTradeNo($outTradeNo); $aliPay->setOrderName($orderName); //$sHtml = $aliPay->doPay(); //echo $sHtml; $commonConfigs = $aliPay->doPay(); //var_dump($commonConfigs);exit; //$sHtml = $this->buildRequestFormHtml($commonConfigs); //echo $sHtml; foreach ($commonConfigs as $key => $value) { if (false === $aliPay->checkEmpty($value)) { $configs[$key] = str_replace("'", "'", $value); }else{ $configs[$key] = $value; } } $this->assign('commonConfigs',$configs); $this->display('loading.html'); } } #### model: class AlipaypcModel extends BaseModel { protected $appId; protected $returnUrl; protected $notifyUrl; public $charset; //私钥值 protected $rsaPrivateKey; protected $totalFee; protected $outTradeNo; protected $orderName; protected $alipayPublicKey; public function __construct() { $this->charset = 'utf8'; } public function setAppid($appid) { $this->appId = $appid; } public function setReturnUrl($returnUrl) { $this->returnUrl = $returnUrl; } public function setNotifyUrl($notifyUrl) { $this->notifyUrl = $notifyUrl; } public function setRsaPrivateKey($saPrivateKey) { $this->rsaPrivateKey = $saPrivateKey; } public function setTotalFee($payAmount) { $this->totalFee = $payAmount; } public function setOutTradeNo($outTradeNo) { $this->outTradeNo = $outTradeNo; } public function setOrderName($orderName) { $this->orderName = $orderName; } public function setAlipayPublicKey($alipayPublicKey) { $this->alipayPublicKey = $alipayPublicKey; } /** * 发起订单 * @return array */ public function doPay() { //请求参数 $requestConfigs = array( 'out_trade_no'=>$this->outTradeNo, 'product_code'=>'FAST_INSTANT_TRADE_PAY', 'total_amount'=>$this->totalFee, //单位 元 'subject'=>$this->orderName, //订单标题 ); $commonConfigs = array( //公共参数 'app_id' => $this->appId, 'method' => 'alipay.trade.page.pay', //接口名称 'format' => 'JSON', 'return_url' => $this->returnUrl, '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), ); $commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']); //return $this->buildRequestForm($commonConfigs); return $commonConfigs; } /** * 获取订单状态 * @param string $order_sn 订单号 * @return [type] [description] */ public function getOrderStatus() { //请求参数 $requestConfigs = array( 'out_trade_no'=>$this->outTradeNo // 订单支付时传入的商户订单号 ); $commonConfigs = array( //公共参数 'app_id' => $this->appId, 'method' => 'alipay.trade.query', //接口名称 'format' => 'JSON', 'charset'=>$this->charset, 'sign_type'=>'RSA2', 'timestamp'=>date('Y-m-d H:i:s'), 'version'=>'1.0', 'biz_content'=>json_encode($requestConfigs), ); $commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']); $result = $this->curlPost('https://openapi.alipay.com/gateway.do', $commonConfigs); $result = iconv('gbk', 'utf-8//IGNORE', $result); return json_decode($result, true); } /** * 建立请求,以表单HTML形式构造(默认) * @param $para_temp 请求参数数组 * @return 提交表单HTML文本 */ protected function buildRequestForm($para_temp) { $sHtml = "正在跳转至支付页面... <form id='alipaysubmit' name='alipaysubmit' action='https://openapi.alipay.com/gateway.do?charset=".$this->charset."' method='POST'>"; while (list($key, $val) = each($para_temp)) { if (false === $this->checkEmpty($val)) { $val = str_replace("'", "'", $val); $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>"; } } //submit按钮控件请不要含有name属性 $sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>"; $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>"; return $sHtml; } public function generateSign($params, $signType = "RSA") { return $this->sign($this->getSignContent($params), $signType); } protected function sign($data, $signType = "RSA") { $priKey=$this->rsaPrivateKey; $res = "-----BEGIN RSA PRIVATE KEY-----\n" . wordwrap($priKey, 64, "\n", true) . "\n-----END RSA PRIVATE KEY-----"; ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); if ("RSA2" == $signType) { openssl_sign($data, $sign, $res, version_compare(PHP_VERSION, '5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持 } else { openssl_sign($data, $sign, $res); } $sign = base64_encode($sign); return $sign; } /** * 校验$value是否非空 * if not set ,return true; * if is null , return true; **/ public 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 */ public 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 curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } /** * 验证签名 **/ public function rsaCheck($params) { $sign = $params['sign']; $signType = $params['sign_type']; unset($params['sign_type']); unset($params['sign']); return $this->verify($this->getSignContent($params), $sign, $signType); } public function verify($data, $sign, $signType = 'RSA') { $pubKey= $this->alipayPublicKey; $res = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($pubKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); //调用openssl内置方法验签,返回bool值 if ("RSA2" == $signType) { $result = (bool)openssl_verify($data, base64_decode($sign), $res, version_compare(PHP_VERSION, '5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); } else { $result = (bool)openssl_verify($data, base64_decode($sign), $res); } // if(!$this->checkEmpty($this->alipayPublicKey)) { // //释放资源 // openssl_free_key($res); // } return $result; } } #### 前台页面 <form id='alipaysubmit' name='alipaysubmit' action='https://openapi.alipay.com/gateway.do?charset={$commonConfigs.charset}' method='POST'>" <input type="hidden" name="app_id" value="{$commonConfigs.app_id}"> <input type="hidden" name="method" value="{$commonConfigs.method}"> <input type="hidden" name="format" value="{$commonConfigs.format}"> <input type="hidden" name="return_url" value="{$commonConfigs.return_url}"> <input type="hidden" name="charset" value="{$commonConfigs.charset}"> <input type="hidden" name="sign_type" value="{$commonConfigs.sign_type}"> <input type="hidden" name="timestamp" value="{$commonConfigs.timestamp}"> <input type="hidden" name="version" value="{$commonConfigs.version}"> <input type="hidden" name="notify_url" value="{$commonConfigs.notify_url}"> <input type="hidden" name="biz_content" value='{$commonConfigs.biz_content}'> <input type="hidden" name="sign" value="{$commonConfigs.sign}"> <input type='submit' value='ok' style='display:none;'/> </form> <script> $(function(){ setTimeout(function(){ document.forms['alipaysubmit'].submit(); },1500); }); </script>