WMS/물류시스템 택배API 연동
창고관리시스템과 배송 상태를 실시간 동기화하세요
WMS에 택배API를 연동하면
- 10개 택배사 통합 - 택배사별 연동 없이 하나의 API로 모든 택배사 조회
- 실시간 상태 동기화 - 배송 상태 변경 시 WMS 자동 업데이트
- 출고 확인 자동화 - 택배사 인수 확인 후 출고 완료 처리
- 반품/교환 추적 - 반송 배송도 동일하게 추적 가능
시스템 아키텍처
데이터 흐름
WMS
출고 요청
→ 출고 요청
택배사
집하/배송
→ 집하/배송
DeliveryAPI
상태 조회
→ 상태 조회
웹훅
상태 알림
→ 상태 알림
WMS
상태 업데이트
상태 업데이트
구현 시나리오
시나리오 1: 출고 후 배송 상태 추적
상품 출고 시 송장번호를 등록하고, 이후 배송 상태를 자동으로 추적합니다.
1 출고 시 송장번호 저장
// WMS에서 출고 처리 시
async function processShipment(orderId, courier, trackingNumber) {
// 1. WMS DB에 송장 정보 저장
await Shipment.create({
orderId,
courier,
trackingNumber,
status: 'shipped',
shippedAt: new Date()
});
// 2. 웹훅 구독 등록 (선택)
await subscribeTracking(courier, trackingNumber);
} 2 배송 상태 조회 (Polling)
// 정기적으로 배송 상태 조회 (예: 1시간마다)
async function syncDeliveryStatus() {
// 배송중인 모든 출고 건 조회
const shipments = await Shipment.findAll({
where: { status: ['shipped', 'in_transit'] }
});
for (const shipment of shipments) {
try {
const result = await deliveryApi.track(
shipment.courier,
shipment.trackingNumber
);
// 상태 업데이트
await shipment.update({
status: mapStatus(result.data.deliveryStatus),
lastLocation: result.data.progresses?.[0]?.location,
updatedAt: new Date()
});
// 배송 완료 시 추가 처리
if (result.data.isDelivered) {
await completeDelivery(shipment);
}
} catch (error) {
console.error(`조회 실패: ${shipment.trackingNumber}`, error);
}
}
} 3 웹훅으로 실시간 수신 (권장)
// 웹훅 엔드포인트
app.post('/webhook/delivery', async (req, res) => {
const { event, items } = req.body;
// 서명 검증
if (!verifySignature(req)) {
return res.status(401).json({ error: 'Invalid signature' });
}
for (const item of items) {
const shipment = await Shipment.findOne({
where: { trackingNumber: item.trackingNumber }
});
if (!shipment) continue;
switch (event) {
case 'tracking.polled':
await shipment.update({
status: mapStatus(item.currentStatus),
lastLocation: item.trackingData?.progresses?.[0]?.location
});
break;
case 'tracking.completed':
await completeDelivery(shipment);
break;
}
}
res.json({ received: true });
}); 시나리오 2: 대량 출고 일괄 조회
// 여러 송장번호 한 번에 조회
async function batchTrackShipments(shipments) {
const results = await Promise.allSettled(
shipments.map(s =>
deliveryApi.track(s.courier, s.trackingNumber)
)
);
return results.map((result, index) => ({
trackingNumber: shipments[index].trackingNumber,
success: result.status === 'fulfilled',
data: result.status === 'fulfilled' ? result.value.data : null,
error: result.status === 'rejected' ? result.reason.message : null
}));
}
// 사용 예시 - 1000건 출고 건 일괄 조회
const shipments = await Shipment.findAll({
where: { status: 'shipped' },
limit: 1000
});
const results = await batchTrackShipments(shipments);
console.log(`성공: ${results.filter(r => r.success).length}건`); 상태 매핑
DeliveryAPI 상태값을 WMS 상태로 매핑합니다.
| DeliveryAPI 상태 | 설명 | WMS 상태 (예시) |
|---|---|---|
PENDING | 접수 | 출고완료 |
PICKED_UP | 집하 완료 | 택배사 인수 |
IN_TRANSIT | 배송중 | 배송중 |
OUT_FOR_DELIVERY | 배송 출발 | 배송중 |
DELIVERED | 배송 완료 | 배송완료 |
function mapStatus(apiStatus) {
const statusMap = {
'PENDING': 'SHIPPED',
'PICKED_UP': 'CARRIER_RECEIVED',
'IN_TRANSIT': 'IN_TRANSIT',
'OUT_FOR_DELIVERY': 'IN_TRANSIT',
'DELIVERED': 'DELIVERED',
};
return statusMap[apiStatus] || 'UNKNOWN';
} 반품/교환 배송 추적
// 반품 접수 시 반송 추적 시작
async function processReturn(returnId, courier, trackingNumber) {
await Return.update(
{
returnCourier: courier,
returnTrackingNumber: trackingNumber,
returnStatus: 'return_shipped'
},
{ where: { id: returnId } }
);
// 반송 배송도 동일하게 추적
// 배송 완료 = 창고 입고
}
// 반송 완료 시 재고 복원
async function handleReturnDelivered(trackingNumber) {
const returnOrder = await Return.findOne({
where: { returnTrackingNumber: trackingNumber }
});
if (returnOrder) {
// 재고 복원
await Inventory.increment('quantity', {
where: { productId: returnOrder.productId }
});
// 상태 업데이트
await returnOrder.update({ returnStatus: 'returned' });
}
} 예상 효과
- 운영 효율 50% 향상 - 수동 상태 확인 작업 제거
- 실시간 재고 정확도 - 배송/반품 상태 기반 재고 관리
- 고객 문의 감소 - 정확한 배송 정보 제공
- 개발 비용 절감 - 택배사별 연동 불필요