checkUid()) { return response()->error('XCX_NOT_LOGIN'); } $device = $request->has('device')?$request->get('device'):''; // 苹果先不展示充值 if($device == 'iPhone'){ return response()->success(); } $res = ProductService::getChargeProduct(); if (!$res->isEmpty()) { $data = []; foreach ($res as $v) { $intro = []; if ($v->given > 0 && $v->type == 'TICKET_RECHARGE') { $intro = [ [ 'label' => ($v->price * 100) . "+", 'important' => false, ], [ 'label' => $v->given, 'important' => true, ], [ 'label' => '书币', 'important' => false, ] ]; $intro2 = [ ['label' => '多送', 'important' => false], ['label' => (int)($v->given / 100), 'important' => true], ['label' => '元', 'important' => false], ]; $v->vip = 0; } if ($v->given == 0 && $v->type == 'TICKET_RECHARGE') { $intro = [ [ 'label' => $v->price * 100, 'important' => false, ], [ 'label' => '书币', 'important' => false, ] ]; $v->vip = 0; $intro2 = []; } if ($v->given == 0 && $v->type == 'YEAR_ORDER') { $intro = [ [ 'label' => '年费VIP会员', 'important' => true, ] ]; $v->vip = 1; $intro2 = [ ['label' => '每天1元,全年免费看', 'important' => false], ]; } $data[] = [ 'product_id' => $v->id, 'price' => (int)$v->price . '元', 'vip' => $v->vip, 'intro' => $intro, 'intro2' => $intro2, 'is_default' => $v->is_default, ]; } return response()->success($data); } else { return response()->error('XCX_SYS_ERROR'); } } /** * @apiVersion 1.0.0 * @apiDescription 单本消费记录 * @api {get} order/bookOrderList 单本消费记录 * @apiParam {String} [token] token * @apiHeader {String} [Authorization] token 两个token任选其一 * @apiGroup Order * @apiName bookOrderList * @apiSuccess {int} code 状态码 * @apiSuccess {String} msg 信息 * @apiSuccess {object} data 结果集 * @apiSuccess {Int} uid uid * @apiSuccess {Int} bid bid * @apiSuccess {Int} book_name 书名 * @apiSuccess {Int} fee 钱 * @apiSuccess {String} created_at 时间 * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * code: 0, * msg: "", * data: list:[ * { * uid: 4, * bid: 1, * book_name: "dfsedfertrwet", * fee: 100, * created_at: "2017-12-02 16:24:54" * } * ] * meta: { * total: 1, * per_page: 15, * current_page: 1, * last_page: 1, * next_page_url: "", * prev_page_url: "" * } * } */ public function bookOrderList(Request $request) { if (!$this->checkUid()) { return response()->error('XCX_NOT_LOGIN'); } $page_size = $request->input('page_size', 15); $book_order = BookOrderService::getRecord($this->uid, $page_size); //$book_order = BookOrder::where('uid', $this->uid)->select('bid', 'uid', 'book_name', 'created_at', 'fee')->paginate($page_size); return response()->pagination(new BookOrderTransformer(), $book_order); } /** * @apiVersion 1.0.0 * @apiDescription 章节消费记录 * @api {get} order/chapterOrderList 章节消费记录 * @apiParam {String} [token] token * @apiHeader {String} [Authorization] token 两个token任选其一 * @apiGroup Order * @apiName chapterOrderList * @apiSuccess {int} code 状态码 * @apiSuccess {String} msg 信息 * @apiSuccess {object} data 结果集 * @apiSuccess {Int} uid uid * @apiSuccess {Int} bid bid * @apiSuccess {Int} cid cid * @apiSuccess {Int} chapter_name 章节名 * @apiSuccess {Int} book_name 书名 * @apiSuccess {Int} fee 钱 * @apiSuccess {String} created_at 时间 * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * code: 0, * msg: "", * data: list:[ * { * uid: 4, * bid: 1, * cid: 1, * chapter_name: "sdfsd", * book_name: "dfsedfertrwet", * fee: 100, * created_at: "2017-12-02 16:24:54" * } * ] * meta: { * total: 1, * per_page: 15, * current_page: 1, * last_page: 1, * next_page_url: "", * prev_page_url: "" * } * } */ public function chapterOrderList(Request $request) { if (!$this->checkUid()) { return response()->error('XCX_NOT_LOGIN'); } $chapter_model = new ChapterOrderService(); $page_size = $request->input('page_size', 15); $chapter_order = $chapter_model->getByUid($this->uid, $page_size); return response()->pagination(new ChapterOrderTransformer(), $chapter_order); } /** * @apiVersion 1.0.0 * @apiDescription 充值记录 * @api {get} order/chargeRecordLists 充值记录 * @apiParam {String} [token] token * @apiHeader {String} [Authorization] token 两个token任选其一 * @apiGroup Order * @apiName chargeRecordLists * @apiSuccess {int} code 状态码 * @apiSuccess {String} msg 信息 * @apiSuccess {object} data 结果集 * @apiSuccess {String} data.price 价格 * @apiSuccess {String} data.status 状态 * @apiSuccess {String} data.trade_no 订单号 * @apiSuccess {String} data.created_at 时间 * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * code: 0, * msg: "", * data: { * list: [ * { * id: 134, * price: "1.00", * status: "PAID", * trade_no: "201712021915481585670623626232", * created_at: "2017-12-02 19:15:56" * } * ], * meta: { * total: 1, * per_page: 15, * current_page: 1, * last_page: 1, * next_page_url: "", * prev_page_url: "" * } * } * } */ public function chargeRecordLists(Request $request) { if (!$this->checkUid()) { return response()->error('XCX_NOT_LOGIN'); } $page_size = $request->input('page_size', 15); $res = OrderService::getOrderList($this->uid, $page_size); return response()->pagination(new ChargeListTransformer(), $res); } //订单是否成功 public function isSuccess(Request $request) { $order = $request->input('order'); $order_info = OrderService::getByTradeNo($order); if ($order_info && $order_info->status == 'PAID') { return response()->success(); } return response()->error('XCX_SYS_ERROR'); } /** * @apiVersion 1.0.0 * @apiDescription 支付 * @api {get} goToPay 支付 * @apiGroup pay * @apiName wxindex * @apiParam {Int} product_id product_id * @apiParam {String} [token] token * @apiHeader {String} [Authorization] token 两个token任选其一 * @apiParam {String} bid bid * @apiParam {String} sign 签名 * @apiSuccess {int} code 状态码 * @apiSuccess {String} msg 信息 * @apiSuccess {Object} data 信息 * @apiSuccess {Object} data.appId 唤起支付的appId * @apiSuccess {Object} data.package 唤起支付的package * @apiSuccess {Object} data.nonceStr 唤起支付的nonceStr * @apiSuccess {Object} data.timeStamp 唤起支付的timeStamp * @apiSuccess {Object} data.signType 唤起支付的signType * @apiSuccess {Object} data.paySign 唤起支付sign * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * code: 0, * msg: "", * data: { * * } */ function wxindex(Request $request) { Log::info($request->all()); $product_id = $request->has('product_id') ? $request->get('product_id') : ''; $sign = $request->has('sign') ? $request->get('sign') : ''; $send_order_id = $request->has('send_order_id') ? $request->get('send_order_id') : 0; if (!$this->checkUid()) { return response()->error('XCX_NOT_LOGIN'); } if (empty($product_id) || empty($sign)) { return response()->error('XCX_PARAM_ERROR'); } if (!$this->checkSign($request->all('_url'))) { //return response()->error('XCX_PARAM_ERROR'); } $bid = $request->has('bid') ? $request->get('bid') : 0; $openid = $this->openid; //$openid = 'o0bsX0b3-kgWIb4JBdTAk7HVtnrk'; //根据分校id获取支付配置id $trade_no = date("YmdHis") . hexdec(uniqid()); $product_info = ProductService::getProductSingle($product_id); $uid = $this->uid; $distribution_channel_id = $this->distribution_channel_id; $price = $product_info->price * 100; if ($uid < 32) { //$price = 1; } if (in_array($uid, explode(',', env('TEST_UID')))) { $price = 1; } if ($bid) { try { $bid = Hashids::decode($bid)[0]; } catch (\Exception $e) { $bid = 0; } } //$price = 1; if ($product_info->type == 'YEAR_ORDER') { $order_type = 'YEAR'; } elseif ($product_info->type == 'BOOK_ORDER') { $order_type = 'BOOK'; } elseif ($product_info->type == 'TICKET_RECHARGE') { $order_type = 'RECHARGE'; } else { $order_type = ''; } $res = $this->createUnPayOrder([ 'distribution_channel_id' => $distribution_channel_id, 'uid' => $uid, 'product_id' => $product_id, 'price' => $price / 100, 'pay_type' => 1, 'trade_no' => $trade_no, 'pay_merchant_source' => 'XIAOCHENGXU', 'pay_merchant_id' => 0, 'create_ip' => $request->getClientIp(), 'send_order_id' => $send_order_id, 'order_type' => $order_type, 'from_bid' => $bid, 'from_type' => 'KuaiYingYong', 'activity_id'=>0 ]); Log::info('order is'); Log::info($res); //微信下单 $options = [ 'app_id' => 'wxa0c8331eba3b34d5', 'payment' => [ 'merchant_id' => 1501944981, 'key' => 'ee245088b93ba88008279d95f6d30413', ] ]; $app = new Application($options); $payment = $app->payment; $attributes = [ 'trade_type' => 'JSAPI', 'body' => 'novel read', 'detail' => 'novel read', 'out_trade_no' => $trade_no, 'total_fee' => $price, 'notify_url' => env('XCX_PAY_CALL_BACK_URL'), 'openid' => $openid, 'spbill_create_ip' => $request->getClientIp(), ]; $order = new Wxorder($attributes); Log::info('wexin order--------'); Log::info($order); $result = $payment->prepare($order); Log::info('wexin order--xcx--result-----'); Log::info($result); if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS') { Log::info('wechat success in'); $data = [ 'appId' => $result->appid, 'package' => 'prepay_id=' . $result->prepay_id, 'nonceStr' => $result->nonce_str, 'timeStamp' => (string)time(), 'signType' => 'MD5', ]; $data['paySign'] = $this->MakeSign($data); unset($data['appId']); $data['order'] = $trade_no; $data = [ 'code' => 0, 'msg' => '', 'data' => $data ]; return response()->json(($data)); } return null; } /** * @apiVersion 1.0.0 * @apiDescription 订单查询 * @api {get} checkOrder 订单查询 * @apiGroup pay * @apiName checkOrder * @apiParam {String} [token] token * @apiHeader {String} [Authorization] token 两个token任选其一 * @apiParam {String} order order * @apiSuccess {int} code 状态码 * @apiSuccess {String} msg 信息 * @apiSuccess {Object} data 信息 * @apiSuccessExample {json} Success-Response: * HTTP/1.1 200 OK * { * code: 0, * msg: "", * data: { * * } */ public function checkOrder(Request $request){ $order = $request->input('order',''); $i = 0; $uid = $this->uid; while ($i <= 10){ $order_info = OrderService::getByTradeNo($order); if(!$order_info){ return response()->error('XCX_SYS_ERROR'); break; } if (isset($order_info->status) && $order_info->status == 'PAID') { $data['balance'] = 0; $user = UserService::getById($uid); if($user){ $data['balance'] = $user->balance; } return response()->success($data); } sleep(1); $i++; } return response()->error('XCX_SYS_ERROR'); } protected function MakeSign($value) { $data = $value; //签名步骤一:按字典序排序参数 ksort($data); $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); //签名步骤二:在string后加入KEY $string = $buff . "&key=" . 'ee245088b93ba88008279d95f6d30413'; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } /** * 官方微信回调 * @param Request $request * @return */ function wxback_xcx(Request $request) { Log::info('-------------en----------------'); $options = [ 'app_id' => 'wxa0c8331eba3b34d5', 'payment' => [ 'merchant_id' => 1501944981, 'key' => 'ee245088b93ba88008279d95f6d30413', ] ]; $app = new Application($options); $response = $app->payment->handleNotify(function ($notify, $successful) { if (!$successful) return 'fail'; $trade_no = $notify->out_trade_no; $order = OrderService::getByTradeNo($trade_no); if (!$order) { return 'fail'; } if (isset($order->status) && $order->status == 'PAID') { Log::info('has_pay:' . $trade_no); return true; } DB::beginTransaction(); try { $transaction_id = $notify->transaction_id; $uid = $order->uid; $distribution_channel_id = $order->distribution_channel_id; $product_id = $order->product_id; $product = ProductService::getProductSingle($product_id); $send_order_id = 0; $price = $product->price; //$this->updateOrderTotal($trade_no,$transaction_id); // 更新其他定制Order表 if ($product->type == 'YEAR_ORDER') { Log::info('YEAR_ORDERYEAR_ORDERYEAR_ORDERYEAR_ORDERYEAR_ORDERYEAR_ORDERYEAR_ORDERYEAR_ORDER'); $order_type = 'YEAR'; $this->yearOrder($uid, $distribution_channel_id, $price, $send_order_id); $order->order_type = $order_type; $order->status = 'PAID'; $order->pay_end_at = date('Y-m-d H:i:s'); $order->transaction_id = $transaction_id; $order->save(); } elseif ($product->type == 'BOOK_ORDER') { Log::info('BOOK_ORDERBOOK_ORDERBOOK_ORDERBOOK_ORDERBOOK_ORDERBOOK_ORDERBOOK_ORDERBOOK_ORDER'); $order_type = 'BOOK'; $this->bookOrder($product_id, $uid, $send_order_id, $price, $distribution_channel_id); $order->order_type = $order_type; $order->status = 'PAID'; $order->pay_end_at = date('Y-m-d H:i:s'); $order->transaction_id = $transaction_id; $order->save(); } elseif ($product->type == 'TICKET_RECHARGE') { Log::info('TICKET_RECHARGETICKET_RECHARGETICKET_RECHARGETICKET_RECHARGETICKET_RECHARGE'); $order_type = 'RECHARGE'; $this->userCharge($product, $uid); $order->order_type = $order_type; $order->status = 'PAID'; $order->pay_end_at = date('Y-m-d H:i:s'); $order->transaction_id = $transaction_id; $order->save(); } else { DB::rollback(); return 'Order not exist.'; } DB::commit(); return true; } catch (\Exception $e) { DB::rollback(); return 'fail'; } }); return $response; } /** * 单本充值会掉 * @param $product_id * @param $uid * @param $send_order_id * @param $fee */ private function bookOrder($product_id, $uid, $send_order_id, $fee, $distribution_channel_id) { $book_conf = BookConfigService::getBookByProduct($product_id); $insert_data['bid'] = isset($book_conf->bid) ? $book_conf->bid : ''; $insert_data['book_name'] = isset($book_conf->book_name) ? $book_conf->book_name : ''; $insert_data['uid'] = $uid; $insert_data['distribution_channel_id'] = $distribution_channel_id; $insert_data['fee'] = $fee; $insert_data['send_order_id'] = $send_order_id; $insert_data['charge_balance'] = 0; $insert_data['reward_balance'] = 0; Log::info('start_save_book_order'); Log::info($insert_data); return BookOrderService::save_book_order($insert_data); } /** * 包年 * @param $uid * @param $distribution_channel_id * @param $fee * @param $send_order_id * @return mixed */ private function yearOrder($uid, $distribution_channel_id, $fee, $send_order_id) { Log::info('start_save_year_order'); $insert_data['uid'] = $uid; $insert_data['distribution_channel_id'] = $distribution_channel_id; $insert_data['fee'] = $fee; $insert_data['send_order_id'] = $send_order_id; Log::info($insert_data); return YearOrderService::save_year_order($insert_data); } /** * 用户充值 * @param $product * @param $uid\ */ private function userCharge($product, $uid) { $total = $product->price * 100 + $product->given; UserService::addBalance($uid, $total, $product->price * 100, $product->given); Log::info('update_user_balance_end:' . $uid . ' balance_add:' . $total); } /** * 添加位置付订单 * @param $data * @return mixed */ private function createUnPayOrder($data) { $data['status'] = 'UNPAID'; $data['transaction_id'] = ''; $data['pay_end_at'] = '0000-00-00 00:00:00'; return OrderService::save_order($data); } }