微信JSAPI支付那點(diǎn)事

準(zhǔn)備工作

微信商戶賬戶/密碼(獲取appid等信息)
微信公眾號賬戶/密碼(獲取cert證書等信息牺氨,不做線上退款不需要證書)
基礎(chǔ)php知識
自己已備案的域名(備案后微信不攔截)
自己可登陸的服務(wù)器(上傳代碼用)

下載php支付demo

從商戶平臺進(jìn)入的話是以下界面或者直接搜索公眾號支付文檔

支付類型

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

payType.png

php-demo下載

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

php-demo.png

修改部分文件并預(yù)覽index.php

解壓文件刃唐,打開index.php修改
可以改成絕對路徑层玲,即你放的位置(某個域名或者某個域名下某個文件夾下)或者相對路徑

http://'.$_SERVER['HTTP_HOST'].'/WxpayAPI/example/jsapi.php
path.png
更改配置(整個demo最重要的修改的地方)
config.png

說明
appId:是你的微信公眾平臺的appId
appsecret:是你商戶平臺的appsecret這兩個參數(shù)可登錄你的微信公眾平臺查看
mchId:是你的商戶Id,這個是你的微信公眾號開通微信支付萝招,微信分配給你的一個商戶支付ID蚂斤,可登陸商戶平臺查看,即是你登錄商戶平臺的賬號
key:是你商戶平臺的支付秘鑰槐沼,這個參數(shù)很關(guān)鍵橡淆,它是一個32位的字符串

一定要保證你以上四個參數(shù)的正確,不然出現(xiàn)的各種錯誤皆可能是這四個參數(shù)不正確造成的母赵,當(dāng)然前提是你開通微信支付并且配置正確的授權(quán)域名和支付目錄

修改異步通知地址

打開example文件夾下的jsapi.php

$input->SetNotify_url("http://www.xxx.com/WxpayAPI/example/notify.php"); //設(shè)置接收微信支付異步通知回調(diào)地址

改為你自己的地址逸爵,可以寫死或者相對路徑獲取該地址

添加異步通知地址配置

Wxpay.api.php中的unifiedOrder下單方法中需要

//異步通知url未設(shè)置,則使用配置文件中的url

    if(!$inputObj->IsNotify_urlSet()){
        $inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//異步通知url
    }

所以如果你沒設(shè)置凹嘲,則需要去WXPay.Config.php中添加一條:

const NOTIFY_URL='https://www.xxx.com/WxpayAPI/example/notify.php';
配置授權(quán)域名

因?yàn)槲⑿胖Ц兑@取openId,它是微信支付用戶的憑證

auth.png
配置支付目錄
mchId.png
上傳整個文件夾到你寫的支付目錄下的域名下

比如你的是www.xxx.com/WxpayAPI/example/
那么你就把你整個WxpayAPI文件夾傳到你的www.xxx.com域名目錄下
預(yù)覽index.php

index.png

確認(rèn)你的商戶信息
pay.png
重點(diǎn)(坑點(diǎn))

支付成功jsapi中的js就可以根據(jù)返回的信息跳轉(zhuǎn)到支付成功的頁面,這是接收微信同步返回的處理

function jsApiCall()
{
    WeixinJSBridge.invoke(
        'getBrandWCPayRequest',
         <?php echo $jsApiParameters; ?>, //訂單參數(shù)
         function (res) {
                alert(res.err_msg);
                WeixinJSBridge.log(res.err_msg);
                if (res.err_msg == 'get_brand_wcpay_request:ok') {
                      window.location.+<?php echo $paymentId;?>+'&orderId='+<?php echo $orderId;?>;
                }else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
                      alert('cancel');
                } else {
                      alert('fail');
                      alert(res.err_msg);
                }
           }
      );
   }

但是最終是否支付成功不能以這個為準(zhǔn)师倔,而是notify.php接收到的異步通知為準(zhǔn),這是微信異步返回的結(jié)果處理

public function NotifyProcess($data, &$msg)
{
    Log::DEBUG("call back:" . json_encode($data));
    $notfiyOutput = array();
    if(!array_key_exists("transaction_id", $data)){
        $msg = "輸入?yún)?shù)不正確";
        return false;
    }
    //查詢訂單周蹭,判斷訂單真實(shí)性
    if(!$this->Queryorder($data["transaction_id"])){
        $msg = "訂單查詢失敗";
        return false;
    }
    $this->UpdateOrderStatus();//自定義更改數(shù)據(jù)庫支付成功狀態(tài)
    return true;
}

具體的更改數(shù)據(jù)庫訂單狀態(tài)需要接收到微信異步通知的xml趋艘,然后判斷是否支付成功,再進(jìn)行更改

function UpdateOrderStatus() {
      $string = file_get_contents("php://input");//微信返回的xml支付結(jié)果
      $arr = (array) simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);
      if ($arr['result_code'] == 'SUCCESS' && $arr['return_code'] == 'SUCCESS') {
           //操作數(shù)據(jù)庫處理訂單狀態(tài)等
      }
}

以上是分析的demo大致流程凶朗,接下來我說一下我遇到的坑瓷胧,望各位注意:

坑一:簽名錯誤

這是我最開始調(diào)試SDK的demo時候第一個坑
我們公司把已經(jīng)使用是APP的商戶Id和key給我,讓我用這個棚愤,這個后臺可以登錄搓萧,我看到了商戶id沒問題,但key看不到宛畦,只有重置才可以瘸洛,因?yàn)榫€上用著,我也沒法重置次和,還以為代碼有問題反肋,各種輸出查看。
百度好多人都讓重置key踏施,說同一個key重新提交一次也行石蔗,有人提交兩三次同一個key罕邀,說就不報簽名無效了。但我們沒有開發(fā)環(huán)境养距,我不能任性重置燃少。只能找代碼的問題

最終發(fā)現(xiàn)還是第一步的四個配置參數(shù)有問題,appId沒問題是公眾號的id,我沒用他們給我的appId,他們的appId應(yīng)該是App開放平臺的appId

商戶id和秘鑰铃在,給我的是app的商戶id和key,其實(shí)不是碍遍。應(yīng)該是我們微信公眾號申請微信支付分配的商戶id和秘鑰定铜。而不是說用APP申請的商戶id和秘鑰。
雖然文檔說的很清楚怕敬,我也知道揣炕,但領(lǐng)導(dǎo)就說和app共用一個,我也很無奈狡相。因?yàn)殚_始我也不是很清楚圃庭,就覺得那就是吧坦刀,或許是demo有問題(哈哈哈)

坑二:out_trade_no的最少位數(shù)問題

微信說是32位以內(nèi),但是丁恭,如果你傳1位,肯定會報錯斋日,它的提示還很弱牲览,不是說位數(shù)不足,具體什么提示我忘了恶守。反正位數(shù)太少會出錯第献,我在這里也是摔了個跟頭

坑三:不知道notify.php這個文件怎么接收微信支付返回結(jié)果

搜了好多資料,大部分人都只講解了demo兔港,說支付成功以異步通知為準(zhǔn)庸毫,微信是通知給你設(shè)置的地址了,但問題是我怎么獲取他的通知呢衫樊?

總是覺得沒有返回變量飒赃,就不知道怎么輸出變量,怎么處理科侈。

$string = file_get_contents("php://input");

這就是接收到微信的通知盒揉,一個xml,詳細(xì)代碼上邊有

坑四:jsapi.php接收不到上一個頁面post或get傳過來的參數(shù)

原因:在創(chuàng)建商戶訂單時,需要獲取到用戶的openid

//①兑徘、獲取用戶openid
$tools = new JsApiPay();
$openId = $tools->GetOpenid();

Wxpay.JsApiPay.php
但是在獲取用戶openid的過程中需要請求CODE刚盈,CODE請求函數(shù)如下:

public function GetOpenid()
{
    //通過code獲得openid
    if (!isset($_GET['code'])){
        //觸發(fā)微信返回code碼
        $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
        $url = $this->__CreateOauthUrlForCode($baseUrl);
        Header("Location: $url");
        exit();
    } else {
        //獲取code碼,以獲取openid
        $code = $_GET['code'];
        $openid = $this->getOpenidFromMp($code);
        return $openid;
    }
}

因此挂脑,在獲取openid商戶后臺與微信系統(tǒng)進(jìn)行多次交互藕漱,當(dāng)再次回到生成商戶訂單頁的時候欲侮,我們之前從h5頁面通過$_GET或者$_POST方式獲取的參數(shù)已經(jīng)被清空,所以無法生成商戶訂單肋联。
解決辦法:
1.先將用戶h5頁面提交過來的參數(shù)保存到session中威蕉,然后再重定向到要生成商戶訂單的頁面,
在生成商戶訂單的頁面中先獲取openid,再獲取session
中的值(這是我百度到別人采用的方法)
2.我的辦法:
在獲取openid之前把post或者get的參數(shù)取到橄仍,然后傳給微信(采用和他獲取code的機(jī)制一樣)

//①韧涨、獲取用戶openid
$tools = new JsApiPay();
$arr = $tools->GetOpenid($Out_trade_no,$paymentId,$Total_fee);

重寫GetOpenid方法,如下:

public function GetOpenid($orderId,$paymentId,$totalFee)
{
    //通過code獲得openid
    if (!isset($_GET['code'])){
        //觸發(fā)微信返回code碼
        $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING'].'?orderId='.$orderId.'&paymentId='.$paymentId.'&totalFee='.$totalFee);
        $url = $this->__CreateOauthUrlForCode($baseUrl);
        Header("Location: $url");
        exit();
    } else {
        //獲取code碼侮繁,以獲取openid
        $code = $_GET['code'];
        $orderId = $_GET['orderId'];
        $paymentId= $_GET['paymentId'];
        $totalFee = $_GET['totalFee'];
        $openid = $this->getOpenidFromMp($code);
        return $arr;
    }
}
金額的問題

傳遞的金額虑粥,微信是以分為單位,而一般是以元為單位宪哩,所以記得金額轉(zhuǎn)換一下娩贷,不要傳給微信小數(shù)點(diǎn)
還有這個金額最好在jsapi這個頁面,查詢一下數(shù)據(jù)庫該筆訂單應(yīng)支付多少锁孟,而不是從提交訂單頁面?zhèn)鬏斶^來彬祖,這樣不安全,也別以為請求接口會安全品抽,都不安全储笑,只要存在網(wǎng)絡(luò)傳輸就會出現(xiàn)篡改,最好是自己在本頁面查詢出來圆恤,然后傳給微信

out_trade_no的問題
(說明這是針對我們的流程設(shè)計出次下策)

我們的提交訂單會生成一個orderId和paymentId存在我們的兩個表中(這兩個表)南蓬,然后因?yàn)橐o微信傳我們自己的訂單id,一般來說只需要傳orderId就行哑了,但是接收到微信異步通知的支付成功以后赘方, 我們需要根據(jù)paymenId去改我們的支付狀態(tài)。
問題是從微信返回時我們沒有paymentId弱左。
用orderId去查可能會不唯一(我們數(shù)據(jù)庫設(shè)計如此窄陡,會有多訂單支付),另一方面是多次請求會慢拆火,所以我采取了把訂單id和paymentId拼接在一起作為傳給微信跳夭,然后支付成功以后微信返回out_trade_no就是我們的orderId和paymentId

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市们镜,隨后出現(xiàn)的幾起案子币叹,更是在濱河造成了極大的恐慌,老刑警劉巖模狭,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颈抚,死亡現(xiàn)場離奇詭異,居然都是意外死亡嚼鹉,警方通過查閱死者的電腦和手機(jī)贩汉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門驱富,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匹舞,你說我怎么就攤上這事褐鸥。” “怎么了赐稽?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵叫榕,是天一觀的道長。 經(jīng)常有香客問我姊舵,道長晰绎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任蠢莺,我火速辦了婚禮,結(jié)果婚禮上零如,老公的妹妹穿的比我還像新娘躏将。我一直安慰自己,他們只是感情好考蕾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布祸憋。 她就那樣靜靜地躺著,像睡著了一般肖卧。 火紅的嫁衣襯著肌膚如雪蚯窥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天塞帐,我揣著相機(jī)與錄音拦赠,去河邊找鬼。 笑死葵姥,一個胖子當(dāng)著我的面吹牛荷鼠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播榔幸,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼允乐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了削咆?” 一聲冷哼從身側(cè)響起牍疏,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拨齐,沒想到半個月后鳞陨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞻惋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年炊邦,在試婚紗的時候發(fā)現(xiàn)自己被綠了编矾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡馁害,死狀恐怖窄俏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碘菜,我是刑警寧澤凹蜈,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站忍啸,受9級特大地震影響仰坦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜计雌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一悄晃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凿滤,春花似錦妈橄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至反番,卻和暖如春沙热,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罢缸。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工篙贸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人枫疆。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓歉秫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親养铸。 傳聞我的和親對象是個殘疾皇子雁芙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 引言 秋高氣爽兔甘,天氣轉(zhuǎn)涼,正是學(xué)習(xí)工作做的好時候鳞滨。(~ ̄▽ ̄)~~(~ ̄▽ ̄)~ 我是個phper最近在寫微信支付...
    恩就是這個名閱讀 7,943評論 2 15
  • 該文僅對于中間這種支付方式有參考價值喲 一洞焙、開發(fā)背景 在微信公眾號中,需要進(jìn)行微信支付且為微信公眾號網(wǎng)頁支付。 二...
    英文名叫夏天閱讀 1,795評論 0 7
  • 微信公眾號支付分為三類 以下主要介紹公眾號H5授權(quán)支付 首先看一下微信支付的業(yè)務(wù)邏輯 大部分微信支付邏輯在于服務(wù)器...
    撩人C小羅閱讀 2,660評論 0 0
  • 燕歸巢 作者:天義 陳風(fēng)怒號兮木葉下澡匪, 繼往云煙兮悲余茫熔任。 紅豆植南國兮別離悵, 儂濃余懷兮顧心涼唁情。 要比鄰星...
    天義小哥哥閱讀 267評論 0 0
  • 昨天2017年4月29日疑苔、周六,我興致勃勃地參加了世博公園的草莓音樂節(jié)甸鸟,有幸聽到了萬能青年旅店現(xiàn)場版的《殺死那個石...
    同叔練級之路閱讀 615評論 0 49