微信小程序支付功能 php后台对接完整代码分享


Posted in Javascript onJune 12, 2018

微信小程序支付,php后台对接完整代码,全是干货呀,拿过来可以直接使用。小程序在调起微信支付之前需要5个参数,这时候就需要携带code向后台请求,然后后台根据code获取openid 再进行服务器之间的。

一、准备工作

1、小程序注册,要以公司的以身份去注册一个小程序,才有微信支付权限;

2、绑定商户号。

3、在小程序填写合法域

 二、完成以上条件,你可以得到

     小程序appid 小程序秘钥    这两个用于获取用户openid;

     商户号id ,商户号秘钥     支付接口必须的;

三、开始开发

前台代码

/* 
 调起微信支付 
 @param 支付价格,不填写默认为1分钱 
*/ 
function pay(total_fee) { 
 
 var total_fee = total_fee; 
 wx.login({ 
 success: res => { 
 
 //code 用于获取openID的条件之一 
 var code = res.code; 
 wx.request({ 
 url: '后台地址/index.php', 
 method: "POST", 
 data: { 
  total_fee:total_fee, 
  code: code, 
 }, 
 header: { 
  'content-type': 'application/x-www-form-urlencoded' // 默认值 
 }, 
 success: function (res) { //后端返回的数据 
  var data = res.data; 
  console.log(data); 
  console.log(data["timeStamp"]); 
  wx.requestPayment({ 
  timeStamp: data['timeStamp'], 
  nonceStr: data['nonceStr'], 
  package: data['package'], 
  signType: data['signType'], 
  paySign: data['paySign'], 
  success: function (res) { 
  wx.showModal({ 
  title: '支付成功', 
  content: '', 
  }) 
  }, 
  fail: function (res) { 
  console.log(res); 
  } 
  }) 
 } 
 }); 
 
 
 } 
 }) 
 
}

以下是PHP后台代码 ,这里用的是tp框架

<?php 
namespace Home\Controller; 
use Think\Controller; 
class PayController extends Controller { 
 
 /** 
 * [callback 微信支付回调处理] 
 * @Author zhengmingzhou 
 * @DateTime 2018-05-22 
 * @return function [description] 
 */ 
 public function callback(){ 
 vendor("Wechart.WxPay.Api"); 
 vendor("Wechart.NativePay"); 
 vendor("Wechart.WxPay.Data"); 
 vendor("Wechart.WxPay.Notify"); 
 
 
 //获取微信返回支付信息 
 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; 
 $WxPayData = new \WxPayDataBase(); 
 $result = $WxPayData->FromXml($xml); 
 if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ 
  //回调逻辑处理。。。 
  
  
  //返回给微信的参数 
  $data['RETURN_CODE'] = 'SUCCESS'; 
  $data['RETURN_MSG'] = 'OK'; 
 
 
 }else{ 
  $data['RETURN_CODE'] = 'FAIL'; 
  $data['RETURN_MSG'] = 'NO'; 
 } 
 //返回给微信 
 $xml = self::arrtoxml($data); 
 echo $xml; 
 } 
 
 /** 
 * [arrtoxml 格式化返回给微信的数据格式] 
 * @Author zhengmingzhou 
 * @DateTime 2018-05-22 
 * @param [type] $arr [description] 
 * @return [type]  [description] 
 */ 
 private function arrtoxml( $arr ){ 
 if(!$arr){ 
  return ''; 
 }else{ 
  $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 pay(){ 
 //获取openid 
 if(I("post.code")) 
 { //用code获取openid 
  $code=I("post.code"); 
  $WX_APPID = '';//appid 
  $WX_SECRET = '';//AppSecret 
  $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $WX_APPID . "&secret=" . $WX_SECRET . "&js_code=" . $code . "&grant_type=authorization_code"; 
  $infos = json_decode(file_get_contents($url)); 
  $openid = $infos->openid; 
 } 
 if(I("post.total_fee")) 
 { 
  $total_fee=I("post.total_fee"); 
 } 
 else 
 { 
  $total_fee=0.01; 
 } 
 
 $fee = 0.01;//举例充值0.01 
 $appid = '';//appid 
 $body =  '标题'; 
 $mch_id = ''; //商户号 
 $nonce_str = $this->nonce_str();//随机字符串 
 $notify_url = ''; //回调的url【自己填写】 
 $openid = $openid; 
 $out_trade_no = $this->order_number();//商户订单号 
 $spbill_create_ip = '';//服务器的ip【自己填写】; 
 $total_fee = $fee*100;//这里需要*100 
 $trade_type = 'JSAPI';//交易类型 默认 
 
 
 //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错 
 $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'] = $total_fee;//总金额 
 $post['trade_type'] = $trade_type; 
 $sign = $this->sign($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> 
  <spbill_create_ip>'.$spbill_create_ip.'</spbill_create_ip> 
  <total_fee>'.$total_fee.'</total_fee> 
  <trade_type>'.$trade_type.'</trade_type> 
  <sign>'.$sign.'</sign> 
 </xml> '; 
 
 
 //print_r($post_xml);die; 
 //统一接口prepay_id 
 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; 
 $xml = $this->http_request($url,$post_xml); 
 
 $array = $this->xml($xml);//全要大写 
 
 
 //print_r($array); 
 if($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS'){ 
 $time = time(); 
 $tmp='';//临时数组用于签名 
 $tmp['appId'] = $appid; 
 $tmp['nonceStr'] = $nonce_str; 
 $tmp['package'] = 'prepay_id='.$array['PREPAY_ID']; 
 $tmp['signType'] = 'MD5'; 
 $tmp['timeStamp'] = "$time"; 
 
 
 $data['state'] = 200; 
 $data['timeStamp'] = "$time";//时间戳 
 $data['nonceStr'] = $nonce_str;//随机字符串 
 $data['signType'] = 'MD5';//签名算法,暂支持 MD5 
 $data['package'] = 'prepay_id='.$array['PREPAY_ID'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* 
 $data['paySign'] = $this->sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档; 
 $data['out_trade_no'] = $out_trade_no; 
 
 
 }else{ 
 $data['state'] = 0; 
 $data['text'] = "错误"; 
 $data['RETURN_CODE'] = $array['RETURN_CODE']; 
 $data['RETURN_MSG'] = $array['RETURN_MSG']; 
 } 
 
 
 echo json_encode($data); 
} 

 
//随机32位字符串 
private function nonce_str(){ 
 $result = ''; 
 $str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz'; 
 for ($i=0;$i<32;$i++){ 
 $result .= $str[rand(0,48)]; 
 } 
 return $result; 
} 
 
 
//生成订单号 
private function order_number($openid){ 
 //date('Ymd',time()).time().rand(10,99);//18位 
 return md5($openid.time().rand(10,99));//32位 
} 
 
 
//签名 $data要先排好顺序 
private function sign($data){ 
 $stringA = ''; 
 foreach ($data as $key=>$value){ 
 if(!$value) continue; 
 if($stringA) $stringA .= '&'.$key."=".$value; 
 else $stringA = $key."=".$value; 
 } 
 $wx_key = '';//申请支付后有给予一个商户账号和密码,登陆后自己设置的key 
 $stringSignTemp = $stringA.'&key='.$wx_key; 
 return strtoupper(md5($stringSignTemp)); 
} 
 
 
//curl请求 
public function http_request($url,$data = null,$headers=array()) 
{ 
 $curl = curl_init(); 
 if( count($headers) >= 1 ){ 
 curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
 } 
 curl_setopt($curl, CURLOPT_URL, $url); 
 
 
 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 
 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 
 
 
 if (!empty($data)){ 
 curl_setopt($curl, CURLOPT_POST, 1); 
 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 
 } 
 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 
 $output = curl_exec($curl); 
 curl_close($curl); 
 return $output; 
} 
 
 
//获取xml 
private function xml($xml){ 
 $p = xml_parser_create(); 
 xml_parse_into_struct($p, $xml, $vals, $index); 
 xml_parser_free($p); 
 $data = ""; 
 foreach ($index as $key=>$value) { 
 if($key == 'xml' || $key == 'XML') continue; 
 $tag = $vals[$value[0]]['tag']; 
 $value = $vals[$value[0]]['value']; 
 $data[$tag] = $value; 
 } 
 return $data; 
} 
 
}

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

Javascript 相关文章推荐
button没写type=button会导致点击时提交
Mar 06 Javascript
jQuery Migrate 1.1.0 Released 注意事项
Jun 14 Javascript
JavaScript的各种常见函数定义方法
Sep 16 Javascript
javascript解三阶幻方(九宫格)
Apr 22 Javascript
laypage分页控件使用实例详解
May 19 Javascript
JS实现图片局部放大或缩小的方法
Aug 20 Javascript
jquery实现网页定位导航
Aug 23 Javascript
微信小程序 动态传参实例详解
Apr 27 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
Feb 26 Javascript
让axios发送表单请求形式的键值对post数据的实例
Aug 11 Javascript
Vue起步(无cli)的啊教程详解
Apr 11 Javascript
javascript实现点亮灯泡特效示例
Oct 15 Javascript
js replace 全局替换的操作方法
Jun 12 #Javascript
微信小程序自定义prompt组件步骤详解
Jun 12 #Javascript
js实现购物车功能
Jun 12 #Javascript
浅谈Node.js 中间件模式
Jun 12 #Javascript
浅谈Webpack打包优化技巧
Jun 12 #Javascript
关于TypeScript模块导入的那些事
Jun 12 #Javascript
JS实现前端页面的搜索功能
Jun 12 #Javascript
You might like
给初学PHP的5个入手程序
2006/11/23 PHP
php REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
解析CI即CodeIgniter框架在Nginx下的重写规则
2013/06/03 PHP
PHP根据图片色界在不同位置加水印的方法
2015/07/01 PHP
php解析url并得到url中的参数及获取url参数的四种方式
2015/10/26 PHP
joomla组件开发入门教程
2016/05/04 PHP
PHP序列化的四种实现方法与横向对比
2018/11/29 PHP
解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
2007/08/13 Javascript
Javascript String对象扩展HTML编码和解码的方法
2009/06/02 Javascript
jQuery的实现原理的模拟代码 -5 Ajax
2010/08/07 Javascript
Jquery绑定事件(bind和live的区别介绍)
2013/08/23 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
js省市联动效果完整实例代码
2015/12/09 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
IScroll5 中文API参数说明和调用方法
2016/05/21 Javascript
Vue.js组件使用开发实例教程
2016/11/01 Javascript
微信小程序购物商城系统开发系列-工具篇的介绍
2016/11/21 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
js canvas实现擦除效果示例代码
2017/04/26 Javascript
vue之将echart封装为组件
2018/06/02 Javascript
vue踩坑记录之数组定义和赋值问题
2019/03/20 Javascript
js中调用微信的扫描二维码功能的实现代码
2020/04/11 Javascript
[03:41]DOTA2上海特锦赛小组赛第三日recap精彩回顾
2016/02/28 DOTA
[00:59]DOTA2背景故事第二期之四大基本法则
2020/07/07 DOTA
利用python爬取软考试题之ip自动代理
2017/03/28 Python
Python 3中print函数的使用方法总结
2017/08/08 Python
python网络爬虫学习笔记(1)
2018/04/09 Python
Numpy 改变数组维度的几种方法小结
2018/08/02 Python
Python调用C语言的实现
2019/07/26 Python
英国复古服装和球衣购买网站:3Retro Football
2018/07/09 全球购物
工作自我评价分享
2013/12/01 职场文书
单位刻章介绍信范文
2014/01/11 职场文书
小学毕业演讲稿
2014/04/25 职场文书
暑假安全教育广播稿
2014/09/10 职场文书
工作作风懒散检讨书
2014/10/29 职场文书
学习与创新自我评价
2015/03/09 职场文书