tl;dr: The cycles of group1 and group2 should not involve the same values. The simplest way to obtain a direct product is to use the function FiniteGroupData with the syntax
FiniteGroupData[ { "DirectProduct", { $group_1$, $group_2$, ...} }, "PermutationGroupRepresentation"]
From the examples
The issue can be found by noticing that $Z_2 \times Z_4$ can be represented as AbelianGroup[{2, 4}], and by comparing the group elements
GroupElements@AbelianGroup[{2, 4}] (* {Cycles[{}], Cycles[{{3, 4, 5, 6}}], Cycles[{{3, 5}, {4, 6}}], Cycles[{{3, 6, 5, 4}}], Cycles[{{1, 2}}], Cycles[{{1, 2}, {3, 4, 5, 6}}], Cycles[{{1, 2}, {3, 5}, {4, 6}}], Cycles[{{1, 2}, {3, 6, 5, 4}}]} *)
to those obtained from the PermutationProduct of $Z_2$ and $Z_4$
Flatten@ Outer[PermutationProduct, GroupElements[CyclicGroup[2]], GroupElements[CyclicGroup[4]]] (* {Cycles[{}], Cycles[{{1, 2, 3, 4}}], Cycles[{{1, 3}, {2, 4}}], Cycles[{{1, 4, 3, 2}}], Cycles[{{1, 2}}], Cycles[{{1, 3, 4}}], Cycles[{{1, 4, 2, 3}}], Cycles[{{2, 4, 3}}]} *)
To get the correct elements, we can replace GroupElements[CyclicGroup[4]] by GroupElements[CyclicGroup[4]] /. Thread[Range[4] -> Range[3, 6]],
cycles = Flatten@Outer[PermutationProduct, GroupElements[CyclicGroup[2]], GroupElements[CyclicGroup[4]] /. Thread[Range[4] -> Range[3, 6]]]; cycles === GroupElements[AbelianGroup[{2, 4}]] (* True *)
which has the correct group order
GroupOrder[PermutationGroup[cycles]] (* 8 *)
Generalization
For the direct product of two arbitrary groups, a possible approach could be (see alternative (b) below for a simplest way)
directProduct[group1_, group2_] := With[ {order1 = GroupOrder[group1], order2 = GroupOrder[group2]}, PermutationGroup[Flatten@Outer[PermutationProduct, GroupElements[group1], GroupElements[group2] /. Thread[Range[order2] -> (order1 + Range[order2])]]] ]
For $Z_2 \times Z_4$:
directProduct[CyclicGroup[2], CyclicGroup[4]] % // GroupOrder (* PermutationGroup[{Cycles[{}], Cycles[{{3, 4, 5, 6}}], Cycles[{{3, 5}, {4, 6}}], Cycles[{{3, 6, 5, 4}}], Cycles[{{1, 2}}], Cycles[{{1, 2}, {3, 4, 5, 6}}], Cycles[{{1, 2}, {3, 5}, {4, 6}}], Cycles[{{1, 2}, {3, 6, 5, 4}}]}] *) (* 8 *)
Alternatives
(a) A similar workaround can be applied from the GroupGenerators
directProduct2[group1_, group2_] := PermutationGroup[Join[ GroupGenerators[group1], GroupGenerators[group2] /. Cycles[l_] :> Cycles[l + PermutationMax[group1]] ]]
For $Z_2 \times Z_4$:
directProduct2[CyclicGroup[2], CyclicGroup[4]] % // GroupOrder (* PermutationGroup[{Cycles[{{1, 2}}], Cycles[{{3, 4, 5, 6}}]}] *) (* 8 *)
In both approaches, one should make sure that the cycles of group1 and those of group2 do not involve the same values.
(b) A simpler way to go, equivalent to alternative (a) above in terms of the cycles generated, is to use the function FiniteGroupData
FiniteGroupData[{"DirectProduct", {{"CyclicGroup", 2}, {"CyclicGroup", 4}} }, "PermutationGroupRepresentation"] (* PermutationGroup[{Cycles[{{1, 2}}], Cycles[{{3, 4, 5, 6}}]}] *) FiniteGroupData[{"DirectProduct", {{"AlternatingGroup", 5}, {"CyclicGroup", 2}} }, "PermutationGroupRepresentation"] (* PermutationGroup[{Cycles[{{6, 7}}], Cycles[{{1, 2, 3}}], Cycles[{{1, 2, 3, 4, 5}}]}] *)