Weixin.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. namespace app\api\controller\v1;
  3. use app\BaseController;
  4. use app\model\api\Member;
  5. use app\model\api\Order;
  6. use app\model\api\OrderInfo;
  7. use app\model\api\PayTrade;
  8. use app\model\api\Product;
  9. use app\model\api\Recharge;
  10. use app\Request;
  11. use EasyWeChat\Factory;
  12. use library\lib\weixina;
  13. use library\services\UtilService;
  14. use think\db\exception\DbException;
  15. use think\db\exception\PDOException;
  16. use think\Exception;
  17. use think\facade\Db;
  18. class Weixin extends BaseController
  19. {
  20. public function getInfo(Request $request)
  21. {
  22. $code = trim($request->get('code'));
  23. $weixinA = new weixina;
  24. $token = $weixinA->oauth_reuslt($code);
  25. if (!empty($token['access_token'])) {
  26. $userInfo = $weixinA->userinfo($token['access_token']);
  27. $data['openid'] = $userInfo['openid'];
  28. $data['nickname'] = $userInfo['nickname'];
  29. $data['sex'] = $userInfo['sex'];
  30. $data['language'] = $userInfo['language'];
  31. $data['city'] = $userInfo['city'];
  32. $data['province'] = $userInfo['province'];
  33. $data['country'] = $userInfo['country'];
  34. $data['avatar'] = $userInfo['headimgurl'];
  35. (new Member)->where('uid',$request->user['uid'])->save($data);
  36. return app('json')->success([
  37. 'nickname' => $data['nickname'],
  38. 'avatar' => $data['avatar']
  39. ]);
  40. }
  41. }
  42. /**
  43. * @param Request $request
  44. */
  45. public function result(Request $request)
  46. {
  47. $state = trim($request->get('state'));
  48. $code = trim($request->get('code'));
  49. if (empty($state)) {
  50. exit('error');
  51. }
  52. $weixinA = new weixina;
  53. $data = $weixinA->oauth_reuslt($code);
  54. if (!empty($data['access_token'])) {
  55. $userInfo = $weixinA->userinfo($data['access_token']);
  56. $userInfo['access_token'] = $data['access_token'];
  57. $userInfo['expires_in'] = $data['expires_in'];
  58. $userInfo['time'] = time();
  59. cookie("weix_userinfo", serialize($userInfo));
  60. $url = setParam(cookie('w_url'), ['data' => json_encode($userInfo, \JSON_UNESCAPED_UNICODE)]);
  61. redirect($url)->send();
  62. } else {
  63. exit('微信授权登录失败,关闭页面重新,重新扫描!');
  64. }
  65. }
  66. public function pay(Request $request)
  67. {
  68. [$orderId, $from] = UtilService::getMore([
  69. ['order_id', '', 'empty', '参数错误'],
  70. ['from', '', 'empty', '参数错误'],
  71. ], $request, true);
  72. $order = Order::where('order_id', $orderId)->find();
  73. if (empty($order)) {
  74. return app('json')->fail('找不到订单信息');
  75. }
  76. //订单已付款
  77. if (!empty($order['is_pay'])) {
  78. return app('json')->fail('订单已经支付成功');
  79. }
  80. $data['out_trade_no'] = $order['order_id'];
  81. $data['money'] = $order['all_price'];
  82. $data['type'] = 'order';
  83. $data['time'] = time();
  84. Db::name('wx_notify')->insert($data);
  85. $app = Factory::payment(config('weixin')['wxPay']);
  86. if ($from == 'weixin') {
  87. $result = $app->order->unify([
  88. 'body' => '支付订单',
  89. 'out_trade_no' => $order['order_id'],
  90. 'total_fee' => $order['all_price'] * 100,
  91. 'notify_url' => 'https://www.boofly.cn/api/weixin/notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  92. 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
  93. 'openid' => $request->user['openid']
  94. ]);
  95. $jssdk = $app->jssdk;
  96. $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
  97. $json['result'] = $jsConfig;
  98. $json['type'] = 'WECHAT_PAY';
  99. } else {
  100. $result = $app->order->unify([
  101. 'body' => '支付订单',
  102. 'out_trade_no' => $order['order_id'],
  103. 'total_fee' => $order['all_price'] * 100,
  104. 'notify_url' => 'https://www.boofly.cn/api/weixin/notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  105. 'trade_type' => 'MWEB' // 请对应换成你的支付方式对应的值类型
  106. ]);
  107. $jssdk = $app->jssdk;
  108. $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
  109. $json['result'] = $jsConfig;
  110. $json['type'] = 'WECHAT_H5_PAY';
  111. }
  112. return app('json')->success($json);
  113. }
  114. public function recharge(Request $request)
  115. {
  116. [$money, $from] = UtilService::getMore([
  117. ['money', '', 'empty', '请选择充值金额'],
  118. ['from', '', 'empty', '参数错误']
  119. ], $request, true);
  120. try {
  121. Recharge::beginTrans();
  122. $recharge = new Recharge();
  123. $d = [];
  124. $d['order_id'] = 'RE' . time() . sprintf('%04d', rand(0, 1000)) . $request->user['uid'];
  125. $d['v'] = $money;
  126. $d['time'] = time();
  127. $d['uid'] = $request->user['uid'];
  128. $recharge->insert($d);
  129. //生成支付凭证
  130. $data['out_trade_no'] = $d['order_id'];
  131. $data['money'] = $money;
  132. $data['type'] = 'recharge';
  133. $data['time'] = time();
  134. Db::name('wx_notify')->insert($data);
  135. Recharge::commitTrans();
  136. $app = Factory::payment(config('weixin')['wxPay']);
  137. if ($from == 'weixin') {
  138. $result = $app->order->unify([
  139. 'body' => '充值余额',
  140. 'out_trade_no' => $d['order_id'],
  141. 'total_fee' => $money * 100,
  142. 'notify_url' => 'https://www.boofly.cn/api/weixin/notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  143. 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
  144. 'openid' => $request->user['openid'],
  145. ]);
  146. $jssdk = $app->jssdk;
  147. $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
  148. $json['result'] = $jsConfig;
  149. $json['type'] = 'WECHAT_PAY';
  150. } else {
  151. $result = $app->order->unify([
  152. 'body' => '充值余额',
  153. 'out_trade_no' => $d['order_id'],
  154. 'total_fee' => $money * 100,
  155. 'notify_url' => 'https://www.boofly.cn/api/weixin/notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  156. 'trade_type' => 'MWEB' // 请对应换成你的支付方式对应的值类型
  157. ]);
  158. $json['result'] = $result;
  159. $json['type'] = 'WECHAT_H5_PAY';
  160. }
  161. return app('json')->success($json);
  162. } catch (DbException $db) {
  163. Recharge::rollbackTrans();
  164. return app('json')->fail("充值失败,请联系客服人员");
  165. }
  166. }
  167. /**
  168. * @throws \Exception
  169. */
  170. public function notify()
  171. {
  172. // 获取微信回调的数据
  173. $notifiedData = file_get_contents('php://input');
  174. //XML格式转换
  175. $xmlObj = simplexml_load_string($notifiedData, 'SimpleXMLElement', LIBXML_NOCDATA);
  176. $xmlObj = json_decode(json_encode($xmlObj), true);
  177. // 当支付通知返回支付成功时
  178. if ($xmlObj['return_code'] == "SUCCESS" && $xmlObj['result_code'] == "SUCCESS") {
  179. try {
  180. $data['appid'] = $xmlObj['appid'];
  181. $data['bank_type'] = $xmlObj['bank_type'];
  182. $data['cash_fee'] = $xmlObj['cash_fee'];
  183. $data['fee_type'] = $xmlObj['fee_type'];
  184. $data['is_subscribe'] = $xmlObj['is_subscribe'];
  185. $data['mch_id'] = $xmlObj['mch_id'];
  186. $data['nonce_str'] = $xmlObj['nonce_str'];
  187. $data['openid'] = $xmlObj['openid'];
  188. $data['result_code'] = $xmlObj['result_code'];
  189. $data['return_code'] = $xmlObj['return_code'];
  190. $data['sign'] = $xmlObj['sign'];
  191. $data['time_end'] = $xmlObj['time_end'];
  192. $data['total_fee'] = $xmlObj['total_fee'];
  193. $data['trade_type'] = $xmlObj['trade_type'];
  194. $data['transaction_id'] = $xmlObj['transaction_id'];
  195. $data2 = Db::name('wx_notify')->where('out_trade_no', $xmlObj['out_trade_no'])->find();
  196. if (empty($data2)) {
  197. echo 'SUCCESS';
  198. exit;
  199. }
  200. $res = Db::name('wx_notify')->where('out_trade_no',$xmlObj['out_trade_no'])->save($data);
  201. if($res){
  202. if ($data2['type'] == 'order') {
  203. $order = Order::where('order_id', $xmlObj['out_trade_no'])->find();
  204. //减库存加销量
  205. Product::where('id', $order['pro_id'])->dec('stock', $order['num'])->inc('sales', $order['num'])->update();
  206. Db::name('ProductAttrValue')->where('product_id', $order['pro_id'])->where('unique', $order['unique'])->dec('stock', $order['num'])->inc('sales', $order['num'])->update();
  207. //改订单状态
  208. Order::where('order_id', $xmlObj['out_trade_no'])->save([
  209. 'status' => 1,
  210. 'is_pay' => 1,
  211. 'pay_type' => 'weixin',
  212. 'pay_time' => time()
  213. ]);
  214. //改子订单状态
  215. OrderInfo::where('o_id', $order['id'])->save(['status' => 1,]);
  216. }
  217. if ($data2['type'] == 'recharge') {
  218. $recharge = new Recharge();
  219. $recharge->rechargeSuccess($xmlObj['out_trade_no']);
  220. }
  221. echo 'SUCCESS';
  222. exit;
  223. }
  224. } catch (Exception $e) {
  225. @file_put_contents('error.txt', '[' . date('Y-m-d') . ']Exception:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
  226. } catch (DbException $e) {
  227. @file_put_contents('error.txt', '[' . date('Y-m-d') . ']DbException:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
  228. } catch (\Exception $e) {
  229. @file_put_contents('error.txt', '[' . date('Y-m-d') . ']\Exception:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
  230. }
  231. }
  232. }
  233. }