从0开始一步一步用Laravel5.2集成原生微信支付
来源:互联网 发布:ubuntu 14.04 16.04 编辑:程序博客网 时间:2024/06/16 03:12
目前微信支付集成到框架里面有太多的坑了,项目中刚好遇到一个,把经验和重要的坑写出来,一步一步从0开始,大家有什么不会的可以留言。
1.首先,我们要去官方下载人家做好的DEMO,链接是https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
2.下载好以后,我们可以把里面的东西放到app\Wechat里(文件夹需要新建)
3.打开lib/WxPay.Config.php,把里面四个重要参数改成自己的,下面有两个证书路径,如果有退款什么的才需要,光支付就不管他
- const APPID = '在你的公众号里看';
- const MCHID = '商户ID';
- const KEY = '自己在公众号设置的32位';
- const APPSECRET = '也在公众号里看';
4.在resource/view/下新建文件夹wechat,里面视图就把app\Wechat里面的jsapi.php改名为jsapi.blade.php放进去,这里要说一下,引用的文件路径,必须是我这种格式“../app/Wechat”下才能正确读取,而且把所有app/Wechat下的各种文件都打开,里面只要用到路径,你就在require_once后面加个“../app/Wechat/”
- <?php
-
- ini_set('date.timezone','Asia/Shanghai');
-
- require_once "../app/Wechat/lib/WxPay.Api.php";
- require_once "../app/Wechat/example/WxPay.JsApiPay.php";
- require_once '../app/Wechat/example/log.php';
-
-
-
- $tools = new JsApiPay();
-
- $openId = $tools->GetOpenid("/wechat?money=".$money);
-
-
- $input = new WxPayUnifiedOrder();
- $input->SetBody("微信支付");
- $input->SetAttach("微信支付");
- $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
- $input->SetTotal_fee($money);
- $input->SetTime_start(date("YmdHis"));
- $input->SetTime_expire(date("YmdHis", time() + 600));
- $input->SetGoods_tag("");
- $input->SetNotify_url("http://aaa.com/wechat/notify");//这里填你的回调路径,是绝对路径,例如http://aaa.com/wechat/notify
- $input->SetTrade_type("JSAPI");
- $input->SetOpenid($openId);
- $order = WxPayApi::unifiedOrder($input);
-
-
- $jsApiParameters = $tools->GetJsApiParameters($order);
-
-
- $editAddress = $tools->GetEditAddressParameters();
-
-
-
-
-
-
-
-
-
-
- ?>
-
- <html>
- <head>
- <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
- <title>微信支付</title>
-
- <script src="http://7xwdxi.com1.z0.glb.clouddn.com/lib/js/jquery-2.0.3.min.js"></script>
-
- <script type="text/javascript">
-
- function jsApiCall()
- {
- WeixinJSBridge.invoke(
- 'getBrandWCPayRequest',
- <?php echo $jsApiParameters; ?>,
- function(res){
-
- WeixinJSBridge.log(res.err_msg);
-
- if (res.err_msg == "get_brand_wcpay_request:ok") {
-
- alert("支付成功!");
- window.location.href="/wechat/do;
- }else if(res.err_msg == "get_brand_wcpay_request:cancel"){
- 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>
- <script type="text/javascript">
-
- function editAddress()
- {
- WeixinJSBridge.invoke(
- 'editAddress',
- <?php echo $editAddress; ?>,
- function(res){
- var value1 = res.proviceFirstStageName;
- var value2 = res.addressCitySecondStageName;
- var value3 = res.addressCountiesThirdStageName;
- var value4 = res.addressDetailInfo;
- var tel = res.telNumber;
-
- alert(value1 + value2 + value3 + value4 + ":" + tel);
- }
- );
- }
-
- window.onload = function(){
- if (typeof WeixinJSBridge == "undefined"){
- if( document.addEventListener ){
- document.addEventListener('WeixinJSBridgeReady', editAddress, false);
- }else if (document.attachEvent){
- document.attachEvent('WeixinJSBridgeReady', editAddress);
- document.attachEvent('onWeixinJSBridgeReady', editAddress);
- }
- }else{
- editAddress();
- }
- };
-
- </script>
-
-
- </head>
- <body>
- <div class="title-bar">
- <span><a href="/home/student/pay"><img src="http://7xwdxi.com1.z0.glb.clouddn.com/images/back-icon.png"></a></span>
- <h1>充值</h1>
- </div>
- <br/>
- <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px"><?php $sum=$money/100; ?>{{$sum}}</span>元钱</b></font><br/><br/>
-
- <div align="center">
- <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
-
- </div>
-
- </body>
- </html>
5.写控制器,新建控制器叫WechatController,主要是回调函数里写好你的逻辑(官方无回调文档,很坑)
- ...
- public function index(Request $request){
- if(!is_numeric(Input::get('money'))){
- return Redirect::back();
- }
- $money = Input::get('money')*10;
-
-
- return view("home.student.jsapi")
- ->withMoney($money);
- }
-
- public function notify(){
- public function notify(Request $request){
- $streamData = isset($GLOBALS['HTTP_RAW_POST_DATA'])? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
-
- if(empty($streamData)){
- $streamData = file_get_contents('php://input');
- }
-
- if($streamData!=''){
- $streamData=xmlToArray($streamData);
- $Data=json_encode($streamData);
- Log::debug('Alipay notify post data verification fail.', [
- 'data' => $Data.'xxxxxx'
- ]);
- if($streamData['return_code'] == 'SUCCESS' && $streamData['result_code'] == 'SUCCESS'){
- try {
-
-
- } catch (Exception $e) {
-
- throw $e;
- }
-
- }
- }else{
- $ret = false;
- }
- }
- }
6.注册路由(这里最好用any的方法,因为发过去是post,回来的是get)- Route::any(‘wechat’,'WechatController@index');
- Route::any(‘wechat/notify’,'WechatController@notify');
7.app/Wechat/example/WxPay.JsApiPay.php里面的getopenid方法还要改一下,否则不能传参数- ...
- public function GetOpenid($addUrl="")
- {
-
- if (!isset($_GET['code'])){
-
-
- $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$addUrl);
-
- $url = $this->__CreateOauthUrlForCode($baseUrl);
- Header("Location: $url");
- exit();
- } else {
-
- $code = $_GET['code'];
- $openid = $this->getOpenidFromMp($code);
- return $openid;
- }
- }
...8.这样程序这块基本就完事了,访问时你要花的钱要这么传http://aaa.com/wechat?money=5(这样的话是充5元钱)9.下面就要说说微信公众平台上,一共要改3个地方
(1)在开发者工具下面,修改网页账号(否则通过不了Oauth2.0验证会报redirect_url错误)
(2)验证你的URL,URL就是这个验证文件在项目中的位置,如果放到public文件夹下,你就直接写http://aaa.com/wx_sample.php
验证文件如下:
wx_sample.php
- <?php
-
-
-
-
-
- define("TOKEN", "weixin");
- $wechatObj = new wechatCallbackapiTest();
- $wechatObj->valid();
-
- class wechatCallbackapiTest
- {
- public function valid()
- {
- $echoStr = $_GET["echostr"];
-
-
- if($this->checkSignature()){
- echo $echoStr;
- exit;
- }
- }
-
- public function responseMsg()
- {
-
- $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
-
-
- if (!empty($postStr)){
-
-
- libxml_disable_entity_loader(true);
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
- $fromUsername = $postObj->FromUserName;
- $toUsername = $postObj->ToUserName;
- $keyword = trim($postObj->Content);
- $time = time();
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[%s]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- <FuncFlag>0</FuncFlag>
- </xml>";
- if(!empty( $keyword ))
- {
- $msgType = "text";
- $contentStr = "Welcome to wechat world!";
- $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
- echo $resultStr;
- }else{
- echo "Input something...";
- }
-
- }else {
- echo "";
- exit;
- }
- }
-
- private function checkSignature()
- {
-
- if (!defined("TOKEN")) {
- throw new Exception('TOKEN is not defined!');
- }
-
- $signature = $_GET["signature"];
- $timestamp = $_GET["timestamp"];
- $nonce = $_GET["nonce"];
-
- $token = TOKEN;
- $tmpArr = array($token, $timestamp, $nonce);
-
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode( $tmpArr );
- $tmpStr = sha1( $tmpStr );
-
- if( $tmpStr == $signature ){
- return true;
- }else{
- return false;
- }
- }
- }
-
- ?>
(3)修改开发配置(支付授权目录和测试授权目录),这里要注意,如果你的支付路径是http://aaa.com/index.php/wechat,你就填http://aaa.com/index.php/,反正就是最后那个斜杠后面的别加