摘要:微信公眾號支付就是微信商城的一種支付方式,微信支付隨著微信的推廣使用也被廣泛應用。微信公眾平臺的地址是。代碼分析我們需要獲取到關注微信公眾號的人的。回調的方法使用以上就是我的微信支付。
序言
隨著微信被越來越多的人使用,微信商城成為如今的熱門。每一個商城都需要有自己的支付方式,微信商城也不例外。微信公眾號支付就是微信商城的一種支付方式,微信支付隨著微信的推廣使用也被廣泛應用。今天我主要講的是yii2嵌入微信公眾號支付,微信官網的微信支付文檔比較簡潔,接下來跟著我來看一下yii2如何嵌入微信公眾號支付,以及需要注意的事項吧!
前期準備工作
首先必須有一個微信公眾號,并且需要在微信公眾平臺申請微信支付。微信公眾平臺的地址是:https://mp.weixin.qq.com/cgi-bin/loginpage。申請的過程我這邊就不寫了,錄公眾平臺以后就可以看到。
其次需要先配置一個域名,必須是80端口,然后在申請完微信支付以后配置上支付授權目錄。
準備工作完成以后我們可以開始開發了。
代碼分析
1、我們需要獲取到關注微信公眾號的人的openid。獲取openid,我這邊是通過網頁授權獲取用戶基本信息接口獲取的。其實在github上已經有封裝好的關于微信的開發的接口,我們可以直接從上面下載,以后基于yii2的開發微信的其他的功能可以使用。網址是:https://github.com/callmez/yii2-wechat-sdk 大家可以下載然后安裝。我的openid的獲取也是在此基礎上更改的。安裝完成以后的目錄結構如下圖:
我這邊使用的是MpWechat.php,在MpWechat.php中我增加了一個方法獲取openid。
public function getOpenid($turl) { if (!isset($_GET["code"])){ //觸發微信返回code碼 $url=$this->getOauth2AuthorizeUrl($turl, $this->state, "snsapi_userinfo"); Header("Location: $url"); exit(); } else { //獲取code碼,以獲取openid $code = $_GET["code"]; $access_info = $this->getOauth2AccessToken($code); return $access_info; } }
$turl是獲取到code以后需要跳轉的地址。
在控制其中獲取openid我是這樣寫的:
public function actionView($id) { $openid=isset($_COOKIE["openid"])?$_COOKIE["openid"]:""; if(empty($openid)) { $t_url=Url::to(["@web/clue/view?id=".$id],true);//這個是獲取到code以后需要跳轉的url。Url這個是在頭部需要增加:use yiihelpersUrl $info=$this->wechat->getOpenid($t_url);//注:$this->wechat安裝完成yii2-wechat-sdk以后配置以后可以使用 if($info){ setcookie("access_token",$info["access_token"],time()+86400*365); setcookie("openid",$info["openid"],time()+86400*365); } } }
將獲取到的openid放入的cookie中儲存。
2、openid獲取以后可以進行開發微信支付,我這邊將微信支付封裝成了一個類,可以配置訪問。
第一步、我們可以在common/config/main.php中配置
return [ "vendorPath" => dirname(dirname(__DIR__)) . "/vendor", "language" => "zh-CN", // 啟用國際化支持 "sourceLanguage" => "zh-CN", // 源代碼采用中文 "timeZone" => "Asia/Shanghai", // 設置時區 "components" => [ "cache" => [ "class" => "yiicachingFileCache", ], "user" => [ "identityClass" => "loginmodelsUser", "enableAutoLogin" => false, //開啟authTimeout失效 "identityCookie" => ["name" => "_identity", "httpOnly" => true,"domain" => "." . DOMAIN], // "returnUrl"=>"http://" . DOMAIN_HOME, "authTimeout" => 24*3600*30, // 30 days ], "session" => [ "timeout" => 24*3600*30, // 30 days "useCookies" => true, "cookieParams" => [ "domain" => "." . DOMAIN, "lifetime" => 24*3600*30, ], ], //這個是支付的 "payment" => [ "class"=>"commonwidgetspaymentInstance", "weixinjspi_config" => [ "code" => 2, "appid" => "wx88ee3ca8c06be5c6",//微信的appid "secret" => "48180f87c2693d50b29d822d019999",//appsecret,在申請完公眾號以后可以看到 "mch_id" => "13260614455",//商戶號 "key" => "16ceshi",//key需要設置 "cert_path" => "",//可以不用填寫 "key_path" => "",//可以不用填寫 ], ], ],
我上面的appid、key等都是錯誤信息需要你們根據自己申請的微信支付進行填寫
第二步、在commonwidgets中加入payment文件夾,在文件夾中增加Instance.php
weixin_config = $config; } public function setWeixins_config($config) { $this->weixins_config = $config; } public function setWeixinjspi_config($config) { $this->weixinjspi_config = $config; } public function setAlipay_config($config) { $this->alipay_config = $config; } public function setBalance_config($config) { $this->balance_config = $config; } /** * 組合使用余額支付和其他支付 * @param $order * @param $payment * @param $balance */ public function unionPay($order,$payment,$balance,$notify) { $res = []; $total_fee = $order["total_fee"]; if($balance > 0) { $pay = $this->getBalance(); if($balance >= $total_fee) { $res["balance"] = $pay->pay($order); return $res; } else { $order["total_fee"] = $balance; $res["balance"] = $pay->pay($order); $total_fee -= $balance; } } $order["total_fee"] = $total_fee; $pay = $this->$payment; $pay->setNotifyUrl($notify); $res[$payment] = $pay->prepay($order); //$res[$payment]["balance"] = $balance; return $res; } /** * 獲得支付寶支付 * @param null $notify_url * @return mixed|object */ public function getAlipay($notify_url = null) { $this->alipay_config = array_merge(["class"=>Alipay::className()],$this->alipay_config); //"var_dump($this->alipay_config);exit; return $this->_getPayment("_alipay",$notify_url); } /** * 獲得微信app c端支付 * @param null $notify_url * @return mixed|object */ public function getWeixin($notify_url = null) { $this->weixin_config = array_merge(["class"=>Weixin::className()],$this->weixin_config); return $this->_getPayment("_weixin",$notify_url); } /** * 獲得手機微信端支付 * @param null $notify_url * @return mixed|object */ public function getWeixinjspi($notify_url = null) { $this->weixinjspi_config = array_merge(["class"=>Weixinjspi::className()],$this->weixinjspi_config); return $this->_getPayment("_weixinjspi",$notify_url); } /** * 獲得微信app s端支付 * @param null $notify_url * @return mixed|object */ public function getWeixins($notify_url = null) { $this->weixins_config = array_merge(["class"=>Weixin::className()],$this->weixins_config); return $this->_getPayment("_weixins",$notify_url); } /** * 獲得余額支付 * @return mixed|object */ public function getBalance() { $this->balance_config = array_merge(["class"=>Balance::className()],$this->balance_config); return $this->_getPayment("_balance",null); } /** * @param $name * @param $notify_url * @return mixed|object * @throws yiiaseInvalidConfigException */ private function _getPayment($name, $notify_url) { $config = substr($name."_config",1); if(is_null($this->{$name})) { $this->{$name} = Yii::createObject($this->{$config}); } if(!is_null($notify_url)) { $this->{$name}->setNotifyUrl($notify_url); } return $this->{$name}; } }
這個類其實是結合了其他的支付方式,其中現在最主要的是getWeixinjspi($notify_url = null)這個方法。
除了這個還需要增加Weixinjspi.php
appid = $appid; } public function setKey($key) { $this->key = $key; } public function setSecret($secret) { $this->secret = $secret; } public function setKey_path($key_path) { $this->key_path = Yii::getAlias($key_path); } public function setCert_path($cert_path) { $this->cert_path = Yii::getAlias($cert_path); } public function setMch_id($mch_id) { $this->mch_id = $mch_id; } public function init() { parent::init(); $needs = array("appid","mch_id","key","secret"); foreach($needs as $need) { if(empty($this->{$need})) { throw new InvalidConfigException(get_class($this) . " must define weixin"s params {$need}."); } } } private function _checkRefund() { $needs = array("key_path","cert_path"); foreach($needs as $need) { if(empty($this->{$need})) { throw new InvalidConfigException(get_class($this) . " must define weixin"s params {$need}."); } } } /** * jsapi支付接口 * @param $order * @return mixed */ public function pay($order) { $paras = [ "body" =>$order["goods_desc"],//設置商品或支付單簡要描述 "attach" =>"PC",//設置附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據 "out_trade_no" =>$this->order_pre.$order["order_sn"],//訂單號 "total_fee" =>(int)($order["total_fee"] * 100),//訂單總金額 "detail" =>$order["body"], "time_start" =>empty($order["time_start"])? "":$order["time_start"], "time_expire" =>empty($order["time_expire"])? "":$order["time_expire"], "goods_tag" =>empty($order["goods_tag"])? "":$order["goods_tag"],//設置商品標記,代金券或立減優惠功能的參數,說明詳見代金券或立減優惠 "notify_url" =>empty($order["notify_url"])? "":$this->setNotifyUrl($order["notify_url"]),//回調地址 "trade_type" =>"JSAPI", "product_id" =>empty($order["order_sn"])? "":$order["order_sn"], "openid" =>empty($order["openid"])? "":$order["openid"], "nonce_str" =>$this->randomStr(), ]; ///var_dump($paras);exit; $timeout = empty($order["timeout"])? 6 :$order["timeout"]; if($order["total_fee"] <= 0) { throw new InvalidValueException(get_class($this) . " 支付金額必須大于0"); } $trade = $this->createOrder($paras,$timeout); if(isset($trade["return_code"]) && $trade["return_code"] == "SUCCESS") { if(isset($trade["result_code"]) && $trade["result_code"] == "SUCCESS") { $data=[ "appId" =>$trade["appid"], "timeStamp"=>"".time()."", "nonceStr" =>$this->randomStr(), "signType"=>"MD5", "package" =>"prepay_id=".$trade["prepay_id"], ]; $data["paySign"]=$this->sign($data); //$data["signature"]=$order["signature"]; $parameters = json_encode($data); return $parameters;//二維碼的信息 } else { return false; } } else { return false; } } public function getJs($parameters,$order_sn) { $str=" "; return $str; } /** * 預支付接口,在APP上發起支付 * @param $order * @return mixed */ public function prepay($order) { $needs = array("title","order_sn","body","total_fee"); foreach($needs as $need) { if(!isset($order[$need])) { throw new InvalidConfigException(get_class($this) . " $order 中必須包含鍵 {$need}."); } } $paras = [ "trade_type" =>"APP", "time_start" =>empty($order["time_start"])? "":$order["time_start"], "time_expire" =>empty($order["time_expire"])? "":$order["time_expire"], "goods_tag" =>empty($order["goods_tag"])? "":$order["goods_tag"], "device_info" =>empty($order["device_info"])? "":$order["device_info"], "out_trade_no" =>$this->order_pre.$order["order_sn"], "detail" =>$order["body"], "total_fee" =>(int)($order["total_fee"] * 100), "body" =>$order["title"], "fee_type" =>empty($order["fee_type"])? "":$order["fee_type"], "product_id" =>empty($order["product_id"])? "":$order["product_id"], "openid" =>empty($order["openid"])? "":$order["openid"], "attach" =>empty($order["attach"])? "":$order["attach"], "notify_url" =>empty($order["notify_url"])? "":$this->setNotifyUrl($order["notify_url"]),//回調地址 ]; $timeout = empty($order["timeout"])? 6 :$order["timeout"]; if($order["total_fee"] <= 0) { throw new InvalidValueException(get_class($this) . " 支付金額必須大于0"); } $trade = $this->createOrder($paras,$timeout); if(isset($trade["return_code"]) && $trade["return_code"] == "SUCCESS") { if(isset($trade["result_code"]) && $trade["result_code"] == "SUCCESS") { $trade["total_fee"] = $order["total_fee"]; return $this->getSign($trade); } else { throw new InvalidValueException(get_class($this) . $trade["err_code_des"]); } } else { throw new InvalidValueException(get_class($this) . $trade["return_msg"]); } } public function getSign($order) { $total_fee = $order["total_fee"]; $keys = ["appid","partnerid","prepayid","package","noncestr","timestamp","sign"]; $order["partnerid"] = $order["mch_id"]; $order["prepayid"] = $order["prepay_id"]; $order = array_intersect_key($order,array_fill_keys($keys,"")); $order["package"] = "Sign=WXPay"; $order["timestamp"] = time(); $order["noncestr"] = $this->randomStr(30); $order["sign"] = $this->sign($order); $order["total_fee"] = $total_fee; return $order; } public function notify() { //獲取通知的數據 $xml = $GLOBALS["HTTP_RAW_POST_DATA"]; //如果返回成功則驗證簽名 //try { $result = $this->fromXml($xml); if($result["return_code"] == "SUCCESS") { $sign = $this->sign($result); if($sign == $result["sign"]) { $result["trade_no"]=$result["transaction_id"]; $result["out_trade_no"]=substr($result["out_trade_no"],strlen($this->order_pre)); $result["trade_status"]="TRADE_SUCCESS"; return $result; } else { return false; } } else { return false; } // } catch (Exception $e){ // throw new InvalidValueException(get_class($this) . $e->errorMessage()); // } } /** * 退款接口 * @param $order * @return mixed */ public function refund($order) { $this->_checkRefund(); $needs = array("order_sn","total_fee"); foreach($needs as $need) { if(!isset($order[$need])) { throw new InvalidConfigException(get_class($this) . " $order 中必須包含鍵 {$need}."); } } $order["out_trade_no"] = $this->order_pre.$order["order_sn"]; $order["total_fee"] = round($order["total_fee"],2) * 100; $order["refund_fee"] = $order["total_fee"]; $order["op_user_id"] = $this->mch_id; $need = array("out_trade_no","out_refund_no","total_fee","refund_fee","op_user_id"); $keys = ["device_info","refund_fee_type","transaction_id"]; foreach($need as $key) { if(empty($order[$key])) { throw new InvalidConfigException("缺少退款申請接口必填參數{$key}!"); } } $order = array_intersect_key($order,array_fill_keys(array_merge($need, $keys),"")); $order["appid"] = $this->appid; $order["mch_id"] = $this->mch_id; $order["nonce_str"] = $this->randomStr(); $order["sign"] = $this->sign($order); $xml = $this->toXml($order); $response = $this->postXmlCurl($xml, $this->refund_url); $result = $this->convertResponse($response); return $result; } /** * Notify處理完成接口 * @return mixed */ public function finish() { $arr = ["return_code"=>"SUCCESS"]; $xml = $this->toXml($arr); return $xml; } /** * 設置Notify回調接口 * @return mixed */ public function setNotifyUrl($url) { $this->notify_url = $url; } /** * 獲得Notify返回的支付金額 * @return mixed */ public function getTotalFee($total_fee = null) { if($total_fee) { return round($total_fee/100,2,PHP_ROUND_HALF_DOWN); } if(isset($this->notify_data["total_fee"])) { return round($this->notify_data["total_fee"]/100,2,PHP_ROUND_HALF_DOWN); } return false; } /** * 獲得Notify返回的交易號 * @return mixed */ public function getSerialNo($arr = null) { if(isset($arr["transaction_id"])) { return $arr["transaction_id"]; } if(isset($this->notify_data["transaction_id"])) { return $this->notify_data["transaction_id"]; } return false; } /** * 獲得Notify返回的原始數據 * @return mixed */ public function getNotifyRaw() { return $GLOBALS["HTTP_RAW_POST_DATA"]; } public function randomStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } public function getIp() { if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) { $arr = explode(",", $_SERVER["HTTP_X_FORWARDED_FOR"]); $strIp = $arr[0]; } elseif (isset($_SERVER["HTTP_CLIENT_IP"])) { $strIp = $_SERVER["HTTP_CLIENT_IP"]; } elseif (isset($_SERVER["REMOTE_ADDR"])) { $strIp = $_SERVER["REMOTE_ADDR"]; } else { $strIp = "0.0.0.0"; } return $strIp; } private function toXml($values) { if(!is_array($values) || count($values) <= 0) { throw new InvalidValueException("數組數據異常!"); } //var_dump($values);exit; $xml = ""; foreach ($values as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."".$key.">"; }else{ $xml.="<".$key.">".$key.">"; } } $xml.=" "; //echo $xml;exit; return $xml; } private function fromXml($xml) { if(!$xml){ throw new InvalidValueException("xml數據異常!"); } try { $values = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true); } catch(Exception $e) { throw new InvalidValueException("xml數據異常!"); } return $values; } public function sign($values) { ksort($values); $string = ""; foreach ($values as $k => $v) { if($k != "sign" && $v != "" && !is_array($v)){ $string .= $k . "=" . $v . "&"; } } $string = trim($string, "&"); $string = $string . "&key=".$this->key; $string = md5($string); return strtoupper($string); } public function checkSign($values) { if($this->sign($values) == $values["sign"]){ return true; } throw new InvalidValueException("驗證簽名錯誤!"); } private function convertResponse($xml) { $result = $this->fromXml($xml); if($result["return_code"] != "SUCCESS") { throw new InvalidValueException($result["return_msg"]); } if($this->checkSign($result) === true){ return $result; }else{ return false; } } public function searchOrder($out_trade_no, $transaction_id = "",$timeOut = 6) { if(empty($out_trade_no) && empty($transaction_id)) { throw new InvalidValueException("缺少訂單查詢接口必填參數out_trade_no或transaction_id!"); } $order = ["out_trade_no"=>$out_trade_no,"transaction_id"=>$transaction_id]; $order["appid"] = $this->appid; $order["mch_id"] = $this->mch_id; $order["nonce_str"] = $this->randomStr(); $order["sign"] = $this->sign($order); $xml = $this->toXml($order); $response = $this->postXmlCurl($xml, $this->search_order_url, false, $timeOut); $result = $this->convertResponse($response); return $result; } public function closeOrder($out_trade_no, $timeOut = 6) { if(empty($out_trade_no)) { throw new InvalidValueException("缺少訂單查詢接口必填參數out_trade_no!"); } $order = ["out_trade_no"=>$out_trade_no]; $order["appid"] = $this->appid; $order["mch_id"] = $this->mch_id; $order["nonce_str"] = $this->randomStr(); $order["sign"] = $this->sign($order); $xml = $this->toXml($order); $response = $this->postXmlCurl($xml, $this->close_order_url, false, $timeOut); $result = $this->convertResponse($response); return $result; } public function createOrder(array $order, $timeOut = 6) { //檢測必填參數 $need = array("out_trade_no","body","total_fee","trade_type"); $keys = array("appid","mch_id","device_info","nonce_str","sign","detail","attach","fee_type", "spbill_create_ip","time_start","time_expire","goods_tag","notify_url","product_id","openid"); $keys = array_merge($need,$keys); foreach($need as $key) { if(empty($order[$key])) { throw new InvalidValueException("缺少統一下單接口必填參數{$key}!"); } } //關聯參數 if($order["trade_type"] == "JSAPI" && empty($order["openid"])){ throw new InvalidValueException("統一支付接口中,缺少必填參數openid!trade_type為JSAPI時,openid為必填參數!"); } if($order["trade_type"] == "NATIVE" && empty($order["product_id"])){ throw new InvalidValueException("統一支付接口中,缺少必填參數product_id!trade_type為JSAPI時,product_id為必填參數!"); } $order = array_intersect_key($order,array_fill_keys($keys,"")); $order["appid"] = $this->appid; $order["mch_id"] = $this->mch_id; $order["notify_url"] = $this->notify_url; $order["spbill_create_ip"] = $this->getIp(); $order["nonce_str"] = $this->randomStr(); $order["sign"] = $this->sign($order); $xml = $this->toXml($order); // var_dump( $order["notify_url"] );exit; $response = $this->postXmlCurl($xml, $this->order_url, false, $timeOut); //var_dump($response);exit; $result = $this->convertResponse($response); return $result; } public function searchRefund($order, $timeOut = 6) { $keys = ["out_refund_no","out_trade_no","transaction_id","refund_id"]; if(empty($order["out_trade_no"]) && empty($order["transaction_id"]) && empty($order["out_refund_no"]) && empty($order["refund_id"])) { throw new InvalidValueException("退款查詢接口中,out_refund_no、out_trade_no、transaction_id、refund_id四個參數必填一個!"); } $order = array_intersect_key($order,array_fill_keys($keys,"")); $order["appid"] = $this->appid; $order["mch_id"] = $this->mch_id; $order["nonce_str"] = $this->randomStr(); $order["sign"] = $this->sign($order); $xml = $this->toXml($order); $response = $this->postXmlCurl($xml, $this->search_refund_url, true, $timeOut); $result = $this->convertResponse($response); return $result; } private function postXmlCurl($xml, $url, $useCert = false, $second = 30) { $ch = curl_init(); //設置超時 curl_setopt($ch, CURLOPT_TIMEOUT, $second); //如果有配置代理這里就設置代理 if($this->curl_proxy_host != "0.0.0.0" && $this->curl_proxy_port != 0){ curl_setopt($ch,CURLOPT_PROXY, $this->curl_proxy_host); curl_setopt($ch,CURLOPT_PROXYPORT, $this->curl_proxy_port); } curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); //設置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求結果為字符串且輸出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if($useCert == true && !empty($this->cert_path) && !empty($this->key_path)){ //設置證書 //使用證書:cert 與 key 分別屬于兩個.pem文件 curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLCERT, $this->cert_path); curl_setopt($ch,CURLOPT_SSLKEYTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLKEY, $this->key_path); } //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //運行curl $data = curl_exec($ch); //返回結果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); throw new InvalidValueException("curl出錯,錯誤碼:{$error}"); } } }
還需要增加一個Notifyurl.php
payment->$funame(); $result=$respmodel->notify(); if($result){ //商戶訂單號 $out_trade_no = $result["out_trade_no"]; //交易號 $trade_no = $result["trade_no"]; //交易狀態 $trade_status = $result["trade_status"]; if ($trade_status == "TRADE_SUCCESS") { $this->update_status($out_trade_no,$trade_no,1); echo "success"; }else{ echo "fail"; } }else{ echo "fail"; } } //支付狀態更改 public function update_status($out_trade_no,$trade_no,$pay_status) { } } ?>
第三步、我們如何使用呢,
在我們需支付的controller中,
//微信支付
public function actionWeixinpay() { $openid=isset($_COOKIE["openid"])?$_COOKIE["openid"]:""; if($openid) { $order_=[ "goods_desc"=>"測試", "order_sn" =>"2222", "total_fee" =>12, "body"=>"測試", "time_start" =>date("YmdHis"), "time_expire"=>date("YmdHis", time() + 86400*300), "goods_tag" =>"", "notify_url"=>Url::to(["@web/respond/updatepay"],true),//這是回調地址,微信通知的地址 "openid"=>$openid, ]; $paymodel=Yii::$app->payment->getWeixinjspi(); $result=$paymodel->pay($order_);//生成預付單 if($result) { $jsstr=$paymodel->getJs($result,$order_["order_sn"]); //根據預付單信息生成js,詳細的可以看上面的類的方法。 } } echo $jsstr; }
第四步、在view層我們可以這樣寫:
我這邊是采用的ajax的形式進行支付的,可以根據自己的情況進行調整
第五步、支付最重要的是需要回調,yii2增加了Csrf驗證,禁止了外部的訪問,我們在控制其中寫回調方法的時候必須增加:
public function beforeAction($action) { $this->enableCsrfValidation = false; return parent::beforeAction($action); }
不然微信將訪問不到。
回調的方法使用:
use commonwidgetspaymentWeixinjspi; use commonwidgetspaymentNotifyurl; public function actionUpdatepay() { $model=new Notifyurl(); $model->notify("Weixinjspi"); }
以上就是我的微信支付。
第一次寫文章,有不完善的地方請多包涵,有不對的地方請指出我這邊再完善
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21555.html
摘要:多入口模式,多入口分為后臺前端,微信,其他或接口對接,不同的業務不同的設備進入不同的入口。對接微信公眾號,使用了一款優秀的微信非官方,系統內已集成了該,調用方式會在文檔說明,也可直接看其文檔進入深入開發。 RageFrame 為二次開發而生,讓開發變得更簡單。 前言 RageFrame項目創建于2016年4月16日,基于Yii2框架開發的應用開發引擎,目前正在成長中,目的是為了集成更多...
摘要:極致的插件機制,系統內的系統,安裝和卸載不會對原來的系統產生影響強大的功能完全滿足各階段的需求,支持用戶多端訪問后臺微信前臺等,系統中的系統。多入口模式,多入口分為后臺前端,微信,對內接口,對外接口,不同的業務,不同的設備,進入不同的入口。 RageFrame 2.0 為二次開發而生,讓開發變得更簡單 項目地址:https://github.com/jianyan74/... 前言 這...
摘要:極致的插件機制,系統內的系統,安裝和卸載不會對原來的系統產生影響強大的功能完全滿足各階段的需求,支持用戶多端訪問后臺微信前臺等,系統中的系統。多入口模式,多入口分為后臺前端,微信,對內接口,對外接口,不同的業務,不同的設備,進入不同的入口。 RageFrame 2.0 為二次開發而生,讓開發變得更簡單 項目地址:https://github.com/jianyan74/... 前言 這...
摘要:如果讀者對微信開發沒有一個主觀上的認識,那么建議讀者先研讀微信公眾平臺開發者文檔,然后再閱讀本文,效果更佳另外本文的分章節版本可以在八寶粥的博客找到。在中新建微信公眾號后臺配置在微信公眾號后臺配置和,然后提交驗證即可。 本文內容較多,包括微信接入、獲取微信用戶信息、微信支付、JSSDK配置參數獲取等部分。如果讀者對微信開發沒有一個主觀上的認識,那么建議讀者先研讀微信公眾平臺開發者文檔,...
閱讀 3044·2021-11-22 09:34
閱讀 3636·2021-08-31 09:45
閱讀 3836·2019-08-30 13:57
閱讀 1669·2019-08-29 15:11
閱讀 1680·2019-08-28 18:04
閱讀 3218·2019-08-28 17:59
閱讀 1558·2019-08-26 13:35
閱讀 2187·2019-08-26 10:12