기술 포스트
간편하게 처리하는 비접촉 거래
칩 카드가 얼마나 번거로운지는 다들 아실 겁니다. 카드를 꽂고, 발을 동동 구르며, 차라리 칩이 오작동해서 그냥 긁을 수 있으면 하고 바라게 되죠… 물론, 조금 과장된 표현이긴 합니다. 하지만 무슨 말인지 다들 공감하실 겁니다. 일반적인 접촉식 EMV는 느리고 복잡하며 조금의 실수도 용납하지 않기 때문에, 고객들을 답답하게 만들고 결제 앱 개발자들을 지치게 만들기로 악명이 높습니다.
비접촉 EMV는 이 모든 상황을 바꿔놓습니다. "탭 앤 고" 방식의 거래는 일반적으로 500밀리초도 채 걸리지 않으며, 플라스틱 카드를 꺼내는 것보다 훨씬 편리한 스마트폰으로도 처리할 수 있습니다. 더구나 개발자 입장에서도 훨씬 간편합니다. 단 몇 줄의 코드만으로 비접촉 거래를 실행할 수 있으며, 원한다면 JavaScript만으로도 구현이 가능합니다. Visual Studio나 Xcode를 굳이 열 필요도 없고, 컴파일 과정도, 라이브러리 연결이나 복잡한 의존성 문제도 없습니다. 이야말로 진정한 신속 개발이라 할 수 있죠!
다음 JavaScript 코드 4줄을 살펴보겠습니다.
믿기 어려우시겠지만, 이 4줄의 코드만으로 ID TECH에서 제공하는 소형 저비용 VP3300 시리즈 카드 리더기(위 이미지의 VP3300 포함)를 사용해 비접촉 EMV 거래를 실행할 수 있습니다. 이 4줄이 실행되면 스마트폰(또는 탭 카드)을 리더기에 가져다 대기만 하면 리더기에서 알림음이 울리고 NFC 통신이 시작된 후 USB를 통해 거래 데이터가 출력됩니다.
물론, 이 코드가 실제로 작동하려면 먼저 USB 장치와 통신하는 Node 스크립트(및 Node JS 자체)를 설치해야 합니다. 지난 포스트에서 설명한 바와 같이. (실행 가능한 스크립트와 Node를 하나의 압축 파일로 다운로드하실 수 있습니다. 여기.) 그리고 위 코드는 Firefox 또는 Chrome에서 다음 앱을 통해 실행하시기 바랍니다. 여기서 다운로드.
ViVOpay Explorer란 무엇인가요? JS 콘솔과 사전 로드된 명령어들을 포함한 매우 간단한 HTML 페이지입니다. 이 웹 페이지는 50줄의 HTML과 400줄의 JavaScript로 구성되어 있으며, 여기에는 제가 이전에 소개한 TLV 파서 루틴도 포함되어 있습니다. 이전 포스트). Chrome 또는 Firefox에서 ViVOpay Explorer를 사용할 때(Internet Explorer에서는 사용하지 마십시오), 다음과 유사한 브라우저 페이지가 표시됩니다:
"Console" 아래의 회색 영역은 실시간 REPL (이 경우 jQuery Terminal)로, 임의의 JavaScript 코드를 실시간으로 실행할 수 있습니다. 오른쪽 상단에는 Connect 버튼 옆에 텍스트 입력란("http://localhost" 및 "9901" 표시)이 있습니다. 이 버튼을 누르면 ViVOpay Explorer가 127.0.0.1의 포트 9901에서 Websocket 연결을 검색합니다. 페이지 하단은 로그 영역으로, 명령에 응답하여 다양한 상태 정보(예: USB 트래픽 내역)가 실시간으로 표시됩니다.
드롭다운 메뉴 옆의 작은 물음표를 클릭하면 ViVOpay Explorer 사용 방법을 안내하는 소형 도움말 패널이 열립니다. 간략히 설명하면, 다음과 같이 진행하시면 됩니다:
1. Node driver (11MB Zip 압축 파일)를 다운로드하여 로컬 Windows 머신에 압축을 해제하십시오. (node.exe 사본과 스크립트 및 지원 파일이 포함되어 있으며, 필요한 모든 것이 압축 파일 안에 있습니다. 단, Mac 또는 Linux에서는 실행하지 마십시오. 이는 Windows 전용 Node 빌드입니다.)
2. 압축 해제된 Zip 폴더에서 start.bat 을 실행하십시오. (계속 실행 상태를 유지하고 창을 닫지 마십시오.) 이 파일을 실행하면 USB와 통신하는 Node 기반 드라이버가 시작되고, Websockets 서버도 함께 구동됩니다.
3. ID TECH의 VP3300 시리즈 신용카드 리더기(UniPay III, BTPay Mini 등)를 USB 포트에 연결하십시오. Node 드라이버가 장치를 자동으로 감지하여 연결합니다.
4. Connect 버튼(우측 상단)을 클릭하십시오. 아래에 "Connected to the driver on port 9901."이라는 메시지가 표시되면, 브라우저가 Websockets를 통해 드라이버와 통신 중임을 의미합니다. 통신 주소: http://localhost:9901.
5. Ping reader 명령을 드롭다운 메뉴에서 선택하십시오. 이 명령은 연결된 USB 장치에 핑(ping)을 보내는 스크립트를 실행합니다.
5단계가 성공적으로 완료되면, 메인 화면의 Console 아래에 다음과 같은 응답 로그가 표시됩니다:
OUT:
{
"source":"client"
"data":"5669564f74656368320018010000b3cd"
"type":"raw command"
}
IN:
{
"source":"usb"
"data":"5669564f74656368320018000000fa83″
"type":"data"
}
위의 JSON 메시지는 핑(ping) 과정에서 Websockets를 통해 송신(USB 장치로)되고 수신(브라우저로)된 내용입니다. 이 맞춤형 JSON 객체는 매우 단순한 스키마를 따릅니다. source, data, type 세 가지 필드로 구성되어 있으며, 브라우저에서 드라이버로 전송되는 아웃바운드 메시지의 경우 source 속성값은 "client"이어야 하고, data 필드에는 USB 장치로 전송되는 명령을 나타내는 16진수 문자열이 포함되며, type 필드에는 "raw command"가 입력되어 해당 데이터 명령을 USB 장치로 그대로 전달하도록 드라이버에 알립니다.
브라우저에서 드라이버로 JSON 객체(또는 기타 메시지)를 전송하는 방법은 간단합니다. 브라우저 코드에서 다음과 같이 입력하면 됩니다. socket.emit( 'echo', myObject )드라이버로부터 데이터를 수신하려면 다음과 같이 리스너를 설정하면 됩니다. socket.on( 'message', myListener )여기서 myListener 익명 함수(anonymous function)를 사용할 수도 있습니다. 예를 들면 function( m ) { log( m ); }와 같은 형태입니다. 드라이버로 데이터를 전송하기 전에 리스너를 먼저 설정해야 합니다. 그렇지 않으면 응답을 받을 준비가 되기 전에 드라이버가 먼저 응답할 수 있습니다.
비접촉 결제 트랜잭션 시작 방법: 전략 1
리더기를 NFC 모드로 전환하여 비접촉 카드 또는 모바일 지갑을 읽으려면, 적절한 펌웨어 명령어를 16진수 문자열 형태로 전송하면 됩니다.
첫 번째 줄은 명령어를 문자열로 선언합니다. 이러한 명령어를 구성하는 방법은 해당 리더기의 기술 문서를 참조하시기 바랍니다. (ID TECH 문서는 ID TECH 공개 지식 베이스의 다운로드 페이지에서 다운로드할 수 있습니다.) 이 명령어에는 기본 결제 금액으로 $1.00이 포함되어 있으며 날짜도 현재 기준으로는 유효하지 않습니다. 따라서 이 코드는 동작은 하지만 개념 검증(proof-of-concept) 수준으로만 간주해야 하며, 실제 운영 환경에는 적합하지 않습니다. 운영 코드라면 실제 결제 금액, 정확한 트랜잭션 날짜 등을 반영하여 구성해야 합니다.
명령어를 리더기에 전달하는 과정은 두 단계로 이루어집니다. 먼저 Websockets를 통해 JSON 객체 형태로 드라이버에 전송한 다음, 드라이버가 이를 USB 리더기에 전달합니다. 드라이버가 처리할 수 있는 JSON 객체로 명령어를 패키징하는 것은 매우 간단합니다. 위 코드의 2번째와 3번째 줄을 참조하세요. 4번째 줄은 데이터 객체를 소켓으로 전송합니다.
다시 한번 강조하지만, 이 모든 작업을 수행하기 전에 리더기의 응답을 처리할 수 있도록 소켓에 리스너(또는 콜백)를 먼저 연결해야 합니다. 설정 방법은 다음과 같이 간단합니다.
비접촉 결제 트랜잭션 시작 방법: 전략 2
트랜잭션을 시작하는 두 번째 전략이 있습니다. 앞서 시작 과정이 두 단계로 이루어진다고 설명한 내용을 기억하실 것입니다.
1. 브라우저에서 드라이버로 메시지를 전송합니다.
2. 드라이버에서 USB 장치로 메시지를 전달합니다.
여기서 "메시지"란 길고 복잡한 펌웨어 hex 문자열을 의미합니다.
이 경우 "드라이버"는 Node의 프로세스 공간에서 실행되는 단순한 Node 스크립트(약 350줄의 JavaScript)입니다. 드라이버의 소스 코드는 driver 폴더에 있습니다. 다음 파일을 참조하세요. usb-websocket-shim.js.
드라이버 코드를 손쉽게 수정하여, 트랜잭션을 시작하는 특수 펌웨어 명령(문자열로 미리 캐싱하거나 해당 문자열을 생성하는 함수 형태로)을 드라이버 내부에 포함시킬 수 있습니다. 이렇게 하면 특수 펌웨어 명령을 원하는 API 뒤에 숨길 수 있으며, 결제 앱(여기서는 ViVOpay Explorer)은 트랜잭션을 시작하기 위해 드라이버에 매우 간단한 메시지만 전송하면 됩니다.
그렇게 하는 이유는 무엇인가요? 펌웨어 명령을 드라이버 내부에 숨기는 것이 왜 중요한가요?
몇 가지 타당한 이유를 생각해볼 수 있습니다.
첫째, 장치 의존성을 결제 앱에서 분리하여 장치와 논리적으로 훨씬 가까운 장치 드라이버에 두는 것이 합리적입니다. 생각해보세요. 결제 앱이 펌웨어 명령의 세부 사항까지 알아야 할 필요가 있을까요? 하드웨어에 대한 세부 지식으로부터 앱을 자유롭게 하는 것이 더 낫지 않을까요? 앱은 비즈니스 로직만 알면 되지 않을까요?
둘째, 특수 명령을 드라이버 내부로 이동시키면 해당 명령에 대한 자체 API를 작성할 수 있으며, 결제 앱이 사용할 수 있는 훨씬 단순화된 API를 제공할 기회가 생깁니다. (아래 예시를 참조하세요.)
이 외에도 범위 축소(scope reduction)를 고려할 필요가 있습니다. 실무적으로, 대부분의 결제 앱과 POS 시스템은 POS 또는 결제 앱이 트랜잭션 금액 정도만 트랜잭션 하위 시스템에 제공하는 방식으로 설계됩니다. 그리고 카드 리더기와 통신하는 트랜잭션 하위 시스템은 승인 코드와 영수증 출력 정보만 반환합니다. 민감한 카드 데이터는 결제 앱에 전달되지 않습니다.
따라서 "범위 축소" 방식을 적용할 경우, 드라이버 내부 코드가 다음과 같은 형태로 수신되는 WebSockets 메시지에 응답하도록 구성하는 것이 이상적입니다.
이 기능은 실제로 이미 Node 드라이버에 구현되어 있습니다. (드라이버 코드 목록은 이전 게시물 을 참조하십시오.) 즉, 결제 앱(또는 ViVOpay Explorer)에서 비접촉 거래를 시작하려면 다음과 같이 실행하기만 하면 됩니다.
ViVOpay Explorer에서는 거래에서 TLV 데이터를 파싱하여 화면에 표시하는 콜백 코드를 포함한 모든 필요한 코드를 startContactlessTransaction().
라는 함수로 래핑했습니다. Node 기반 드라이버가 USB 연결을 지원하는 방식에 대한 자세한 내용은 이전 게시물(링크는 아래로 스크롤)을 참조하시기 바랍니다. 또한 추가적인 제품 문서, 백서, SDK 문서 등을 위해 ID TECH의 무료 다운로드 페이지 도 꼭 확인하시기 바랍니다.
ID TECH 카드 리더기가 포함된 평가 키트를 받으시려면 아래에 표시된 번호로 언제든지 문의해 주십시오.
