PHP解读微信请求加密,微信支付实例

Posted 哈尔滨洛弘科技有限公司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP解读微信请求加密,微信支付实例相关的知识,希望对你有一定的参考价值。

php解读微信请求加密微信支付实例

  • 微信统一下单接口(以微信公众号支付为例)

接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder

微信支付接口文档

开发之前先完成微信支付配置

在上面完成你的微信配置获取到微信 mch_id以及授权你的支付授权域名,全部配置好就可以开始微信支付的

微信支付密钥key申请位置

我们先来了解些微信请求加密方式
一般采用两种 MD5SHA256

生成微信签名的方法
    /**
     * 生成微信签名
     * @param $options
     * @param string $type
     * @return string
     */
    protected static function MakeSign($data, $signType = 'MD5',$buff='')
    
        ksort($data);
        $mch_key='你的微信支付key';//在微信支付中申请
        if (isset($data['sign'])) unset($data['sign']);
        foreach ($data as $k => $v) $buff .= "$k=$v&";
        $buff .= ("key=" . self::get('mch_key'));
        if (strtoupper($signType) === 'MD5') 
            return strtoupper(md5($buff));
        
        return strtoupper(hash_hmac('SHA256', $buff, $mch_key));
    

其实此步操作就是将请求字段按照abcd排序方式排序后用&拼接然后统一加密,就可以获得加密字段

加密方法知道后我们就可以开启我们的支付请求了

支付请求参数,这里我只例举支付实例的实现,如果需要更多的业务逻辑,我们可以对照开发文档增加参数

	$param=[
	'appid'=>'微信公众号appid',
	'mch_id'=>'微信商户ID',
	'nonce_str'=>'随机三十二位字符,后面附了随机字符生成方法',
	'out_trade_no'=>'请求单号,后面附了唯一单号生成方法',
	'total_fee'=>'支付金额,单位为分,一般需要你需要支付的金额*100',
	'openid'=>'用户openid',
	'trade_type'=>'请求的支付场景,可以对照开发文档选择不同参数,这里我们用,JSAPI',
	'notify_url'=>'支付的回调链接,处理支付完成后的业务',
	'spbill_create_ip'=>'服务器请求ip',
	'sign'=>'前面我们谈到的加密字段,将上面的参数放入加密方法里可以生成sign'
	
	];

微信支付采用的数据格式为xml,返回数据也为xml,我们将此转为xml然后请求数据就可以了

curl post和get请求数据的方法
如此我们的支付请求就会成功了,将返回的参数按照文档打包发给前端即可

微信支付回调方法

  /**
     * 微信支付通知
     * @return array
     * @throws InvalidResponseException
     */
    public function notify()
    
        $data = xml2array(file_get_contents('php://input'));
        if (isset($data['sign']) && $this->getPaySign($data) === $data['sign']) 
           //处理相应的程序逻辑
        else
			return ['msg'=>'签名未通过'];

    
    /**
 	*数组转xml
     * @param $data /要转的数据
     * @return array|mixed|string
     * 转xml
     */
    public function toXml($data)
    
        $data_type = self::getDataType($data);
        if ($data_type == 'xml') return $data;
        $data = self::toArray($data);
        if (is_array($data)) 
            return "<xml>" . self::arr2xml($data) . "</xml>";
         else 
            $this->message = '数据格式不正确转换出错';
            return $data;
        
    
        /**xml转数组
     * @param $data /xml数据
     * @return mixed
     * xml转数组
     */
    public function xml2array($data)
    
        $entity = libxml_disable_entity_loader(true);
        $data = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
        libxml_disable_entity_loader($entity);
        return json_decode(self::toJson($data), true);
    

这里附随机32为字符生成方法,可以生成多种模式和长度的随机数

    public function create_number($length = 6, int $type = 1)
    
        $chars = [
            1 => '0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
            2 => '0123456789',
            3 => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []<>~`+=,.;:/?|',
            4 => 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        ];
        $str = '';
        for ($i = 0; $i < $length; $i++) 
            $str .= $chars[$type][mt_rand(0, strlen($chars[$type]) - 1)];
        
        return $str;
    

唯一单号生成方法,可带前缀

  /**
     * @param int $digits /单号位数
     * @param string $prefix /单号前缀
     * @return string
     * 创建随机单号
     */
    public function create_order_number($digits = 24, $prefix = '')
    
        $date = date('YmdHis');
        $digits = intval($digits);
        if ($digits < 14) return '随机单号大于14字符';
        $digits = $digits - strlen($date) - strlen($prefix);
        if ($digits < 0) return '随机单号生成失败';
        $rand = '';
        $num = floor($digits / 10);
        for ($i = 0; $i < $num; $i++) 
            $rand .= str_pad(mt_rand(1, (int)9999999999), 10, '0', STR_PAD_LEFT);
        
        if ($digits % 10 != 0) 
            $rand .= str_pad(mt_rand(1, (int)substr(9999999999, 0, $digits - ($num * 10))), $digits - ($num * 10), '0', STR_PAD_LEFT);
        
        $order_number = $prefix . $date . $rand;
        return $order_number;
    

微信支付其实很简单,让我们一起进步

以上是关于PHP解读微信请求加密,微信支付实例的主要内容,如果未能解决你的问题,请参考以下文章

微信内网页支付(微信 JSAPI 支付)的一点经验

微信支付错误:201 商户订单号重复

微信网页支付V3版js_api_call.php从订单跳转到微信支付提示缺少统一支付接口必填参数out_trade_no!

微信支付 jsapi接口怎么调

python实现微信扫码支付完整流程

php 处理微信账单