微信支付现在用到的地方越来越多,从公众号支付,扫码支付一直到现在的小程序支付等等六种快捷支付方式,公司要求开发小程序商城,就只能我上手处理接口支付问题了,使用最常规的第三方模式,第三方帮特约商户申请商户号并为他进行支付开发,第三方本身不经手资金,支付成功后资金直接进入特约商户商户号。

废话不多说直接上代码。

小程序访问地址:payfee.php 如果使用 TP 框架处理后台的话,写成方法即可

include 'WeixinPay.php';
$appid=''; //小程序appid
$openid= $_POST['id'];
$mch_id=''; //微信支付商户支付号
$key=''; //Api密钥
$out_trade_no = $mch_id. time();
$total_fee = $_POST['fee'];
if (empty($total_fee)) { //押金$body = "充值押金";$total_fee = floatval(99*100);
} else {$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 微信小程序支付类 所有微信小程序需要的参数都已经写入

/** 小程序微信支付*/
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' => '2018013106125348', //商户订单号'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' => 'https://www.weixin.qq.com/wxpay/notify.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); //严格校验//设置headercurl_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");}}//数组转换成xmlprivate function arrayToXml($arr) {$xml = "<xml>";foreach ($arr as $key => $val) {if (is_array($val)) {$xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";} else {$xml .= "<" . $key . ">" . $val . "</" . $key . ">";}}$xml .= "</xml>";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;}}

小程序页面请求处理:

wx.request({url: 'https://yourhost.com/wxpay/payfee.php',//改成你自己的链接data:{id: app.globalData.openid,//获取用户openidfee:100 //商品价格},header: {'Content-Type': 'application/x-www-form-urlencoded'},method: 'POST',success: function (res) {console.log(res.data);console.log('调起支付');wx.requestPayment({'timeStamp': res.data.timeStamp,'nonceStr': res.data.nonceStr,'package': res.data.package,'signType': 'MD5','paySign': res.data.paySign,'success': function (res) {console.log('success');wx.showToast({title: '支付成功',icon: 'success',duration: 3000});},'fail': function (res) {console.log(res);},'complete': function (res) {console.log('complete');}});},fail: function (res) {console.log(res.data)}});

回调 URL:notify.php

$postXml = $GLOBALS["HTTP_RAW_POST_DATA"]; //接收微信参数
// 接受不到参数可以使用file_get_contents("php://input"); PHP高版本中$GLOBALS好像已经被废弃了
if (empty($postXml)) {return false;
}//将xml格式转换成数组
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;
}
$attr = xmlToArray($postXml);
$total_fee = $attr['total_fee'];
$open_id = $attr['openid'];
$out_trade_no = $attr['out_trade_no'];
$time = $attr['time_end'];

支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理,并返回应答。

对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为 15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

注意:同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。

推荐的做法是,当收到通知进行处理时,首先检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。

所以在微信的异步通知后,也需要给微信服务器,返回一个信息,只不过微信的所有数据格式都是 xml 的,所以我们在返回一个数据给微信即可。

cho exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');

微信小程序支付开发者文档:

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_10&index=1

PHP完成微信小程序在线支付功能相关推荐

  1. 小白也能看懂的教程:微信小程序在线支付功能开通详细流程(图文介绍)

    微信小程序不仅是一个展示平台,更多会用到小程序的电商功能,当然了,支付目前而言需要接入微信支付,那么具体而言,微信小程序要怎么开通支付功能呢?最近需要在微信小程序中用到在线支付功能,于是看了一下官方的 ...

  2. 【Node.js】实现微信小程序在线支付功能

    实战项目名称:微信小程序实现在线支付功能 - 文章结尾附上微信小程序码,扫码登录后即可体验!! 文章目录 一.实战步骤 1. 前期准备 2. 添加`wechatpay-node-v3`和`fs`插件 ...

  3. 微信小程序实现支付功能

    小程序支付,没有封装支付代码:直接上一段可用的流程代码吧: 微信小程序支付官网文档有详细的说明,这里我就不再赘述啦: 客户端js: wx.request({ url:'https://www.xxxx ...

  4. 微信小程序在线客服系统都有哪些功能?

    微信小程序的用户已经破6亿,不少企业都看准了小程序这块大蛋糕.但是想要把握住小程序红利,除了做好运营推广外,用户服务也是重中之重.微信小程序自带的客服系统却很难满足用户服务的需求,于是很多小程序使用者 ...

  5. 在线刷题题库微信小程序开发制作功能介绍

    在线刷题题库微信小程序开发制作功能介绍 1.题库大全:支持搜索查询各类课程试题答案. 2.多试题类型:支持单选题.多选题.判断题.问答题等多种类型. 3.批量导入:支持批量导入课程试题. 4.试题纠错 ...

  6. 微信小程序:常用功能5——在线客服功能的实现

    微信小程序:常用功能5--在线客服功能的实现 微信小程序的客服功能比较纯熟,非常简单易用,只要在公众平台小程序账号中设置好相关客服人员,基本用户就能实现与客服人员的实时对话. 首先登陆微信公众平台小程 ...

  7. ios微信小程序虚拟支付解决办法

    ios微信小程序虚拟支付整理介绍 目前iOS端暂不支持虚拟支付,微信小程序虚拟支付仅涉及到ios端,安卓端不受影响. 小程序支付规范 https://developers.weixin.qq.com/ ...

  8. 个体门店微信小程序在线开店的教程

    个体门店微信小程序在线开店的教程,在前面写过一篇文章有关个体门店微信小程序如何注册和认证流程总结,写得有些粗略,有很多个体门店商家都在问具体怎么样操作才能拥有自己的可马上运营微信小程序. 如果对关于个 ...

  9. 微信小程序 iOS支付

    微信小程序运营支付规范 微信官方针对有虚拟支付功能的小程序下发了整改通知.截至5月8号,平台将对账号屏蔽iOS系统的支付接口调用.我去查了<<微信小程序运营规则>>,如上图.发 ...

最新文章

  1. php程序员笔试题库,2017年初级PHP程序员笔试题
  2. php获取 POST请求的数据
  3. web developer tips (74):在 Visual Studio 2008设计器里添加或移除AJAX Extenders
  4. Shell 下面的几种运算方式
  5. Python(60)_闭包
  6. C#使用Xamarin开发可移植移动应用(2.Xamarin.Forms布局,本篇很长,注意)附源码
  7. 用非递归方式实现二叉树后序遍历
  8. 【Python】Matplotlib画布图案保存为PDF文件
  9. Docker的新版本,R软件包的R-Hub以及更多新闻
  10. html中md5如何使用方法,html中使用js進行登錄md5加密提交並重定向新頁面
  11. 2656 阿克曼函数
  12. 手机连接ftp文件服务器,手机轻松玩转小白文件管理器远程FTP教程——x-plo
  13. python实现语法分析器_Python源码分析5 – 语法分析器PyParser | 学步园
  14. ObjectARX反应器概述
  15. CSS——CSS定位※ ( position )
  16. 计算机快捷方式后缀名,电脑快捷键-文件扩展名详解.doc
  17. swap分区、硬盘和磁盘
  18. 被人误解的设计思路1
  19. Access to XMLHttpRequest at ‘xxx‘ from origin ‘http://localhost:8082‘has been blocked by CORS policy
  20. Django + Pytest搭建在线自动化测试平台

热门文章

  1. 脑机接口(BCI)常用的实验范式
  2. QQ相册(html)实例详述----Div布局
  3. 原创|智能交通2022第十六届北京国际数字交通展览会
  4. sin的导数为cos的几何和公式证明
  5. 天瑞地安科技集团:VR虚拟现实未来发展趋势
  6. 干净利落的消除网页全局事件监听,匿名函数也可以搞定,一文让你掌握同步CSDN文章到公众号的技巧,从此远离繁重的编辑工作
  7. AD20原理图设计与PCB封装画板--学习笔记
  8. 【手绘漫画】图解LeetCode之猜数字大小(LeetCode 374题)
  9. Vue超全资源,收藏!
  10. 开源中国源码学习(五)——切换皮肤(日间模式和夜间模式)