Spinner Akila Dananjaya took two key wickets as Sri Lanka beat the Proteas by 14 runs in the first of three ODIs on Thursday.
Opening batsman Avishka Fernando first hit an attacking 118 to set up a morale-boosting victory.
The hosts scored 300-9 from their 50 overs after electing to bat first in Colombo, with Fernando scoring his third ODI century.
South Africa fell short on 286-6 despite opener Aiden Markram’s 96 off 90 balls and a run-a-ball 59 by Rassie van der Dussen.
Markram put on 106 runs for the second wicket with skipper Temba Bavuma, who retired hurt on 38, but missed out on a maiden ODI ton.
The Proteas’ chase looked on track at 155-1 after 28 overs when Bavuma walked off the field due to a hand injury suffered by a throw from a Sri Lanka fielder.
Left-arm spinner Praveen Jayawickrama soon sent Markram, who hit five fours and four sixes, trudging back to the pavilion.
Van der Dussen then put up a fight with his ninth ODI half-century as he hit six boundaries before being bowled by spinner Akila Dananjaya.
Wicketkeeper-batsman Heinrich Klaasen hit a valiant 36.
Earlier, Fernando put on key partnerships including a 97-run fourth-wicket stand with Charith Asalanka, who scored 72.
South African spinner Keshav Maharaj returned figures of 2-30 from his 10 overs to check Sri Lanka’s run rate in the middle overs.
Fernando, who put on 79 runs with Dhananjaya de Silva (44) for the third wicket, changed gears after raising his half-century and took the attack to the opposition with the left-handed Asalanka.
The 23-year-old reached his ton with a single, raising his bat and punching the air amid a standing ovation from the Sri Lanka dressing room.
Fernando finally fell to Tabraiz Shamsi’s left-arm wrist-spin, having hit 10 fours and two sixes in his 115-ball knock.
Kagiso Rabada got Asalanka caught behind after the batsman’s second ODI half-century in his sixth match. Rabada took two wickets.
The second ODI is on Saturday with all the matches to be played behind closed doors at the same venue.
© Agence France-Presse