微信小程序支付功能 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 相关文章推荐
js设置cookie过期及清除浏览器对应名称的cookie
Oct 24 Javascript
js键盘事件的keyCode
Jul 29 Javascript
javascript实现可全选、反选及删除表格的方法
May 15 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
Dec 15 Javascript
jQuery使用unlock.js插件实现滑动解锁
Apr 04 jQuery
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 Javascript
javascript 取小数点后几位几种方法总结
Aug 02 Javascript
BootStrap 页签切换失效的解决方法
Aug 17 Javascript
Vue中 key keep-alive的实现原理
Sep 18 Javascript
js中this的指向问题归纳总结
Nov 28 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
Mar 28 jQuery
jQuery中DOM操作原则实例分析
Aug 01 jQuery
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数据库操作之基于Mysqli的数据库操作类库
2014/04/19 PHP
11个PHPer必须要了解的编程规范
2014/09/22 PHP
PHP实现的购物车类实例
2015/06/17 PHP
PHP aes (ecb)解密后乱码问题
2015/06/22 PHP
Zend Framework数据库操作技巧总结
2017/02/18 PHP
laravel配置Redis多个库的实现方法
2019/04/10 PHP
Javascript 中的类和闭包
2010/01/08 Javascript
JavaScript 学习笔记之操作符(续)
2015/01/14 Javascript
JavaScript面对国际化编程时的一些建议
2015/06/24 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
JQuery.validate在ie8下不支持的快速解决方法
2016/05/18 Javascript
jQuery树形控件zTree使用小结
2016/08/02 Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
2016/10/11 Javascript
vue之数据交互实例代码
2017/06/16 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
Nuxt.js实战详解
2018/01/18 Javascript
p5.js入门教程和基本形状绘制
2018/03/15 Javascript
vue实现在线翻译功能
2019/09/27 Javascript
vue element upload组件 file-list的动态绑定实现
2019/10/11 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
Python简直是万能的,这5大主要用途你一定要知道!(推荐)
2019/04/03 Python
python函数与方法的区别总结
2019/06/23 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
2020/03/09 Python
matplotlib 画双轴子图无法显示x轴的解决方法
2020/07/27 Python
Python3中对json格式数据的分析处理
2021/01/28 Python
css3进阶之less实现星空动画的示例代码
2019/09/10 HTML / CSS
html5的input的required使用中遇到的问题及解决方法
2018/04/24 HTML / CSS
如何进行Linux分区优化
2013/02/12 面试题
应届毕业生简历自我评价
2014/01/31 职场文书
大学生2014全国两会学习心得体会
2014/03/10 职场文书
希特勒的演讲稿
2014/05/23 职场文书
2014年员工工作总结范文
2014/11/18 职场文书
三峡大坝导游词
2015/01/31 职场文书
高中家长意见怎么写
2015/06/03 职场文书