The opener changed his running line while attempting a second run and was struck by a throw from AB de Villiers aimed at the non-striker's end.
He was given out by third umpire Billy Bowden, becoming the first player to fall victim to the new International Cricket Council rule that prohibits batsman from intentionally changing their running line to intercept the ball.
Hafeez is only the sixth player ever in international cricket to be given out for obstructing the field.
Pakistan, chasing 235 to win at Kingsmead, stuttered to 33-3 before a 153-run stand between captain Misbah-ul-Haq (80) and opener Imran Farhat (93) laid the platform for victory.
"It was a much-needed victory for us, everybody put in 100 percent. It was a combined effort. You dream of a start like we got with the ball, all of the bowlers bowled well," Misbah said.
The decider is in Benoni on Sunday with Pakistan holding the chance of ending their nightmare tour with a series win.
South Africa lost two wickets with the first two balls of their innings after winning the toss and electing to bat, a disastrous start in which Hashim Amla was caught by the wicketkeeper and Colin Ingram bowled by Mohammad Irfan.
It was a set-back from which they never quite recovered, although AB de Villiers (75) and David Miller (67) put on 115 for the fourth wicket to see the home side to a below-par 234 for nine in their 50 overs.
All of the Pakistan bowlers played their part in restricting the runs, with the pick being Saeed Ajmal (three for 42), Junaid Khan (three for 45) and Mohammad Irfan (three for 46).
"I thought we fought back well with the bat, but we came up 20 runs short. They bowled really well in the first 10 overs again," said South Africa captain de Villiers.
"We then lost our way in the field, we just didn't put on the pressure for long enough."
Pakistan were in early trouble in their reply but recovered with a Kingsmead one-day international record stand for the fourth wicket by Misbah and Farhat.
Both departed before the end and despite a scare when Shahid Afridi and Wahab Riaz lost their wickets, Pakistan coasted home with eight balls to spare.