之前寫過支付寶app支付的支付的后臺代碼,現(xiàn)在來說一下異步通知:
個人感覺支付寶的異步通知,步驟比微信簡單點,但里面的坑可是沒少多少,就一個驗簽就把我整的快瘋了….
異步通知:
1,先確定在支付的時候?qū)懙幕卣{(diào)地址的正確性!!!!!!
2.找到支付寶封裝的驗簽類,rsaCheckV1(這個也是在app2.0接口里面)
3.驗證回調(diào)參數(shù)
*4.檢驗訂單
先確定在支付的時候?qū)懙幕卣{(diào)地址的正確性!!!!!!
一定要確定回調(diào)地址的寫的是否指到是你寫回調(diào)驗證的那個放里面,別到時候在回頭找錯誤的時候,抓耳撓腮..
找到支付寶封裝的驗簽類,rsaCheckV1(這個也是在app2.0接口里面)
這是支付寶已經(jīng)封裝好的類:
/** rsaCheckV1 rsaCheckV2 * 驗證簽名 * 在使用本方法前,必須初始化AopClient且傳入公鑰參數(shù)。 * 公鑰是否是讀取字符串還是讀取文件,是根據(jù)初始化傳入的值判斷的。 html' target='_blank'>public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType= RSA ) { $sign = $params[ sign $params[ sign_type ] = null; $params[ sign ] = null; $this- alipayrsaPublicKey = $rsaPublicKeyFilePath; return $this- verify($this- getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType= RSA ) { $sign = $params[ sign $params[ sign ] = null; return $this- verify($this- getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); function verify($data, $sign, $rsaPublicKeyFilePath, $signType = RSA ) { if($this- checkEmpty($this- alipayPublicKey)){ $pubKey= $this- alipayrsaPublicKey; $res = -----BEGIN PUBLIC KEY-----/n . wordwrap($pubKey, 64, /n , true) . /n-----END PUBLIC KEY----- }else { //讀取公鑰文件 $pubKey = file_get_contents($rsaPublicKeyFilePath); //轉(zhuǎn)換為openssl格式密鑰 $res = openssl_get_publickey($pubKey); ($res) or die( 支付寶RSA公鑰錯誤。請檢查公鑰文件格式是否正確 //調(diào)用openssl內(nèi)置方法驗簽,返回bool值 if ( RSA2 == $signType) { $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); } else { $result = (bool)openssl_verify($data, base64_decode($sign), $res); if(!$this- checkEmpty($this- alipayPublicKey)) { //釋放資源 openssl_free_key($res); return $result; }
還有就是別把這兩個方法混淆了,前者需要傳signtype,后者不需要(前面兩個方法都會調(diào)用第三個方法),還有一點很重要,就是這個方法的本身是從文件里面提取公鑰的的,但是本人是直接傳的,就把這個方法稍加改動了一下,讓它直接讀取我傳的公鑰.這個驗簽方法返回的是(bool)true或者(bool)false,來判斷驗簽是否成功.
在這里要注意三點:
1—注意公鑰的正確性,還有用的是支付寶公鑰不是你當(dāng)初生成的公鑰
2—區(qū)別這里的方法和支付寶接口本身方法的公鑰獲取方式
3—注意接口方法本身的注釋,很重要
驗證回調(diào)參數(shù)
支付寶的回調(diào)參數(shù)是以post的方式回傳的,但是我們在測試的時候可以直接把回調(diào)url直接寫在地址欄里面,然后用get方式接受,這樣就不用拼參數(shù)了,結(jié)果是一樣的(回調(diào)url可以記錄在log文件里面),還有就是驗簽的時候需要所有的回傳參數(shù)原封不動的去驗簽,而這里自己需要什么參數(shù)就接收什么參數(shù)就可以,這里就不多說了,就是正常的接受參數(shù)的問題.下面給出我在驗證參數(shù)時,檢驗訂單金額和商家編號的代碼,僅做參考(我用的tp5):
public function check($receipt_amount,$buyer_pay_amount,$order_price,$app_id,$seller_email){ if($receipt_amount !== $order_price || $buyer_pay_amount !== $order_price){// echo 1; return $this- log( 訂單支付金額有誤! //支付寶支付的所有參數(shù) $alipay_config = Config::get( alipay_config if($app_id !== $alipay_config[ appid ]){// echo 2; return $this- log( 商家編號有誤! //驗證收款商家是否正確 if($seller_email !== $alipay_config[ seller_id ]){// echo 3; return $this- log( 收款商家有誤! return success }
檢驗訂單
這里主要就是檢驗庫存,這里最好用事物處理,(雖然你的訂單量可能不一定回到這個地步),下面給出我的代碼,僅做參考(tp5):
public function index($order_sn= ) if(isset($_POST[ order_sn ]) empty($order_sn)){ $order_sn = $_POST[ order_sn $table = self::order_info($order_sn); if($table == failure ){return false } $oid = $table[ order_id //通過訂單id $oid 查詢出訂單中物品的id $goodsTable = Db::name( goods $allgoods = Db::name( test1 )- where( o_id , $oid)- field( g_id,g_num )- select(); foreach ($allgoods as $k = $v) { //事務(wù)處理 $goodsTable- startTrans();//事物開始 try { //判斷庫存數(shù)量 $goodsTable- query( update test2 set g_num = g_num- . $v[ g_num ] . where g_num = . $v[ g_num ] . and gid = . $v[ g_id } catch (/Exception $e) { $goodsTable- rollBack();//事物回滾 $goodsTable- commit();// 事物提交 //修改訂單 $res = Db::name( test3 )- where( order_sn ,$order_sn)- update([ order_state = 1 , pay_time = time()]); if($res != 0){ return success }
接下來就是把結(jié)果返回給支付寶就可以,失敗:return ‘failure 成功:return ‘success 到這里就結(jié)束了.
還有就是在出錯后和在找bug的時候都平心靜氣一些,理智的找問題才會更快的找到問題 ( 如果實在不行就去找支付寶的人工支持,他會為你調(diào)試你的代碼,會給出一個差不多的結(jié)論,然后你再去改就會容易很多 :) ).
最后希望大家支付,回調(diào)都可以成功!
相關(guān)推薦:
php如何實現(xiàn)支付寶的APP支付功能(代碼)
以上就是php實現(xiàn)支付寶app支付和異步通知的代碼實例的詳細內(nèi)容,PHP教程
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答
圖片精選