481 lines
24 KiB
PHP
481 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* SaaSMall商城系统 - 团队十年电商经验汇集巨献!
|
|
* =========================================================
|
|
* Copy right 2019-2029 成都SAAS云科技有限公司, 保留所有权利。
|
|
* ----------------------------------------------
|
|
* 官方网址: https://www.gobuysaas.com
|
|
* =========================================================
|
|
*/
|
|
namespace addon\alilife\model;
|
|
use addon\aliapp\model\MinCode;
|
|
use addon\alipay\model\Pay as PayModel;
|
|
use app\model\BaseModel;
|
|
use app\model\member\MemberAddress;
|
|
use app\model\order\OrderCommon;
|
|
use app\model\order\OrderCommon as OrderCommonModel;
|
|
use app\model\order\OrderRefund as OrderRefundModel;
|
|
class Order extends BaseModel
|
|
{
|
|
|
|
/***
|
|
* 同步异常订单
|
|
* @param $trade_no //支付宝交易号
|
|
* @param $site_id
|
|
* @return void
|
|
*/
|
|
public function syncRepair($trade_no, $order_id, $site_id)
|
|
{
|
|
$apiApp = new MinCode($site_id);
|
|
$data = [
|
|
'trade_no' => $trade_no
|
|
];
|
|
$info = $apiApp->requestApi('alipay.trade.query', $data)['alipay_trade_query_response'];
|
|
$buyer_user_id = $info['buyer_user_id'];
|
|
$datas = [
|
|
'user_id' => $buyer_user_id,
|
|
'order_id' => $order_id,
|
|
];
|
|
if ($info['code'] == 10000) {
|
|
$order_mini_query = $apiApp->requestApi('alipay.open.mini.order.query', $datas)['alipay_open_mini_order_query_response'];
|
|
if ($order_mini_query['code'] == 10000) {
|
|
$order_detail = $order_mini_query['order_detail']['item_infos'];
|
|
$pay_info = $order_mini_query['order_detail']['pay_info'];
|
|
foreach ($order_detail as $key => $value) {
|
|
$condition = [
|
|
'm.site_id' => $site_id,
|
|
'm.ali_openid' => $buyer_user_id,
|
|
'og.sku_id' => $value['out_sku_id'],
|
|
'o.order_status' => -1,
|
|
];
|
|
$field = 'm.ali_openid,m.member_id,og.*';
|
|
$alias = 'og';
|
|
$join = [
|
|
[
|
|
'member m', 'm.member_id=og.member_id', 'left'
|
|
],
|
|
[
|
|
'order o', 'og.order_id=o.order_id', 'left'
|
|
]
|
|
];
|
|
$order_info = model('order_goods')->getInfo($condition, $field, $alias, $join);
|
|
if ($order_info) {
|
|
if (in_array($order_mini_query['status'], ['PAID'])) {
|
|
$updata = [
|
|
'order_status' => 1,
|
|
'pay_status' => 1,
|
|
'is_enable_refund' => 1,
|
|
'out_trade_no' => $info['out_trade_no'],
|
|
'is_video_number' => 1,
|
|
'pay_type' => 'alipay',
|
|
'pay_type_name' => '支付宝支付',
|
|
'pay_money' => $info['buyer_pay_amount'],
|
|
'order_status_name' => '待发货',
|
|
'order_status_action' => '{"status":1,"name":"待发货","is_allow_refund":0,"icon":"public\/resource\/order\/order-icon-send.png","action":[{"action":"orderDelivery","title":"发货","color":""},{"action":"orderAddressUpdate","title":"修改地址","color":""}],"member_action":[],"color":""}',
|
|
];
|
|
model('order')->update($updata, ['order_id' => $order_info['order_id']]);
|
|
$data = array(
|
|
'site_id' => $site_id,
|
|
'out_trade_no' => $info['out_trade_no'],
|
|
'pay_type' => 'alipay',
|
|
'trade_no' => $trade_no,
|
|
'pay_body' => $order_info['sku_name'],
|
|
'pay_detail' => $order_info['sku_name'],
|
|
'pay_money' => $info['buyer_pay_amount'],
|
|
'pay_no' => '',
|
|
'event' => 'OrderPayNotify',
|
|
'return_url' => '',
|
|
'pay_status' => 2,
|
|
'create_time' => strtotime($info['send_pay_date']),
|
|
'pay_time' => strtotime($pay_info['pay_time']),
|
|
);
|
|
if (!model('pay')->getValue(['out_trade_no' => $info['out_trade_no']], 'id')) {
|
|
model('pay')->add($data);
|
|
} else {
|
|
unset($data['out_trade_no']);
|
|
model('pay')->update($data, ['out_trade_no' => $info['out_trade_no']]);
|
|
}
|
|
} else {
|
|
var_dump(555);
|
|
}
|
|
} else {
|
|
$res = $this->createOrder($site_id, $order_detail, $pay_info, $info, $order_mini_query);
|
|
return $res;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return $this->success('成功');
|
|
}
|
|
|
|
/****
|
|
* 同步快递信息
|
|
* @param $order_id
|
|
* @param $site_id
|
|
* @param $trade_no
|
|
* @return void
|
|
*/
|
|
public function syncDelivery($order_id,$order_status='')
|
|
{
|
|
$res = $this->delivery($order_id, 1);
|
|
if ($res['code'] == 0 && $order_status==10) {
|
|
$this->takeDelivery($order_id, 1);
|
|
}
|
|
return $res;
|
|
}
|
|
|
|
/***
|
|
* 直接退款
|
|
* @param $trade_no
|
|
* @param $order_id
|
|
* @param $site_id
|
|
* @return void
|
|
*/
|
|
public function refund($trade_no, $order_id, $site_id)
|
|
{
|
|
$apiApp = new MinCode($site_id);
|
|
$data = [
|
|
'trade_no' => $trade_no
|
|
];
|
|
$info = $apiApp->requestApi('alipay.trade.query', $data)['alipay_trade_query_response'];
|
|
$buyer_user_id = $info['buyer_user_id'];
|
|
$datas = [
|
|
'user_id' => $buyer_user_id,
|
|
'order_id' => $order_id,
|
|
];
|
|
if ($info['code'] == 10000) {
|
|
$order_mini_query = $apiApp->requestApi('alipay.open.mini.order.query', $datas)['alipay_open_mini_order_query_response'];
|
|
$pay_model = new PayModel($site_id);
|
|
$order_detail = $order_mini_query['order_detail']['item_infos'][0];
|
|
$pay_info = $order_mini_query['order_detail']['pay_info'];
|
|
$data = [
|
|
'pay_info' => [
|
|
'trade_no' => $info['trade_no'],
|
|
'pay_type' => 'alipay',
|
|
],
|
|
'refund_no' => $info['trade_no'],
|
|
'trade_no' => $info['trade_no'],
|
|
'refund_fee' => $info['buyer_pay_amount'],
|
|
'goods_id' => $order_detail['out_item_id'],
|
|
'sku_id' => $order_detail['out_sku_id'],
|
|
'is_video_number' => 1,
|
|
];
|
|
$rse = $pay_model->refund($data);
|
|
return $rse;
|
|
}
|
|
}
|
|
|
|
/***
|
|
* 直接创建订单
|
|
* @param $site_id
|
|
* @param $order_detail
|
|
* @param $pay_info
|
|
* @param $info
|
|
* @param $order_mini_query
|
|
* @return array
|
|
*/
|
|
public function createOrder($site_id, $order_detail, $pay_info, $info, $order_mini_query)
|
|
{
|
|
$member_info = model('member')->getInfo(['ali_openid' => $info['buyer_user_id']]);
|
|
if (!$member_info) return error(-1, '地址信息不全');
|
|
$member_address = new MemberAddress();
|
|
$type = 1;
|
|
$address = $member_address->getMemberAddressInfo([['member_id', '=', $member_info['member_id']], ['is_default', '=', 1], ['type', '=', $type]]);
|
|
if ($address) {
|
|
$addressInfo = $address['data'];
|
|
$out_trade_no = $info['out_trade_no'];
|
|
$order_item = model('goods_sku')->getInfo(['sku_id' => $order_detail[0]['out_sku_id']]);
|
|
model('order')->startTrans();
|
|
try {
|
|
$data_order = [
|
|
'order_no' => $out_trade_no,
|
|
'site_id' => $site_id,
|
|
'site_name' => '',
|
|
'order_from' => 'alipay',
|
|
'order_from_name' => '支付宝小程序',
|
|
'order_type' => 1,
|
|
'order_status' => 1,
|
|
'pay_status' => 1,
|
|
'is_video_number' => 1,
|
|
'order_type_name' => '普通订单',
|
|
'order_status_name' => '待发货',
|
|
'order_status_action' => '{"status":1,"name":"待发货","is_allow_refund":0,"icon":"public\/resource\/order\/order-icon-send.png","action":[{"action":"orderDelivery","title":"发货","color":""},{"action":"orderAddressUpdate","title":"修改地址","color":""}],"member_action":[],"color":""}',
|
|
'out_trade_no' => $out_trade_no,
|
|
'member_id' => $member_info['member_id'],
|
|
'name' => $addressInfo['name'] ?? '',
|
|
'mobile' => $addressInfo['mobile'] ?? '',
|
|
'telephone' => $addressInfo['telephone'] ?? '',
|
|
'province_id' => $addressInfo['province_id'] ?? '',
|
|
'city_id' => $addressInfo['city_id'] ?? '',
|
|
'district_id' => $addressInfo['district_id'] ?? '',
|
|
'community_id' => $addressInfo['community_id'] ?? '',
|
|
'address' => $addressInfo['address'] ?? '',
|
|
'full_address' => $addressInfo['full_address'] ?? '',
|
|
'longitude' => $addressInfo['longitude'] ?? '',
|
|
'latitude' => $addressInfo['latitude'] ?? '',
|
|
'buyer_ip' => request()->ip(),
|
|
'goods_money' => $info['buyer_pay_amount'],
|
|
'delivery_money' => 0,
|
|
'coupon_id' => 0,
|
|
'coupon_money' => 0,
|
|
'adjust_money' => 0,
|
|
'invoice_money' => 0,
|
|
'promotion_money' => 0,
|
|
'order_money' => $info['buyer_pay_amount'],
|
|
'balance_money' => 0,
|
|
'point_money' => 0,
|
|
'pay_money' => $info['buyer_pay_amount'],
|
|
'create_time' => time(),
|
|
'is_enable_refund' => 0,
|
|
'order_name' => $order_item['sku_name'],
|
|
'goods_num' => $order_detail[0]['item_cnt'],
|
|
'delivery_type' => 'express',
|
|
'delivery_type_name' => '快递配送',
|
|
'delivery_store_id' => $order_item['delivery_store_id'] ?? 0,
|
|
'delivery_store_name' => $order_item['delivery_store_name'] ?? '',
|
|
'delivery_store_info' => $order_item['delivery_store_info'] ?? '',
|
|
'buyer_message' => '',
|
|
'invoice_delivery_money' => $order_item['invoice_delivery_money'] ?? 0,
|
|
'taxpayer_number' => $order_item['taxpayer_number'] ?? '',
|
|
'invoice_rate' => $order_item['invoice_rate'] ?? 0,
|
|
'invoice_content' => $order_item['invoice_content'] ?? '',
|
|
'invoice_full_address' => $order_item['invoice_full_address'] ?? '',
|
|
'is_invoice' => $order_item['is_invoice'] ?? 0,
|
|
'invoice_type' => $order_item['invoice_type'] ?? 0,
|
|
'invoice_title' => $order_item['invoice_title'] ?? '',
|
|
'is_tax_invoice' => $order_item['is_tax_invoice'] ?? '',
|
|
'invoice_email' => $order_item['invoice_email'] ?? '',
|
|
'invoice_title_type' => $order_item['invoice_title_type'] ?? 0,
|
|
'buyer_ask_delivery_time' => $order_item['buyer_ask_delivery_time'] ?? '',//定时达
|
|
'member_card_money' => 0,
|
|
'store_id' => $order_item['store_id'] ?? ''
|
|
];
|
|
$order_id = model('order')->add($data_order);
|
|
$data_order_goods = array(
|
|
'order_id' => $order_id,
|
|
'site_id' => $order_item['site_id'],
|
|
'order_no' => $out_trade_no,
|
|
'member_id' => $member_info['member_id'],
|
|
'sku_id' => $order_item['sku_id'],
|
|
'sku_name' => $order_item['sku_name'],
|
|
'sku_image' => $order_item['sku_image'],
|
|
'sku_no' => $order_item['sku_no'],
|
|
'is_virtual' => $order_item['is_virtual'],
|
|
'goods_class' => $order_item['goods_class'],
|
|
'goods_class_name' => $order_item['goods_class_name'],
|
|
'price' => $order_item['price'],
|
|
'cost_price' => $order_item['cost_price'],
|
|
'num' => $data_order['goods_num'],
|
|
'goods_money' => $data_order['goods_money'],
|
|
'cost_money' => $order_item['cost_price'] * $data_order['goods_num'],
|
|
'goods_id' => $order_item['goods_id'],
|
|
'delivery_status' => 0,
|
|
'delivery_status_name' => '未发货',
|
|
'real_goods_money' => 0,
|
|
'coupon_money' => 0,
|
|
'promotion_money' => 0,
|
|
'goods_name' => $order_item['goods_name'],
|
|
'sku_spec_format' => $order_item['sku_spec_format'],
|
|
'use_point' => $order_item['use_point'] ?? 0,
|
|
'point_money' => $order_item['point_money'] ?? 0.00,
|
|
'create_time' => time(),
|
|
'store_id' => '',
|
|
'card_item_id' => 0,
|
|
'card_promotion_money' => 0.00
|
|
);
|
|
$data = array(
|
|
'site_id' => $site_id,
|
|
'out_trade_no' => $info['out_trade_no'],
|
|
'pay_type' => 'alipay',
|
|
'trade_no' => $info['trade_no'],
|
|
'pay_body' => $data_order_goods['sku_name'],
|
|
'pay_detail' => $data_order_goods['sku_name'],
|
|
'pay_money' => $info['buyer_pay_amount'],
|
|
'pay_no' => '',
|
|
'event' => 'OrderPayNotify',
|
|
'return_url' => '',
|
|
'pay_status' => 2,
|
|
'create_time' => strtotime($info['send_pay_date']),
|
|
'pay_time' => strtotime($pay_info['pay_time']),
|
|
);
|
|
if (!model('pay')->getValue(['out_trade_no' => $info['out_trade_no']], 'id')) {
|
|
model('pay')->add($data);
|
|
} else {
|
|
unset($data['out_trade_no']);
|
|
model('pay')->update($data, ['out_trade_no' => $info['out_trade_no']]);
|
|
}
|
|
model('order_goods')->add($data_order_goods);
|
|
model('order')->commit();
|
|
return $this->success('成功');
|
|
} catch (\Exception $e) {
|
|
model('order')->rollback();
|
|
return error(-1, $e);
|
|
}
|
|
} else {
|
|
return error(-1, '地址信息不全');
|
|
}
|
|
}
|
|
|
|
/***
|
|
* 发货同步到支付宝
|
|
* @param $order_id
|
|
* @param $is_video_number
|
|
* @return array
|
|
* @throws \GuzzleHttp\Exception\GuzzleException
|
|
*/
|
|
public function delivery($order_id,$is_video_number=0)
|
|
{
|
|
try {
|
|
$order = model('order')->getInfo([['order_id', '=', $order_id]], 'site_id,order_no,out_trade_no,is_video_number,pay_type,member_id,order_type,delivery_time');
|
|
if ($is_video_number || ($order['is_video_number'] && in_array($order["pay_type"],['alipay','alipay_stages','zmxxpay','huabie','zmautopay','zmgopay']))) {
|
|
$member = model('member')->getInfo([['member_id', '=', $order['member_id']]], 'ali_openid');
|
|
$apiApp = new MinCode($order['site_id']);
|
|
$data = [
|
|
'out_order_id' => $order['out_trade_no'],
|
|
'finish_all_delivery' => 1,
|
|
'ship_done_time' => date('Y-m-d H:i:s', $order['delivery_time']),
|
|
'delivery_list' => []
|
|
];
|
|
if (is_numeric($member['ali_openid'])) {
|
|
$data['user_id'] = $member['ali_openid'];
|
|
} else {
|
|
$data['open_id'] = $member['ali_openid'];
|
|
}
|
|
if ($order['order_type'] == 1) {
|
|
$package_list = model('express_delivery_package')->getList([['order_id', '=', $order_id]], 'delivery_type,express_company_name,delivery_no,order_goods_id_array');
|
|
if (!empty($package_list)) {
|
|
$company_list = $apiApp->getCompanyList();
|
|
foreach ($package_list as $item) {
|
|
$delivery_id = 'OTHERS';
|
|
$index = array_search($item['express_company_name'], array_column($company_list, 'delivery_name'));
|
|
if ($index !== false && isset($company_list[$index])) {
|
|
$delivery_id = $company_list[$index]['delivery_id'];
|
|
}
|
|
$order_goods_model = model('order_goods')->getList([['order_goods_id', "in", $item['order_goods_id_array']]], "goods_id,sku_id,num");
|
|
if ($item['delivery_type'] == 0) {
|
|
$item['delivery_no'] = date('YmdHis');
|
|
}
|
|
$temp = [
|
|
'delivery_id' => $delivery_id,
|
|
'waybill_id' => $item['delivery_no'],
|
|
'item_info_list' => []
|
|
];
|
|
foreach ($order_goods_model as $order_iem) {
|
|
$temp['item_info_list'][] = [
|
|
'out_item_id' => $order_iem['goods_id'], //提报服务库外部商品ID
|
|
'out_sku_id' => $order_iem['sku_id'],//商家SKU
|
|
'item_cnt' => (int)$order_iem['num'] //商品数量
|
|
];
|
|
}
|
|
array_push($data['delivery_list'], $temp);
|
|
}
|
|
} else {
|
|
unset($data['delivery_list']);
|
|
}
|
|
}
|
|
$res = $apiApp->sendDelivery($data);
|
|
if ($res['code'] == 10000) {
|
|
return $this->success();
|
|
} else if (isset($res['sub_code']) && !in_array($res['sub_code'], ['STATUS_INVALID', 'SEND_ORDER_IS_REPEAT', 'ORDER_ID_NOT_EXIST', 'OUT_ORDER_ID_INVALIDATE'])) {
|
|
model('order')->update(['is_sync_order' => 2, 'sync_msg' => $res['sub_msg']], [['order_id', '=', $order_id]]);
|
|
return $this->error('', $res['sub_msg']);
|
|
} else { //标记订单已同步
|
|
model('order')->update(['is_sync_order' => 2, 'sync_msg' => $res['sub_msg']], [['order_id', '=', $order_id]]);
|
|
return $this->success();
|
|
}
|
|
return $res;
|
|
}
|
|
} catch (\Exception $e) {
|
|
|
|
}
|
|
return $this->success();
|
|
}
|
|
|
|
/**
|
|
* 订单收货
|
|
* @param $order_id
|
|
* @return array
|
|
*/
|
|
public function takeDelivery($order_id,$is_video_number=0)
|
|
{
|
|
$order = model('order')->getInfo([['order_id', '=', $order_id]], 'site_id,order_no,out_trade_no,is_video_number,pay_type,member_id,order_type');
|
|
if ($is_video_number || ($order['is_video_number'] && in_array($order["pay_type"],['alipay','alipay_stages','zmxxpay','huabie','zmautopay','zmgopay']))) {
|
|
$member = model('member')->getInfo([['member_id', '=', $order['member_id']]], 'ali_openid');
|
|
$apiApp = new MinCode($order['site_id']);
|
|
$res = $apiApp->recieveDelivery(['out_order_id' => $order['out_trade_no'], 'user_id' => $member['ali_openid']]);
|
|
if ($res['code'] != 10000) {
|
|
return $this->error('', $res['sub_msg']);
|
|
}
|
|
}
|
|
return $this->success();
|
|
}
|
|
/***
|
|
* 订单状态标记
|
|
* @param $json
|
|
* @return void
|
|
*/
|
|
public function OrderStatus($json)
|
|
{
|
|
switch ($json['status']) {
|
|
case 'RECEIVED_CONFIRM': //确认收货
|
|
$where = [['out_trade_no', '=', $json['out_order_id']]];
|
|
$field = 'o.order_id,m.nickname,m.member_id';
|
|
$join = [
|
|
['member m', 'o.member_id=m.member_id', 'inner'],
|
|
];
|
|
$orderInfo = model('order')->getInfo($where, $field, 'o', $join);
|
|
if ($orderInfo) {
|
|
$log_data = [
|
|
'uid' => $orderInfo['member_id'],
|
|
'nick_name' => $orderInfo['nickname'],
|
|
'action_way' => 2
|
|
];
|
|
$order_model = new OrderCommonModel();
|
|
$order_model->orderCommonTakeDelivery($orderInfo['order_id'], $log_data);
|
|
}
|
|
break;
|
|
case 'REFUND_CLOSED': //退款
|
|
$where = [['out_trade_no', '=', $json['out_order_id']]];
|
|
$field = 'g.order_goods_id,m.nickname,m.member_id,o.order_id';
|
|
$join = [
|
|
['order_goods g', 'o.order_id=g.order_id', 'inner'],
|
|
['member m', 'o.member_id=m.member_id', 'inner'],
|
|
];
|
|
$orderInfo = model('order')->getList($where, $field, '', 'o', $join);
|
|
$order_refund_model = new OrderRefundModel();
|
|
if ($orderInfo) {
|
|
foreach ($orderInfo as $item) {
|
|
$buyer_name = empty($item['nickname']) ? '' : '【' . $item['nickname'] . '】';
|
|
$log_data = [
|
|
'uid' => $item['member_id'],
|
|
'nick_name' => $item['nickname'],
|
|
'action' => '买家' . $buyer_name . '发起了退款申请',
|
|
'action_way' => 1
|
|
];
|
|
$data = array(
|
|
"order_goods_id" => $item['order_goods_id'],
|
|
"refund_type" => 1,
|
|
"refund_reason" => '会员平台申请退款',
|
|
"refund_remark" => '支付宝平台直接申请退款'
|
|
);
|
|
$order_refund_model->orderRefundApply($data, $item, $log_data);
|
|
}
|
|
model('dividemoney_bill')->update(['states' => 5, 'refuse' => '订单已退款'], [['order_id', 'in', array_column($orderInfo, 'order_id')]]);//关闭分账
|
|
}
|
|
break;
|
|
case 'PAID':
|
|
model('order')->update(['is_video_number' => 1], [['out_trade_no', '=', $json['out_order_id']]]);
|
|
break;
|
|
case 'CANCEL_CLOSED'://交易取消
|
|
case 'TIMEOUT_CLOSED': //超时关闭订单
|
|
$order = new OrderCommon();
|
|
$where = [['out_trade_no', '=', $json['out_order_id']]];
|
|
$order_info_result = $order->getOrderInfo($where, "order_id,order_status");
|
|
if (!empty($order_info_result) && $order_info_result["data"]["order_status"] == 0) {
|
|
$order->orderClose($order_info_result['data']["order_id"], [], '长时间未支付,订单自动关闭');//订单自动关闭
|
|
}
|
|
break;
|
|
}
|
|
return success();
|
|
}
|
|
} |