The Norwegian forward, who had been out since late September, scored in the 54th minute with a spot kick following a lengthy VAR review over a hand ball and then again deep in second half stoppage time.
The hosts, who travel to Ajax for the Champions League next week, had shot out of the blocks and earned a dream start with captain Marco Reus thumping in a deflected cutback in the third minute for a dream start.
It was Reus’ 14th goal in 20 games against Mainz, the most he has scored against any Bundesliga club.
In a tense first half Dortmund had three quarters of possession but had to wait almost the entire half for another chance in stoppage time when a Jude Bellingham effort was cleared off the line.
Haaland’s penalty gave Dortmund a measure of comfort in the second half and Mats Hummels hit the post with a glancing header but the visitors were not yet done.
Mainz struck with Jonathan Burkardt in the 87th from a mistake by Dortmund keeper Gregor Kobel to set up a nervous finale before Haaland completed a quick break to secure Dortmund’s ninth consecutive home league win.