키움 OpenAPI 로그인 에러 -100, -106 뜨는 이유 (feat. 코드 문제가 아님)

봇을 만들면서 제일 먼저 넘어야 할 벽은 의외로 단순했다. 로그인이었다.

 

키움 OpenAPI 로그인 실패 로그가 반복해서 찍힌 화면

주문 로직이니 전략이니 하는 건 그다음 문제였다. 일단 키움 서버에 붙어야 뭐라도 할 수 있는데, 나는 그 첫 단추에서 한참을 헤맸다. 로그인 창은 떴다가 안 떴다가 했고, 어느 순간부터는 -100-106이라는 숫자만 계속 찍혔다. 그날 새벽 로그를 다시 열어보니, 네 시 반부터 봇을 껐다 켰다 한 흔적이 열 번도 넘게 찍혀 있었다.

목차

붙긴 붙었는데, 됐는지를 모르겠다

처음 겪은 이상함은 에러도 아니었다. 로그인 창은 떴다. 아이디도 들어갔다. 그런데 코드는 이미 저만치 앞서가 있었다.

AI가 짜준 코드는 로그인 요청을 보내는 줄 바로 다음에, 계좌번호를 읽어오는 줄이 있었다. 언뜻 보면 멀쩡하다. 그런데 돌려보면 계좌번호가 비어 있다. 로그인이 아직 끝나지도 않았는데, 코드가 그걸 기다리지 않고 다음 줄로 넘어가버린 것이다.

원인은 로그인 요청을 보내는 함수(CommConnect)에 있었다. 나중에 알고 보니 이 함수는 로그인 창을 띄우기만 하고, 로그인이 끝날 때까지 기다려주지 않는다. 요청만 던지고 바로 반환해버린다. 실제 결과는 한참 뒤에 OnEventConnect라는 별도의 신호로 돌아온다. 그러니 내 코드는 로그인이 성공했는지 실패했는지도 모르는 채 그냥 다음 줄을 실행하고 있었던 것이다.

이걸 몰랐을 때가 제일 이상했다. 터미널에서 돌리면 로그인이 된 건지 안 된 건지조차 알 수 없었다. 창은 떴는데 프로그램은 이미 저 혼자 앞서가서 엉뚱한 값을 물고 있으니, 나는 성공도 실패도 아닌 애매한 상태로 화면만 들여다보곤 했다.

결국 나는 로그인이 끝났다는 신호가 올 때까지 코드를 붙잡아두기로 했다. 로그인 요청을 보낸 다음, OnEventConnect로 성공·실패 결과가 실제로 도착할 때까지 대기하도록 이벤트 루프를 하나 걸어줬다. 그제서야 코드가 순서대로 움직였다. 로그인이 끝나야 계좌번호를 읽고, 그다음 단계로 넘어갔다.

초보가 짠 코드나 AI가 뱉은 코드가 로그인에서 유독 이상하게 구는 건, 대부분 이 대기 처리가 빠져 있어서다.

로그인은 됐다가, 안 됐다가

순서 문제를 잡고 나니, 이번엔 로그인 자체가 됐다 안 됐다 했다. 처음 몇 번은 됐다. 로그인 요청을 보내면 이십 초쯤 뒤에 성공 메시지가 떴다.

🔑 로그인 요청
✅ 로그인 성공

그런데 어느 순간부터 안 됐다. 같은 코드인데, 같은 방식인데, 갑자기 실패가 찍히기 시작했다.

❌ 로그인 실패: -100
🏦 계좌번호 인식: None
❌ 로그인 실패: -106

나는 이 숫자들이 뭔지도 몰랐다. -100은 뭐고 -106은 뭔가. 그냥 빨간 X만 계속 떴다. 로그인이 안 되니 계좌번호도 None으로 읽혔다. 당연했다. 접속이 안 됐으니 계좌를 읽어올 리가.

그래서 -100과 -106이 뭐였나

나중에 키움 OpenAPI+ 개발가이드의 에러코드 표를 찾아보고서야 알았다.

-100은 "사용자정보교환 실패"였다. 로그인 인증 과정에서 서버와 정보를 주고받는 데 실패했다는 뜻이다. -106은 "통신연결 종료"였다. 서버와의 연결이 끊겼다는 의미다.

둘 다 공통점이 있었다. 내 코드의 문제가 아니라 서버·연결 쪽 문제라는 것. 로그인 로직을 아무리 뜯어봐도 안 나오던 이유가 여기 있었다. 애초에 코드에서 고칠 게 아니었던 것이다.

혹시 지금 이 글을 -100이나 -106 에러로 새벽에 검색해서 들어온 사람이 있다면, 이 말을 해주고 싶다. 일단 코드부터 의심하지 마라. 이 두 코드는 서버 상태나 연결 문제일 가능성이 크다. 키움 서버 점검 시간대(보통 새벽)는 아닌지, 인터넷 연결이나 방화벽 문제는 없는지부터 확인하는 게 빠르다.

껐다 켜니까 됐다

한참을 시도하다, 봇을 완전히 껐다가 다시 켜니 갑자기 풀렸다.

✅ 로그인 성공
🏦 계좌번호 인식: **********

허무했다. 그 새벽 내내 코드를 노려보던 시간이 무색하게, 재접속 한 번에 해결됐다.

이때 나는 하나를 배웠다. OpenAPI+는 내 코드가 완벽해도 그냥 안 될 때가 있다. 그래서 지금 내 봇은 로그인이 실패하면 무작정 멈추는 게 아니라, 잠깐 기다렸다가 다시 접속을 시도하도록 만들어뒀다. 새벽에 나처럼 손으로 껐다 켰다 하지 않으려면, 이 재시도 로직은 처음부터 넣어두는 게 좋다.

로그인이 끝이 아니었다

겨우 로그인을 뚫었더니, 이번엔 다른 벽이 기다리고 있었다. 예수금을 조회하는데 자꾸 응답이 안 왔다.

📨 opw00001 CommRqData ret=-202
⏳ 예수금 응답 타임아웃(5초) → 1회 재요청

찾아보니 -202는 "전문작성 입력값 오류"였다. 조회를 요청할 때 넘기는 입력값에 문제가 있다는 뜻이다.

나는 계좌 비밀번호를 그대로 넘기고 있었다. 그런데 개발가이드를 열어보니 opw00001의 비밀번호 항목은 "사용안함(공백)"으로 되어 있었다. 이 조회는 애초에 비밀번호를 받지 않는 것이다. 모의투자든 실계좌든 마찬가지였다.

헷갈리기 쉬운 지점이 있다. 계좌 비밀번호를 미리 저장해두는 창이 따로 있고, 거기서는 모의투자 계좌에 0000을 넣는다. 나는 그 값을 조회 요청 인자로도 넘겨야 하는 줄 알았다. 그게 착각이었다.

같은 에러로 헤매는 사람이 있다면, opw00001을 부를 때 비밀번호 자리는 공백으로 넘겨보길 권한다. 내 환경에서는 0000을 넣었을 때 -202가 계속 떴고, 공백으로 바꾸자 바로 해결됐다.

그래도 나는 이때 타임아웃 처리와 재요청 로직을 넣어두길 잘했다고 생각했다. 응답이 5초 안에 안 오면 무한정 기다리는 게 아니라, 끊고 한 번 더 요청하게 해둔 것이다. 이게 없었다면 봇은 그냥 멈춰서 아무것도 못 했을 것이다.

그날 새벽에 배운 것

로그인은 그냥 "붙었다/안 붙었다"의 문제가 아니었다. 코드가 로그인 완료를 기다리지 않아서 순서가 꼬이기도 하고, 붙었어도 그다음이 안 될 수 있고, 안 붙어도 다시 켜면 될 수 있다. 그리고 에러코드를 모르면 엉뚱한 데서 시간을 날린다. -100과 -106을 코드 문제로 착각하고 로직만 파던 그 새벽처럼.

그래서 나는 이때부터 두 가지를 습관으로 만들었다. 하나는 모든 단계를 로그로 남기는 것. 로그인 성공 여부, 계좌번호를 읽었는지, 조회 요청에 응답이 왔는지. 다른 하나는 에러코드가 뜨면 일단 개발가이드 표부터 찾아보는 것. 숫자 하나에 원인이 다 적혀 있는데, 나는 그걸 모르고 새벽을 태웠다.

지금 이 글도 그때 남긴 로그 덕분에 쓰고 있다. 기억은 안 나도, 로그는 남아 있으니까.

Post a Comment

다음 이전