PHP applet payment function full version [based on ThinkPHP]

Time:2020-5-22

This article describes the PHP applet payment function. To share with you for your reference, as follows:

Environment: tp3.2 + app wechat payment function opening

Step1:  Download PHP payment SDK (download address) and put it under library \ vendor, named wxpay

modify WxPay.Config.php Appid appsecret key mchid in

Step2:Applet JS code:

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' {// balance payment
      that.afterPaySuccess(ret.data.data);
    }Else {// wechat payment
      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 , 'failed to submit order');
  }
});
/**
 *Network request
 */
function http(url, params, callback) {
  wx.request({
    url: url,
    data: params,
    success: function (res) {
      callback(res);
    },
    fail: function (err) {
      console.log(err);
    }
  });
}

Step3: Interface code:

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 '] =' failed to get shopping cart ';
      $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;
    }
    //Check whether the total amount is consistent
    if ($totalMoney != $cartAmount) {
      $result ['msg '] =' total amount mismatch: '. $totalmoney;
      $result['code'] = 0;
      $this->ajaxReturn($result);
    }
    //Get user address
    $address = M('MemberAddress')->where('userid=' . $userId . " andid=" . $userId)->find();
    if ($payment == 'balance') {
      if ($user['amount'] < $cartAmount) {
        $result ['msg '] =' insufficient balance ';
        $result['code'] = 0;
        $this->ajaxReturn($result);
      }
    }
    //Generate order
    $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 '] =' failed to create order ';
      $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') {
      //Balance payment
      $this->balancePay($cartAmount, $user['wxopenid'], $orderId);
    } else if ($payment == 'weixin') {
      //Wechat payment
      $this->weixinPay($cartAmount, $user['wxopenid'], $orderId, $order['ordersn']);
    }
}
/**
*Wechat payment
*@ author big face
* @param $cart
* @param $cartAmount
* @param $address
* @param $user
*/
private function weixinPay($cartAmount, $openId, $orderId, $orderSn)
{
    import("Vendor.Wxpay.lib.WxPay#Api", "", ".php");
    //Order No
    $money = $cartAmount * 100;
    $openid = $openId;
    $input = new \WxPayUnifiedOrder();
    $input - > setbody ("Dick merchandise");
    $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"; // timestamp
      $data['nonceStr'] = $unifiedOrder['nonce_ STR ']; // random string
      $data ['signtype '] ='md5'; // signature algorithm, MD5 is supported temporarily
      $data['package'] = 'prepay_ id=' . $unifiedOrder['prepay_ ID ']; // prepay returned from the unified order interface_ The ID parameter value. The submission format is as follows: prepay_ id=*
      $data['paySign'] = $this->genPaySign ($unifiedOrder, $time); // formerly thought $unifiedOrder['sign']; later found to be the method of calling. The signature scheme is referred to WeChat official account for payment assistance document;
      $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 '] =' wechat payment failed '; // $unifiedorder ['return_ MSG'];
    }
    $this->ajaxReturn($return);
}
/*Generate payment signature*/
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;
}
/**
*Payment callback
*@ Author: big face
*/
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>');
    }
}

Pay attention to return in paynotify callback method

<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>

If not, you will find that paynotify will be executed many times. See official documents

To sum up: pay attention to two points, 1. Signature problem 2. Callback method return processing.

Welcome to correct.

For more information about PHP, readers who are interested in PHP, please refer to the following topics: summary of PHP wechat development skills, summary of PHP curl usage, summary of PHP network programming skills, summary of PHP string usage, summary of JSON format data operation skills in PHP and summary of PHP operation skills for XML files

I hope this article is helpful for PHP programming.

Recommended Today

Python basics Chinese series tutorial · translation completed

Original: Python basics Python tutorial Protocol: CC by-nc-sa 4.0 Welcome anyone to participate and improve: a person can go very fast, but a group of people can go further. Online reading Apache CN learning resources catalog introduce Seven reasons to learn Python Why Python is great Learn Python introduction Executing Python scripts variable character string […]