admin/addon/cashier/model/order/CashierOrderPay.php

565 lines
24 KiB
PHP

<?php
/**
* ThinkShop商城系统 - 团队十年电商经验汇集巨献!
* =========================================================
* Copy right 2019-2029 上海牛之云网络科技有限公司, 保留所有权利。
* ----------------------------------------------
* 官方网址: https://www.cdcloudshop.com
* =========================================================
*/
namespace addon\cashier\model\order;
use addon\cardservice\model\MemberCard;
use addon\coupon\model\MemberCoupon;
use addon\memberrecharge\model\MemberrechargeOrder;
use addon\memberrecharge\model\MemberrechargeOrderCreate;
use addon\memberrecharge\model\o2o\O2oRechargeOrder;
use addon\o2o\model\member\MemberOnceCard;
use addon\o2o\model\store\Store;
use app\model\BaseModel;
use app\model\member\Hongbao;
use app\model\member\Member;
use app\model\member\MemberAccount;
use app\model\member\MemberLevelOrder;
use app\model\order\OrderCommon;
use app\model\order\OrderRefund;
use app\model\order\OrderStock;
use app\model\site\Site;
use app\model\store\Stat;
use app\model\system\Pay;
use think\facade\Log;
/**
* 收银订单
*
* @author Administrator
*
*/
class CashierOrderPay extends BaseModel
{
public function setCache($out_trade_no, $json)
{
$pay_model = new Pay();
$data = array (
'pay_json' => json_encode($json)
);
$condition = array (
[ 'out_trade_no', '=', $out_trade_no ]
);
$pay_model->edit($data, $condition);
//写入单据表
// Cache::set('cashier_cache_' . $out_trade_no, $json);
return $this->success();
}
public function getCache($out_trade_no)
{
$pay_model = new Pay();
$pay_info = $pay_model->getPayInfo($out_trade_no)[ 'data' ] ?? [];
$cache = !empty($pay_info[ 'pay_json' ]) ? json_decode($pay_info[ 'pay_json' ], true) : [];
// $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('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)
{
try {
$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();
} catch (\Exception $e) {
return $this->error('', $e->getMessage() . $e->getLine() . $e->getFile());
}
}
/**
* 订单线上支付
* @param unknown $out_trade_no
*/
public function orderPay($calculate)
{
model('order')->startTrans();
try {
$out_trade_no = $calculate[ 'out_trade_no' ];
$cashier_condition = array (
[ 'out_trade_no', '=', $out_trade_no ],
);
$cashier_order_info = model('order')->getInfo($cashier_condition, '*');
if ($cashier_order_info[ 'order_status' ] != 0) {
model('order')->rollback();
return $this->error([], '订单未处于待支付状态!');
}
$pay_type = empty($calculate[ 'pay_type' ]) ? 'ONLINE_PAY' : $calculate[ 'pay_type' ];
$cashier_order_model = new CashierOrder();
$order_common_model = new OrderCommon();
$pat_type_list = $order_common_model->getPayType(['order_type' => $cashier_order_info['order_type']]);
$pay_model = new Pay();
$pay_model->edit([ 'pay_type' => $pay_type ], [ [ 'out_trade_no', '=', $out_trade_no ] ]);
$cashier_order_type = $cashier_order_info[ 'cashier_order_type' ];
switch ( $cashier_order_type ) {
case 'goods':
$is_enable_refund = 1;
break;
case 'recharge':
$is_enable_refund = 0;
break;
case 'card':
$is_enable_refund = 1;
break;
}
$data = array (
'pay_money' => $calculate[ 'pay_money' ],
'pay_type' => $pay_type,
'pay_type_name' => $pat_type_list[$pay_type] ?? '',
'pay_status' => 1,
'pay_time' => time(),
'reduction' => $calculate[ 'reduction' ] ?? 0,
'round_money' => $calculate[ 'round_money' ],
'order_money' => $calculate[ 'order_money' ],
'promotion_money' => $calculate[ 'promotion_money' ] ?? 0,
'balance_money' => $calculate[ 'total_balance' ],//总余额 todo 暂时先不区分可提现和不可提现余额
'coupon_id' => $calculate[ 'coupon_id' ],
'coupon_money' => $calculate[ 'coupon_money' ] ?? 0,
'is_enable_refund' => $is_enable_refund,
);
$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('order')->update($data, $condition);
//扣除抵扣项
$offset_result = $this->deductOffset($calculate);
if ($offset_result[ 'code' ] < 0) {
model('order')->rollback();
return $offset_result;
}
$complete_result = $cashier_order_model->complete($cashier_order_info);
if ($complete_result[ 'code' ] < 0) {
model('order')->rollback();
return $complete_result;
}
$create_result = $this->create($cashier_order_info);
if ($create_result[ 'code' ] < 0) {
model('order')->rollback();
return $create_result;
}
model('order')->commit();
return $this->success();
} catch (\Exception $e) {
model('order')->rollback();
return $this->error('', $e->getMessage() . $e->getFile() . $e->getLine());
}
}
/**
* 订的创建
* @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 ],
);
$cashier_order_info = model('order')->getInfo($cashier_condition, '*');
model('order')->startTrans();
try {
$cashier_order_id = $cashier_order_info[ 'order_id' ];
$store_id = $cashier_order_info[ 'store_id' ];
//拆分订单
$order_goods_condition = array (
[ 'order_id', '=', $cashier_order_id ],
);
$order_goods_list = model('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[ 'cashier_order_type' ];
//根据商品类型合并订单组
$cashier_order_refund_model = new CashierOrderRefund();
$order_refund_model = new OrderRefund();
$store_stat = new Stat();
$stat_data = [];
switch ( $cashier_order_type ) {
case 'goods':
$cashier_trade_model = new CashierTrade();
$member_card_model = new MemberCard();
$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->cardUse($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_result = $order_refund_model->activeRefund($cashier_order_id, '', '订单退款');
//todo 理论上退款转账不会导致退失败
if ($refund_result[ 'code' ] < 0) {
model('order')->rollback();
return $refund_result;
}
model('order')->commit();
return $user_card_result;
}
}
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_result = $order_refund_model->activeRefund($cashier_order_id, '', '订单退款');
//todo 理论上退款转账不会导致退失败
if ($refund_result[ 'code' ] < 0) {
model('order')->rollback();
return $refund_result;
}
model('order')->commit();
return $cashier_result;
}
}
// 统计数据
$stat_data[ 'billing_count' ] = 1;
$stat_data[ 'billing_money' ] = $cashier_order_info[ 'pay_money' ];
break;
case 'recharge':
Log::write('收银订单创建');
$recharge_order_create_model = new MemberrechargeOrderCreate();
$recharge_order_model = new MemberrechargeOrder();
foreach ($order_goods_list as $k => $v) {
$item_sku_id = $v[ 'sku_id' ];
$goods_money = $v[ 'goods_money' ];
$data = [
'recharge_id' => $item_sku_id,//套餐id
'face_value' => $goods_money,//自定义充值面额
'member_id' => $member_id,
'order_from' => $cashier_order_info[ 'order_from' ],
'order_from_name' => $cashier_order_info[ 'order_from_name' ],
'site_id' => $site_id,
'relate_id' => $cashier_order_id,
'relate_type' => 'order'
];
$recharge_order_result = $recharge_order_create_model->create($data);
//todo 这儿也应该退款的
if ($recharge_order_result[ 'code' ] < 0) {
model('order')->rollback();
Log::write('充值订单错误' . json_encode($recharge_order_result));
return $recharge_order_result;
}
$recharge_order_out_trade_no = $recharge_order_result[ 'data' ];
//todo 支付方式兼容(因为充值订单不一定有)
$result = $recharge_order_model->orderPay([
'out_trade_no' => $recharge_order_out_trade_no,
'pay_type' => $cashier_order_info[ 'pay_type' ]
]);
if ($result[ 'code' ] < 0) {
model('order')->rollback();
return $result;
}
}
// 统计数据
$stat_data[ 'recharge_count' ] = 1;
$stat_data[ 'recharge_money' ] = $cashier_order_info[ 'pay_money' ];
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('order')->commit();
// return $refund_res;
$refund_result = $order_refund_model->activeRefund($cashier_order_id, '', '订单退款');
//todo 理论上退款转账不会导致退失败
if ($refund_result[ 'code' ] < 0) {
model('order')->rollback();
return $refund_result;
}
model('order')->commit();
return $cashier_result;
}
}
// 统计数据
$stat_data[ 'buycard_count' ] = 1;
$stat_data[ 'buycard_money' ] = $cashier_order_info[ 'pay_money' ];
break;
}
$order_stock_model = new OrderStock();
$stock_params = array (
'store_id' => $store_id,
'goods_sku_list' => $order_goods_list,
'site_id' => $cashier_order_info[ 'site_id' ],
'user_info' => [
'uid' => $cashier_order_info[ 'cashier_operator_id' ],
'username' => $cashier_order_info[ 'cashier_operator_name' ],
]
);
$result = $order_stock_model->decOrderStock($stock_params);
if ($result[ 'code' ] < 0) {
$refund_result = $order_refund_model->activeRefund($cashier_order_id, '', '订单退款');
//todo 理论上退款转账不会导致退失败
if ($refund_result[ 'code' ] < 0) {
model('order')->rollback();
return $refund_result;
}
model('order')->commit();
return $result;
}
// 统计下单人数
if ($member_id) {
$count = model('order')->getCount([ [ 'member_id', '=', $member_id ], [ 'pay_status', '=', 1 ], [ 'store_id', '=', $store_id ] ]);
if ($count == 1) $stat_data[ 'order_member_count' ] = 1;
if ($cashier_order_info[ 'balance_money' ]) $stat_data[ 'balance_money' ] = $cashier_order_info[ 'balance_money' ];
}
// 添加统计数据
if (!empty($stat_data)) {
$stat_data[ 'site_id' ] = $site_id;
$stat_data[ 'store_id' ] = $store_id;
$store_stat->addStoreStat($stat_data);
}
model('order')->commit();
return $this->success();
} catch (\Exception $e) {
model('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;
}
//抵扣余额
$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' ];
$cashier_order_type = $calculate_data[ 'cashier_order_type' ];
$order_id = $calculate_data[ 'order_id' ] ?? 0;
$is_use_balance = $calculate_data[ 'is_use_balance' ] ?? 0;
if (in_array($cashier_order_type, [ 'goods', 'card' ])) {
//判断是否已经扣除过余额
if ($is_use_balance > 0) {
$balance_money = $calculate_data[ 'total_balance' ] ?? 0;
if ($balance_money > 0) {
$member_model = new Member();
$member_account_model = new MemberAccount();
$member_condition = array (
[ 'member_id', '=', $member_id ],
[ 'site_id', '=', $site_id ]
);
$member_info = $member_model->getMemberInfo($member_condition)[ 'data' ] ?? [];
$member_balance = $member_info[ 'balance' ];//储值余额
$member_balance_money = $member_info[ '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;
$remark = '收银订单余额抵扣';
if ($temp_balance > 0) {
$result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance', -$temp_balance, $from_type, $relate_tag, $remark, $order_id);
if ($result[ 'code' ] < 0) {
return $result;
}
$order_data[ 'balance' ] = $temp_balance;
}
//扣除现金余额
$temp_balance = $member_balance_money;
if ($member_balance_money > $surplus) {
$temp_balance = $surplus;
}
$from_type = 'order';
$relate_tag = '余额抵扣';
$remark = '订单名称:' . $calculate_data[ 'order_name' ] . ',订单编号:' . $calculate_data[ 'out_trade_no' ] . ',订单金额:' . $calculate_data[ 'order_money' ] . ',订单余额抵扣,扣除储值余额:' . $temp_balance;
$remark = '收银订单余额抵扣';
if ($temp_balance > 0) {
$result = $member_account_model->addMemberAccount($site_id, $member_id, 'balance_money', -$temp_balance, $from_type, $relate_tag, $remark, $order_id);
if ($result[ 'code' ] < 0) {
return $result;
}
$order_data[ 'balance_money' ] = $temp_balance;
}
if (!empty($order_data)) {
$order_condition = array (
[ 'order_id', '=', $order_id ]
);
model('order')->update($order_data, $order_condition);
}
}
}
}
}
return $this->success();
}
public function useCoupon($calculate_data)
{
$coupon_id = $calculate_data[ 'coupon_id' ] ?? 0;
//只有开单和卡项可以用优惠券
$cashier_order_type = $calculate_data[ 'cashier_order_type' ];
if (in_array($cashier_order_type, [ 'goods', 'card' ])) {
if (!empty($coupon_id)) {
$order_id = $calculate_data[ 'order_id' ];
$member_coupon_model = new MemberCoupon();
//扣除优惠券
$result = $member_coupon_model->useMemberCoupon($coupon_id, $calculate_data[ 'member_id' ], $order_id);
if ($result[ 'code' ] < 0) {
return $result;
}
}
}
return $this->success();
}
}