ליד זאמה התכנסו צבאותיהם של סקיפיו וחניבעל לקרב הכרעה אחרון, שיקבע את עתיד המלחמה. היקף הצבאות שלקחו חלק בקרב אינו ברור כל צורכו. לטענת חלק מהחוקרים המצדדים בסקיפיו, לחניבעל היו בין 50,000 ל-55,000 חיילים רגליים, בין 3,000 ל-6,000 פרשים – חלקם לובי-פיניקים וחלקם נומידים, וכן 80 פילים. לעומתו, היו לסקיפיו קצת פחות מ-35,000 רגליים, ובין 5,500 ל-9,000 פרשים. לדעת החוקרים המצדדים בחניבעל, כלל צבאו בין 35,000 ל-40,000 רגליים בלבד.
על כל פנים, העובדות הברורות הן שלחניבעל היה יתרון בחיילים רגליים ולסקיפיו יתרון בפרשים. חניבעל החליט לחרוג ממנהגו הרגיל להציב את כל החיילים בחזית אחת, וחילק אותם לשלושה קווים. בקו הראשון הוצבו שכירי חרב מגאליה ומליגוריה, וקלעים מהאיים הבלאריים, שגויסו על ידי אחיו מאגו (מאגו עצמו מת מפצעיו בדרכו לאפריקה). בקו השני הוצבו חיילים רגליים בעלי חימוש כבד יותר, רובם טירונים שגויסו מקרתגו ומלוב, ואילו בקו האחרון הוחזקו ותיקי המלחמה מאיטליה, שרידי צבאו המקורי של חניבעל. לא ברור מדוע בחר להיערך באופן הזה. ייתכן שחניבעל לא בטח בטירונים החדשים שגייס, והשתמש בהם רק כ"בשר תותחים" עבור החיילים הוותיקים מאיטליה, אותם שמר רעננים לשלב המכריע. את הפרשים הלובי-פיניקים ערך באגף אחד, את הנומידים באגף שני, ואת הפילים ערך מקדימה. סקיפיו מצידו ערך גם הוא את חייליו בשלושה קווים. את הפרשים הנומידים הציב באגף השמאלי והפקיד עליהם את מסיניסה, ואת הפרשים הלטינים שגויסו מקרב בעלות הברית הציב באגף הימני והפקיד עליהם את גאיוס ליליוס. תוכניתו של סקיפיו דמתה למעשה לתוכניתו של חניבעל בקרב קאנאי, ריתוק חיל הרגלים, בו בזמן שחיל הפרשים הרומאי-נומידי החזק יאגף את חיל הרגלים הקרתגי ויביס אותו. חניבעל שהיה מנוסה באסטרטגיות מעין אלו, הבין היטב שהסיכוי היחיד שלו לנצח בקרב יהיה אם יצליח בעזרת חיל הרגלים העדיף שלו להביס את חיל הרגלים הרומאי, לפני שחיל הפרשים יסיים את מלאכתו.
הקרב התרחש ב-19 באוקטובר, שנת 202. חניבעל פתח אותו בהסתערות שמונים פיליו, אולם אז קרה דבר בלתי צפוי, ורווחים נפערו לקראתם במערך הרומאי. הפילים שאומנו לבצע הסתערות אחת מהירה התבלבלו, והרומאים הטילו בהם כידונים ותקעו בחצוצרות. הפילים נבהלו ונמלטו לאחור, רומסים בני ברית ואויבים כאחד. לאחר מכן התנגש הקו הקרתגי הראשון עם הקו הרומאי הראשון. לקרתגים היו פקודות ברורות מאוד, לא לשבור את הקווים בשום מחיר. סקיפיו לעומת זאת התגמש יותר בעניין זה.
בתחילה הדפו הקרתגים את אויביהם לאחור, אולם אז תוגבר הקו הרומאי הראשון, בחיילים שהובאו מהקו השני. הקו הקרתגי הראשון הובס, וחייליו נסוגו לאחור בתקווה למצוא מקלט מאחרי הקו הקרתגי השני, אך החיילים בקו השני לא איפשרו להם לעבור דרכם, מחשש שאם יפתחו את שורותיהם, הדבר ישבש את מערכם ויאפשר לרומאים הרודפים להבקיע דרכם. חלק מהנמלטים הנואשים ניסו להבקיע לעצמם דרך בלחימה, והשאר פנו ימינה ושמאלה והגדילו את רוחב החזית הקרתגית. כעת קידם חניבעל את הקו השני, אך גורלו דמה לזה של הקו הראשון וסקיפיו הביס גם אותו. אז קידם חניבעל את הקו השלישי, שהיה כאמור מורכב מחיילים ותיקים מנוסים ורעננים שעדיין לא השתתפו בלחימה. סקיפיו שבר את שלושת הקווים ויצר מהם קו אחד, אולם חייליו הרעננים של חניבעל שנהנו גם מיתרון מספרי הצליחו להדוף אותם. נראה היה שהקרב יוכרע לטובת הקרתגים, אולם אז הופיעו הפרשים הנומידים והלטינים בעורף צבאו של חניבעל, והכריעו את הקרב, שהסתיים בניצחון מוחץ לסקיפיו.
שופט בקרתגו.
חניבעל נמלט מתבוסת זאמה עם קומץ פליטים. הוא הותיר את מלוויו בהדרומטום והגיע בעצמו אל קרתגו. הייתה זו הפעם הראשונה בה נכנס בשערי העיר מאז עזב אותה כילד בן תשע. אשתו ובנו ככל הנראה כבר מתו. על אף ההפסד התקבל חניבעל כגיבור בעיר. הוא סימל אומץ לב גבורה ונחישות בעיני בני קרתגו, והיה המצביא היחיד שהצליח לקצור ניצחונות כה רבים במלחמה. חניבעל תמך בכניעה לתנאי השלום שהציב סקיפיו, והדבר עורר מחאה בקרב הסיעות השליטות בעיר. מסופר שבאחת מאספות המועצה צעיר בשם גיסקו קרא להילחם ברומאים ולהדיח את חניבעל, זה האחרון איבד את השליטה העצמית והוריד את גיסקו בכוח מדוכן הנואמים. כאשר חבריו של גיסקו פתחו במחאה, חניבעל הכריז:
חניבעל הסביר מדוע השלום עם רומא אינו נורא כפי שהוא נראה ממבט ראשון, וכי קרתגו תוכל להשתקם ממנו. בהשפעתו הושג הסכם שלום שכלל את התנאים הבאים: קרתגו תשלם לרומא 200 טלנטים מדי שנה במשך 50 שנים. הצי המלחמתי הקרתגי יפורק למעט 10 ספינות. כמו כן צבאה היבשתי של קרתגו יצומצם. יוסגרו כל הפילים. ייאסר על קרתגו לפתוח במלחמה חיצונית או פנימית כלשהי ללא הסכמת רומא, אם כי קרתגו תתחייב לסייע לרומא בכל מלחמה שלה. תוכר שליטתו של מסיניסה בנומידיה כולה, ושליטתם של הרומאים בהיספניה, סיציליה, קורסיקה, סרדיניה, והאיים הבליארים. קרתגו שלחה לרומא 100 בני ערובה ממשפחותיהם של נכבדי העיר והחזירה את כל העריקים והשבויים. תנאי השלום הקשים הולידו את הביטוי "שלום קרתגו".
לא ברור מה עשה חניבעל לאחר הכניעה. דיו קסיוס כותב שהוא הועמד למשפט על כך שסירב לתקוף את רומא לאחר קאנאי, אולם זוכה מהר מאוד. קורנליוס נפוס טען שהוא עדיין פיקד על הצבא, אולם טענה זו אינה מסתברת וככל הנראה הרומאים הורו להרחיק אותו מכל פעילות צבאית. לא ברור מה עשה עד שנת 196 לפנה"ס, אולם ככל הנראה הייתה לו השפעה רבה בעיר. קרתגו נאלצה להתחיל לשלם את הפיצויים לרומא. הוצאות המלחמה האדירות, איבוד מכרות הכסף בהיספניה, והרס יחסי החוץ והמסחר, הפכו את המשימה לבלתי אפשרית. בשנת 196 חניבעל מונה לשופט (שוּפֵט בלשונם), כלומר אחד משני שליטים בני קרתגו (בדומה למגיסטראטים ברומא), שנבחרו על ידי העם לעמוד בראש המעצמה והיו כפופים למועצת הזקנים ולמועצת המאה וארבעה (תת-מועצה הכפופה למועצת הזקנים). מתוקף תפקידו ריכז את כל הסמכויות הפוליטיות של המדינה, פרט לניהול הצבא. כעת נאלץ חניבעל למצוא מקורות לתשלום הפיצויים. בנסיבות רגילות היו משתמשים בכספי מכס ובמיסים שהוטלו על סחורות שהיה עליהן מונופול, אולם כעת לא היה די בכך, ולכן הטיל חניבעל מס על רכוש פרטי, וכך יצא שהאזרחים העשירים ביותר שילמו את הסכום הגבוה ביותר. הדבר עורר מרמור רב בקרב האזרחים העשירים ורבי ההשפעה, ואחד מהם הכריז במהלך אחת האספות שזוהי מעמסה שלא ניתן לשאתה. כאשר חניבעל שמע זאת הוא פרץ בצחוק והכריז:
חניבעל ארגן מחדש את שיטת גביית המיסים, דאג ליישב מחדש אזורים שחרבו, צמצם את כוח האצולה, וכונן מחדש יחסי חוץ עם אנטיוכיה, צור, רודוס, ופרגמון. הוא חוקק חוק שמנע מחברי מועצת המאה וארבע לכהן בתפקיד זה למשך כל ימי חייהם, וקבע שמעתה ואילך יתקיימו בחירות מדי שנה בשנה. פעולות אילו השניאו אותו על רבים מתושביה העשירים יותר של קרתגו, והללו טענו ברומא שחניבעל מתנהג כדיקטטור ומתכנן מלחמה חדשה ברומא. הרומאים נטו להאמין לשמועות אלו, ומשלחת רומאית הגיעה לקרתגו בשנת 195 לפנה"ס, כביכול כדי לפתור סכסוך עם מסיניסה, אולם למעשה כדי לבדוק מקרוב את בעיית חניבעל. חניבעל הבין את מטרתה האמיתית של המשלחת. הוא התנהג כרגיל במשך כל היום, ורק לקראת הערב רכב במהירות לכיוון אחוזה פרטית שלו ששכנה על חוף הים בריחוק מה מקרתגו. משם לקח ספינה פרטית שלו ויצא לגלות.
גלות.
חניבעל אצל אנטיוכוס.
חניבעל הפליג לצור, עיר פיניקית בלבנון של ימינו, שהייתה למעשה עיר האם של קרתגו. בצור קיבלו אותו בידידות, כיאה למנהיג של מעצמה ידידה, אולם חניבעל לא התעכב שם. ברור היה לו שהמקום היחיד בו יוכל למצוא מקלט יהיה אצל שליט הלניסטי חזק. מצרים לא באה בחשבון, כיוון שהפרעה תלמי החמישי היה תלוי מאוד ברומאים שסיפקו לו הגנה מפני אויביו מבית ומחוץ. גם מוקדון לא באה בחשבון, כיוון שלאחר קרב קינוסקאפאלאי הסתיימה המלחמה המוקדונית השנייה בתבוסת מוקדון, ופיליפוס החמישי נושל ממרבית אדמותיו ביוון ועדיין ליקק את פצעיו. היחידה שיכלה אפוא לספק מקלט אידיאלי לחניבעל הייתה האימפריה הסלאוקית, עליה מלך אותה תקופה אנטיוכוס השלישי שכונה "הגדול" (Μέγας ביוונית). אנטיוכוס היה שליט חזק שהפך את ממלכתו לממלכה החזקה ביותר באסיה, ושאף להרחיב את שלטונו גם לאירופה על חשבון מוקדון ורומא. ככל הנראה חניבעל ואנטיוכוס כבר החליפו מכתבים לפני כן, משום שכאשר הופיעה ספינתו של חניבעל באפסוס (אז לידיה, בשטחי טורקיה המודרנית) ערך לו אנטיוכוס קבלת פנים מפוארת.
אנטיוכוס ראה בחניבעל את האיש הנכון בזמן הנכון. הוא תכנן מלחמה נגד רומא, והבין שניסיונו הרב של חניבעל יוכל לסייע לו רבות. חניבעל הציע לאנטיוכוס תוכניות רבות, ביניהן תוכנית להנחית אותו יחד עם 10,000 רגליים ו-1,000 פרשים באיטליה, וכך לעורר בה פאניקה רבתי. אנטיוכוס התרשם, אולם היה מסופק ובחר שלא להחליט. חניבעל שלח שליח בן צור בשם אריסטון אל קרתגו במטרה לנסות לברר את הלך הרוח בעיר, אולם בני הסיעה שהתנגדה לחניבעל חשפו זאת ודיווחו לרומאים. אלו האחרונים שלחו משלחת לאנטיוכיה במטרה לחדש את שיחות השלום עם אנטיוכוס. בדרך עצרו חברי המשלחת באפסוס, ומנהיג המשלחת פובליוס ויליוס נפגש מספר פעמים עם חניבעל והתייחס אליו בידידות גלויה. מקורות שונים טוענים שגם סקיפיו בכבודו ובעצמו נכח במשלחת, ואף מביאים אנקדוטה אודות ויכוח ביניהם מיהו המצביא הגדול בהיסטוריה. כל העניין עורר את חשדו של אנטיוכוס כלפי חניבעל, אולם אז כבר היה ברור שמלחמה עם רומא היא רק עניין של זמן.