Kusal Perera scored 51 in the first innings to lift Sri Lanka to 191.
South Africa were cruising in the second innings but lost 5 for 8 to fold for 259. Lasith Embuldeniya bagged a maiden five-wicket haul in his debut Test.
Vishwa Fernando's four wickets in the second game were also instrumental in the South Africa collapse.
Kusal Perera and Dhananjaya de Silva scored 96 for the sixth wicket to help Sri Lanka get close.
Perera struck a ton to bring the deficit below 50.
Fernando and Perera scored 78 for the last wickets in Sri Lanka's win.
Perera scored 153 off 200 as Sri Lanka sealed a dramatic one-wicket win.