They had earlier looked like cruising to a first Champions League win of the campaign when Ismaily and Taison scored in the space of two first-half minutes in Germany.
Hoffenheim had other ideas, though, pulling one back almost straight away through a fine Andrej Kramaric goal and then drawing level after 40 minutes thanks to Steven Zuber's header.
Adam Szalai was dismissed for Hoffenheim – who can no longer qualify from the group – just before the hour and Taison left it mightily late to secure a vital three points.
Shakhtar could scarcely have wished for a better start, racing into a two-goal lead after just 15 minutes.
Ismaily got them on their way in the 13th minute with a deflected strike from 10 yards after surging onto Taison's pass.
Taison then doubled their advantage, springing the offside trap to collect Moraes' pass and curl past the onrushing Oliver Baumann.
Far from being shell-shocked, Hoffenheim pulled one back just two minutes later. Ishak Belfodil fed Kramaric and the Croatian lofted a wonderful chipped finish over Andriy Pyatov that flew in off the post.
They pulled level five minutes before the interval, Zuber looping a header over Pyatov from 10 yards after a cross had been deflected to him.
Hoffenheim's chances were dealt a blow after 59 minutes when Szalai received his marching orders after picking up a second yellow card in quick succession for a late challenge on Mykola Matviyenko.
Despite their numerical inferiority, Zuber hit the crossbar for the hosts, while Nico Schulz and Reiss Nelson blazed wide.
Taison and Maycon both struck the post late on for Shakhtar, but the former ultimately had the final say, spinning in the area and slotting into Baumann's left-hand corner to set up a decider against Lyon.
What does it mean? Shakhtar leave it late, Hoffenheim bow out
Fonseca's side were less than a minute away from exiting the Champions League before Taison's last-gasp intervention. They are just two points behind Lyon now and know that a second win on the spin will see them join Manchester City in the last 16. Hoffenheim, meanwhile, will rue a series of missed chances in the closing stages as their wait for a first ever Champions League win goes on.
Taison packs a punch
The Brazilian enjoyed a near-perfect game. He expertly teed up Ismaily for Shakhtar's opener and then twice showed outstanding composure to ensure his side left Germany with all three points.
Szalai red proves costly
The powerful Hungarian had caused problems all game for the Shakhtar backline, but his exuberance got the better of him when he lunged in on Matviyenko, delivering a critical blow to his side's hopes of claiming the points.
Key Opta Facts
- Both Hoffenheim (10 scored, 12 conceded) and Shakhtar Donetsk's (seven scored, 15 conceded) Champions League games in 2018-19 have seen 22 goals; more than any other side in the competition.
- There were just 221 seconds between Ismaily scoring the opener for Shakhtar Donetsk, Taison doubling the Ukrainian side's lead and Andrej Kramaric pulling one goal back for Hoffenheim.
- Hoffenheim have both scored and conceded in all 13 of their games in European competitions (including qualifiers).
- Taison's winning goal for Shaktar was the 81st scored by a Brazilian player for the club in the Champions League (excluding own goals) – only Barcelona (83) have had more.
- There were just 72 seconds between Hoffenheim’s Adam Szalai's first and second yellow cards in this match.