成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

支付開發(fā)填坑記之微信支付

zhunjiee / 3358人閱讀

摘要:前者集成在中,后者主要是為微信用戶提供了另一種支付方式需要在微信的內(nèi)置瀏覽器中打開頁(yè)面,再調(diào)起微信支付。步驟商戶后臺(tái)收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。拿到所有參數(shù)后,就可以在頁(yè)面中發(fā)起微信支付的請(qǐng)求了。

微信支付,支持的支付方式比較多:有掃碼支付,刷卡支付,APP支付和公眾號(hào)支付。其中,APP和網(wǎng)站上最常用的就是APP支付和公眾號(hào)支付。前者集成在APP中,后者主要是為微信用戶提供了另一種支付方式(需要在微信的內(nèi)置瀏覽器中打開頁(yè)面,再調(diào)起微信支付)。

同樣的,微信的APP支付和支付寶的APP支付也是很簡(jiǎn)單:

APP支付

商戶系統(tǒng)和微信支付系統(tǒng)主要交互說明:

步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。

步驟2:商戶后臺(tái)收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。參見【統(tǒng)一下單API】。

步驟3:統(tǒng)一下單接口返回正常的prepay_id,再按簽名規(guī)范重新生成簽名后,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appIdpartnerId,prepayId,nonceStrtimeStamp,package注意:package的值格式為Sign=WXPay

步驟4:商戶APP調(diào)起微信支付。

步驟5:商戶后臺(tái)接收支付通知。

步驟6:商戶后臺(tái)查詢支付結(jié)果。

這里主要的還是后臺(tái)干活(獲取 prepay_id,生成隨機(jī)字符串 nonceStr 和時(shí)間戳 timeStamp ,appIdpartnerId 均能在后臺(tái)管理中查看。)

后臺(tái)的步驟也很簡(jiǎn)潔,就是上述中的步驟1,2。

獲取 prepayId

設(shè)置獲取 prepayId 所需參數(shù)。

此處需要調(diào)用微信的統(tǒng)一下單接口。這個(gè)過程,官方文檔已經(jīng)寫得十分之詳細(xì)了,包括調(diào)用的接口API地址,需要傳遞的參數(shù)(必要和非必要的參數(shù)),還有返回結(jié)果也寫得很清楚。

以下是我在實(shí)際項(xiàng)目開發(fā)中傳入的參數(shù)。

簽名。

簽名都差不多,都是先將所有的帶簽名的參數(shù)進(jìn)行字典排序。

ksort($data);

然后將參數(shù)以 {key}={value} 的組合形式,用 & 連接。

$a = array();
foreach ($data as $k => $v) {
    if ((string) $v === "") {
        continue;
    }
    $a[] = "{$k}={$v}";
}

$a = implode("&", $a);

最后拼上 &key={Your apiKey} ,然后對(duì)整串字符串進(jìn)行MD5加密即可。

$sign = strtoupper(md5($a));

將拼好的數(shù)據(jù),以 XML 的格式發(fā)送給微信,請(qǐng)求 prepayId

沒錯(cuò),就是要轉(zhuǎn)成 XML 格式再發(fā)送。

但是,這個(gè)XML格式很簡(jiǎn)單,只需要進(jìn)行簡(jiǎn)單的拼接即可:

public function arrayToXml(array $data)
{
    $xml = "";
    foreach ($data as $k => $v) {
        if (is_numeric($v)) {
            $xml .= "<{$k}>{$v}";
        } else {
            $xml .= "<{$k}>";
        }
    }
    $xml .= "";
    return $xml;
}

參數(shù)值用XML轉(zhuǎn)義即可,CDATA標(biāo)簽用于說明數(shù)據(jù)不被XML解析器解析。。

然后請(qǐng)求統(tǒng)一下單API即可(url = https://api.mch.weixin.qq.com/pay/unifiedorder

$ch = curl_init();
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
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_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$response = curl_exec($ch);
if (!$response) {
    throw new Exception("CURL Error: " . curl_errno($ch));
}
curl_close($ch);

請(qǐng)求回來的數(shù)據(jù)也為XML格式,只需要簡(jiǎn)單做下處理,轉(zhuǎn)換成array即可:

public function xmlToArray($xml){
    return json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true);
}

如果返回值中的 return_coderesult_code 都為 SUCCESS 的時(shí)候會(huì)返回 交易類型 trade_type 和 預(yù)支付交易會(huì)話標(biāo)識(shí) prepayId 。到這里,我們就可以獲取到 prepayId

將獲取的 prepayId 與其他參數(shù)拼接,返回給APP即可。

$params = array();
//  商戶號(hào)
$params["appid"] = $this->config->appId;
//  時(shí)間戳
$params["timestamp"] = "" . time();
//  隨機(jī)字符串
$params["noncestr"] = md5(uniqid(mt_rand(), true));
//  固定為 "Sign=WXPay"
$params["package"] = "Sign=WXPay";
//  步驟3獲取的預(yù)支付交易會(huì)話標(biāo)識(shí)
$params["prepayid"] = $prepayId;
//  合作伙伴id
$params["partnerid"] = $this->config->partnerId;
//  步驟2生成的簽名。
$params["sign"] = $this->sign($params);

微信APP支付,后臺(tái)需要干的活到這里就暫時(shí)結(jié)束了(因?yàn)檫€有支付成功后的異步通知商戶后面再講)


jsapi支付

下面就是web版的微信支付(公司項(xiàng)目是在微信瀏覽器內(nèi),選擇微信支付后,在微信中調(diào)起的微信支付)

web版微信支付的步驟和APP的大同小異,也是現(xiàn)獲取 prepayId ,再在頁(yè)面中,調(diào)用jsapi進(jìn)行支付。

但是,此處有2個(gè)坑

坑1: 支付時(shí)出現(xiàn) appid and openid not match 的報(bào)錯(cuò)

原因非常的簡(jiǎn)單,就是支付時(shí)所獲取的 openid 在并不屬于支付的商戶。
這個(gè) openid 為微信用戶在商戶對(duì)應(yīng)appid下的唯一標(biāo)識(shí)。也就是說,必須根據(jù)支付的商戶的 appid 去獲取用戶的 openid 。

因?yàn)闃I(yè)務(wù)邏輯需要,項(xiàng)目中用于微信登錄用的公眾號(hào)A用于支付的公眾號(hào)B(其實(shí)還和開放平臺(tái)用于APP支付的 appId 也是不一樣的)是不一樣的,雖然所獲取unionid是一致,但是 openid 是不!一!樣!的!所以,在獲取 openid 時(shí),需要使用當(dāng)前支付時(shí)所用到的 appid 去請(qǐng)求用戶的 openid ,同時(shí),請(qǐng)求 openid 后的回調(diào)也必須是 支付商戶 后臺(tái)所設(shè)置好的回調(diào)地址,要不然就會(huì)報(bào) redirect_uri 參數(shù)錯(cuò)誤 的錯(cuò)誤。

坑2: 參數(shù)名大小寫不一致。

↑ APP支付的參數(shù)

↑ web支付的參數(shù)

仔細(xì)看看劃?rùn)M線的地方。沒錯(cuò),app中的參數(shù)的key全是小寫,web支付中的key則為駝峰命名方式。而且,簽名方式 signType 是必填的, 簽名的字段也變成了 paySign,其中 package 的值也是不一樣,APP支付是固定的值,web支付則為 prepayId,這也要注意。當(dāng)然,官方文檔也是很詳細(xì)的說明,但是需要細(xì)心觀察(所以說嘛,還是直接拷貝必填項(xiàng)最保險(xiǎn)了2333)。

拿到所有參數(shù)后,就可以在頁(yè)面中發(fā)起微信支付的請(qǐng)求了。

代碼可以直接使用官方提供的js代碼

function onBridgeReady(){
   WeixinJSBridge.invoke(
       "getBrandWCPayRequest", YOUR_PARAMS,
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
               // success_callback
           }     // 使用以上方式判斷前端返回,微信團(tuán)隊(duì)鄭重提示:res.err_msg將在用戶支付成功后返回    ok,但并不保證它絕對(duì)可靠。 
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener("WeixinJSBridgeReady", onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent("WeixinJSBridgeReady", onBridgeReady); 
       document.attachEvent("onWeixinJSBridgeReady", onBridgeReady);
   }
}else{
   onBridgeReady();
}

其中 YOUR_PARAMS 是參數(shù)轉(zhuǎn)換成json格式直接渲染至頁(yè)面即可。

如果參數(shù)沒錯(cuò)的話,那么就可以順利的調(diào)起支付窗口了。

坑3: APP支付和jsapi支付不是同一個(gè)號(hào)

APP支付是在開放平臺(tái)中申請(qǐng)下來的,appId和apiKey都是不一樣的。而jsapi支付實(shí)質(zhì)就是公眾號(hào)支付,是在公眾平臺(tái)中申請(qǐng)得到的。所以,在這里,需要注意一下。


重要的來了,能體現(xiàn)后臺(tái)的重要性的地方終于來了 ---

支付結(jié)果的異步通知

官方文檔寫得也很詳細(xì)了(不得不說,微信的開發(fā)文檔真的很清晰。很容易找到。就是沒有詳細(xì)的步驟區(qū)分)。

首先需要申明的是:異步通知的URL是必須能在公網(wǎng)訪問的,而且,必須不能攜帶參數(shù)。

也就是說,http://domain.com/payment/wxp... 是沒問題的,但是 http://domain.com/payment/not... 這樣的URL是不行的。如果要想達(dá)到這種效果,要不服務(wù)器(Nginx , Apache)進(jìn)行rewrite,要不在notify.php 中,手動(dòng)修改 $_GET 中的參數(shù)。

返回的數(shù)據(jù),都是一致的:

這時(shí)候,商戶后臺(tái)拿到這些異步通知的數(shù)據(jù)進(jìn)行簡(jiǎn)單的校驗(yàn)即可,然后修改商戶中相應(yīng)訂單的支付狀態(tài)。

校驗(yàn)返回碼是否成功

$d = $this->xmlToArray(file_get_contents("php://input"));
if (empty($d)) {
    throw new Exception(__METHOD__);
}
if ($d["return_code"] != "SUCCESS") {
    throw new Exception($d["return_msg"]);
}
if ($d["result_code"] != "SUCCESS") {
    throw new Exception("[{$d["err_code"]}]{$d["err_code_des"]}");
}

對(duì)返回?cái)?shù)據(jù)進(jìn)行校驗(yàn)

和請(qǐng)求 prepayId 時(shí)處理數(shù)據(jù)的方式差不多,先取出簽名 sign,然后除去簽名后,進(jìn)行字典排序,以 {key}={value} 的方式進(jìn)行組合,并在最后加上 &key={apiKey}得到待校驗(yàn)字符串,最后,將待校驗(yàn)字符串進(jìn)行MD5加密,和簽名進(jìn)行比較,若一致則校驗(yàn)成功,并且支付成功,然后后臺(tái)做相應(yīng)操作。

if (!$this->verify($d)) {
    throw new Exception("Invalid signature");
}

//  驗(yàn)證函數(shù)
if (empty($d["sign"])) {
    return false;
}
$sign = $d["sign"];
unset($d["sign"]);
return $sign == $this->sign($d);

微信退款

有支付肯定就會(huì)有退款。微信的退款操作也是很簡(jiǎn)單,而且退款速度非???,測(cè)試時(shí)基本都是秒退。

但是退款是有注意事項(xiàng)的:

交易時(shí)間超過一年的訂單無法提交退款;

微信支付退款支持單筆交易分多次退款,多次退款需要提交原支付訂單的商戶訂單號(hào)和設(shè)置不同的退款單號(hào)??偼丝罱痤~不能超過用戶實(shí)際支付金額。一筆退款失敗后重新提交,請(qǐng)不要更換退款單號(hào),請(qǐng)使用原商戶退款單號(hào)

退款請(qǐng)求需要證書。

【證書獲取方式:】

微信支付接口中,涉及資金回滾的接口會(huì)使用到商戶證書,包括退款、撤銷接口。商家在申請(qǐng)微信支付成功后,收到的相應(yīng)郵件后,可以按照指引下載API證書,也可以按照以下路徑下載:微信商戶平臺(tái)(pay.weixin.qq.com)-->賬戶中心-->賬戶設(shè)置-->API安全-->證書下載。

微信退款程序流程:

設(shè)置退款時(shí)得參數(shù)。

請(qǐng)求的參數(shù)有:

appid : 公眾賬號(hào)ID

mch_id : 商戶號(hào)

nonce_str : 隨機(jī)字符串

sign: 簽名

transaction_id / out_trade_no :微信訂單號(hào) / 商戶訂單號(hào) 二者中傳其中一個(gè)即可。

out_refund_no: 商戶退款單號(hào)(由商戶自行生成的唯一標(biāo)識(shí))

total_fee:訂單金額(單位為分)

refund_fee:退款金額(單位為分),退款金額不能大于訂單金額。

op_user_id:操作員帳號(hào), 默認(rèn)為商戶號(hào)

簽名還是老規(guī)矩(默認(rèn)是MD5方式),先將所有參數(shù)進(jìn)行字典排序,然后以$key=$value的形式用&字符拼接成字符串,最后將拼上 &key=YOUR_APIKEY 的待簽名字符串進(jìn)行MD5加密即可。

將參數(shù)列表轉(zhuǎn)換成XML格式。

發(fā)送退款請(qǐng)求。

退款請(qǐng)求需要攜帶微信上下載的證書,請(qǐng)保證證書存放路徑外網(wǎng)不能直接訪問。

解析請(qǐng)求結(jié)果。

當(dāng)返回的結(jié)果中, return_coderesult_code 均為 SUCCESS ,即為退款申請(qǐng)成功。更多返回結(jié)果,請(qǐng)移步至 官網(wǎng)

結(jié)尾

微信支付的官方開發(fā)文檔其實(shí)算是很詳細(xì)了,傳遞的參數(shù),返回結(jié)果,如果判斷是否成功,都寫的很好。只是,開發(fā)中的邏輯過程需要自己慢慢摸索,理清思路后,開發(fā)起來其實(shí)都是很迅速的。

但是,開發(fā)微信支付時(shí),需要留個(gè)心,需要將所有涉及到的微信后臺(tái)提供的數(shù)據(jù)小心保存(比如AppSecret,一當(dāng)忘記只能重置。)

祝各位開發(fā)過程順利進(jìn)行。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/22906.html

相關(guān)文章

  • 支付開發(fā)填坑記之支付

    摘要:原文地址支付支付步驟為獲取支付寶的配置信息。將得到的數(shù)據(jù)請(qǐng)求支付寶客戶端進(jìn)行支付。端將拼接好的字符串拿去請(qǐng)求支付寶客戶端即可調(diào)起支付寶進(jìn)行支付。向支付寶申請(qǐng)新訂單,獲取支付。成功請(qǐng)求回來后,就可以向支付寶發(fā)出一次支付請(qǐng)求。 支付寶在所有支付方式中最好開發(fā)的了,因?yàn)槲臋n比較清晰,而且開發(fā)起來也比較簡(jiǎn)單。因此,支付寶的坑是相對(duì)較少的。原文地址 APP支付 APP支付步驟為: 獲取支付寶的...

    chanjarster 評(píng)論0 收藏0
  • 微信支付PHP SDK之微信公眾號(hào)支付代碼詳解

    摘要:微信支付接口下載官方文檔參考配置公眾號(hào)信息我們先進(jìn)行測(cè)試,所以先把測(cè)試授權(quán)目錄和測(cè)試白名單添加上。在申請(qǐng)微信支付后發(fā)來的郵件中可以找到,則根據(jù)郵件提示拜訪官方我們首先需要的是支付。 微信php支付接口demo下載https://pay.weixin.qq.com/wik... 官方文檔參考https://pay.weixin.qq.com/wik... 1. 配置公眾號(hào)信息showIm...

    jimhs 評(píng)論0 收藏0
  • 支付寶小程序爬坑記、支付寶與微信小程序的區(qū)別。

    摘要:上線時(shí)間問題發(fā)布審核時(shí)間,微信小時(shí)內(nèi)會(huì)審核完成,但是支付寶官方公示是上線審核需要三到五個(gè)工作日,據(jù)親測(cè),實(shí)際支付寶審核印版不會(huì)超過小時(shí),但是支付寶的審核相比較微信真的很嚴(yán)格。 前言: 最近一個(gè)月接收一個(gè)支付寶小程序項(xiàng)目,并進(jìn)行原生開發(fā),現(xiàn)將遇到的問題,爬過的坑給大家進(jìn)行分享,希望讀者可以少走彎路,以下介紹的內(nèi)容將從大方面到細(xì)節(jié)進(jìn)行展開。 廢話少言,直接開始步入正題 ①:上傳、發(fā)布問...

    WilsonLiu95 評(píng)論0 收藏0
  • 使用vue開發(fā)微信公眾號(hào)下SPA站點(diǎn)的填坑之旅

    摘要:原文見我的博客,點(diǎn)擊進(jìn)入使用開發(fā)微信公眾號(hào)下站點(diǎn)的填坑之旅本文為我創(chuàng)業(yè)過程中,開發(fā)項(xiàng)目的填坑之旅。作為一個(gè)技術(shù)宅男,我的項(xiàng)目是做一個(gè)微信公眾號(hào),前后端全部自己搞定,不浪費(fèi)國(guó)家一分錢。 原文見我的博客,點(diǎn)擊進(jìn)入使用vue開發(fā)微信公眾號(hào)下SPA站點(diǎn)的填坑之旅 本文為我創(chuàng)業(yè)過程中,開發(fā)項(xiàng)目的填坑之旅。作為一個(gè)技術(shù)宅男,我的項(xiàng)目是做一個(gè)微信公眾號(hào),前后端全部自己搞定,不浪費(fèi)國(guó)家一分錢^_^。 ...

    yeyan1996 評(píng)論0 收藏0
  • 使用 vue2.0 開發(fā)微信公眾號(hào)下前后端分離的SPA站點(diǎn)的填坑之旅

    摘要:目前正在寫一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問題和解決方法主要是前端。前端提交時(shí)使用,在后端再取出對(duì)應(yīng)的微信支付看了下文檔,以前是需要用喚起支付,而現(xiàn)在則是把微信內(nèi)置到了微信的瀏覽器中。 目前正在寫一個(gè)微信公眾號(hào)的小項(xiàng)目,記錄一下遇到的問題和解決方法(主要是前端)。內(nèi)容持續(xù)更新中~ 主要實(shí)現(xiàn) 前后端分離前端為 SPA 單頁(yè)面使用微信的JSSDK微信支付 技術(shù)方案 后端使用 php ...

    afishhhhh 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<