success(); } public function getCache($out_trade_no) { $cache = Cache::get('cashier_cache_' . $out_trade_no); return $this->success($cache); } /** * 创建支付单据 * @param $params * @return array */ public function createPay($params) { $out_trade_no = $params['out_trade_no']; $cache = $this->getCache($out_trade_no)['data'] ?? []; $promotion = $cache['promotion'] ?? []; $member_id = $cache['member_id'] ?? 0; $site_id = $params['site_id']; $params['member_id'] = $member_id; $params['promotion'] = $promotion; $calculate_model = new CashierOrderCalculate(); $calculate_result = $calculate_model->calculate($params); if ($calculate_result['code'] < 0) { return $calculate_result; } $calculate = $calculate_result['data']; $pay_model = new Pay(); $pay_info = $pay_model->getPayInfo($out_trade_no)['data'] ?? []; $pay_money = $pay_info['pay_money']; $surplus_money = $calculate['surplus_money']; if ($pay_money != $surplus_money) { $pay_model->deletePay($out_trade_no); //如果金额与上次一样的话就不需要生成新的支付 // 生成整体付费支付单据 $pay_model->addPay($site_id, $out_trade_no, 'ONLINE_PAY', $calculate['order_name'], $calculate['order_name'], $surplus_money, '', 'CashierOrderPayNotify', ''); } return $this->success(); } /** * 去支付 * @param $params * @return array */ public function doPay($params) { $out_trade_no = $params['out_trade_no']; $cache = $this->getCache($out_trade_no)['data'] ?? []; $promotion = $cache['promotion'] ?? []; $member_id = $cache['member_id'] ?? 0; $condition = array( ['out_trade_no', '=', $out_trade_no] ); $info = model('store_cashier_order')->getInfo($condition); $pay_type = $params['pay_type']; $calculate_params = array( 'site_id' => $info['site_id'],//站点id 'out_trade_no' => $out_trade_no, 'store_id' => $info['store_id'], 'online_type' => $params['online_type'] ?? $pay_type, 'pay_type' => $pay_type, 'member_id' => $member_id, ); if(!empty($promotion)){ $calculate_params['promotion'] = $promotion; } $result = $this->confirm($calculate_params); return $result; } /** * 确认支付,生成订单 * @param $params * @return array */ public function confirm($params) { $calculate_model = new CashierOrderCalculate(); $result = $calculate_model->calculate($params); if ($result['code'] < 0) return $result; $calculate = $result['data']; $surplus_money = $calculate['surplus_money']; if ($surplus_money <= 0) { $result = $this->orderPay($calculate); if ($result['code'] < 0) return $result; } else { return $this->error([], '当前收银订单未支付'); } return $this->success(); } /** * 订单线上支付 * @param unknown $out_trade_no */ public function orderPay($calculate) { model('store_cashier_order')->startTrans(); try { $out_trade_no = $calculate['out_trade_no']; $cashier_condition = array( ['out_trade_no', '=', $out_trade_no], ); $cashier_order_info = model('store_cashier_order')->getInfo($cashier_condition, '*'); if ($cashier_order_info['status'] != 'topay') { model('store_cashier_order')->rollback(); return $this->error([], '订单未处于待支付状态!'); } $pay_type = empty($calculate['pay_type']) ? 'ONLINE_PAY' : $calculate['pay_type']; $data = array( 'pay_money' => $calculate['pay_money'], 'pay_type' => $pay_type, 'paid_money' => $calculate['paid_money'], 'surplus_money' => $calculate['surplus_money'], 'cash' => $calculate['cash'], 'cash_change' => $calculate['cash_change'] ?? 0, 'online_money' => $calculate['online_money'], 'online_type' => $calculate['online_type'], 'own_wechatpay' => $calculate['own_wechatpay'] ?? 0, 'own_alipay' => $calculate['own_alipay'] ?? 0, 'own_pos' => $calculate['own_pos'] ?? 0, 'pay_status' => 1, 'pay_time' => time(), 'reduction' => $calculate['reduction'] ?? 0, 'total_balance' => $calculate['total_balance'],//总余额 'point' => $calculate['point'] ?? 0, 'point_money' => $calculate['point_money'] ?? 0, 'coupon_id' => $calculate['coupon_id'], 'coupon_money' => $calculate['coupon_money'] ?? 0, 'hongbao_money' => $calculate['hongbao_money'] ?? 0, 'hongbao_id' => $calculate['hongbao_id'] ?? '', 'offset_money' => $calculate['offset_money'] ?? 0, 'discount_money' => $calculate['discount_money'] ?? 0, ); $member_id = $params['member_id'] ?? 0; if ($member_id > 0) { $data['member_id'] = $member_id; } $out_trade_no = $calculate['out_trade_no']; $condition = array( ['out_trade_no', '=', $out_trade_no], ); model('store_cashier_order')->update($data, $condition); //扣除抵扣项 $offset_result = $this->deductOffset($calculate); if ($offset_result['code'] < 0) { model('store_cashier_order')->rollback(); return $offset_result; } $cashier_data = array( 'status' => 'complete' ); model('store_cashier_order')->update($cashier_data, $cashier_condition); model('store_cashier_order')->commit(); $job_name = 'addon\store\job\CashierOrderCreate'; $job_data = [ 'out_trade_no' => $out_trade_no, ]; Queue::push($job_name, $job_data); return $this->success(); } catch ( \Exception $e ) { model('store_cashier_order')->rollback(); return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine()); } } /** * 获取收银订单的支付方式 * @param $order_info */ public function checkOrderPayType($order_info) { $cash = $order_info['cash']; $total_balance = $order_info['total_balance']; $online_money = $order_info['online_money']; $pay_money = $order_info['pay_money']; //只要存在线上支付金额,就去用线上的支付方式 if ($online_money > 0 && $online_money == $pay_money) { $online_type = $order_info['online_type']; return $online_type; } if ($total_balance > 0 && $total_balance == $pay_money) { return 'BALANCE'; } if ($cash > 0 && $cash == $pay_money) { return 'CASH'; } $own_wechatpay = $order_info['own_wechatpay'] ?? 0;//标记微信支付 $own_alipay = $order_info['own_alipay'] ?? 0;//标记支付宝 $own_pos = $order_info['own_pos'] ?? 0;//标记pos机 $own_money = $own_wechatpay + $own_alipay + $own_pos; if ($own_money > 0 && $own_money == $pay_money) { return 'SIGN'; } return 'MAKEUP'; } /** * 订的创建 * @param $params * @return array */ public function create($params) { Log::write('收银订单创建' . json_encode($params)); $out_trade_no = $params['out_trade_no']; $cashier_condition = array( ['out_trade_no', '=', $out_trade_no], // ['status', '=', 'topay'] ); $cashier_order_info = model('store_cashier_order')->getInfo($cashier_condition, '*'); model('store_cashier_order')->startTrans(); try { $cashier_order_id = $cashier_order_info['order_id']; $order_id = $cashier_order_info['order_id']; $store_id = $cashier_order_info['store_id']; // $pay_type = $this->checkOrderPayType($cashier_order_info); // $order_money = $cashier_order_info['order_money']; // $goods_money = $cashier_order_info['goods_money']; // $pay_money = $cashier_order_info['pay_money']; //拆分订单 $order_goods_condition = array( ['order_id', '=', $cashier_order_id], ['is_gift', '=', 0],//非赠品 ); $order_goods_list = model('store_cashier_order_goods')->getList($order_goods_condition); $site_id = $cashier_order_info['site_id']; $cashier_order_data = $cashier_order_info; $cashier_order_data['goods_list'] = $order_goods_list; $member_id = $cashier_order_info['member_id']; $cashier_order_type = $cashier_order_info['order_type']; //根据商品类型合并订单组 $member_model = new Member(); $member_condition = array( ['member_id', '=', $member_id], ); $member_info = $member_model->getMemberInfo($member_condition)['data'] ?? []; $cashier_order_refund_model = new CashierOrderRefund(); switch ($cashier_order_type) { case 'goods': $cashier_trade_model = new CashierTrade(); $member_card_model = new MemberOnceCard(); $item_list = []; foreach ($order_goods_list as $k => $v) { $card_item_id = $v['card_item_id']; if ($card_item_id > 0) { $num = $v['num']; $order_goods_id = $v['order_goods_id']; $type = 'order'; //订单使用此卡 $item_params = array( 'item_id' => $card_item_id, 'num' => $num, 'type' => $type, 'relation_id' => $order_goods_id, 'store_id' => $store_id ); $item_list[] = $item_params; } } if (!empty($item_list)) { $user_card_result = $member_card_model->onceCardUse($item_list); Log::write('使用此卡错误' . json_encode($user_card_result)); if ($user_card_result['code'] < 0) { $cashier_order_data['refund_reason'] = $user_card_result['message']; $refund_res = $cashier_order_refund_model->activeOrderRefund($cashier_order_data); model('store_cashier_order')->commit(); return $refund_res; } else { $out_relation_ids = $user_card_result['data']['out_relation_ids'] ?? []; //设置订单项为已扣除库存 $cashier_order_goods_model = new CashierOrderGoods(); $cashier_order_goods_model->setOrderGoodsIsDecStock([['order_goods_id', 'in', $out_relation_ids]]); } } foreach ($order_goods_list as $k => $v) { $cashier_result = $cashier_trade_model->toSend($v, $cashier_order_info); if ($cashier_result['code'] < 0) { $cashier_order_data['refund_reason'] = $cashier_result['message']; $refund_res = $cashier_order_refund_model->activeOrderRefund($cashier_order_data); model('store_cashier_order')->commit(); return $refund_res; } } break; case 'level': foreach ($order_goods_list as $k => $v) { $item_goods_id = $v['goods_id']; $item_sku_id = $v['sku_id']; $member_level_order_model = new MemberLevelOrder(); $params = [ 'site_id' => $site_id, 'level_id' => $item_goods_id, 'period_unit' => $item_sku_id, 'member_id' => $member_id, 'cashier_id' => $cashier_order_id, 'store_id' => $store_id, ]; $member_level_order_result = $member_level_order_model->create($params); if ($member_level_order_result['code'] < 0) { model('store_cashier_order')->rollback(); return $member_level_order_result; } $item_out_trade_no = $member_level_order_result['data']['out_trade_no']; $member_level_order_result = $member_level_order_model->orderPay(['out_trade_no' => $item_out_trade_no]); if ($member_level_order_result['code'] < 0) { model('store_cashier_order')->rollback(); return $member_level_order_result; } } break; case 'recharge': Log::write('收银订单创建'); $recharge_order_model = new O2oRechargeOrder(); foreach ($order_goods_list as $k => $v) { $item_goods_id = $v['goods_id']; $item_sku_id = $v['sku_id']; $goods_money = $v['goods_money']; $data = [ 'site_id' => $site_id, 'money' => $goods_money, 'promotion_id' => $item_goods_id, 'promotion_name' => $v['goods_name'], 'group_id' => $item_sku_id, 'member_id' => $member_id, 'fans_id' => 0, 'cashier_id' => $cashier_order_id, 'store_id' => $store_id, ]; $recharge_order_result = $recharge_order_model->recharge($data); if ($recharge_order_result['code'] < 0) { model('store_cashier_order')->rollback(); Log::write('充值订单错误' . json_encode($recharge_order_result)); return $recharge_order_result; } } break; case 'card': $cashier_trade_model = new CashierTrade(); foreach ($order_goods_list as $k => $v) { $cashier_result = $cashier_trade_model->toSend($v, $cashier_order_info); if ($cashier_result['code'] < 0) { // $refund_res = $cashier_order_refund_model->orderRefund(['order_id' => $order_id]); // model('store_cashier_order')->commit(); // return $refund_res; } } break; } //赠品发放 $gift_order_goods_condition = array( ['order_id', '=', $cashier_order_id], ['is_gift', '=', 1],//非赠品 ); $gift_order_goods_list = model('store_cashier_order_goods')->getList($gift_order_goods_condition); if(!empty($gift_order_goods_list)){ $cashier_trade_model = new CashierTrade(); foreach ($gift_order_goods_list as $k => $v) { $cashier_result = $cashier_trade_model->toSend($v, $cashier_order_info); if ($cashier_result['code'] < 0) { } } } $job_name = 'addon\store\job\CashierOrderReward'; $reward_params = [ 'order_id' => $order_id, 'site_id' => $site_id, 'member_id' => $member_id, ]; Queue::push($job_name, $reward_params); event('SiteStat', [ 'site_id' => $cashier_order_info['site_id'], 'store_id' => $cashier_order_info['store_id'] ?? 0, 'stat_type' => 'cashier_order', 'order_info' => $cashier_order_info, 'order_goods_list' => $order_goods_list, ]); model('store_cashier_order')->commit(); return $this->success(); } catch ( \Exception $e ) { model('store_cashier_order')->rollback(); Log::write('收银单支付完成错误' . $e->getMessage() . $e->getFile() . $e->getLine()); return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine()); } } /** * 抵扣扣除 * @param $calculate_data */ public function deductOffset($calculate_data) { //使用优惠券 $coupon_result = $this->useCoupon($calculate_data); if ($coupon_result['code'] < 0) { return $coupon_result; } //记录调价 $reduction_result = $this->useReduction($calculate_data); if ($reduction_result['code'] < 0) { return $reduction_result; } //扣除积分 $point_result = $this->deductPoint($calculate_data); if ($point_result['code'] < 0) { return $point_result; } // //抵扣红包 $hongbao_result = $this->useHongbao($calculate_data); if ($hongbao_result['code'] < 0) { return $hongbao_result; } //抵扣余额 $balance_result = $this->deductBalance($calculate_data); if ($balance_result['code'] < 0) { return $balance_result; } return $this->success(); } /** * 扣除余额 * @param $calacalc_data */ public function deductBalance($calculate_data) { $member_id = $calculate_data['member_id']; $site_id = $calculate_data['site_id']; $is_deduct_balance = $calculate_data['is_deduct_balance'] ?? 0; $order_type = $calculate_data['order_type']; $order_id = $calculate_data['order_id'] ?? 0; $is_use_balance = $calculate_data['is_use_balance'] ?? 0; if (in_array($order_type, ['goods', 'card'])) { //判断是否已经扣除过余额 if (!$is_deduct_balance && $is_use_balance > 0) { $balance_money = $calculate_data['total_balance'] ?? 0; if ($balance_money > 0) { $order_offset_model = new CashierOrderOffset(); $offset_info = $order_offset_model->getOrderOffsetInfo([['order_id', '=',$order_id], ['type', 'in', ['balance','balance_money']]])['data'] ?? []; if(empty($offset_info)) { $member_account_model = new MemberAccount(); $member_account_condition = array( ['member_id', '=', $member_id], ['site_id', '=', $site_id] ); $member_account = $member_account_model->getMemberAccount($member_account_condition)['data'] ?? []; $member_balance = $member_account['balance'];//储值余额 $member_balance_money = $member_account['balance_money'];//现金余额 if ($balance_money > 0) { $order_data = array(); //优先扣除可不提现余额 $surplus = $balance_money; $temp_balance = $member_balance; if ($member_balance > $surplus) { $temp_balance = $surplus; } $surplus -= $temp_balance; $from_type = 'order'; $relate_tag = '余额抵扣'; $remark = '订单名称:' . $calculate_data['order_name'] . ',订单编号:' . $calculate_data['out_trade_no'] ?? '' . ',订单金额:' . $calculate_data['order_money'] . ',订单余额抵扣,扣除储值余额:' . $temp_balance; $account_title = '订单余额抵扣'; if ($temp_balance > 0) { $result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance', -$temp_balance, $from_type, $relate_tag, $remark, $account_title); if ($result['code'] < 0) { return $result; } $order_data['balance'] = $temp_balance; $discount_params = array( 'order_id' => $order_id, 'type' => 'balance', 'num' => $temp_balance, 'offset_money' => $temp_balance, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'offset' ); $order_offset_model->addOrderOffset($discount_params); } //扣除现金余额 $temp_balance = $member_balance_money; if ($member_balance_money > $surplus) { $temp_balance = $surplus; } // $surplus -= $temp_balance; $from_type = 'order'; $relate_tag = '余额抵扣'; $remark = '订单名称:' . $calculate_data['order_name'] . ',订单编号:' . $calculate_data['out_trade_no'] . ',订单金额:' . $calculate_data['order_money'] . ',订单余额抵扣,扣除储值余额:' . $temp_balance; $account_title = '订单余额抵扣'; if ($temp_balance > 0) { $result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance_money', -$temp_balance, $from_type, $relate_tag, $remark, $account_title); if ($result['code'] < 0) { return $result; } $order_data['balance_money'] = $temp_balance; $discount_params = array( 'order_id' => $order_id, 'type' => 'balance_money', 'num' => $temp_balance, 'offset_money' => $temp_balance, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'offset' ); $order_offset_model->addOrderOffset($discount_params); } if (!empty($order_data)) { $order_data['is_deduct_balance'] = 1; $order_condition = array( ['order_id', '=', $order_id] ); model('store_cashier_order')->update($order_data, $order_condition); } } } } } } return $this->success(); } /** * 扣除积分 * @param $calacalc_data */ public function deductPoint($calculate_data) { $member_account_model = new MemberAccount(); $member_id = $calculate_data['member_id']; $site_id = $calculate_data['site_id']; $point = $calculate_data['point'] ?? 0; $order_id = $calculate_data['order_id'] ?? 0; $point_money = $calculate_data['point_money'] ?? 0; $order_type = $calculate_data['order_type']; if (in_array($order_type, ['goods', 'card'])) { if ($point > 0) { $is_use_point = $calculate_data['is_use_point'] ?? 0; if($is_use_point > 0){ $order_offset_model = new CashierOrderOffset(); $offset_info = $order_offset_model->getOrderOffsetInfo([['order_id', '=',$order_id], ['type', '=', 'point']])['data'] ?? []; if(empty($offset_info)) { $from_type = 'order'; $relate_tag = '积分抵扣'; $remark = '收银订单积分抵扣,扣除积分:' . $point; $account_title = '收银订单积分抵扣'; $result = $member_account_model->addMemberAccount($site_id, $member_id, 'point', -$point, $from_type, $relate_tag, $remark, $account_title); if ($result['code'] < 0) { return $result; } //增加订单优惠项 $discount_params = array( 'order_id' => $order_id, 'type' => 'point', 'num' => $point, 'offset_money' => $point_money, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'offset' ); $order_offset_model->addOrderOffset($discount_params); } } } } return $this->success(); } public function useCoupon($calculate_data) { $coupon_id = $calculate_data['coupon_id'] ?? 0; $site_id = $calculate_data['site_id']; $order_type = $calculate_data['order_type']; $order_id = $calculate_data['order_id'] ?? 0; //只有开单和卡项可以用优惠券 $order_type = $calculate_data['order_type']; if (in_array($order_type, ['goods', 'card'])) { if (!empty($coupon_id)) { $order_offset_model = new CashierOrderOffset(); $offset_info = $order_offset_model->getOrderOffsetInfo([['order_id', '=',$order_id], ['type', '=', 'coupon']])['data'] ?? []; if(empty($offset_info)){ $coupon_money = $calculate_data['coupon_money']; $order_id = $calculate_data['order_id']; $order_goods_id_map = $calculate_data['order_goods_id_map']; $coupon_order_goods_id_array = []; $coupon_order_goods_id = $calculate_data['coupon_order_goods_ids'] ?? []; foreach($order_goods_id_map as $k => $v){ if(in_array($k, $coupon_order_goods_id)){ $coupon_order_goods_id_array[] = $v; } } $member_coupon_model = new MemberCoupon(); $coupon_data = array( 'site_id' => $calculate_data['site_id'], 'member_id' => $calculate_data['member_id'], 'coupon_id' => $coupon_id, 'order_id' => $order_id ); $result = $member_coupon_model->useCoupon($coupon_data); if ($result['code'] < 0) { return $result; } //增加订单优惠项 $offset_params = array( 'order_id' => $order_id, 'type' => 'coupon', 'num' => 1, 'relate_id' => $coupon_id, 'order_goods_id' => implode(',', $coupon_order_goods_id_array), 'offset_money' => $coupon_money, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'discount' ); $order_offset_model->addOrderOffset($offset_params); } } } return $this->success(); } /** *批量使用红包 * @param $calculate_data */ public function useHongbao($calculate_data) { $hongbao_id = $calculate_data['hongbao_id'] ?? ''; $site_id = $calculate_data['site_id']; $order_type = $calculate_data['order_type']; if(in_array($order_type, ['goods', 'card'])) { if (!empty($hongbao_id)) { $order_id = $calculate_data['order_id'] ?? 0; $order_offset_model = new CashierOrderOffset(); $offset_info = $order_offset_model->getOrderOffsetInfo([['order_id', '=',$order_id], ['type', '=', 'hongbao']])['data'] ?? []; if(empty($offset_info)) { $hongbao_model = new Hongbao(); $hongbao_id_array = explode(',', $hongbao_id); $hongbao_money = $calculate_data['hongbao_money']; $order_goods_id = $calculate_data['order_goods_id'] ?? ''; $hongbao_data = array( 'site_id' => $calculate_data['site_id'], 'member_id' => $calculate_data['member_id'], 'hongbao_id_array' => $hongbao_id_array, 'order_id' => $calculate_data['order_id'], ); $result = $hongbao_model->batchUse($hongbao_data); if ($result['code'] < 0) return $result; //增加订单优惠项 foreach ($hongbao_id_array as $k => $v) { $offset_params = array( 'order_id' => $order_id, 'type' => 'hongbao', 'num' => 1, 'relate_id' => $v, 'order_goods_id' => $order_goods_id, 'offset_money' => $hongbao_money, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'discount' ); $order_offset_model->addOrderOffset($offset_params); } } } } return $this->success(); } /** * 记录调价 * @param $calculate_data * @return array */ public function useReduction($calculate_data) { $site_id = $calculate_data['site_id']; $order_type = $calculate_data['order_type']; $reduction = $calculate_data['reduction'] ?? 0; if ($reduction > 0) { $order_id = $calculate_data['order_id'] ?? 0; $order_offset_model = new CashierOrderOffset(); $offset_info = $order_offset_model->getOrderOffsetInfo([['order_id', '=',$order_id], ['type', '=', 'reduction']])['data'] ?? []; if(empty($offset_info)) { $offset_params = array( 'order_id' => $order_id, 'type' => 'reduction', 'num' => $reduction, 'relate_id' => 0, 'order_goods_id' => '', 'offset_money' => $reduction, 'site_id' => $site_id, 'store_id' => $calculate_data['store_id'], 'offset_type' => 'discount' ); $order_offset_model->addOrderOffset($offset_params); } } return $this->success(); } /** * 奖励 * @param $calculate_data * @return array */ public function rewardAction($calculate_data){ $reward = $calculate_data['reward'] ?? []; if(!empty($reward)){ $member_id = $calculate_data['member_id']; $order_reward_model = new CashierOrderReward(); $order_id = $calculate_data['order_id'] ?? 0; $site_id = $calculate_data['site_id']; foreach($reward as $k => $v){ foreach($v as $item_k => $item){ $order_goods_id_map = $calculate_data['order_goods_id_map']; $item_order_goods_id = []; $item_sku_ids = $item['keys'] ?? []; foreach($order_goods_id_map as $map_k => $map_v){ if(in_array($map_k, $item_sku_ids)){ $item_order_goods_id[] = $map_v; } } $reward_array = array( 'order_id' => $order_id, 'promotion_type' => $item['promotion_type'], 'promotion_id' => $item['promotion_id'], 'type' => $k, 'order_goods_id' => implode(',', $item_order_goods_id), 'num' => $item['num'], 'relate_id' => $item['relate_id'], 'site_id' => $site_id, 'member_id' => $member_id, 'desc' => $item['desc'], 'status' => $item['status'] ?? 0 ); $order_reward_model->addOrderReward($reward_array); } } } return $this->success(); } }