php实现小程序支付完整版

本文实例为大家分享了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));
}
 /**
   * 支付回调
   * @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. 回调方法的返回处理。

欢迎大家指正。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解PHP实现支付宝小程序用户授权的工具类

    背景 最近项目需要上线支付宝小程序,同时需要走用户的授权流程完成用户信息的存储,以前做过微信小程序的开发,本以为实现授权的过程是很简单的事情,但是再实现的过程中还是遇到了不少的坑,因此记录一下实现的过程 学到的知识 支付宝开放接口的调用模式以及实现方式 支付宝小程序授权的流程 RSA加密方式 吐槽点 支付宝小程序的入口隐藏的很深,没有微信小程序那么直接了当 支付宝小程序的开发者工具比较难用,编译时候比较卡,性能有很大的问题 每提交一次代码,支付宝小程序的体验码都要进行更换,比较繁琐,而且loca

  • PHP:微信小程序 微信支付服务端集成实例详解及源码下载

    微信小程序 微信支付服务端集 理论上集成微信支付的全部工作可以在小程序端完成,因为小程序js有访问网络的能力,但是为了安全,不暴露敏感key,而且可以使用官方提供的现成php demo更省力,于是在服务端完成签名与发起请求,小程序端只做一个wx.requestPayment(OBJECT)接口的对接. 整体集成过程与JSAPI.APP类似,先统一下单,然后拿返回的结果来请求支付. 一共三步: 1.小程序端通过wx.login的返回的code换取openid 2.服务端向微信统一下单 3.小程序端

  • 微信小程序调用PHP后台接口 解析纯html文本

    微信小程序调用PHP后台接口,解析纯html文本,效果图片预览 1.微信js动态传参: wx.request({ url: 'https://m.****.com/index.php/Home/Xiaoxxf/activity_detail?a_id='+options.id,//含富文本html data: { is_detail:1 }, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT heade

  • 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 =

  • 微信小程序 支付功能实现PHP实例详解

    微信小程序 支付功能实现PHP实例详解 前端代码: wx.request({ url: 'https://www.yourhost.com/weixin/WeiActivity/payJoinfee',//改成你自己的链接 header: { 'Content-Type': 'application/x-www-form-urlencoded' }, method:'POST', success: function(res) { console.log(res.data); console.lo

  • 微信小程序request请求后台接口php的实例详解

    微信小程序request请求后台接口php的实例详解 后台php接口:http://www.vueyun.com/good/info 没有处理数据,直接返回了,具体再根据返回格式处理 public function getGoodInfo(Request $request) { $goods_datas = $this->Resource->get(); return response()->json(['status' => 'success','code' => 200,

  • 微信小程序支付功能 php后台对接完整代码分享

    微信小程序支付,php后台对接完整代码,全是干货呀,拿过来可以直接使用.小程序在调起微信支付之前需要5个参数,这时候就需要携带code向后台请求,然后后台根据code获取openid 再进行服务器之间的. 一.准备工作 1.小程序注册,要以公司的以身份去注册一个小程序,才有微信支付权限: 2.绑定商户号. 3.在小程序填写合法域  二.完成以上条件,你可以得到      小程序appid 小程序秘钥    这两个用于获取用户openid: 商户号id ,商户号秘钥     支付接口必须的: 三.

  • 微信小程序与php 实现微信支付的简单实例

    微信小程序与php 实现微信支付的简单实例 小程序访问地址: payfee.PHP: include 'WeixinPay.php'; $appid=''; $openid= $_GET['id']; $mch_id=''; $key=''; $out_trade_no = $mch_id. time(); $total_fee = $_GET['fee']; if(empty($total_fee)) //押金 { $body = "充值押金"; $total_fee = float

  • 微信小程序支付PHP代码

    本文实例为大家分享了微信小程序支付PHP具体代码,供大家参考,具体内容如下 服务器端获取 openid Getopenid.php <?php header('Content-type: application/json; charset=UTF-8'); $APPID="";//填写小程序appid $SECRET="";//填写小程序secret $JSCODE=""; if(isset($_GET['js_code'])){ $JSC

  • 微信小程序 PHP后端form表单提交实例详解

    微信小程序 PHP后端form表单 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了微信端,用小程序固定的格式前前端进行布局.事件触发和数据的输送和读取,服务器端可以用任何后端语言写,但是所有的数据都要以JSON的形式返回给小程序. 2.昨天写了登录注册.忘记密码功能,他们实质上都是一个表单提交操作.因此就拿注册功能来写这个例子. 3.目录图 js文件是逻辑控制,主要是它发送请求和接收数据, json 用于此页面局部 配置并且覆盖全局app.json配置, wxss用于

随机推荐