сделайте вардамп $fields после $checkout->get_checkout_fields( 'billing' ); а то не понятно что вы туда получаете, может это вообще ресурс...
PS: добавьте if($_POST["$key"."$i"]) {...} else{var_dump($key);} и все встанет на сво места.
PPS: вообще код конечно кроме того что построен ногами вперед, пестрит как явными ошибками, так и неявными(для новичков) глюками... например
billing_email_dop в итоге становится
billing_emaildop, про пропуски итераций внутри условных операторов я молчу, и как указал
Максим Тимофеев - циклически затираемые данные
Короче классический пример как делать НЕ НАДО.
Как нужно переделать:
1) Нет смысла строить цикл по $fields, вы же четко знаете его структуру, в отличие от данных из $_POST.
2) В цикле по $_POST ищете подходящие по шаблону ключи(например проверка на подстроку billing_email или регулярка billing_email\d{1,2}). Если точно billing_email1 - пишете в $postemail, иначе $postdop[] = $val; По уму на клиенте поля формы должны называться более внятно, например billing_email[], после чего сразу можно получить ВЕСЬ массив емэйлов.
3) в конце если $postdop не пустой - имплодите запятыми значения $postdop, получите вашу строку с емэйлами через запятую.
4) присваиваете все в нужные поля вашего $fields.
5) Profit.