Kylian Mbappe scored his 50th international goal as France beat Nations League hosts Germany in their third-place play-off.
The captain finished well for the 45th-minute opener following a pass from Real Madrid team-mate Aurelien Tchouameni.
And Mbappe set up the second goal six minutes from time when he pounced on a mistake from Robin Koch and unselfishly squared the ball for Michael Olise to slot into the empty net.
Germany had their chances, though, with both a penalty award and goal overturned by the video assistant referee (VAR).
First Karim Adeyemi was awarded a spot-kick after being brought down by France keeper Mike Maignan, but the Germany forward was instead booked for diving after a VAR check.
And then Deniz Undav’s effort was disallowed after Niclas Fullkrug was deemed to have fouled Adrien Rabiot in the build-up.
Adeyemi also had three shots saved by Chelsea target Maignan, while Florian Wirtz struck a post.
But France could have added to their goal haul in Stuttgart too. Marcus Thuram’s curling strike hit the post, while Mbappe missed the target several times and forced a great save from Marc-Andre ter Stegen.
Julian Nagelsmann’s Germany have now failed to win in three games, including Wednesday’s semi-final defeat by Portugal.
Captain Joshua Kimmich told RTL: “We should have been leading 3-0 after six minutes. Then we went into the break a goal behind.
“We lost patience too early and lost our structure in the second half. We made too many mistakes and gave them what they wanted.”
Les Bleus boss Didier Deschamps added: “Mike [Maignan] was a fantastic last line of defence and he kept us in it at the start.
“I thought the scoreline at half-time against Spain [2-0] was incredibly severe. I’m not going to sit here and lie to you and say that we deserved to go into half-time today in the lead, but it allowed us to go on and become better.”
Spain, who beat France 5-4 in their last-four tie, and Portugal play in the final later on Sunday (20:00 BST) in Munich.