Open unizhu opened 9 years ago
take a look at my fork Repo
Thanks, @denghongcai
@denghongcai 你的 repo我装了,然而没能理解如何使用...并且..你的 repo 里面没法 open issue. 所以只能写在这里. 首先有个小 bug 是在laravel 5.1 下:config/app.php: 需要写成:'Wxpay' => 'HongcaiDeng\Wxpay\Facades\Wxpay', 用::class 是会报错的.使用的时候用 \Wxpay
另外重要的是:
以上尝试方法的配置是基于我原先拿微信的官方 SDK 改得,自己改得那个可以使用,但是没整合过 laravel. 所以基本上,固定的配置参数是对的,除了那个 js_api_call_url .
所以我还是不会用你的 vendor .. 或许你可以把使用方法写的更详细一点?
更新了下readme
理解下这个过程,js_api_call_url是可以在使用时改变的,config里的只是个参考
$wxpay = Wxpay::instance('jsApi');
$config = [
'body' => $order->activity->content,
'total_fee' => 1,
'out_trade_no' => $order->oid,
'sub_mch_id' => '',
'device_info' => '',
'attach' => '', // 附加数据
'time_start' => '',
'time_expire' => '',
'goods_tag' => '',
'product_id' => '',
'js_api_call_url' => action('OrderController@pay', ['id' => $order->id])
];
list($prepay_id, $view) = $wxpay->setConfig($config)->pay();
然后你拿到了返回的$view,如果在控制器里就直接return $view就好了
看看代码就知道了,还有些API我实现了但是没写在readme里
@unidotnet 你问题的第1点:它只会跳转到我配置的 js_api_call_url ,但是没法使用,因为这个 url 只会拿到code. 然而我并不知道应该跳转到哪个订单. 关键就是这个js_api_call_url要设置成你订单的页面。比如 /orders/pay/1 这样子就知道要支付 id =1的订单了。(由于微信的特殊要求,必须得设置成 /xxx/xxx/{id} 这种形式。) 组件的流程基本集中在 pay() 这个方法里了,流程为:获取code -> 通过code获取openid -> 组装参数 (这里会调用一次统一支付接口,拿到prepay_id)-> 把参数传给views -> views里的js 发起支付。希望能帮到你。
@denghongcai @hardywen 谢谢. 目前我是这样写的: $this->values['timeStamp'] = (string)$value; 发起支付页面controller里:
$config = array(
'body'=>'xxx',
'attach'=>'xxx',
'goods_tag'=>'xxx',
'total_fee' =>'1',
'out_trade_no'=>$order_id,
'time_start'=>date("YmdHis"),
'time_expire'=>date("YmdHis", time() + 600),
'js_api_call_url' => action('OrderController@wechatPayRedirect', ['order_id' => $order_id])
);
list($prepay_id, $view) = \Wxpay::instance('jsApi')->setConfig($config)->pay();
Log::debug('$prepay_id :'.$prepay_id);
Log::debug('$view :'.$view);
return $view;
并没有执行,而是到了 OrderController@wechatPayRedirect . 这里返回了一个微信 js 的标准页面,也就是 invoke 的方法.然而.. 微信返回: 缺少必要参数 $key0$ 按照以前的经验,貌似是要把 timeStamp 强制改成 string , 但是我看了下你的代码, 已经 $jsApiObj["timeStamp"] = "$timeStamp";
还是没法出现支付,请赐教.
能调用到js的接口了,说明你的流程能跑通了,看错误是缺少参数。 那你你试试在views里, 这句<?php echo $jsApiParameters ?>, 调试一下 看看输出的参数对不对,有没有少什么。 还有就是其实你可以 进vender里直接改源码,做些调试,Log 一下 微信接口的返回值之类的,甚至是 dd() 跳出来调试。
@denghongcai @hardywen
在wechatPayRedirect里,就是跳转回来的那个 controller 方法里:
$parameters = \Wxpay::instance('jsApi')->getParameters();
print_r($parameters);
return view('wechat_redirect',['$jsApiParameters',$parameters]);
出来的 prepay_id=空. 这个prepay_id应该在第一次 oauth 请求的时候就应该生成了吧? 然后再传回Wxpay. 我猜想是因为Wxpay类不能持久化,所以成员变量都没拉? 怎么样才能让prepay_id正确的出现在getParameters()里?
另外: @denghongcai 我每次运行
[root@centserver test]# php artisan vendor:publish --force --provider="HongcaiDeng\Wxpay\WxpayServiceProvider"
Copied File [/vendor/hongcaideng/wxpay/config/wxpay.php] To [/config/wxpay.php]
Copied Directory [/vendor/hongcaideng/wxpay/resources/views] To [/resources/views/vendor/wxpay]
Publishing complete for tag []!
[root@centserver test]# vim ./vendor/hongcaideng/wxpay/src/HongcaiDeng/Wxpay/JsApi/JsApi.php
[root@centserver test]# php artisan vendor:publish
Copied Directory [/vendor/hongcaideng/wxpay/resources/views] To [/resources/views/vendor/wxpay]
Publishing complete for tag []!
[root@centserver test]# php artisan vendor:publish
Copied Directory [/vendor/hongcaideng/wxpay/resources/views] To [/resources/views/vendor/wxpay]
Publishing complete for tag []!
都会重新复制一遍 view?
另外
$prepay_id = $this->getUnifiedOrderPrepayId();
Log::debug('prepay id : '.$prepay_id);
$this->setPrepayId($prepay_id);
log 里并没任何反应..
唉,你没有理解这个的流程……
vendor:publish只需要执行一次……你要明白这个命令是用来干嘛的……
首先,用户在微信里点击链接或者自定义菜单跳转到你的页面,然后点击支付,这个时候进入的是
action('OrderController@pay', ['id' => 1])
这个url,然后这个控制器的代码是
public function pay($orderId)
{
$order = Order::find($orderId);
if(is_null($order)) {
return response(Response::HTTP_NOT_FOUND);
}
$wxpay = Wxpay::instance('jsApi');
$config = [
'body' => $order->activity->content,
'total_fee' => 1,
'out_trade_no' => $order->id,
'sub_mch_id' => '',
'device_info' => '',
'attach' => '', // 附加数据
'time_start' => '',
'time_expire' => '',
'goods_tag' => '',
'product_id' => '',
'js_api_call_url' => action('OrderController@pay', ['id' => $order->id])
];
list($prepay_id, $view) = $wxpay->setConfig($config)->pay();
return $view;
}
这时在调用pay()
这个方法的时候,由于还没拿到微信网页授权的code
,取不到openid
,也就没法发起支付。在pay()
里的代码会直接调用redirect()跳转到授权URL进行snapi_base形式的回调授权,回调的返回地址就是
action('OrderController@pay', ['id' => $order->id])
从微信返回之后还是回到这个控制器里来了,但是回调过来的URL里有CODE
这个GET参数,走到pay()
这里之后我们的包会帮你获取用户的openid并且将参数准备好填入到view里,这时才会走到
return $view
这里,将包里带的最简单的view渲染出来,唤起微信支付的界面,接下来的事情就是在支付完成后处理js的回调并且等待服务器推送的确认 确认方法的示例如下
public function payNotify(Request $req)
{
$wxpay = Wxpay::instance('jsApi');
list($notify, $data) = $wxpay->verifyNotify();
if($notify) {
Log::info($data);
$order = Order::find($data['out_trade_no'])->first();
$order->status = config('constants.ORDER_STATUS_PAID');
$wxpay->setReturnParameter('return_code', 'SUCCESS');
$wxpay->returnXML();
}
else {
Log::info($data);
$wxpay->setReturnParameter("return_code","FAIL");//返回状态码
$wxpay->setReturnParameter("return_msg","签名失败");//返回信息
$wxpay->returnXml();
}
}
代码没太好的格式化,凑合看吧
这样说还是没明白那我就……
@denghongcai 谢谢. 我终于明白了原来是同一个 action... 不好意思请原谅我才用 laravel 2周时间. 改成 'js_api_call_url' => action('OrderController@wechatPayMobile', ['order_id' => $order_id]) 就可以了进行支付了.
接着是微信支付的验证,也就是 notify 我设置的 url 是 /Payment/wechatpay/callback 但是一直是验证失败.... 再次请教.
callback这个控制器参考我的示例就好……
如果不对就把数据都打印到log里慢慢找
@denghongcai @hardywen 2位目前想换个工作吗?我正在招人。。
@denghongcai 在你的repo中 notify.php line14 checkSign方法生成本地签名时需要将$data中原有的sign值unset掉
@unidotnet 遇到验证失败的问题估计就是这个bug导致的
@kevineves 确实是的,我的问题,我本地的代码里unset了sign,但是发布库里没改
@denghongcai @kevineves 谢谢,今天试了下可以了. 另外再问个问题,后台验证成功后,设置哪个 url 可以跳转回我的网站页面?现在是个空白页面...
跳转需要改view里的js的
@denghongcai 那再laravel框架下授权目录应该设置成什么?
我在这里回复你吧 @gamelife1314
1.我在获取code的时候,返回以下错误信息,您是否能帮我解释一下:
array:2 [▼ "errcode" => 40029 "errmsg" => "req id: dB1j50900ns39, invalid code" ]
code
会在网页授权之后回调redirect_uri
返回,只能使用一次,你看你是不是多次调用了获取access_token
的接口
确保参数都对,没什么大问题
@denghongcai 好的,谢谢,我去再尝试尝试
@hardywen @denghongcai @unidotnet @kevineves 真的很着急, :sob: 请问授权目录该怎么样设置?出现了access_denied
错误;
我发起支付的路由是http://hostname/order/wxpay/{id}
,按照这样,应该怎么样设置才好?
谢谢各位的帮助,我自己debug出来了!
thanks