微信小程序支付功能 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 相关文章推荐
List the Stored Procedures in a SQL Server database
Jun 20 Javascript
DOMAssitant最新版 DOMAssistant 2.5发布
Dec 25 Javascript
JS解密入门 最终变量劫持
Jun 25 Javascript
jquery.boxy插件的iframe扩展代码
Jul 02 Javascript
JavaScript Serializer序列化时间处理示例
Jul 31 Javascript
Node.js的特点和应用场景介绍
Nov 04 Javascript
JS实现六边形3D拖拽翻转效果的方法
Sep 11 Javascript
Vue.js实战之组件的进阶
Apr 04 Javascript
web前端vue之CSS过渡效果示例
Jan 10 Javascript
微信小程序从注册账号到上架(图文详解)
Jul 17 Javascript
微信小程序左滑删除实现代码实例
Sep 16 Javascript
解决element-ui里的下拉多选框 el-select 时,默认值不可删除问题
Aug 14 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在获取指定目录下的目录,在获取的目录下面再创建文件,多平台
2011/08/03 PHP
php上传apk后自动提取apk包信息的使用(示例下载)
2013/04/26 PHP
修改PHP脚本使WordPress拦截垃圾评论的方法示例
2015/12/10 PHP
PHP编写RESTful接口
2016/02/23 PHP
PHP设计模式之简单投诉页面实例
2016/02/24 PHP
php+mongodb判断坐标是否在指定多边形区域内的实例
2016/10/28 PHP
Zend Framework上传文件重命名的实现方法
2016/11/25 PHP
PHP常用字符串函数小结(推荐)
2018/08/05 PHP
基于ThinkPHP删除目录及目录文件函数
2020/10/28 PHP
用函数式编程技术编写优美的 JavaScript
2006/11/25 Javascript
用javascript实现计算两个日期的间隔天数
2007/08/14 Javascript
jQuery UI Dialog控件中的表单无法正常提交的解决方法
2010/12/19 Javascript
一个基于jQuery的树型插件(OrangeTree)使用介绍
2012/05/03 Javascript
jquery 层次选择器siblings与nextAll的区别介绍
2013/08/02 Javascript
javascript的push使用指南
2014/12/05 Javascript
jQuery获得document和window对象宽度和高度的方法
2015/03/25 Javascript
JS中产生标识符方式的演变
2015/06/12 Javascript
原生js的数组除重复简单实例
2016/05/24 Javascript
关于function类中定义变量this的简单说明
2016/05/28 Javascript
AngularJS通过$http和服务器通信详解
2016/09/21 Javascript
浅谈函数调用的不同方式,以及this的指向
2017/09/17 Javascript
微信小程序移动拖拽视图-movable-view实例详解
2019/08/17 Javascript
Openlayers实现图形绘制
2020/09/28 Javascript
Windows下搭建python开发环境详细步骤
2020/07/20 Python
python抓取并保存html页面时乱码问题的解决方法
2016/07/01 Python
如何运行带参数的python脚本
2019/11/15 Python
获取python运行输出的数据并解析存为dataFrame实例
2020/07/07 Python
3D动画《斗罗大陆》上线当日播放过亿
2021/03/16 国漫
Gap加拿大官网:Gap Canada
2017/08/24 全球购物
俄罗斯极限运动网上商店:Board Shop №1
2020/12/18 全球购物
小学数学课后反思
2014/04/23 职场文书
知识竞赛拉拉队口号
2014/06/16 职场文书
2015年司法局工作总结
2015/05/22 职场文书
推广普通话的宣传语
2015/07/13 职场文书
教师节主题班会方案
2015/08/17 职场文书
承诺书应该怎么写?
2019/09/10 职场文书