小程序微信支付(PHP)

条件:申请微信支付商户号,拥有
商户号id及商户号密钥

一、微信接口

https://developers.weixin.qq.com/miniprogram/dev/api/open-api/payment/wx.requestPayment.html#wxrequestpaymentobject
在这里插入图片描述
在这里插入图片描述
这几个参数需要通过wx.request从后台得到
前台代码:

  wx.request({                     
      url: '后台地址',
      data: {
        //根据需要所传参数
      },
      method: 'POST',
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      success: function (response) {

       // console.log(response.data);
        // 发起支付  出现支付页面
        wx.requestPayment({
          'timeStamp': response.data.timeStamp,
          'nonceStr': response.data.nonceStr,
          'package': response.data.package,
          'signType': 'MD5',
          'paySign': response.data.paySign,
          success: function (res) {
     
            wx.showToast({
              title: '支付成功'
            });
            //  跳转页面
            wx.switchTab({
              url: '../index'
            })
          },
          fail:function(res){
            console.log(res);
          }
        });
      }
    });

二、后台代码(PHP)

一大部分与公众号是一样的,可以看这个人的视频来学习
https://www.imooc.com/u/197650/courses?sort=publish
代码里的很多算法原理讲的很清楚
上代码!
(代码我也是学习的,原链接在这里
https://segmentfault.com/a/1190000014444847

<?php
date_default_timezone_set("PRC");
class PayController{
    private $appid=""; //小程序appid
    private $appsecret= ""; //小程序的secret
    private $MCHID=""; //商户号id
    private $KEY=""; //商户号key
    /*
    *   发起支付回调支付信息
    *   by:leoyi
    *   Date:2018-4-8
    */
    public function payOrder($total,$r_openid,$r_body,$r_trade_no){
       $total_fee = $total; //支付金额
//$total_fee = 1;
        $openid = $r_openid; //用户的Openid
        if(empty($total_fee) || empty($openid)){ //一定要有用户Openid和支付金额
            die("缺少参数!");
        }


        $appid = $this->appid;
        $MCHID = $this->MCHID; //商户号
        $KEY =  $this->KEY; //商户key

        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

        $data['appid'] = $appid;  //小程序appid
        $data['mch_id'] = $MCHID;	//商户号id
        $data['nonce_str'] = md5($MCHID.time()); //验证的支付
        $data['openid'] = $openid; //用户openid
        $data['body'] = $r_body; //微信支付对应的商家/公司主体名
        $data['out_trade_no'] = $r_trade_no; //订单号id,用于回调改订单状态
        $data['total_fee'] = $total_fee; //支付金额,单位为分!!
        $data['spbill_create_ip'] = '8.8.8.8'; //验证ip地址,这个不用改随意
        $data['notify_url'] = ""; 
        //微信支付成功的回调路径,必须是外网可以访问的链接,必须在支付文件的同目录下
        //不能带参数    
        //这是个巨大的坑,到现在也没懂,所以回调采用了别的方法,下面介绍
        $data['trade_type'] = "JSAPI"; //小程序支付,所以是JSAPI

// --------------------以下这一串都不用改--------------------------------
        ksort($data);
        $sign_str = $this->ToUrlParams($data);
        $sign_str = $sign_str."&key=".$KEY;
        $data['sign'] = strtoupper(md5($sign_str));
        $xml = $this->arrayToXml($data);
        $r = $this->postXmlCurl($xml,$url,true);
        $result = json_decode($this->xml_to_json($r));



//var_dump($result);
        if($result->return_code == 'SUCCESS'){

            $stringtime = date("Y-m-d H:i:s",time());
            $sdata['timeStamp'] = (string)strtotime($stringtime);    //必须为字符串类型

            $sdata['appId'] = $appid;

// $sdata['timeStamp'] = time();
            $sdata['nonceStr'] = md5(time().rand().rand().$openid);
            if(isset($result->prepay_id)) {
                $sdata['package'] = "prepay_id=" . $result->prepay_id;  //必须带前面的prepay_id
            }
            $sdata['signType'] = "MD5";

            ksort($sdata);
            $sign_str = $this->ToUrlParams($sdata);
            $sign_str = $sign_str."&key=".$KEY;
            $sdata['paySign'] = strtoupper(md5($sign_str));

            echo json_encode($sdata);

        }
        else{
            echo "失败";
        }
// -----------------------都不用改-----------------------------------------------
    
    //这些方法如果不懂在上面的视频链接中都能找到讲解,这与公众号是一模一样的
    public function postXmlCurl($xml, $url, $useCert = false, $second = 10)
    {
        $ch = curl_init();
//设置超时
        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);//严格校验2
//设置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
        $data = curl_exec($ch);
//返回结果
        if($data){
            curl_close($ch);
            return $data;
        } else {
            $error = curl_errno($ch);
            curl_close($ch);
            return $error;
        }
    }
   
    public function ToUrlParams($data)
    {
        $buff = "";
        foreach ($data as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }
    
    public 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 function  xml_to_json($xmlstring) {
        return json_encode($this->xml_to_array($xmlstring),JSON_UNESCAPED_UNICODE);
    }
   
    public function post_url($post_data, $url)
    {
        $ch = curl_init();
//设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);

        curl_setopt($ch,CURLOPT_URL, $url);

        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//严格校验2

        curl_setopt($ch, CURLOPT_HEADER, FALSE);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);


        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
    
    public function xml_to_array($xml) {
//return ((array) simplexml_load_string($xmlstring));
        return simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA);

//return json_decode(xml_to_json($xmlstring));
    }
}



//整个类写完记得要实例化
$total_fee = $_POST['totalFee'];   //支付金额
$openid = $_POST['openid'];
$body = $_POST['body'];   //商家名
$trade_no = $_POST['tradeNo'];  //订单编号

$demo = new PayController();
$demo->payOrder($total_fee,$openid,$body,$trade_no);

三、支付成功后修改订单状态

在支付的后端代码里是有回调路径的,但是这个…反正我没搞明白,如果我搞明白了我再来补这个坑。
所以采用了另外的方法:在wx.requestPayment成功后再对后端进行请求再更改状态
在这里插入图片描述
就更容易理解了,注意局部变量的使用,保证参数有效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值