hash('sha256', $externalId), ]; $customData = array_merge( array_filter([ 'currency' => $currency, 'value' => $value, ], static function ($v) { return $v !== null && $v !== ''; }), $extraCustomData ); $payload = [ 'data' => [ [ 'event_name' => $eventName, 'event_time' => $eventTime, 'action_source' => 'website', 'event_id' => $eventId, 'user_data' => $userData, 'custom_data' => $customData, ], ], ]; $url = sprintf( 'https://graph.facebook.com/v25.0/%s/events?access_token=%s', $pixelId, $accessToken ); try { $http = new HttpCurl(); $response = $http->curlPost($url, $payload, 'json', true); Log::info('FacebookEventService trackEvent success', [ 'event_name' => $eventName, 'event_id' => $eventId, 'user_id' => $userId, 'pixel_id' => $pixelId, 'payload' => $payload, 'response' => $response, ]); } catch (\Throwable $e) { Log::error('FacebookEventService trackEvent error', [ 'event_name' => $eventName, 'event_id' => $eventId, 'user_id' => $userId, 'pixel_id' => $pixelId, 'message' => $e->getMessage(), ]); } } /** * 注册完成事件(对应前端 CompleteRegistration) */ public static function trackCompleteRegistration(GlobalUserInfo $user, WebChannelConfig $config): void { if (empty($config->PlatformID) || empty($config->PlatformToken)) { return; } $pixelId = $config->PlatformID; $accessToken = $config->PlatformToken; // 建议前端也使用相同的 event_id:reg_{UserID} $eventId = 'reg_' . $user->UserID; FacebookServerEvent::dispatch( 'CompleteRegistration', $eventId, $user->UserID, null, null, $pixelId, $accessToken ); } /** * 支付事件(对应前端 pay + firstpayD0/firstpayD1/payagain/Purchase) * * @param int|string $userId * @param string $orderSn * @param float|int $amount * @param string $currency * @param bool $isFirst * @param bool $isD0 * @param int $channel */ public static function trackPayEvent( $userId, string $orderSn, $amount, string $currency, bool $isFirst, bool $isD0, int $channel ): void { $config = WebChannelConfig::getByChannel($channel); if (!$config || empty($config->PlatformID) || empty($config->PlatformToken)) { return; } $pixelId = $config->PlatformID; $accessToken = $config->PlatformToken; // 统一使用同一个 event_id(与前端保持一致) // 前端所有支付相关事件共用:purchase_{order_sn} $eventId = 'purchase_' . $orderSn; // 标准 Purchase 事件(所有支付都会上报) FacebookServerEvent::dispatch( 'Purchase', $eventId, $userId, $amount, $currency, $pixelId, $accessToken ); // 首次支付 if ($isFirst) { FacebookServerEvent::dispatch( 'firstpayD1', $eventId, $userId, $amount, $currency, $pixelId, $accessToken ); if ($isD0) { // D0 首充自定义事件 FacebookServerEvent::dispatch( 'firstpayD0', $eventId, $userId, $amount, $currency, $pixelId, $accessToken ); // D0 首充标准事件:AddToWishlist(与前端保持一致) FacebookServerEvent::dispatch( 'AddToWishlist', $eventId, $userId, $amount, $currency, $pixelId, $accessToken ); } } elseif (!$isD0) { // 复充(非首次且非 D0) FacebookServerEvent::dispatch( 'payagain', $eventId, $userId, $amount, $currency, $pixelId, $accessToken ); } } }