- PHP后台调用微信支付下单<br>function wx_getPayRequest($openid, $orderid, $rmb, $title,$appoids)<br>{<br> $nonce = $orderid.mt_rand(10000,99999);<br> $orderid=$orderid.'_'.$nonce;//str_replace(",","_",$appoids);<br> //Log::write('\n ================'.$orderid,'notice');<br> $srct='0x'.md5(config('app.environment')['paykey'].$orderid);<br> $notify = '';//回调地址,自己写,支付成功回调,在回调页面进行更改与用户金钱相关的代码<br> $url= 'https://api.mch.weixin.qq.com/pay/unifiedorder';//统一接口prepay_id<br> // post data<br> $now = time().'';//时间<br> $appid ='';//小程序ID 写到一个类里面了 方便后期修改 当然也可以在这里直接写<br> $mchid ='';//商户号<br> // Log::write('\n $mchid================'.json_encode($mchid),'notice');<br> // Log::write('\n $appid================'.json_encode($appid),'notice');<br> $data = array(<br> 'appid' => $appid,<br> 'mch_id' => $mchid,<br> 'spbill_create_ip' => '127.0.0.1',//终端ip Y<br> 'nonce_str' => $nonce, //随机字符串Y<br> 'openid' => $openid, //用户标识 N<br> 'body' => $title, //商品描述 Y<br> // 'detail' => $body, //商品详情 N<br> 'attach' => $appoids, //附加数据 N<br> 'out_trade_no' => $orderid, //商户订单号 Y<br> 'total_fee' => $rmb, //总金额 单位分 int Y<br> 'notify_url' => $notify, //通知地址 Y<br> 'trade_type' => 'JSAPI',<br> );<br><br> $data[ 'sign' ] = self::MakeSign($data);<br> //echo $data[ 'sign' ];<br> // Log::write('\n sign================'.json_encode($data[ 'sign' ]),'notice');<br><br> $xml=self::wx_toXML($data);<br> $ret = $this->http_request($url,$xml);<br> $json = self::wx_parseXML( $ret );<br> //Log::write('\n ================'.json_encode($json),'notice');<br> if( !$json || !isset($json[ 'prepay_id' ]) )<br> {<br> return array( 'payCode'=>1,'ret' => 'fail', 'tip' => $json[ 'return_msg' ] );<br> }<br><br> $prepayid = $json[ 'prepay_id' ];<br> $req = array(<br> 'appId' => $appid,<br> 'timeStamp' => $now,<br> 'nonceStr' => $nonce,<br> 'package' => 'prepay_id='.$prepayid,<br> 'signType' => 'MD5',<br> );<br> $req[ 'paySign' ] = self::wx_getPkgSign($req);<br> //$req[ 'notify' ] = $notify;<br> return $req;<br>}<br><br>///作用:格式化参数,签名过程需要使用<br>private function formatBizQueryParaMap($paraMap, $urlencode) {<br> $buff = "";<br> ksort($paraMap);<br> foreach ($paraMap as $k => $v) {<br> if ($urlencode) {<br> $v = urlencode($v);<br> }<br> $buff .= $k . "=" . $v . "&";<br> }<br> $reqPar;<br> if (strlen($buff) > 0) {<br> $reqPar = substr($buff, 0, strlen($buff) - 1);<br> }<br> return $reqPar;<br>}<br><br><br>public function wx_getPkgSign($req )<br>{<br> foreach ($req as $k => $v) {<br> $Parameters[$k] = $v;<br> }<br> //签名步骤一:按字典序排序参数<br> ksort($Parameters);<br> $String = $this->formatBizQueryParaMap($Parameters, false);<br> //签名步骤二:在string后加入KEY<br> $String = $String . "&key=" . config('app.environment')['paykey'];<br> //签名步骤三:MD5加密<br> $String = md5($String);<br> //签名步骤四:所有字符转为大写<br> $result_ = strtoupper($String);<br> return $result_;<br>}<br><br>public function wx_toXML( $data )<br>{<br> $xml = '<xml>';<br> foreach( $data as $key => $val )<br> {<br> $xml .= '<' . $key . '><![CDATA[' . $val . ']]></' . $key . '>';<br> }<br> $xml .= '</xml>';<br> return $xml;<br>}<br><br>/**<br> * 输出xml字符<br> * @param $data<br> * @return string<br> */<br>public function ToXml($data)<br>{<br> if(!is_array($data)<br> || count($data) <= 0)<br> {<br> throw new WxPayException("数组数据异常!");<br> }<br><br> $xml = "<xml>";<br> foreach ($data as $key=>$val)<br> {<br> if (is_numeric($val)){<br> $xml.="<".$key.">".$val."</".$key.">";<br> }else{<br> $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";<br> }<br> }<br> $xml.="</xml>";<br> return $xml;<br>}<br><br>/**<br> * 格式化参数格式化成url参数<br> */<br>public function ToUrlParams($data)<br>{<br> $buff = "";<br> foreach ($data as $k => $v)<br> {<br> if($k != "sign" && $v != "" && !is_array($v)){<br> $buff .= $k . "=" . $v . "&";<br> }<br> }<br><br> $buff = trim($buff, "&");<br> return $buff;<br>}<br><br>/**<br> * 生成签名<br> * @param $data<br> * @return string 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值<br> */<br>public function MakeSign($data)<br>{<br> //签名步骤一:按字典序排序参数<br> ksort($data);<br> $string = $this->ToUrlParams($data);<br> //签名步骤二:在string后加入KEY<br> $string = $string . "&key=".config('app.environment')['paykey'];<br> //签名步骤三:MD5加密<br> $string = md5($string);<br> //签名步骤四:所有字符转为大写<br> $result = strtoupper($string);<br> return $result;<br>}<br><br>public function wx_parseXML( $str )<br>{<br> $rsp = array();<br> $xml = @simplexml_load_string( $str );<br> if( $xml && $xml->children() )<br> {<br> foreach( $xml->children() as $node )<br> {<br> if( $node->children() )<br> {<br> $k = $node->getName();<br> $nodeXml = $node->asXML();<br> $v = substr( $nodeXml, strlen($k)+2, strlen($nodeXml)-2*strlen($k)-5 );<br> }<br> else<br> {<br> $k = $node->getName();<br> $v = (string)$node;<br> }<br> $rsp[ $k ] = $v;<br> }<br> }<br> return $rsp;<br>}<br><br>public function payRefund($wxtranid,$order_childid, $ordertotalrmb,$refundrmb){<br> $appid = config('environment')[config('current_environment')]['appid'];//小程序ID 写到一个类里面了 方便后期修改 当然也可以在这里直接写<br> $mchid = config('environment')[config('current_environment')]['mchid'];//商户号<br> $nonce = $order_childid.mt_rand(10000,99999);<br><br> Log::write('取消预约单申请退款中===$ordertotalrmb='.$ordertotalrmb.'=======$refundrmb='.$refundrmb,'notice');<br><br> //统一下单退款参数构造<br> $unifiedorder = array(<br> 'appid' => $appid,<br> 'mch_id' => $mchid,<br> 'nonce_str' => $nonce,<br> 'transaction_id' => $wxtranid,<br> 'out_refund_no' => $order_childid,<br> 'total_fee' => intval($ordertotalrmb),<br> 'refund_fee' => intval($refundrmb),<br> 'notify_url'=>'https://wxcon.drmpsy.com.cn/api/appo/payBackSuccess'<br> );<br> $unifiedorder['sign'] = self::wx_getPkgSign($unifiedorder);<br> Log::write('$content111111================'.json_encode($unifiedorder),'notice');<br> //请求数据<br> $xmldata = self::wx_toXml($unifiedorder);<br> $opUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";<br> //$res = $this->http_request($opUrl, $xmldata);<br> $res = $this->postXmlSSLCurl($xmldata,$opUrl);<br> Log::write($res,'notice');<br> if (!$res) {<br> return "Can't connect the server";<br> }<br> $content = self::xmlToArray($res);<br> Log::write('$content================'.json_encode($content),'notice');<br> try{<br> if (strval($content['result_code']) == 'FAIL') {<br> return strval($content['err_code_des']);<br> }<br> }<br> catch (Exception $err){<br><br> }<br> try{<br> if ($content['return_code']&&strval($content['return_code']) == 'FAIL') {<br> return strval($content['return_msg']);<br> }<br> }<br> catch (Exception $err){<br><br> }<br> return $content;<br>}<br><br>public function xmlToArray($xml){<br> $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);<br> return $array_data;<br>}<br><br>//需要使用证书的请求<br>private function postXmlSSLCurl($xml,$url,$second=30)<br>{<br> $ch = curl_init();<br> //超时时间<br> curl_setopt($ch,CURLOPT_TIMEOUT,$second);<br> //这里设置代理,如果有的话<br> //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');<br> //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);<br> curl_setopt($ch,CURLOPT_URL, $url);<br> curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);<br> curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);<br> //设置header<br> curl_setopt($ch,CURLOPT_HEADER,FALSE);<br> //要求结果为字符串且输出到屏幕上<br> curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);<br> //设置证书<br> //使用证书:cert 与 key 分别属于两个.pem文件<br> //默认格式为PEM,可以注释<br> curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');<br> curl_setopt($ch,CURLOPT_SSLCERT, '/nfs/website/wx.drmpsy.com.cn/api/cert/apiclient_cert.pem');<br> //默认格式为PEM,可以注释<br> curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');<br> curl_setopt($ch,CURLOPT_SSLKEY,'/nfs/website/wx.drmpsy.com.cn/api/cert/apiclient_key.pem');<br> //post提交方式<br> curl_setopt($ch,CURLOPT_POST, true);<br> curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);<br> $data = curl_exec($ch);<br> //返回结果<br> if($data){<br> curl_close($ch);<br> return $data;<br> }<br> else {<br> $error = curl_errno($ch);<br> echo "curl出错,错误码:$error"."<br>";<br> curl_close($ch);<br> return false;<br> }<br>}<br>//curl请求<br>public function http_request($url,$data = null,$headers=array())<br>{<br> $curl = curl_init();<br> if( count($headers) >= 1 ){<br> curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);<br> }<br> curl_setopt($curl, CURLOPT_URL, $url);<br> curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);<br> curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);<br> if (!empty($data)){<br> curl_setopt($curl, CURLOPT_POST, 1);<br> curl_setopt($curl, CURLOPT_POSTFIELDS, $data);<br> }<br> curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);<br> $output = curl_exec($curl);<br> curl_close($curl);<br> return $output;<br>}
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |