data = $data; } /** * Execute the job. * * @return void */ public function handle() { Log::channel('adjustEvent')->info('enter:'.json_encode($this->data)); if (empty($this->data)) return; [$UserID, $payAmt, $AdId, $eventType, $channel, $pfType, $params] = $this->normalizePayload($this->data); if (!$UserID) { return; } if (empty($eventType)) $eventType = 2; Log::channel('adjustEvent')->info('接收数据' . \GuzzleHttp\json_encode($this->data)); if ($this->isFacebookPlatform($pfType)) { $this->reportFacebookEvents($channel, $UserID, $payAmt, $AdId, $params); return; } if ($payAmt && !empty($AdId)) { // 执行AF事件 $dao = new \App\dao\af\AfEvent(); $dao->pay($AdId, $UserID, $eventType); $dao->paySum($AdId, $UserID, $payAmt, $eventType); $dao->payCount($AdId, $UserID, $eventType); } // $dao->recordKwaiRecharge($UserID, $payAmt); // $dao->recordGoogleRecharge($UserID, $payAmt); } protected function normalizePayload($data) { if (isset($data['UserID'])) { $user = GlobalUserInfo::getGameUserInfo('UserID', $data['UserID']); $this->user = $user; $params = is_array($data['params'] ?? null) ? $data['params'] : []; $orderSn = $params['order_sn'] ?? ''; $orderInfo = $orderSn === '' ? null : DB::connection('write')->table('agent.dbo.order') ->where('order_sn', $orderSn) ->select('AdId', 'eventType','Channel') ->first(); $channel = $data['channel'] ?? ($orderInfo->Channel ?? null) ?? ($user->Channel ?? null) ?? $this->extractChannelFromCookie($data['UserID']) ?? 100; $channelConfig = $channel ? WebChannelConfig::getByChannel($channel) : null; $params['config'] = $channelConfig; $params['event_name'] = $data['event_name'] ?? ($params['event_name'] ?? ''); $params['custom_data'] = is_array($data['custom_data'] ?? null) ? $data['custom_data'] : ($params['custom_data'] ?? []); Log::channel('adjustEvent')->info('normalizePayload:' . json_encode([ 'user_id' => $data['UserID'] ?? 0, 'event_name' => $params['event_name'], 'order_sn' => $orderSn, 'order_channel' => $orderInfo->Channel ?? null, 'global_channel' => $user->Channel ?? null, 'final_channel' => $channel, 'platform_name' => $channelConfig->PlatformName ?? null, ], JSON_UNESCAPED_UNICODE)); return [ $data['UserID'] ?? 0, $params['golds'] ?? 0, $orderInfo->AdId ?? '', $orderInfo->eventType ?? 2, $channel, $channelConfig->PlatformName ?? '', $params, ]; } return [ $data[0] ?? 0, $data[1] ?? 0, $data[2] ?? '', $data[3] ?? 2, $data[4] ?? 0, $data[5] ?? '', $data[6] ?? [], ]; } protected function isFacebookPlatform($pfType) { return is_string($pfType) && stripos($pfType, 'fb') !== false; } protected function reportFacebookEvents($channel, $userID, $payAmt, $adId, array $params = []) { try { $config = $params['config'] ?? null; if (!$config || !$this->isFacebookPlatform($config->PlatformName ?? '')) { Log::channel('adjustEvent')->info('facebook s2s skipped: invalid config', [ 'channel' => $channel, 'user_id' => $userID, 'platform_name' => $config->PlatformName ?? null, ]); return; } $pixelId = trim((string)($config->PlatformID ?? '')); $accessToken = trim((string)($config->PlatformToken ?? '')); if ($pixelId === '' || $accessToken === '') { Log::channel('adjustEvent')->info('facebook s2s skipped: missing pixel config', [ 'channel' => $channel, 'user_id' => $userID, 'pixel_id' => $pixelId, ]); return; } $events = $this->buildFacebookEvents($userID, $payAmt, $adId, $params); if (empty($events)) { return; } $url = "https://graph.facebook.com/v21.0/{$pixelId}/events"; $payload = [ 'data' => $events, 'access_token' => $accessToken, ]; Log::channel('adjustEvent')->info('facebook s2s request ' . json_encode([ 'channel' => $channel, 'user_id' => $userID, 'pixel_id' => $pixelId, 'event_count' => count($events), 'payload' => $payload, ], JSON_UNESCAPED_UNICODE)); $client = new Client([ 'timeout' => 10, 'http_errors' => false, ]); $response = $client->post($url, ['json' => $payload]); Log::channel('adjustEvent')->info('facebook s2s response ' . json_encode([ 'channel' => $channel, 'user_id' => $userID, 'status' => $response->getStatusCode(), 'body' => (string)$response->getBody(), ], JSON_UNESCAPED_UNICODE)); } catch (\Throwable $e) { Log::channel('adjustEvent')->info('facebook s2s failed ' . json_encode([ 'channel' => $channel, 'user_id' => $userID, 'message' => $e->getMessage(), ], JSON_UNESCAPED_UNICODE)); } } protected function buildFacebookEvents($userID, $payAmt, $adId, array $params = []) { $cookieInfo = $this->getFacebookCookieInfo($userID); if (!empty($params['event_name'])) { return $this->buildSingleFacebookEvent($userID, $adId, $params, $cookieInfo); } $orderSn = $params['order_sn'] ?? ''; $first = !empty($params['first']); $isD0 = !empty($params['isd0']); $currency = env('CONFIG_24680_CURRENCY', 'BRL'); $userData = $this->buildFacebookUserData($userID, $adId, $params, $cookieInfo); $customData = array_filter([ 'value' => (float)$payAmt, 'currency' => $currency, ], function ($value) { return $value !== '' && $value !== null; }); $origin = $cookieInfo['Origin'] ?? ''; $events = []; if ($first) { if ($isD0) { $events[] = $this->makeFacebookEvent('firstpayD0', 'd0_' . $orderSn, $userData, $customData, $origin); $events[] = $this->makeFacebookEvent('AddToWishlist', 'aw_' . $orderSn, $userData, $customData, $origin); } else { $events[] = $this->makeFacebookEvent('firstpayD1', 'd1_' . $orderSn, $userData, $customData, $origin); $events[] = $this->makeFacebookEvent('AddToCart', 'ac_' . $orderSn, $userData, $customData, $origin); } } else if (!$isD0) { $events[] = $this->makeFacebookEvent('payagain', 'pa_' . $orderSn, $userData, $customData, $origin); $events[] = $this->makeFacebookEvent('InitiateCheckout', 'ic_' . $orderSn, $userData, $customData, $origin); } $events[] = $this->makeFacebookEvent('Purchase', 'pay_' . $orderSn, $userData, $customData, $origin); return $events; } protected function buildSingleFacebookEvent($userID, $adId, array $params = [], array $cookieInfo = []) { $user = $this->user; $eventName = trim((string)($params['event_name'] ?? '')); if ($eventName === '') { return []; } $eventId = $eventName . '_' . ($user->FPID ?? ''); $customData = is_array($params['custom_data'] ?? null) ? $params['custom_data'] : []; $customData = array_filter($customData, function ($value) { return $value !== '' && $value !== null; }); return [ $this->makeFacebookEvent( $eventName, $eventId, $this->buildFacebookUserData($userID, $adId, $params, $cookieInfo), $customData, $cookieInfo['Origin'] ?? '' ) ]; } protected function buildFacebookUserData($userID, $adId, array $params = [], array $cookieInfo = []) { $user = $this->user; if (empty($cookieInfo)) { $cookieInfo = $this->getFacebookCookieInfo($userID); } $cookieValues = $this->parseCookieValues($cookieInfo['Cookie'] ?? ''); $browserIds = $this->resolveFacebookBrowserIds($userID, $params, $cookieInfo, $cookieValues); $externalId = $params['udid'] ?? ($user ? md5($user->UserID) : md5($userID)); $userData = [ 'external_id' => (string)$externalId, 'fbp' => $browserIds['fbp'], 'fbc' => $browserIds['fbc'], 'client_ip_address' => $cookieInfo['IP'] ?? '', 'client_user_agent' => $cookieInfo['ClickUA'] ?? $cookieInfo['GameUA'] ?? '', ]; return array_filter($userData, function ($value) { return $value !== '' && $value !== null; }); } protected function getFacebookCookieInfo($userID) { $user = $this->user; return ApkService::loadCookie($userID, $user->FPID ?? '', $user->FF ?? '') ?: []; } protected function parseCookieValues($cookieString) { $cookies = []; if (!is_string($cookieString) || $cookieString === '') { return $cookies; } foreach (explode(';', $cookieString) as $part) { $part = trim($part); if ($part === '' || strpos($part, '=') === false) { continue; } [$name, $value] = explode('=', $part, 2); $cookies[trim($name)] = trim($value); } return $cookies; } protected function resolveFacebookBrowserIds($userID, array $params, array $cookieInfo, array $cookieValues) { $fbp = trim((string)($cookieValues['_fbp'] ?? '')); $fbc = trim((string)($cookieValues['_fbc'] ?? '')); $cookieParamsFbclid = ''; if (!empty($cookieInfo['Params'])) { $cookieParams = json_decode($cookieInfo['Params'], true); if (is_array($cookieParams)) { $cookieParamsFbclid = trim((string)($cookieParams['fbclid'] ?? '')); } } if ($cookieParamsFbclid === '') { return compact('fbp', 'fbc'); } $timestamp = $this->resolveFacebookCookieTimestamp($cookieInfo); $currentFbclid = ApkService::extractFbclid($fbc); if ($fbc === '' || $currentFbclid === '' || $currentFbclid !== $cookieParamsFbclid) { $fbc = 'fb.1.' . $timestamp . '.' . $cookieParamsFbclid; } if ($fbp === '') { $seed = implode('|', [ $userID, $cookieInfo['FPID'] ?? '', $cookieInfo['FF'] ?? '', $cookieInfo['IP'] ?? '', $cookieInfo['CreateTime'] ?? '', ]); $fbp = 'fb.1.' . $timestamp . '.' . substr(md5($seed), 0, 16); } return compact('fbp', 'fbc'); } protected function resolveFacebookCookieTimestamp(array $cookieInfo) { $rawTime = $cookieInfo['CreateTime'] ?? ''; if (!empty($rawTime)) { $timestamp = strtotime((string)$rawTime); if ($timestamp !== false) { return (string)($timestamp * 1000); } } return (string)round(microtime(true) * 1000); } protected function extractChannelFromCookie($userID) { $cookieInfo = $this->getFacebookCookieInfo($userID); if (!$cookieInfo || empty($cookieInfo['Params'])) { return null; } $params = json_decode($cookieInfo['Params'], true); if (!is_array($params)) { return null; } return $params['c'] ?? null; } protected function makeFacebookEvent($eventName, $eventId, array $userData, array $customData, $eventSourceUrl = '') { $event = [ 'event_name' => $eventName, 'event_time' => time(), 'event_id' => $eventId, 'action_source' => 'website', 'user_data' => $userData, ]; if (!empty($customData)) { $event['custom_data'] = (object)$customData; } if (!empty($eventSourceUrl)) { $event['event_source_url'] = $eventSourceUrl; } return $event; } }