微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

微信小程序基于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匹配

签名算法

PHP

/*

* 小程序微信支付

*/

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."&notify_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) . "

} else {

$xml .= "<" . $key . ">" . $val . "

}

}

$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;

}

}

以上就是我微信支付解决的过程,没有太大的坑,但是记录一下,免的以后自己再次遇到

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐