支付--微信公众号

xiaoxiao2021-02-28  159

公众号支付的接口文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

先写好必要的方法:

    const API_UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";     const API_ORDER_QUERY   = "https://api.mch.weixin.qq.com/pay/orderquery";     const API_CLOSE_ORDER   = "https://api.mch.weixin.qq.com/pay/closeorder";

    //签名算法

    public static  function getSign($param, $appKey){         $param = array_filter($param);         ksort($param);         $stringA = "";         foreach ($param as $key=>$value){             if (!empty($value)){//值为空则不参与签名                 $stringA .= $key."=".$value."&";             }         }         $stringSignTemp = $stringA. "key=" .$appKey;         return strtoupper(md5($stringSignTemp));     }

    //生成随机数     public static  function getNonceStr(){         $nonce_str = '';         $max    = mt_rand(16,32);         $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";         for ( $i = 0; $i < $max; $i++ ) {             $nonce_str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);         }         return $nonce_str;     }

    //数组转XML     public static function arrayToXml($arr)     {         $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;     }

    //XML转数组     public static function xmlToArray($xml)     {         //禁止引用外部xml实体         libxml_disable_entity_loader(true);         $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);         return $values;     }

    public static function curlPost($url, $postData) {         $ch = curl_init();         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);    // https请求 不验证证书和hosts         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);         curl_setopt($ch, CURLOPT_URL, $url);         curl_setopt($ch, CURLOPT_POST, 1);         curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         $res = curl_exec($ch);         curl_close($ch);         return $res;     }

    调用统一下单接口:

    public function prePay($body,$userIp,$orderNo, $price, $userOpenId){         $postData = [             "appid"     => self::APPID,             "mch_id"     => self::MCHID,             "nonce_str" => self::getNonceStr(),             "body"       => $body,             "out_trade_no"   => $orderNo,             "total_fee"     => (int)($price*100),//微信以分为单位             "spbill_create_ip"   => $userIp,             "notify_url"         => self::notify_url,             "trade_type"         => "JSAPI",             "openid"             => $userOpenId,         ];         $postData["sign"] = self::getSign($postData, self::APPKEY);         $postData = Func::arrayToXml($postData);         $response = Func::xmlToArray(Func::curlPost(self::API_UNIFIED_ORDER, $postData));         if (isset($response["return_code"]) && $response["return_code"] == "SUCCESS"){             if ($response["result_code"] == "SUCCESS"){                 $package = "prepay_id=".$response["prepay_id"];                 $res = [                     "appId"     => self::APPID,                     "timeStamp" => (string)time(),                     "nonceStr"   => self::getNonceStr(),                     "package"   => $package,                     "signType"   => "MD5"                 ];                 $res["paySign"] = self::getSign($res, self::APPKEY);                 return $res;//调起支付所需参数             }         }         return [];     }

    /*      * 接收异步通知,处理订单      * */     public function endOrder($param){         if (isset($param["return_code"]) && $param["return_code"] == "SUCCESS" && $param["result_code"] == "SUCCESS"){             $resSign = $param["sign"];             unset($param["sign"]);             $orderInfo = "订单信息";             if (empty($orderInfo) || $param["total_fee"] != $orderInfo["price"]*100){                 return false;             }             $sign = self::getSign($param, self::APPKEY);             if ($sign != $resSign){                 return false;//签名失败             }             if ($param["appid"] != self::APPID){                 return false;             }             if ($param["mch_id"] != self::MCHID){                 return false;             }             if (1 == $orderInfo["pay_status"]){                 return true;             }else{ //TODO 处理订单                 return true;             }         }         return false;     }

    /*      * 向微信发起订单查询      * */     public function queryOrder($orderNO)     {         $nonce_str = self::getNonceStr();         $params = [             "appid" => self::APPID,             "mch_id" => self::MCHID,             "out_trade_no" => $orderNO,             "nonce_str" => $nonce_str         ];         $params["sign"] = self::getSign($params, self::APPKEY);         $params = Func::arrayToXml($params);         $response = Func::xmlToArray(Func::curlPost(self::API_ORDER_QUERY, $params));         if (isset($response["return_code"]) && $response["return_code"] == "SUCCESS") {             if ($response["result_code"] == "SUCCESS" && $response["trade_state"] == "SUCCESS"){                 return true;             }         }         return false;     }

    /*      * 关闭支付订单      * */     public function closeOrder($orderNo){         $nonce_str = self::getNonceStr();         $params = [             "appid" => self::APPID,             "mch_id" => self::MCHID,             "out_trade_no" => $orderNO,             "nonce_str" => $nonce_str         ];

        $params["sign"] = self::getSign($params, self::APPKEY);         $params = Func::arrayToXml($params);         $response = Func::xmlToArray(Func::curlPost(self::API_CLOSE_ORDER, $params));         if (isset($response["return_code"]) && $response["return_code"] == "SUCCESS") {             $res_sign = $response["sign"];//返回的签名             unset($response["sign"]);             $gen_sign = self::getSign($response, self::APPKEY);             if ($res_sign != $gen_sign){                 return false;             }             if ($response["appid"] != self::APPID || $response["mch_id"] != self::MCH_ID ){                 return false;             }             if ($response["result_code"] == "SUCCESS"){                 return true;             }         }         return false;     }

商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。

注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。调用关单或撤销接口API之前,需确认支付状态。

接收异步通知时要注意:

        $param = file_get_contents("php://input");         $param = Func::xmlToArray($param);

转载请注明原文地址: https://www.6miu.com/read-23490.html

最新回复(0)