首页 > 编程语言 >php 微信支付V3API 签名生成

php 微信支付V3API 签名生成

时间:2022-09-27 13:56:07浏览次数:85  
标签:ch return string 微信 param timestamp curl php V3API

class Formatter
{
    /**
     * Generate a random BASE62 string aka `nonce`, similar as `random_bytes`.
     *
     * @param int $size - Nonce string length, default is 32.
     *
     * @return string - base62 random string.
     */
    public static function nonce(int $size = 32): string
    {
        if ($size < 1) {
            throw new Exception('Size must be a positive integer.');
        }
        return implode('', array_map(static function(string $c): string {
            return '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[ord($c) % 62];
        }, str_split(random_bytes($size))));
    }

    /**
     * Retrieve the current `Unix` timestamp.
     *
     * @return int - Epoch timestamp.
     */
    public static function timestamp(): int
    {
        return time();
    }

    /**
     * Formatting for the heading `Authorization` value.
     *
     * @param string $mchid - The merchant ID.
     * @param string $nonce - The Nonce string.
     * @param string $signature - The base64-encoded `Rsa::sign` ciphertext.
     * @param string $timestamp - The `Unix` timestamp.
     * @param string $serial - The serial number of the merchant public certification.
     *
     * @return string - The APIv3 Authorization `header` value
     */
    public static function authorization(string $mchid, string $nonce, string $signature, string $timestamp, string $serial): string
    {
        return sprintf(
            'WECHATPAY2-SHA256-RSA2048 mchid="%s",serial_no="%s",timestamp="%s",nonce_str="%s",signature="%s"',
            $mchid, $serial, $timestamp, $nonce, $signature
        );
    }

    /**
     * Formatting this `HTTP::request` for `Rsa::sign` input.
     *
     * @param string $method - The HTTP verb, must be the uppercase sting.
     * @param string $uri - Combined string with `URL::pathname` and `URL::search`.
     * @param string $timestamp - The `Unix` timestamp, should be the one used in `authorization`.
     * @param string $nonce - The `Nonce` string, should be the one used in `authorization`.
     * @param string $body - The playload string, HTTP `GET` should be an empty string.
     *
     * @return string - The content for `Rsa::sign`
     */
    public static function request(string $method, string $uri, string $timestamp, string $nonce, string $body = ''): string
    {
        return static::joinedByLineFeed($method, $uri, $timestamp, $nonce, $body);
    }

    /**
     * Formatting this `HTTP::response` for `Rsa::verify` input.
     *
     * @param string $timestamp - The `Unix` timestamp, should be the one from `response::headers[Wechatpay-Timestamp]`.
     * @param string $nonce - The `Nonce` string, should be the one from `response::headers[Wechatpay-Nonce]`.
     * @param string $body - The response payload string, HTTP status(`201`, `204`) should be an empty string.
     *
     * @return string - The content for `Rsa::verify`
     */
    public static function response(string $timestamp, string $nonce, string $body = ''): string
    {
        return static::joinedByLineFeed($timestamp, $nonce, $body);
    }

    /**
     * Joined this inputs by for `Line Feed`(LF) char.
     *
     * @param string|float|int|bool $pieces - The scalar variable(s).
     *
     * @return string - The joined string.
     */
    public static function joinedByLineFeed(...$pieces): string
    {
        return implode("\n", array_merge($pieces, ['']));
    }

    /**
     * Sort an array by key with `SORT_STRING` flag.
     *
     * @param array<string, string|int> $thing - The input array.
     *
     * @return array<string, string|int> - The sorted array.
     */
    public static function ksort(array $thing = []): array
    {
        ksort($thing, SORT_STRING);

        return $thing;
    }

    /**
     * Like `queryString` does but without the `sign` and `empty value` entities.
     *
     * @param array<string, string|int|null> $thing - The input array.
     *
     * @return string - The `key=value` pair string whose joined by `&` char.
     */
    public static function queryStringLike(array $thing = []): string
    {
        $data = [];

        foreach ($thing as $key => $value) {
            if ($key === 'sign' || is_null($value) || $value === '') {
                continue;
            }
            $data[] = implode('=', [$key, $value]);
        }

        return implode('&', $data);
    }
    public static function curlPostWithWx($params,$authorization,$url)
    {
        $paramsString = json_encode($params);
        // 初始化curl
        $ch = curl_init();
        // 设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $paramsString);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($paramsString),
                'Authorization: ' . "WECHATPAY2-SHA256-RSA2048 " . $authorization,
                'Accept: application/json',
                'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
            )
        );
        // 运行curl,结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        // 取出数据
        $data = json_decode($res, true);
        return $data;
    }

    /**
     * get请求
     * @param $url
     * @param $authorization
     * @return mixed
     */
    public static function curlGetWithWx($url, $authorization,$params=[])
    {
        $paramsString = json_encode($params);
        // 初始化curl
        $ch = curl_init();
        // 设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($paramsString),
                'Authorization: ' . "WECHATPAY2-SHA256-RSA2048 " . $authorization,
                'Accept: application/json',
                'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36'
            )
        );
        // 运行curl,结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        // 取出数据
        $data = json_decode($res, true);
        //返回
        return $data;
    }
    public static function getAuthorization($url, $body,$mch_id, $priKey, $serial, $http_method = "POST")
    {
        // Authorization: <schema> <token>
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $timestamp = static::timestamp();
        $nonce = static::nonce();
        $message = static::request($http_method, $canonical_url, $timestamp, $nonce, json_encode($body));
        openssl_sign($message, $raw_sign, $priKey, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign);
        return static::authorization($mch_id, $nonce, $sign, $timestamp, $serial);
    }

首先,把以上工具类,保存到自己项目中。(方法改源于微信官方建议 github sdk,点击可前往)调用方法如下:

$mch_id = '1630****';//商户号
$priKey = '';//私钥文本
$serial = '';//证书序号
$queryUrl = 'https://api.mch.weixin.qq.com/v3/bill/tradebill';//账单接口
$param = ['bill_date'=>'2022-09-01','sub_mchid'=>$mch_id,'bill_type'=>'ALL','tar_type'=>'GZIP'];
$authorization = Formatter::getAuthorization($queryUrl, $param, $mch_id, $priKey, $serial);//生成签名
$result = Formatter::curlGetWithWx($param, $authorization, $queryUrl);//接口请求
var_dump($result);

证书序号和私钥文本内容,是必须的。建议先仔细阅读官方文档。

https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml

 

标签:ch,return,string,微信,param,timestamp,curl,php,V3API
From: https://www.cnblogs.com/itbaby/p/16734311.html

相关文章

  • ubuntu的apt源更新后只能装php8新版本,无法安装php7老版本了
    新电脑更新apt源以后,发现新装的都是php8.1,而且apt源update后,search也找不到php7了。于是找到了这篇文章然后按照他说的做sudoapt-getupdatesudoapt-yinstallsof......
  • 微信小程序入门介绍
    1.创建小程序项目1.申请小程序开发账号2.安装小程序开发者工具3.创建和配置小程序项目1.1注册访问https://mp.weixin.qq.com/网址,点击立即注册,选择小程序,填写......
  • 微信小程序实现与登录
    一、小程序的实现原理在小程序中,渲染层和逻辑层是分开的,双线程同时运行,渲染层和逻辑层这两个通信主体之间的通讯以及通讯主体与第三方服务器之间的通信,都是通过微信客户......
  • jquery实现点击复制微信号并自动打开微信加好友​
    近期,有建网站客户要求实现在自己的手机网站上实现点击复制微信号并自动打开微信加好友的功能。怎么在自己建网站时,制作出这样的点击复制微信号并自动打开微信加好友功能呢?......
  • 微信小程序路由跳转
    小程序路由跳转官网链接一、声明式导航在页面上声明一个<navigator>导航组件通过点击<navigator>组件实现页面跳转1.导航到tabBar页面tabBar页面指的是被配置为......
  • Swift h5 调起微信支付 并返回APP
    参考简书:https://www.jianshu.com/p/2d2237ad16d6第一步先配置URLtypes(在微信操作完成以后回到原APP)第二步直接上代码,然后再解释funcwebView(_webView:WKWebView,......
  • 微信小程序生命周期
    一、生命周期1.应用的生命周期概念:特指小程序从启动-->运行-->销毁的过程。在app.js中进行声明。常见的应用生命周期函数://app.js文件App({//小程序初始......
  • 微信小程序专题(一)-----微信后台的相关开发
    本人最近在做微信小程序后端的相关开发工作接触到微信小程序目前来讲需要两个条件1.前端通过后台服务器去调用微信平台接口,来获取openid;2.前端必须调用https跟域名......
  • 微信小程序专题(二)-----微信openid的获取
    一,简单来讲就是以下流程 通过get方式获取信息在前端调用wx.login()获取临时登录凭证code之后,将code字符串发送给后端,后端通过auth.code2Session接口获取用户唯一......
  • HBuilderX配置微信开发者工具后,微信开发者工具显示Fail to open IDE
     问题微信开发者工具地址配置正确,且端口也开启了,但是显示打开微信ide失败。   原因manifest.json中有微信小程序AppID,但未在微信开发平台将我的微信号加......