Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

微信支付相关文档细化 #138

Closed
yangweijie opened this issue Oct 26, 2015 · 11 comments
Closed

微信支付相关文档细化 #138

yangweijie opened this issue Oct 26, 2015 · 11 comments

Comments

@yangweijie
Copy link

在用你的微信类做微信支付功能,
微信配置商户号和key 总算要到了,然后微信unifiedOrder 返回配置总算 看懂要用

    $payment = new Payment($unifiedOrder);
    $payconfig = $payment->getConfig();

去获取,问题是进入下一步

wxjs发起支付,总是提示 get_brand_wxpay_request::fail_invalid signature

网上搜了很多,有的说是支付授权目录不对,有的说是参数大小写顺序之类的。第二个应该可以排除,因为能下单。

第一个。我的项目是分前后端,前端3demo.sinaapp.com/wxbuy 第二部是 /wxorder 出现按钮,点击支付调回调。
而后端是 3api.sinaapp.com/weixin/wxpayNotify post方式。 授权目录 设为 3api.sinaapp.com/ 或者3api.sinaapp.com/weixin/ 都没用, 以为是发起支付前的页面地址 3demo.sinaapp.com/ 或者 3demo.sinaapp.com/wxorder/ 都不对。

不知道如何调试这个签名错误呢?楼主有没有调试微信开发的思路 ,或者放一个测试demo。我发现官方的那个php的demo 就可以访问,也就是里面的商户id 是任意使用的,希望楼主能出个 简单的该支付框架 使用微信支付的demo 给大家填填坑

@overtrue
Copy link
Collaborator

@0i @tianyong90 帮忙看看这个问题呗

@0i
Copy link

0i commented Oct 26, 2015

金额参数需要是字符串,可以贴一下你的代码吗?

@update152
Copy link

公众账号支付授权目录,再检查下,我之前遇到的就是这个问题 结果是授权目录的问题

@yangweijie
Copy link
Author

后端 http://3api.sinaapp.com/weixin/unifiedOrder 这是url。
对应文件是 http://3api.sinaapp.com/app/Http/Controller/WeixinController.php

//创建微信支付订单
    public function unifiedOrder(){
        $fee = Request::input('fee'); //TODO 根据订单读取出来。
        $openid = Request::input('openid');
        slog('调试 下单的微信 openid:');
        slog($openid);
        $order_num = Request::input('order_num');
        $orderInfo = DB::table('order')->where('order_num', $order_num)->first();
        if(!$orderInfo){
            warn("订单号为:{$order_num}的订单不存在");
            error('订单不存在');
        }
        //debug
        warn("正在尝试发起订单{$order_num}的微信支付");
        $config = config('wechat');
        slog($config);
        /**
         * 第 1 步:定义商户
         */
        $business = new Business(
            $config['app_id'],
            $config['secret'],
            $config['mch_id'],
            $config['mch_key']
        );

        slog('business');
        slog($business);
        /**
         * 第 2 步:定义订单
         */
        $order = new Order();
        $luckymoneyTypeInfo = DB::table('luckymoney_type')->select('event_id', 'name')->where('id', $orderInfo->type_id)->first();
        if(!$luckymoneyTypeInfo){
            error('获取红包类型信息失败,请刷新重试。');
        }
        $eventInfo = DB::table('event')->select('id', 'name', 'start_time', 'end_time')->where('id', $luckymoneyTypeInfo->event_id)->first();

        $order->body = $eventInfo->name;
        $order->out_trade_no = $order_num.'_t'.date("YmdHis");
        $order->total_fee = $orderInfo->pay_money * 100;    // 单位为 “分”, 字符串类型
        //debug
        $order->total_fee = '1';
        $order->openid = $openid;
        $order->notify_url = 'http://3api.sinaapp.com/weixin/wxpayNotify';

        /**
         * 第 3 步:统一下单
         */
        $unifiedOrder = new UnifiedOrder($business, $order);

        slog(objectToArray($unifiedOrder));
        /**
         * 第 4 步:生成支付配置文件
         */
        $payment = new Payment($unifiedOrder);
        $payconfig = $payment->getConfig();
        // echo $payconfig;
        return success(['order'=>['body'=>$eventInfo->name, 'out_trade_no'=>$order_num, 'total_fee'=>$order->total_fee,'openid'=>$openid, 'notify_url'=>'http://3api.sinaapp.com/weixin/wxpayNotify'], 'config'=>$payconfig]);
    }

    //微信支付结果回调
    public function wxpayNotify(){
        lesslog("begin notify");

        $config = config('wechat');

        $notify = new Notify(
            $config['app_id'],
            $config['secret'],
            $config['mch_id'],
            $config['mch_key']
        );

        $transaction = $notify->verify();

        if (!$transaction) {
            $notify->reply('FAIL', 'verify transaction error');
        }
        slog($transaction);
        lesslog($transaction, '微信支付后的通知');

        // var_dump($transaction);

        echo $notify->reply();
    }

前端的http://3demo.sinaapp.com/app/pay/controller.js

(function(){
    'use strict';
    angular.module('3demo')
    .controller('wxBuyCtrl',function($scope, $stateParams,jconfig,$state,check_in_weixin,$timeout, $cookies){
        var vm = this;
        vm.buy = function(good){
            $state.go('wxorder', {title:good.title, price:good.price*100});
        }
        vm.weixin_openid = '';
        var openid = $cookies.get('weixin_openid');
        //debug openid = '';
        if(openid){
            vm.weixin_openid = openid;
        }
    })
    .controller('wxOrderCtrl',function($scope, $zh,$state,$stateParams,$cookies){
        var vm = this;
        var params = {
            title: $stateParams.title,
            fee: $stateParams.price,
            openid: $cookies.get('weixin_openid')
        }
        vm.loading = true;
        vm.title = params.title;
        vm.price = params.price == 0? 0.01: params.price/100;
        //正式流程是先创建系统订单后调用此接口 会多传order_id
        params.order_num = '320151025150318';
        $zh.post('weixin/unifiedOrder', params).success(function(data){
            vm.loading = false;
            vm.order = angular.fromJson(data.order);
            vm.jsApiCall = function(){
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest',
                    angular.fromJson(data.config),
                    function(res){
                        if(res.err_msg == "get_brand_wcpay_request:ok"){
                            $state.go('wxorder_result');
                        }else{
                            vm.errmsg = res.err_msg;
                        }
                    }
                );
            }

            vm.callpay = function(){
                if (typeof WeixinJSBridge == "undefined"){
                    if( document.addEventListener ){
                        document.addEventListener('WeixinJSBridgeReady', vm.jsApiCall, false);
                    }else if (document.attachEvent){
                        document.attachEvent('WeixinJSBridgeReady', vm.jsApiCall);
                        document.attachEvent('onWeixinJSBridgeReady', vm.jsApiCall);
                    }
                }else{
                    vm.jsApiCall();
                }
            }
        }).error(function(data){
            vm.errmsg = data;
        });
    })
    .controller('wxOrderResultCtrl',function(){

    })
    ;
})();

模板

<div class="container">
    <div class="row" id="order" ng-hide="errmsg" ng-if="!wxOrder.loading">
        <font color="#f00"><b>统一下单支付单信息</b></font><br/>
        <p ng-repeat="(key,value) in wxOrder.order"><font color='#00ff55;'>{{key}}</font> : {{value}}</p>
        <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">{{wxOrder.order.total_fee/100}}元</span>钱</b></font><br/><br/>
        <div align="center">
            <a ng-click="wxOrder.callpay()" class="btn btn-primary">立即支付</a>
        </div>
    </div>
    <div class="row" ng-show="wxOrder.errmsg">
        发起微信支付 预处理出错, <br>
        出错信息:<pre>{{wxOrder.errmsg}}</pre>
    </div>
</div>

刚试过把 金额改成字符串,还是没用。

支付授权目录
http://www.zhanhuigou.com/mobile/
http://www.zhanhuigou.com/weixin/weixinpay/
http://www.zhanhuigou.com/weixin/weixinpay/demo
测试授权目录http://3api.sinaapp.com/weixin/

@yangweijie
Copy link
Author

路由是

//微信支付相关接口
$app->post('/weixin/unifiedOrder','WeixinController@unifiedOrder');
$app->post('/weixin/wxpayNotify','WeixinController@wxpayNotify');

@tianyong90
Copy link
Contributor

没看出代码里有啥毛病。建议用官方SDK里的签名工具传相同的参数生成签名,然后和overtrue/wecaht生成的签名比对下。这样可以确定是签名本身出错了还是因为配置的授权目录不对。

@update152
Copy link

授权目录写详细点,发起支付url是什么

@yangweijie
Copy link
Author

image
发起支付的URL是什么意思啊, 是指调用点立即支付按钮所在页面的地址吗?那个是http://3demo.sinaapp.com/wxorder啊 大家可以 先浏览器打开 http://3demo.sinaapp.com/wxbuy 用二维码插件 微信浏览到啊
@tianyong90 官方sdk 签名工具地址在哪, 然后overtrue/wechat 里哪个方法的生成签名去对比,是unifiedOrder 还是wxpayNotify 里面生成的签名呢,如果 验证成功,前面返回的数据格式的杨莉是什么样字的呢?

我的获取订单返回json是这样的

{
    "code": 0,
    "message": "",
    "data": {
        "order": {
            "body": "\u91cd\u5e86\u56fd\u9645\u535a\u89c8\u4e2d\u5fc3\uff08\u91cd\u5e86 \u60a6\u6765\uff09",
            "out_trade_no": "320151025150318",
            "total_fee": "1",
            "openid": "owca5twvhoHw2W7jkp8b1y2-DYFk",
            "notify_url": "http:\/\/3api.sinaapp.com\/weixin\/wxpayNotify"
        },
        "config": "{\"appId\":\"wx6f390c0b020f9e1e\",\"timeStamp\":\"1445846549\",\"nonceStr\":\"Kna7dSufNLRJEOal\",\"package\":\"prepay_id=wx20151026160229a8b89aba410747207536\",\"signType\":\"MD5\",\"paySign\":\"17C6486C20A8EDA18AC7D0F35C26DAC7\"}"
    }
}

@tianyong90
Copy link
Contributor

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
这里可以下载官方的SDK,里面有签名工具。
支付授权目录就是实际发现支付的地址,您这上面有好几个域名,我看晕了。
估计还是授权目录闹的……

@yangweijie
Copy link
Author

终于好了,其实问题很曲折,开始做的时候,订单号加了长了超过32字节了。
然后是支付金额 测试写了个1 习惯了 没带‘’ 这个建议sdk传的时候检查一下。因为php是弱类型,经常会拿来运算。
最后一个问题, 签名错误 实际上还是与授权目录有关,因为 实在弄不懂

根据图中栏目顺序进入修改栏目,勾选JSAPI网页支付开通该权限,并配置好支付授权目录,该目录必须是发起支付的页面的精确目录,子目录下无法正常调用支付。
精准目录是什么意思, 有的说是回调地址里 方法前面那个 比如 我回调是 weixin/wxpayNotify 域名是 http://3api.sinaapp.com 那么就写http://3api.sinaapp.com/weixin/
这是错误的,后来证明,是发起页面所在域名, 比方我有个页面回去掉wxPay,那个方法, 支付目录应该是 域名/pay.html。 而由于我的是angularjs ,http://3demo.sinaapp.com/wxorder 这页面发起的,所以支付目录是去掉wxorder 就是根域名。而且开始我以为签名还与证书有关,那个大家看看文档应该是退款用的。

@dhb52
Copy link

dhb52 commented Oct 26, 2015

只有操作商户金额的才需要证书。其他业务不需要

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants