mirror of
https://gitee.com/liuxioabin/fengketrade.git
synced 2026-04-17 21:03:17 +08:00
同步订单状态
This commit is contained in:
parent
ca82c79c78
commit
a4b8b710d5
@ -112,10 +112,23 @@ class CcbOrderService
|
|||||||
// 获取订单商品列表
|
// 获取订单商品列表
|
||||||
$orderItems = Db::name('shopro_order_item')
|
$orderItems = Db::name('shopro_order_item')
|
||||||
->where('order_id', $orderId)
|
->where('order_id', $orderId)
|
||||||
->select();
|
->select()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
// 获取支付流水号(PAY_FLOW_ID必填字段)
|
||||||
|
$payInfo = Db::name('shopro_pay')
|
||||||
|
->where('order_id', $orderId)
|
||||||
|
->where('status', 'paid')
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if (!$payInfo || empty($payInfo['pay_sn'])) {
|
||||||
|
throw new \Exception('订单未支付或支付流水号不存在');
|
||||||
|
}
|
||||||
|
|
||||||
|
$payFlowId = $payInfo['pay_sn'];
|
||||||
|
|
||||||
// 构建订单数据(符合A3341TP01接口规范)
|
// 构建订单数据(符合A3341TP01接口规范)
|
||||||
$orderData = $this->buildOrderData($order, $orderItems, $ccbUserId);
|
$orderData = $this->buildOrderData($order, $orderItems, $ccbUserId, $payFlowId);
|
||||||
|
|
||||||
// 记录请求数据(同步日志)
|
// 记录请求数据(同步日志)
|
||||||
$txSeq = CcbMD5::generateTransactionSeq();
|
$txSeq = CcbMD5::generateTransactionSeq();
|
||||||
@ -270,13 +283,13 @@ class CcbOrderService
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// 获取订单信息
|
// 获取订单信息
|
||||||
$order = Order::find($orderId);
|
$order = Db::name('shopro_order')->where('id', $orderId)->find();
|
||||||
if (!$order) {
|
if (!$order) {
|
||||||
throw new \Exception('订单不存在');
|
throw new \Exception('订单不存在');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证退款金额
|
// 验证退款金额
|
||||||
if ($refundAmount > $order['total_amount']) {
|
if ($refundAmount > $order['order_amount']) {
|
||||||
throw new \Exception('退款金额不能超过订单总额');
|
throw new \Exception('退款金额不能超过订单总额');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,148 +320,112 @@ class CcbOrderService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建符合建行要求的订单数据
|
* 构建符合建行 A3341TP01 接口规范的订单数据
|
||||||
*
|
*
|
||||||
* ⚠️ 注意:Shopro字段说明
|
* 📋 建行生活订单推送接口规范说明:
|
||||||
* - pay_fee: 实际支付金额(Shopro字段)
|
*
|
||||||
* - order_amount: 订单总金额(Shopro字段)
|
* 必填字段(11个):
|
||||||
* - total_discount_fee: 优惠总金额(Shopro字段)
|
* - USER_ID: 客户编号(建行用户ID)
|
||||||
* - paid_time: 支付时间(毫秒时间戳!需除以1000)
|
* - ORDER_ID: 订单号
|
||||||
* - createtime: 创建时间(毫秒时间戳!需除以1000)
|
* - ORDER_DT: 订单日期(yyyyMMddHHmmss格式)
|
||||||
|
* - TOTAL_AMT: 订单原金额
|
||||||
|
* - ORDER_STATUS: 订单状态
|
||||||
|
* - MCT_NM: 商户名称
|
||||||
|
* - CUS_ORDER_URL: 订单详情链接
|
||||||
|
* - PAY_FLOW_ID: 支付流水号(从 shopro_pay.pay_sn 获取)
|
||||||
|
* - PRPFTL_MRCH_ID: 门店商户号(使用 merchant_id)
|
||||||
|
* - PAY_MRCH_ID: 支付商户号(使用 merchant_id)
|
||||||
|
* - SKU_LIST: 商品信息JSON字符串
|
||||||
|
*
|
||||||
|
* 非必填但推荐字段:
|
||||||
|
* - PAY_AMT: 订单实际支付金额
|
||||||
|
* - DISCOUNT_AMT: 第三方平台优惠金额
|
||||||
|
* - DISCOUNT_AMT_DESC: 第三方平台优惠说明
|
||||||
|
* - REFUND_STATUS: 退款状态
|
||||||
|
* - PAY_MODE: 支付方式
|
||||||
|
* - PLAT_ORDER_TYPE: 服务方订单类型
|
||||||
|
* - COUPON_AMT: 优惠券金额
|
||||||
|
*
|
||||||
|
* ⚠️ 注意:Shopro字段映射
|
||||||
|
* - pay_fee → PAY_AMT(实际支付金额)
|
||||||
|
* - order_amount → TOTAL_AMT(订单总金额)
|
||||||
|
* - total_discount_fee → DISCOUNT_AMT(优惠总金额)
|
||||||
|
* - createtime → ORDER_DT(毫秒时间戳需除以1000)
|
||||||
*
|
*
|
||||||
* @param array $order 订单数组
|
* @param array $order 订单数组
|
||||||
* @param array $orderItems 订单商品列表
|
* @param array $orderItems 订单商品列表
|
||||||
* @param string $ccbUserId 建行用户ID
|
* @param string $ccbUserId 建行用户ID
|
||||||
|
* @param string $payFlowId 支付流水号(从shopro_pay表获取)
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function buildOrderData($order, $orderItems, $ccbUserId)
|
private function buildOrderData($order, $orderItems, $ccbUserId, $payFlowId)
|
||||||
{
|
{
|
||||||
// 构建商品列表
|
// 构建SKU商品列表(JSON字符串格式)
|
||||||
$goodsList = $this->buildGoodsList($orderItems);
|
$skuList = $this->buildSkuList($orderItems);
|
||||||
|
// 计算各项金额(保留2位小数)
|
||||||
// 计算各项金额(Shopro字段:pay_fee=实付金额,order_amount=订单总金额)
|
|
||||||
$totalAmount = number_format($order['order_amount'] ?? 0, 2, '.', '');
|
$totalAmount = number_format($order['order_amount'] ?? 0, 2, '.', '');
|
||||||
$payAmount = number_format($order['pay_fee'] ?? 0, 2, '.', '');
|
// 处理订单时间(Shopro的createtime是毫秒时间戳,需要除以1000)
|
||||||
$discountAmount = number_format($order['total_discount_fee'] ?? 0, 2, '.', '');
|
|
||||||
|
|
||||||
// 处理支付时间(Shopro的paid_time是毫秒时间戳,需要除以1000)
|
|
||||||
$payTime = '';
|
|
||||||
if (!empty($order['paid_time']) && is_numeric($order['paid_time'])) {
|
|
||||||
$payTime = date('YmdHis', intval($order['paid_time'] / 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理创建时间(Shopro的createtime是毫秒时间戳,需要除以1000)
|
|
||||||
$createTimeValue = $order['createtime'] ?? null;
|
$createTimeValue = $order['createtime'] ?? null;
|
||||||
if (empty($createTimeValue) || !is_numeric($createTimeValue)) {
|
if (empty($createTimeValue) || !is_numeric($createTimeValue)) {
|
||||||
$createTimeValue = time() * 1000; // 当前时间的毫秒时间戳
|
$createTimeValue = time() * 1000;
|
||||||
}
|
}
|
||||||
$createTime = date('YmdHis', intval($createTimeValue / 1000));
|
$orderDt = date('YmdHis', intval($createTimeValue / 1000));
|
||||||
|
|
||||||
// 获取订单地址信息(Shopro将地址存储在单独的表中)
|
// 构建符合A3341TP01接口规范的订单数据
|
||||||
$orderAddress = Db::name('shopro_order_address')
|
|
||||||
->where('order_id', $order['id'])
|
|
||||||
->find();
|
|
||||||
|
|
||||||
// 获取支付方式(Shopro将支付信息存储在单独的表中)
|
|
||||||
$payInfo = Db::name('shopro_pay')
|
|
||||||
->where('order_id', $order['id'])
|
|
||||||
->where('status', 'paid')
|
|
||||||
->find();
|
|
||||||
|
|
||||||
// 获取快递信息(Shopro将快递信息存储在单独的表中)
|
|
||||||
$expressInfo = Db::name('shopro_order_express')
|
|
||||||
->where('order_id', $order['id'])
|
|
||||||
->find();
|
|
||||||
|
|
||||||
// 构建订单数据(34个必填字段)
|
|
||||||
return [
|
return [
|
||||||
'USER_ID' => $ccbUserId, // 建行用户ID
|
// ========== 必填字段 ==========
|
||||||
|
'USER_ID' => $ccbUserId, // 客户编号
|
||||||
'ORDER_ID' => $order['order_sn'], // 订单号
|
'ORDER_ID' => $order['order_sn'], // 订单号
|
||||||
'ORDER_DT' => $createTime, // 订单时间
|
'ORDER_DT' => $orderDt, // 订单日期(yyyyMMddHHmmss)
|
||||||
'TOTAL_AMT' => $totalAmount, // 订单原金额
|
'TOTAL_AMT' => $totalAmount, // 订单原金额
|
||||||
'PAY_AMT' => $payAmount, // 实付金额
|
|
||||||
'DISCOUNT_AMT' => $discountAmount, // 优惠金额
|
|
||||||
'ORDER_STATUS' => $this->mapOrderStatus($order['status']), // 订单状态
|
'ORDER_STATUS' => $this->mapOrderStatus($order['status']), // 订单状态
|
||||||
'REFUND_STATUS' => '0', // 退款状态(默认无退款)
|
'REFUND_STATUS' => $this->mapRefundStatus($order['refund_status'] ?? 0), // 退款状态
|
||||||
'MCT_NM' => $this->config['merchant']['name'] ?? '商户名称', // 商户名称
|
'MCT_NM' => $this->config['merchant']['name'] ?? '商户名称', // 商户名称
|
||||||
'MCT_ORDER_ID' => $order['id'], // 商户订单ID
|
'CUS_ORDER_URL' => $this->config['merchant']['order_detail_url'] . $order['id'], // 订单详情链接
|
||||||
'GOODS_LIST' => json_encode($goodsList, JSON_UNESCAPED_UNICODE), // 商品列表
|
'PAY_FLOW_ID' => $payFlowId, // 支付流水号(必填!)
|
||||||
'PAY_TYPE' => $this->mapPayType($payInfo['pay_type'] ?? ''), // 支付方式(从支付表获取)
|
'PAY_MRCH_ID' => $this->config['merchant_id'], // 支付商户号(必填!)
|
||||||
'PAY_TIME' => $payTime, // 支付时间(毫秒转秒)
|
'SKU_LIST' => $skuList, // 商品信息JSON字符串(必填!)
|
||||||
'DELIVERY_TYPE' => '01', // 配送方式(01快递)
|
// ========== 非必填字段 ==========
|
||||||
'DELIVERY_STATUS' => $this->mapDeliveryStatus($order['status']), // 配送状态
|
'PLAT_ORDER_TYPE' => "T0000", // 服务方订单类型
|
||||||
'DELIVERY_TIME' => !empty($expressInfo['createtime']) ? date('YmdHis', intval($expressInfo['createtime'] / 1000)) : '', // 发货时间
|
|
||||||
'RECEIVE_NAME' => $orderAddress['consignee'] ?? '', // 收货人姓名(从地址表获取)
|
|
||||||
'RECEIVE_PHONE' => $orderAddress['mobile'] ?? '', // 收货人电话(从地址表获取)
|
|
||||||
'RECEIVE_ADDRESS' => $this->buildAddress($order), // 收货地址(从地址表获取)
|
|
||||||
'EXPRESS_COMPANY' => $expressInfo['express_name'] ?? '', // 快递公司(从快递表获取)
|
|
||||||
'EXPRESS_NO' => $expressInfo['express_no'] ?? '', // 快递单号(从快递表获取)
|
|
||||||
'REMARK' => $order['remark'] ?? '', // 备注
|
|
||||||
'ORDER_TYPE' => '01', // 订单类型(01普通订单)
|
|
||||||
'IS_VIRTUAL' => '0', // 是否虚拟商品
|
|
||||||
'ORDER_URL' => $this->config['merchant']['order_detail_url'] . $order['id'], // 订单详情链接
|
|
||||||
'CREATE_TIME' => $createTime, // 创建时间
|
|
||||||
'UPDATE_TIME' => date('YmdHis'), // 更新时间
|
|
||||||
'SHOP_ID' => '1', // 店铺ID
|
|
||||||
'SHOP_NAME' => $this->config['merchant']['name'] ?? '', // 店铺名称
|
|
||||||
'ACTIVITY_ID' => '', // 活动ID
|
|
||||||
'ACTIVITY_NAME' => '', // 活动名称
|
|
||||||
'COUPON_AMT' => number_format($order['coupon_discount_fee'] ?? 0, 2, '.', ''), // 优惠券金额
|
|
||||||
'FREIGHT_AMT' => number_format($order['dispatch_amount'] ?? 0, 2, '.', ''), // 运费(Shopro字段名为dispatch_amount)
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建商品列表
|
* 构建符合建行规范的SKU商品列表(JSON字符串格式)
|
||||||
*
|
*
|
||||||
* @param array $items 订单商品项
|
* 📋 建行 SKU_LIST 字段规范:
|
||||||
* @return array
|
*
|
||||||
|
* 必填字段(4个):
|
||||||
|
* - SKU_NAME: 商品名称(必填)
|
||||||
|
* - SKU_REF_PRICE: 商品参考价(必填,支持小数最多2位)
|
||||||
|
* - SKU_NUM: 商品数量(必填,支持小数最多1位)
|
||||||
|
* - SKU_SELL_PRICE: 商品售价(必填,支持小数最多2位)
|
||||||
|
*
|
||||||
|
* ⚠️ 注意:Shopro字段映射
|
||||||
|
* - goods_title → SKU_NAME(商品名称)
|
||||||
|
* - goods_original_price → SKU_REF_PRICE(商品原价作为参考价)
|
||||||
|
* - goods_num → SKU_NUM(购买数量)
|
||||||
|
* - goods_price → SKU_SELL_PRICE(商品实际售价)
|
||||||
|
*
|
||||||
|
* @param array $items 订单商品项数组
|
||||||
|
* @return string JSON字符串格式的SKU列表
|
||||||
*/
|
*/
|
||||||
private function buildGoodsList($items)
|
private function buildSkuList($items)
|
||||||
{
|
{
|
||||||
$goodsList = [];
|
$skuList = [];
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$goodsList[] = [
|
$skuList[] = [
|
||||||
'goods_id' => $item['goods_id'],
|
'SKU_NAME' => $item['goods_title'], // 商品名称(必填)
|
||||||
'goods_name' => $item['goods_title'],
|
'SKU_REF_PRICE' => number_format($item['goods_original_price'] ?? $item['goods_price'], 2, '.', ''), // 商品参考价(必填)
|
||||||
'goods_price' => number_format($item['goods_price'], 2, '.', ''),
|
'SKU_NUM' => $item['goods_num'], // 商品数量(必填)
|
||||||
'goods_num' => $item['goods_num'],
|
'SKU_SELL_PRICE' => number_format($item['goods_price'], 2, '.', ''), // 商品售价(必填)
|
||||||
'goods_amount' => number_format($item['goods_amount'], 2, '.', ''),
|
|
||||||
'goods_image' => $item['goods_image'] ?? '',
|
|
||||||
'goods_sku' => $item['goods_sku_text'] ?? ''
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return $goodsList;
|
|
||||||
|
// 返回JSON字符串(不转义Unicode,保持中文可读)
|
||||||
|
return json_encode($skuList, JSON_UNESCAPED_UNICODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建收货地址
|
|
||||||
*
|
|
||||||
* ⚠️ 注意:Shopro的收货地址存储在单独的表 shopro_order_address 中
|
|
||||||
*
|
|
||||||
* @param array $order 订单数组
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function buildAddress($order)
|
|
||||||
{
|
|
||||||
// 从订单地址表获取地址信息
|
|
||||||
$orderAddress = Db::name('shopro_order_address')
|
|
||||||
->where('order_id', $order['id'])
|
|
||||||
->find();
|
|
||||||
|
|
||||||
if (!$orderAddress) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$address = '';
|
|
||||||
if (!empty($orderAddress['province_name'])) $address .= $orderAddress['province_name'];
|
|
||||||
if (!empty($orderAddress['city_name'])) $address .= $orderAddress['city_name'];
|
|
||||||
if (!empty($orderAddress['district_name'])) $address .= $orderAddress['district_name'];
|
|
||||||
if (!empty($orderAddress['address'])) $address .= $orderAddress['address'];
|
|
||||||
|
|
||||||
return $address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录同步日志
|
* 记录同步日志
|
||||||
*
|
*
|
||||||
@ -543,38 +520,6 @@ class CcbOrderService
|
|||||||
return '0';
|
return '0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 映射支付方式
|
|
||||||
*
|
|
||||||
* @param string $payType 支付类型
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function mapPayType($payType)
|
|
||||||
{
|
|
||||||
$payMap = [
|
|
||||||
'wechat' => '01', // 微信支付
|
|
||||||
'alipay' => '02', // 支付宝
|
|
||||||
'ccb' => '03', // 建行支付
|
|
||||||
'balance' => '04' // 余额支付
|
|
||||||
];
|
|
||||||
|
|
||||||
return $payMap[$payType] ?? '00';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 映射配送状态
|
|
||||||
*
|
|
||||||
* @param string $status 订单状态
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function mapDeliveryStatus($status)
|
|
||||||
{
|
|
||||||
if (in_array($status, ['unpaid', 'paid'])) return '0'; // 未发货
|
|
||||||
if ($status == 'shipped') return '1'; // 已发货
|
|
||||||
if (in_array($status, ['received', 'completed'])) return '2'; // 已收货
|
|
||||||
return '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量同步订单
|
* 批量同步订单
|
||||||
* 用于初始化或定时同步
|
* 用于初始化或定时同步
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user