Wechat applet - complete the payment function of the applet

Keywords: xml PHP curl

Recently, we have developed small programs, and we have been looking at the payment of small programs. After a day's hard work, the applet payment function is finally realized.

Thanks to csdn blogger: the "little program and php to realize wechat payment" released by Qiandui xuegedust


Original address:

http://blog.csdn.net/admin1008611/article/details/73240458

Here is the code I wrote: thinkphp used: others can be modified by reference:


Server:

Get the user's openid:

public function get_openid(){ 
    $data = array();        
    $url = "https://api.weixin.qq.com/sns/jscode2session";
    $data['appid'] = I('get.appid','','trim'); // App_id $data ['secret '] = I ('Get. Secret', ',','trim '); / / app_secret $data ['js_code'] = I ('Get. Js_code ',', ','trim');
    $data['grant_type'] = "authorization_code";
    $res = $this->http_request($url,$data);
    echo $res;
}


Payment interface:

public function wxPay(){
    $openID = I('get.openid','','trim');
    $totalFee = I('get.total_fee','','trim');
    $title = I('get.title','','trim');
    // Specific configuration $appid = "fill in app ID of the applet"; / / APP ID $openid = $openid; / / user's openid $mch_id = "fill in merchant ID"; / / merchant ID $key = "fill in secret key of merchant ID"; 
    $out_trade_no = $this->order_number();//Merchant order number $body = $title; 
    $total_fee = $totalFee;//The total amount is divided into $weixinpay = new \ components \ weixinpay ($appid, $openid, $MCH ﹣ ID, $key, $out ﹣ trade ﹣ no, $body, $total ﹣ fee);
    $result = $weixinpay->pay();
    echo json_encode($result); 
}


Generate random string and order number:

//Random 32-bit string private function nonce_{
    $result = '';
    $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
    for ($i=0;$i<32;$i++){
        $result .= $str[rand(0,48)];
    }
    return $result;
}
//Generate order number private function order [number ($openid){
    //date('Ymd',time()).time().rand(10,99);//18 Bit return md5($openid.time().rand(10,99));//32 bit
}


Payment callback interface:

// Payment callback address public function notify(){
    $postXml = $GLOBALS["HTTP_RAW_POST_DATA"]; //Receive wechat parameter if (empty($postXml)){  
        return false;  
    }  
      
    //Convert xml format to array function xmlToArray($xml){  
      
        //Prohibit reference to external xml entities   
        libxml_disable_entity_loader(true);  
      
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);  
      
        $val = json_decode(json_encode($xmlstring), true);  
      
        return $val;  
    }  
      
    $attr = xmlToArray($postXml);  
      
    $total_fee = $attr[total_fee];  
    $open_id = $attr[openid];  
    $out_trade_no = $attr[out_trade_no];  
    $time = $attr[time_end]; 
}


Applet JS:

//index.js
//Get application instance
const app = getApp()
const APP_ID = "Applet appid";//Enter the app ID of the applet
const APP_SECRET = "Applet app_secret";//Enter the applet app_secret var open_id = ""; / / save and get the openid var session_key = ""; / / save and get the session_key page ({
  data:{
    'message':"Initiate payment"
  },
  wxPay:function(){
    var that = this;
    wx.login({
      success:function(res){
        wx.request({
          url:"https://xiaochengxu.e0yu.com/index.php?s=Index/get_openid",
          data:{
            appid: APP_ID,
            secret:APP_SECRET,
            js_code:res.code,
            grant_type: 'authorization_code' 
          },
          method:'GET',
          success:function(res){
            //console.log(res);
            OPEN_ID = res.data.openid;//Obtained openid Wx. Request ({
              url: "https://xiaochengxu.e0yu.com/index.php?s=Index/wxPay",
              data:{
                openid:OPEN_ID,
                total_fee:1,//Recharging amount unit "minute"
                title:'Product title'
              },
              method:'GET',
              success:function(result){
                //console.log(result);
                console.log('Transfer payment');
                wx.requestPayment({
                  'timeStamp': result.data.timeStamp,
                  'nonceStr': result.data.nonceStr,
                  'package': result.data.package,
                  'signType': 'MD5',
                  'paySign': result.data.paySign,
                  'success': function (res) {
                    console.log('success');
                  },
                  'fail': function (res) {
                    console.log('fail');
                  },
                  'complete': function (res) {
                    console.log('complete');
                  }
                });
              }
            })
          },
        })
      }
    });
  }
})


Effect:


Here's how: WeixinPay:

<?php
namespace Components;
/* App wechat payment */ class WeixinPay {
    protected $appid;
    protected $mch_id;
    protected $key;
    protected $openid;
    protected $out_trade_no;
    protected $body;
    protected $total_fee;
            function __construct($appid, $openid, $mch_id, $key,$out_trade_no,$body,$total_fee) {
        $this->appid = $appid;
        $this->openid = $openid;
        $this->mch_id = $mch_id;
        $this->key = $key;
        $this->out_trade_no = $out_trade_no;
        $this->body = $body;
        $this->total_fee = $total_fee;
    }


    public function pay() {
        //Unified order interface $return = $this - > weixinapp();
        return $return;
    }


    //Private function unifiedor (){
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $parameters = array(
            'appid' => $this->appid, //Applet ID
            'mch_id' => $this->mch_id, //Merchant number
            'nonce_str' => $this->createNoncestr(), //Random string
//            'body' = > test ', / / product description
            'body' => $this->body,
//            'out trade no' = > 2015450806125348 '/ / merchant Order No
            'out_trade_no'=> $this->out_trade_no,
//            'total' fee '= > floatval (0.01 * 100), / / total amount unit: minute
            'total_fee' => $this->total_fee,
//            'spbill_create_ip' = > $_server ['remote_addr '], / / terminal IP
            'spbill_create_ip' => '192.168.0.161', //Terminal IP
            'notify_url' => 'http://www.weixin.qq.com/wxpay/pay.php ', / / notice address to ensure normal access to the Internet
            'openid' => $this->openid, //User id
            'trade_type' => 'JSAPI'//Transaction type);
        //Unified order signing $parameters ['sign '] = $this - > getsign ($parameters);
        $xmlData = $this->arrayToXml($parameters);
        $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));
        return $return;
    }


    private static function postXmlCurl($xml, $url, $second = 30) 
    {
        $ch = curl_init();
        //Set timeout
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //Strict calibration
        //Set header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //The result is expected to be a string and output to the screen
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //post submission method
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);


        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($ch, CURLOPT_TIMEOUT, 40);
        set_time_limit(0);


        //Run curl $data = curl Ou exec ($CH);
        //Return the result if ($data){
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            throw new WxPayException("curl Error, error code:$error");
        }
    }
    
    
    
    //Array to xml private function arrayToXml($arr){
        $xml = "<root>";
        foreach ($arr as $key => $val) {
            if (is_array($val)) {
                $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
            } else {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            }
        }
        $xml .= "</root>";
        return $xml;
    }


    //xml to array private function xmlToArray($xml){


        //Prohibit reference to external xml entities  

        libxml_disable_entity_loader(true);


        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);


        $val = json_decode(json_encode($xmlstring), true);


        return $val;
    }


    //private function weixinapp(){
        //Unified order = $this - > unified order();
//        print_r($unifiedorder); $parameters = array(
            'appId' => $this->appid, //Applet ID
            'timeStamp' => '' . time() . '', //time stamp
            'nonceStr' => $this->createNoncestr(), //Random strings
            'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //data packet
            'signType' => 'MD5'//Signature method);
        //Signature $parameters ['paysign '] = $this - > getsign ($parameters);
        return $parameters;
    }


    //Function: generate random string, no longer than 32-bit private function createNoncestr($length = 32){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }


    //Function: generate signature private function getSign($Obj){
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }
        //Signature step 1: sort the parameters ksort($Parameters) in dictionary order;
        $String = $this->formatBizQueryParaMap($Parameters, false);
        //Step 2: after the string, add key $string = $string. "& key =". $this - > key;
        //Signature step 3: MD5 encryption $String = md5($String);
        //Signature step 4: all characters are converted to uppercase $result "= strtoupper ($string);
        return $result_;
    }


    ///Function: format parameters. private function formatBizQueryParaMap($paraMap, $urlencode) is required for signature{
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar;
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }
}


Author: Handsome enough to call the police
Links: Wechat applet - complete the payment function of the applet
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

Posted by ltoto on Fri, 03 Apr 2020 08:32:08 -0700