Closed yangweijie closed 8 years ago
@0i @tianyong90 帮忙看看这个问题呗
金额参数需要是字符串,可以贴一下你的代码吗?
公众账号支付授权目录,再检查下,我之前遇到的就是这个问题 结果是授权目录的问题
后端 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/
路由是
//微信支付相关接口
$app->post('/weixin/unifiedOrder','WeixinController@unifiedOrder');
$app->post('/weixin/wxpayNotify','WeixinController@wxpayNotify');
没看出代码里有啥毛病。建议用官方SDK里的签名工具传相同的参数生成签名,然后和overtrue/wecaht生成的签名比对下。这样可以确定是签名本身出错了还是因为配置的授权目录不对。
授权目录写详细点,发起支付url是什么
发起支付的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\"}"
}
}
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里可以下载官方的SDK,里面有签名工具。 支付授权目录就是实际发现支付的地址,您这上面有好几个域名,我看晕了。 估计还是授权目录闹的……
终于好了,其实问题很曲折,开始做的时候,订单号加了长了超过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 就是根域名。而且开始我以为签名还与证书有关,那个大家看看文档应该是退款用的。
只有操作商户金额的才需要证书。其他业务不需要
在用你的微信类做微信支付功能, 微信配置商户号和key 总算要到了,然后微信unifiedOrder 返回配置总算 看懂要用
去获取,问题是进入下一步
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 给大家填填坑