zoukankan      html  css  js  c++  java
  • 微信支付

    //微信支付接口
    public function wx_pay($pay_sn,$openid,$goods_amount){
    //$pay_sn 订单号
    //$goods_amount 总价格
     
     
     
    // $APPID = 'wx4cbf015baaaaaaa'; //appid
    // $APPSECRET = 'a4fa4a7d2711043bbbbbbbbb'; //appsecret
    // $MCH_ID = '155304111111';
    // $KEY = 'Ailangshangmaoyouxiangon11111234';
    //获取微信配置信息
    $wxconfig = db('wxconfig')->find();
    // echo '<pre/>';print_r($wxconfig);die;
    $APPID = $wxconfig['xcx_appid']; //小程序appid
    $APPSECRET = $wxconfig['xcx_appsecret']; //小程序appsecret
    $MCH_ID = $wxconfig['xcx_mch_id']; //商户号
    $KEY = $wxconfig['xcx_key']; //微信支付KEY
     
     
    // $APPID = config(''); //appid
    // $APPSECRET = config(''); //appsecret
    // $MCH_ID = config(''); //商户号
    $notify_url = 'https://'.$_SERVER['HTTP_HOST'].'/index.php/home/buy/notify'; //支付完成回调地址url,不能带参数
    $trade_type = 'JSAPI';//交易类型 默认JSAPI
    $out_trade_no = $pay_sn; //商户订单号
    // $nonce_str = mt_rand(10000, 99999).time();//随机字符串
    $nonce_str = $this->getNonceStr();//随机字符串
    $time_start = date("YmdHis"); //开始时间
    $time_expire = date("YmdHis", time() + 600); //结束时间
    $Total_fee = $goods_amount*100; //总金额
    $body = 'testbody';
    $spbill_create_ip = $_SERVER['SERVER_ADDR']; //终端IP
     
    //这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错
    $post['appid'] = $APPID;
    $post['body'] = $body;
    $post['mch_id'] = $MCH_ID;
    $post['nonce_str'] = $nonce_str;//随机字符串
    $post['notify_url'] = $notify_url;
    $post['openid'] = $openid;
    $post['out_trade_no'] = $out_trade_no;
    $post['spbill_create_ip'] = $spbill_create_ip;//服务器终端的ip
    $post['total_fee'] = intval($Total_fee); //总金额 最低为一分钱 必须是整数
    $post['trade_type'] = 'JSAPI';
     
    $sign = $this->MakeSign($post, $KEY); //签名
    //echo '<pre/>';print_r($post);
    $post_xml = '<xml>
    <appid>'.$APPID.'</appid>
    <body>'.$body.'</body>
    <mch_id>'.$MCH_ID.'</mch_id>
    <nonce_str>'.$nonce_str.'</nonce_str>
    <notify_url>'.$notify_url.'</notify_url>
    <openid>'.$openid.'</openid>
    <out_trade_no>'.$out_trade_no.'</out_trade_no>
    <sign>'.$sign.'</sign>
    <spbill_create_ip>'.$spbill_create_ip.'</spbill_create_ip>
    <total_fee>'.$Total_fee.'</total_fee>
    <trade_type>'.$trade_type.'</trade_type>
    </xml>';
     
    // echo '<pre/>';print_r($post_xml);
     
     
    $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    $xml = $this->send_prePaycurl($url,$post_xml);
     
    //将【统一下单】api返回xml数据转换成数组,全要大写
    // $array = $this->xml2array($xml);
    $array = $this->_xmldataparse($xml);
    // echo '<pre/>';print_r($array);die;
    if($array['return_code'] == 'SUCCESS' || $array['result_code'] == 'SUCCESS'){
    $time = time();
    //二次签名数组
    $tmp = array();
    $tmp['appId'] = $APPID;
    $tmp['timeStamp'] = strval($time);
    $tmp['nonceStr'] = $nonce_str;
    $tmp['signType'] = 'MD5';
    $tmp['package'] = 'prepay_id='.$array['prepay_id'];
     
     
    //返回数据数组
    $data['code'] = 1;
    $data['timeStamp'] = strval($time);
    $data['nonceStr'] = $nonce_str;
    $data['signType'] = 'MD5';
    $data['package'] = 'prepay_id='.$array['prepay_id'];
    $data['paySign'] = $this->MakeSign($tmp,$KEY);
    $data['pay_sn'] = $out_trade_no;
     
     
     
    }else{
    $data['code'] = 0;
    $data['msg'] = '错误';
    $data['return_code'] = $array['return_code'];
    $data['return_msg'] = $array['return_msg'];
    $data['err_code_des'] = $array['err_code_des'];
    }
     
    // echo 123456789;
    // echo '<pre/>';print_r($array);die;
    return $data;
     
    }
     
     
    /** * 将参数拼接为url: key=value&key=value * @param $params * @return string */
    private function ToUrlParams($params){
    $string = '';
    if(!empty($params)){
    // $array = array();
    // foreach($params as $key =>$value){
    // $array[] = $key.'='.$value;
    // }
     
    // $string = implode('&',$array);
     
    $array = '';
    foreach ($params as $key => $value) {
    $array .= !$array ? $key . '=' . $value : '&' . $key . '=' . $value;
    }
    $string = $array;
     
    }
    // echo '<pre/>';print_r($array);die;
    return $string;
    }
     
    //生成随机字符串
    public static function getNonceStr($length = 32)
    {
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ ) {
    $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return strtoupper($str);
    }
     
    /** * 调用接口, $data是数组参数 * @return 签名 */
    private function send_prePaycurl($url,$xmlData) {
    // $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    $header[] = "Content-type: text/xml";
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlData);
    $data = curl_exec($curl);
    if (curl_errno($curl)) {
    print curl_error($curl);
    }
    curl_close($curl);
    return $data;
    }
     
    //xml数据解析函数
    private function _xmldataparse($data){
    $msg = array();
    $msg = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
    return $msg;
    }
     
    //支付完成回调地址url
    public function notify_url(){
    $post = file_get_contents("php://input");
    // echo '<pre/>';print_r($post);die;
     
    //创建存入access_token的文件
    $accessfile = __DIR__.'/aaa.txt';
    $file = fopen($accessfile,'a');
    $file = json_decode(file_get_contents($accessfile),true);
    $fd = fopen($accessfile,'w');
     
    $data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);//XML转数组
    $data = json_encode($data);
    $data = json_decode($data,true);
     
    // if ($result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
     
     
    if($data['return_code']=='SUCCESS' && $data['result_code'] == 'SUCCESS'){
     
    //订单号
    $out_trade_no = $data['out_trade_no'];
     
    //修改成已支付
    $upd['order_state'] = 20;
    $upd['transaction_id'] = $data['transaction_id'];
    $upd['pay_time'] = time();
    $update = db('order')->where('pay_sn='.$out_trade_no)->update($upd);
     
    //更新积分
    $total_fee = $data['total_fee']/100;
     
    fwrite($fd,$post);
    fclose($fd);
    if($total_fee >=1 ){
    db('member')->where('openid like "%'.$data['openid'].'%" ')->setInc('member_points',$total_fee);
    }
    echo 'SUCCESS';
    }else{
    echo 'FAIL';
    }
    }
     
     
    微信退款
    //测试退款
    public function aaa(){
    $out_trade_no = '19120210485069094001';
    $order_amount= '0.01';
    $this->refund($out_trade_no,$order_amount);
    }
    //退款
    public function refund($out_trade_no,$order_amount){
     
    //获取微信配置信息
    $wxconfig = db('wxconfig')->find();
     
    $APPID = $wxconfig['xcx_appid']; //小程序appid
    // $APPSECRET = $wxconfig['xcx_appsecret']; //小程序appsecret
    $MCH_ID = $wxconfig['xcx_mch_id']; //商户号
    $KEY = $wxconfig['xcx_key']; //微信支付KEY
    $nonce_str = $this->getNonceStr();//随机字符串
    $out_trade_no = $out_trade_no; //商户订单号
    $out_refund_no = rand(100000,999999).time(); //退单号
     
    $a = db('order')->where('pay_sn='.$out_trade_no)->find();
    $total_fee = $a['order_amount']*100; //订单金额
    $refund_fee = $order_amount*100; //退单金额
    $transaction_id = $a['transaction_id'];
     
    if($refund_fee<1){
    return json_encode(['code'=>400,'msg'=>'退款金额不得小于1分']);
    }
     
    if($refund_fee>$total_fee){
    return json_encode(['code'=>400,'msg'=>'退款金额不得大于订单总金额']);
    }
    //这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错
    $post['appid'] = $APPID;
    $post['mch_id'] = $MCH_ID;
    $post['nonce_str'] = $nonce_str;//随机字符串
    $post['out_refund_no'] = $out_refund_no;
    //$post['out_trade_no'] = $out_trade_no;
    $post['refund_fee'] = intval($refund_fee); //退款总金额 最低为一分钱 必须是整数
    $post['total_fee'] = intval($total_fee); //总金额 最低为一分钱 必须是整数
    $post['transaction_id'] = $transaction_id; //微信单号
    $sign = $this->MakeSign($post, $KEY); //签名
    $post['sign'] = $sign;
    //echo '<pre/>';print_r($post_xml);die;
    $post_xml = '<xml>
    <appid>'.$APPID.'</appid>
    <mch_id>'.$MCH_ID.'</mch_id>
    <nonce_str>'.$nonce_str.'</nonce_str>
    <out_refund_no>'.$out_refund_no.'</out_refund_no>
    <refund_fee>'.$refund_fee.'</refund_fee>
    <total_fee>'.$total_fee.'</total_fee>
    <transaction_id>'.$transaction_id.'</transaction_id>
    <sign>'.$sign.'</sign>
    </xml>';
    // <out_trade_no>'.$out_trade_no.'</out_trade_no>
    // echo $KEY;
     
    $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';
     
    $xml = $this->postXmlCurl($url,$post_xml);
    //将退款api返回xml数据转换成数组,全要大写
     
    $array = $this->_xmldataparse($xml);
    echo '<pre/>';print_r($array);die;
    if(($array['return_code']=='SUCCESS') && ($array['result_code']=='SUCCESS')){
    $arrays['refund_state'] = 2;
    db('order')->where('pay_sn='.$out_trade_no)->update($arrays);
    return json_encode(['code'=>200,'msg'=>'退款成功']);
    }else{
    return json_encode(['code'=>400,'msg'=>'退款失败']);
    }
     
    }
     
     
    public function postXmlCurl($url,$xml)
    {
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    // curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
    // return CURLOPT_RETURNTRANSFER;
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//严格校验
    // $header[] = "Content-type: text/xml";
    //设置header
    curl_setopt($ch, CURLOPT_HEADER, false);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    //使用证书:cert 与 key 分别属于两个.pem文件
    //第一种
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch, CURLOPT_SSLCERT, '/www/wwwroot/hzp/extend/Wxpay/cert/apiclient_cert.pem');
    // curl_setopt($ch, CURLOPT_SSLCERT, 'https://hzp.bjcaicheng.cn/extend/Wxpay/cert/apiclient_cert.pem');
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    // curl_setopt($ch, CURLOPT_SSLKEY, 'https://hzp.bjcaicheng.cn/extend/Wxpay/cert/apiclient_key.pem');
    curl_setopt($ch, CURLOPT_SSLKEY, '/www/wwwroot/hzp/extend/Wxpay/cert/apiclient_key.pem');
    //第二种
    // curl_setopt($ch, CURLOPT_CAINFO, dirname(dirname(__FILE__))."/cert".DIRECTORY_SEPARATOR.'rootca.pem');
    //post提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    //运行curl
    $data = curl_exec($ch);
    // var_dump($data);die;
    // echo '<pre/>';print_r($data);die;
    //返回结果
    if($data){
    // return 333;
    curl_close($ch);
    return $data;
    } else {
    // return 222;
    $error = curl_errno($ch);
    // return $error;
    curl_close($ch);
    // return false;
    return json_encode("curl出错,错误码:$error");
    }
    }
     
     
     
     
     

  • 相关阅读:
    Python LED
    vmvare虚拟机经验
    Debian系统简要说明
    Android onclick监听事件打开新界面
    在国外搭个人服务器(顺便访问外网)
    生成指定时间内的 随机日起
    生成指定时间内的日期
    Mac 上查找javahome
    java 学习的网站
    Java 线程
  • 原文地址:https://www.cnblogs.com/DevilBoy/p/14087681.html
Copyright © 2011-2022 走看看