The Proteas scored 145-6 after electing to bat and then restricted Sri Lanka to 123-7 on a wind-swept evening. Earlier, some aggressive batting by JP Duminy and David Miller steered South Africa to a challenging total.
Duminy scored 30 off 23 balls and Miller hit a 21-ball 36 after the tourists, who elected to bat after winning the toss, were reduced to 48-3 in the ninth over.
South Africa needed a win to wrap up the three-match series, having won the first game by 12 runs in Colombo on Friday.
The tourists were unchanged for the second game, while Sri Lanka brought in Mahela Jayawardene and Nuwan Kulasekara in place of Tillakaratne Dilshan and Jeevan Mendis.
Seamer Kulasekara finished with two for 22, while Sachithra Senanayake claimed two for 18 in four steady overs of off-spin bowling despite the windy conditions. Opener Quinton de Kock scored 19 and star batsman AB de Villiers was run out after making 15.