외주로 만든 결제 모듈을 넘겨받았다. 소스와 스키마와 설치 문서 셋을 받고 돌아가는 것을 확인한 뒤 거기서 끝냈다. 두 달 뒤 결제가 안 된다는 연락이 왔다.
Table of contents
Open Table of contents
받은 것만 확인했다
코드를 열어 보니 처음 보는 구조였다.
class PayGateway {
private function _makeHash($data) {
return md5($data['mid'] . $data['amt'] . $data['oid'] . SECRET_KEY);
}
}
PayGateway 안의 _makeHash 가 MD5 로 mid 와 amt 와 oid 와 SECRET_KEY 를 이어 붙이는데 왜 그 순서인지가 안 적혀 있었다. 결제사 규격을 따라 만든 것인데 그 규격 문서가 우리에게 없었다. 만든 쪽에 연락했더니 그 사람은 이미 다른 곳으로 옮긴 뒤였다.
없는 것이 무엇인지 적었다
무엇이 없는지부터 목록으로 만들었다. 결제사 연동 규격 문서와 시험 계정과 오류 코드 목록과 만든 사람 연락처와 결제사 담당자 연락처 다섯이었다.
결제사에 직접 연락해 규격 문서 PDF 를 받고 시험 계정도 다시 만들었다. 받은 것은 docs/ 아래에 넣어 svn 으로 함께 관리했다. 밖에 있는 문서는 없어지고 없어진 것을 나중에 알게 된다.
결제사 담당자 ...
규격 문서 docs/pg-spec-2015-01.pdf
시험 계정 별도 관리 (문서에는 위치만 적는다)
오류 코드 docs/pg-error-codes.md
규격을 보면서 코드를 읽었다
문서가 생기고 나서 코드를 처음부터 읽었다. 왜 이렇게 돼 있는지를 규격서 절 번호와 함께 주석으로 적었다.
/* 결제 요청 해시
규격서 3.2 절: MID + 금액 + 주문번호 + 상점키를 이어 붙여 MD5.
순서가 바뀌면 검증에 실패한다. */
private function _makeHash($data) { ... }
읽다가 이상한 것도 나왔다. 결제 응답을 검증하지 않고 완료 처리하고 있었다.
if ($_POST['resultCode'] === '0000') {
$this->order->complete($orderNo);
}
$_POST 로 온 resultCode 만 보고 있으니 결제사가 보낸 것인지 확인하지 않는 것이다. 누구든 그 주소로 요청을 보내면 주문이 완료된다.
규격서에 응답에도 해시가 함께 온다고 적혀 있었다. 그 값을 _makeHash 로 다시 계산해 비교하는 검증을 넣었다. 비교는 hash_equals 로 했다 — 한 글자씩 끊어 보는 비교는 걸린 시간으로 어디까지 맞았는지가 새어 나간다. 넘겨받은 코드를 안 읽고 뒀으면 이걸 몰랐을 것이다.
담당과 대리
모듈마다 누가 보는지를 정했다. 담당을 정하니 그 사람이 규격서를 읽었고 정하기 전에는 아무도 안 읽었다. 대리를 함께 둔 것은 한 사람만 알면 그 사람이 없을 때 멈추기 때문이다.
넘겨받은 것이 또 있는지도 찾았다. 문자 발송과 배송 추적 둘이 더 있었고 같은 방식으로 문서를 모아 담당을 정했다. 문자 발송에서도 비슷한 것이 나왔는데 curl_exec 의 반환값을 안 보고 성공으로 처리하고 있었다.
담당을 정하고 나서도 한동안 손대기 어려웠다. 결제 코드를 고쳐도 확인할 방법이 없었기 때문이다. 실제 결제를 해 볼 수는 없고 시험 계정으로 어디까지 되는지도 몰랐다.
결제사에서 시험 환경을 받고 나서 달라졌다. 시험용 카드 번호 몇 개로 승인과 거절과 취소를 다 해 볼 수 있게 되니 그때부터 고칠 수 있었다. 손댈 수 없던 이유가 시험 방법이 없어서인 경우가 많았다.
정리
- 넘겨받을 때 소스와 설치 문서만 받으면 부족하다
- 규격과 시험 계정과 오류 코드와 연락처까지 확인한다
- 만든 사람은 없어진다. 연락처가 유일한 통로면 그것이 끊긴다
- 밖에 있는 문서는 없어지므로
docs/에 넣어svn으로 관리한다 - 규격을 보면서 코드를 읽으면 이상한 것이 나온다
$_POST의resultCode만 보고 완료 처리하는 자리가 있을 수 있다- 응답 해시를
_makeHash로 다시 계산하고hash_equals로 비교한다 - 누가 볼지 정한다. 정하지 않으면 아무도 안 읽는다
- 한 사람만 알면 그 사람이 없을 때 멈추므로 대리를 둔다
- 손댈 수 없는 코드는 시험 방법이 없어서인 경우가 많다