
미안하다 이거 보여주려고 어그로끌었다..
드디어 길다면 길고 짧다면 짧은 캡스톤디자인이 24.6.10일 학술제를 마지막으로 끝났다.
중간중간 진행하면서 느끼고 배웠던 부분들을 적어보고 싶었지만, 프로젝트를 진행하면서 일정 관리, 내가 맡아 개발했던 부분, 사적인 약속 이슈들로 정신없는 하루들을 보내며 어떻게 여기까지 와버렸다...
(사실 핑계고 기억을 경험으로 바꾸는데에 게을렀다.. 다음에는 기억이 조금이라도 더 남아 있을 때, 바로바로 적어야겠다고 느꼈다)
모든 부분들을 이 글에 적고 싶지만, 너무 길어질 수 있으니 내가 맡았던 개발과 팀 프로젝트를 하면서 배우고 느꼈던 부분을 나눠서 글로 작성해 보고자 한다.
그 중에서도 이 글에서는 내가 맡았던 개발과 전반적인 진행 과정에 대하여 이야기 해보고자 한다.
우리 팀은 이번 프로젝트에서 학교 식권을 앱으로 사용할 수 있도록 만들었다.
아이디어 회의를 하던 중 너무 어려운 기술을 가져와서 시도해보려고 하기 보다는 현재 우리 주변에 있는 문제들 중 해결하면 어떨까! 하는 팀원 형의 말로 시작되었다.
현재 우리 학교 학생 식당의 프로세스는 요약하자면 이렇다.

이 과정에서(학생 기준) 식권이 코인과 식권 쿠폰이 있는데 대부분은 식권 구매 창구에서 코인을 구매한 후 배식을 받는 방식이다.
학생 식당의 점심 식사 시간이 11:30~1:30까지인데, 그 중에서도 12시에서 1시 사이의 시간은 사람이 정말정말정말 많다.
그렇다보니 식권을 구매하는 식권 구매 대기줄, 학식 배식을 기다리는 줄. 이렇게 두 줄이 아주 길~게 늘어지게 된다.
또한 배식을 하는 과정에서 코인을 구매한 사람들이 식권함에 식권을 넣어야하기 때문에 국을 배식해 주시는 급양원 분이 점심시간 내내 " 코인 넣어주세요~ " 라며 확인을 하셔야 하는 번거로움도 있다.
여기서 우리는 길어지는 대기줄과 구매 확인의 번거로움으로 인한 업무 효율의 저하를 문제점으로 삼고 이 과정을 간소화 시키고자 이 프로젝트를 시작하게 되었다.
기능은 다음과 같이 요약할 수 있다.
빠른 처리를 통한 프로세스 간소화 및 시간 단축

(우리 팀의 캡스톤 5형제)
차례대로 포트원, 파이어베이스, 플러터, 피그마, 안드로이드 스튜디오이다. 우리는 여기 나와있는 다섯개의 툴을 사용해서 앱을 제작했다.
결제 모듈을 구현했다. 이미 모듈이 전부 나와있기 때문에 조금만 커스텀하면 사용할 수 있었다. 너무 너무 편리했다. 그 중에서 토스페이먼츠를 연결했다. 실제 내가 맡았던 부분이기도 하다.

모두가 어렵다고 생각했던 부분인데, 어렵다고 생각하니 오히려 도전해보고 싶다는 마음이 들었던 나는 홍대병에 걸려 자원해서 하겠다고 했다.
(포트원 감사합니다)
결제 연동을 고민하던 중 가장 유명하다고 생각했던 것이 아임포트(현 포트원)이었고, 연동 docs가 자세하게 잘 나와있다고 판단해 포트원으로 조금은 단순하게 결정했다.
https://github.com/iamport/iamport_flutter (아임포트 플러터 문서)
메일로 문의 드렸을 때도 친절하게 하나하나 답변해 주셨다.. 최고..
iOS는 스키마 설정만 수정하면 되었고, 안드로이드는 따로 설정할 것도 없었다.


(요약한 결제 흐름의 화면들, 2번째 사진 : 실제 포트원을 통해 구현한 결제 화면 모습)
요렇게 진행을 해서 구매를 하면 
메인 화면의 식권 결제 버튼 -> 비밀번호 인증을 통해 이렇게 QR 화면으로 넘어오게 된다. 실제 포스기로 찍으면 그 값을 전달해 사용처리가 될 수 있도록 구현했다.

...
final int ticketCount;
final String? name;
final String? studentId;
final String? major;
final String? grade;
...
/* 결제 데이터 */
data: PaymentData(
pg: 'tosspayments', // PG사
payMethod: 'card', // 결제수단
name: '한남대학교 학생 식당 식권 구매' , // 주문명
merchantUid: 'mid_${DateTime.now().millisecondsSinceEpoch}', // 주문번호
amount: 4500 * ticketCount, // 결제금액
buyerName: name, // 구매자 이름
buyerTel: '01012345678', // 구매자 연락처
buyerEmail: '${studentId}@gm.hannam.ac.kr', // 구매자 이메일 -> 학번
buyerAddr: '한남대학교 학생 식당', // 구매자 주소
buyerPostcode: '06018', // 구매자 우편번호
appScheme: 'supertoss://', // 앱 URL scheme
cardQuota : [2,3] // 결제창 UI 내 할부개월수 제한
),
...
실제로 가장 헤맸던 부분 중 하나가 포트원 콘솔에 구매자 정보를 보내는 부분이었다. 정보를 끌어와야 했는데, 파이어베이스에 저장되어있는 유저 정보를 끌어다 오려고 했는데, 파이어베이스 유저 정보만 가져오려고 하면 오류가 나고 파이어스토어를 설정하는 과정에서 자꾸 ffi_c 오류가 나 결국 처음 학생 정보 입력시 사용되는 데이터를 끌어다 넣었다.
두번째는 QR 코드를 포스기가 인식했을 때 사용처리를 하는 부분이었는데, 내가 사용했던 포스기는 코드를 인식하면 저장되어 있는 값을 텍스트로 출력하는 방식이었다.
<!-- 일부코드 --!>
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class QrScanner extends StatefulWidget {
@override
_QrScannerState createState() => _QrScannerState();
}
class _QrScannerState extends State<QrScanner> {
final FocusNode _focusNode = FocusNode(); // FocusNode 추가
String _scannedDataBuffer = ''; // 스캔된 데이터를 저장할 버퍼
void _processScannedQRCode() {
// 여기에 QR 코드 처리 로직을 추가합니다.
print('QR 코드 데이터: $_scannedDataBuffer');
_scannedDataBuffer = ''; // 버퍼 초기화
}
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
_focusNode.requestFocus(); // 위젯이 빌드된 후 FocusNode에 포커스 설정
});
}
@override
void dispose() {
_focusNode.dispose(); // FocusNode 해제
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('QR 코드 스캐너'),
),
body: RawKeyboardListener(
focusNode: _focusNode, // FocusNode 사용
onKey: (RawKeyEvent event) {
if (event is RawKeyDownEvent) {
if (event.logicalKey == LogicalKeyboardKey.enter) {
// 엔터 키 입력 시 처리
_processScannedQRCode();
} else {
// 다른 키 입력을 버퍼에 추가
_scannedDataBuffer += event.character ?? '';
}
}
},
child: Center(
child: Text('QR 코드를 스캔해 주세요'),
),
),
);
}
}

나는 이 결제 연동에만 집중하기로 했기에, 나머지 부분의 구현은 팀원들이 해주었다. 모두 고마웠습니다..
결제 관련 부분을 처음 구현해 보는 부분이었기 때문에 모듈을 사용해서 조금만 커스텀해서 돌아보면 정말 쉽게 구현했던 것 같다. 스타트업이나 단기, 캡스톤 프로젝트 같은 때에는 빠르게 결과물을 내야하기 때문에 사용하기 좋다고 생각이 들었다.
but 백엔드 지망생으로써,, 다음에 결제 연동이 필요한 프로젝트를 하게 된다면 모듈이 아닌 직접 개발하고 연동해서 만들어보고 싶다고 생각했다.
기술적인 부분은 요정도까지만 쓰도록 하고 다음 下편에서 팀 프로젝트를 하면서. 느낀 부분을 적어보고자 한다.
