PayController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. <?php
  2. namespace App\Http\Controllers\Api\V1;
  3. use App\Http\HelperTraits\LogHelper;
  4. use App\Http\HelperTraits\PayHelper;
  5. use App\Http\HelperTraits\JpushHelper;
  6. use Omnipay\Omnipay;
  7. use App\User;
  8. use App\Models\MerchantMemberService;
  9. use App\Models\Order;
  10. use App\Models\AccountLog;
  11. use Request, Config, DB;
  12. class PayController extends Controller
  13. {
  14. use PayHelper, LogHelper,JpushHelper;
  15. /**
  16. * p++ webhooks通知
  17. */
  18. // public function pppNotify() {
  19. // $sig = Request::header('x-pingplusplus-signature');
  20. // $request = Request::instance();
  21. // $data = $request->getContent();
  22. //
  23. // if (!$this->checkPppSignature($data, $sig)) {//验签失败
  24. // header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
  25. // exit("fail");
  26. // }
  27. //
  28. // $event = json_decode($data);
  29. // if (!isset($event->type)) {
  30. //// return Response::make('fail', 400);
  31. // header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
  32. // exit("fail");
  33. // }
  34. // switch ($event->type) {
  35. // case "charge.succeeded":
  36. // // 开发者在此处加入对支付异步通知的处理代码
  37. // header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
  38. // break;
  39. // case "refund.succeeded":
  40. // // 开发者在此处加入对退款异步通知的处理代码
  41. // header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
  42. // break;
  43. // default:
  44. // header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request');
  45. // break;
  46. // }
  47. // }
  48. public function alipayNotify() {
  49. $rawInfo = Request::all();
  50. \Log::info('aliplay callback');
  51. \Log::info($rawInfo);
  52. $config = Config::get('laravel-omnipay.gateways.alipay');
  53. $gateway = Omnipay::create($config['driver']);
  54. $gateway->setEnvironment($config['options']['environment']);
  55. $gateway->setAppId($config['options']['appid']);
  56. $gateway->setEncryptKey($config['options']['encrypt_key']);
  57. $gateway->setPrivateKey($config['options']['prikey']);
  58. $gateway->setAlipayPublicKey($config['options']['ali_pubkey']);
  59. $gateway->setNotifyUrl($config['options']['notify_url']);
  60. $request = $gateway->completePurchase();
  61. $request->setParams($rawInfo);//Optional
  62. try {
  63. $response = $request->send();
  64. if($response->isPaid()){
  65. \Log::info('支付成功');
  66. $out_trade_no = $rawInfo['out_trade_no'];
  67. $order = Order::where('transaction_id', '=', $out_trade_no)->first();
  68. if (!$order) {
  69. \Log::error('找不到订单' . $out_trade_no);
  70. return 'fail';
  71. }
  72. $master_amount = $order->number;
  73. $slave_amount = 0;
  74. if (!empty($order->ext_info)) {
  75. $extInfo = json_decode($order->ext_info, true);
  76. if ($extInfo !== null) {
  77. $cc = $extInfo['cc_bonus'];
  78. $master_amount = round(($cc / 100) * $order->number);
  79. $slave_amount = $order->number - $master_amount;
  80. }
  81. }
  82. $tp = '';
  83. // $u = null;
  84. if ($order->user_type == Order::USER_TYPE_MERCHANT) {
  85. $tp = 'Merchant';
  86. // $u = Merchant::find($order->user_id);
  87. } elseif ($order->user_type == Order::USER_TYPE_MEMBER) {
  88. $tp = 'Member';
  89. //Not handled here
  90. }
  91. $u = User::find($order->user_id);
  92. if (!$u) {
  93. \Log::error('用户不存在' . $order->user_type . ', ' . $order->user_id);
  94. return 'success';
  95. }
  96. DB::beginTransaction();
  97. if ($order->goods_type == Order::GOODS_TYPE_BALANCE||$order->goods_type == Order::GOODS_TYPE_COSUME) {
  98. $cType = AccountLog::TYPE_BALANCE;
  99. // $u->account_balance += $order->number;
  100. $u->balance += $master_amount;
  101. } elseif ($order->goods_type == Order::GOODS_TYPE_CREDIT) {
  102. $cType = AccountLog::TYPE_CREDIT;
  103. // $u->credit_balance += $order->number;
  104. $u->credit += $master_amount;
  105. } else {
  106. \Log::error('商品不存在' . $order->goods_type);
  107. return 'success';
  108. }
  109. \Log::info('支付金额 '.$master_amount);
  110. if ($u->save()) {
  111. //更新订单状态
  112. $order->status = Order::STATUS_FINISHED;
  113. $order->save();
  114. //记日志
  115. $amount = $rawInfo['total_amount'] * 100;
  116. if (empty($extInfo)) {
  117. $this->logAccount($tp, $u->id, $u->name,
  118. AccountLog::OP_CHARGE, $cType, $master_amount,
  119. AccountLog::DIRECTION_INC, $cType == AccountLog::TYPE_BALANCE ? $u->balance : $u->credit, AccountLog::CHANNEL_ALIPAY);
  120. } else {
  121. //续消费
  122. $this->continue_consume($order);
  123. $this->logAccount($tp, $u->id, $u->name,
  124. AccountLog::OP_CC, $cType, $master_amount,
  125. AccountLog::DIRECTION_INC, $cType == AccountLog::TYPE_BALANCE ? $u->balance : $u->credit, AccountLog::CHANNEL_ALIPAY);
  126. }
  127. \Log::info('支付完成');
  128. } else {
  129. DB::rollBack();
  130. \Log::error('保存数据失败');
  131. }
  132. DB::commit();
  133. return 'success';
  134. }else{
  135. \Log::error('支付失败');
  136. return 'fail';
  137. }
  138. } catch (\Exception $e) {
  139. \Log::error('支付异常' . $e->getMessage());
  140. return 'fail';
  141. }
  142. }
  143. public function wechatpayNotify() {
  144. \Log::debug('wechatpay callback');
  145. // \Log::debug(Request::all());
  146. $config = Config::get('laravel-omnipay.gateways.wechatpay');
  147. $gateway = Omnipay::create("WechatPay");
  148. // $gateway->setEnvironment('sandbox');
  149. $gateway->setAppId($config['options']['appid']);
  150. $gateway->setMchId($config['options']['merchant_id']);
  151. $gateway->setApiKey($config['options']['apikey']);
  152. $response = $gateway->completePurchase([
  153. 'request_params' => file_get_contents('php://input')
  154. ])->send();
  155. try {
  156. if ($response->isPaid()) {
  157. //pay success
  158. $rawInfo = $response->getRequestData();
  159. \Log::debug($rawInfo);
  160. \Log::info('支付成功');
  161. $out_trade_no = $rawInfo['out_trade_no'];
  162. $order = Order::where('transaction_id', '=', $out_trade_no)->first();
  163. if (!$order) {
  164. \Log::error('找不到订单' . $out_trade_no);
  165. return 'fail';
  166. }
  167. $master_amount = $order->number;
  168. $slave_amount = 0;
  169. if (!empty($order->ext_info)) {
  170. $extInfo = json_decode($order->ext_info, true);
  171. if ($extInfo !== null) {
  172. $cc = $extInfo['cc_bonus'];
  173. $master_amount = round(($cc / 100) * $order->number);
  174. $slave_amount = $order->number - $master_amount;
  175. }
  176. }
  177. $tp = '';
  178. // $u = null;
  179. if ($order->user_type == Order::USER_TYPE_MERCHANT) {
  180. $tp = 'Merchant';
  181. // $u = Merchant::find($order->user_id);
  182. } elseif ($order->user_type == Order::USER_TYPE_MEMBER) {
  183. $tp = 'Member';
  184. //Not handled here
  185. }
  186. $u = User::find($order->user_id);
  187. if (!$u) {
  188. \Log::error('用户不存在' . $order->user_type . ', ' . $order->user_id);
  189. return 'success';
  190. }
  191. DB::beginTransaction();
  192. if ($order->goods_type == Order::GOODS_TYPE_BALANCE||$order->goods_type == Order::GOODS_TYPE_COSUME) {
  193. $cType = AccountLog::TYPE_BALANCE;
  194. // $u->account_balance += $order->number;
  195. $u->balance += $master_amount;
  196. } elseif ($order->goods_type == Order::GOODS_TYPE_CREDIT) {
  197. $cType = AccountLog::TYPE_CREDIT;
  198. // $u->credit_balance += $order->number;
  199. $u->credit += $master_amount;
  200. } else {
  201. \Log::error('商品不存在' . $order->goods_type);
  202. return 'success';
  203. }
  204. //测试
  205. \Log::info('支付金额 '.$master_amount);
  206. if ($u->save()) {
  207. //更新订单状态
  208. $order->status = Order::STATUS_FINISHED;
  209. $order->save();
  210. //记日志
  211. $amount = $rawInfo['total_fee'] * 100;
  212. if (empty($extInfo)) {
  213. $this->logAccount($tp, $u->id, $u->name,
  214. AccountLog::OP_CHARGE, $cType, $master_amount,
  215. AccountLog::DIRECTION_INC, $cType == AccountLog::TYPE_BALANCE ? $u->balance : $u->credit, AccountLog::CHANNEL_WECHATPAY);
  216. } else {
  217. $this->logAccount($tp, $u->id, $u->name,
  218. AccountLog::OP_CC, $cType, $master_amount,
  219. AccountLog::DIRECTION_INC, $cType == AccountLog::TYPE_BALANCE ? $u->balance : $u->credit, AccountLog::CHANNEL_WECHATPAY);
  220. }
  221. \Log::info('支付完成');
  222. } else {
  223. DB::rollBack();
  224. \Log::error('保存数据失败');
  225. }
  226. DB::commit();
  227. return 'success';
  228. }else{
  229. //pay fail
  230. \Log::error($response->getData());
  231. return 'fail';
  232. }
  233. } catch (\Exception $e) {
  234. \Log::error('支付异常' . $e->getMessage());
  235. return 'fail';
  236. }
  237. }
  238. function continue_consume($order){
  239. }
  240. /**
  241. * @api {post} /api/pay/charge 充值
  242. * @apiDescription 充值(向平台充值)
  243. * @apiGroup Merchant
  244. * @apiPermission Passport
  245. * @apiVersion 0.1.0
  246. * @apiParam {int} [goods=1] 充值商品(1:余额,2:卡金)
  247. * @apiParam {int} number 充值数量,人民币,以分表示
  248. * @apiParam {int} type 支付类型(1:支付宝,2:微信支付)
  249. * @apiSuccessExample {json} Success-Response:
  250. * HTTP/1.1 200 OK
  251. * {
  252. * "state": true,
  253. * "code": 0,
  254. * "message": "",
  255. * "data": {
  256. * "id": 2,
  257. * "code": "ALIPAY_201610231314145719",
  258. * "transaction_id": "201610231314145719",
  259. * "user_type": 2,
  260. * "user_id": 1,
  261. * "goods_type": 1,
  262. * "price": 1,
  263. * "number": 1,
  264. * "amount": 1,
  265. * "pay_type": 1,
  266. * "status": 0,
  267. * "created_at": "2016-10-23 13:14:14",
  268. * "updated_at": "2016-10-23 13:14:14",
  269. * "orderString": "alipay_sdk=lokielse%2Fomnipay-alipay&app_id=2016091201894867&biz_content=%7B%22subject%22%3A%22%5Cu7532%5Cu8c61%5Cu8054%5Cu5408-%5Cu4f59%5Cu989d%5Cu5145%5Cu503c%22%2C%22out_trade_no%22%3A%22201610231314145719%22%2C%22total_amount%22%3A0.01%2C%22product_code%22%3A1%7D&charset=UTF-8&format=JSON&method=alipay.trade.app.pay&notify_url=http%3A%2F%2Fweb%2Fapi%2Fpay%2Falipay%2Fnotify&sign_type=RSA&timestamp=2016-10-23+13%3A14%3A14&version=1.0&sign=oxKM0qGMHLWDlMrXHIiy9%2Fk2BXJq3rC3RKdmcfFwkBJVRXvtG6cBoAYPll6VxJYOMQWeu78Ibfov%2FxIVCuN9yUfzEiokfQrzBoptc94bCQ5k0pNyJcSdgezOUKHB12P5Zmm3Hd6AAbGRDV9UCaLVz0wYkFJPrCyUv1ZfhrM%2BBqc%3D"
  270. * }
  271. * }
  272. * @apiErrorExample {json} Error-Response:
  273. * HTTP/1.1 400 Bad Request
  274. * {
  275. * "state": false,
  276. * "code": 1000,
  277. * "message": "传入参数不正确",
  278. * "data": null or []
  279. * }
  280. * 可能出现的错误代码:
  281. * 1000 CLIENT_WRONG_PARAMS 传入参数不正确
  282. * 1300 MERCHANT_NOT_EXIST 商户不存在
  283. */
  284. public function charge(Request $request)
  285. {
  286. $goodsTypes = Order::getAllGoodsTypes();
  287. $gTypes = array_keys($goodsTypes);
  288. $payTypes = Order::getAllPayTypes();
  289. $pTypes = array_keys($payTypes);
  290. $validator = Validator::make($data = $request->input(),
  291. [
  292. 'number' => 'required|integer|min:1',
  293. 'type' => 'required|in:' . join(',', $pTypes),
  294. 'goods' => 'in:' . join(',', $gTypes),
  295. ],
  296. [
  297. 'number.required' => '充值金额必填',
  298. 'number.integer' => '金额必须为整数',
  299. 'number.min' => '充值金额至少为1',
  300. 'type.required' => '支付类型必填',
  301. 'type.in' => '支付类型非法',
  302. 'goods.in' => '充值商品非法',
  303. ]
  304. );
  305. if ($validator->fails()) {
  306. return $this->validatorError($validator->messages()->all(), ErrorCode::CLIENT_WRONG_PARAMS);
  307. }
  308. $user = Auth::user();
  309. $merchant = Merchant::where('user_id', '=', $user->id)->first();//模型支持单用户多商户,业务只设计单商户
  310. if (!$merchant) {
  311. return $this->error(ErrorCode::MERCHANT_NOT_EXIST);
  312. }
  313. $data['goods_id'] = 0;
  314. if (!isset($data['goods'])) {//默认充余额
  315. $data['goods'] = Order::GOODS_TYPE_BALANCE;
  316. }
  317. $data['user_type'] = Order::USER_TYPE_MERCHANT;
  318. $data['user_id'] = $user->id;//$merchant->id;
  319. if ($data['type'] == Order::PAY_TYPE_ALIPAY) {
  320. $result = $this->createAlipayCharge($data);
  321. } else {
  322. $result = $this->createWechatpayCharge($data);
  323. }
  324. if ($result === false) {
  325. return $this->error(ErrorCode::ORDER_GENERATE_FAILED);
  326. }
  327. //log
  328. // $data['amount'] = $data['number'];
  329. // $this->chargeLog('Merchant', $merchant->id, $merchant->name,
  330. // 'balance', $data['amount'], 'balance', $data['amount'],
  331. // 'Merchant', $user->id, $merchant->name);
  332. return $this->api($result);
  333. }
  334. }