/** * Vietnamese phone number helpers. * * Regex covers the current VN numbering plan: * 0[35789]x xxxxxxx — Viettel, Mobifone, Vinaphone, Gmobile, Indochina * * See: https://en.wikipedia.org/wiki/Telephone_numbers_in_Vietnam */ /** Matches a VN mobile number, with optional +84 or leading 0. */ export const VN_PHONE_REGEX = /^(0|\+84)(3[2-9]|5[2689]|7[06-9]|8[1-9]|9[0-9])\d{7}$/; /** * Normalise a VN phone number to the E.164-ish form used by Zalo / APIs: * strip leading 0 and prepend the country code (84). * * "0987654321" → "84987654321" * "+84987654321" → "84987654321" * "84987654321" → "84987654321" (already normalised — idempotent) */ export function normalizePhone(phone: string): string { const cleaned = phone.trim(); if (cleaned.startsWith('+84')) return `84${cleaned.slice(3)}`; if (cleaned.startsWith('84')) return cleaned; if (cleaned.startsWith('0')) return `84${cleaned.slice(1)}`; return cleaned; } /** * Format a raw VN phone number for display. * Handles 10-digit numbers (0xx xxxx xxxx). * * "0987654321" → "0987 654 321" * Passthrough for anything that doesn't match. */ export function formatPhone(phone: string): string { const cleaned = phone.trim().replace(/\s+/g, ''); // 10-digit local format: 0xxx yyy zzz const tenDigit = cleaned.match(/^(0\d{3})(\d{3})(\d{3})$/); if (tenDigit) return `${tenDigit[1]} ${tenDigit[2]} ${tenDigit[3]}`; // +84 prefix → treat as 10-digit local after swapping prefix const e164 = cleaned.match(/^\+84(\d{9})$/); if (e164) return formatPhone(`0${e164[1]}`); return phone; } /** * Returns the https://zalo.me deep-link URL for a given phone number. * * Zalo expects the number without a leading zero, prefixed with 84. * "0987654321" → "https://zalo.me/84987654321" */ export function zaloHref(phone: string): string { return `https://zalo.me/${normalizePhone(phone)}`; }