Match ends, Borussia Dortmund 4, SV Werder Bremen 3.
Defender Marc Bartra returned to action for the first time since being injured in the attack on Borussia Dortmund's team bus as his side gained entry to the Champions League group stage.
Bartra, 26, had surgery on his right hand and wrist after the blast before a Champions League tie with Monaco.
He played 90 minutes as Dortmund edged Werder Bremen 4-3 to beat Hoffenheim to third place in the Bundesliga.
Hamburg avoided a relegation play-off with a late win over Wolfsburg.
Bartra makes Dortmund return
Spain centre-back Bartra, who joined Dortmund from Barcelona last June, was the only player to receive serious injuries in the blast on April 11.
Three devices containing pieces of metal exploded shortly after Dortmund left their hotel to travel to the home leg of their quarter-final tie against the Ligue 1 side.
Police in Germany have charged a man suspected of being behind the attack. Prosecutors say he was a market trader hoping to make money if the price of shares in the team fell.
Aubameyang seals third place - and top scorer prize
Dortmund started the final day of the Bundesliga season level on points with fourth-placed Hoffenheim, knowing a victory against eighth-placed Bremen would seal third because of their superior goal difference.
They secured the three points - but it required an 89th-minute penalty from top scorer Pierre-Emerick Aubameyang to defeat an away side that had led twice.
Aubameyang, who also scored a spectacular volley to put Dortmund 2-1 ahead, was crowned the Bundesliga's top scorer after taking his tally to 31 goals for the season.
Marco Reus also netted twice as Bremen, who scored through Zlatko Junuzovic, Fin Bartels and Max Kruse, missed out on European qualification.
Hoffenheim drew 0-0 against Augsburg and will go forward to the Champions League play-offs in order to gain entry to the group stage.
Birthday boy scores to save Hamburg
Hamburg are the only club to have never been relegated from the Bundesliga since the league was founded in 1963 - and they made sure that run continued with a dramatic 2-1 win against relegation rivals Wolfsburg.
Hamburg started the final day of the season fourth bottom, knowing they had to beat Wolfsburg - the team directly above them - to avoid a two-legged play-off against the side that finishes third in Bundesliga II.
Wolfsburg took the lead on a tense afternoon when Robin Knoche headed in after 23 minutes, before Filip Kostic fired in Hamburg's equaliser nine minutes later.
The home side knew they needed a winner to survive and it eventually arrived when substitute Luca Waldschmidt - on his 21st birthday - kept them up with his first goal of the season.
It sparked ecstatic scenes in the Volksparkstadion, with thousands of Hamburg fans pouring onto the pitch to celebrate at the final whistle.
- 25PapastathopoulosBooked at 11mins
- 8SahinBooked at 62minsSubstituted forCastroat 72'minutes
- 37DurmSubstituted forPulisicat 45'minutes
- 7DembéléBooked at 61minsSubstituted forBenderat 90+3'minutes
- 23KagawaBooked at 87mins
- 13Jose Guerreiro
- 13VeljkovicBooked at 90mins
- 26SanéSubstituted forEggesteinat 86'minutes
- 23Gebre SelassieSubstituted forGnabryat 45'minutes
- 27GrillitschSubstituted forBargfredeat 72'minutesBooked at 88mins
- 22BartelsBooked at 58mins
- Günter Perl
- Shots on Target
Second Half ends, Borussia Dortmund 4, SV Werder Bremen 3.
Raphael Guerreiro (Borussia Dortmund) wins a free kick in the defensive half.
Foul by Fin Bartels (SV Werder Bremen).
Substitution, Borussia Dortmund. Sven Bender replaces Ousmane Dembélé.
Milos Veljkovic (SV Werder Bremen) is shown the yellow card for a bad foul.
Pierre-Emerick Aubameyang (Borussia Dortmund) wins a free kick in the defensive half.
Foul by Milos Veljkovic (SV Werder Bremen).
Attempt saved. Thomas Delaney (SV Werder Bremen) header from the left side of the box is saved in the top left corner. Assisted by Zlatko Junuzovic.
Foul by Marc Bartra (Borussia Dortmund).
Thomas Delaney (SV Werder Bremen) wins a free kick on the right wing.
Goal! Borussia Dortmund 4, SV Werder Bremen 3. Pierre-Emerick Aubameyang (Borussia Dortmund) converts the penalty with a right footed shot to the bottom left corner.
Philipp Bargfrede (SV Werder Bremen) is shown the yellow card for a bad foul.
Penalty Borussia Dortmund. Christian Pulisic draws a foul in the penalty area.
Penalty conceded by Philipp Bargfrede (SV Werder Bremen) after a foul in the penalty area.
Shinji Kagawa (Borussia Dortmund) is shown the yellow card for a bad foul.
Foul by Shinji Kagawa (Borussia Dortmund).
Fin Bartels (SV Werder Bremen) wins a free kick in the attacking half.
Substitution, SV Werder Bremen. Maximilian Eggestein replaces Lamine Sané because of an injury.
Foul by Sokratis (Borussia Dortmund).