微信小程序支付功能 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 相关文章推荐
javascript背投广告代码的完善
Apr 08 Javascript
面向对象的Javascript之二(接口实现介绍)
Jan 27 Javascript
JavaScript中的变量声明早于赋值分析
Mar 01 Javascript
关于jQuery新的事件绑定机制on()的使用技巧
Apr 26 Javascript
浅析return false的正确使用
Nov 04 Javascript
js点击选择文本的方法
Feb 09 Javascript
js实现div拖动动画运行轨迹效果代码分享
Aug 27 Javascript
D3.js实现散点图和气泡图的方法详解
Sep 21 Javascript
easyui下拉框动态级联加载的示例代码
Nov 29 Javascript
详解如何在你的Vue项目配置vux
Jun 04 Javascript
@angular前端项目代码优化之构建Api Tree的方法
Dec 24 Javascript
vue中使用GraphQL的实例代码
Nov 04 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模板引擎Smarty内建函数foreach,foreachelse用法分析
2016/04/11 PHP
php gd等比例缩放压缩图片函数
2016/06/12 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
PHP实现验证码校验功能
2017/11/16 PHP
php+js实现裁剪任意形状图片
2018/10/31 PHP
IE8 兼容性问题(属性名区分大小写)
2009/06/04 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
jquery实现ajax提交form表单的方法总结
2014/03/03 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
不定义JQuery插件 不要说会JQuery
2016/03/07 Javascript
Bootstrap 模态框实例插件案例分析
2016/12/28 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
vuejs手把手教你写一个完整的购物车实例代码
2017/07/06 Javascript
React + webpack 环境配置的方法步骤
2017/09/07 Javascript
react native 获取地理位置的方法示例
2018/08/28 Javascript
手把手15分钟搭一个企业级脚手架
2019/09/16 Javascript
Vue 实现html中根据类型显示内容
2019/10/28 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
[06:15]2016国际邀请赛中国区预选赛单车采访:我顶WINGS
2016/06/27 DOTA
[01:05:56]Liquid vs VP Supermajor决赛 BO 第二场 6.10
2018/07/04 DOTA
python多重继承新算法C3介绍
2014/09/28 Python
python如何实现excel数据添加到mongodb
2015/07/30 Python
pyshp创建shp点文件的方法
2018/12/31 Python
如何利用Pyecharts可视化微信好友
2019/07/04 Python
Python 如何查找特定类型文件
2020/08/17 Python
python使用ctypes库调用DLL动态链接库
2020/10/22 Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
2021/01/05 Python
家长给孩子的评语
2014/01/30 职场文书
财产公证书样本
2014/04/04 职场文书
物理分数没达标检讨书
2014/09/13 职场文书
学生上课迟到检讨书
2015/01/01 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
商务信函英语问候语
2015/11/10 职场文书
原生JS封装vue Tab切换效果
2021/04/28 Vue.js
Python办公自动化之Excel(中)
2021/05/24 Python
Netty分布式客户端处理接入事件handle源码解析
2022/03/25 Java/Android