기술 포스트
결제 게이트웨이 연동 시작하기
결제 앱을 구축하고 실제로 운영하려면 최소 두 가지 유형의 연동을 처리할 수 있어야 합니다. 첫째, 필요한 하드웨어(즉, 카드 리더기와 해당 기기가 연결되는 장치)를 연동하는 방법을 알아야 합니다. 그다음, 온라인 결제 게이트웨이와 같은 결제 '백엔드'—거래를 승인하고 정산을 처리하는 주체—와 연동하는 방법을 파악해야 합니다.
이전 게시물이 퍼즐에서 하드웨어 연동 부분에 대해 많은 이야기를 나눠왔는데, 사실 그리 어렵지 않습니다. ID TECH 카드 리더기를 사용하면 Universal SDK 를 활용해 고수준 언어 환경에서 디바이스와 통신할 수 있으며, 아키텍처에 Node JS를 도입할 의향이 있다면 순수 JavaScript 방식으로도 구현이 가능합니다. 어느 방법을 택하든, ID TECH 디바이스와의 통신은 그리 복잡한 일이 아닙니다.
그러나 여전히 이런 의문이 남습니다. 신용카드 리더기로 카드의 칩이나 마그네틱 선을 읽은 후, 그 정보를 어떻게 승인된 거래로 전환할 수 있을까요?
아마도 어떤 신용카드 프로세서가 요청을 처리할지는 이미 결정되어 있을 것입니다. 그렇다면 핵심 과제는 해당 프로세서 또는 게이트웨이가 온라인 요청 처리를 위해 어떤 SDK를 지원하는지 파악하는 것입니다.
대부분의 게이트웨이 또는 프로세서는 개발자 프로그램이나 온라인 개발자 포털을 운영하고 있으며, 이를 통해 결제 앱 구축에 필요한 SDK를 제공합니다. 이러한 SDK는 일반적으로 프로세서의 결제 API에 접근하기 위한 프런트엔드 및 백엔드 컴포넌트를 함께 구축할 수 있도록 지원합니다. 결제 API는 실시간 승인을 받기 위해 MagStripe 데이터 및/또는 ICC(칩 카드) 데이터를 네트워크를 통해 백엔드 프로세서로 전송하는 기능을 지원합니다.
결제 승인은 지원해야 할 여러 유형의 온라인 요청 중 하나에 불과합니다. 그 외 주요 요청 유형은 아래 표에 정리되어 있습니다.
요청 유형
설명
Auth
결제 승인 요청
Conf
이전 승인 요청 확인
Offline
오프라인 EMV 거래 정산
PreAuth
소액 거래를 통해 카드 정보 유효성 확인
Refund
기 정산된 거래 환불
Test
프로세서와의 연결 테스트
VoiceReferralNotification
음성 조회 요청의 결과를 프로세서에 통보합니다
Void
미결제 상태의 거래를 취소할 때 사용합니다
결제 프로세서의 SDK 문서를 살펴보면, 각 거래 유형에 적용되는 다양한 결과 코드 및/또는 오류 코드가 상당히 많다는 것을 알 수 있습니다. 그렇다면 이 모든 오류 유형을 어떻게 테스트할 수 있을까요? 대부분의 프로세서는 거래 금액의 센트 단위를 특정 값으로 설정하여 테스트 샌드박스 환경에서 특정 오류를 유발할 수 있는 방식을 제공합니다. (예를 들어, '금액 초과' 오류 코드가 1243인 경우, SDK에서는 $12.43 금액으로 테스트 거래를 제출하면 해당 오류를 재현할 수 있습니다.) 자세한 내용은 해당 프로바이더의 SDK 문서를 참조하시기 바랍니다.
많은 결제 프로세서는 암호화된 카드 데이터를 백엔드로 직접 전달할 수 있는 사전 인증된(반통합형) "인앱" 솔루션을 제공합니다. 이 방식은 결제 앱을 PCI 적용 범위 밖에 두는 것을 목적으로 하며, 대체로 투명하게 처리됩니다. 반면, 적용 범위 문제를 직접 처리해야 하는 경우에는 암호화된 카드 데이터를 방화벽 뒤에 있는 자체 서버 앱으로 전송한 후, HSM의 도움을 받아 카드 데이터를 복호화한 뒤 매입사 또는 게이트웨이로 라우팅하게 됩니다.
개괄적인 설명은 여기까지 하겠습니다. 이제 결제 백엔드와의 실제 연동이 어떤 의미인지 구체적으로 살펴보겠습니다.
이 사례가 모든 경우에 적용되는 것은 아니지만(단일 사례로 모든 상황을 다룰 수는 없습니다), 백엔드 연동 시 실제로 접하게 될 상황에 대한 이해를 높이는 데 도움이 될 것입니다.
이 사례에서 저는 EMV 거래에 대한 실시간 승인을 받기 위해 거래 데이터를 CreditCall 테스트 서버로 전송하는 "가상 단말기" 데모 앱을 개발하는 작업을 맡았습니다. CreditCall은 자체 ChipDNA Direct API, 이를 통해 Java, C++, Perl 또는 기타 언어로 제공되는 SDK를 활용한 개발이 가능합니다. 저는 Java 버전을 선택했습니다.
저는 ChipDNA Direct 웹사이트에서 개발자 계정을 등록했고, 곧바로 이메일로 CreditCall 테스트 서버에 접속할 수 있는 자격 증명을 받았습니다. 또한 CreditCall의 Java SDK를 다운로드하여 샘플 코드를 살펴보기 시작했습니다. 특히 EMV 거래 승인 요청을 처리하는 방법을 파악하고 싶었는데, 마침 예제 코드 파일 중 하나인 ExampleAuthEMV.java에 필요한 코드가 정확히 담겨 있었습니다.
저는 Java 클래스 두 개를 작성하는 작업에 착수했습니다. 하나는 브라우저 기반 프런트엔드의 HTTP 요청을 처리하는 서블릿 클래스이고, 다른 하나는 서블릿에서 수집한 브라우저 데이터를 CreditCall 백엔드로 전달하는 '워커(worker)' 클래스입니다. 서블릿 클래스는 약 250줄, 워커 클래스는 92줄로 완성되었습니다.
서블릿 클래스의 코드는 별도로 소개하지 않겠습니다. 대부분 표준 Java 서블릿 코드이며, 다만 AJAX를 통해 폼 필드 값으로 제출된 TLV 값을 런타임에 java.util.Hashtable 객체에 저장하는 부분이 추가되어 있습니다. 이 Hashtable은 워커 클래스의 정적 메서드인 authorize()에 전달됩니다. 워커 클래스는 CreditCall ChipDNA Direct SDK의 헬퍼(라이브러리) 클래스를 사용하여 com.creditcall.Request 객체를 생성하고, 이를 Client 객체에 전달하면 CreditCall 서버가 호출되는 구조입니다. 코드는 다음과 같습니다:
이 코드는 매우 간결하고 직관적이어서 별도의 설명이 거의 필요하지 않습니다. 핵심은 CreditCall의 Request 및 Client 클래스가 CreditCall 서버로 전송되는 XML 문서를 자동으로 생성해 준다는 점입니다. 개발자는 원시 XML을 직접 보거나 수정하거나 파싱하거나 신경 쓸 필요가 전혀 없습니다(처음부터 그렇게 설계된 것처럼 말이죠).
18번과 19번 줄에는 테스트 계정 자격 증명을 입력해야 합니다. (위에 표시된 자격 증명은 가상의 값입니다. 코드를 그대로 사용하지 마십시오!) 69번 줄에서는 CreditCall 엔드포인트 URL을 설정하고, 72번 줄에서 실제 HTTPS 아웃바운드 호출이 실행됩니다.
CreditCall 서버는 거래 데이터에 포함하는 TLV 태그의 종류에 대해 특별히 까다롭지 않습니다. 단, 핵심 카드 데이터가 담긴 태그는 반드시 포함해야 합니다(예: 접촉식 EMV의 경우 태그 5A 및 57, 비접촉식의 경우 태그 56, 그리고 암호문 정보가 담긴 9F26 및 9F27). CreditCall 서버는 EMV 데이터에 대한 응답으로 일반적으로 태그 8A, 89, 91에 대한 TLV를 반환하며, 필요 시 71 또는 72(칩 카드에 스크립트를 전달해야 하는 경우)도 선택적으로 반환합니다. 승인 코드는 태그 89에 포함되어 있습니다.
시행착오를 거치며 알게 된 사실은, CreditCall 서버 애플리케이션이 카드에서 AAC 암호문이 제시되었다고 해서 곧바로 거래를 거절하지는 않는다는 점입니다. (암호문 유형은 태그 9F27의 상위 비트를 확인하여 판별할 수 있으며, 모두 0이면 AAC, 즉 거절을 의미합니다.) 이는 사실 당연한 결과입니다. 카드의 판단은 어디까지나 권고에 불과하기 때문입니다. EMV 거래의 최종 승인 또는 거절 여부는 일반적으로 매입사가 결정하며, 카드의 판단이 번복되는 경우도 흔히 있습니다.
이처럼 실제로 다양한 시도를 해보다 보면 EMV에 관한 흥미로운 세부 사항들을 많이 배울 수 있습니다. 결제 애플리케이션 코드를 검증하는 데 있어 실시간 승인 테스트만큼 효과적인 방법은 없습니다!
EMV 거래에 관한 더 많은 정보가 필요하신가요? ID TECH 지식 베이스의 개발자 홈 페이지를 방문해 보세요. 또한 ID TECH의 EMV 개발 백서를 다운로드하시거나, 평가 키트 도입을 위해 전문가에게 무료 전화로 문의하세요.
