Skip to main content

Службы доставки

Интеграция с курьерскими службами и логистическими провайдерами для автоматизации доставки.

Российские службы доставки

СДЭК

Одна из крупнейших курьерских служб России с развитой сетью пунктов выдачи.

Настройка СДЭК

interface CDEKConfig {
account: string;
secure_password: string;
test_mode: boolean;
api_url: string;
webhook_url?: string;
}

Расчет стоимости доставки

const calculateCDEKShipping = async (params: ShippingParams) => {
const requestData = {
version: '1.0',
dateExecute: new Date().toISOString(),
authLogin: account,
authPassword: securePassword,
senderCityId: params.fromCityId,
receiverCityId: params.toCityId,
tariffId: params.tariffId,
goods: params.items.map(item => ({
weight: item.weight,
length: item.length,
width: item.width,
height: item.height
}))
};

const response = await fetch(`${apiUrl}/calculator/calculate_price_by_json.php`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(requestData)
});

return await response.json();
};

Создание заказа СДЭК

const createCDEKOrder = async (orderData: CDEKOrderData) => {
const order = {
Number: orderData.orderNumber,
SendCityCode: orderData.fromCityCode,
RecCityCode: orderData.toCityCode,
TariffTypeCode: orderData.tariffCode,
RecipientName: orderData.recipient.name,
RecipientEmail: orderData.recipient.email,
Phone: orderData.recipient.phone,
Address: {
Street: orderData.address.street,
House: orderData.address.house,
Flat: orderData.address.flat
},
Package: orderData.packages.map(pkg => ({
Number: pkg.number,
BarCode: pkg.barcode,
Weight: pkg.weight,
SizeA: pkg.length,
SizeB: pkg.width,
SizeC: pkg.height,
Item: pkg.items.map(item => ({
WareKey: item.sku,
Cost: item.cost,
Payment: item.payment,
Weight: item.weight,
Amount: item.quantity,
Comment: item.description
}))
}))
};

const response = await fetch(`${apiUrl}/new_orders.php`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(order)
});

return await response.json();
};

Почта России

Государственная почтовая служба с широкой географией доставки.

Настройка Почты России

interface RussianPostConfig {
login: string;
password: string;
token: string;
test_mode: boolean;
}

Создание отправления

const createRussianPostOrder = async (shipment: PostShipmentData) => {
const order = {
'order-num': shipment.orderNumber,
'mail-type': shipment.mailType,
'mail-category': shipment.mailCategory,
'mass': shipment.weight,
'declared-value': shipment.declaredValue,
'insr-value': shipment.insuranceValue,
'recipient': {
'given-name': shipment.recipient.firstName,
'surname': shipment.recipient.lastName,
'patronymic': shipment.recipient.middleName,
'address': {
'index': shipment.address.postalCode,
'region': shipment.address.region,
'place': shipment.address.city,
'street': shipment.address.street,
'house': shipment.address.house,
'room': shipment.address.apartment
}
},
'dimension': {
'height': shipment.dimensions.height,
'length': shipment.dimensions.length,
'width': shipment.dimensions.width
}
};

const response = await fetch('https://otpravka-api.pochta.ru/1.0/user/backlog', {
method: 'PUT',
headers: {
'Authorization': `AccessToken ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify([order])
});

return await response.json();
};

Boxberry

Сервис доставки с сетью постаматов и пунктов выдачи.

API Boxberry

interface BoxberryConfig {
api_token: string;
api_url: string;
}

const getBoxberryPoints = async (cityCode: string) => {
const response = await fetch(
`${apiUrl}/json.php?token=${apiToken}&method=ListPoints&CityCode=${cityCode}`
);

return await response.json();
};

const calculateBoxberryDelivery = async (params: BoxberryCalcParams) => {
const response = await fetch(
`${apiUrl}/json.php?token=${apiToken}&method=DeliveryCosts` +
`&weight=${params.weight}&size=${params.size}&zip=${params.zip}`
);

return await response.json();
};

Международные службы доставки

DHL Express

interface DHLConfig {
user_id: string;
password: string;
account_number: string;
site_id: string;
api_url: string;
}

const createDHLShipment = async (shipment: DHLShipmentData) => {
const requestData = {
ShipmentRequest: {
RequestedShipment: {
DropoffType: 'REGULAR_PICKUP',
ServiceType: shipment.serviceType,
PackagingType: 'YOUR_PACKAGING',
Shipper: {
Contact: {
PersonName: shipment.shipper.name,
CompanyName: shipment.shipper.company,
PhoneNumber: shipment.shipper.phone
},
Address: shipment.shipper.address
},
Recipient: {
Contact: {
PersonName: shipment.recipient.name,
PhoneNumber: shipment.recipient.phone
},
Address: shipment.recipient.address
},
ShippingChargesPayment: {
PaymentType: 'SENDER'
},
PackageCount: shipment.packages.length,
RequestedPackageLineItems: shipment.packages
}
}
};

const response = await fetch(`${apiUrl}/ship`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Basic ${btoa(`${userId}:${password}`)}`
},
body: JSON.stringify(requestData)
});

return await response.json();
};

FedEx

interface FedExConfig {
key: string;
password: string;
account_number: string;
meter_number: string;
}

const trackFedExPackage = async (trackingNumber: string) => {
const requestData = {
TrackRequest: {
WebAuthenticationDetail: {
UserCredential: {
Key: key,
Password: password
}
},
ClientDetail: {
AccountNumber: accountNumber,
MeterNumber: meterNumber
},
SelectionDetails: [{
PackageIdentifier: {
Type: 'TRACKING_NUMBER_OR_DOORTAG',
Value: trackingNumber
}
}]
}
};

// SOAP запрос к FedEx API
return await makeFedExSOAPRequest('track', requestData);
};

Локальная доставка

Собственная курьерская служба

interface LocalDeliveryConfig {
enabled: boolean;
delivery_zones: DeliveryZone[];
couriers: Courier[];
time_slots: TimeSlot[];
same_day_delivery: boolean;
}

interface DeliveryZone {
id: string;
name: string;
polygon: GeoPolygon;
base_cost: number;
delivery_time: number; // часы
working_hours: WorkingHours;
}

interface Courier {
id: string;
name: string;
phone: string;
vehicle_type: VehicleType;
max_weight: number;
working_zones: string[];
status: CourierStatus;
}

Оптимизация маршрутов

const optimizeDeliveryRoutes = async (orders: DeliveryOrder[]) => {
// Группировка заказов по зонам
const ordersByZone = groupOrdersByZone(orders);

// Назначение курьеров
const assignments = await assignCouriers(ordersByZone);

// Оптимизация маршрутов
const optimizedRoutes = await Promise.all(
assignments.map(assignment =>
optimizeRoute(assignment.courier, assignment.orders)
)
);

return optimizedRoutes;
};

const optimizeRoute = async (courier: Courier, orders: DeliveryOrder[]) => {
// Алгоритм оптимизации маршрута (например, TSP)
const waypoints = orders.map(order => order.delivery_address);
const optimizedOrder = await solveTSP(waypoints);

return {
courier_id: courier.id,
route: optimizedOrder.map(index => orders[index]),
total_distance: optimizedOrder.distance,
estimated_time: optimizedOrder.time
};
};

Управление складами

Мультискладская логистика

interface WarehouseSystem {
warehouses: Warehouse[];
inventory_distribution: InventoryDistribution;
fulfillment_rules: FulfillmentRule[];
}

interface Warehouse {
id: string;
name: string;
address: Address;
coordinates: GeoCoordinates;
capacity: WarehouseCapacity;
working_hours: WorkingHours;
supported_services: ShippingService[];
}

interface FulfillmentRule {
priority: number;
condition: FulfillmentCondition;
warehouse_selection: WarehouseSelection;
}

Выбор оптимального склада

const selectOptimalWarehouse = async (
order: Order,
customerAddress: Address
): Promise<Warehouse> => {
const availableWarehouses = await getWarehousesWithInventory(
order.items.map(item => item.sku)
);

const scoredWarehouses = await Promise.all(
availableWarehouses.map(async warehouse => {
const distance = calculateDistance(warehouse.coordinates, customerAddress);
const shippingCost = await calculateShippingCost(warehouse, customerAddress);
const processingTime = getProcessingTime(warehouse, order);

const score = calculateWarehouseScore({
distance,
shippingCost,
processingTime,
warehouse
});

return { warehouse, score };
})
);

return scoredWarehouses
.sort((a, b) => b.score - a.score)[0]
.warehouse;
};

Отслеживание доставки

Единый интерфейс отслеживания

interface TrackingInfo {
tracking_number: string;
carrier: string;
status: DeliveryStatus;
events: TrackingEvent[];
estimated_delivery: Date;
current_location?: GeoLocation;
}

interface TrackingEvent {
timestamp: Date;
location: string;
description: string;
status_code: string;
}

const trackPackage = async (trackingNumber: string, carrier: string) => {
const trackingAPI = getTrackingAPI(carrier);

try {
const trackingInfo = await trackingAPI.track(trackingNumber);

// Нормализация данных
const normalizedInfo = normalizeTrackingInfo(trackingInfo, carrier);

// Сохранение в БД
await updateTrackingInfo(trackingNumber, normalizedInfo);

// Уведомления клиента
await sendTrackingUpdate(trackingNumber, normalizedInfo);

return normalizedInfo;
} catch (error) {
console.error(`Tracking error for ${carrier}:`, error);
throw new TrackingError(`Failed to track package: ${trackingNumber}`);
}
};

Уведомления о доставке

interface DeliveryNotification {
type: NotificationType;
recipient: string;
message: string;
channels: NotificationChannel[];
}

type NotificationType =
| 'shipped'
| 'in_transit'
| 'out_for_delivery'
| 'delivered'
| 'delayed'
| 'failed_delivery';

const sendDeliveryNotification = async (
trackingNumber: string,
notificationType: NotificationType
) => {
const order = await getOrderByTracking(trackingNumber);
const customer = await getCustomer(order.customer_id);

const message = generateNotificationMessage(notificationType, order);

// Отправка через разные каналы
const notifications = [
sendEmail(customer.email, message),
sendSMS(customer.phone, message.short),
sendPushNotification(customer.id, message)
];

await Promise.allSettled(notifications);

// Запись в историю уведомлений
await logNotification({
order_id: order.id,
type: notificationType,
channels: ['email', 'sms', 'push'],
sent_at: new Date()
});
};

Возвраты и обмены

Процесс возврата

interface ReturnRequest {
id: string;
order_id: string;
items: ReturnItem[];
reason: ReturnReason;
return_method: ReturnMethod;
status: ReturnStatus;
created_at: Date;
}

interface ReturnItem {
product_id: string;
quantity: number;
condition: ItemCondition;
reason: string;
}

type ReturnReason =
| 'defective'
| 'wrong_item'
| 'not_as_described'
| 'changed_mind'
| 'damaged_shipping';

const initiateReturn = async (returnRequest: ReturnRequest) => {
// Валидация возврата
const isValid = await validateReturnRequest(returnRequest);
if (!isValid) {
throw new Error('Return request is not valid');
}

// Генерация обратной доставки
const returnLabel = await generateReturnLabel(returnRequest);

// Создание задачи на возврат
const returnTask = await createReturnTask(returnRequest);

// Уведомление клиента
await sendReturnInstructions(returnRequest, returnLabel);

return {
return_id: returnRequest.id,
return_label: returnLabel,
tracking_number: returnTask.tracking_number
};
};

Аналитика доставки

Метрики доставки

interface DeliveryAnalytics {
delivery_performance: DeliveryPerformance;
cost_analysis: CostAnalysis;
customer_satisfaction: SatisfactionMetrics;
carrier_comparison: CarrierComparison[];
}

interface DeliveryPerformance {
on_time_delivery_rate: number;
average_delivery_time: number;
failed_delivery_rate: number;
return_rate: number;
}

interface CostAnalysis {
average_shipping_cost: number;
cost_per_mile: number;
cost_by_carrier: CarrierCostBreakdown[];
seasonal_variations: SeasonalCostData[];
}

Оптимизация затрат

const optimizeShippingCosts = async () => {
const analytics = await getDeliveryAnalytics();

const recommendations = [
// Анализ производительности перевозчиков
analyzeCarrierPerformance(analytics.carrier_comparison),

// Оптимизация зон доставки
optimizeDeliveryZones(analytics.delivery_performance),

// Анализ упаковки
analyzePackagingEfficiency(analytics.cost_analysis),

// Предложения по улучшению
generateImprovementSuggestions(analytics)
];

return recommendations;
};