Skip to main content

Country Resolution & Region Mapping

Meta's WhatsApp billing model charges based on the country code of the recipient's phone number. To calculate costs accurately, the pricing engine maps E.164 phone numbers to destination countries and region groups.

🌍 Ingestion & Country Extraction

During contact ingestion (e.g., CSV imports, API creation, manual adds), the ContactImportJob parses the phone number into standard E.164 format and populates the countryCode column on the Contact model:

  • Phone numbers are validated using libphonenumber-js.
  • The parsed country code (e.g., IN, US, AE, GB) is stored directly on the Contact.
  • Validations occur before estimation to ensure the estimation database stays clean.

⚡ High-Performance Country Aggregation

Instead of loading thousands of contact records into NestJS memory and grouping them in Javascript (which risks memory leaks), the engine aggregates records directly in PostgreSQL using a single indexed query.

SQL Aggregation Details

SELECT "countryCode", COUNT(*)::bigint as count
FROM "Contact"
WHERE "vendorId" = $1::uuid
AND "deletedAt" IS NULL
AND "id" = ANY($2::uuid[])
AND "countryCode" IS NOT NULL
GROUP BY "countryCode"
ORDER BY count DESC;

🔄 Region Resolution Flow

Once country counts are aggregated, they are mapped to billing regions:

Region Groups Mapped

Meta clusters countries into billing region groups:

  1. SOUTH_ASIA (e.g. India, Pakistan, Bangladesh, Sri Lanka)
  2. NORTH_AMERICA (e.g. United States, Canada)
  3. WESTERN_EUROPE (e.g. United Kingdom, Germany, France)
  4. MIDDLE_EAST (e.g. UAE, Saudi Arabia)
  5. NORTH_AFRICA (e.g. Egypt)
  6. LATIN_AMERICA (e.g. Brazil, Mexico, Argentina)
  7. SOUTHEAST_ASIA (e.g. Indonesia, Malaysia, Singapore)
  8. APAC (e.g. Australia, Japan, South Korea, China)
  9. EASTERN_EUROPE (e.g. Russia, Poland)
  10. SUB_SAHARAN_AFRICA (e.g. South Africa, Nigeria)
  11. OTHER (Universal Fallback)

⚠️ Unresolved Country Fallback Strategy

If a contact has a missing or invalid country code:

  • The engine falls back to XX (Unknown).
  • Unknown records are grouped into the OTHER region group.
  • Using OTHER as a fallback ensures estimations can still be generated without failing the entire transaction.