收藏
回答

php微信支付,接口签名校验工具校验通过,但请求接口提示签名错误,已贴源码,帮看看怎么解决(急)

大神帮忙看下是哪里错了,要怎么修复(急)!谢谢

请求结果(上边是发送的XML源原串,下方是返回结果),php代码在下方。

我把上方输出的XML源串拿去“支付接口签名校验工具”中测试,测试结果是“校验通过

php代码

调用页面(做了自动加载):

Pay::createOrder(1,1);


pay类部分代码如下:

<meta charset="utf-8">
<?php
class Pay{
	public static $appid="wx4********";
	protected static $secret="9d324e********18";
	
	public static $mch_id="*********";//商户号
	public static $api_key="a************";//APIkey
	
	protected static $siteurl="https://*************/wechat";//回执域名
	
	public static function createOrder($aid,$amount,$billno=''){
		date_default_timezone_set("PRC");
		$url="https://api.mch.weixin.qq.com/pay/unifiedorder";
		$data=self::getTem($aid,$amount,$billno);
		$result=self::httpRequest($url,$data);
		$re1 = simplexml_load_string($result,'SimpleXMLElement',LIBXML_NOCDATA);
		$re2 = json_encode($re1);
		$result2 = json_decode($re2,true);
		echo htmlspecialchars($data);
		echo "<br/>";
		print_r($result2);
		//return $result2;
	}
	
	public static function getTem($aid,$amount,$billno){
		$data = self::getSign($aid,$amount,$billno);
		$str="<xml>";
		foreach($data as $key => $value){
			if(is_numeric($value)){
				$str.="<".$key.">".$value."</".$key.">";
			} else {
				$str.="<".$key."><![CDATA[".$value."]]></".$key.">";
			}
		}
		$str.="</xml>";
		return $str;
	}
	
	public static function getSign($aid,$amount,$billno){
		$data=array();
		$data['appid'] = self::$appid;//应用ID
		$data['body'] = "付费文档获取-支付";//商品描述
		$data['mch_id'] = self::$mch_id;//直连商户号
		$data['nonce_str'] = self::getStr(12);//随机字符串
		$data['notify_url'] = self::$siteurl ."/info.php";//通知地址
		$data['out_trade_no'] = $billno==''?time().rand(10000,99999):$billno;//商户订单号
		$data['trade_type'] = "NATIVE";//交易类型
		$data['total_fee'] = $amount;//标价金额
		$data['attach']= $aid;//
		
		ksort($data);
		$str = self::getString($data);
		$str .= "key=". self::$api_key;
		$sign = strtoupper(MD5($str));
		$data['sign'] = $sign;//签名
		return $data;
	}
	
	public static function getString($data){
		$str="";
		foreach($data as $k=>$v){
			$str.=$k."=".$v."&";
		}
		return $str;
	}
	
	public static function getStr($number){//随机字符串$number长度
		$name=substr(md5(uniqid(microtime(true),true)),8,$number);
		return $name;
	}
	
	public static function httpRequest($url,$data=''){
		$curl = curl_init();
		curl_setopt($curl,CURLOPT_URL, $url);
		curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE);
		curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,FALSE);
		if(!empty($data)){
			curl_setopt($curl,CURLOPT_POST,TRUE);
			curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
		}
		curl_setopt($curl,CURLOPT_HEADER,FALSE);
		curl_setopt($curl,CURLOPT_RETURNTRANSFER,TRUE);
		$output = curl_exec($curl);
		curl_close($curl);
		return $output;
	}


	
}
最后一次编辑于  2021-08-26
回答关注问题邀请回答
收藏

3 个回答

  • 没有猫吃的鱼🐳
    没有猫吃的鱼🐳
    2021-08-26

    解决了,谢谢大家,是密钥问题,我使用了APIv3密钥,这里要用API密钥,两个密钥不一样

    2021-08-26
    有用 3
    回复 3
    • 九玖·
      九玖·
      2021-08-31
      哈哈 解决了就行
      2021-08-31
      回复
    • 大鱼
      大鱼
      2023-05-25
      请问API密钥是APIv2密钥吗?
      2023-05-25
      回复
    • 没有猫吃的鱼🐳
      没有猫吃的鱼🐳
      2023-09-08回复大鱼
      是的,用APIv2密钥
      2023-09-08
      回复
  • Memory
    Memory
    2021-08-26

    签名工具只校验签名的方式是否正确,不校验参数的正确性。先确认商户key是否有问题,可以通过请求获取沙箱key接口来验证,然后再比对文档参数,检查是否有多传、漏传、错误的参数

    2021-08-26
    有用 1
    回复 1
  • 九玖·
    九玖·
    2021-08-26

    请按照以下几点进行排查:

    1、使用签名检查工具(https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1)校验签名算法是否有误

    2、确认秘钥是否有误(服务商模式使用服务商商户号秘钥,秘钥是在商户平台配置,如果同一商户号调用其它接口成功可排除是秘钥问题)

    3、确认接口实际的请求参数与生成签名原串的参数一致,不能增加或缺少参数(可通过打印签名原串进行排查)

    4、确认参数的大小写,参数名与接口文档一致

    5、签名原串的参数值使用原始值,不需要encode

    6、接口需要使用UTF-8编码

    官方发言是这样的,咱也不懂这一块的内容,能帮到更好,多检查试试?

    2021-08-26
    有用 1
    回复 1
    • 没有猫吃的鱼🐳
      没有猫吃的鱼🐳
      2021-08-26
      1、校验通过
      2、秘钥正确,校验使用密钥也是通过的
      3、发送函数的串打印出来,通过了1中检验
      4、参数名应该没问题,我写错一个就会提示缺少某个参数
      5、没有进行encode
      6、是UTF-8编码
      我检查一遍,是这个样子,也可能个人原因会习惯性跳过某些忽略的问题,所以来求助了,求帮忙
      2021-08-26
      1
      回复
登录 后发表内容