<?php namespace api\sdk; use Yii; class WechatPay { protected $mchid ; protected $appid ; protected $key ; public function __construct( $mchid , $appid , $key ){ $this ->mchid = $mchid ; $this ->appid = $appid ; $this ->key = $key ; } public function createJsBizPackage( $openid , $totalFee , $outTradeNo , $orderName , $notifyUrl , $timestamp ){ $config = array ( 'mch_id' => $this ->mchid, 'appid' => $this ->appid, 'key' => $this ->key, ); $unified = array ( 'appid' => $config [ 'appid' ], 'attach' => '支付' , 'body' => $orderName , 'mch_id' => $config [ 'mch_id' ], 'nonce_str' => self::createNonceStr(), 'notify_url' => $notifyUrl , 'openid' => $openid , 'out_trade_no' => $outTradeNo , 'spbill_create_ip' => '127.0.0.1' , 'total_fee' => intval ( $totalFee * 100), 'trade_type' => 'JSAPI' , ); $unified [ 'sign' ] = self::getSign( $unified , $config [ 'key' ]); $responseXml = self::curlPost( 'https://api.mch.weixin.qq.com/pay/unifiedorder' , self::arrayToXml( $unified )); $unifiedOrder = simplexml_load_string( $responseXml , 'SimpleXMLElement' , LIBXML_NOCDATA); if ( $unifiedOrder === false) { die ( 'parse xml error' ); } if ( $unifiedOrder ->return_code != 'SUCCESS' ) { die ( $unifiedOrder ->return_msg); } if ( $unifiedOrder ->result_code != 'SUCCESS' ) { die ( $unifiedOrder ->err_code); } $arr = array ( "appId" => $config [ 'appid' ], "timeStamp" => $timestamp , "nonceStr" => self::createNonceStr(), "package" => "prepay_id=" . $unifiedOrder ->prepay_id, "signType" => 'MD5' , ); $arr [ 'paySign' ] = self::getSign( $arr , $config [ 'key' ]); return $arr ; } public static function curlGet( $url = '' , $options = array ()){ $ch = curl_init( $url ); curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $ch , CURLOPT_TIMEOUT, 30); 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 static 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 static function createNonceStr( $length = 16){ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' ; $str = '' ; for ( $i = 0; $i < $length ; $i ++){ $str .= substr ( $chars , mt_rand(0, strlen ( $chars ) - 1), 1); } return $str ; } public static function arrayToXml( $arr ){ $xml = "<xml>" ; foreach ( $arr as $key => $val ){ if ( is_numeric ( $val )) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">" ; } else { $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">" ; } } $xml .= "</xml>" ; return $xml ; } public static function getSign( $params , $key ){ ksort( $params , SORT_STRING); $unSignParaString = self::formatQueryParaMap( $params , false); $signStr = strtoupper (md5( $unSignParaString . "&key=" . $key )); return $signStr ; } protected static function formatQueryParaMap( $paraMap , $urlEncode = false){ $buff = "" ; ksort( $paraMap ); foreach ( $paraMap as $k => $v ){ if (null != $v && "null" != $v ) { if ( $urlEncode ) { $v = urlencode( $v ); } $buff .= $k . "=" . $v . "&" ; } } $reqPar = '' ; if ( strlen ( $buff )>0) { $reqPar = substr ( $buff , 0, strlen ( $buff ) - 1); } return $reqPar ; } } |