Skip to main content
Version: Latest

4. Configuration

4.1 Platform-Wide Configuration — WhatsAppCloudApi Section

Bound from appsettings.json's WhatsAppCloudApi section into WhatsAppCloudApiOptions via services.AddWhatsAppIntegration(config) (Shumoul.Infrastructure/Extensions/ServiceCollectionExtensions.cs).

KeyTypeDefaultPurpose
WhatsAppCloudApi:VerifyTokenstring(empty)Shared secret Meta echoes back during the webhook GET verification handshake
WhatsAppCloudApi:AppSecretstring(empty)Meta App secret — HMAC-SHA256 key for X-Hub-Signature-256 webhook signature validation
WhatsAppCloudApi:SignatureValidationEnabledbooltrueGate for webhook signature enforcement — never disable in production
WhatsAppCloudApi:LogRawPayloadboolfalseDebug-only — logs raw webhook JSON; must stay false in production (payloads can contain customer message content)
WhatsAppCloudApi:AccessTokenstring(empty)Meta Cloud API long-lived access token for the platform's own WhatsApp Business number
WhatsAppCloudApi:PhoneNumberIdstring(empty)Meta registered phone number ID for the platform's own number
WhatsAppCloudApi:BusinessAccountIdstring(empty)Meta business account ID
WhatsAppCloudApi:GraphApiVersionstringv25.0Graph API version segment used in every outbound URL — centralized as of Phase 1 Runtime Consolidation
WhatsAppCloudApi:BaseUrlstringhttps://graph.facebook.comGraph API base URL

Environment variable form (double-underscore, ASP.NET Core convention — this is the form actually used in this codebase, not colon-separated):

WhatsAppCloudApi__VerifyToken
WhatsAppCloudApi__AppSecret
WhatsAppCloudApi__AccessToken
WhatsAppCloudApi__PhoneNumberId
WhatsAppCloudApi__BusinessAccountId

No secret values are reproduced here or anywhere in this guide.

4.2 SecretsManifest Relationship

Shumoul.Application/Secrets/SecretsManifest.cs declares the platform's canonical list of externally-sourced secrets, consumed by SecretsHealthCheck at startup. It lists exactly five WhatsApp-related entries:

Environment VariableRequiredProduction-RequiredRotation SupportedDescription
WhatsAppCloudApi__VerifyTokenNoYesYesMeta webhook verify token
WhatsAppCloudApi__AppSecretNoYesNoMeta App secret for webhook HMAC-SHA256 validation
WhatsAppCloudApi__AccessTokenNoYesYesMeta Cloud API long-lived access token
WhatsAppCloudApi__PhoneNumberIdNoYesNoMeta registered phone number ID
WhatsAppCloudApi__BusinessAccountIdNoYesNoMeta business account ID

"Production-Required" means the health check flags a missing value as a startup warning in Production, even though the value is not strictly Required at the framework level (WhatsApp can be entirely disabled for a deployment that doesn't use it).

4.3 Tenant-Scoped Credentials — WhatsAppOperationalSettings

Read per-tenant via IAppSettingService.GetAppSetting<WhatsAppOperationalSettings>() — never hardcoded, never shared across tenants:

PropertyDefaultPurpose
EnableWhatsApptrueMaster switch for the tenant
EnableWhatsAppOtptrueEnables OTP delivery via WhatsApp
EnableWhatsAppNotificationstrueEnables Notification Framework WhatsApp channel dispatch
EnableWhatsAppTemplatestrueGate for template-based sends
EnableWhatsAppActivationForFreeSubscriptionsfalseWhether free-tier tenants get an activation WhatsApp message
WhatsAppTenantActivationTemplateNameAr / ...Enwelcome_activation_ar / welcome_activation_enActivation template names
WhatsAppTenantActivationDefaultLanguageCodearFallback language for activation messages
WhatsAppTenantOtpTemplateNameAr / ...Enotp_verification_ar / otp_verification_enOTP template names
WhatsAppTenantOtpLanguageDefaultarFallback language for OTP messages
WhatsAppTenantOtpIncludeUrlButtontrueWhether the OTP template includes a URL button component reusing the OTP code
EnableSendingfalseMaster switch for the tenant's own Meta Business number (Communication module)
PhoneNumberId / BusinessAccountId / AccessToken / AppSecret / VerifyToken(empty)The tenant's own Meta credentials, used only by the Communication module's TenantWhatsAppSender
DefaultLanguagearDefault template language for tenant document sends
DefaultTemplatePrefixsend_documentPrefix used when resolving a document-type-specific template name
TemplateLanguageStrategyByRecipientLanguageWhatsAppTemplateLanguageStrategy enum — see §16 Appendix
WebhookEnabledfalseWhether this tenant's own number has webhook delivery configured

Important nuance: the OTP and Activation message services actually resolve their template names from a different, platform-level settings class, SaaSNotificationSettings (bound via IOptions<T>, not tenant-scoped) — not from WhatsAppOperationalSettings. The two classes have similarly-named properties for different purposes: WhatsAppOperationalSettings governs the tenant's own WhatsApp Business number (used by the Communication module only); SaaSNotificationSettings governs the platform's WhatsApp number used for OTP/activation to every tenant's end customers.

4.4 Graph API Version — One Source of Truth

As of the Phase 1 Runtime Consolidation, every outbound Meta call in the solution reads GraphApiVersion/BaseUrl from the same IOptions<WhatsAppCloudApiOptions> — including TenantWhatsAppSender, which previously hardcoded v19.0. There is exactly one place to change the Graph API version platform-wide: the WhatsAppCloudApi:GraphApiVersion configuration key.