Skip to content
isdnetworks
Go back

상대가 실제로 보내는 것을 재서 고정했다

배송 추적 연동을 문서대로 만들었는데 실제 응답이 다르게 왔다.

Table of contents

Open Table of contents

문서와 실제가 달랐다

문서에는 result 가 대문자 YN 으로 오고 regDate 가 구분자 있는 형식으로 온다고 적혀 있었다. log_message 로 응답을 통째로 남겨 실제를 봤다.

{"result":"y","status":"41","statusName":"배송완료","regDate":"20150407103022"}

세 가지가 달랐다. result 가 소문자로 왔다. regDate 에 구분자가 없었다. 어떤 응답에는 statusName 이 아예 없었다. 상대에게 알렸지만 고쳐 주는 데 시간이 걸린다고 해서 우리 쪽에서 다뤄야 했다.

실제를 기준으로 고쳤다

strtolower 로 대소문자를 안 가리게 했다. 날짜는 preg_match 로 두 형식을 갈라 받는다. 문서 형식으로 바뀔 수도 있으니 둘 다 두는 것이 맞았다.

$raw = $res['regDate'] ?? '';
if (preg_match('/^\d{14}$/', $raw)) {
    $dt = DateTime::createFromFormat('YmdHis', $raw);
} elseif (preg_match('/^\d{4}-\d{2}-\d{2} /', $raw)) {
    $dt = DateTime::createFromFormat('Y-m-d H:i:s', $raw);
} else {
    log_message('error', '알 수 없는 날짜 형식: ' . $raw);
    $dt = null;
}

모르는 형식이 오면 log_message 에 남기고 null 로 둔다. 조용히 오늘 날짜로 채우지 않았다. 채우면 그 자리에서는 넘어가지만 나중에 이상한 날짜를 보고 원인을 못 찾는다.

DateTime::createFromFormat 자체에도 조용히 채우는 성질이 있다. 형식에 시분초가 없으면 그 자리를 현재 시각으로 메운다. 'Ymd''20150407' 을 넘기면 뒤에 지금 시각이 붙는다. 앞에 ! 를 붙여 '!Ymd' 로 줘야 00:00:00 이 된다.

statusName 이 없는 경우에는 status 코드로 우리 표에서 채웠다. 그 표는 상대 문서에서 옮긴 것이라 낡을 수 있다. 모르는 코드가 오면 log_message 에 남기게 했다. 실제로 두 달 뒤 새 코드가 하나 늘었고 그 로그에서 봤다.

받은 것을 그대로 남겼다

파싱한 결과 말고 받은 응답 자체를 저장했다.

$this->db->insert('delivery_log', [
    'invoice' => $invoice,
    'raw' => json_encode($res, JSON_UNESCAPED_UNICODE),
    'reg_date' => date('Y-m-d H:i:s'),
]);

raw 에 원문이 있으니 우리가 잘못 읽은 것인지 상대가 이상하게 준 것인지가 갈린다. JSON_UNESCAPED_UNICODE 를 준 이유는 따로 있다. 한글이 \uXXXX 로 박히면 눈으로 못 본다. 이걸 안 남겼으면 문서와 다르다는 것 자체를 몰랐을 것이다.

바뀌면 알게 하는 장치

한 번 맞춘 것이 나중에 또 바뀔 수 있어서 array_diff 로 응답 항목을 검사하게 했다.

$expected = ['result', 'status', 'regDate'];
$missing = array_diff($expected, array_keys($res));
if ($missing) {
    log_message('error', '응답에 없는 항목: ' . implode(',', $missing));
}
$extra = array_diff(array_keys($res), $expected, ['statusName']);
if ($extra) {
    log_message('info', '응답에 새 항목: ' . implode(',', $extra));
}

없어진 항목과 새로 생긴 항목을 둘 다 봤다. 새 항목이 생기는 것 자체는 문제가 아니지만 나중에 필요할 수 있어서 남겼다.

상대에게 언제 무엇을 알렸는지도 날짜와 함께 적어 뒀다. 나중에 그때 알렸다는 말에 근거가 생기고, 상대가 고쳐 주면 우리 쪽 대응 코드를 뺄지 판단하는 자리가 된다. 실제로는 안 뺐다. 둘 다 받는 쪽이 안전했다.

정리


Share this post on:

Previous Post
고쳤는데 화면이 안 바뀌었다
Next Post
쿠폰이 두 번 쓰였다