iamport / iamport_flutter

Flutter App에서 아임포트 결제서비스 연동을 위한 모듈입니다.
MIT License
67 stars 36 forks source link

본인인증 예제코드에서 취소시 callback함수호출되지않음 #116

Open puppleStar77 opened 5 months ago

puppleStar77 commented 5 months ago

안녕하세요 포트원으로 본인인증하다가 예제코드로 취소 눌렀을 경우 callback함수가 호출되지 않으며 m_redirect_url을 설정하라는 메세지가 나와서 본문 예제를 수정 해야할 것 같아서 이슈를 작성합니다.

예제코드 example/lib/certification_test.dart:137에서 CertificationData 를 아래와 같이 구성하고 전송하는 경우

                child: ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      _formKey.currentState!.save();

                      CertificationData data = CertificationData(
                        pg: pg,
                        merchantUid: merchantUid,
                        carrier: carrier,
                        company: company,
                        name: name,
                        phone: phone,
                      );
                      print("m_redirect_url: ${data.mRedirectUrl}");
                      if (minAge.length > 0) {
                        data.minAge = int.parse(minAge);
                      }

                      Get.toNamed('/certification', arguments: data);
                    }
                  },

예제코드 example/lib/certification_test.dart:13에서 CertificationData를 받아 그대로 전송하게 됩니다.

    return IamportCertification(
      appBar: AppBar(
        title: Text('아임포트 본인인증'),
        centerTitle: true,
        leading: IconButton(
          icon: Icon(Icons.arrow_back_ios),
          onPressed: () {
            Get.back();
          },
        ),
      ),
      initialChild: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Image.asset('assets/images/iamport-logo.png'),
              Padding(padding: EdgeInsets.symmetric(vertical: 15)),
              Text('잠시만 기다려주세요...', style: TextStyle(fontSize: 20.0)),
            ],
          ),
        ),
      ),
      userCode: userCode,
      data: data,
      callback: (Map<String, String> result) {
        Get.offNamed('/certification-result', arguments: result);
      },
    );
  }

이 예제코드를 통해 전송을 하게 되면 아래 화면에서 취소를 누를 경우

스크린샷 2023-12-01 114733

아래의 화면이 나오게 됩니다. 스크린샷 2023-12-01 115207

해당 부분은 예제에서 IamportWebView를 호출할때 받은 CertificationData를 그대로 나열하여 전송하며 CertificationData의 m_redirect_url 의 기본값은 null이기 때문에 m_redirect_url의 값이 전송되지않습니다.

lib/Iamport_certification.dart:45

  return IamportWebView(
        type: ActionType.auth,
        appBar: this.appBar,
        initialChild: this.initialChild,
        gestureRecognizers: this.gestureRecognizers,
        customUserAgent: this.customUserAgent,
        executeJS: (WebViewController controller) {
          controller.evaluateJavascript('''
            IMP.init("${this.userCode}");
            IMP.certification(${jsonEncode(this.data.toJson())}, function(response) {
              const query = [];
              Object.keys(response).forEach(function(key) {
                query.push(key + "=" + response[key]);
              });
              location.href = "$redirectUrl" + "?" + query.join("&");
            });
          ''');
        },
        useQueryData: (Map<String, String> data) {
          this.callback(data);
        },
        isPaymentOver: (String url) {
          return url.startsWith(redirectUrl);
        },
        // 인증에는 customPGAction 수행할 필요 없음
        customPGAction: (WebViewController controller) {},
      );

m_redirect_url이 전송되지않았기떄문에 취소를 눌렀을때 페이지가 이동되지 않으며 이동되지 않았기때문에 lib/widget/iamport_webview.dart:112줄의 Webview navigationDelegate이벤트가 발생하지 않고 에러메시지만 출력되게 되며 navigationDelegate메세지가 발생하지않아 callback 함수를 호출하지 않습니다.

Flutter 앱이므로 취소 눌렀을 경우 정상적으로 callback 함수가 호출되어 창을 관리할 수 있어야 합니다. callback 함수를 호출하려면 navigationDelegate에서 widget.isPaymentOver가 true로 되어야하므로 이렇게 하기 위해서는 m_redirect_url에 무조건 UrlData.redirectUrl 값이 전송 되어야 합니다.

이를 적용하는 방법으로는

  1. CertificationData의 m_redirect_url 기본값을 UrlData.redirectUrl 로 하여 기본값을 변경합니다.
  2. 예제코드에서 CertificationData를 호출할때 UrlData.redirectUrl 를 아래와 같이 포함하도록 하여 예제소스코드를 변경합니다.
    data: CertificationData(
        merchantUid: 'mid_${DateTime.now().millisecondsSinceEpoch}',  // 주문번호
        company: '아임포트',                                            // 회사명 또는 URL
        carrier: 'SKT',                                               // 통신사
        name: '홍길동',                                                 // 이름
        phone: '01012341234',  // 전화번호
        mRedirectUrl: UrlData.redirectUrl
      ),

편의를 위해서 코드를 업데이트 하면 좋을 것 같습니다. 예제를 업데이트할지, 기본 값을 변경할지 확인해주신다면 풀리퀘 올리도록하겠습니다.

anymate98 commented 5 months ago

안녕하세요. 이슈 공유해주셔서 감사합니다. 해당 문제는 이니시스 통합인증이 m_redirect_url을 필수로 받기 때문에 발생하는 문제입니다. 취소 뿐만 아니라 인증에 성공해도 해당 메시지가 뜨게 됩니다. 원래 예전에는 본인인증 예제가 다날 본인인증이었고 다날의 경우엔 m_redirect_url이 필수가 아니었기 때문에 문제가 없었습니다. 가장 간단한 해결책은 예제에서 사용되는 본인인증 pg의 기본값을 다날로 바꾸고 readme에 이니시스 통합인증 관련 내용을 추가하는 것으로 보이는데 의견 부탁드리겠습니다.

puppleStar77 commented 5 months ago

확인 감사드립니다. 이니시스에서만 발생하는 건지는 모르고 있었습니다. 내용 다시 확인해보니 제가 올린 이슈 내용에도 오류가 있었네요 제가 실행했던 코드는 example/lib/certification_test.dart 에 있는 코드가 아니라 readme에 있는 본인인증코드였습니다.

readme에 있는 본인인증 코드는 실행시 이니시스이며 (userCode:'iamport', pg:'null') 정상동작을 위해서는 이니시스에서만 m_redirect_url가 필수이기에 둘이 요구조건이 달라 readme에 있는 본인인증 코드에 말씀해주신대로 다날본인인증 예제와 이니시스 본인인증예제 각 2개 추가하는 것이 혼동을 줄 여지가 제일 적을 것 같습니다.

anymate98 commented 5 months ago

네 의견 감사합니다. 그러면 readme에 다날과 이니시스 본인인증 예제를 각 pg별 설명과 함께 추가하고 코드상에도 m_redirect_url에 대한 주석을 추가하는 방향으로 수정하겠습니다.

puppleStar77 commented 5 months ago

넵 감사합니다