Давайте разберем чуть подробнее ваш фрагмент кода и представим гипотетическую ситуацию: у вас на сайте создана 1 отгрузка, а после обмена из вашей системы прилетает 2 новые отгрузки, вместо 1 существовавшей.
Начнем с того что в:
// создаём отгрузки
$shipmentCollection = $orderBx->getShipmentCollection();
Вы получаете коллекцию отгрузок. Коллекция отгрузок представляет из себя набор, состоящий из системной отгрузки + созданных системой или пользователем.
При обработке существующего заказа с одной отгрузкой вам вернется коллекция (объект) с содержимым в 2 отгрузки: системная + ваша.
Далее, вы производите итерацию по пришедшим отгрузкам
foreach (importJson['Shipments'] as $importOrderShipment)
Т.е. получается вам пришло 2 отгрузки и соответственно вы 2 раза зайдете в ваш цикл.
Фрагмент:
$shipment = $shipmentCollection->createItem();
Создаст еще одну отгрузку. Иными словами после выполнения фрагмента в коллекции отгрузок у вас будет уже 4 отгрузки: системная, исходная (которая была на сайте), а так же две новых отгрузки, которые вы создали при итерировании по импортируемым отгрузкам.
В данном случае у вас есть несколько вариантов развития событий:
1) Вы можете очищать коллекцию отгрузок и создавать новые. Событий на изменение заказа у вас будет большое количество, но тем не менее это даст вам больше прозрачности в вашем процессе (не говоря уже о простоте реализации).
2) Добавить маркер и по нему обновлять существующие отгрузки - менять стоимость тип и т.п.
Это будет сложнее, но при этом чище с точки зрения событий в системе.
P.S. И насколько я помню, цена доставки PRICE_DELIVERY из order это вроде как сумма PRICE_DELIVERY (?CUSTOM_PRICE_DELIVERY) из всех не системных отгрузок, так что задавать его бесполезно.