services->setting->addons->get($mallId, HappinessEnum::ADDONS_NAME, 'basic.pv_scale'); $settle_mode = \Yii::$app->services->setting->addons->get($order['mall_id'], HappinessEnum::ADDONS_NAME, 'basic.settlement_method'); $scoreTotal = bcmul($order['pay_money'],bcdiv($scale,100,4),3); if ($scoreTotal<=0) { throw new \Exception('赠送积分为0'); } //创建订单,若不存在 $recordRes = self::recordOrder($order); if ($recordRes === false) { throw new \Exception(self::getStaticError()); } //非结算订单不执行下面的逻辑 if ($is_settle != $settle_mode) { return true; } $t = Yii::$app->db->beginTransaction(); try { $service=new self; $syncResult= $service->syncUserPv($userId); if ($syncResult === false) { throw new \Exception($service->error); } $orderData = [ 'order_id' => $order['id'], 'order_no' => $order['order_no'], 'mall_id' => $order['mall_id'], 'user_id' => $order['user_id'], 'score' => $scoreTotal, 'is_settled' => StatusEnum::ENABLED, 'status' => StatusEnum::ENABLED, 'goods_price' => $order['pay_money'], 'settled_time' => time() ]; // 写入订单明细 $resOrder = HappinessPvOrder::setData($orderData); if (!$resOrder) { throw new \Exception('创建订单失败' . HappinessPvOrder::getStaticError()); } //同步幸福宝 $thirdUser=HappinessThirdUser::find()->where(['user_id'=>$order['user_id'],'type'=>2])->asArray() ->one(); $res=$this->updatePv($thirdUser['uid'],$scoreTotal,'幸福小店订单消费赠送'.$order['order_no'],$order['order_no']); if($res===false) { throw new \Exception('更新PV失败'); } //同步信息 $commissionService=new CommissionService; $res=$commissionService->statsItem( [ 'mall_id' => $order['mall_id'], 'order_id' => $order['id'], 'store_id' => $store_order['store_id'], 'order_no' => $order['order_no'], 'order_money' => $order['pay_money'], 'money'=>$scoreTotal, 'user_id' => $order['user_id'], ],'pv_money'); if (!$res) throw new Exception($commissionService->getError()); $t->commit(); return true; } catch (\Exception $e) { $t->rollBack(); throw $e; } } catch (\Exception $e) { $this->error = $e->getMessage(); \Yii::error('Happiness OrderPay : ' . $this->error . ' : ' . $e->getLine()); return false; } } //创建订单 public static function recordOrder($order) { try { $powerOrder = HappinessPvOrder::findOne(['mall_id' => $order['mall_id'], 'order_id' => $order['id']]); if ($powerOrder) { return true; } $mallId = $order['mall_id']; $scale = \Yii::$app->services->setting->addons->get($mallId, HappinessEnum::ADDONS_NAME, 'basic.pv_scale'); $scoreTotal = bcmul($order['pay_money'],bcdiv($scale,100,4),3); if($scoreTotal<=0) { throw new \Exception('赠送金额为0'); } $service=new self; $syncResult= $service->syncUserPv($order['user_id']); if ($syncResult === false) { throw new \Exception($service->error); } //添加订单记录 $orderData = [ 'order_id' => $order['id'], 'order_no' => $order['order_no'], 'mall_id' => $order['mall_id'], 'user_id' => $order['user_id'], 'score' => $scoreTotal, 'is_settled' => StatusEnum::DISABLED, 'status' => StatusEnum::ENABLED, 'goods_price' => $order['pay_money'], ]; $resOrder = HappinessPvOrder::setData($orderData); if (!$resOrder) { throw new \Exception('创建订单失败' . HappinessPvOrder::getStaticError()); } } catch (\Exception $e) { self::$static_error = $e->getMessage(); \Yii::error('Happiness OrderPay : ' . self::$static_error . ' : ' . $e->getLine()); return false; } return true; } //退还积分(取消订单) public static function orderCancel($detail_ids,$order_id) { $where = [ 'source_table' => 'order', 'source_table_id' => $detail_ids, 'from_type' => HappinessPvEnum::FROM_ORDER_BUY ]; $log = HappinessPvWalletLog::find()->where($where)->asArray()->all(); if (!empty($log)) { $wallet_log = []; foreach ($log as $item) { $wallet_log[] = [ 'mall_id' => $item['mall_id'], 'user_id' => $item['user_id'], 'change_num' => $item['change_num'], 'desc' => '订单关闭退回,订单号:' . $item['order_no'], 'source_table' => 'order', 'source_table_id' => $item['source_table_id'], 'order_no' => $item['order_no'], 'from_type' => HappinessPvEnum::FROM_ORDER_CANCEL, 'wallet_type' => HappinessPvEnum::SCORE_VALUE, 'status' => 1, ]; } $tran = Yii::$app->db->beginTransaction(); try { $service=new self; $uid= $service->syncUserPv($log[0]['user_id']); if ($uid === false) { throw new \Exception($service->error); } $res = WalletLogic::batchHandle($wallet_log); if ($res === false) { throw new \Exception(WalletLogic::getStaticError()); } //同步pv if(!empty($wallet_log)) { foreach ($wallet_log as $item) { $syncResult= $service->updatePoints($uid,$item['change_num'],$item['order_no']); if ($syncResult === false) { throw new \Exception($service->error); } } } $pvOrder=HappinessPvOrder::find()->where(['order_id'=>$order_id])->one(); if($pvOrder) { $pvOrder->status=StatusEnum::DISABLED; if(!$pvOrder->save()) { throw new \Exception($pvOrder->getErrorMessage()); } } $tran->commit(); return true; } catch (\Exception $e) { $tran->rollBack(); self::$static_error = $e->getMessage(); Yii::error($e->getMessage() . __LINE__, __METHOD__); return false; } } return true; } //退还积分(售后) public static function orderRefund($order_detail_id, $params) { $trans = Yii::$app->db->beginTransaction(); try { $deduct = OrderMarketing::find()->select('deduct_currency')->where(['order_detail_id' => $order_detail_id, 'status' => StatusEnum::ENABLED])->scalar(); if (empty($deduct)) { throw new Exception('订单不存在PV_SCORE营销'); } $order_detail = OrderDetail::find()->where(['id' => $order_detail_id])->asArray()->one(); $order = Order::find()->where(['id' => $order_detail['order_id']])->asArray()->one(); $deduct_arr = Json::decode($deduct, true); $wallet_log = []; foreach ($deduct_arr as $key => $item) { if ($key == 'pv_score' && $item['money'] > 0) { $wallet_log[] = [ 'mall_id' => $params['mall_id'], 'user_id' => $params['user_id'], 'change_num' => $item['money'], 'desc' => '订单售后退回,订单号' . $order['order_no'], 'source_table' => 'order', 'order_no' => $order['order_no'], 'from_type' => HappinessPvEnum::FROM_ORDER_REFUND, 'wallet_type' => HappinessPvEnum::SCORE_VALUE, 'status' => 1, ]; } } if (!empty($wallet_log)) { //同步pv $service=new self; $uid= $service->syncUserPv($params['user_id']); if ($uid === false) { throw new \Exception($service->error); } $res = WalletLogic::batchHandle($wallet_log); if ($res === false) { throw new Exception(WalletLogic::getStaticError()); } foreach ($wallet_log as $item) { $syncResult= $service->updatePoints($uid,$item['change_num'],$item['order_no']); if ($syncResult === false) { throw new \Exception($service->error); } } } $trans->commit(); return true; } catch (\Exception $e) { $trans->rollBack(); self::setStaticError($e->getMessage()); Yii::error($e->getMessage() . __LINE__, __METHOD__); return false; } } //同步幸福保积分 private const API_KEY = "HXJT_XFXD_B31_M_3279_Y_250707_01"; private const API_SECRET = '8f^ynijrE9Mc9Q5ez5e8$Tm&$6Xx!ycQ'; private const GATEWAY_URL = "https://testapi.hxxfb.com/gateway"; //获取用户积分 public function getUserInfo($uid) { // 请求 URL $url = self::GATEWAY_URL . "/external/userCenter_service/user/getUserList?uid=".$uid; return $this->getUrl($url); } public function getUserInfoByMobile($mobile) { // 请求 URL $url = self::GATEWAY_URL . "/external/userCenter_service/user/getUserList?account=".$mobile; return $this->getUrl($url); } private function generateSignature($apiKey, $timestamp) { $data = $apiKey . "|" . $timestamp . "|" . self::API_SECRET; return md5($data); // 返回 MD5 签名 } public function createUser($mobile,$user_name,$mall_id,$avatar_url,$user_id) { // 请求 URL $url = self::GATEWAY_URL . "/external/userCenter_service/user/createUserInfo"; $data = [ "account" => $mobile, //账号 "realName" => $user_name, //真实姓名 "nickname" => $user_name, //用户昵称 "sex" => 1, //性别 "spreadUid" => 1001, //推广员id "avatar" => $avatar_url, //用户头像 "phone" =>$mobile, //手机号码 "status" => 1, //1为正常,0为禁止 "external" => 4, //用户来源1:储蓄保,2:长寿美,3:聚宝盆1.0,4:幸福小店 "externalId" => $user_id, //外部用户id "levelId" => 2, "lastIp" => \Yii::$app->request->getRemoteIP() //获取IP ]; $res= $this->postUrl($url,$data); if($res === false && $this->error == '用户已存在') { //查询用户 $resGetUserInfo=$this->getUserInfoByMobile($mobile); if($resGetUserInfo === false) { return false; } if(empty($resGetUserInfo['list'])) { $this->error='用户不存在'; return false; } $res=$resGetUserInfo['list'][0]; } if(isset($res) && $res['uid']) { //保存第三方信息 $saveData=[ 'uid'=>$res['uid'], 'mall_id'=>$mall_id, 'type'=>2, 'user_id'=>$user_id ]; $resSave=HappinessThirdUser::setData($saveData); if($resSave===false) { $this->error=HappinessThirdUser::getStaticError(); return false; } return $res; } return false; } public function syncUserPv($user_id) { //先检测是否存在用户,没存在先创建 $third_user=HappinessThirdUser::find()->where(['type'=>2,'user_id'=>$user_id])->one(); if(!$third_user) { //创建用户 $user=User::find()->where(['id'=>$user_id])->asArray()->one(); $resCreate=$this->createUser($user['mobile'],$user['nickname'],$user['mall_id'],$user['avatar_url'], $user_id); if($resCreate===false) { return false; } $uid=$resCreate['uid']; } else { $uid=$third_user['uid']; } //同步用户积分 $resGetUserInfo=$this->getUserInfo($uid); if($resGetUserInfo===false) { return false; } if(empty($resGetUserInfo['list'])) { $this->error='用户不存在'; return false; } $pv=$resGetUserInfo['list'][0]['score']; //当前pv值 $userWallet=HappinessPvWallet::find()->where(['user_id'=>$user_id])->asArray()->one(); $wallet_log=[]; if($userWallet['score_value']>$pv) { //需要减少 $reduce_num=$userWallet['score_value']-$pv; $wallet_log[] = [ 'mall_id' => $third_user['mall_id'], 'user_id' => $third_user['user_id'], 'change_num' =>-$reduce_num, 'desc' => '系统同步', 'source_table' => HappinessPvWallet::tableName(), 'source_table_id' => $third_user['user_id'], 'order_no' => '', 'from_type' => HappinessPvEnum::FROM_SYNC, 'wallet_type' => HappinessPvEnum::SCORE_VALUE, 'status' => 1, ]; } elseif($userWallet['score_value']<$pv) { //需要增加 $add_num=$pv-$userWallet['score_value']; $wallet_log[] = [ 'mall_id' => $third_user['mall_id'], 'user_id' => $third_user['user_id'], 'change_num' => $add_num, 'desc' => '系统同步', 'source_table' => HappinessPvWallet::tableName(), 'source_table_id' => $third_user['user_id'], 'order_no' => '', 'from_type' => HappinessPvEnum::FROM_SYNC, 'wallet_type' => HappinessPvEnum::SCORE_VALUE, 'status' => 1, ]; } if(!empty($wallet_log)) { $res = WalletLogic::batchHandle($wallet_log); if ($res === false) { $this->error=WalletLogic::getStaticError(); return false; } } return $uid; } //更新用户积分 public function updatePv($uid, $pv,$remark='',$order_id='') { // 请求 URL $url = self::GATEWAY_URL . "/external/userCenter_service/user/modifyPV"; $data = [ "uid" => $uid, //会员id "pv" => $pv, //pv值 "status" => 1, //pv值状态:1为有效,0为失效,-1为待确认 "mark" => $remark, //pv值获取来源备注 "orderId" => $order_id, //订单id "orderType" => 1001, //订单类型,关联订单id "settlementTime" => date('Y-m-d H:i:s') ]; return $this->postUrl($url,$data); } //更新用户积分 public function updatePoints($uid, $pv,$orderId='') { // 请求 URL $url = self::GATEWAY_URL . "/external/userCenter_service/user/modifyUserScore"; $data = [ "uid" => $uid, //会员id "pm" => $pv>0?1:2, //1为收入积分,2为支出积分 "rewardScore" => abs($pv), //赠送积分数量 "orderId" => $orderId, //订单id "orderType" => "XFXD" //订单类型,关联订单id ]; return $this->postUrl($url,$data); } private function postUrl($url,$data=[]) { $timestamp = round(microtime(true) * 1000); // 获取当前时间戳(毫秒) $signature = $this->generateSignature(self::API_KEY, $timestamp); // 设置请求头 $headers = [ "X-API-KEY: " . self::API_KEY, "X-TIMESTAMP: " . $timestamp, "X-SIGNATURE: " . $signature, "Content-Type: application/json" ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($data), CURLOPT_HTTPHEADER => $headers, ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); //记录报文 if ($err) { throw new \Exception('curl错误:' . $err); } else { Yii::error('幸福宝返回信息'); Yii::error('请求参数'); Yii::error('请求地址'.$url); Yii::error('请求header'); Yii::error(json_encode($headers)); Yii::error($data); Yii::error('返回报文'); $result = json_decode($response,true); Yii::error($response); if (isset($result['code']) && $result['code'] != '200') { $this->error=$result['message']; return false; } return $result['data']; } } private function getUrl($url, $params = []) { // 如果有参数,将其附加到URL上 if (!empty($params)) { $queryString = http_build_query($params); $url .= (strpos($url, '?') !== false ? '&' : '?') . $queryString; } $timestamp = round(microtime(true) * 1000); // 获取当前时间戳(毫秒) $signature = $this->generateSignature(self::API_KEY, $timestamp); // 设置请求头 $headers = [ "X-API-KEY: " . self::API_KEY, "X-TIMESTAMP: " . $timestamp, "X-SIGNATURE: " . $signature, "Content-Type: application/json" ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => "", CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => $headers, ]); $response = curl_exec($curl); $err = curl_error($curl); curl_close($curl); // 记录报文 if ($err) { throw new \Exception('curl错误:' . $err); } else { Yii::error('幸福宝返回信息(GET)'); Yii::error('请求地址: ' . $url); Yii::error('请求header'); Yii::error(json_encode($headers)); Yii::error('返回报文'); Yii::error($response); $result = json_decode($response, true); if (!isset($result['list'])) { $this->error = '请求出错'; return false; } return $result; } } }