序言

随着微信被越来越多的人使用,微信商城成为如今的热门。每一个商城都需要有自己的支付方式,微信商城也不例外。微信公众号支付就是微信商城的一种支付方式,微信支付随着微信的推广使用也被广泛应用。今天我主要讲的是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 yii\helpers\Url$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' => 'yii\caching\FileCache',],'user' => [            'identityClass' => 'login\models\User','enableAutoLogin' => false,  //开启authTimeout失效'identityCookie' => ['name' => '_identity', 'httpOnly' => true,'domain' => '.' . DOMAIN],// 'returnUrl'=>'//' . 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'=>'common\widgets\payment\Instance','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

<?phpnamespace common\widgets\payment;use yii\base\Component;class Instance extends Component{private $weixin_config;private $weixins_config;private $weixinjspi_config;private $alipay_config;private $balance_config;private $_weixin = null;private $_weixins = null;private $_alipay = null;private $_balance = null;private $_weixinjspi = null;public function setWeixin_config($config){$this->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 \yii\base\InvalidConfigException*/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

<?php
namespace common\widgets\payment;use Yii;
use yii\base\InvalidConfigException;
use yii\base\InvalidValueException;class Weixinjspi extends Payment
{public $order_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';public $search_order_url = 'https://api.mch.weixin.qq.com/pay/orderquery';public $close_order_url = 'https://api.mch.weixin.qq.com/pay/closeorder';public $refund_url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';public $notify_url;public $search_refund_url = 'https://api.mch.weixin.qq.com/pay/refundquery';public $order_pre = 'Weixin';private $appid;private $mch_id;private $key;private $key_path;private $secret;private $cert_path;private $notify_data;private $curl_proxy_host;private $curl_proxy_port;public function setAppid($appid){$this->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="<script type=\"text/javascript\">//调用微信JS api 支付function jsApiCall(){WeixinJSBridge.invoke('getBrandWCPayRequest',".$parameters.",function(res){if(res.err_msg == \"get_brand_wcpay_request:ok\"){$.ajax({type:\"get\",url:\"/clue/pay_status?order_sn=".$order_sn."\",datatype:\"json\",data:{},success: function(data_){window.location.reload();}})alert('支付成功!');}else if(res.err_msg == \"get_brand_wcpay_request:cancel\"){alert('支付过程中用户取消!');}else{alert('支付失败!'); }    });}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>";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 = "<xml>";foreach ($values as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";}}$xml.="</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);//设置headercurl_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

<?phpnamespace common\widgets\payment;
use Yii;
use common\widgets\payment\Weixinjspi;class Notifyurl
{public function notify($code){$funame='get'.$code;$respmodel=Yii::$app->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层我们可以这样写:

<button type="button" class="btn red-sunglo" onclick="pay_(2)" >
<div id="js_"></div>
<script>
//支付function pay_(id){$.ajax({type:"get",url:"/ceshi/weixinpay?id="+id,//这是访问的地址datatype:"json",data:{},success: function(data){if(data!=''){$("#js_").html(data);callpay();}//alert(data);}})}
</script>

我这边是采用的ajax的形式进行支付的,可以根据自己的情况进行调整
第五步、支付最重要的是需要回调,yii2增加了Csrf验证,禁止了外部的访问,我们在控制其中写回调方法的时候必须增加:

public function beforeAction($action) {$this->enableCsrfValidation = false;return parent::beforeAction($action);}

不然微信将访问不到。
回调的方法使用:

 use common\widgets\payment\Weixinjspi;
use common\widgets\payment\Notifyurl;public function actionUpdatepay(){$model=new Notifyurl();$model->notify('Weixinjspi');}

以上就是我的微信支付。
第一次写文章,有不完善的地方请多包涵,有不对的地方请指出我这边再完善

yii2嵌入微信公众号支付相关推荐

  1. java版微信公众号支付

    前言 今天是2020-4-1愚人节,好久没写博客了,今天准备写一篇微信公众号支付,刚好公司给了我账户,让我有参数测试,由于以前对于支付是小白,所以把这个功能打通花了2天,一天8小时,首先看官网文档,其 ...

  2. vue 调用共众url_vue单页面,在微信公众号支付中遇到的URL未注册BUG解决方法-Go语言中文社区...

    今天在做微信公众号支付的时候,遇到一个bug,在当前支付页面点击支付,就会报错,提示当前页面的URL未注册.如下图: 但是,这个URL我们是在后台微信公众号配置了的,所以说不会出错. 但是我们刷新一次 ...

  3. 微信公众号支付调用chooseWXPay提示“errmsg choosewxpay fail”

    微信公众号支付一直提示"errmsg choosewxpay fail",也没有提示具体错误信息,签名没有问题(签名验证地址:https://pay.weixin.qq.com/w ...

  4. 微信公众号页面支付接口java,[Java教程]微信公众号支付(三):页面调用微信支付JS并完成支付...

    [Java教程]微信公众号支付(三):页面调用微信支付JS并完成支付 0 2015-09-15 15:00:30 一.调用微信的JS文件 1.首先要绑定[JS接口安全域名],"公众号设置&q ...

  5. js如何调用h5的日期控价_微信公众号支付H5调用支付解析

    最近项目需要微信支付,然后看了下微信公众号支付,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付 ...

  6. vue 微信公众号支付接口_基于vue的h5项目之支付宝支付与微信支付

    本文仅记录基于vue开发h5项目过程中使用支付宝和微信支付过程中的重点与槽点,仅为前端部分,如有疏漏不正之处,请于文末评论探讨.注意:标红部分灰常重要,仔细阅读官方文档非常重要,耐心非常重要,细心非常 ...

  7. h5通过php微信支付宝支付,用H5调用支付微信公众号支付的解析

    这篇文章主要为大家详细介绍了微信公众号支付H5调用支付,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 最近项目需要微信支付,然后看了下微信公众号支付,虽然不难,但是细节还是需要注意的,用了大半天时 ...

  8. PHP微信公众号支付弹出“NaN:undefined”解决方法

    PHP微信公众号支付弹出"NaN:undefined"解决方法 参考文章: (1)PHP微信公众号支付弹出"NaN:undefined"解决方法 (2)http ...

  9. php调用微信公众号支付接口,Thinkphp微信公众号支付接口

    本文实例为大家分享了Thinkphp微信公众号支付接口,供大家参考,具体内容如下 第一步 先把文件夹的那两个图片 配置成一样的路径 除了域名要改 其他保持一致. 第二步  把 Weixinpay 这个 ...

最新文章

  1. Nature:功能微生物组研究典范—采用甘露糖苷选择性抑制尿路致病性大肠杆菌(Gordon组作品)...
  2. Bootstrap框架中的字形图标的理解
  3. bug最后汇总-2018/08/03
  4. verilog对YCrCb转换灰度设计及仿真
  5. oracle数据库扩展目录,Oracle 扩充磁盘空间
  6. 漫步数学分析三十五——乘法法则与梯度
  7. 解决有效时间的字段的知识查询
  8. 大工20秋《计算机原理》在线作业2答案,奥鹏大工15秋《计算机组成原理》在线作业2满分答案...
  9. How to use neural network to realize logic 'and' and 'or'?
  10. 计算机网络——数据通信系统(三)
  11. (c++)求平均成绩和优秀率
  12. 被“中年危机”榨干的年轻人:如何尽早实现财务自由?
  13. 码云推荐 | 那些优秀的网络爬虫工具介绍
  14. Docker 网络连通
  15. java 返回ro,错误retrofit rxjava优雅的处理服务器返回异常、错误
  16. 宋叔日记--新手级别入门全能赚钱软件!
  17. 2018的穿肠毒药和2019的心灵鸡汤
  18. html点击按钮显示星期,js实现日期显示的一些操作(实例讲解)
  19. 数字旋转方阵c语言主函数,数据结构——递归求数字旋转方阵
  20. NC57 开发小结篇

热门文章

  1. Go 2将添加错误处理和泛型
  2. Redis和消息队列使用实战
  3. thinkPHP 模板的使用技巧(十三)
  4. ReadResolve方法与序列化
  5. 递归查询树状结构某个确定的节点
  6. 无符号256位整数运算
  7. iOS 7 — navigationController is setting the contentInset and ContentOffset of my UIScrollView
  8. 查看PID 进程是否存在的一个小技巧
  9. Ext Tree异步树的增加修改删除的简单实现~
  10. Silverlight导航应用程序Uri映射问题的分析与解决