I used method below. But I see it does work only for one polyline, but not on full mesh.
To get a plane origin I sum up all boundary vertices and divided by number of them.
Then for normal vector I thought I could do the same by summing up all vertex normals and dividing by number of them.
But this does not produce normal perpendicular planar ngon face.

Before I was using this method:

public static Plane[] GetNgonPlanes(this Mesh mesh)
{
Plane[] p = new Plane[mesh.Ngons.Count];
uint[][] b = mesh.GetNGonsBoundaries(); //extension method
for (int i = 0; i < mesh.Ngons.Count; i++)
{
Vector3f temp = new Vector3f();
for (int j = 0; j < b[i].Length; j++)
temp += mesh.Normals[(int)b[i][j]];
if (b[i].Length > 0)
temp /= b[i].Length;
p[i] = new Plane(mesh.Ngons.GetNgonCenter(i), temp); //Extension method
}
return p;
}

Rhino will calculate mesh face normals for, by way of MeshFaceNormalList.ComputeFaceNormals, which basically does something like this:

public static Vector3d CalculateMeshFaceNormal(Mesh mesh, int faceIndex)
{
var n = Vector3d.Unset;
if (null != mesh && faceIndex >= 0 && faceIndex < mesh.Faces.Count)
{
var face = mesh.Faces[faceIndex];
var a = mesh.Vertices[face.C] - mesh.Vertices[face.A];
var b = mesh.Vertices[face.D] - mesh.Vertices[face.B];
n = Vector3d.CrossProduct(a, b);
n.Unitize();
}
return n;
}

Since Rhino’s ngons are planar, if face normals have already been calculated then just get the normal of one of the ngon’s faces.

Would it work also for triangles polylines if this would look like this?

public static Vector3d CalculateMeshFaceNormal(this Polyline p)
{
var n = Vector3d.Unset;
if (null != p && p.Count-1 > 3)
{
var a = p[1] - p[0];
var b = p[2] - p[1];
n = Vector3d.CrossProduct(a, b);
n.Unitize();
}
return n;
}

public static Vector3d CalculatePolygonNormal(Polyline polyline)
{
var n = Vector3d.Unset;
if (null != polyline && polyline.IsValid && polyline.IsClosed)
{
Plane plane;
var rc = Plane.FitPlaneToPoints(polyline, out plane);
if (rc == PlaneFitResult.Success)
n = plane.Normal;
}
return n;
}

Does Plane.FitPlaneToPoints take into account direction of polyline? For clockwise pointing in one direction and for anticlockwise pointing into opposite?