The win lifted the Foals out of the relegation zone, while at the same time ruined Dortmund's chance of moving into second place on the Bundesliga table behind Bayern Munich, which won easily on Saturday (AEST) against Greuther Furth.
Both sides couldn't be separated early on, but it was Gladbach that carved out the first big chance, but Matthias Ginter let it get away from him as the ball t ricocheted around the penalty area.
The hosts remained on the back foot and seemed comfortable doing so as Dortmund was unable to muster any sort of breakthrough.
Gladbach seized the initiative and took the lead with ruthless efficiency in the 37th minute. Raphael Guerreiro's back-heeled clearance was picked up by Zakaria, who exchanged passes with Ginter and then got a lucky rebound off Jude Bellingham before picking his spot past Gregor Kobel.
Soon after, Lars Stindl broke down the right and tried to tee up Luca Netz with a low cross that the 18-year-old met on the slide, but could not keep in play, and Gladbach's hopes of victory were boosted further when Mahmoud Dahoud saw his second yellow card and preceded the other 21 players to the dressing room by five minutes.
Jonas Hofmann fizzed in the first shot of the second half which Kobel did well to turn behind, as Gladbach immediately sought to turn the screw with its numerical advantage.
Dortmund had gambled at the restart with Thorgan Hazard replacing Marin Pongracic, but continued to struggle to find any space in the final third as the absence of the injured Erling Haaland told.
At the other end, Zakaria found room to test Kobel once more before Ginter headed wide from the resultant corner.
Hofmann got in around the back of the Dortmund defence as more and more gaps opened up for Gladbach, but he could not find a team-mate having done all the hard work.
Hazard then wasted Dortmund's best chance of the game right at the death, looping a free header on to the roof of the net as the hosts held on for only their second win of the season.