# Services

Business logic and external integration layer. Services encapsulate domain operations, third-party API calls, and complex workflows that don't belong in controllers or query classes.

## Files

| Service | Description |
|---------|-------------|
| `BajajHealthEventService` | Sends user progress events to the Bajaj Health partner API with retry logic |
| `CalculationService` | Computes smoking addiction scores and resolves personality types from questionnaire answers |
| `EmailService` | Sends error notifications, angel introduction emails, and transactional emails via SendGrid |
| `FacebookService` | Sends server-side conversion events to the Facebook Conversions API (web and app channels) |
| `GeoLocationService` | Resolves IP addresses to country/geodata using ipgeolocation.io with circl.lu fallback |
| `GympassService` | Fires user engagement events to the Gympass Wellness API for partner tracking |
| `PostmarkService` | Sends templated transactional emails through the Postmark API |
| `RazorpayService` | Wraps Razorpay API for orders, customers, subscriptions, and webhook signature verification |
| `SubModuleService` | Orchestrates submodule completion: progress updates, partner events, and completion emails |
| `UserUtilityService` | User utilities: ID encryption, SSO tokens, Branch.io deep links, journey logging, media metadata |
| `UtilityService` | Static helpers for session-or-fallback data retrieval and User-Agent parsing |
| `WebProfilerService` | Records per-request performance profiles (timing, DB queries, HTTP calls) to `ApiTiming` |

## Conventions

- **Constructor injection** uses PHP 8 promoted properties for query dependencies (`protected UserQuery $userQuery`)
- Config-based services (Razorpay, Postmark, BajajHealth) read config values in the constructor
- `GeoLocationService` and `WebProfilerService` are registered as **singletons** via their service providers
- **Error handling**: external calls are wrapped in try/catch; failures logged via `Log::error()` with structured arrays
- **Return patterns**: status arrays (`['status' => bool, ...]`) for multi-value results; `object|false` for Razorpay API calls
- `UtilityService` is the only fully-static service; all others are instance-based for container resolution
- Outbound HTTP uses Laravel's `Http` facade except `FacebookService` (official SDK) and `GeoLocationService` (`file_get_contents`)
