thinkphp5开发小程序后台(PHP小程序支付功能完整版基于thinkPHP)
类别:编程学习 浏览量:117
时间:2022-04-01 01:39:51 thinkphp5开发小程序后台
PHP小程序支付功能完整版基于thinkPHP本文实例讲述了PHP小程序支付功能。分享给大家供大家参考,具体如下:
环境: tp3.2 + 小程序 微信支付功能开通
Step1: 下载PHP 支付SDK(下载地址) 放到Library\Vendor下,取名Wxpay
修改WxPay.Config.php 里的appid appsecret key MCHID
Step2: 小程序 js 代码:
|
var url = getApp().globalData.httpServer + 'api/buy/pay' ; var userId = getApp().globalData.userId; var totalMoney = this .data.totalMoney; var cart = this .data.goods; var param = { cart: JSON.stringify(cart), cartamount: totalMoney, userid: userId, payment: this .data.payment, addressid: defaultAddress.id }; var that = this ; util.http(url, param, function (ret) { if (ret.data.code == 1) { if (that.data.payment == 'balance' ) { // 余额支付 that.afterPaySuccess(ret.data.data); } else { // 微信支付 wx.requestPayment({ timeStamp: ret.data.data.timeStamp, nonceStr: ret.data.data.nonceStr, package: ret.data.data.package, signType: ret.data.data.signType, paySign: ret.data.data.paySign, 'success' : function (res) { that.afterPaySuccess(ret.data.data.orderid); }, 'fail' : function (res) { console.log(res); } }) } } else { util.showTip(ret.data.msg, '提交订单失败' ); } }); /** * 网络请求 */ function http(url, params, callback) { wx.request({ url: url, data: params, success: function (res) { callback(res); }, fail: function (err) { console.log(err); } }); } |
Step3: 接口代码:
|
public function pay() { $cart = I( 'cart' , '' , 'trim' ); $cartAmount = I( 'cartamount' ); $addressId = I( 'addressid' , 0, 'intval' ); $payment = I( 'payment' , '' , 'trim' ); $userId = $this ->userid; $cart = json_decode( $cart , true); if ( empty ( $cart )) { $result [ 'msg' ] = '购物车获取失败' ; $result [ 'code' ] = 0; $this ->ajaxReturn( $result ); } $totalMoney = 0; foreach ( $cart as $goods ) { $money = $goods [ 'price' ]; // price $selectCount = $goods [ 'selectcount' ]; // price $itemAmount = number_format( $money * $selectCount , 2, '.' , '' ); $totalMoney += $itemAmount ; } // 检查总金额是否一致 if ( $totalMoney != $cartAmount ) { $result [ 'msg' ] = '总金额不匹配:' . $totalMoney ; $result [ 'code' ] = 0; $this ->ajaxReturn( $result ); } // 获取用户地址 $address = M( 'MemberAddress' )->where( 'userid=' . $userId . " and id=" . $addressId )->find(); if ( empty ( $address )) { $result [ 'msg' ] = '用户地址不存在' ; $result [ 'code' ] = 0; $this ->ajaxReturn( $result ); } // 用户信息 $user = M( 'Member' )->where( "id=" . $userId )->find(); if ( $payment == 'balance' ) { if ( $user [ 'amount' ] < $cartAmount ) { $result [ 'msg' ] = '余额不足' ; $result [ 'code' ] = 0; $this ->ajaxReturn( $result ); } } // 生成订单 $order [ 'ordersn' ] = $this ->genOrdersn( $user [ 'id' ]); $order [ 'price' ] = $cartAmount ; $order [ 'addressid' ] = $address [ 'id' ]; $order [ 'addressinfo' ] = serialize( $address ); //json_encode($address); $order [ 'longitude' ] = $address [ 'longitude' ]; $order [ 'latitude' ] = $address [ 'latitude' ]; $order [ 'addtime' ] = time(); $order [ 'status' ] = 0; $order [ 'userid' ] = $user [ 'id' ]; $order [ 'paytype' ] = $payment ; $order [ 'paysn' ] = '' ; $order [ 'paytime' ] = time(); $orderId = M( "Order" )->add( $order ); if ( $orderId == 0) { $result [ 'msg' ] = '创建订单失败' ; $result [ 'code' ] = 0; $this ->ajaxReturn( $result ); } foreach ( $cart as $goods ) { $orderGoods [ 'orderid' ] = $orderId ; $orderGoods [ 'goodsid' ] = $goods [ 'id' ]; $orderGoods [ 'title' ] = $goods [ 'title' ]; $orderGoods [ 'price' ] = $goods [ 'price' ]; $orderGoods [ 'attr' ] = $goods [ 'attr' ]; $orderGoods [ 'pic' ] = $goods [ 'pic' ]; $orderGoods [ 'num' ] = $goods [ 'selectcount' ]; M( "OrderGoods" )->add( $orderGoods ); } if ( $payment == 'balance' ) { // 余额支付 $this ->balancePay( $cartAmount , $user [ 'wxopenid' ], $orderId ); } else if ( $payment == 'weixin' ) { // 微信支付 $this ->weixinPay( $cartAmount , $user [ 'wxopenid' ], $orderId , $order [ 'ordersn' ]); } } /** * 微信支付 * @author 大脸猫脸大 * @param $cart * @param $cartAmount * @param $address * @param $user */ private function weixinPay( $cartAmount , $openId , $orderId , $orderSn ) { import( "Vendor.Wxpay.lib.WxPay#Api" , "" , ".php" ); //订单号 $money = $cartAmount * 100; $openid = $openId ; $input = new \WxPayUnifiedOrder(); $input ->SetBody( "迪克-商品" ); $input ->SetOut_trade_no( "$orderSn" ); $input ->SetTotal_fee( "$money" ); $input ->SetNotify_url( "https://" . $_SERVER [ 'HTTP_HOST' ] . "/api/buy/payNotify" ); $input ->SetTrade_type( "JSAPI" ); $input ->SetOpenid( $openid ); $unifiedOrder = \WxPayApi::unifiedOrder( $input ); if ( $unifiedOrder [ 'result_code' ] == 'SUCCESS' && $unifiedOrder [ 'return_code' ] == 'SUCCESS' ) { $time = time(); $data [ 'timeStamp' ] = "$time" ; //时间戳 $data [ 'nonceStr' ] = $unifiedOrder [ 'nonce_str' ]; //随机字符串 $data [ 'signType' ] = 'MD5' ; //签名算法,暂支持 MD5 $data [ 'package' ] = 'prepay_id=' . $unifiedOrder [ 'prepay_id' ]; //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* $data [ 'paySign' ] = $this ->genPaySign( $unifiedOrder , $time ); // 之前以为是$unifiedOrder['sign']; 后来发现是调用的这种方法. 签名方案参见微信公众号支付帮助文档; $data [ 'out_trade_no' ] = $orderSn ; $data [ 'orderid' ] = $orderId ; $return [ 'code' ] = 1; $return [ 'data' ] = $data ; } else { Log::write(var_export( $unifiedOrder , true), Log::ERR, '' , C( 'LOG_PATH' ). "wx_pay_" . date ( 'y_m_d' ). '.log' ); $return [ 'code' ] = 0; $return [ 'msg' ] = '微信支付失败' ; // $unifiedOrder['RETURN_MSG']; } $this ->ajaxReturn( $return ); } /* 生成支付签名*/ private function genPaySign( $unifiedOrder , $time ) { $appId = \WxPayConfig::APPID; $nonceStr = $unifiedOrder [ 'nonce_str' ]; $package = 'prepay_id=' . $unifiedOrder [ 'prepay_id' ]; $signType = "MD5" ; $timeStamp = $time ; $key = \WxPayConfig::KEY; $sign = md5(sprintf( "appId=%s&nonceStr=%s&package=%s&signType=%s&timeStamp=%s&key=%s" , $appId , $nonceStr , $package , $signType , $timeStamp , $key )); return $sign ; } /** * 支付回调 * @author:大脸猫脸大 */ public function payNotify() { import( "Vendor.Wxpay.lib.WxPay#Data" , "" , ".php" ); $xml = $GLOBALS [ 'HTTP_RAW_POST_DATA' ]; $val = \WxPayResults::Init( $xml ); if ( $val [ 'result_code' ] == 'SUCCESS' && $val [ 'return_code' ] == 'SUCCESS' ) { $orderSn = $val [ 'out_trade_no' ]; $transactionId = $val [ 'transaction_id' ]; $data = array ( 'paytype' => 'weixin' , 'status' => '1' , 'paytime' => time(), 'paysn' => $transactionId ); M( "Order" )->where( "ordersn='$orderSn'" )->setField( $data ); exit ( '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>' ); } else { Log::write(var_export( $val , true), Log::ERR, '' , C( 'LOG_PATH' ). "wx_pay_notify_" . date ( 'y_m_d' ). '.log' ); exit ( '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>' ); } } |
payNotify 回调方法里一定要注意返回
<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>
如果不处理,你会发现payNotify 会被执行很多次参见:官方文档
总结一下: 注意二点, 1.签名的问题 2. 回调方法的返回处理。
欢迎大家指正。
希望本文所述对大家PHP程序设计有所帮助。
您可能感兴趣
- php中怎么分割数组(PHP实现数组根据某个字段进行水平合并,横向合并案例分析)
- php小例子(PHP反射实际应用示例)
- php设置上传文件代码(PHP大文件切割上传并带进度条功能示例)
- php返回数组值最大的键(PHP实现通过二维数组键值获取一维键名操作示例)
- thinkphp5.1请求流程(ThinkPHP5.0框架使用build 自动生成模块操作示例)
- php类的属性和方法(PHP进阶学习之反射基本概念与用法分析)
- phpsession登录功能(php实现session共享的实例方法)
- dedecms验证码识别(dedecms 软件下载频道防盗链php代码)
- linux中ceph的状态(Wdcp linux控制面板配置多PHP版本记录)
- phpstudyv8.0部署多站点(phpstudy v8.1 全站301重定向设置教程)
- php怎么设置静态成员函数(php输出控制函数和输出函数生成静态页面)
- php入门基本笔记(PHP之认识二关于Traits的用法详解)
- php array只能放一种类型的数据(浅谈PHP array_search 和 in_array 函数效率问题)
- dedecms注册怎么给权限(织梦DedeCms系统未审核文档禁止动态浏览修改方法view.php)
- thinkphp5设计权限(Thinkphp5.0 框架视图view的比较标签用法分析)
- phpstudy中apache到期如何修改(phpStudy找不到Apache“服务名” 解决方法)
- ()
- 对你思念入骨的女人,跟你见面时会有这几种表现,藏都藏不住(对你思念入骨的女人)
- 纳兰性德绝美作,一场重逢,成就最后一首称得上惊艳的《如梦令》(纳兰性德绝美作)
- 如何快速赚钱(如何快速赚钱方法真实有效)
- 这里输入关键词(如何输入关键词)
- 熊猫中国国宝(熊猫国宝酒53酱香)
热门推荐
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9