最近項目涉及到小程序開發:需要進行微信支付模塊,接下來通過敘述,記錄一下微信小程序中微信支付模塊的開發,以便日后翻閱和使用。
學習指南----------微信支付開發文檔: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;
}
