微信小程序------微信支付模块

时间:2024-02-23 20:30:02

最近项目涉及到小程序开发:需要进行微信支付模块,接下来通过叙述,记录一下微信小程序中微信支付模块的开发,以便日后翻阅和使用。

学习指南----------微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_11&index=2

1、在开发小程序微信支付之前,首先需要申请账号,注册一个小程序开发者账号,并进行微信认证。

2、小程序开通微信支付

获取到appid(小程序ID)、AppSecret 、MchID(商户ID)、API Key

小程序支付交互图

 

商户系统和微信支付系统主要交互:

1、小程序登录接口、获取openid(小程序登录)

2、商户端调用支付统一下单接口,返回预付单信息(统一下单)

3、小程序端显示二维码,客户扫码支付,小程序端鉴权调起支付,返回支付结果到小程序端(再次签名)

4、推送支付结果到小程序端(支付结果通知API)

5、商户查询支付结果(查询订单API)

 

注意点:

1、签名 需要对所有非空参数按照参数名ASSIC字典序排序,拼接API密钥MD5加密后转大写。

2、需要将所有参数转xml形式,使用curl发起请求。再将获取到的返回值从xml形式转化为数组进行取值。 注意返回参数都是大写。

 

以下几个通用函数方法:

	/**
	 * 签名算法
	 * 1、对参数按照key=value的格式,并按照参数名ASCII字典序排序
	 * ◆ 参数名ASCII码从小到大排序(字典序);
		◆ 如果参数的值为空不参与签名;
		◆ 参数名区分大小写;
		◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
		◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
	 *2、 拼接上key,MD5加密,并将字符串全部转成大写,拼接API密钥
	 * 
	 * @param unknown $post
	 */
	function getSign($post){
		$stringA = \'\';
		ksort($post);//key值排序 参数名ASCII码从小到大排序(字典序)
		foreach ($post as $key=>$value){
			if(!$value)continue;
			if(!$stringA){
				$stringA= $key."=".$value;
			}else{
				$stringA.= "&".$key."=".$value;
			}
		}
		$stringA.=\'&key=\'.$APIKey;
		$sign = strtoupper(md5($stringA));
		return $sign;
	}

 

    /**
     * 随机的32位字符串
     * @param unknown $len
     */
    private function getNonceStr($len){
        $a=range(\'a\',\'z\');
        $b=range(\'A\',\'Z\');
        $c=range(\'0\',\'9\');
        $chars=array_merge($a,$b,$c);
        $charslen=count($chars)-1;
        shuffle($chars);
        $nonce_str=\'\';
        for($i=0;$i<$len;$i++){
            $nonce_str.=$chars[mt_rand(0,$charslen)];
        }
        return $nonce_str;
    }

 

  

 

    /**
	 * curl请求
	 * @param unknown $url
	 * @param unknown $data
	 * @param array $headers
	 */
	private function http_request($url,$data = null,$headers=array()) {
		$curl = curl_init();
		if( count($headers) >= 1 ){
			curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		}
		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, 1);
			curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
		}
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$output = curl_exec($curl);
		curl_close($curl);
		return $output;
	}

  

private function getIP(){
		if(!empty($_SERVER[\'HTTP_CDN_SRC_IP\'])){
			$ip = $_SERVER[\'HTTP_CDN_SRC_IP\'];
	
		}else if (getenv(\'HTTP_CLIENT_IP\')){
			$ip = getenv(\'HTTP_CLIENT_IP\');
	
		}else if (getenv(\'HTTP_X_FORWARDED_FOR\')){ //获取客户端用代理服务器访问时的真实ip 地址
			$ip = getenv(\'HTTP_X_FORWARDED_FOR\');
	
		}else if (getenv(\'HTTP_X_FORWARDED\')){
			$ip = getenv(\'HTTP_X_FORWARDED\');
	
		}else if (getenv(\'HTTP_FORWARDED_FOR\')){
			$ip = getenv(\'HTTP_FORWARDED_FOR\');
	
		}else if (getenv(\'HTTP_FORWARDED\')){
			$ip = getenv(\'HTTP_FORWARDED\');
	
		}else{
			$ip = $_SERVER[\'REMOTE_ADDR\'];
		}
		return $ip;
	}