微信小程序基于PHP微信支付“签名错误”填坑
|
第一次写,主要给自己看,记录一下 利用微信开发者工具开发商城类微信小程序,开发微信支付必不可少,但微信支付api开发文档说明压根看不懂,自己摸索,运行报错找不到错误代码解决方法 先说说我的开发流程吧 小程序前端——小程序js网络请求php后台——后台接收小程序传回数据——微信支付官网下载sdk包——微信商户配置——sdk配置——签名验证获取prepay_id——传回前端调用微信支付api——完成 想要完成微信支付就必须获取由微信系统后台传回的prepay_id,就必须要生成正确的签名 微信官方文档说明 微信官方文档说明https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1 支付SDKhttps://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 做好一切准备,前端后端配置要求都编写完毕,编译运行,签名错误,检查一遍,更改商户号,商户key,编译运行,签名错误,网上百度查各种方法总结一下 查看小程序appid,商户号,商户key,小程序密钥是否正确匹配 检查签名拼接是否按要求拼接,用签名验证工具验证一下https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1 修改商户key,原封不动的改一次 key设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置 检查商户是否对支付目录授权,必须授权才可以,然后商户对appid授权会生成一个商户号对应 我就是败在了第4点上,检查了一遍又一遍发现没有授权目录与appid,因为商户号是可变动的,一定要与appid匹配我就是败在了第4点上,检查了一遍又一遍发现没有授权目录与appid,因为商户号是可变动的,一定要与appid匹配 签名算法/* * 小程序微信支付 */ 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'; $jjc=$this->createNoncestr(); $parameters = array( 'appid' => $this->appid, 'body' => $this->body, 'mch_id' => $this->mch_id, 'nonce_str' => $jjc, 'notify_url' => 'https://*************/notify.php', 'openid' => $this->openid, 'out_trade_no'=> $this->out_trade_no, 'spbill_create_ip' => '*********',//授权目录的ip地址 'total_fee' => $this->total_fee, 'trade_type' => 'JSAPI' ); $t="appid=".$this->appid."&body=".$this->body."&mch_id=".$this->mch_id."&nonce_str=".$jjc."¬ify_url=https://*************/notify.php&openid=".$this->openid."&out_trade_no=".$this->out_trade_no."&spbill_create_ip=************&total_fee=".$this->total_fee."&trade_type=JSAPI"; $t=$t."&key=************************************"; $sign=strtoupper(md5($t)); $parameters['sign']=$sign; $xmlData = $this->arrayToXml($parameters); $return = $this->xmlToArray($this->postXmlCurl($xmlData,$url,60)); return $return; } private static function postXmlCurl($xml,$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); //严格校验 //设置header curl_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,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"); } } //数组转换成xml private function arrayToXml($arr) { $xml = " foreach ($arr as $key => $val) { if (is_array($val)) { $xml .= "<" . $key . ">" . arrayToXml($val) . "" . $key . ">"; } else { $xml .= "<" . $key . ">" . $val . "" . $key . ">"; } } $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); $jjc=$this->createNoncestr(); $parameters = array( 'appId' => $this->appid,//小程序ID 'nonceStr' => $jjc,//随机串 'package' => 'prepay_id=' . $unifiedorder['prepay_id'],//数据包 'signType' => 'MD5',//签名方式 'timeStamp' => '' . time() . '' //时间戳 ); //签名 $t="appId=".$this->appid."&nonceStr=".$jjc."&package=prepay_id=".$unifiedorder['prepay_id']."&signType=MD5&timeStamp=".time(); $t=$t."&key=*************************"; $sign=strtoupper(md5($t)); $parameters['paySign'] = $sign; 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,strlen($buff) - 1); } return $reqPar; } } 以上就是我微信支付解决的过程,没有太大的坑,但是记录一下,免的以后自己再次遇到 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
