1. 程式人生 > >APP支付(支付寶和微信生成客戶端簽名及回撥驗籤)

APP支付(支付寶和微信生成客戶端簽名及回撥驗籤)

<?php
namespace Pn\Controller;
use Think\Controller\RestController;
class PayController extends RestController{
    public function __construct(){
        import('Vendor.WePay.WeEncryption');
        import('Vendor.WePay.Curl');
    }
    public function Payment(){
        $arr['appid'] = $_POST['appid'];//應用id
        $arr['userdid'] = $_POST['userdid'];//登入使用者id
        $arr['paytype'] = $_POST['paytype'];//支付方式
        $arr['productid'] = $_POST['productid'];//商品id
        $arr['time'] = $_POST['time'];
        $sign = $_POST['sign'];//安全驗證sign
        $vsign = strrank($arr);//簽名加密
        
        if($vsign!=$sign){
            $return['respCode'] = 1001;
            $return['msg'] = "簽名錯誤";
            $this -> response($return,'json');//返回資料
            exit();
        }else{
            switch ($_POST["paytype"]){
                case 1://支付寶
                    $data["signdata"] = $this->alipay();
                    echo json_encode($data);
                break;
                case 2://微信支付
                    $data = $this->wechatpay($_POST['appid'],$_POST['userdid'],$_POST['productid']);
                    echo $data;
                break;
                default:
                $return["respCode"] = "error"; 
                $return['msg'] = "支付方式錯誤";
                $this -> response($return,'json');//返回資料
                exit();
            }
        }
    }
    /**
     * 微信APP客戶端支付
     */
    public function wechatpay($appid,$userdid,$productid){
       $WeEncryption = new \WeEncryption();	//例項化傳輸類;
       switch ($productid){
           case 1://季付商品(¥100)
               $body = "陪你季付VIP";//商品描述
               $total_fee = "100.00";//總金額
           break;
           case 2://月付商品(¥50)
               $body = "陪你月付VIP";//商品描述
               $total_fee = "50.00";//總金額
           break;
       }
       $out_trade_no = date("YmdHis").rand(10,100);//商戶訂單號
       $spbill_create_ip = getclientip();//終端IP

       $data = array(
           'body'				=>	$body,
           'out_trade_no'		=>	$out_trade_no,
           'total_fee'			=>	$total_fee,
           'spbill_create_ip'	=>	$spbill_create_ip,
       );
       
       $encpt = $WeEncryption::getInstance();	//例項化簽名類
       $url = "http://xxxx.com/Pay/wx_notify_verify";
       $encpt->setNotifyUrl($url);			//設定非同步通知地址
       
       $curl = new \Curl();				//例項化傳輸類;
       $xml_data = $encpt->sendRequest($curl, $data);		//傳送請求

       $postObj = $encpt->xmlToObject($xml_data);			//解析返回資料
       if ($postObj === false) {
           echo 'FAIL';
           exit;
       }
       if ($postObj->return_code == 'FAIL') {
           echo $postObj->return_msg;
       } else {
           $resignData = array(
               'appid'			=>	$postObj->appid,
               'partnerid'		=>	$postObj->mch_id,
               'prepayid'		=>	$postObj->prepay_id,
               'noncestr'		=>	$postObj->nonce_str,
               'timestamp'		=>	time(),
               'package'	=>	'Sign=WXPay'
           );
           $sign = $encpt->getClientPay($resignData);
           $resignData['sign'] = $sign;
           return  json_encode($resignData);
       }
    }
    /**
     * 微信App支付回撥
     */
    public function wx_notify_verify(){
        $WeEncryption = new \WeEncryption();	//例項化傳輸類;
        $encpt = $WeEncryption::getInstance();
        $obj = $encpt->getNotifyData();
        if ($obj === false) {
            exit;
        }
        if ($obj) {
            $data = array(
                'appid'				=>	$obj->appid,
                'mch_id'			=>	$obj->mch_id,
                'nonce_str'			=>	$obj->nonce_str,
                'result_code'		=>	$obj->result_code,
                'openid'			=>	$obj->openid,
                'trade_type'		=>	$obj->trade_type,
                'bank_type'			=>	$obj->bank_type,
                'total_fee'			=>	$obj->total_fee,
                'cash_fee'			=>	$obj->cash_fee,
                'transaction_id'	=>	$obj->transaction_id,
                'out_trade_no'		=>	$obj->out_trade_no,
                'time_end'			=>	$obj->time_end
            );
            $sign = $encpt->getSign($data);
            if ($sign == $obj->sign) {//驗籤通過
                $reply = "<xml>
					<return_code><![CDATA[SUCCESS]]></return_code>
					<return_msg><![CDATA[OK]]></return_msg>
				</xml>";
                echo $reply;
                exit;
            }else{
                $reply = "<xml>
					<return_code><![CDATA[FAIL]]></return_code>
					<return_msg><![CDATA[NO]]></return_msg>
				</xml>";
                echo $reply;
                exit;
            }
        }
    }
    
    /**
     * https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.NgdeQA&treeId=59&articleId=103663&docType=1
     * 服務端生成app支付使用的引數以及簽名
     * @param $params <Array>
     * @return <Array>
    */
    public function alipay(){ 

        $ali = array(
          'service' => 'mobile.securitypay.pay',
          'partner' => 'xxxx',
          '_input_charset' => 'utf-8',
          'sign_type' => 'RSA',
          'sign' => '',
          'notify_url' => 'http://xxxxxxxx.com/Pay/alipay_notify_url',//回撥地址
          'out_trade_no' => date("YmdHis").rand(10,100),//商戶網站唯一訂單號
          'subject' => '測試',//商品名稱
          'payment_type' => 1,//支付型別
          'seller_id' => '
[email protected]
',//支付寶賬號 'total_fee' => '0.01',//總金額 'body' => 'Iphone6 16G',//商品詳情 ); $ali = self::argSort($ali); $str = ''; foreach($ali as $key=>$val){ if($key == 'sign_type' || $key == 'sign'){ continue; }else{ if($str == ''){ $str = $key.'='.'"'.$val.'"'; }else{ $str = $str.'&'.$key.'='.'"'.$val.'"'; } } } $sign = urlencode(self::sign($str)); $str = $str.'&sign='.'"'.$sign.'"'.'&sign_type='.'"'.$ali['sign_type'].'"';//傳給支付寶介面的資料 return $str; } /** * 準備簽名引數 */ public function argSort($para) { ksort($para); reset($para); return $para; } /** * 生成請求引數的簽名 * @param $params <Array> * @return <String> * */ public function sign($data) { //讀取私鑰檔案 $priKey = file_get_contents('./Public/key/rsa_private_key.pem');//私鑰檔案路徑 //轉換為openssl金鑰,必須是沒有經過pkcs8轉換的私鑰 $res = openssl_get_privatekey($priKey); //呼叫openssl內建簽名方法,生成簽名$sign openssl_sign($data, $sign, $res); //釋放資源 openssl_free_key($res); //base64編碼 $sign = base64_encode($sign); return $sign; } /** * 支付寶回撥地址 */ public function alipay_notify_url(){ $orderpay = M("orderpay"); $async = empty($_GET); $data = $async ? $_POST : $_GET; if (empty($data)) { return FALSE; } $signValid = $this->verifyParameters($data, $data["sign"]);//驗籤 $notify_id = isset($data['notify_id']) ? $data['notify_id'] : NULL; //獲取支付寶遠端伺服器ATN結果(驗證是否是支付寶發來的訊息) $responseTxt = 'true'; if (!empty($notify_id)) { $responseTxt = $this->verifyFromServer($notify_id); } if($signValid && preg_match("/true$/i", $responseTxt)){//驗證成功 if($_POST['trade_status'] == 'TRADE_FINISHED'){ $_POST["createdatetime"] = time(); if($orderpay->create()){ $orderpay->add(); echo "success"; }else{ echo "fail";//驗證失敗 } } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { $_POST["createdatetime"] = time(); if($orderpay->create()){ $orderpay->add(); echo "success"; }else{ echo "fail";//驗證失敗 } } }else{ echo "fail";//驗證失敗 } } /** * 將剩下引數進行url_decode, 然後進行字典排序,組成字串,得到待簽名字串 * @param unknown $params * @param unknown $sign * @return boolean */ function verifyParameters($params, $sign) { $public_key_path = './Public/key/alipay_public_key.pem';//公鑰(合作伙伴) $params = $this->filterSignParameter($params); ksort($params); reset($params); $content = urldecode(http_build_query($params)); return $this->rsaVerify($content, $public_key_path, $sign); } /** * 過濾引數,去除sign/sign_type引數 * @param $params * @return <Array> */ function filterSignParameter($params) { $result = array(); foreach ($params as $key => $value) { if ($key != 'sign' && $key != 'sign_type' && $value) { $result[$key] = $value; } } return $result; } /** * RSA驗籤,注意驗籤的公鑰是支付寶的公鑰,不是自己生成的rsa公鑰,可以在淘寶的demo中獲得 * @param $data string 待簽名資料 * @param $ali_public_key_path string 支付寶的公鑰檔案路徑 * @param $sign string 要校對的的簽名結果 * @return <Boolean> 驗證結果 * @throws Exception */ function rsaVerify($data, $ali_public_key_path, $sign) { $pubKey = file_get_contents($ali_public_key_path); $res = openssl_get_publickey($pubKey); if(!$res){ throw new \Exception('公鑰格式錯誤'); } $result = (bool)openssl_verify($data, base64_decode($sign), $res); openssl_free_key($res); return $result; } function verifyFromServer($notify_id) { $transport = "http"; $partner = "xxxxxxxxxxx"; $cacert = "./Public/key/cacert.pem"; $transport = strtolower(trim($transport)); $partner = trim($partner); $veryfy_url = "http://notify.alipay.com/trade/notify_query.do?partner=$partner¬ify_id=$notify_id"; $curl = curl_init($veryfy_url); curl_setopt($curl, CURLOPT_HEADER, 0); // 過濾HTTP頭 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL證書認證 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//嚴格認證 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);// 顯示輸出結果 curl_setopt($curl, CURLOPT_CAINFO, $cacert);//證書地址 $responseText = curl_exec($curl); // var_dump( curl_error($curl) );//如果執行curl過程中出現異常,可開啟此開關,以便檢視異常內容 curl_close($curl); return $responseText; }
      /**格式化公鑰
    * $pubKey PKCS#1格式的公鑰串
    * return pem格式公鑰, 可以儲存為.pem檔案
    */
   function formatPubKey($pubKey) {
       $fKey = "-----BEGIN PUBLIC KEY-----\n";
       $len = strlen($pubKey);
       for($i = 0; $i < $len; ) {
           $fKey = $fKey . substr($pubKey, $i, 64) . "\n";
           $i += 64;
       }
       $fKey .= "-----END PUBLIC KEY-----";
       return $fKey;
   }
}
問題諮詢QQ1370373713http://blog.csdn.net/apensu/article/details/46945193

相關推薦

APP支付支付生成客戶簽名

<?php namespace Pn\Controller; use Think\Controller\RestController; class PayController extends RestController{ public function __

JAVA支付APP支付,提現,退款

公共引數圖表:       介面需要引數通知方式支付寶APP支付應用公鑰,應用私鑰非同步支付寶APP提現應用公鑰,應用私鑰,支付寶公鑰同步支付寶APP退款應用公鑰,應用私鑰,支付寶公鑰同步微信APP支付APPID,商戶號,api_key支付金鑰非同步微信APP提現APPID,

一個二維碼支援支付支付

開發十年,就只剩下這套Java開發體系了 >>>        一個二維碼同時支援微信和支付寶掃描的原理很簡單,就是中間做了一個跳轉,判斷使用者用的是什麼瀏覽器請求的即可。     這裡首先要說清楚的是支

React Native (IOSAndroid) 支付支付整合實戰支付Android篇

序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。 支付

React Native (IOSAndroid) 支付支付整合實戰IOS篇

序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。 微信

支付APP支付 java服務程式碼

支付寶和微信支付的接入基本只需要看官方文件就能很好的弄明白,這裡我做記錄一些我在接入是寫demo 首先需要建立一個配置管理的類: public final class ZhifubaoConfig { /** * 應用號 */ publ

React Native (IOSAndroid) 支付支付整合實戰支付服務

序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。 微信

React Native (IOSAndroid) 支付支付整合實戰支付服務

序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。 支

有了支付為什麽要用聚合支付

聚合支付 在街上 近期好多網友朋友咨詢聚合支付產品是什麽!我有支付寶跟微信了,要聚合支付有什麽用?今天這邊我們就針對這個問題做個闡述! 首先我們先來了解下什麽是聚合支付,聚合支付也稱第四方支付,它只是把支付寶、微信、銀行這些機構的資金通道做了集成,並

JS處理支付(同步提交/非同步提交)方式

PHP交流群:294088839 Python交流群:652376983 GO交流群:874512552 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title&

銀行紛紛斷開與支付機構直連,那支付支付還能用嗎?

近日,包括中國銀行、交通銀行、中信銀行、光大銀行等在內多家銀行宣佈,將關閉原直連業務模式下與持牌第三方支付機構的合作通道,範圍包括協議支付、閘道器支付、付款業務及通過支付機構客戶備付金賬戶發生的代收付業務。有些人或許會擔心,在銀行關閉與支付機構的合作通道後,對我們使用微信、支付寶等三方支付平

支付移動支付的個人總結

今天在看了移動支付的文件,對整個流程都有了自己的理解,在這裡記錄下來自己的總結,把裡面的邏輯都整理一遍 一、支付寶支付 先去看官方的支付文件,連結如下 1、先說前期準備,關鍵就是要生成一對公鑰和私鑰,這個看官方文件,現在官方有個自動生成工具,其實挺方便的。注意的是如

來聊聊支付支付

學習 不同 人的 一個人 同事 微信支付 就會 感覺 吃飯 最近支付寶像是瘋了一樣,開始瘋狂地推紅包活動。紅包,可以激發人的貪性。成千上萬的民眾,像瘋了一樣,開始義無反顧地加入了這場紅包盛宴中。 於是,我們的微博、朋友圈都被支付寶紅包占領了;去飯館吃飯,老板主動拿二維碼讓你

Android 支付支付整合

場景 隨著移動支付的興起,在我們的app中,會經常有整合支付的需求.這時候一般都會採用微信和支付寶的sdk 來整合 支付寶支付 在使用支付寶支付的過程中,我們是在伺服器端生成訂單,客戶端訪問介面,得到訂單資訊.然後調起支付,支付成功後支付寶會分別 非同步呼叫伺服器端

支付失敗解決辦法

按照支付寶的文件,呼叫rsaCheckV1的方法,他已經把方法封裝的很透徹了,只需要將取到的引數Map(request.getParameterMap())集合放入即可。但是驗籤一直不通過,查了很多資料,說公鑰不對,應該使用支付寶公鑰,不是應用公鑰,修改之後,還是驗籤不通過。

支付錯誤 false

支付寶支付使用的是RSA非對稱加密,商戶服務端驗籤為支付寶的公鑰! 檢視入參,出參是否亂碼,若亂碼設定客戶端初始化時請求url為:https://openapi.alipay.com/gateway.do?charset=utf-8

thinkphp網站支付非同步失敗問題,發現一個原因點

手頭一個專案,用到了支付寶手機網站支付,專案用tp做的,下載支付寶SDK後修改後調起正常,同步介面也可訪問,但非同步介面驗籤總是錯誤失敗,fail,追蹤到AopClient.php的580行,下段程式碼處 if ("RSA2" == $signType)

面試常見測試場景-杯子,筆,直播,客戶伺服器

1,看直播卡原因 網速慢。記憶體不足。頁面快取過多。電腦中毒。瀏覽器版本低 2,微信傳送測試 功能點:傳送內容(空白,正常文字,超長文字,特殊字元,表情,圖片,紅包,語音) 傳送物件(普通使用者,公眾號,群,其它特殊主體) 衍生功能(轉發,語音轉文字,刪除,撤回)

iOS客戶升級核心對自定義分享的影響

       上週,業務同學反應,公司的商品詳情頁,在有的Iphone手機上自定義分享資訊失效。在自己手機上一直無法重現,在一個同事的手機上也重現了。       &

[第三方客戶]wewechat免費版

wewechat mac版是mac上一款製作精良的微信第三方開源客戶端,wewechat mac版基於 React + Electron + 微信 Web 開發,目前具備的功能已足夠日常使用,包括群聊(新建)、發表情、收紅包、拖拽式發文件、發動圖,甚至是多發訊息功能均已支援。小編現為您帶來wewec