PHP微信支付

1.微信公眾平臺(tái)開通微信支付贬媒,審核通過(guò)。
2.微信商戶平臺(tái)配置支付授權(quán)目錄

Paste_Image.png

3.微信交易單號(hào)獲取類

<?php

/*
 * 生活服務(wù)_微信付款
 */

namespace Apis\Controller;

use Common\Controller\AppframeController;

class WxpayController extends AppframeController {

    protected $mchid;
    protected $appid;
    protected $key;

    public function _initialize() {
        parent::_initialize();

        $this->mchid = '1430532102'; // 微信支付商戶號(hào) PartnerID 通過(guò)微信支付商戶資料審核后郵件發(fā)送
        $this->appid = 'wx20d62ad060e66486'; //公眾號(hào)APPID 通過(guò)微信支付商戶資料審核后郵件發(fā)送
        $this->key = '8934e7d15453e97507ef7mao521125ab';   //https://pay.weixin.qq.com 帳戶設(shè)置-安全設(shè)置-API安全-API密鑰-設(shè)置API密鑰
    }

    public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp) {
        
        $config = array(
            'mch_id' => $this->mchid,
            'appid' => $this->appid,
            'key' => $this->key,
        );
        
        $unified = array(
            'appid' => $config['appid'],
            'attach' => '支付', //商家數(shù)據(jù)包肘习,原樣返回
            'body' => $orderName,
            'mch_id' => $config['mch_id'],
            'nonce_str' => $this->createNonceStr(),
            'notify_url' => $notifyUrl,
            'openid' => $openid, //rade_type=JSAPI际乘,此參數(shù)必傳
            'out_trade_no' => $outTradeNo,
            'spbill_create_ip' => '127.0.0.1',
            'total_fee' => intval($totalFee * 100), //單位 轉(zhuǎn)為分
            'trade_type' => 'JSAPI',
        );
        
        $unified['sign'] = $this->getSign($unified, $config['key']);
        $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($unified));
        
        $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($unifiedOrder === false) {
            die('parse xml error');
        }
        if ($unifiedOrder->return_code != 'SUCCESS') {
            die($unifiedOrder->return_msg);
        }
        if ($unifiedOrder->result_code != 'SUCCESS') {
            die($unifiedOrder->err_code);
            /*
              NOAUTH 商戶無(wú)此接口權(quán)限
              NOTENOUGH 余額不足
              ORDERPAID 商戶訂單已支付
              ORDERCLOSED 訂單已關(guān)閉
              SYSTEMERROR 系統(tǒng)錯(cuò)誤
              APPID_NOT_EXIST   APPID不存在
              MCHID_NOT_EXIST MCHID不存在
              APPID_MCHID_NOT_MATCH appid和mch_id不匹配
              LACK_PARAMS 缺少參數(shù)
              OUT_TRADE_NO_USED 商戶訂單號(hào)重復(fù)
              SIGNERROR 簽名錯(cuò)誤
              XML_FORMAT_ERROR XML格式錯(cuò)誤
              REQUIRE_POST_METHOD 請(qǐng)使用post方法
              POST_DATA_EMPTY post數(shù)據(jù)為空
              NOT_UTF8 編碼格式錯(cuò)誤
             */
        }
        //$unifiedOrder->trade_type 交易類型 調(diào)用接口提交的交易類型,取值如下:JSAPI漂佩,NATIVE脖含,APP
        //$unifiedOrder->prepay_id 預(yù)支付交易會(huì)話標(biāo)識(shí) 微信生成的預(yù)支付回話標(biāo)識(shí)罪塔,用于后續(xù)接口調(diào)用中使用,該值有效期為2小時(shí)
        //$unifiedOrder->code_url 二維碼鏈接 trade_type為NATIVE是有返回养葵,可將該參數(shù)值生成二維碼展示出來(lái)進(jìn)行掃碼支付
        $arr = array(
            "appId" => $config['appid'],
            "timeStamp" => $timestamp,
            "nonceStr" => $this->createNonceStr(),
            "package" => "prepay_id=" . $unifiedOrder->prepay_id,
            "signType" => 'MD5',
        );
        $arr['paySign'] = $this->getSign($arr, $config['key']);
        return $arr;
    }

    public function notify() {
        $config = array(
            'mch_id' => $this->mchid,
            'appid' => $this->appid,
            'key' => $this->key,
        );
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj === false) {
            die('parse xml error');
        }
        if ($postObj->return_code != 'SUCCESS') {
            die($postObj->return_msg);
        }
        if ($postObj->result_code != 'SUCCESS') {
            die($postObj->err_code);
        }
        $arr = (array) $postObj;
        unset($arr['sign']);
        if ($this->getSign($arr, $config['key']) == $postObj->sign) {
            // $mch_id = $postObj->mch_id; //微信支付分配的商戶號(hào)
            // $appid = $postObj->appid; //微信分配的公眾賬號(hào)ID
            // $openid = $postObj->openid; //用戶在商戶appid下的唯一標(biāo)識(shí)
            // $transaction_id = $postObj->transaction_id;//微信支付訂單號(hào)
            // $out_trade_no = $postObj->out_trade_no;//商戶訂單號(hào)
            // $total_fee = $postObj->total_fee; //訂單總金額征堪,單位為分
            // $is_subscribe = $postObj->is_subscribe; //用戶是否關(guān)注公眾賬號(hào),Y-關(guān)注关拒,N-未關(guān)注佃蚜,僅在公眾賬號(hào)類型支付有效
            // $attach = $postObj->attach;//商家數(shù)據(jù)包,原樣返回
            // $time_end = $postObj->time_end;//支付完成時(shí)間
            echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $postObj;
        }
    }

    /**
     * curl get
     *
     * @param string $url
     * @param array $options
     * @return mixed
     */
    public static function curlGet($url = '', $options = array()) {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https請(qǐng)求 不驗(yàn)證證書和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    public static function curlPost($url = '', $postData = '', $options = array()) {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //設(shè)置cURL允許執(zhí)行的最長(zhǎng)秒數(shù)
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https請(qǐng)求 不驗(yàn)證證書和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    public static function createNonceStr($length = 16) {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $str = '';
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    public static function arrayToXml($arr) {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 例如:
     * appid:  wxd930ea5d5a258f4f
     * mch_id:  10000100
     * device_info: 1000
     * Body:  test
     * nonce_str: ibuaiVcKdpRxkhJA
     * 第一步:對(duì)參數(shù)按照 key=value 的格式着绊,并按照參數(shù)名 ASCII 字典序排序如下:
     * stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_i
     * d=10000100&nonce_str=ibuaiVcKdpRxkhJA";
     * 第二步:拼接支付密鑰:
     * stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d"
     * sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
     */
    public static function getSign($params, $key) {
        ksort($params, SORT_STRING);
        $unSignParaString = self::formatQueryParaMap($params, false);
        $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
        return $signStr;
    }

    protected static function formatQueryParaMap($paraMap, $urlEncode = false) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && "null" != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k . "=" . $v . "&";
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

}

//方法調(diào)用
$res = $wx->createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp);

3.回調(diào)函數(shù)

<?php
header('Content-Type: text/html; charset=utf-8');
$mysql_server_name='localhost'; //改成自己的mysql數(shù)據(jù)庫(kù)服務(wù)器
$mysql_username='root'; //改成自己的mysql數(shù)據(jù)庫(kù)用戶名
$mysql_password='Pa1mtrends'; //改成自己的mysql數(shù)據(jù)庫(kù)密碼
$mysql_database='cloud'; //
$conn=mysql_connect($mysql_server_name,$mysql_username,$mysql_password) or die("error connecting") ; //連接數(shù)據(jù)庫(kù)
mysql_query("set names 'utf8'"); //數(shù)據(jù)庫(kù)輸出編碼 應(yīng)該與你的數(shù)據(jù)庫(kù)編碼保持一致.南昌網(wǎng)站建設(shè)公司百恒網(wǎng)絡(luò)PHP工程師建議用UTF-8 國(guó)際標(biāo)準(zhǔn)編碼.
mysql_select_db($mysql_database); //打開數(shù)據(jù)庫(kù)

$mchid = '143053xxxx'; // 微信支付商戶號(hào) PartnerID 通過(guò)微信支付商戶資料審核后郵件發(fā)送
$appid = 'wx20d62ad06xxxxx'; //公眾號(hào)APPID 通過(guò)微信支付商戶資料審核后郵件發(fā)送
$key = '8934e7d15453e97507ef7mao5xxxxxx';   //https://pay.weixin.qq.com 帳戶設(shè)置-安全設(shè)置-API安全-API密鑰-設(shè)置API密鑰

$config = array(
    'mch_id' => $mchid,
    'appid' => $appid,
    'key' => $key,
);

$postStr = file_get_contents("php://input");
if (!$postStr) {
    $postStr = "maozi";
}

$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

if ($postObj === false) {
    die('parse xml error');
}
if ($postObj->return_code != 'SUCCESS') {
    die($postObj->return_msg);
}
if ($postObj->result_code != 'SUCCESS') {
    die($postObj->err_code);
}
$arr = (array) $postObj;
unset($arr['sign']);

if (getSign($arr, $config['key']) == $postObj->sign) {
    
    $mch_id = $postObj->mch_id; //微信支付分配的商戶號(hào)
    $appid = $postObj->appid; //微信分配的公眾賬號(hào)ID
    $openid = $postObj->openid; //用戶在商戶appid下的唯一標(biāo)識(shí)
    $transaction_id = $postObj->transaction_id;//微信支付訂單號(hào)
    $out_trade_no = $postObj->out_trade_no;//商戶訂單號(hào)
    $total_fee = $postObj->total_fee; //訂單總金額谐算,單位為分
    $total_fee = floatval($total_fee/100);
    
    $time_end = $postObj->time_end;//支付完成時(shí)間
    $time_end = strtotime(substr($time_end,0,4)."-".substr($time_end, 4,2)."-".substr($time_end,6,2)." ".substr($time_end,8,2).":".  substr($time_end, 10, 2).":".substr($time_end, 12, 2));
    
    //用戶id
    $res = mysql_query("select * from cmf_market_order where sn='{$out_trade_no}'",$conn);
    $oinfo = mysql_fetch_assoc($res);
    $uid = $oinfo['uid'];
    
    //查詢訂單是否存在
    $has_sql = "select * from cmf_market_order_wx where wx_sn='{$transaction_id}'";
    $has = mysql_query($has_sql,$conn);
    $has = mysql_fetch_assoc($has);
    if ($has) {
        echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
        exit;
    }
    
    //插入微信訂單信息
    $sql = "insert into cmf_market_order_wx (mch_id,appid,openid,uid,sn,wx_sn,total,time) values ('{$mch_id}','{$appid}','{$openid}','{$uid}','{$out_trade_no}','{$transaction_id}','{$total_fee}','{$time_end}')";
    $result = mysql_query($sql,$conn);
    if ($result) {//更新訂單狀態(tài)
        $up_sql = "update cmf_market_order set haspay=1,status=1,paytime='{$time_end}' where sn='{$out_trade_no}'";
        $result_update = mysql_query($up_sql,$conn);
    }
    
    echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
    return $postObj;
}

function getSign($params, $key) {
    ksort($params, SORT_STRING);
    $unSignParaString = formatQueryParaMap($params, false);
    $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    return $signStr;
}

function formatQueryParaMap($paraMap, $urlEncode = false) {
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v) {
        if (null != $v && "null" != $v) {
            if ($urlEncode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
    }
    $reqPar = '';
    if (strlen($buff) > 0) {
        $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
}

?>

4.支付頁(yè)面,直接調(diào)用支付接口

<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <title>微信安全支付</title>
    
    
    <script type="text/javascript">
        //調(diào)用微信JS api 支付
        function jsApiCall()
        {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest',
                {
                    "appId": "{$info['appId']}",
                    "timeStamp": "{$info['timeStamp']}",
                    "nonceStr": "{$info['nonceStr']}",
                    "package": "{$info['package']}",
                    "signType": "MD5",
                    "paySign": "{$info['paySign']}"
                },
                function(res){
                    if (res.err_msg == 'get_brand_wcpay_request:ok') {
                        alert("支付成功");
                        window.location.;
                    } else {
                        alert("錯(cuò)誤");
                    }
                }
            );
        }
        function callpay()
        {
            if (typeof WeixinJSBridge == "undefined"){
                if( document.addEventListener ){
                    document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
                }else if (document.attachEvent){
                    document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
                    document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                }
            }else{
                jsApiCall();
            }
        }
    </script>
</head>
<body>
    </br></br></br></br>
    <div align="center">
        <button style="width:210px; height:30px; background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >貢獻(xiàn)一下11111111</button>
    </div>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末归露,一起剝皮案震驚了整個(gè)濱河市洲脂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剧包,老刑警劉巖恐锦,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異玄捕,居然都是意外死亡踩蔚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門枚粘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)馅闽,“玉大人,你說(shuō)我怎么就攤上這事馍迄「R玻” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵攀圈,是天一觀的道長(zhǎng)暴凑。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赘来,這世上最難降的妖魔是什么现喳? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮犬辰,結(jié)果婚禮上嗦篱,老公的妹妹穿的比我還像新娘。我一直安慰自己幌缝,他們只是感情好灸促,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般浴栽。 火紅的嫁衣襯著肌膚如雪荒叼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天典鸡,我揣著相機(jī)與錄音咽笼,去河邊找鬼叔壤。 笑死鼻由,一個(gè)胖子當(dāng)著我的面吹牛涩馆,可吹牛的內(nèi)容都是我干的审洞。 我是一名探鬼主播庵佣,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼是己,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼白筹!你這毒婦竟也來(lái)了挖诸?” 一聲冷哼從身側(cè)響起汁尺,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎多律,沒(méi)想到半個(gè)月后痴突,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狼荞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年辽装,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片相味。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拾积,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出丰涉,到底是詐尸還是另有隱情拓巧,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布一死,位于F島的核電站肛度,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏投慈。R本人自食惡果不足惜承耿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伪煤。 院中可真熱鬧加袋,春花似錦、人聲如沸带族。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至阳堕,卻和暖如春跋理,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恬总。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工前普, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壹堰。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓拭卿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贱纠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峻厚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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