기술 포스트
간편하게 비접촉 결제 처리하기
칩 카드가 얼마나 번거로운지는 누구나 잘 알고 있습니다. 카드를 꽂고, 발을 동동 구르며, 차라리 칩이 오류를 일으켜서 그냥 긁을 수 있었으면 하고 바라게 되죠… 물론 조금 과장된 표현이긴 합니다. 하지만 무슨 말인지 충분히 공감하실 겁니다. 기존의 '접촉식 EMV'는 느리고 복잡하며 오류에 민감하기 때문에 고객들을 답답하게 만들고, 결제 앱 개발자들에게도 큰 골칫거리였습니다.
하지만 비접촉식 EMV는 이 모든 것을 바꿔놓습니다. '탭 앤 고(tap and go)' 방식의 거래는 일반적으로 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 코드를 실시간으로 실행할 수 있습니다. 오른쪽 상단에는 텍스트 입력란("http://localhost" 및 "9901" 표시)과 Connect 버튼이 있습니다. 이 버튼을 누르면 ViVOpay Explorer가 127.0.0.1의 포트 9901에서 Websocket 연결을 탐색합니다. 페이지 하단부는 로그 영역으로, 명령 실행에 따라 다양한 상태 정보(예: USB 트래픽 수신 내용)가 실시간으로 표시됩니다.
드롭다운 메뉴 옆의 작은 물음표를 클릭하면 ViVOpay Explorer 사용 방법을 안내하는 간단한 도움말 패널이 나타납니다. 핵심 사용 절차는 다음과 같습니다.
1. Node 드라이버 (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를 통해 포트 9901번으로 드라이버와 통신하고 있음을 의미합니다. 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) 과정에서 Websocket을 통해 송신(USB 장치로)되고 수신(브라우저로)된 내용입니다. 이 맞춤형 JSON 객체는 매우 단순한 스키마를 따르며, source, data, type 세 가지 필드로 구성됩니다. 브라우저에서 드라이버로 전송되는 아웃바운드 메시지의 경우, source 속성값은 "client"여야 하며, data 필드에는 USB 장치로 전송할 명령을 나타내는 16진수 문자열이 포함됩니다. 또한 type 필드에는 "raw command"가 입력되어, 드라이버가 해당 데이터 명령을 USB 장치로 그대로 전달해야 함을 인식할 수 있도록 합니다.
브라우저에서 드라이버로 JSON 객체(또는 기타 메시지)를 전송하는 방법은 간단합니다. 브라우저 코드에서 다음과 같이 입력하면 됩니다: socket.emit( 'echo', myObject )드라이버로부터 데이터를 수신하려면 리스너를 설정하면 됩니다: socket.on( 'message', myListener )여기서 myListener 는 다음과 같은 익명 함수로 정의할 수 있습니다: 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 장치로 메시지를 전달합니다.
여기서 "메시지"란 길고 복잡한 펌웨어 16진수 문자열을 의미합니다.
이 경우 "드라이버"는 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 연결을 지원하는 방식에 대한 자세한 내용은 이전 게시물을 참조하십시오(링크는 아래로 스크롤하여 확인하실 수 있습니다). 또한 ID TECH의 무료 다운로드 페이지 에서 추가 제품 문서, 백서, SDK 문서 등을 확인하시기 바랍니다.
ID TECH 카드 리더기가 포함된 평가 키트를 받아보시려면 아래에 표시된 번호로 언제든지 문의하십시오.
