微信小程序

1.最近在搞小程序的支付后端,这里就聊一下这个签名

在和微信后端交互数据,服务端给微信服务器发数据,要添加签名,服务端在接受微信请求的时候,要验证签名,签名怎么算呢?

微信为每个小程序都生成了一个API秘钥key,这个key用来参与签名的,不要给客户端,不要给别人,不要在网络中传输,反正打死不能告诉别人,只能服务端和微信服务端知道(详情见:微信小程序开发文档)

假如:

    要传给微信后端的数据为: array $data , 
    API秘钥key为:$key 

    按着参数名ASCII码从小到大排序,参数的值为空不参与签名,参数名区分大小写,sign参数不参与签名的原则加密得sign,翻译为函数:


         /**
         * @param array $arr 要传输的数据
         * @param key 小程序API秘钥key
         * @return string 返回加密值 sign
         */
        public static function GetSign(array $arr, $key)
        {
            ksort($arr);
            $string = "";
            foreach ($arr as $key => $v) {
            if ($key == "sign") {
                continue;
            }
            $string .= $key . "=" . $v . "&";
        
            $string = rtrim($string, "&");
            $string = $string . "&key=" . $key;

            return strtoupper(md5($string));
        }

2.其他用到的函数

2.1 由于和微信传输数据,都是xml格式,需要把数组转换成xml字符串

/**
 * @param array $arr 要传输的数据
 * @return string 得到的xml
 */
public static function ToXml(array $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;
}

2.2 curl请求微信服务端

 /**
 * @param string $xml 需要提交的xml数据
 * @param string $url 提交的地址
 * @param int $second url 执行超时时间,默认30s
 */
public function postXmlCurl($xml, $url, $second = 30)
{
    //初始化curl
    $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);

    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    //运行curl
    $data = curl_exec($ch);
    //返回结果
    curl_close($ch);

    if ($data) {
        return $data;
    } else {
        return false;
    }

    return $data;
}

3.注意事项

3.1 每次接受数据都要验签

3.2 支付成功回调的时候,验签通过后,通过订单号,找到订单信息,要判断实付钱数和订单钱数一直不

3.3 回调的业务逻辑处理事,更改多张表要用到事务,确保不出岔子

3.4 与微信交互金额(total_fee)的单位为分,且Int类型,不能传小数 (ps: 在测试的时候,为了能少付点钱,传了0.01,一直报错,自己也没有看微信的报错信息,一直在其他地方找原因,坑到我了)

3.5 订单已完成要给微信返回success,不要让微信一直回调(频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒)

以上内容全部参考微信开发文档,加上自己的一些小总结,微信小程序开发文档 :https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=2