Third-Party Services
RoundTrip integrates with a number of external services to deliver its full feature set. This section documents every third-party integration — what it does, why it was chosen, how it is configured, and how to operate it.
Integration Philosophy
All third-party service integrations follow the same rules without exception:
Credentials never touch the codebase. All API keys, client secrets, and tokens live in Azure Key Vault and are injected into the application via App Service environment variables at startup. No credentials are ever committed to a repository or hardcoded in configuration files.
All external calls live in the Infrastructure layer. Service clients (SendGridEmailService, GraphUserService, etc.) are implemented in RoundTrip.API.Infrastructure. The Application and Domain layers never reference external service SDKs directly — they call interfaces defined in Core.Interfaces and implemented in Infrastructure.
All services are configured via IConfiguration. Service constructors read config keys at startup and throw InvalidOperationException if a required key is missing. This surfaces misconfiguration immediately on startup rather than at runtime when the first call is made.
Hangfire handles all deferred delivery. Emails, PDF generation, and other async work are enqueued as Hangfire background jobs rather than called inline in request handlers. This keeps API response times fast and provides automatic retry on failure.
Services at a Glance
| Service | Purpose | Status | Key Vault Secret |
|---|---|---|---|
| SendGrid | All outbound email — invitations, invoices | ✅ Live | SendGrid--ApiKey |
| Stripe | Subscription billing, payments, webhooks | ✅ Live | Stripe--SecretKey etc. |
| Microsoft Graph API | User management in Entra External ID CIAM | ✅ Live | GraphApi--ClientSecret etc. |
| Web Push (VAPID) | PWA push notifications to technician devices | ✅ Live | VapidKeys--PrivateKey etc. |
| Twilio | SMS notifications to technicians | ⏳ Planned | Twilio--AuthToken etc. |
| Azure Blob Storage | Invoice PDF storage | ✅ Live | ConnectionStrings--BlobStorage |
Adding a New Service
When integrating a new third-party service, follow this checklist:
- Create the interface in
RoundTrip.API.Core/Interfaces/— e.g.ISmsService - Implement the interface in
RoundTrip.API.Infrastructure/Services/— e.g.TwilioSmsService - Read all required config in the constructor — throw
InvalidOperationExceptionif missing - Register the implementation in
InfrastructureServiceExtensions.cs - Add required secrets to
kv-roundtrip-productionin Key Vault - Add App Service environment variable referencing the Key Vault secret
- Add the secret name and mapping to the Infrastructure Reference
- Document the service on a new page in this section
- Do a full stop/start of App Service after adding new Key Vault references
- Store credentials in Bitwarden as well as Key Vault
Credential Management
All service credentials are stored in two places:
| Store | Purpose | Contains |
|---|---|---|
Azure Key Vault (kv-roundtrip-production) | Runtime credential injection into the application | API keys, client secrets, tokens — the actual values the app uses |
| Bitwarden (Traxs Group vault) | Human access — dashboard logins, account credentials, backup | Login emails, passwords, account URLs, billing info |
See the Infrastructure Reference for the full Key Vault secret inventory.