חניבעל הביס את הרומאים בסדרת קרבות: קרב טיקינוס, קרב טרביה וקרב טראסימנוס. הרומאים החלו בהפעלת האסטרטגיה הפביאנית, שהועילה אך מעט. בשנת 216 לפנה"ס הביס חניבעל את הרומאים בקרב ענק שכונה קרב קאנאי, שלאחריו עמדה רומא על סף התמוטטות. בין 50,000-60,000 רומים נהרגו או נשבו במהלכו. אולם במקביל בהיספניה התנהלה המערכה לרעת קרתגו, ואחיו של חניבעל, עזרובעל לא הצליח להדוף את התקפות הרומאים שם. מאז שנת 215 לפנה"ס, הפכה המערכה בחצי האפניני למנומנמת יחסית, והקרבות הגדולים שנערכו במהלכה היו מעטים. חניבעל ניסה ללא הרף לנתק את רומא מבעלות בריתה וכך להכריח אותה לחתום על הסכם כניעה, אולם הרומאים העקשנים עמדו בסירובם. הקרתגים ערכו פשיטות על סרדיניה וסיציליה, שהסתיימו ללא תוצאות משמעותיות מבחינת קרתגו. הם אף כרתו ברית עם שתיים מאויבותיהן המסורתיות מוקדון וסירקוסאי. בשנת 204 לפנה"ס פשט המצביא הרומאי סקיפיו אפריקנוס על אפריקה עצמה. הוא ניצל במיומנות רבה את מרירותם של כמה שבטים נומידים ובראשם מסיניסה נגד קרתגו, והטיל מצור על העיר הקרתגית החשובה אוטיקה. אנשי קרתגו הבינו שכעת הם מאוימים ישירות, וחניבעל נקרא לשוב חזרה מאיטליה. חניבעל נענה לפקודה, הוא חמק ממנה בעזרת צי שיצא מקרוטון בלי שהרומאים ירגישו בכך, והפליג עם צבאו חזרה אל אפריקה. לא ברור מה היה גודל הצבא שחניבעל חזר עמו, חסידיו של סקיפיו טוענים שמספרם הגיע ל-24,000. בעוד חסידי חניבעל מצמצמים את המספר לכדי 10,000. שני הצדדים דחו את פעולות האיבה לשנה הבאה, ועם תחילת השנה נפגשו בקרב זאמה. קרב זה היה הרה אסון מבחינת קרתגו, והיא אולצה לחתום על תנאי שלום משפילים שטבעו את המונח "שלום קרתגו".