微信小程序支付PHP代码


Posted in Javascript onAugust 23, 2018

本文实例为大家分享了微信小程序支付PHP具体代码,供大家参考,具体内容如下

服务器端获取 openid

Getopenid.php

<?php
 header('Content-type: application/json; charset=UTF-8');
 $APPID="";//填写小程序appid
 $SECRET="";//填写小程序secret
 $JSCODE="";
 if(isset($_GET['js_code'])){
  $JSCODE=$_GET['js_code'];
  $url="https://api.weixin.qq.com/sns/jscode2session?appid=".$APPID
  ."&secret=".$SECRET."&js_code=".$JSCODE."&grant_type=authorization_code";
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_HEADER, 0);
  $data = curl_exec($curl);
  $array=json_decode($data,true);

  curl_close($curl);
  $openid=isset($array['openid'])?$array['openid']:$array['errcode'];
  if($openid=="40029"){
   $response["result"] = 0;
   $response["msg"] = "invalid code";
   $response["openid"] = $openid;
   echo json_encode($response);
  }else{
   $response["result"] = 1;
   $response["msg"] = "user exist";
   $response["openid"] = $openid;
   echo json_encode($response);
  }
 }

小程序存储openid
在app.js中

getUserInfo:function(cb){
 var that = this
 if(this.globalData.userInfo){
  typeof cb == "function" && cb(this.globalData.userInfo)
 }else{
  wx.login({
  success: function (res) {
   if (res.code) {
   var code = res.code;
   wx.getUserInfo({
    success: function (res2) {
    console.log(res2);
    that.globalData.userInfo = res2.userInfo;
    typeof cb == "function" && cb(that.globalData.userInfo)
    var encryptedData = encodeURIComponent(res2.encryptedData);//一定要把加密串转成URI编码
    var iv = res2.iv;
    //请求自己的服务器
    //Login(code, encryptedData, iv);
    wx.showToast({
     title: '正在登录...',
     icon: 'loading',
     duration: 10000
    });
    //请求服务器
    wx.request({
     url: API_URL,//Getopenid.php
     data: {
     js_code: code,
     },
     method: 'GET',
     header: {
     'content-type': 'application/json'
     }, // 设置请求的 header
     success: function (res) {
     // success
     wx.hideToast();
     console.log("JSON:" + res.data);
     if (res.data.result=="1"){//获取openid成功
      wx.setStorage({//存储openid
      key: "openid",
      data: res.data.openid
      })
     }else{
      wx.showToast({
      title: 'openid获取失败',
      icon: 'none',
      duration: 2000
      })
     }
     console.log('服务器返回' + res.data.result);
     console.log('服务器返回' + res.data.msg);
     console.log('服务器返回' + res.data.openid);
     },
     fail: function () {
     // fail
     // wx.hideToast();
     },
     complete: function () {
     // complete
     }
    })
    }
   })
   } else {
   console.log('获取用户登录态失败!' + res.errMsg)
   }
  }
  })
 }
 }

在登陆界面获取openid

var app = getApp()
onLoad: function () {
 console.log('onLoad')
 var that = this
 //调用应用实例的方法获取全局数据
 app.getUserInfo(function(userInfo){//获取用户信息 
  //更新数据
  that.setData({
  userInfo:userInfo
  })
 })
}

通过以上步骤已经获取到openid

支付方法小程序

pay() {
 var that = this;
 if (this.data.totalPrice == 0) {
  return;
 }
 wx.getStorage({//获取存储在本地的openid
  key: 'openid',
  success: function (res) {
  console.log(res.data)
  that.setData({
   openid:res.data,
  })
  var carArray = that.data.carArray;
  var str="";
  for (var i = 0; i < carArray.length; i++) {
   str=str+ carArray[i].num+"个" + carArray[i].name+" ";
  }
  wx.request({
   url: 'Pay.php',//支付接口
   data: {
   openid: res.data,//openid
   total_fee: that.data.totalPrice,//总金额
   body: str,//商品描述
   },
   method:'GET',
   success:function(res){
   console.log(res.data['timeStamp'])
   if(res.data){
    wx.requestPayment({
    'timeStamp': res.data['timeStamp'],
    'nonceStr': res.data['nonceStr'],
    'package': res.data['package'],
    'signType': 'MD5',
    'paySign': res.data['paySign'],
    'success': function (res) {
     wx.showToast({
     title: '支付成功',
     icon: 'succes',
     duration: 1000,
     mask: true
     })
     //支付成功后在数据库减去购买商品的数量
     var carArray = that.data.carArray;
     for (var i = 0; i < carArray.length; i++) {
     that.setData({
      jiesuan_num: carArray[i].num,
      jiesuan_id: carArray[i].goods_id,
     })
     DeGood(that);
     }
    },
    'fail': function (res) {
     wx.showToast({
     title: '支付失败',
     icon: 'none',
     duration: 1000,
     mask: true
     })
    }
    })
   }
   }
  })
  }
 })
 },

Pay.php

<?php
 include 'WeixinPay.php'; 
 $appid=''; //小程序appid
 $openid= $_GET['openid']; 
 $mch_id=''; //商户id
 $key=''; //商户key
 $out_trade_no = $mch_id. time(); 
 $total_fee = $_GET['total_fee']; 
 $body= $_GET['body'];
 if(empty($total_fee)){ 
  $body = $body; 
  $total_fee = floatval(99*100); 
 }else{ 
  $body = $body; 
  $total_fee = floatval($total_fee*100); 
 } 
 $weixinpay = new WeixinPay($appid,$openid,$mch_id,$key,$out_trade_no,$body,$total_fee); 
 $return=$weixinpay->pay(); 
 echo json_encode($return);

WeixinPay.php

<?php


/*
 * 小程序微信支付
 */


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() {
  //统一下单接口
  $return = $this->weixinapp();
  return $return;
 }


 //统一下单接口
 private function unifiedorder() {
  $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  $parameters = array(
   'appid' => $this->appid, //小程序ID
   'mch_id' => $this->mch_id, //商户号
   'nonce_str' => $this->createNoncestr(), //随机字符串
//   'body' => 'test', //商品描述
   'body' => $this->body,
//   'out_trade_no' => '2015450806125348', //商户订单号
   'out_trade_no'=> $this->out_trade_no,
//   'total_fee' => floatval(0.01 * 100), //总金额 单位 分
   'total_fee' => $this->total_fee,
//   'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], //终端IP
   'spbill_create_ip' => '192.168.0.161', //终端IP
   'notify_url' => 'http://www.weixin.qq.com/wxpay/pay.php', //通知地址 确保外网能正常访问
   'openid' => $this->openid, //用户id
   'trade_type' => 'JSAPI'//交易类型
  );
  //统一下单签名
  $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();
  //设置超时
  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); //严格校验
  //设置header
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
  //要求结果为字符串且输出到屏幕上
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  //post提交方式
  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);


  //运行curl
  $data = curl_exec($ch);
  //返回结果
  if ($data) {
   curl_close($ch);
   return $data;
  } else {
   $error = curl_errno($ch);
   curl_close($ch);
   throw new WxPayException("curl出错,错误码:$error");
  }
 }



 //数组转换成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转换成数组
 private function xmlToArray($xml) {


  //禁止引用外部xml实体 


  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() {
  //统一下单接口
  $unifiedorder = $this->unifiedorder();
//  print_r($unifiedorder);
  $parameters = array(
   'appId' => $this->appid, //小程序ID
   'timeStamp' => '' . time() . '', //时间戳
   'nonceStr' => $this->createNoncestr(), //随机串
   'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包
   'signType' => 'MD5'//签名方式
  );
  //签名
  $parameters['paySign'] = $this->getSign($parameters);
  return $parameters;
 }


 //作用:产生随机字符串,不长于32位
 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;
 }


 //作用:生成签名
 private function getSign($Obj) {
  foreach ($Obj as $k => $v) {
   $Parameters[$k] = $v;
  }
  //签名步骤一:按字典序排序参数
  ksort($Parameters);
  $String = $this->formatBizQueryParaMap($Parameters, false);
  //签名步骤二:在string后加入KEY
  $String = $String . "&key=" . $this->key;
  //签名步骤三:MD5加密
  $String = md5($String);
  //签名步骤四:所有字符转为大写
  $result_ = strtoupper($String);
  return $result_;
 }


 ///作用:格式化参数,签名过程需要使用
 private function formatBizQueryParaMap($paraMap, $urlencode) {
  $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;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
document.getElementById的简写方式(获取id对象的简略写法)
Sep 10 Javascript
jquery 层次选择器siblings与nextAll的区别介绍
Aug 02 Javascript
Jquery右下角抖动、浮动 实例代码(兼容ie6、FF)
Aug 15 Javascript
利用进制转换压缩数字函数分享
Jan 02 Javascript
window.returnValue使用方法示例介绍
Jul 03 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
Jul 17 Javascript
jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
Nov 19 Javascript
jQuery插件扩展操作入门示例
Jan 16 Javascript
Bootstrap 表单验证formValidation 实现表单动态验证功能
May 17 Javascript
Vue 莹石摄像头直播视频实例代码
Aug 31 Javascript
如何在vue中使用kindeditor富文本编辑器
Dec 19 Vue.js
vue+django实现下载文件的示例
Mar 24 Vue.js
vue+axios 前端实现的常用拦截的代码示例
Aug 23 #Javascript
详解如何配置vue-cli3.0的vue.config.js
Aug 23 #Javascript
JS使用Date对象实时显示当前系统时间简单示例
Aug 23 #Javascript
React key值的作用和使用详解
Aug 23 #Javascript
vue项目中使用lib-flexible解决移动端适配的问题解决
Aug 23 #Javascript
从零开始学习搭建React脚手架项目
Aug 23 #Javascript
angular2 ng2-file-upload上传示例代码
Aug 23 #Javascript
You might like
php 文件上传系统手记
2009/10/26 PHP
php中用socket模拟http中post或者get提交数据的示例代码
2013/08/08 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
PHP中phar包的使用教程
2017/06/14 PHP
PHP实现数据四舍五入的方法小结【4种方法】
2019/03/27 PHP
phpcmsv9.0任意文件上传漏洞解析
2020/10/20 PHP
PHP中isset、empty的用法与区别示例详解
2020/11/05 PHP
IE不出现Flash激活框的小发现的js实现方法
2007/09/07 Javascript
jquery 3D 标签云示例代码
2014/06/12 Javascript
jquery UI Datepicker时间控件的使用方法(终结版)
2015/11/07 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
2016/11/22 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
2017/01/19 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
2017/07/24 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
图文介绍Vue父组件向子组件传值
2018/02/17 Javascript
微信小程序实现富文本图片宽度自适应的方法
2019/01/20 Javascript
使用Angular自定义字段校验指令的方法示例
2019/02/01 Javascript
TypeScript之调用栈的实现
2019/12/31 Javascript
javaScript实现一个队列的方法
2020/07/14 Javascript
vue使用vant中的checkbox实现全选功能
2020/11/17 Vue.js
Vue如何实现变量表达式选择器
2021/02/18 Vue.js
Python基础篇之初识Python必看攻略
2016/06/23 Python
python安装pil库方法及代码
2019/06/25 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
对Python获取屏幕截图的4种方法详解
2019/08/27 Python
tensorflow使用range_input_producer多线程读取数据实例
2020/01/20 Python
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
2021/01/20 HTML / CSS
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
全球最大的生存食品、水和装备专用在线市场:BePrepared.com
2020/01/02 全球购物
Why do we need Unit test
2013/01/03 面试题
咖啡店的创业计划书,让你hold不住
2014/01/03 职场文书
公司中秋节活动方案
2014/02/12 职场文书
婚前协议书范本两则
2014/10/16 职场文书
师德承诺书
2015/01/20 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
教师教育教学随笔
2015/08/15 职场文书