The tourists, restricted to a modest 115 for six after electing to bat, bounced back to stop Sri Lanka at 103 for nine in front of a packed house of 30,000 at the Premadasa Stadium.
Duminy top-scored with 51 off 52 balls to help South Africa recover from a poor start and then grabbed three wickets for 18 runs, earning himself the man-of-the-match award.
It was a morale-boosting win for South Africa over the world's top-ranked Twenty20 side following an embarrassing 4-1 defeat in a one-day series.
Kumar Sangakkara put up a fight for the hosts with an unbeaten 59 off 53 balls, but the young opener Kusal Perera (11) was the only other batsman to reach double figures.
With 21 runs needed off the last two overs and three wickets in hand, the left-arm seamer Wayne Parnell swung the game South Africa's way by removing Sachithra Senanayake and Lasith Malinga without conceding a run in the penultimate over.
Sangakkara hit two boundaries in Morne Morkel's final over, but it was not enough to carry his team to victory. Morkel and Parnell finished with two wickets each.
South Africa's Twenty20 captain, Faf du Plessis, was delighted by his team's win.
"I am very chuffed and so proud of the boys," he said. "We were under pressure after the one-day series, but the team showed great character tonight.
"The wicket was not easy to bat on, so I thought ours could be a good total. I told the boys that if we kept fighting, we could pull it off."
India could make it 5-0 on Saturday
Parvez Rasool, the Jammu and Kashmir all-rounder, could make his India debut in the fifth and final ODI against Zimbabwe in Bulawayo on Saturday.
The tourists lead the series 4-0. Rasool, a right-handed batsman and off-spinner, could become the first player from the northern Indian state to play for his country.
Second day of Canada v UAE match delayed
Action on the second day of the ICC Intercontinental match between the hosts Canada and the UAE was delayed due to a wet outfield. The opening day of the four-day match was washed out on Thursday because the ground at King City could not be dried out in time.
Follow us @SprtNationalUAE