So, while the FilledCurve is automatically closing the curve, the individual BSplineCurves themselves aren't actually closed. Yes, you've duplicated the origin point, but the behavior is still different if you set the SplineClosed option to True or False. And so, the FilledCurve is doing its thing, creating "closures" between adjacent curves, but the final "closure" doesn't work as a spline closure. Or at least that's my intuition of what's going on. What I would do is to manipulate the points themselves and make one big spline curve.
rotationCount = 30;
splinepts = {{0, 0}, {1, 1}, {3, -7}, {3, 1}, {0, 0}};
mandalapts =
Catenate[
Table[RotationTransform[i*2 \[Pi]/rotationCount][splinepts], {i,
rotationCount}]];
mandalacurve = BSplineCurve[mandalapts, SplineClosed -> True];
Graphics[{EdgeForm[Black], FaceForm[Yellow],
FilledCurve[mandalacurve]}]

It's important that SplineClosed be True (default is False) so that the first and last points ({0,0}) get "doubled up" like all the others.