支付开发填坑记之支付宝
支付寶在所有支付方式中最好開發的了,因為文檔比較清晰,而且開發起來也比較簡單。因此,支付寶的坑是相對較少的。
原文地址
APP支付
APP支付步驟為:
由于APP支付是由APP去調起支付寶支付,所以服務端需要做的事情就是將請求參數封裝好之后返回APP即可。
獲取支付寶的配置信息。
支付時需要的配置信息有:
- key: 交易安全校驗碼。
- app_id:支付寶分配給開發者的應用ID。
生成商家訂單信息。
這個步驟由商家自行生成。支付寶那邊只需要知道的訂單信息為:
- subject: 必填。商品的標題/交易標題/訂單標題/訂單關鍵字等。
- total_amount: 必填。訂單價格。
- out_trade_no: 必填。商戶網站唯一訂單號。
- body: 非必填。交易的具體描述信息。
APP支付的詳細請求參數: 點擊查看
生成請求給支付寶的加密字符串。
$sign = $alipaySubmit->buildRequestParaForApp($para_token);其中, buildRequestParaForApp 的實現為:
將待校驗數據和加密字符串拼接,返回給APP。
$url = ""; foreach ($para_token as $key => $value) {$url .= $key."=".urlencode($value)."&"; } return $url."sign=".urlencode($sign);APP端將拼接好的字符串拿去請求支付寶客戶端即可調起支付寶進行支付。拼接好的字符串大致如下圖所示:
網頁版支付
網頁版支付步驟為:
網頁版的支付寶支付相對于APP調起支付寶要復雜,因為網頁支付時,需要多次請求支付寶服務器獲取支付的必要參數。
設置支付寶配置信息。
/**調用授權接口alipay.wap.trade.create.direct獲取授權碼token**///返回格式private $format = "";//必填,不需要修改//版本private $v = "";//必填,不需要修改//請求號private $req_id = "";//必填,須保證每次請求都是唯一//**req_data詳細信息**//服務器異步通知頁面路徑private $notify_url = "";//需http://格式的完整路徑,不允許加?id=123這類自定義參數//頁面跳轉同步通知頁面路徑private $call_back_url = "";//需http://格式的完整路徑,不允許加?id=123這類自定義參數//賣家支付寶賬戶private $seller_email = "";//必填//商戶訂單號private $out_trade_no = "";//商戶網站訂單系統中唯一訂單號,必填//訂單名稱private $subject = "";//必填//付款金額private $total_fee = "";//必填//請求業務參數詳細private $req_data = "";//必填//配置private $alipay_config = array();/************************************************************/向支付寶申請新訂單,并獲取訂單的token。
請求token的service為: alipay.wap.trade.create.direct。
構造參數:
$para_token = array("service" => "alipay.wap.trade.create.direct",// 合作者身份(partner ID)"partner" => trim($this->alipay_config['partner']),// APP使用的是RSA,網頁版使用的是MD5"sec_id" => trim($this->alipay_config['sign_type']),// 返回的數據格式"format" => $this->format,// 版本號?"v" => $this->v,// 唯一的請求號"req_id" => $this->req_id,// 請求參數"req_data" => $req_data,// 字符集,一般為utf8即可。"_input_charset" => trim(strtolower($this->alipay_config['input_charset'])) );將構造好的請求參數,進行處理,字典排序,拼接字符串,簽名:
$para_filter = paraFilter($para_temp); $para_sort = argSort($para_filter); $mysign = $this->buildRequestMysign($para_sort); //簽名結果與簽名方式加入請求提交參數組中 $para_sort['sign'] = $mysign; return $para_sort;處理:過濾值為空的數據,過濾簽名類型和簽名。
function paraFilter($para) {$para_filter = array();while (list ($key, $val) = each ($para)) {if($key == "sign" || $key == "sign_type" || $val == "")continue;else $para_filter[$key] = $para[$key];}return $para_filter; }字典排序:
/*** 對數組排序* @param $para 排序前的數組攜帶token進行訂單支付。
成功請求token回來后,就可以向支付寶發出一次支付請求。
同樣構造請求數據:
//業務詳細只需要攜帶步驟2的token即可。 $req_data = '<auth_and_execute_req><request_token>' . $request_token . '</request_token></auth_and_execute_req>'; //必填//構造要請求的參數數組,無需改動 $parameter = array("service" => "alipay.wap.auth.authAndExecute",// 合作者身份(partner ID)"partner" => trim($this->alipay_config['partner']),// 簽名類型"sec_id" => trim($this->alipay_config['sign_type']),// 和步驟2一致"format" => $this->format,"v" => $this->v,"req_id" => $this->req_id,// 業務詳細參數"req_data" => $req_data,// 字符集,一般為utf8."_input_charset" => trim(strtolower($this->alipay_config['input_charset'])) );將這些參數,在頁面中傳送給支付寶即可發起一次支付請求。
在PHP 中的實現就是將這些參數,渲染至HTML中,再將HTML中的表單提交即可。
到此,網頁版的支付寶支付完成整個流程。
支付結果異步通知
在上面,我們看到有兩個參數傳給了支付寶:
- call_back_url: 交易成功后,支付寶頁面上“返回到商家頁面”的地址(同步回調)
- notify_url: 交易狀態變更后,支付寶通知網站的回調地址(異步通知)
對于App支付產生的交易,支付寶會根據原始支付API中傳入的異步通知地址notify_url,通過POST請求的形式將支付結果作為參數通知到商戶系統。
支付寶異步通知官方文檔中寫的比較清楚,什么時候出發通知,返回什么參數,注意事項都有,開發者可以根據自己的情況查看具體信息。
驗簽步驟可以移步至這里
這里就簡單的用手上的項目舉例說明,支付寶通知后,后臺是如何進行驗簽和處理訂單。
public function app_notifyOp(){$payment_api = $this->_get_payment_api();$payment_config = $this->_get_payment_config();// 支付寶是用POST方式發送通知信息$callback_info = $payment_api->getNotifyInfoApp($_POST);if($callback_info) {//驗證成功if ($callback_info['order_state']) {// 如果是支付成功則改變訂單狀態$result = $this->_update_order($callback_info['out_trade_no'], $callback_info['trade_no']);}else{// 如果是退款成功則修改退訂的相關狀態$result = $this->_app_refund($callback_info['out_trade_no'], $callback_info['trade_no'], $callback_info['refund_fee']);}if($result['state']) {echo 'success';die;}}//驗證失敗echo "fail";die; }獲取支付寶通知數據
支付寶異步通知是POST請求,返回的數據結構如下:
驗簽數據
驗簽需要支付寶的公鑰
驗簽和簽名的流程是一樣的,都是將所有除了 sign 以外的參數,進行字典排序,并以 key=value 的形式以 & 符號拼成字符串,再使用密鑰進行簽名,將得到的簽名與支付寶返回的簽名進行對比,完成驗簽過程。
function getSignVeryfy($para_temp, $sign) {//除去待簽名參數數組中的空值和簽名參數$para = paraFilter($para_temp);//對待簽名參數數組排序$para = argSort($para);//把數組所有元素,按照“參數=參數值”的模式用“&”字符拼接成字符串$prestr = createLinkstring($para);$prestr = htmlspecialchars_decode($prestr);$isSgin = false;switch (strtoupper(trim($this->alipay_config['sign_type']))) {case "MD5" :$isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);break;case "RSA" :$isSgin = rsaVerify($prestr, trim($this->alipay_config['ali_public_key_path']), $sign);break;case "0001" :$isSgin = rsaVerify($prestr, trim($this->alipay_config['ali_public_key_path']), $sign);break;default :$isSgin = false;}logResult($log);return $isSgin; }但是這里有個坑,就是返回數據中的 fund_bill_list 是經過html轉義的(如例子中的數據: [{"amount":"31.00","fundChannel":"ALIPAYACCOUNT"}]),如果直接使用該參數進行簽名,則會導致簽名失敗。這里就需要將字符串轉義了: [{"amount":"31.00","fundChannel":"ALIPAYACCOUNT"}] ,用轉義后的參數值進行簽名,通過校驗。
驗簽完畢后,后臺就可以根據實際情況進行訂單狀態的更改。
完畢
祝各位程序猿在開發支付寶支付時不再有坑,也希望支付寶在后續的更新中不再埋雷。
總結
以上是生活随笔為你收集整理的支付开发填坑记之支付宝的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集成 jpush-react-nativ
- 下一篇: 5月10日优酷殴打腾讯员工那些事