From b636bd7ae62c3895e631e32afabf77c6bc418ea2 Mon Sep 17 00:00:00 2001 From: minkyu1128 Date: Thu, 30 Mar 2023 13:27:16 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=84=A4=EC=9D=B4=EB=B2=84=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=20=EA=B0=84=ED=8E=B8=EA=B2=B0=EC=A0=9C=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EA=B5=AC=EC=B6=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + 결제 process 변경 + 미사용 클래스 삭제 + 클래스 패키지경로 편집 --- pom.xml | 9 +- .../iup/alimtalk/model/IupAlimtalkReqVO.java | 12 - .../iup/alimtalk/mq/IupAlimtalkConsumer.java | 38 - .../iup/alimtalk/mq/IupAlimtalkProducer.java | 28 - .../presentation/IupAlimtalkController.java | 54 - .../alimtalk/sched/IupAlimtalkScheduler.java | 45 - .../alimtalk/service/IupAlimtalkService.java | 164 - .../service/IupBillPayApiAlimtalkService.java | 430 -- .../service/support/IupAlimtalkAcceptor.java | 294 -- .../service/support/IupAlimtalkFetcher.java | 192 - .../service/support/IupAlimtalkMaker.java | 66 - .../service/support/IupAlimtalkSender.java | 66 - .../iup/billpay/api/IupKkoPayUseSysApi.java} | 4 +- .../billpay/api/IupKkoPayUseSysApiSpec.java} | 4 +- .../billpay/api/IupKkoPayUseSysApiTest.java} | 4 +- ...ava => IupBillKkoPayUseSysController.java} | 16 +- .../IupBillPayRsltFwdController.java | 109 - .../presentation/IupPayUseSysController.java | 135 + ...t.java => IupBillKkoPayUseSysService.java} | 80 +- .../billpay/service/IupPayUseSysService.java | 6 + .../service/IupPayUseSysServiceFactory.java | 32 + .../impl/IupKkoPayUseSysServiceImpl.java | 86 + .../impl/IupNvPayUseSysServiceImpl.java | 81 + .../service/process/IupKkoPayAbleService.java | 217 + .../process/IupKkoPayNoticeService.java | 227 + .../process/IupKkoPayResultService.java | 191 + .../service/process/IupKkoPayUrlService.java | 147 + .../service/process/IupNvPayAbleService.java | 224 + .../process/IupNvPayCancelService.java | 51 + .../process/IupNvPayNoticeService.java | 229 + .../process/IupNvPayResultService.java | 212 + .../cokr/xit/ens/biz/iup/domain/FsJob.java | 57 +- .../ens/biz/iup/domain/TbIupBillPayHist.java | 33 + .../ens/biz/iup/domain/TbKakaoPayResult.java | 1 - .../ens/biz/iup/domain/TbNaverPayResult.java | 159 + .../biz/iup/domain/VKakaoNoticeInfoSn.java | 12 +- .../repository/TbEnfrcLevRcivRepository.java | 3 +- .../TbEnfrcLevRcivRepositoryCustom.java | 5 - .../TbEnfrcLevRcivRepositoryImpl.java | 12 - .../TbInputDataXitCustomRepositoryImpl.java | 14 +- .../TbIupBillPayHistRepository.java | 9 + .../TbNaverPayResultRepository.java | 9 + .../VKakaoNoticeInfoRepository.java | 2 +- .../VKakaoNoticeInfoRepositoryCustom.java | 5 - .../VKakaoNoticeInfoRepositoryImpl.java | 12 - .../VKakaoNoticeInfoSnRepository.java | 2 +- .../VKakaoNoticeInfoSnRepositoryCustom.java | 5 - .../VKakaoNoticeInfoSnRepositoryImpl.java | 12 - ...java => IupBillKkoPaySigntalkService.java} | 153 +- .../service/support/IupSigntalkAcceptor.java | 61 +- .../support/TrafficCaSigntalkAcceptor.java | 8 +- .../chuncheon/init/TrafficCcJpaRunner.java | 4 +- .../v1/service/UserElctrnNticService.java | 2 +- .../cokr/xit/ens/core/aop/EnsResponseVO.java | 12 + .../xit/ens/core/config/SecurityConfig.java | 14 + .../xit/ens/core/config/SpringDocConfig.java | 24 +- .../config/redis/EmbeddedRedisConfig.java | 1 - .../xit/ens/core/exception/code/EnsErrCd.java | 252 +- .../cokr/xit/ens/core/init/InitJpaRunner.java | 16 +- .../dialect/MariaDB103DialectCustom.java | 2 +- .../dialect/Oracle10gDialectCustom.java | 2 +- .../jpa/support/BooleanToYnConverter.java | 18 + .../xit/ens/core/model/EnsBillAcptReqDTO.java | 48 + .../core/model/config/XitBaseProperty.java | 6 +- .../utils/ApplicationContextProvider.java | 20 +- .../cokr/xit/ens/core/utils/BeanUtils.java | 22 +- .../cokr/xit/ens/core/utils/CmmnUtil.java | 361 +- .../cokr/xit/ens/core/utils/DateUtil.java | 685 +-- .../cokr/xit/ens/core/utils/IdGenerator.java | 3 +- .../java/cokr/xit/ens/core/utils/JwtUtil.java | 198 +- .../xit/ens/core/utils/MapDeserailizer.java | 37 +- .../xit/ens/core/utils/RequireValidator.java | 134 +- .../ctgy/intgrnbill/BillAcptReqDTO.java | 38 - .../ctgy/intgrnbill/BillAcptReqData.java | 6 - .../ctgy/intgrnbill/BillMakerSupport.java | 127 - .../common/ctgy/intgrnbill/BillService.java | 8 - .../ctgy/intgrnbill/BillUrlReqData.java | 6 - .../ctgy/intgrnbill/code/BillReqSeCd.java | 41 - .../common/ctgy/intgrnbill/entity/Bill.java | 50 - .../entity/repository/BillHistRepository.java | 9 - .../entity/repository/BillSeRepository.java | 10 - .../{BillKkoApi.java => BillKkoPayApi.java} | 114 +- ...KkoApiSpec.java => BillKkoPayApiSpec.java} | 2 +- ...KkoApiTest.java => BillKkoPayApiTest.java} | 2 +- .../ctgy/intgrnbill/kko/entity/BillKko.java | 69 - .../intgrnbill/kko/entity/BillKkoPay.java | 117 + ...ository.java => BillKkoPayRepository.java} | 8 +- .../repository/BillKkoRepositoryCustom.java | 11 - .../repository/BillKkoRepositoryImpl.java | 42 - .../repository/BillSeKkoRepositoryImpl.java | 26 - .../kko/model/BillKkoAcptReqDTO.java | 32 - .../kko/model/BillKkoAcptReqVO.java | 68 - ...sultDTO.java => BillKkoPayResultData.java} | 4 +- .../kko/model/BillKkoRsltFwdFailDTO.java | 25 - .../model/BillKkoRsltFwdFailSearchDTO.java | 18 - .../kko/model/BillKkoUrlReqDTO.java | 32 - .../intgrnbill/kko/model/BillKkoUrlReqVO.java | 33 - .../presentation/BillKkoClientController.java | 114 - .../kko/presentation/BillKkoController.java | 118 - .../presentation/KkoPayProcessController.java | 92 + .../KkoPayUseSysSampleController.java | 195 + .../kko/service/BillKkoClientApiSpec.java | 35 - .../kko/service/BillKkoClientApiSupport.java | 158 - .../kko/service/BillKkoService.java | 13 - .../kko/service/KkoPayProcessService.java | 102 + .../kko/service/KkoPayRepairService.java | 143 + .../kko/service/KkoPaymentTriggerService.java | 66 + .../impl/BillKkoClientServiceImpl.java | 175 - .../kko/service/impl/BillKkoMaker.java | 163 - .../kko/service/impl/BillKkoServiceImpl.java | 288 -- .../service/process/KkoPayAbleService.java | 261 ++ .../service/process/KkoPayNoticeService.java | 287 ++ .../service/process/KkoPayResultService.java | 233 + .../kko/service/process/KkoPayUrlService.java | 420 ++ .../process/model}/CustomUrl.java | 2 +- .../process/model/KkoPayBankAccounts.java | 43 + .../process/model/KkoPayNoticeRespData.java | 68 + .../process/model/KkoPayResultReqData.java | 124 + .../process/model/KkoPayUrlRespData.java | 46 + .../kit/RepairKkoPayResultTransferFail.java | 27 + .../intgrnbill/nv/api/BillNvEasyPayApi.java | 265 ++ .../nv/api/BillNvEasyPayApiSpec.java | 80 + .../ctgy/intgrnbill/nv/code/NvEpBankCd.java | 90 + .../ctgy/intgrnbill/nv/code/NvEpCardCd.java | 44 + .../intgrnbill/nv/entity/BillNvEasyPay.java | 83 + .../repository/BillNvEasyPayRepository.java | 9 + .../intgrnbill/nv/model/BillNvAcptReqVO.java | 57 + .../presentation/NvPayProcessController.java | 96 + .../NvPayUseSysSampleController.java | 216 + .../presentation/NvPaymentPageController.java | 84 + .../nv/service/NvPayProcessService.java | 99 + .../nv/service/NvPayRepairService.java | 139 + .../nv/service/NvPaymentTriggerService.java | 87 + .../nv/service/process/NvPayAbleService.java | 380 ++ .../service/process/NvPayCancelService.java | 308 ++ .../service/process/NvPayNoticeService.java | 485 ++ .../service/process/NvPayResultService.java | 231 + .../nv/service/process/code/NvEpCtgyIdCd.java | 69 + .../service/process/code/NvEpCtgyTypeCd.java | 38 + .../process/code/NvEpPayReferrerCd.java | 39 + .../process/model/NvPayAbleReqData.java | 55 + .../process/model/NvPayApplyRespData.java | 35 + .../process/model/NvPayNoticeRespData.java | 96 + .../process/model/NvPayResultDetail.java | 211 + .../process/model/NvPayResultReqData.java | 31 + .../process/model/config/able/Detail.java | 240 + .../model/config/notice/ProductItem.java | 74 + .../kit/RepairNvPayResultTransferFail.java | 27 + .../ctgy/intgrnbill/support/PayApi.java | 170 + .../intgrnbill/support/PayController.java | 51 + .../support/PayRepairController.java | 84 + .../support/PayUseSysController.java | 11 + .../support/PaymentTriggerController.java | 95 + .../intgrnbill/support/api/PayUseSysApi.java | 91 + .../intgrnbill/support/code/BillLogSeCd.java | 38 + .../intgrnbill/support/code/BillReqSeCd.java | 55 + .../{ => support}/code/BillSeCd.java | 10 +- .../intgrnbill/support/code/PaidTypeCd.java | 38 + .../support/code/PayUseSysHisSeCd.java | 41 + .../support/code/PayUseSysResCd.java | 61 + .../ctgy/intgrnbill/support/entity/Bill.java | 72 + .../entity/BillBaseEntity.java} | 8 +- .../{ => support}/entity/BillHist.java | 41 +- .../support/entity/BillHistBaseEntity.java | 38 + .../entity/BillHistPayUseSysBaseEntity.java | 33 + .../entity/repository/BillHistRepository.java | 9 + .../entity/repository/BillRepository.java | 4 +- .../support/model/PayApiRespDTO.java | 56 + .../support/service/process/Pay.java | 21 + .../service/process/PayHelperService.java | 53 + .../service/process/PayProcessService.java | 51 + .../service/process/kit/PayAbleService.java | 10 + .../service/process/kit/PayCancelService.java | 10 + .../service/process/kit/PayNoticeService.java | 10 + .../service/process/kit/PayResultService.java | 10 + .../service/process/kit/PayUrlService.java | 11 + .../service/process/model/PayAbleData.java | 24 + .../service/process/model/PayCancelData.java | 24 + .../service/process/model/PayNoticeData.java | 24 + .../service/process/model/PayResultData.java | 24 + .../service/process/model/PayUrlData.java | 24 + .../service/process/model/ReqAndRespInf.java | 26 + .../service/process/template/PayHelper.java | 56 + .../repair/PayRepairServiceFactory.java | 28 + .../repair/RepairPayResultService.java | 23 + .../kit/RepairPayResultTransferFail.java | 176 + .../model/PayResultTransferFailData.java | 43 + .../model/PayResultTransferProcessVO.java | 23 + .../model/RepairPayRsltFwdFailSearchDTO.java | 34 + .../trigger/PaymentTriggerService.java | 23 + .../trigger/PaymentTriggerServiceFactory.java | 28 + .../PaymentTriggerServiceTemplate.java | 48 + .../intgrnnoti/domain/IntgrnSendDetail.java | 2 +- .../intgrnnoti/model/config/XitProperty.java | 6 +- .../IntgrnNotiMblPageController.java | 22 +- .../service/support/AcceptData.java | 2 +- .../service/support/IntgrnNotiAcceptor.java | 31 +- .../service/support/IntgrnNotiMaker.java | 43 +- .../AcceptByKkoAlimtalkEventListener.java | 2 +- .../kkoalimtalk/AcceptDataByKkoAlimtalk.java | 25 +- .../AcceptByKkoMydocEventListener.java | 2 +- .../kkomydoc/AcceptDataByKkoMydoc.java | 24 +- .../ktGibis/AcceptByKtGibisEventListener.java | 2 +- .../support/ktGibis/AcceptDataByKtGibis.java | 15 +- .../AcceptByKtSigntalkEventListener.java | 8 +- .../ktSigntalk/AcceptDataByKtSigntalk.java | 24 +- .../AcceptByNvSigntalkEventListener.java | 8 +- .../nvsigntalk/AcceptDataByNvSigntalk.java | 27 +- .../mblpage/model/SendDetailMblPageDTO.java | 2 +- .../MblPageControllerSupport.java | 37 + .../SendDetailMblPageController.java | 26 +- .../common/ctgy/sys/mng/domain/OrgMng.java | 92 +- .../common/ctgy/sys/mng/model/OrgMngDTO.java | 57 +- .../ctgy/sys/mng/service/OrgMngService.java | 82 +- .../common/domain/support/FieldError.java | 26 +- .../modules/common/monitor/MessageByBill.java | 2 +- .../domain/SendDetailKkoAlimtalk.java | 2 +- .../SendDetailKkoAlimtalkRepositoryImpl.java | 2 +- .../kkoalimtalk/model/config/XitProperty.java | 4 +- .../service/support/KkoAlimtalkAcceptor.java | 69 +- .../service/support/KkoAlimtalkMaker.java | 50 +- .../kkomydoc/domain/SendDetailKkoMydoc.java | 2 +- .../SendDetailKkoMydocRepositoryImpl.java | 2 +- .../kkomydoc/model/config/XitProperty.java | 8 +- .../KkoMydocMblPageController.java | 27 +- .../service/support/KkoMydocAcceptor.java | 32 +- .../service/support/KkoMydocMaker.java | 21 +- .../direct/domain/SendDetailKtSigntalk.java | 2 +- .../SendDetailKtSigntalkRepositoryImpl.java | 2 +- .../direct/model/config/XitProperty.java | 4 +- .../KtSigntalkMblPageController.java | 26 +- .../service/support/KtSigntalkAcceptor.java | 31 +- .../service/support/KtSigntalkMaker.java | 44 +- .../gibis/domain/SendDetailKtGibis.java | 2 +- .../SendDetailKtGibisRepositoryImpl.java | 2 +- .../gibis/model/config/XitProperty.java | 4 +- .../KtGibisMblPageController.java | 26 +- .../service/support/KtGibisAcceptor.java | 30 +- .../gibis/service/support/KtGibisMaker.java | 20 - .../domain/SendDetailNvSigntalk.java | 2 +- .../nvsigntalk/model/config/XitProperty.java | 6 +- .../NvSigntalkMblPageController.java | 24 +- .../service/support/NvSigntalkAcceptor.java | 31 +- .../service/support/NvSigntalkMaker.java | 39 +- src/main/resources/application-dev-oracle.yml | 79 + .../resources/application-local-maria.yml | 17 +- src/main/resources/application-local-test.yml | 4 +- src/main/resources/application-prod-iup.yml | 70 +- .../resources/application-prod-traffic.yml | 2 +- src/main/resources/application.yml | 61 +- src/main/resources/config/conf-contract.yml | 24 +- .../WEB-INF/jsp/modules/bill/nvEpApply.jsp | 124 + .../jsp/modules/bill/nvEpApply.jsp_back | 265 ++ .../WEB-INF/jsp/modules/bill/nvEpTest.jsp | 143 + .../WEB-INF/jsp/modules/mblpage/notiprnt.jsp | 208 +- .../jsp/modules/mblpage/notiprntproxy.jsp | 60 - .../resource/bill/css/nvep/nvEpComponent.css | 319 ++ .../resource/bill/css/nvep/nvEpDetail.css | 4037 +++++++++++++++++ .../resource/bill/css/nvep/nvEpLayout.css | 689 +++ .../kkopay/payment_icon_yellow_large.png | Bin 0 -> 3746 bytes .../kkopay/payment_icon_yellow_medium.png | Bin 0 -> 1833 bytes .../kkopay/payment_icon_yellow_small.png | Bin 0 -> 1530 bytes .../resource/bill/images/nvep/logo_black.png | Bin 0 -> 1234 bytes .../bill/images/nvep/logo_nocolor.png | Bin 0 -> 7679 bytes .../resource/bill/images/nvep/logo_white.png | Bin 0 -> 1261 bytes .../images/nvep/naverpay_sdk_square_x2.gif | Bin 0 -> 2920 bytes .../resource/bill/images/nvep/sp_bi_bank.png | Bin 0 -> 41289 bytes .../bill/images/nvep/sp_component.png | Bin 0 -> 20022 bytes .../resource/bill/images/nvep/sp_detail.png | Bin 0 -> 47775 bytes .../bill/images/nvep/sp_footer_pc.png | Bin 0 -> 4799 bytes .../bill/images/nvep/sp_header_pc.png | Bin 0 -> 10763 bytes src/main/webapp/resource/bill/js/FncPayBtn.js | 171 + .../webapp/resource/bill/js/jquery.blockUI.js | 620 +++ src/main/webapp/resource/css/style.css | 337 +- .../{notoKR_Bold.ttf => notoKR-Bold.ttf} | Bin .../font/notoKR-Regular/NotoKR-Regular.ttf | Bin 0 -> 367948 bytes .../service/KkoAlimtalkMakeServiceTest.java | 2 +- 277 files changed, 18412 insertions(+), 5338 deletions(-) delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/model/IupAlimtalkReqVO.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkConsumer.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkProducer.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/presentation/IupAlimtalkController.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/sched/IupAlimtalkScheduler.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupAlimtalkService.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupBillPayApiAlimtalkService.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkAcceptor.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkFetcher.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkMaker.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkSender.java rename src/main/java/cokr/xit/ens/{modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApi.java => biz/iup/billpay/api/IupKkoPayUseSysApi.java} (98%) rename src/main/java/cokr/xit/ens/{modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiSpec.java => biz/iup/billpay/api/IupKkoPayUseSysApiSpec.java} (75%) rename src/main/java/cokr/xit/ens/{modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiTest.java => biz/iup/billpay/api/IupKkoPayUseSysApiTest.java} (96%) rename src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/{IupBillPayApiController.java => IupBillKkoPayUseSysController.java} (94%) delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayRsltFwdController.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupPayUseSysController.java rename src/main/java/cokr/xit/ens/biz/iup/billpay/service/{IupBillPayApiServiceSupport.java => IupBillKkoPayUseSysService.java} (62%) create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysServiceFactory.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupKkoPayUseSysServiceImpl.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupNvPayUseSysServiceImpl.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayAbleService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayNoticeService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayResultService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayUrlService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayAbleService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayCancelService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayNoticeService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayResultService.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/TbIupBillPayHist.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/TbNaverPayResult.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryCustom.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryImpl.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbIupBillPayHistRepository.java create mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbNaverPayResultRepository.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryCustom.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryImpl.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryCustom.java delete mode 100644 src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryImpl.java rename src/main/java/cokr/xit/ens/biz/iup/signtalk/service/{IupBillPayApiSigntalkService.java => IupBillKkoPaySigntalkService.java} (82%) create mode 100644 src/main/java/cokr/xit/ens/core/config/SecurityConfig.java rename src/main/java/cokr/xit/ens/core/{ => jpa}/dialect/MariaDB103DialectCustom.java (93%) rename src/main/java/cokr/xit/ens/core/{ => jpa}/dialect/Oracle10gDialectCustom.java (92%) create mode 100644 src/main/java/cokr/xit/ens/core/jpa/support/BooleanToYnConverter.java create mode 100644 src/main/java/cokr/xit/ens/core/model/EnsBillAcptReqDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqData.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillMakerSupport.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillService.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillUrlReqData.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillReqSeCd.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/Bill.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillHistRepository.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillSeRepository.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/{BillKkoApi.java => BillKkoPayApi.java} (96%) rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/{BillKkoApiSpec.java => BillKkoPayApiSpec.java} (94%) rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/{BillKkoApiTest.java => BillKkoPayApiTest.java} (98%) delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKko.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKkoPay.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/{BillKkoRepository.java => BillKkoPayRepository.java} (52%) delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryCustom.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryImpl.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillSeKkoRepositoryImpl.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqVO.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/{BillKkoPayResultDTO.java => BillKkoPayResultData.java} (97%) delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailSearchDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqDTO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqVO.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoClientController.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayProcessController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayUseSysSampleController.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSpec.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSupport.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayProcessService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayRepairService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPaymentTriggerService.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoClientServiceImpl.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoMaker.java delete mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoServiceImpl.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayAbleService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayNoticeService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayResultService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayUrlService.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/{model/config => service/process/model}/CustomUrl.java (94%) create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayBankAccounts.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayNoticeRespData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayResultReqData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayUrlRespData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/repair/kit/RepairKkoPayResultTransferFail.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApi.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApiSpec.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpBankCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpCardCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/BillNvEasyPay.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/repository/BillNvEasyPayRepository.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/model/BillNvAcptReqVO.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayProcessController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayUseSysSampleController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPaymentPageController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayProcessService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayRepairService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPaymentTriggerService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayAbleService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayCancelService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayNoticeService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayResultService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyIdCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyTypeCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpPayReferrerCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayAbleReqData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayApplyRespData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayNoticeRespData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultDetail.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultReqData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/able/Detail.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/notice/ProductItem.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/repair/kit/RepairNvPayResultTransferFail.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayApi.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayRepairController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayUseSysController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PaymentTriggerController.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/api/PayUseSysApi.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillLogSeCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillReqSeCd.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/{ => support}/code/BillSeCd.java (70%) create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PaidTypeCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysHisSeCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysResCd.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/Bill.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/{entity/BillEntity.java => support/entity/BillBaseEntity.java} (57%) rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/{ => support}/entity/BillHist.java (55%) create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistBaseEntity.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistPayUseSysBaseEntity.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillHistRepository.java rename src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/{ => support}/entity/repository/BillRepository.java (73%) create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/model/PayApiRespDTO.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/Pay.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayHelperService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayProcessService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayAbleService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayCancelService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayNoticeService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayResultService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayUrlService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayAbleData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayCancelData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayNoticeData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayResultData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayUrlData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/ReqAndRespInf.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/template/PayHelper.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/PayRepairServiceFactory.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/RepairPayResultService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/kit/RepairPayResultTransferFail.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferFailData.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferProcessVO.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/RepairPayRsltFwdFailSearchDTO.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerService.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceFactory.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceTemplate.java create mode 100644 src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/MblPageControllerSupport.java create mode 100644 src/main/resources/application-dev-oracle.yml create mode 100644 src/main/webapp/WEB-INF/jsp/modules/bill/nvEpApply.jsp create mode 100644 src/main/webapp/WEB-INF/jsp/modules/bill/nvEpApply.jsp_back create mode 100644 src/main/webapp/WEB-INF/jsp/modules/bill/nvEpTest.jsp delete mode 100644 src/main/webapp/WEB-INF/jsp/modules/mblpage/notiprntproxy.jsp create mode 100644 src/main/webapp/resource/bill/css/nvep/nvEpComponent.css create mode 100644 src/main/webapp/resource/bill/css/nvep/nvEpDetail.css create mode 100644 src/main/webapp/resource/bill/css/nvep/nvEpLayout.css create mode 100644 src/main/webapp/resource/bill/images/kkopay/payment_icon_yellow_large.png create mode 100644 src/main/webapp/resource/bill/images/kkopay/payment_icon_yellow_medium.png create mode 100644 src/main/webapp/resource/bill/images/kkopay/payment_icon_yellow_small.png create mode 100644 src/main/webapp/resource/bill/images/nvep/logo_black.png create mode 100644 src/main/webapp/resource/bill/images/nvep/logo_nocolor.png create mode 100644 src/main/webapp/resource/bill/images/nvep/logo_white.png create mode 100644 src/main/webapp/resource/bill/images/nvep/naverpay_sdk_square_x2.gif create mode 100644 src/main/webapp/resource/bill/images/nvep/sp_bi_bank.png create mode 100644 src/main/webapp/resource/bill/images/nvep/sp_component.png create mode 100644 src/main/webapp/resource/bill/images/nvep/sp_detail.png create mode 100644 src/main/webapp/resource/bill/images/nvep/sp_footer_pc.png create mode 100644 src/main/webapp/resource/bill/images/nvep/sp_header_pc.png create mode 100644 src/main/webapp/resource/bill/js/FncPayBtn.js create mode 100644 src/main/webapp/resource/bill/js/jquery.blockUI.js rename src/main/webapp/resource/font/notoKR-Bold/{notoKR_Bold.ttf => notoKR-Bold.ttf} (100%) create mode 100644 src/main/webapp/resource/font/notoKR-Regular/NotoKR-Regular.ttf diff --git a/pom.xml b/pom.xml index f58860d..243215f 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,7 @@ ${package.include.base} WEB-INF/classes/**/ens/batch/**, WEB-INF/classes/**/ens/modules/**, + WEB-INF/classes/application-local*.yml, @@ -157,10 +158,10 @@ org.springframework.boot spring-boot-starter-validation - - - - + + org.springframework.boot + spring-boot-starter-security + diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/model/IupAlimtalkReqVO.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/model/IupAlimtalkReqVO.java deleted file mode 100644 index 4c5af40..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/model/IupAlimtalkReqVO.java +++ /dev/null @@ -1,12 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.model; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Getter; - -@Getter -@Schema(name = "IupAlimtalkReqVO") -public class IupAlimtalkReqVO { - - @Schema(required = true, title = "연계입수 아이디", example = " ") - private Long lnkInputId; -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkConsumer.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkConsumer.java deleted file mode 100644 index 77497ed..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkConsumer.java +++ /dev/null @@ -1,38 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.mq; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Profile; -import org.springframework.kafka.annotation.KafkaListener; - -import javax.annotation.Resource; -import java.io.IOException; - -@Slf4j -//@Component -@Profile("prod-iup") -public class IupAlimtalkConsumer { - - @Resource(name = "iupAlimtalkMakerLegacy") -// @Autowired -// private IupAlimtalkMakerLegacy iupAlimtalkMaker; - - /** - * 알림톡 제작요청 - * @param message - * @throws IOException - */ - @SuppressWarnings("unchecked") - @KafkaListener(topics = "iup-kkoalimtalk-makereq", groupId = "group-id-ens") - public void subMakeReq(String message) throws IOException { - log.info("[iup-kkoalimtalk-makereq] sub message : " + message); - try { - Long sendMastId = Long.parseLong(message); - -// iupAlimtalkMaker.make(sendMastId); - } catch (Exception e) { - e.printStackTrace(); - } - } - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkProducer.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkProducer.java deleted file mode 100644 index a4445b5..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/mq/IupAlimtalkProducer.java +++ /dev/null @@ -1,28 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.mq; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.stereotype.Component; - -@Slf4j -@Component -public class IupAlimtalkProducer { - - @Autowired - private KafkaTemplate kafkaTemplate; - - /** - * 알림톡 제작요청 - * @param message - */ - public void pubMakeReq(String message) { - final String topicName = "iup-kkoalimtalk-makereq"; - - log.info(String.format("[%s] pub message : %s", topicName, message)); - - this.kafkaTemplate.send(topicName, message); - } - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/presentation/IupAlimtalkController.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/presentation/IupAlimtalkController.java deleted file mode 100644 index 82d2cc7..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/presentation/IupAlimtalkController.java +++ /dev/null @@ -1,54 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.presentation; - -import cokr.xit.ens.biz.iup.alimtalk.model.IupAlimtalkReqVO; -import cokr.xit.ens.biz.iup.alimtalk.service.IupAlimtalkService; -import cokr.xit.ens.core.aop.EnsResponseVO; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -@Tag(name = "IupAlimtalkController") -@Slf4j -@RequiredArgsConstructor -@RestController -public class IupAlimtalkController { - - private final IupAlimtalkService iupAlimtalkService; - - @Operation(summary = "접수") - @PostMapping(value = "/iup/alimtalk/accept", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity accept(@RequestBody IupAlimtalkReqVO reqDTO){ - EnsResponseVO responseVO = iupAlimtalkService.accept(reqDTO.getLnkInputId()); - return new ResponseEntity(responseVO, HttpStatus.OK); - } - - @Operation(summary = "제작") -// @PutMapping(value = "/iup/alimtalk/re/make", produces = MediaType.APPLICATION_JSON_VALUE) - @PostMapping(value = "/iup/alimtalk/re/make", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity reMake(@RequestBody IupAlimtalkReqVO reqDTO){ - EnsResponseVO responseVO = iupAlimtalkService.reMake(reqDTO.getLnkInputId()); - return new ResponseEntity(responseVO, HttpStatus.OK); - } - - @Operation(summary = "전송") -// @PutMapping(value = "/iup/alimtalk/re/send", produces = MediaType.APPLICATION_JSON_VALUE) - @PostMapping(value = "/iup/alimtalk/re/send", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity reSend(@RequestBody IupAlimtalkReqVO reqDTO){ - EnsResponseVO responseVO = iupAlimtalkService.reSend(reqDTO.getLnkInputId()); - return new ResponseEntity(responseVO, HttpStatus.OK); - } - - @Operation(summary = "전송결과가져오기") - @PostMapping(value = "/iup/alimtalk/fetch", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity fetch(@RequestBody IupAlimtalkReqVO reqDTO){ - EnsResponseVO responseVO = iupAlimtalkService.fetch(reqDTO.getLnkInputId()); - return new ResponseEntity(responseVO, HttpStatus.OK); - } -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/sched/IupAlimtalkScheduler.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/sched/IupAlimtalkScheduler.java deleted file mode 100644 index cd35f06..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/sched/IupAlimtalkScheduler.java +++ /dev/null @@ -1,45 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.sched; - -import cokr.xit.ens.biz.iup.alimtalk.service.IupAlimtalkService; -import cokr.xit.ens.core.aop.EnsResponseVO; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; - -@Slf4j -//@Component -//@Profile("prod-iup") -@RequiredArgsConstructor -public class IupAlimtalkScheduler { - - private final IupAlimtalkService iupAlimtalkService; - - /** - * 알림톡 접수 - * -. 알림톡 전송을 위해 IUP에 등록된 기초데이터를 ENS에 이관 등록 한다. - */ - @Scheduled(cron = "0 */5 7-22 * * *") - public void accepted() { - EnsResponseVO responseVO = iupAlimtalkService.acceptAll(); - - log.info("======================================================="); - log.info("[IUP] 알림톡 접수처리 결과"); - log.info(responseVO.toString()); - log.info("======================================================="); - } - - - /** - * 알림톡 결과 가져오기 - * -. 전송이 완료된 알림톡 전송결과(성공/실패)를 ENS -> IUP 로 가져온다. - */ - @Scheduled(cron = "0 */15 7-22 * * *") - public void fetched() { - EnsResponseVO responseVO = iupAlimtalkService.fetchAll(); - - log.info("======================================================="); - log.info("[IUP] 알림톡 전송결과 Fetch"); - log.info(responseVO.toString()); - log.info("======================================================="); - } -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupAlimtalkService.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupAlimtalkService.java deleted file mode 100644 index 560547a..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupAlimtalkService.java +++ /dev/null @@ -1,164 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service; - -import cokr.xit.ens.biz.iup.alimtalk.service.support.IupAlimtalkAcceptor; -import cokr.xit.ens.biz.iup.alimtalk.service.support.IupAlimtalkFetcher; -import cokr.xit.ens.biz.iup.alimtalk.service.support.IupAlimtalkMaker; -import cokr.xit.ens.biz.iup.alimtalk.service.support.IupAlimtalkSender; -import cokr.xit.ens.biz.iup.code.IupPrcsCd; -import cokr.xit.ens.biz.iup.code.IupSendTypeCd; -import cokr.xit.ens.biz.iup.domain.TbInputXit; -import cokr.xit.ens.biz.iup.domain.repository.TbInputXitRepository; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.modules.kkoalimtalk.service.event.KkoAlimtalkSendReserveEvent; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - - -@Slf4j -@Service -@RequiredArgsConstructor -@Transactional -public class IupAlimtalkService { - - - - private final TbInputXitRepository tbInputXitRepository; - - private final IupAlimtalkAcceptor iupAlimtalkAcceptor; - private final IupAlimtalkMaker iupAlimtalkMaker; - private final IupAlimtalkSender iupAlimtalkSender; - private final IupAlimtalkFetcher iupAlimtalkFetcher; - - private final ApplicationEventPublisher applicationEventPublisher; - - - /** - * 인증톡 접수(IUP -> ENS) - */ - public EnsResponseVO accept(Long lnkInputId){ - - try { - - TbInputXit tbInputXit = tbInputXitRepository.findByPrcsCdAndSendTypeAndId(IupPrcsCd.TGRG, IupSendTypeCd.NI, lnkInputId) - .orElseThrow(()->new EnsException(EnsErrCd.ACPT404, "일치하는 자료가 없거나 \"등록(TGRG)\" 상태가 아닙니다.")); - - return this.accept(Arrays.asList(tbInputXit)).getResultInfo().get(0); - } catch (EnsException e){ - return EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } - } - /** - * 인증톡 접수(IUP -> ENS) - */ - public EnsResponseVO> acceptAll(){ - try { - - List tbInputXits = tbInputXitRepository.findAllByPrcsCdInAndSendType(Arrays.asList(IupPrcsCd.TGRG), IupSendTypeCd.NI); - if(CmmnUtil.isEmpty(tbInputXits)) - throw new EnsException(EnsErrCd.ACPT404, "\"등록(TGRG)\" 상태의 자료가 없습니다."); - - return this.accept(tbInputXits); - } catch (EnsException e){ - return EnsResponseVO.>errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } - } - private EnsResponseVO> accept(List tbInputXits){ - iupAlimtalkAcceptor.statReady(tbInputXits.stream().map(row -> row.getLnkInputId()).collect(Collectors.toList())); - - List resultInfo = tbInputXits.stream() - .map(row -> iupAlimtalkAcceptor.execute(row.getLnkInputId())) - .collect(Collectors.toList()); - - - List sendMastIds = resultInfo.stream() - .filter(ensResponseVO -> EnsErrCd.OK.equals(ensResponseVO.getErrCode())) - .map(ensResponseVO -> (Long)((Map)ensResponseVO.getResultInfo()).get("sendMastId")) - .collect(Collectors.toList()); - KkoAlimtalkSendReserveEvent event = KkoAlimtalkSendReserveEvent.builder() - .sendMastIds(sendMastIds) - .callback(() -> this.fetch(tbInputXits)) - .build(); - applicationEventPublisher.publishEvent(event); - - return EnsResponseVO.>okBuilder().resultInfo(resultInfo).build(); - } - - /** - * 인증톡 제작 재요청 - * @param lnkInputId - * @return - */ - public EnsResponseVO reMake(Long lnkInputId){ - return iupAlimtalkMaker.execute(lnkInputId); - } - - - /** - * 인증톡 전송 재요청 - * @param lnkInputId - * @return - */ - public EnsResponseVO reSend(Long lnkInputId){ - return iupAlimtalkSender.execute(lnkInputId); - } - - - /** - * 인증톡 전송(성공/실패) 결과 가져오기 - */ - public EnsResponseVO fetch(Long lnkInputId){ - TbInputXit tbInputXit = null; - try { - tbInputXit = tbInputXitRepository.findById(lnkInputId) - .orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("[ lnkInputId %s ]와 일치하는 자료가 없습니다.", lnkInputId))); - if(!IupSendTypeCd.NI.equals(tbInputXit.getSendType())) - new EnsException(EnsErrCd.ERR404, String.format("[ lnkInputId %s ]는 인증톡 자료가 아닙니다.", lnkInputId)); - } catch (EnsException e) { - return EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } - - return this.fetch(Arrays.asList(tbInputXit)); - } - - /** - * 인증톡 전송(성공/실패) 결과 모두 가져오기 - */ - public EnsResponseVO fetchAll(){ - List tbInputXits = tbInputXitRepository.findAllByPrcsCdInAndSendType(Arrays.asList(IupPrcsCd.TGRC), IupSendTypeCd.NI); - - return this.fetch(tbInputXits); - } - - private EnsResponseVO fetch(List tbInputXits){ - iupAlimtalkFetcher.statReady(tbInputXits.stream().map(row -> row.getLnkInputId()).collect(Collectors.toList())); - - return EnsResponseVO.okBuilder() - .resultInfo( - tbInputXits.stream() - .map(row -> iupAlimtalkFetcher.execute(row.getLnkInputId())) - .collect(Collectors.toList() - ) - ) - .build(); - } -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupBillPayApiAlimtalkService.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupBillPayApiAlimtalkService.java deleted file mode 100644 index 296e64d..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/IupBillPayApiAlimtalkService.java +++ /dev/null @@ -1,430 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service; - -import cokr.xit.ens.biz.iup.billpay.service.IupBillPayApiServiceSupport; -import cokr.xit.ens.biz.iup.domain.TbEnfrcLevRciv; -import cokr.xit.ens.biz.iup.domain.TbInputDataXit; -import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfo; -import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfoSn; -import cokr.xit.ens.biz.iup.domain.repository.TbEnfrcLevRcivRepository; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoRepository; -import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoSnRepository; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoClientApiSpec; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.code.BillKkoErrCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.TmpltMng; -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.OrgMngRepository; -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.TmpltMngRepository; -import cokr.xit.ens.modules.kkoalimtalk.domain.SendDetailKkoAlimtalk; -import cokr.xit.ens.modules.kkoalimtalk.domain.repository.SendDetailKkoAlimtalkRepository; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.text.SimpleDateFormat; -import java.util.*; - -@Slf4j -@Service("iupBillPayApiService_NI") -@RequiredArgsConstructor -public class IupBillPayApiAlimtalkService extends IupBillPayApiServiceSupport { - - - private final SendDetailKkoAlimtalkRepository sendDetailKkoAlimtalkRepository; - private final TmpltMngRepository sendTmpltMngRepository; - private final OrgMngRepository orgMngRepository; - private final TbInputDataXitRepository tbInputDataXitRepository; - private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; - private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; - private final TbEnfrcLevRcivRepository tbEnfrcLevRcivRepository; - private final BillKkoClientApiSpec billKkoClientApi; - - - /** - * 청구서 조회 - * - * @param mParam - * @return - */ - @Transactional - public BillKkoApiRespDTO findNoticeInfo(Map mParam) { - Map data = (Map) mParam.get("data"); -// data.get("biller_user_key"); -// data.get("billed_year_month"); -// data.get("ordinal"); -// data.get("biller_notice_key"); - Map parameters = (Map) data.get("parameters"); -// data.get("user_birth"); - - - Map respData = null; - BillKkoApiRespDTO respVO = null; - BillKkoErrCd kkoBillErrCd = BillKkoErrCd.OK; - final String billerUserKey = Optional.ofNullable(data.get("biller_user_key")).isPresent() ? - String.valueOf(data.get("biller_user_key")) : null; - final String userBirth = Optional.ofNullable(data.get("user_birth")).isPresent() ? - String.valueOf(data.get("user_birth")) : null; - final String orgCd = Optional.ofNullable(parameters.get("orgCd")).isPresent() ? - String.valueOf(parameters.get("orgCd")) : null; - final String billUid = Optional.ofNullable(parameters.get("billUid")).isPresent() ? - String.valueOf(parameters.get("billUid")) : null; - - BillHist billHist = null; - try { - billHist = this.addBillHistByReqInfo(BillReqSeCd.NOTICE, billerUserKey, orgCd, billUid, mParam); - - - if (CmmnUtil.isEmpty(billerUserKey)) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR401, "사용자식별키가 없습니다."); - } - if (CmmnUtil.isEmpty(orgCd)) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR401, "기관코드가 없습니다."); - } - if (CmmnUtil.isEmpty(userBirth)) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR401, "생년월일이 없습니다."); - } - - - Optional orgMng = orgMngRepository.findById(orgCd); - if (!orgMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); - } - Optional sendDetailKkoAlimtalk = sendDetailKkoAlimtalkRepository.findByMsgIdx(billerUserKey); - if (!sendDetailKkoAlimtalk.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 발송상세 자료가 없습니다."); - } - Optional sendTmpltMng = sendTmpltMngRepository.findFetchByOrgCdAndTmpltCdAndUseYn(orgCd, sendDetailKkoAlimtalk.get().getSendMast().getTmpltCd(), "Y"); - if (!sendTmpltMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 템플릿정보가 없습니다."); - } - Optional tbInputDataXit = tbInputDataXitRepository.findByLinkedUuid(billerUserKey); - if (!tbInputDataXit.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 발송상세정보가 없습니다."); - } - final String dataId = tbInputDataXit.get().getDataId(); - - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { - Optional vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId); - if (!vKakaoNoticeInfoSn.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 단순미납부과 자료가 없습니다."); - } - if (!userBirth.equals(vKakaoNoticeInfoSn.get().getUserBirth())) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR402, "생년월일이 일치하지 않습니다."); - } - - respData = this.respNoticeSnData(sendTmpltMng.get().getTitle(), orgMng.get(), vKakaoNoticeInfoSn.get()); - - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { - if (dataId.length() < 20) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR403, "빌러코드가 20자리 미만 입니다."); - } - Optional vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)); - if (!vKakaoNoticeInfo.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 강제징수부과 자료가 없습니다."); - } - if (!userBirth.equals(vKakaoNoticeInfo.get().getUserBirth())) { - kkoBillErrCd = BillKkoErrCd.E404; - throw new EnsException(EnsErrCd.ERR402, "생년월일이 일치하지 않습니다."); - } - - respData = this.respNoticeData(sendTmpltMng.get().getTitle(), orgMng.get(), vKakaoNoticeInfo.get()); - - } else { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR999, "위탁업체여부 구분값이 등록되지 않았습니다."); - } - - - - respVO = BillKkoApiRespDTO.okBuilder() - .data(respData) - .build(); - - - this.modifyBillHistByRespInfo(billHist, respVO, null, null); - - } catch (EnsException e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(kkoBillErrCd.getCode()) - .message(kkoBillErrCd.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, e.getErrCd(), e.getMessage()); - - } catch (Exception e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(BillKkoErrCd.E801.getCode()) - .message(BillKkoErrCd.E801.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, EnsErrCd.ERR999, e.getMessage()); - } - - return respVO; - } - - - /** - * 납부 가능 조회 - * - * @param mParam - * @return - */ - @Transactional - public BillKkoApiRespDTO findPrepayInfo(Map mParam) { - Map data = (Map) mParam.get("data"); -// data.get("biller_user_key"); -// data.get("billed_year_month"); -// data.get("ordinal"); -// data.get("biller_notice_key"); - Map parameters = (Map) data.get("parameters"); -// data.get("amount"); - - - BillKkoApiRespDTO respVO = null; - BillKkoErrCd kkoBillErrCd = BillKkoErrCd.OK; - final String billerUserKey = Optional.ofNullable(data.get("biller_user_key")).isPresent() ? - String.valueOf(data.get("biller_user_key")) : null; - final int amount = Optional.ofNullable(data.get("amount")).isPresent() ? - (int) data.get("amount") : 0; - final String orgCd = Optional.ofNullable(parameters.get("orgCd")).isPresent() ? - String.valueOf(parameters.get("orgCd")) : null; - final String billUid = Optional.ofNullable(parameters.get("billUid")).isPresent() ? - String.valueOf(parameters.get("billUid")) : null; - - BillHist billHist = null; - try { - billHist = this.addBillHistByReqInfo(BillReqSeCd.PREPAY, billerUserKey, orgCd, billUid, mParam); - - - if (CmmnUtil.isEmpty(billerUserKey)) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR401, "사용자식별키가 없습니다."); - } - if (CmmnUtil.isEmpty(orgCd)) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR401, "기관코드가 없습니다."); - } - - - - Optional orgMng = orgMngRepository.findById(orgCd); - if (!orgMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); - } - Optional tbInputDataXit = tbInputDataXitRepository.findByLinkedUuid(billerUserKey); - if (!tbInputDataXit.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E402; - throw new EnsException(EnsErrCd.ERR404, "일치하는 발송상세정보가 없습니다."); - } - final String dataId = tbInputDataXit.get().getDataId(); - Optional vKakaoNoticeInfo = Optional.ofNullable(null); - List tbEnfrcLevRcivs = new ArrayList<>(); - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { - if (dataId.length() < 20) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR403, "빌러코드가 20자리 미만 입니다."); - } - Optional vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId); - if (!vKakaoNoticeInfoSn.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E502; - throw new EnsException(EnsErrCd.ERR404, "일치하는 단순미납 자료가 없습니다."); - } - - respVO = billKkoClientApi.callApiByOrg(orgMng.get().getKkoBpCsignPrepayApi(), mParam); - - if ("OK".equals(respVO.getRes_code())) - this.modifyBillHistByRespInfo(billHist, respVO, null, null); - else - this.modifyBillHistByRespInfo(billHist, respVO, EnsErrCd.ERR999, String.format("[%s] %s", respVO.getRes_code(), respVO.getMessage())); - - return respVO; - - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { - vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)); - if (!vKakaoNoticeInfo.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E502; - throw new EnsException(EnsErrCd.ERR404, "일치하는 강제징구 자료가 없습니다."); - } - - tbEnfrcLevRcivs = tbEnfrcLevRcivRepository.findAllByEnfrcLevMastrIdAndDeleteAt(dataId.substring(0, 20), "N"); - - } else { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR999, "위탁업체여부 구분값이 등록되지 않았습니다."); - } - - - if (CmmnUtil.isEmpty(vKakaoNoticeInfo.get().getAmount()) - || amount != Integer.parseInt(vKakaoNoticeInfo.get().getAmount())) { - kkoBillErrCd = BillKkoErrCd.E403; - throw new EnsException(EnsErrCd.ERR902 - , String.format("납부 가능 금액이 없거나 일치하지 않습니다. (요청금액:%s, 실제금액:%s)" - , amount - , vKakaoNoticeInfo.get().getAmount())); - } - if (amount > Integer.parseInt(vKakaoNoticeInfo.get().getAmount())) { - kkoBillErrCd = BillKkoErrCd.E501; - throw new EnsException(EnsErrCd.ERR902 - , String.format("납부 가능 금액을 초과했습니다. (요청금액:%s, 실제금액:%s)" - , amount - , vKakaoNoticeInfo.get().getAmount())); - } - if (!vKakaoNoticeInfo.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E502; - throw new EnsException(EnsErrCd.ERR404, "일치하는 청구서자료가 없습니다."); - } - if (CmmnUtil.isEmpty(vKakaoNoticeInfo.get().getPayExpireDate())) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR401, "납부기한이 값이 없습니다."); - } - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); - if (Integer.parseInt(vKakaoNoticeInfo.get().getPayExpireDate()) < Integer.parseInt(simpleDateFormat.format(new Date()))) { - kkoBillErrCd = BillKkoErrCd.E506; - throw new EnsException(EnsErrCd.ERR902, "납부기한이 경과한 자료 입니다."); - } - if (tbEnfrcLevRcivs.size() > 0) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR903, "납부가 완료된 자료 입니다."); - } - - - respVO = BillKkoApiRespDTO.okBuilder() - .data(null) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, null, null); - - } catch (EnsException e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(kkoBillErrCd.getCode()) - .message(kkoBillErrCd.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, e.getErrCd(), e.getMessage()); - - } catch (Exception e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(BillKkoErrCd.E601.getCode()) - .message(BillKkoErrCd.E601.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, EnsErrCd.ERR999, e.getMessage()); - } - - return respVO; - } - - /** - * 납부결과 저장 - * - * @param mParam - * @return - */ - @Transactional - public BillKkoApiRespDTO addPayReultIfno(Map mParam) { - Map data = (Map) mParam.get("data"); -// data.get("biller_user_key"); -// data.get("billed_year_month"); -// data.get("ordinal"); -// data.get("biller_notice_key"); - Map parameters = (Map) data.get("parameters"); -// data.get("pay_by"); -// data.get("pay_type"); -// data.get("pay_detail1"); -// data.get("pay_detail2"); -// data.get("pay_detail3"); -// data.get("amount"); -// data.get("pay_amount"); -// data.get("pay_fee_type"); -// data.get("pay_fee"); -// data.get("pay_fee_tax"); -// data.get("adjust_date"); -// data.get("paid_at"); -// data.get("pay_id"); - - - BillKkoApiRespDTO respVO = null; - BillKkoErrCd kkoBillErrCd = BillKkoErrCd.OK; - final String billerUserKey = Optional.ofNullable(data.get("biller_user_key")).isPresent() ? - String.valueOf(data.get("biller_user_key")) : null; - final String orgCd = Optional.ofNullable(parameters.get("orgCd")).isPresent() ? - String.valueOf(parameters.get("orgCd")) : null; - final String billUid = Optional.ofNullable(parameters.get("billUid")).isPresent() ? - String.valueOf(parameters.get("billUid")) : null; - - BillHist billHist = null; - try { - billHist = this.addBillHistByReqInfo(BillReqSeCd.PAYRSLT, billerUserKey, orgCd, billUid, mParam); - - - if (CmmnUtil.isEmpty(billerUserKey)) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR401, "사용자식별키가 없습니다."); - } - if (CmmnUtil.isEmpty(orgCd)) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR401, "기관코드가 없습니다."); - } - - - - Optional orgMng = orgMngRepository.findById(orgCd); - if (!orgMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); - } - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { - return billKkoClientApi.callApiByOrg(orgMng.get().getKkoBpCsignPayresultApi(), mParam); - - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { - - } else { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR999, "위탁업체여부 구분값이 등록되지 않았습니다."); - } - - - respVO = BillKkoApiRespDTO.okBuilder() - .data(null) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, null, null); - } catch (EnsException e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(kkoBillErrCd.getCode()) - .message(kkoBillErrCd.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, e.getErrCd(), e.getMessage()); - } catch (Exception e) { - respVO = BillKkoApiRespDTO.errBuilder() - .resCode(BillKkoErrCd.E601.getCode()) - .message(BillKkoErrCd.E601.getCodeNm()) - .build(); - - this.modifyBillHistByRespInfo(billHist, respVO, EnsErrCd.ERR999, e.getMessage()); - } - - return respVO; - } -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkAcceptor.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkAcceptor.java deleted file mode 100644 index d1c4da1..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkAcceptor.java +++ /dev/null @@ -1,294 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service.support; - -import cokr.xit.ens.biz.iup.code.IupPrcsCd; -import cokr.xit.ens.biz.iup.code.IupSendTypeCd; -import cokr.xit.ens.biz.iup.domain.TbInputDataXit; -import cokr.xit.ens.biz.iup.domain.TbInputXit; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.biz.iup.domain.repository.TbInputXitRepository; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.core.utils.MapDeserailizer; -import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; -import cokr.xit.ens.modules.common.code.VenderCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.config.CustomUrl; -import cokr.xit.ens.modules.kkoalimtalk.model.KkoAlimtalkAcceptReqDTO; -import cokr.xit.ens.modules.kkoalimtalk.model.config.*; -import cokr.xit.ens.modules.kkoalimtalk.service.KkoAlimtalkService; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import net.bytebuddy.utility.RandomString; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -@Slf4j -@Component -@RequiredArgsConstructor -public class IupAlimtalkAcceptor implements EnsPhaseProcSupport { - - private final TbInputXitRepository tbInputXitRepository; - private final TbInputDataXitRepository tbInputDataXitRepository; - - private final KkoAlimtalkService kkoAlimtalkService; - - Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create(); - - @Value("${contract.kakao.pay.bill.dozn.api.validate.host}") - private String BILL_HOST; - @Value("${contract.kakao.pay.bill.dozn.api.validate.notice}") - private String BILL_NOTICE_URL; - @Value("${contract.kakao.pay.bill.dozn.api.validate.prepay}") - private String BILL_PREPAY_URL; - @Value("${contract.kakao.pay.bill.dozn.api.validate.payresult}") - private String BILL_PAYREUSLT_URL; - - /** - * Accept 준비 - * - * @param lnkInputIds - * @return - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statReady(List lnkInputIds) { - - - try { - AtomicInteger index = new AtomicInteger(); - String prefixLinkedUuid = String.format("B-KKOAT-%s%s", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")), RandomString.make(5)); - lnkInputIds.stream() - .map(lnkInputId -> tbInputXitRepository.findById(lnkInputId).get()) - .map(tbinput -> tbInputDataXitRepository.findAllByTbInputXit(tbinput)) - .forEach(list -> { - list.stream() - .forEach(row -> { - log.info(row.toString()); -// row.setLinkedUuid(String.format("%s%05d", prefixLinkedUuid, index.getAndIncrement() + 1)); - row.setLinkedUuid(row.getDataId()); - }); - tbInputDataXitRepository.saveAll(list); - - } - - ); - } catch (Exception e) { - return EnsResponseVO.errBuilder() - .errCode(EnsErrCd.ACPT500) - .errMsg(String.format("연계식별UUID 생성에 실패 했습니다. %s", e.getMessage())) - .build(); - } - - EnsResponseVO respVO = null; - try { - /** - * 필수값 확인 - */ - if (CmmnUtil.isEmpty(lnkInputIds)) - throw new EnsException(EnsErrCd.ACPT410, "연계입수아이디(은)는 필수조건 입니다."); - - /** - * 저장 - * -. 발송마스터의 상태를 "대상이관등록(TGRI)" 으로 변경 한다. - */ - - List resultInfo = tbInputXitRepository.findAllByLnkInputIdIn(lnkInputIds).stream() - .map(row -> { - row.setUpdId("ENS_SYS"); - row.setPrcsCd(IupPrcsCd.TGRI); - return row.getLnkInputId(); - }) - .collect(Collectors.toList()); - - respVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); - } catch (EnsException e) { - respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); - } catch (Exception e) { - respVO = EnsResponseVO.errBuilder().errCode(EnsErrCd.ACPT999).errMsg(e.getMessage()).build(); - } - - return respVO; - } - - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statBegin(Long arg) { - log.info("no process"); - return null; - } - - - /** - * 알림톡 전자고지 접수 - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO execute(Long lnkInputId) { - Map resultInfo = new HashMap<>(); - resultInfo.put("lnkInputId", lnkInputId); - - EnsResponseVO responseVO = null; - TbInputXit tbInputXit = null; - try { - tbInputXit = tbInputXitRepository.findById(lnkInputId) - .orElseThrow(() -> new EnsException(EnsErrCd.ACPT404, String.format("일치하는 TB_INPUT_XIT 데이터가 없습니다. [ lnkInputId %s ]", lnkInputId))); - - KkoAlimtalkAcceptReqDTO reqDTO = this.convertTbInputDataToAcceptReqDTO(tbInputDataXitRepository.findAllFetchByLnkInputId(tbInputXit.getLnkInputId())); - - EnsResponseVO reqResp = kkoAlimtalkService.accept(reqDTO); - - - if (EnsErrCd.OK.equals(reqResp.getErrCode())) { - resultInfo.put("sendMastId", (Long) ((Map) reqResp.getResultInfo()).get("sendMastId")); - responseVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); - } else { - responseVO = EnsResponseVO.errRsltBuilder() - .errCode(reqResp.getErrCode()) - .errMsg(reqResp.getErrMsg()) - .resultInfo(reqResp.getResultInfo()) - .build(); - } - } catch (EnsException e) { - responseVO = EnsResponseVO.errRsltBuilder() - .errCode(e.getErrCd()) - .errMsg(String.format("알림톡 \"접수\" 처리 실패. [%s] %s", e.getErrCd().getCode(), e.getMessage())) - .resultInfo(resultInfo) - .build(); - - } catch (Exception e) { - responseVO = EnsResponseVO.errRsltBuilder() - .errCode(EnsErrCd.ACPT500) - .errMsg(String.format("알림톡 \"접수\" 처리 실패. %s", e.getMessage())) - .resultInfo(resultInfo) - .build(); - - } finally { - if (EnsErrCd.OK.equals(responseVO.getErrCode())) { - tbInputXit.setUpdId("ENS_SYS"); - tbInputXit.setPrcsCd(IupPrcsCd.TGRC); - tbInputXit.setErrMsg(null); - } else { - tbInputXit.setUpdId("ENS_SYS"); - tbInputXit.setPrcsCd(IupPrcsCd.TGRF); - tbInputXit.setErrMsg(responseVO.getErrMsg()); - } - } - - return responseVO; - } - - - private KkoAlimtalkAcceptReqDTO convertTbInputDataToAcceptReqDTO(List list) { - - return KkoAlimtalkAcceptReqDTO.builder() - .vender(VenderCd.biztalk.getCode()) - .org_cd(list.get(0).getTbInputXit().getOrgCd()) -// .tmplt_cd(list.get(0).getTbInputXit().getFsJob().getTemplateCd()) - .tmplt_cd(list.get(0).getTbInputXit().getFsJob().getJobCd()) - .post_bundle_title( - String.format("%s(%s건)-%s" - , IupSendTypeCd.NI.getCodeNm() - , list.get(0).getTbInputXit().getTotCnt() - , LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) - ) - ) - .send_dt(list.get(0).getTbInputXit().getRunDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) - .close_dt(list.get(0).getTbInputXit().getExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) - .documents( - list.stream() - .map(row -> createDocument(row)) - .collect(Collectors.toList()) - ) - .build(); - } - - private Document createDocument(TbInputDataXit data) throws EnsException { - - return Document.builder() -// .msg_idx(data.getDataId()) - .msg_idx(data.getLinkedUuid()) - .country_code("82") - .recipient(data.getMoblphonNo()) - .app_user_id(null) - .title(null) - .res_method("PUSH") - .attach(this.createAttach(data)) - .supplement(this.createSupplement(data)) - .message_type("AT") - .use_failback(null) - .mms_attach(this.createMmsAttach(data)) - .xit_property(this.createXitProperty(data)) - .build(); - } - - private Attachment createAttach(TbInputDataXit data) { - return null; - } - - private Supplement createSupplement(TbInputDataXit data) { - return null; - } - - private MmsAttach createMmsAttach(TbInputDataXit data) { - return null; - } - - private XitProperty createXitProperty(TbInputDataXit data) { - return XitProperty.builder() -// .bill_link_info(this.createBillLinkInfo(data)) - .bill_acpt_data(this.createBillAcptData(data)) - .tmplt_msg_data(CmmnUtil.isEmpty(data.getMsgData()) ? null : gson.fromJson(data.getMsgData().replace("~~@@!!", "#{").replace("!!@@~~", "}"), Map.class)) - .build(); - } - - -// return BillLinkInfo.builder() -// .button_name("납부하기") -// .button_type("WL") -// .expire_at(data.getTbInputXit().getPayExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) -// .notice_url(this.BILL_HOST + this.BILL_NOTICE_URL) -// .prepay_url(this.BILL_HOST + this.BILL_PREPAY_URL) -// .pay_result_url(this.BILL_HOST + this.BILL_PAYREUSLT_URL) -// .build(); -// } - protected BillAcptReqDTO createBillAcptData(TbInputDataXit data) { - return BillAcptReqDTO.builder() - .use_bill_uid(false) - .bill_uid(null) - .bill_se(BillSeCd.bpKko) - .bill_kko(BillKkoAcptReqVO.builder() - .billUid(null) - .billerUserKey(data.getLinkedUuid()) - .billedYearMonth(null) - .ordinal(null) - .billerNoticeKey(null) - .expireAt(data.getTbInputXit().getPayExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) - .parameters(null) - .customUrl(CustomUrl.builder() - .noticeUrl(this.BILL_HOST + this.BILL_NOTICE_URL) - .prepayUrl(this.BILL_HOST + this.BILL_PREPAY_URL) - .payResultUrl(this.BILL_HOST + this.BILL_PAYREUSLT_URL) - .build()) - .build()) - .build(); - } - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkFetcher.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkFetcher.java deleted file mode 100644 index cc69684..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkFetcher.java +++ /dev/null @@ -1,192 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service.support; - -import cokr.xit.ens.biz.iup.code.IupPrcsCd; -import cokr.xit.ens.biz.iup.code.IupSendSttusCd; -import cokr.xit.ens.biz.iup.code.IupSendTypeCd; -import cokr.xit.ens.biz.iup.domain.TbInputDataXit; -import cokr.xit.ens.biz.iup.domain.TbInputXit; -import cokr.xit.ens.biz.iup.domain.TbSendResult; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.biz.iup.domain.repository.TbInputXitRepository; -import cokr.xit.ens.biz.iup.domain.repository.TbSendResultRepository; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.core.utils.DateUtil; -import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; -import cokr.xit.ens.modules.common.code.StatCd; -import cokr.xit.ens.modules.kkoalimtalk.model.KkoAlimtalkRsltRespDTO; -import cokr.xit.ens.modules.kkoalimtalk.service.KkoAlimtalkService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Slf4j -@Component -@RequiredArgsConstructor -public class IupAlimtalkFetcher implements EnsPhaseProcSupport { - - private final TbInputXitRepository tbInputXitRepository; - private final TbInputDataXitRepository tbInputDataXitRepository; - - private final TbSendResultRepository tbSendResultRepository; - - private final KkoAlimtalkService kkoAlimtalkService; - - - - /** - * Fetch 준비 - * @param lnkInputIds - * @return - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statReady(List lnkInputIds) { - - EnsResponseVO respVO = null; - try { - if (CmmnUtil.isEmpty(lnkInputIds)) - throw new EnsException(EnsErrCd.RSLT410, "연계입수아이디(은)는 필수조건 입니다."); - - - List resultInfo = tbInputXitRepository.findAllByLnkInputIdIn(lnkInputIds).stream() - .map(row -> { - row.setUpdId("ENS_SYS"); - row.setPrcsCd(IupPrcsCd.INCM); - return row.getLnkInputId(); - }) - .collect(Collectors.toList()); - ; - respVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); - } catch (EnsException e) { - respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); - } catch (Exception e) { - respVO = EnsResponseVO.errBuilder().errCode(EnsErrCd.RSLT999).errMsg(e.getMessage()).build(); - } - - return respVO; - } - - - @Override - public EnsResponseVO statBegin(Long arg) { - log.info("no process"); - return null; - } - - - - - - /** - * 알림톡 발송(성공/실패) 자료에 대한 결과 가져오기 - * @param lnkInputId - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO execute(Long lnkInputId){ - EnsResponseVO responseVO = null; - Map resultInfo = new HashMap<>(); - resultInfo.put("lnkInputId", lnkInputId); - - try { - Long sendMastId = tbInputDataXitRepository.findLastSendMastIdByLnkInputIdAndSendType(lnkInputId, IupSendTypeCd.NI) - .orElseThrow(() -> new EnsException(EnsErrCd.RSLT404, "일치하는 ENS 접수자료가 없습니다.")); - resultInfo.put("sendMastId", sendMastId); - - - EnsResponseVO apiRespVO = kkoAlimtalkService.sendResultProvide(sendMastId); - KkoAlimtalkRsltRespDTO respDTO = (KkoAlimtalkRsltRespDTO) apiRespVO.getResultInfo(); - - - tbSendResultRepository.saveAll(respDTO.getDocuments().stream() - .map(row -> { - IupSendSttusCd iupSendSttusCd = null; - try { - switch (row.getKkoResultCd()){ - case RS_1000: - iupSendSttusCd = IupSendSttusCd.RECV; - break; - case RS_1014: - case RS_1015: - case RS_3018: - iupSendSttusCd = IupSendSttusCd.NOMB; - break; - case RQ_B400: - case RQ_B401: - case RQ_B402: - case RQ_B403: - case RS_1021: - case RS_1025: - iupSendSttusCd = IupSendSttusCd.DENY; - break; - default: - iupSendSttusCd = IupSendSttusCd.FAIL; - break; -// iupSendSttusCd = IupSendSttusCd.SEND; -// iupSendSttusCd = IupSendSttusCd.RECV; - } - } catch (Exception e){ - log.info("IupSendSttusCd와 일치하는 값 없음. [ dataId {} kkoResultCd {} ]", row.getMsgIdx(), row.getKkoResultCd()); - } - return TbSendResult.builder() - .lnkInputId(lnkInputId) -// .dataId(row.getMsgIdx()) - .dataId(tbInputDataXitRepository.findByLinkedUuid(row.getMsgIdx()) - .orElse(new TbInputDataXit()) - .getDataId()) - .prcsOdr(StatCd.close.equals(respDTO.getStatCd())?"2":"1") - .sendSttusCd(iupSendSttusCd) - .sendType(IupSendTypeCd.NI) - .runDt(DateUtil.toLocalDateTime(respDTO.getSendDt())) - .bizSendDt(null) - .bizRecvDt(null) - .bizReadDt(null) - .bizErrMsg(CmmnUtil.isEmpty(row.getErrorMessage()) ? null : row.getErrorMessage()) - .regId("ENS_SYS") - .regDt(LocalDateTime.now()) - .expiresDt(DateUtil.toLocalDateTime(respDTO.getCloseDt())) - .prcsYn("N") - .build(); - }) - .collect(Collectors.toList()) - ); - - responseVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); - } catch (EnsException e){ - responseVO = EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } catch (Exception e){ - responseVO = EnsResponseVO.errBuilder() - .errCode(EnsErrCd.RSLT999) - .errMsg(String.format("[lnkInputId %s]에 대한 전송결과 FETCH 처리 실패. %s", lnkInputId, e.getMessage())) - .build(); - } finally { - TbInputXit tbInputXit = tbInputXitRepository.findById(lnkInputId).orElseThrow(()->new EnsException(EnsErrCd.RSLT404, "일치하는 tbInputXit 자료가 없습니다.")); - if(EnsErrCd.OK.equals(responseVO.getErrCode())){ - tbInputXit.setUpdId("ENS_SYS"); - tbInputXit.setPrcsCd(IupPrcsCd.IPCP); - tbInputXit.setErrMsg(null); - }else{ - tbInputXit.setUpdId("ENS_SYS"); - tbInputXit.setPrcsCd(IupPrcsCd.FAIL); - tbInputXit.setErrMsg(responseVO.getErrMsg()); - } - } - - return responseVO; - } - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkMaker.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkMaker.java deleted file mode 100644 index a7f15c5..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkMaker.java +++ /dev/null @@ -1,66 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service.support; - -import cokr.xit.ens.biz.iup.code.IupSendTypeCd; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; -import cokr.xit.ens.modules.kkoalimtalk.service.KkoAlimtalkService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -@Slf4j -@Component -@RequiredArgsConstructor -public class IupAlimtalkMaker implements EnsPhaseProcSupport { - - private final TbInputDataXitRepository tbInputDataXitRepository; - - private final KkoAlimtalkService kkoAlimtalkService; - - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statReady(List lnkInputIds) { - log.info("no process"); - return null; - } - - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statBegin(Long arg) { - log.info("no process"); - return null; - } - - - - /** - * 알림톡 전자고지 제작 - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO execute(Long lnkInputId){ - EnsResponseVO responseVO = null; - try { - Long sendMastId = tbInputDataXitRepository.findLastSendMastIdByLnkInputIdAndSendType(lnkInputId, IupSendTypeCd.NI) - .orElseThrow(() -> new EnsException(EnsErrCd.MAKE404, "일치하는 ENS 접수자료가 없습니다.")); - - responseVO = kkoAlimtalkService.make(sendMastId); - } catch (EnsException e){ - responseVO = EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } - return responseVO; - } - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkSender.java b/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkSender.java deleted file mode 100644 index 8bb8a45..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/alimtalk/service/support/IupAlimtalkSender.java +++ /dev/null @@ -1,66 +0,0 @@ -package cokr.xit.ens.biz.iup.alimtalk.service.support; - -import cokr.xit.ens.biz.iup.code.IupSendTypeCd; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; -import cokr.xit.ens.modules.kkoalimtalk.service.KkoAlimtalkService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; - -@Slf4j -@Component -@RequiredArgsConstructor -public class IupAlimtalkSender implements EnsPhaseProcSupport { - - private final TbInputDataXitRepository tbInputDataXitRepository; - - private final KkoAlimtalkService kkoAlimtalkService; - - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statReady(List lnkInputIds) { - log.info("no process"); - return null; - } - - - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO statBegin(Long arg) { - log.info("no process"); - return null; - } - - - - /** - * 알림톡 전자고지 전송요청 - */ - @Override - @Transactional(propagation = Propagation.REQUIRES_NEW) - public EnsResponseVO execute(Long lnkInputId){ - EnsResponseVO responseVO = null; - try { - Long sendMastId = tbInputDataXitRepository.findLastSendMastIdByLnkInputIdAndSendType(lnkInputId, IupSendTypeCd.NI) - .orElseThrow(() -> new EnsException(EnsErrCd.SEND404, "일치하는 ENS 접수자료가 없습니다.")); - - responseVO = kkoAlimtalkService.sendBulk(sendMastId); - } catch (EnsException e){ - responseVO = EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } - return responseVO; - } - -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApi.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApi.java similarity index 98% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApi.java rename to src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApi.java index 6b0e112..861217a 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApi.java +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApi.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api; +package cokr.xit.ens.biz.iup.billpay.api; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.code.BillKkoErrCd; @@ -25,7 +25,7 @@ import java.util.Map; @Slf4j @Component @Profile({"!local-test"}) -public class BillKkoClientApi implements BillKkoClientApiSpec { +public class IupKkoPayUseSysApi implements IupKkoPayUseSysApiSpec { /** * 고객사별 납부가능조회 API 호출 diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiSpec.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiSpec.java similarity index 75% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiSpec.java rename to src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiSpec.java index dba42fd..1ca6393 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiSpec.java +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiSpec.java @@ -1,10 +1,10 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api; +package cokr.xit.ens.biz.iup.billpay.api; import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; import java.util.Map; -public interface BillKkoClientApiSpec { +public interface IupKkoPayUseSysApiSpec { /** * 고객사별 납부가능조회 API 호출 diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiTest.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiTest.java similarity index 96% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiTest.java rename to src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiTest.java index 3e42f24..7819160 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoClientApiTest.java +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/api/IupKkoPayUseSysApiTest.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api; +package cokr.xit.ens.biz.iup.billpay.api; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; @@ -16,7 +16,7 @@ import java.util.Map; @Slf4j @Component @Profile({"local-test"}) -public class BillKkoClientApiTest implements BillKkoClientApiSpec { +public class IupKkoPayUseSysApiTest implements IupKkoPayUseSysApiSpec { /** * 고객사별 납부가능조회 API 호출 diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayApiController.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillKkoPayUseSysController.java similarity index 94% rename from src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayApiController.java rename to src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillKkoPayUseSysController.java index 740ab43..f83c439 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayApiController.java +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillKkoPayUseSysController.java @@ -1,6 +1,6 @@ package cokr.xit.ens.biz.iup.billpay.presentation; -import cokr.xit.ens.biz.iup.billpay.service.IupBillPayApiServiceSupport; +import cokr.xit.ens.biz.iup.billpay.service.IupBillKkoPayUseSysService; import cokr.xit.ens.biz.iup.domain.TbInputDataXit; import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; import cokr.xit.ens.core.utils.CmmnUtil; @@ -22,15 +22,15 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Map; -@Tag(name = "IupBillPayApiController") +@Tag(name = "IupBillKkoPayUseSysController") @Slf4j @RequiredArgsConstructor @RestController -public class IupBillPayApiController { +public class IupBillKkoPayUseSysController { private final TbInputDataXitRepository tbInputDataXitRepository; - private final Map mIupBillPayApiService; + private final Map iupBillKkoPayUseSysServiceMap; @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { @@ -121,9 +121,9 @@ public class IupBillPayApiController { Map data = (Map) mParam.get("data"); String billerUserKey = (String) data.get("biller_user_key"); TbInputDataXit tbInputDataXit = tbInputDataXitRepository.findById(billerUserKey).orElseThrow(() -> new RuntimeException("biller_user_key와 일치하는 데이터를 찾을 수 없습니다.")); - IupBillPayApiServiceSupport iupBillPayService = mIupBillPayApiService.get("iupBillPayApiService_" + tbInputDataXit.getTbInputXit().getSendType()); + IupBillKkoPayUseSysService iupPayProcessService = iupBillKkoPayUseSysServiceMap.get("iupBillKkoPayUseSysService_" + tbInputDataXit.getTbInputXit().getSendType()); - return new ResponseEntity(iupBillPayService.findNoticeInfo(mParam), HttpStatus.OK); + return new ResponseEntity(iupPayProcessService.findNoticeInfo(mParam), HttpStatus.OK); } finally { @@ -186,7 +186,7 @@ public class IupBillPayApiController { Map data = (Map) mParam.get("data"); String billerUserKey = (String) data.get("biller_user_key"); TbInputDataXit tbInputDataXit = tbInputDataXitRepository.findById(billerUserKey).orElseThrow(() -> new RuntimeException("biller_user_key와 일치하는 데이터를 찾을 수 없습니다.")); - IupBillPayApiServiceSupport iupBillPayService = mIupBillPayApiService.get("iupBillPayApiService_" + tbInputDataXit.getTbInputXit().getSendType()); + IupBillKkoPayUseSysService iupBillPayService = iupBillKkoPayUseSysServiceMap.get("iupBillKkoPayUseSysService_" + tbInputDataXit.getTbInputXit().getSendType()); return new ResponseEntity(iupBillPayService.findPrepayInfo(mParam), HttpStatus.OK); @@ -253,7 +253,7 @@ public class IupBillPayApiController { Map data = (Map) mParam.get("data"); String billerUserKey = (String) data.get("biller_user_key"); TbInputDataXit tbInputDataXit = tbInputDataXitRepository.findById(billerUserKey).orElseThrow(() -> new RuntimeException("biller_user_key와 일치하는 데이터를 찾을 수 없습니다.")); - IupBillPayApiServiceSupport iupBillPayService = mIupBillPayApiService.get("iupBillPayApiService_" + tbInputDataXit.getTbInputXit().getSendType()); + IupBillKkoPayUseSysService iupBillPayService = iupBillKkoPayUseSysServiceMap.get("iupBillKkoPayUseSysService_" + tbInputDataXit.getTbInputXit().getSendType()); return new ResponseEntity(iupBillPayService.addPayReultIfno(mParam), HttpStatus.OK); diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayRsltFwdController.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayRsltFwdController.java deleted file mode 100644 index 96d9c1b..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupBillPayRsltFwdController.java +++ /dev/null @@ -1,109 +0,0 @@ -package cokr.xit.ens.biz.iup.billpay.presentation; - -import cokr.xit.ens.biz.iup.domain.TbInputXit; -import cokr.xit.ens.biz.iup.domain.repository.TbInputDataXitRepository; -import cokr.xit.ens.biz.iup.domain.repository.TbInputXitRepository; -import cokr.xit.ens.biz.iup.signtalk.model.IupSigntalkReqVO; -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.utils.MapDeserailizer; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.impl.BillKkoClientServiceImpl; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -@Tag(name = "IupBillPayRsltFwdController") -@Slf4j -@RequiredArgsConstructor -@RestController -public class IupBillPayRsltFwdController { - private final TbInputXitRepository tbInputXitRepository; - private final TbInputDataXitRepository tbInputDataXitRepository; - - private final BillKkoClientServiceImpl billKkoClientServiceImpl; - private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create(); - - @Operation(summary = "납부결과 전달(연계 입수 아이디)") - @PostMapping(value = "/iup/bill/payrslt/fwd/bulk", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity payrsltFwdBulk(@RequestBody IupSigntalkReqVO reqDTO) { - - TbInputXit tbInputXit = tbInputXitRepository.findById(reqDTO.getLnkInputId()) - .orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("연계입수아이디(%s)와 일치하는 자료가 없습니다.", reqDTO.getLnkInputId()))); - List billerUserKeys = tbInputDataXitRepository.findAllByTbInputXit(tbInputXit).stream() - .map(tbInputDataXit -> tbInputDataXit.getLinkedUuid()) - .collect(Collectors.toList()); - - - BillKkoApiRespDTO resultInfo = billKkoClientServiceImpl.fwdPayRslt(tbInputXit.getOrgCd(), billerUserKeys).getResultInfo(); - - return new ResponseEntity(EnsResponseVO.okBuilder().resultInfo(resultInfo).build(), HttpStatus.OK); - } - - - @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { - @Content(mediaType = "application/json", examples = { - @ExampleObject(name = "Sample Example..." - , summary = "sample" - , value = "{\"biller_user_key\":[\"abcd11234\",\"dddd1234\"]}") - }) - }) - @Operation(summary = "납부결과 전달(빌러 유저 키)") - @PostMapping(value = "/iup/bill/payrslt/fwd/ids", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity payrsltFwdIds(@RequestBody Map> mParam) { - List> data = mParam.get("biller_user_key").stream() - .map(s -> tbInputDataXitRepository.findById(s)) - .filter(tbInputDataXit -> tbInputDataXit.isPresent()) - .map(tbInputDataXit -> billKkoClientServiceImpl.fwdPayRslt(tbInputDataXit.get().getTbInputXit().getOrgCd(), Collections.singletonList(tbInputDataXit.get().getLinkedUuid()))) - .map(ensResponseVO -> ensResponseVO.getResultInfo().getData()) - .collect(Collectors.toList()); - BillKkoApiRespDTO resultInfo = BillKkoApiRespDTO.okBuilder().data(data).build(); - - return new ResponseEntity(EnsResponseVO.okBuilder().resultInfo(resultInfo).build(), HttpStatus.OK); - } - - -// @Operation(summary = "[미전달분-일회성] - 납부결과 전달(2022.07.04 09:00:00 ~ 2022.07.05 15:00:00 데이터)") -// @PostMapping(value = "/iup/bill/payrslt/fwd/bulk/temp", produces = MediaType.APPLICATION_JSON_VALUE) -// public ResponseEntity payrsltFwdBulkTemp() { -// -// List resultInfo = tbInputDataXitRepository.findAllByNoFwdPayResult().stream() -// .map(tbInputDataXit -> { -// String billerUserKey = tbInputDataXit.getLinkedUuid(); -// -// OrgMng orgMng = orgMngRepository.findById(tbInputDataXit.getTbInputXit().getOrgCd()).orElse(null); -// if (orgMng == null) -// return BillKkoApiRespDTO.errBuilder().resCode(EnsErrCd.ERR404.getCode()).message(String.format("기관코드(%s)와 일치하는 자료가 없습니다. [ biller_user_key %s ]", tbInputDataXit.getTbInputXit().getOrgCd(), billerUserKey)).build(); -// -// KkoBillHist kkoBillHist = kkoBillHistRepository.findByBillerUserKeyAndReqSeAndLast(billerUserKey, KkoBillReqSeCd.PAYRSLT).orElse(null); -// if (kkoBillHist == null) -// return BillKkoApiRespDTO.errBuilder().resCode(EnsErrCd.ERR404.getCode()).message(String.format(" 일치하는 청구서 납부결과가 없습니다. [ biller_user_key %s ]", billerUserKey)).build(); -// else { -// String uri = orgMng.getKkoBpCsignPayresultApi(); -// Map param = gson.fromJson(kkoBillHist.getRequestData(), Map.class); -// return kkoBillClientApi.callApiByOrg(uri, param); -// } -// }) -// .collect(Collectors.toList()); -// -// -// return new ResponseEntity(EnsResponseVO.okBuilder().resultInfo(resultInfo).build(), HttpStatus.OK); -// } -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupPayUseSysController.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupPayUseSysController.java new file mode 100644 index 0000000..507afd3 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/presentation/IupPayUseSysController.java @@ -0,0 +1,135 @@ +package cokr.xit.ens.biz.iup.billpay.presentation; + +import cokr.xit.ens.biz.iup.billpay.service.IupPayUseSysServiceFactory; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; +import java.util.Map; + +@Tag(name = "IupPayUseSysController") +@Slf4j +@RequiredArgsConstructor +@RestController +//public class IupPayUseSysController implements PayUseSysController> { +public class IupPayUseSysController { + + private final IupPayUseSysServiceFactory factory; + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "kkopay(카카오페이)" + , summary = "kkopay(카카오페이)" + , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}") + }) + }) + @Parameters({ + @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "청구서링크생성 정보") + @PostMapping(value = "/iup/bill/{paySe}/gnr/url", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity gnrUrl(@PathVariable String paySe, @RequestBody Map param) { + + if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).gnrUrl(param), HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "kkopay(카카오페이)" + , summary = "kkopay(카카오페이)" + , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"user_birth\":\"\",\"parameters\":{\"some_param\":\"\"}}}"), + @ExampleObject(name = "nvpay(네이버페이)" + , summary = "nvpay(네이버페이)" + , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}") + }) + }) + @Parameters({ + @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "납부(결제)정보") + @PostMapping(value = "/iup/bill/{paySe}/pay/notice", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity payNotice(@PathVariable String paySe, @RequestBody Map param) { + + if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payNotice(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "kkopay(카카오페이)" + , summary = "kkopay(카카오페이)" + , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"amount\":29000,\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"}}}"), + @ExampleObject(name = "nvpay(네이버페이)" + , summary = "nvpay(네이버페이)" + , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\",\"productName\":\"\",\"totalPayAmount\":1000,\"taxScopeAmount\":1000,\"taxExScopeAmount\":null}}") + }) + }) + @Parameters({ + @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "납부(결제)가능여부") + @PostMapping(value = "/iup/bill/{paySe}/pay/able", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity payAble(@PathVariable String paySe, @RequestBody Map param) { + if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payAble(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "kkopay(카카오페이)" + , summary = "kkopay(카카오페이)" + , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"},\"pay_by\":\"MONEY\",\"pay_type\":\"P\",\"pay_detail1\":\"\",\"pay_detail2\":\"\",\"amount\":20000,\"pay_amount\":20000,\"pay_fee_type\":\"BEFORE\",\"pay_fee\":150,\"pay_fee_tax\":15,\"paid_at\":\"20190220161656\",\"pay_id\":2748877}}"), + @ExampleObject(name = "nvpay(네이버페이)" + , summary = "nvpay(네이버페이)" + , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"paymentId\":\"네이버페이 결제번호\",\"detail\":{\"productName\":\"샘플상품\",\"merchantId\":\"loginId\",\"merchantName\":\"가맹점명\",\"cardNo\":\"465887**********\",\"admissionYmdt\":\"20170201151722\",\"payHistId\":\"20170201NP1043587781\",\"totalPayAmount\":1000,\"primaryPayAmount\":1000,\"npointPayAmount\":0,\"giftCardAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"primaryPayMeans\":\"CARD\",\"merchantPayKey\":\"청구서UID\",\"merchantUserKey\":\"빌러유저키\",\"cardCorpCode\":\"C0\",\"paymentId\":\"20170201NP1043587746\",\"admissionTypeCode\":\"01\",\"settleExpectAmount\":971,\"payCommissionAmount\":29,\"admissionState\":\"SUCCESS\",\"tradeConfirmYmdt\":\"20170201152510\",\"cardAuthNo\":\"17545616\",\"cardInstCount\":0,\"usedCardPoint\":false,\"bankCorpCode\":\"\",\"bankAccountNo\":\"\",\"settleExpected\":false,\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}}}") + }) + }) + @Parameters({ + @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "납부(결제)결과") + @PostMapping(value = "/iup/bill/{paySe}/pay/result", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity payResult(@PathVariable String paySe, @RequestBody Map param) { + + if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payResult(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "nvpay(네이버페이)" + , summary = "nvpay(네이버페이)" + , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"responseCount\":1,\"totalCount\":1,\"totalPageCount\":1,\"currentPageNumber\":1,\"list\":[{\"cardAuthNo\":\"00000000\",\"bankAccountNo\":\"\",\"bankCorpCode\":\"\",\"paymentId\":\"20170000NP1000229665\",\"cardCorpCode\":\"C0\",\"cardInstCount\":0,\"usedCardPoint\":false,\"settleInfo\":{\"primaryCommissionAmount\":30,\"npointCommissionAmount\":20,\"giftCardCommissionAmount\":0,\"primarySettleAmount\":470,\"npointSettleAmount\":480,\"giftCardSettleAmount\":0,\"totalSettleAmount\":850,\"totalCommissionAmount\":50,\"settleCreated\":true},\"merchantName\":\"나의가맹점\",\"productName\":\"나의상품\",\"payHistId\":\"20170000NP1000229668\",\"merchantId\":\"MID12345\",\"admissionYmdt\":\"20170914163930\",\"tradeConfirmYmdt\":\"20170915163956\",\"totalPayAmount\":1000,\"merchantPayKey\":\"orderKey-91516397\",\"merchantUserKey\":\"빌러유저키\",\"admissionTypeCode\":\"01\",\"primaryPayMeans\":\"CARD\",\"admissionState\":\"SUCCESS\",\"primaryPayAmount\":500,\"npointPayAmount\":500,\"giftCardPayAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"cardNo\":\"123456**********\",\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}]}}") + }) + }) + @Parameters({ + @Parameter(name = "paySe", example = "kkopay", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "결제취소정보") + @PostMapping(value = "/iup/bill/{paySe}/pay/cancel", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity payCancel(@PathVariable String paySe, @RequestBody Map param) { + + if (Arrays.stream(IupPayUseSysServiceFactory.IupPaySe.values()).noneMatch(iupPaySe -> iupPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + return new ResponseEntity(factory.getService(IupPayUseSysServiceFactory.IupPaySe.valueOf(paySe)).payCancel(param), HttpStatus.OK); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillPayApiServiceSupport.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillKkoPayUseSysService.java similarity index 62% rename from src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillPayApiServiceSupport.java rename to src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillKkoPayUseSysService.java index 1ba00de..333880e 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillPayApiServiceSupport.java +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupBillKkoPayUseSysService.java @@ -2,9 +2,17 @@ package cokr.xit.ens.biz.iup.billpay.service; import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfo; import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfoSn; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.BillKkoClientApiSupport; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Arrays; @@ -14,7 +22,75 @@ import java.util.Map; @Slf4j @Component -public abstract class IupBillPayApiServiceSupport extends BillKkoClientApiSupport { +public abstract class IupBillKkoPayUseSysService { + + @Autowired + private BillHistRepository billHistRepository; + + + /** + * 청구서 이력 저장 - 요청 + * + * @param reqSeCd + * @param billerUserKey + * @param orgCd + * @param mParam + * @return + */ + protected BillHist addBillHistByReqInfo(BillReqSeCd reqSeCd, String billerUserKey, String orgCd, String billUid, Map mParam) { + BillHist billHist = BillHist.builder() + .billSe(BillSeCd.bpKko) + .billUid(billUid) + .reqSe(reqSeCd) + .orgMng(orgCd == null ? null : OrgMng.builder().orgCd(orgCd).build()) + .linkedUuid(billerUserKey) + .requestData(CmmnUtil.toJsonString(mParam)) + .build(); + billHistRepository.save(billHist); + return billHist; + } + + /** + * 청구서 이력 저장 - 응답 + * + * @param billHist + * @param respData + * @param errCd + * @param errMsg + */ + protected void modifyBillHistByRespInfo(BillHist billHist, Object respData, EnsErrCd errCd, String errMsg) { + billHist.setResponseData(CmmnUtil.toJsonString(respData)); + billHist.setError(FieldError.initBuilder() + .errorCode(CmmnUtil.isEmpty(errCd) ? null : errCd.getCode()) + .errorMessage(errMsg) + .build()); + billHistRepository.save(billHist); + } + + /** + * 청구서 조회 + * + * @param mParam + * @return + */ + abstract public BillKkoApiRespDTO findNoticeInfo(Map mParam); + + /** + * 납부 가능 조회 + * + * @param mParam + * @return + */ + abstract public BillKkoApiRespDTO findPrepayInfo(Map mParam); + + /** + * 납부결과 저장 + * + * @param mParam + * @return + */ + abstract public BillKkoApiRespDTO addPayReultIfno(Map mParam); + /** * 청구서조회 "강제징수" 응답메시지 매핑 diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysService.java new file mode 100644 index 0000000..9a8a94e --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysService.java @@ -0,0 +1,6 @@ +package cokr.xit.ens.biz.iup.billpay.service; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayProcessService; + +public interface IupPayUseSysService extends PayProcessService { +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysServiceFactory.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysServiceFactory.java new file mode 100644 index 0000000..d5288fd --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/IupPayUseSysServiceFactory.java @@ -0,0 +1,32 @@ +package cokr.xit.ens.biz.iup.billpay.service; + +import cokr.xit.ens.biz.iup.billpay.service.impl.IupKkoPayUseSysServiceImpl; +import cokr.xit.ens.biz.iup.billpay.service.impl.IupNvPayUseSysServiceImpl; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class IupPayUseSysServiceFactory { + private final IupKkoPayUseSysServiceImpl iupKkoPayUseSysService; + private final IupNvPayUseSysServiceImpl iupNvPayUseSysService; + + public enum IupPaySe { + kkopay, + nvpay + } + + public IupPayUseSysService getService(IupPaySe iupPaySe) { + switch (iupPaySe) { + case kkopay: + return iupKkoPayUseSysService; + case nvpay: + return iupNvPayUseSysService; + default: + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + } + } + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupKkoPayUseSysServiceImpl.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupKkoPayUseSysServiceImpl.java new file mode 100644 index 0000000..183e53a --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupKkoPayUseSysServiceImpl.java @@ -0,0 +1,86 @@ +package cokr.xit.ens.biz.iup.billpay.service.impl; + +import cokr.xit.ens.biz.iup.billpay.service.IupPayUseSysService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupKkoPayAbleService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupKkoPayNoticeService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupKkoPayResultService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupKkoPayUrlService; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayUrlRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template.PayHelper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Map; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class IupKkoPayUseSysServiceImpl implements IupPayUseSysService> { + + private final IupKkoPayUrlService iupKkoPayUrlService; + private final IupKkoPayNoticeService iupKkoPayNoticeService; + private final IupKkoPayAbleService iupKkoPayAbleService; + private final IupKkoPayResultService iupKkoPayResultService; + + @Override + public PayApiRespDTO gnrUrl(Map param) { + Pay> pay = PayHelper., Map, PayApiRespDTO>builder() + .param(param) + .payHelperService(iupKkoPayUrlService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payNotice(Map param) { + Pay> pay = PayHelper., Map, PayApiRespDTO>builder() + .param(param) + .payHelperService(iupKkoPayNoticeService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payAble(Map param) { + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(iupKkoPayAbleService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payResult(Map param) { + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(iupKkoPayResultService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payCancel(Map param) { + return PayApiRespDTO.errBuilder() + .resCode(EnsErrCd.SERVICE_NOT_SUPPORTED.getCode()) + .message(EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm()) + .build(); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupNvPayUseSysServiceImpl.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupNvPayUseSysServiceImpl.java new file mode 100644 index 0000000..a8639bf --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/impl/IupNvPayUseSysServiceImpl.java @@ -0,0 +1,81 @@ +package cokr.xit.ens.biz.iup.billpay.service.impl; + +import cokr.xit.ens.biz.iup.billpay.service.IupPayUseSysService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupNvPayAbleService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupNvPayCancelService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupNvPayNoticeService; +import cokr.xit.ens.biz.iup.billpay.service.process.IupNvPayResultService; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template.PayHelper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Map; + + +@Slf4j +@Service +@RequiredArgsConstructor +public class IupNvPayUseSysServiceImpl implements IupPayUseSysService> { + + private final IupNvPayNoticeService iupNvPayNoticeService; + private final IupNvPayAbleService iupNvPayAbleService; + private final IupNvPayResultService iupNvPayResultService; + private final IupNvPayCancelService iupNvPayCancelService; + + @Override + public PayApiRespDTO gnrUrl(Map param) { + return PayApiRespDTO.errBuilder() + .resCode(EnsErrCd.SERVICE_NOT_SUPPORTED.getCode()) + .message(EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm()) + .build(); + } + + @Override + public PayApiRespDTO payNotice(Map param) { + Pay> pay = PayHelper., Map, PayApiRespDTO>builder() + .param(param) + .payHelperService(iupNvPayNoticeService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payAble(Map param) { + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(iupNvPayAbleService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payResult(Map param) { + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(iupNvPayResultService) + .build(); + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payCancel(Map param) { + return PayApiRespDTO.errBuilder() + .resCode(EnsErrCd.SERVICE_NOT_SUPPORTED.getCode()) + .message(EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm()) + .build(); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayAbleService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayAbleService.java new file mode 100644 index 0000000..c25cd9e --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayAbleService.java @@ -0,0 +1,217 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbEnfrcLevMastrRepository; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoSnRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayAbleService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupKkoPayAbleService implements PayAbleService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; + private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; + private final TbEnfrcLevMastrRepository tbEnfrcLevMastrRepository; + private final PayUseSysApi payUseSysApi; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + private Gson gson = new Gson(); + + private enum DataKeys { + tbInputDataXit, + payApiRespDTO, + responseJsonStr, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); +// Integer amount = (Integer) reqData.get("amount"); + + if (billerUserKey == null) billerUserKey = ""; + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + final String dataId = tbInputDataXit.getDataId(); + + if ("Y".equals(fsJob.getBpEntrustYn()) || "y".equals(fsJob.getBpEntrustYn())) { + + final String url = fsJob.getBpKkoPrepayApi(); + + VKakaoNoticeInfoSn vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 단순미납부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfoSn) + .map(entity -> payUseSysApi.payAble(url, reqParam, null)) + .map(response -> checkResponse(response)) + .map(payApiRespDTO -> loadRespData(data, payApiRespDTO)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "단순미납 응답데이터 수신에 실패했습니다.")) + ; + } else if ("N".equals(fsJob.getBpEntrustYn()) || "n".equals(fsJob.getBpEntrustYn())) { + if (dataId.length() < 20) + throw new EnsException(EnsErrCd.INVALID_DATA, "데이터ID가 20자리 미만 입니다."); + VKakaoNoticeInfo vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 강제징수부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfo) + .map(entity -> validateData(reqParam, entity)); + TbEnfrcLevMastr tbEnfrcLevMastr = tbEnfrcLevMastrRepository.findByEnfrcLevMastrIdAndEnfrcLevMastrProcessSttusAndDeleteAt(dataId.substring(0, 20), "04", "N") + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "납부가능 상태가 아닙니다.", PayUseSysResCd.NO_TARGET_PAYABLE)); + Optional.of(tbEnfrcLevMastr) + .map(entity -> createRespData()) + .map(payApiRespDTO -> loadRespData(data, payApiRespDTO)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "강제징수 응답데이터 생성에 실패했습니다.")); + } else { + throw new EnsException(EnsErrCd.INVALID_DATA, "위탁여부가 등록되지 않았습니다."); + } + + } + + private PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + return result; + } + + private PayApiRespDTO loadRespData(Map data, PayApiRespDTO payApiRespDTO) { + if (CmmnUtil.isEmpty(payApiRespDTO)) + return null; + + data.put(DataKeys.payApiRespDTO.name(), payApiRespDTO); + data.put(DataKeys.responseJsonStr.name(), gson.toJson(payApiRespDTO)); + return payApiRespDTO; + } + + private VKakaoNoticeInfo validateData(Map reqParam, VKakaoNoticeInfo vKakaoNoticeInfo) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + + final Integer amount = (Integer) reqData.getOrDefault("amount", 0); + if (amount != Integer.parseInt(vKakaoNoticeInfo.getAmount())) + throw new EnsException(EnsErrCd.INVALID_DATA + , String.format("납부 가능 금액이 없거나 일치하지 않습니다. (요청금액:%s, 실제금액:%s)", amount, vKakaoNoticeInfo.getAmount()) + , PayUseSysResCd.NO_AMOUNT_PAYABLE); + if (amount > Integer.parseInt(vKakaoNoticeInfo.getAmount())) + throw new EnsException(EnsErrCd.INVALID_DATA + , String.format("납부 가능 금액을 초과했습니다. (요청금액:%s, 실제금액:%s)", amount, vKakaoNoticeInfo.getAmount()) + , PayUseSysResCd.OVERPAYABLE_AMOUNT); + if (CmmnUtil.isEmpty(vKakaoNoticeInfo.getPayExpireDate())) + throw new EnsException(EnsErrCd.INVALID_DATA + , "납부기한의 값이 비어있습니다." + , PayUseSysResCd.EXPIRED_DATE); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); + if (Integer.parseInt(vKakaoNoticeInfo.getPayExpireDate()) < Integer.parseInt(simpleDateFormat.format(new Date()))) + throw new EnsException(EnsErrCd.INVALID_DATA + , "납부기한이 경과한 자료 입니다." + , PayUseSysResCd.EXPIRED_DATE); + + return vKakaoNoticeInfo; + } + + private PayApiRespDTO createRespData() { + return PayApiRespDTO.okBuilder().build(); + } + + + @Override + public PayApiRespDTO> generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + PayApiRespDTO payApiRespDTO = (PayApiRespDTO) data.get(DataKeys.payApiRespDTO.name()); + return gson.fromJson(gson.toJson(payApiRespDTO), PayApiRespDTO.class); + + } else { + if (e.getData() != null && e.getData() instanceof PayUseSysResCd) { + PayUseSysResCd resCode = (PayUseSysResCd) e.getData(); + return PayApiRespDTO.>errBuilder() + .resCode(resCode.getCode()) + .message(resCode.getCodeNm()) + .build(); + } else { + return PayApiRespDTO.>errBuilder() + .resCode(PayUseSysResCd.FAILED_CHECK_INFO.getCode()) + .message(PayUseSysResCd.FAILED_CHECK_INFO.getCodeNm()) + .build(); + } + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.kakaoPay) + .hisSeCd(PayUseSysHisSeCd.payAble) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayNoticeService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayNoticeService.java new file mode 100644 index 0000000..25be927 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayNoticeService.java @@ -0,0 +1,227 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoSnRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayNoticeService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupKkoPayNoticeService implements PayNoticeService, Map, PayApiRespDTO> { + + private final JPAQueryFactory query; + private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; + private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + private Gson gson = new Gson(); + + private enum DataKeys { + tbInputDataXit, + kkoPayNoticeRespData, + responseJsonStr, + } + + private enum PayDataKeys { + billerUserKey, + userBirth, + amount, + payExpireDate, + detailPasngChrgeSm, + detailAdiPasngChrgeSm, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); + + if (billerUserKey == null) billerUserKey = ""; + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + final String dataId = tbInputDataXit.getDataId(); + + if ("Y".equals(fsJob.getBpEntrustYn()) || "y".equals(fsJob.getBpEntrustYn())) { + VKakaoNoticeInfoSn vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 단순미납부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfoSn) + .map(entity -> toDataMap(entity)) + .map(payData -> validateData(reqParam, payData)) + .map(payData -> createRespData(tbInputDataXit, payData)) + .map(kkoPayNoticeRespData -> loadRespData(data, kkoPayNoticeRespData)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "단순미납 응답데이터 생성에 실패했습니다.")) + ; + } else if ("N".equals(fsJob.getBpEntrustYn()) || "n".equals(fsJob.getBpEntrustYn())) { + if (dataId.length() < 20) + throw new EnsException(EnsErrCd.INVALID_DATA, "데이터ID가 20자리 미만 입니다."); + VKakaoNoticeInfo vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 강제징수부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfo) + .map(entity -> toDataMap(entity)) + .map(map -> validateData(reqParam, map)) + .map(map -> createRespData(tbInputDataXit, map)) + .map(kkoPayNoticeRespData -> loadRespData(data, kkoPayNoticeRespData)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "강제징수 응답데이터 생성에 실패했습니다.")) + ; + } else { + throw new EnsException(EnsErrCd.INVALID_DATA, "위탁여부가 등록되지 않았습니다."); + } + + + } + + private Map toDataMap(VKakaoNoticeInfoSn vKakaoNoticeInfoSn) { + Map payData = new HashMap<>(); + payData.put(PayDataKeys.billerUserKey, vKakaoNoticeInfoSn.getDataId()); + payData.put(PayDataKeys.userBirth, vKakaoNoticeInfoSn.getUserBirth()); + payData.put(PayDataKeys.amount, vKakaoNoticeInfoSn.getAmount().intValue()); + payData.put(PayDataKeys.payExpireDate, vKakaoNoticeInfoSn.getPayExpireDate()); + payData.put(PayDataKeys.detailPasngChrgeSm, vKakaoNoticeInfoSn.getDetailPasngChrgeSm()); + payData.put(PayDataKeys.detailAdiPasngChrgeSm, vKakaoNoticeInfoSn.getDetailAdiPasngChrgeSm()); + return payData; + } + + private Map toDataMap(VKakaoNoticeInfo vKakaoNoticeInfo) { + Map payData = new HashMap<>(); + payData.put(PayDataKeys.billerUserKey, vKakaoNoticeInfo.getEnfrcLevMastrId()); + payData.put(PayDataKeys.userBirth, vKakaoNoticeInfo.getUserBirth()); + payData.put(PayDataKeys.amount, Integer.parseInt(vKakaoNoticeInfo.getAmount())); + payData.put(PayDataKeys.payExpireDate, vKakaoNoticeInfo.getPayExpireDate()); + payData.put(PayDataKeys.detailPasngChrgeSm, vKakaoNoticeInfo.getDetailPasngChrgeSm()); + payData.put(PayDataKeys.detailAdiPasngChrgeSm, vKakaoNoticeInfo.getDetailAdiPasngChrgeSm()); + return payData; + } + + private Map validateData(Map reqParam, Map payData) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + + String userBirth = (String) reqData.getOrDefault("user_birth", ""); + if (!userBirth.equals(payData.get(PayDataKeys.userBirth))) + throw new EnsException(EnsErrCd.INVALID_DATA, String.format("요청과 실제 생년월일이 일치하지 않습니다. (요청: %s 실제: %s)", userBirth, payData.get(PayDataKeys.userBirth))); + + return payData; + } + + + private KkoPayNoticeRespData createRespData(TbInputDataXit tbInputDataXit, Map payData) { + + Map detail = new HashMap<>(); + detail.put("item_type", "TEXT"); + detail.put("elements", Arrays.asList(String.format("상세 통행료: %s", payData.get(PayDataKeys.detailPasngChrgeSm)) + , String.format("상세 부가통행료: %s", payData.get(PayDataKeys.detailAdiPasngChrgeSm)))); + List> details = Arrays.asList(detail); + + return KkoPayNoticeRespData.builder() + .title(tbInputDataXit.getTbInputXit().getFsJob().getJobName()) + .amount((Integer) payData.get(PayDataKeys.amount)) + .expireType("D1") + .payExpireDate((String) payData.get(PayDataKeys.payExpireDate)) + .details(details) + .build(); + } + + private KkoPayNoticeRespData loadRespData(Map data, KkoPayNoticeRespData kkoPayNoticeRespData) { + if (CmmnUtil.isEmpty(kkoPayNoticeRespData)) + return null; + + data.put(DataKeys.kkoPayNoticeRespData.name(), kkoPayNoticeRespData); + data.put(DataKeys.responseJsonStr.name(), gson.toJson(kkoPayNoticeRespData)); + return kkoPayNoticeRespData; + } + + + @Override + public PayApiRespDTO generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + KkoPayNoticeRespData kkoPayNoticeRespData = (KkoPayNoticeRespData) data.get(DataKeys.kkoPayNoticeRespData.name()); + return PayApiRespDTO.okBuilder() + .data(kkoPayNoticeRespData) + .build(); + + } else { + String resCode = null; + String message = null; + switch (e.getErrCd()) { + case NO_DATA_FOUND: + resCode = PayUseSysResCd.NOT_FOUND_PAYDATA.getCode(); + message = PayUseSysResCd.NOT_FOUND_PAYDATA.getCodeNm(); + break; + default: + resCode = PayUseSysResCd.PAYDATA_FIND_FAILED.getCode(); + message = PayUseSysResCd.PAYDATA_FIND_FAILED.getCodeNm(); + break; + } + + return PayApiRespDTO.errBuilder() + .resCode(resCode) + .message(message) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.kakaoPay) + .hisSeCd(PayUseSysHisSeCd.payNotice) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayResultService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayResultService.java new file mode 100644 index 0000000..b9dacb5 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayResultService.java @@ -0,0 +1,191 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.TbKakaoPayResultRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayResultReqData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayResultService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupKkoPayResultService implements PayResultService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + private final PayUseSysApi payUseSysApi; + private final TbKakaoPayResultRepository tbKakaoPayResultRepository; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + + private Gson gson = new Gson(); + + private enum DataKeys { + tbInputDataXit, + responseJsonStr, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); + + if (billerUserKey == null) billerUserKey = ""; + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + + final String url = fsJob.getBpKkoPayresultApi(); + + + Optional.ofNullable(gson.fromJson(gson.toJson(reqParam.get("data")), KkoPayResultReqData.class)) + .map(kkoPayResultReqData -> toEntity(kkoPayResultReqData)) + .map(entity -> savePayResult(entity)) + .map(entity -> tbInputDataXit) + .filter(detail -> "Y".equals(detail.getTbInputXit().getFsJob())) + .map(vKakaoNoticeInfoSn -> payUseSysApi.payResult(url, reqParam, null)) + .map(response -> loadRespData(data, response)) + .map(response -> checkResponse(response)) + ; + + } + + private TbKakaoPayResult toEntity(KkoPayResultReqData kkoPayResultReqData) { + + + final String jobSe = "EL".equals(kkoPayResultReqData.getBillerUserKey().substring(0, 2)) ? "2" : "1"; + + + final String payAmount = CmmnUtil.isEmpty(kkoPayResultReqData.getPayAmount()) ? null : String.valueOf(kkoPayResultReqData.getPayAmount()); + final String payFee = CmmnUtil.isEmpty(kkoPayResultReqData.getPayFee()) ? null : String.valueOf(kkoPayResultReqData.getPayFee()); + final String payFeeTax = CmmnUtil.isEmpty(kkoPayResultReqData.getPayFeeTax()) ? null : String.valueOf(kkoPayResultReqData.getPayFeeTax()); + final String payId = CmmnUtil.isEmpty(kkoPayResultReqData.getPayId()) ? null : String.valueOf(kkoPayResultReqData.getPayId()); + + return TbKakaoPayResult.builder() + .dataId(kkoPayResultReqData.getBillerUserKey()) + .jobSe(jobSe) + .payMn(kkoPayResultReqData.getPayBy()) + .payTy(kkoPayResultReqData.getPayType()) + .payDetail1(kkoPayResultReqData.getPayDetail1()) + .payDetail2(kkoPayResultReqData.getPayDetail2()) + .payDetail3(kkoPayResultReqData.getPayDetail3()) + .payAmount(payAmount) + .payFeeTy(kkoPayResultReqData.getPayFeeType()) + .payFeeAmount(payFee) + .payFeeVat(payFeeTax) + .excclcPrearngeDe(kkoPayResultReqData.getAdjustDate()) + .payDt(kkoPayResultReqData.getPaidAt()) + .payId(payId) + .payResultProcessSttus("0") +// .creatDt() + .crtr("ENS_SYS") +// .updtDt() +// .updusr() + .build(); + + } + + private TbKakaoPayResult savePayResult(TbKakaoPayResult entity) { + tbKakaoPayResultRepository.save(entity); + return entity; + } + + private ResponseEntity loadRespData(Map data, ResponseEntity response) { + data.put(DataKeys.responseJsonStr.name(), response.getBody()); + return response; + } + + private PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + return result; + } + + @Override + public PayApiRespDTO> generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + return PayApiRespDTO.>okBuilder().build(); + + } else { + return PayApiRespDTO.>errDataBuilder() + .resCode(PayUseSysResCd.FAILED_SAVE_PAYRSLT.getCode()) + .message(PayUseSysResCd.FAILED_SAVE_PAYRSLT.getCodeNm()) + .data(null) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("biller_user_key"); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.kakaoPay) + .hisSeCd(PayUseSysHisSeCd.payResult) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayUrlService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayUrlService.java new file mode 100644 index 0000000..7d9f94f --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupKkoPayUrlService.java @@ -0,0 +1,147 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.CustomUrl; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayUrlRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayUrlService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupKkoPayUrlService implements PayUrlService, Map, PayApiRespDTO> { + + private final JPAQueryFactory query; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + + private Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + @Value("${contract.kakao.pay.bill.dozn.api.validate.host}") + private String BILL_HOST; + @Value("${contract.kakao.pay.bill.dozn.api.validate.notice}") + private String BILL_NOTICE_URL; + @Value("${contract.kakao.pay.bill.dozn.api.validate.prepay}") + private String BILL_PREPAY_URL; + @Value("${contract.kakao.pay.bill.dozn.api.validate.payresult}") + private String BILL_PAYREUSLT_URL; + + + private enum DataKeys { + tbInputDataXit, + responseJsonStr, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + final String billerUserKey = (String) reqData.getOrDefault("billerUserKey", ""); + + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + Optional.ofNullable(createRespData(data)) + .map(kkoPayUrlRespData -> loadRespData(data, kkoPayUrlRespData)); + } + + + private KkoPayUrlRespData createRespData(Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + return KkoPayUrlRespData.builder() + .billedYearMonth(null) + .ordinal(null) + .expireAt(tbInputDataXit.getTbInputXit().getPayExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) + .parameters(null) + .customUrl(CustomUrl.builder() + .noticeUrl(this.BILL_HOST + this.BILL_NOTICE_URL) + .prepayUrl(this.BILL_HOST + this.BILL_PREPAY_URL) + .payResultUrl(this.BILL_HOST + this.BILL_PAYREUSLT_URL) + .build()) + .build(); + + } + + private Map loadRespData(Map data, KkoPayUrlRespData kkoPayUrlRespData) { + + data.put(DataKeys.responseJsonStr.name(), gson.toJson(kkoPayUrlRespData)); + return data; + } + + + @Override + public PayApiRespDTO generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + KkoPayUrlRespData kkoPayUrlRespData = gson.fromJson((String) data.get(DataKeys.responseJsonStr.name()), KkoPayUrlRespData.class); + return PayApiRespDTO.okBuilder() + .data(kkoPayUrlRespData) + .build(); + + } else { + return PayApiRespDTO.errBuilder() + .resCode(PayUseSysResCd.GRNURL_FIND_FAILED.getCode()) + .message(PayUseSysResCd.GRNURL_FIND_FAILED.getCodeNm()) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + final String billerUserKey = (String) reqData.getOrDefault("billerUserKey", ""); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.kakaoPay) + .hisSeCd(PayUseSysHisSeCd.gnrUrl) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayAbleService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayAbleService.java new file mode 100644 index 0000000..72266d6 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayAbleService.java @@ -0,0 +1,224 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbEnfrcLevMastrRepository; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoSnRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayAbleService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupNvPayAbleService implements PayAbleService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; + private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; + private final TbEnfrcLevMastrRepository tbEnfrcLevMastrRepository; + private final PayUseSysApi payUseSysApi; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + private Gson gson = new Gson(); + + private enum DataKeys { + tbInputDataXit, + payApiRespDTO, + responseJsonStr, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("billerUserKey"); +// String productName = (String) reqData.get("productName"); +// Integer totalPayAmount = (Integer) reqData.get("totalPayAmount"); +// Integer taxScopeAmount = (Integer) reqData.get("taxScopeAmount"); +// Integer taxExScopeAmount = (Integer) reqData.get("taxExScopeAmount"); + + if (billerUserKey == null) billerUserKey = ""; + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + final String dataId = tbInputDataXit.getDataId(); + + if ("Y".equals(fsJob.getBpEntrustYn()) || "y".equals(fsJob.getBpEntrustYn())) { + + final String url = fsJob.getBpNvPrepayApi(); + + VKakaoNoticeInfoSn vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 단순미납부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfoSn) + .map(entity -> payUseSysApi.payAble(url, reqParam, null)) + .map(response -> checkResponse(response)) + .map(payApiRespDTO -> loadRespData(data, payApiRespDTO)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "단순미납 응답데이터 수신에 실패했습니다.")) + ; + } else if ("N".equals(fsJob.getBpEntrustYn()) || "n".equals(fsJob.getBpEntrustYn())) { + if (dataId.length() < 20) + throw new EnsException(EnsErrCd.INVALID_DATA, "데이터ID가 20자리 미만 입니다."); + VKakaoNoticeInfo vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 강제징수부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfo) + .map(entity -> validateData(reqParam, entity)); + TbEnfrcLevMastr tbEnfrcLevMastr = tbEnfrcLevMastrRepository.findByEnfrcLevMastrIdAndEnfrcLevMastrProcessSttusAndDeleteAt(dataId.substring(0, 20), "04", "N") + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "납부가능 상태가 아닙니다.", PayUseSysResCd.NO_TARGET_PAYABLE)); + Optional.of(tbEnfrcLevMastr) + .map(entity -> createRespData()) + .map(payApiRespDTO -> loadRespData(data, payApiRespDTO)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "강제징수 응답데이터 생성에 실패했습니다.")); + } else { + throw new EnsException(EnsErrCd.INVALID_DATA, "위탁여부가 등록되지 않았습니다."); + } + + } + + private PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + return result; + } + + private PayApiRespDTO loadRespData(Map data, PayApiRespDTO payApiRespDTO) { + if (CmmnUtil.isEmpty(payApiRespDTO)) + return null; + + data.put(DataKeys.payApiRespDTO.name(), payApiRespDTO); + data.put(DataKeys.responseJsonStr.name(), gson.toJson(payApiRespDTO)); + return payApiRespDTO; + } + + private VKakaoNoticeInfo validateData(Map reqParam, VKakaoNoticeInfo vKakaoNoticeInfo) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + + final String productName = (String) reqData.get("productName"); + final Integer totalPayAmount = (Integer) reqData.getOrDefault("totalPayAmount", 0); + final Integer taxScopeAmount = (Integer) reqData.get("taxScopeAmount"); + final Integer taxExScopeAmount = (Integer) reqData.get("taxExScopeAmount"); + + + if (totalPayAmount != Integer.parseInt(vKakaoNoticeInfo.getAmount())) + throw new EnsException(EnsErrCd.INVALID_DATA + , String.format("납부 가능 금액이 없거나 일치하지 않습니다. (요청금액:%s, 실제금액:%s)", totalPayAmount, vKakaoNoticeInfo.getAmount()) + , PayUseSysResCd.NO_AMOUNT_PAYABLE); + if (totalPayAmount > Integer.parseInt(vKakaoNoticeInfo.getAmount())) + throw new EnsException(EnsErrCd.INVALID_DATA + , String.format("납부 가능 금액을 초과했습니다. (요청금액:%s, 실제금액:%s)", totalPayAmount, vKakaoNoticeInfo.getAmount()) + , PayUseSysResCd.OVERPAYABLE_AMOUNT); + if (CmmnUtil.isEmpty(vKakaoNoticeInfo.getPayExpireDate())) + throw new EnsException(EnsErrCd.INVALID_DATA + , "납부기한의 값이 비어있습니다." + , PayUseSysResCd.EXPIRED_DATE); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd"); + if (Integer.parseInt(vKakaoNoticeInfo.getPayExpireDate()) < Integer.parseInt(simpleDateFormat.format(new Date()))) + throw new EnsException(EnsErrCd.INVALID_DATA + , "납부기한이 경과한 자료 입니다." + , PayUseSysResCd.EXPIRED_DATE); + + return vKakaoNoticeInfo; + } + + private PayApiRespDTO> createRespData() { + return PayApiRespDTO.>okBuilder().build(); + } + + @Override + public PayApiRespDTO> generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + PayApiRespDTO> payApiRespDTO = (PayApiRespDTO>) data.get(DataKeys.payApiRespDTO.name()); + return payApiRespDTO; + + } else { + if (e.getData() != null && e.getData() instanceof PayUseSysResCd) { + PayUseSysResCd resCode = (PayUseSysResCd) e.getData(); + return PayApiRespDTO.>errBuilder() + .resCode(resCode.getCode()) + .message(resCode.getCodeNm()) + .build(); + } else { + return PayApiRespDTO.>errBuilder() + .resCode(PayUseSysResCd.FAILED_CHECK_INFO.getCode()) + .message(PayUseSysResCd.FAILED_CHECK_INFO.getCodeNm()) + .build(); + } + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + String billerUserKey = (String) reqData.get("billerUserKey"); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.naverPay) + .hisSeCd(PayUseSysHisSeCd.payAble) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayCancelService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayCancelService.java new file mode 100644 index 0000000..8d61b5b --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayCancelService.java @@ -0,0 +1,51 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.utils.MapDeserailizer; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayCancelService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayCancelData; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupNvPayCancelService implements PayCancelService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + + private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).create(); + + @Override + public PayCancelData getData(Map reqParam) { + return null; + } + + @Override + public void validate(Map reqParam, PayCancelData data) { + + } + + @Override + public void callApi(Map reqParam, PayCancelData data) { + + } + + @Override + public PayApiRespDTO> generateResult(Map reqParam, PayCancelData data, EnsException e) { + return null; + } + + @Override + public void saveHist(Map reqParam, PayCancelData data, EnsException e) { + + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayNoticeService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayNoticeService.java new file mode 100644 index 0000000..96da18a --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayNoticeService.java @@ -0,0 +1,229 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoRepository; +import cokr.xit.ens.biz.iup.domain.repository.VKakaoNoticeInfoSnRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyIdCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.notice.ProductItem; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayNoticeService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.*; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupNvPayNoticeService implements PayNoticeService, Map, PayApiRespDTO> { + + private final JPAQueryFactory query; + private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; + private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + private Gson gson = new Gson(); + @Value("${contract.naver.pay.easy.api.validate.host}") + private String BILL_HOST; + @Value("${contract.naver.pay.easy.api.validate.prepay}") + private String BILL_PAYABLE_URL; + + private enum DataKeys { + tbInputDataXit, + nvPayNoticeRespData, + responseJsonStr, + } + + private enum PayDataKeys { + billerUserKey, + userBirth, + amount, + payExpireDate, + detailPasngChrgeSm, + detailAdiPasngChrgeSm, + } + + @Override + public Map getData(Map reqParam) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + final String billerUserKey = (String) reqData.getOrDefault("billerUserKey", ""); + + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + final String dataId = tbInputDataXit.getDataId(); + + if ("Y".equals(fsJob.getBpEntrustYn()) || "y".equals(fsJob.getBpEntrustYn())) { + VKakaoNoticeInfoSn vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 단순미납부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfoSn) + .map(entity -> toDataMap(entity)) + .map(payData -> validateData(reqParam, payData)) + .map(payData -> createRespData(tbInputDataXit, payData)) + .map(kkoPayNoticeRespData -> loadRespData(data, kkoPayNoticeRespData)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "단순미납 응답데이터 생성에 실패했습니다.")) + ; + } else if ("N".equals(fsJob.getBpEntrustYn()) || "n".equals(fsJob.getBpEntrustYn())) { + if (dataId.length() < 20) + throw new EnsException(EnsErrCd.INVALID_DATA, "데이터ID가 20자리 미만 입니다."); + VKakaoNoticeInfo vKakaoNoticeInfo = vKakaoNoticeInfoRepository.findById(dataId.substring(0, 20)) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 강제징수부과 자료가 없습니다.")); + Optional.of(vKakaoNoticeInfo) + .map(entity -> toDataMap(entity)) + .map(map -> validateData(reqParam, map)) + .map(map -> createRespData(tbInputDataXit, map)) + .map(kkoPayNoticeRespData -> loadRespData(data, kkoPayNoticeRespData)) + .orElseThrow(() -> new EnsException(EnsErrCd.FAILED_CREATE_RESPONSE_DATA, "강제징수 응답데이터 생성에 실패했습니다.")) + ; + } else { + throw new EnsException(EnsErrCd.INVALID_DATA, "위탁여부가 등록되지 않았습니다."); + } + } + + private Map toDataMap(VKakaoNoticeInfoSn vKakaoNoticeInfoSn) { + Map payData = new HashMap<>(); + payData.put(PayDataKeys.billerUserKey, vKakaoNoticeInfoSn.getDataId()); + payData.put(PayDataKeys.userBirth, vKakaoNoticeInfoSn.getUserBirth()); + payData.put(PayDataKeys.amount, vKakaoNoticeInfoSn.getAmount().intValue()); + payData.put(PayDataKeys.payExpireDate, vKakaoNoticeInfoSn.getPayExpireDate()); + payData.put(PayDataKeys.detailPasngChrgeSm, vKakaoNoticeInfoSn.getDetailPasngChrgeSm()); + payData.put(PayDataKeys.detailAdiPasngChrgeSm, vKakaoNoticeInfoSn.getDetailAdiPasngChrgeSm()); + return payData; + } + + private Map toDataMap(VKakaoNoticeInfo vKakaoNoticeInfo) { + Map payData = new HashMap<>(); + payData.put(PayDataKeys.billerUserKey, vKakaoNoticeInfo.getEnfrcLevMastrId()); + payData.put(PayDataKeys.userBirth, vKakaoNoticeInfo.getUserBirth()); + payData.put(PayDataKeys.amount, Integer.parseInt(vKakaoNoticeInfo.getAmount())); + payData.put(PayDataKeys.payExpireDate, vKakaoNoticeInfo.getPayExpireDate()); + payData.put(PayDataKeys.detailPasngChrgeSm, vKakaoNoticeInfo.getDetailPasngChrgeSm()); + payData.put(PayDataKeys.detailAdiPasngChrgeSm, vKakaoNoticeInfo.getDetailAdiPasngChrgeSm()); + return payData; + } + + private Map validateData(Map reqParam, Map payData) { + return payData; + } + + + private NvPayNoticeRespData createRespData(TbInputDataXit tbInputDataXit, Map payData) { + NvEpCtgyIdCd productSe = NvEpCtgyIdCd.ETC_ETC; + List productItems = Arrays.asList(ProductItem.builder() + .categoryType(productSe.getCategoryTypeCd()) + .categoryId(productSe.getCode().split("_")[1]) +// .uid(tbInputDataXit.getLinkedUuid()) + .uid(tbInputDataXit.getTbInputXit().getFsJob().getJobCd()) //2023.03.14 네이버페이 검수 결과 - 상품고유ID로 변경 + .name(tbInputDataXit.getTbInputXit().getFsJob().getJobName()) + .count(1) + .build()); + Integer productCount = productItems.stream().map(productItem -> productItem.getCount()).reduce(Integer::sum).get(); + return NvPayNoticeRespData.builder() + .productName(tbInputDataXit.getTbInputXit().getFsJob().getJobName()) + .productCount(productCount) + .totalPayAmount((Integer) payData.get(PayDataKeys.amount)) + .taxScopeAmount((Integer) payData.get(PayDataKeys.amount)) + .taxExScopeAmount(0) + .environmentDepositAmount(0) + .productItems(productItems) + .returnUrl(this.BILL_HOST + this.BILL_PAYABLE_URL) + .build(); + } + + private NvPayNoticeRespData loadRespData(Map data, NvPayNoticeRespData kkoPayNoticeRespData) { + if (CmmnUtil.isEmpty(kkoPayNoticeRespData)) + return null; + + data.put(DataKeys.nvPayNoticeRespData.name(), kkoPayNoticeRespData); + data.put(DataKeys.responseJsonStr.name(), gson.toJson(kkoPayNoticeRespData)); + return kkoPayNoticeRespData; + } + + + @Override + public PayApiRespDTO generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + NvPayNoticeRespData nvPayNoticeRespData = (NvPayNoticeRespData) data.get(DataKeys.nvPayNoticeRespData.name()); + return PayApiRespDTO.okBuilder() + .data(nvPayNoticeRespData) + .build(); + + } else { + String resCode = null; + String message = null; + switch (e.getErrCd()) { + case NO_DATA_FOUND: + resCode = PayUseSysResCd.NOT_FOUND_PAYDATA.getCode(); + message = PayUseSysResCd.NOT_FOUND_PAYDATA.getCodeNm(); + break; + default: + resCode = PayUseSysResCd.PAYDATA_FIND_FAILED.getCode(); + message = PayUseSysResCd.PAYDATA_FIND_FAILED.getCodeNm(); + break; + } + + return PayApiRespDTO.errBuilder() + .resCode(resCode) + .message(message) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>()); + final String billerUserKey = (String) reqData.getOrDefault("billerUserKey", ""); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.naverPay) + .hisSeCd(PayUseSysHisSeCd.payNotice) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayResultService.java b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayResultService.java new file mode 100644 index 0000000..04b4d64 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/billpay/service/process/IupNvPayResultService.java @@ -0,0 +1,212 @@ +package cokr.xit.ens.biz.iup.billpay.service.process; + +import cokr.xit.ens.biz.iup.domain.*; +import cokr.xit.ens.biz.iup.domain.repository.TbIupBillPayHistRepository; +import cokr.xit.ens.biz.iup.domain.repository.TbNaverPayResultRepository; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayResultDetail; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayResultReqData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayResultService; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class IupNvPayResultService implements PayResultService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + private final PayUseSysApi payUseSysApi; + private final TbNaverPayResultRepository tbNaverPayResultRepository; + private final TbIupBillPayHistRepository tbIupBillPayHistRepository; + + private Gson gson = new Gson(); + + private enum DataKeys { + tbInputDataXit, + responseJsonStr, + } + + @Override + public Map getData(Map reqParam) { + Map body = (Map) reqParam.getOrDefault("body", new HashMap<>()); + Map detail = (Map) body.getOrDefault("detail", new HashMap<>()); + String billerUserKey = (String) detail.get("merchantUserKey"); + + if (billerUserKey == null) billerUserKey = ""; + TbInputDataXit tbInputDataXit = query.selectFrom(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(billerUserKey)) + .fetchOne(); + + + Map data = new HashMap<>(); + data.put(DataKeys.tbInputDataXit.name(), tbInputDataXit); + return data; + } + + @Override + public void validate(Map reqParam, Map data) { + + if (CmmnUtil.isEmpty(data.get(DataKeys.tbInputDataXit.name()))) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, EnsErrCd.NO_DATA_FOUND.getCodeNm()); + } + + @Override + public void callApi(Map reqParam, Map data) { + TbInputDataXit tbInputDataXit = (TbInputDataXit) data.get(DataKeys.tbInputDataXit.name()); + TbInputXit tbInputXit = tbInputDataXit.getTbInputXit(); + FsJob fsJob = tbInputXit.getFsJob(); + + final String url = fsJob.getBpKkoPayresultApi(); + + Optional.ofNullable(gson.fromJson(gson.toJson(reqParam.get("body")), NvPayResultReqData.class)) + .map(nvPayResultReqData -> toEntity(nvPayResultReqData)) + .map(entity -> savePayResult(entity)) + .map(entity -> tbInputDataXit) + .filter(detail -> "Y".equals(detail.getTbInputXit().getFsJob())) + .map(vKakaoNoticeInfoSn -> payUseSysApi.payResult(url, reqParam, null)) + .map(respnose -> loadRespData(data, respnose)) + .map(response -> checkResponse(response)) + ; + + } + + private TbNaverPayResult toEntity(NvPayResultReqData nvPayResultReqData) { + NvPayResultDetail detail = nvPayResultReqData.getDetail(); + final String billerUserKey = detail.getMerchantUserKey(); + + + final String jobSe = "EL".equals(billerUserKey.substring(0, 2)) ? "2" : "1"; + + + return TbNaverPayResult.builder() + .dataId(billerUserKey) + .jobSe(jobSe) + .paymentId(detail.getPaymentId()) + .payHistId(detail.getPayHistId()) + .merchantId(detail.getMerchantId()) + .merchantName(detail.getMerchantName()) + .merchantPayKey(detail.getMerchantPayKey()) + .merchantUserKey(detail.getMerchantUserKey()) + .admissionTypeCode(detail.getAdmissionTypeCode()) + .admissionYmdt(detail.getAdmissionYmdt()) + .tradeConfirmYmdt(detail.getTradeConfirmYmdt()) + .admissionState(detail.getAdmissionState()) + .totalPayAmount(detail.getTotalPayAmount()) + .primaryPayAmount(detail.getPrimaryPayAmount()) + .npointPayAmount(detail.getNpointPayAmount()) + .giftCardAmount(detail.getGiftCardAmount()) + .taxScopeAmount(detail.getTaxScopeAmount()) + .taxExScopeAmount(detail.getTaxExScopeAmount()) + .environmentDepositAmount(detail.getEnvironmentDepositAmount()) + .primaryPayMeans(detail.getPrimaryPayMeans()) + .cardCorpCode(detail.getCardCorpCode()) + .cardNo(detail.getCardNo()) + .cardAuthNo(detail.getCardAuthNo()) + .cardInstCount(detail.getCardInstCount()) + .usedCardPoint(detail.getUsedCardPoint()) + .bankCorpCode(detail.getBankCorpCode()) + .bankAccountNo(detail.getBankAccountNo()) + .productName(detail.getProductName()) + .settleExpected(detail.getSettleExpected()) + .settleExpectAmount(detail.getSettleExpectAmount()) + .payCommissionAmount(detail.getPayCommissionAmount()) + .extraDeduction(detail.getExtraDeduction()) + .useCfmYmdt(detail.getUseCfmYmdt()) + .merchantExtraParameter(detail.getMerchantExtraParameter()) + .userIdentifier(detail.getUserIdentifier()) + .payResultProcessSttus("0") +// .creatDt() + .crtr("ENS_SYS") +// .updtDt() +// .updusr() + .build(); + + } + + private TbNaverPayResult savePayResult(TbNaverPayResult entity) { + tbNaverPayResultRepository.save(entity); + return entity; + } + + private ResponseEntity loadRespData(Map data, ResponseEntity response) { + data.put(DataKeys.responseJsonStr.name(), response.getBody()); + return response; + } + + private PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + return result; + } + + + @Override + public PayApiRespDTO> generateResult(Map reqParam, Map data, EnsException e) { + if (e == null) { + return PayApiRespDTO.>okBuilder().build(); + + } else { + return PayApiRespDTO.>errDataBuilder() + .resCode(PayUseSysResCd.FAILED_SAVE_PAYRSLT.getCode()) + .message(PayUseSysResCd.FAILED_SAVE_PAYRSLT.getCodeNm()) + .data(null) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, Map data, EnsException e) { + Map body = (Map) reqParam.getOrDefault("body", new HashMap<>()); + Map detail = (Map) body.getOrDefault("detail", new HashMap<>()); + String billerUserKey = (String) detail.get("merchantUserKey"); + + String errorCode = null; + String errorMessage = null; + if (e != null) { + errorCode = e.getErrCd().getCode(); + errorMessage = String.format("%s %s", e.getMessage(), CmmnUtil.printStackTraceToString(e)); + } + + TbIupBillPayHist tbIupBillPayHist = TbIupBillPayHist.builder() + .dataId(billerUserKey) + .paidType(PaidTypeCd.naverPay) + .hisSeCd(PayUseSysHisSeCd.payResult) + .requestData(gson.toJson(reqParam)) + .responseData((String) data.get(DataKeys.responseJsonStr.name())) + .error(FieldError.initBuilder() + .errorCode(errorCode) + .errorMessage(errorMessage) + .build()) + .build(); + tbIupBillPayHistRepository.save(tbIupBillPayHist); + } +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/FsJob.java b/src/main/java/cokr/xit/ens/biz/iup/domain/FsJob.java index af87b32..f5ccdd9 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/FsJob.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/FsJob.java @@ -20,69 +20,94 @@ public class FsJob { @Column(name = "job_cd", nullable = false, length = 10) private String jobCd; - + @Column(name = "job_name", nullable = true) private String jobName; - + @Column(name = "job_desc", nullable = true) private String jobDesc; - + @Column(name = "enc_phone_no_yn", nullable = true) private String encPhoneNoYn; - + @Column(name = "enc_name_yn", nullable = true) private String encNameYn; - + @Column(name = "enc_birthday_yn", nullable = true) private String encBirthdayYn; - + @Column(name = "unsube_use_yn", nullable = true) private String unsubeUseYn; - + @Column(name = "unsube_type", nullable = true) private String unsubeType; - + @Column(name = "use_yn", nullable = true) private String useYn; - + @Column(name = "reg_id", nullable = true) private String regId; - + @Column(name = "reg_dt", nullable = true) private java.sql.Date regDt; - + @Column(name = "upd_id", nullable = true) private String updId; - + @Column(name = "upd_dt", nullable = true) private java.sql.Date updDt; - + @Column(name = "org_cd", nullable = true) private String orgCd; - + @Column(name = "call_center_no", nullable = true) private String callCenterNo; - + @Column(name = "redirect_url", nullable = true) private String redirectUrl; - + @Column(name = "template_cd", nullable = true) private String templateCd; + + /* ================================================= + * 2023.02.14. 페이결제 진행 시 민자사 호출을 위해 추가 함 + ================================================= */ + + @Column(name = "bp_entrust_yn", nullable = true, length = 1) + @Setter + private String bpEntrustYn; + + @Column(name = "bp_kko_prepay_api", nullable = true) + @Setter + private String bpKkoPrepayApi; + + @Column(name = "bp_kko_payresult_api", nullable = true) + @Setter + private String bpKkoPayresultApi; + + @Column(name = "bp_nv_prepay_api", nullable = true) + @Setter + private String bpNvPrepayApi; + + @Column(name = "bp_nv_payresult_api", nullable = true) + @Setter + private String bpNvPayresultApi; + } diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/TbIupBillPayHist.java b/src/main/java/cokr/xit/ens/biz/iup/domain/TbIupBillPayHist.java new file mode 100644 index 0000000..cca09b0 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/TbIupBillPayHist.java @@ -0,0 +1,33 @@ +package cokr.xit.ens.biz.iup.domain; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHistPayUseSysBaseEntity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Entity +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "tb_iup_bill_pay_hist", schema = "", catalog = "", indexes = { + @Index(name = "idx_iup_bp_his_01", columnList = "data_id") +}) + +public class TbIupBillPayHist extends BillHistPayUseSysBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id", nullable = false) + private Long id; + + + @Column(name = "data_id", nullable = true) + private String dataId; + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/TbKakaoPayResult.java b/src/main/java/cokr/xit/ens/biz/iup/domain/TbKakaoPayResult.java index 7f5a18c..71c0bef 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/TbKakaoPayResult.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/TbKakaoPayResult.java @@ -23,7 +23,6 @@ import java.time.LocalDateTime; public class TbKakaoPayResult { @Id - @Column(name = "data_id", length = 30) private String dataId; diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/TbNaverPayResult.java b/src/main/java/cokr/xit/ens/biz/iup/domain/TbNaverPayResult.java new file mode 100644 index 0000000..ec1dbd3 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/TbNaverPayResult.java @@ -0,0 +1,159 @@ +package cokr.xit.ens.biz.iup.domain; + +import cokr.xit.ens.core.jpa.support.BooleanToYnConverter; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +//@Data +@Getter +@ToString +@Builder +@EqualsAndHashCode +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "tb_naver_pay_result", schema = "", catalog = "") +public class TbNaverPayResult { + + @Id + @Column(name = "data_id", length = 30) + private String dataId; + + + @Column(name = "job_se", length = 1, nullable = true) + private String jobSe; + + + @Column(name = "payment_id", length = 50) + private String paymentId; + + + @Column(name = "pay_hist_id", length = 50) + private String payHistId; + + @Column(name = "merchant_id", length = 50) + private String merchantId; + + @Column(name = "merchant_name", length = 50) + private String merchantName; + + @Column(name = "merchant_pay_key", length = 64) + private String merchantPayKey; + + @Column(name = "merchant_user_key", length = 50) + private String merchantUserKey; + + @Column(name = "admission_type_code", length = 2) + private String admissionTypeCode; + + @Column(name = "admission_ymdt", length = 14) + private String admissionYmdt; + + @Column(name = "trade_confirm_ymdt", length = 50) + private String tradeConfirmYmdt; + + @Column(name = "admission_state", length = 10) + private String admissionState; + + @Column(name = "total_pay_amount") + private Integer totalPayAmount; + + @Column(name = "primary_pay_amount") + private Integer primaryPayAmount; + + @Column(name = "npoint_pay_amount") + private Integer npointPayAmount; + + @Column(name = "gift_card_amount") + private Integer giftCardAmount; + + @Column(name = "tax_scope_amount") + private Integer taxScopeAmount; + + @Column(name = "tax_ex_scope_amount") + private Integer taxExScopeAmount; + + @Column(name = "environment_deposit_amount") + private Integer environmentDepositAmount; + + @Column(name = "primary_pay_means", length = 10) + private String primaryPayMeans; + + @Column(name = "card_corp_code", length = 10) + private String cardCorpCode; + + @Column(name = "card_no", length = 50) + private String cardNo; + + @Column(name = "card_auth_no", length = 30) + private String cardAuthNo; + + @Column(name = "card_inst_count") + private Integer cardInstCount; + + @Column(name = "used_card_point", length = 1) + @Convert(converter = BooleanToYnConverter.class) + private Boolean usedCardPoint; + + @Column(name = "bank_corp_code", length = 10) + private String bankCorpCode; + + @Column(name = "bank_account_no", length = 50) + private String bankAccountNo; + + @Column(name = "product_name", length = 128) + private String productName; + + @Column(name = "settle_expected", length = 1) + @Convert(converter = BooleanToYnConverter.class) + private Boolean settleExpected; + + @Column(name = "settle_expect_amount") + private Integer settleExpectAmount; + + @Column(name = "pay_commission_amount") + private Integer payCommissionAmount; + + @Column(name = "extra_deduction", length = 1) + @Convert(converter = BooleanToYnConverter.class) + private Boolean extraDeduction; + + @Column(name = "use_cfm_ymdt", length = 8) + private String useCfmYmdt; + + @Column(name = "merchant_extra_parameter", length = 400) + private String merchantExtraParameter; + + @Column(name = "user_identifier", length = 28) + private String userIdentifier; + + + + @Column(name = "pay_result_process_sttus", length = 1, nullable = true) + private String payResultProcessSttus; + + + @CreationTimestamp + @Column(name = "creat_dt", nullable = true) + private LocalDateTime creatDt; + + + @Column(name = "crtr", length = 50, nullable = true) + private String crtr; + + + @UpdateTimestamp + @Column(name = "updt_dt", nullable = true) + private LocalDateTime updtDt; + + + @Column(name = "updusr", length = 50, nullable = true) + private String updusr; + + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/VKakaoNoticeInfoSn.java b/src/main/java/cokr/xit/ens/biz/iup/domain/VKakaoNoticeInfoSn.java index c18e26f..1b27021 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/VKakaoNoticeInfoSn.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/VKakaoNoticeInfoSn.java @@ -14,15 +14,15 @@ import java.util.Objects; @EqualsAndHashCode @NoArgsConstructor @AllArgsConstructor -@Table(name = "V_KAKAO_NOTICE_INFO_SN", schema = "", catalog = "") +@Table(name = "v_kakao_notice_info_sn", schema = "", catalog = "") public class VKakaoNoticeInfoSn { @Id - @Column(name = "DATA_ID", nullable = true, length = 24) + @Column(name = "data_id", nullable = true, length = 24) private String dataId; - @Column(name = "USER_BIRTH", nullable = true, length = 4000) + @Column(name = "user_birth", nullable = true, length = 4000) private String userBirth; @@ -30,14 +30,14 @@ public class VKakaoNoticeInfoSn { private Long amount; - @Column(name = "PAY_EXPIRE_DATE", nullable = true, length = 8) + @Column(name = "pay_expire_date", nullable = true, length = 8) private String payExpireDate; - @Column(name = "DETAIL_PASNG_CHRGE_SM", nullable = true, precision = 0) + @Column(name = "detail_pasng_chrge_sm", nullable = true, precision = 0) private Long detailPasngChrgeSm; - @Column(name = "DETAIL_ADI_PASNG_CHRGE_SM", nullable = true, precision = 0) + @Column(name = "detail_adi_pasng_chrge_sm", nullable = true, precision = 0) private Long detailAdiPasngChrgeSm; } diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepository.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepository.java index 7800f0a..b6e8954 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepository.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepository.java @@ -4,10 +4,9 @@ import cokr.xit.ens.biz.iup.domain.TbEnfrcLevRciv; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; -import java.util.Optional; -public interface TbEnfrcLevRcivRepository extends JpaRepository, TbEnfrcLevRcivRepositoryCustom { +public interface TbEnfrcLevRcivRepository extends JpaRepository { List findAllByEnfrcLevMastrIdAndDeleteAt(String enfrcLevMastrId, String deleteAt); } diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryCustom.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryCustom.java deleted file mode 100644 index 348eefa..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryCustom.java +++ /dev/null @@ -1,5 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -public interface TbEnfrcLevRcivRepositoryCustom { - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryImpl.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryImpl.java deleted file mode 100644 index 2f24ef3..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbEnfrcLevRcivRepositoryImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class TbEnfrcLevRcivRepositoryImpl implements TbEnfrcLevRcivRepositoryCustom { - - private final JPAQueryFactory query; - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbInputDataXitCustomRepositoryImpl.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbInputDataXitCustomRepositoryImpl.java index c24f02b..92b4505 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbInputDataXitCustomRepositoryImpl.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbInputDataXitCustomRepositoryImpl.java @@ -2,8 +2,8 @@ package cokr.xit.ens.biz.iup.domain.repository; import cokr.xit.ens.biz.iup.code.IupSendTypeCd; import cokr.xit.ens.biz.iup.domain.TbInputDataXit; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; import com.querydsl.core.types.dsl.DateTemplate; import com.querydsl.core.types.dsl.Expressions; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -19,7 +19,7 @@ import java.util.Optional; import static cokr.xit.ens.biz.iup.domain.QFsJob.fsJob; import static cokr.xit.ens.biz.iup.domain.QTbInputDataXit.tbInputDataXit; import static cokr.xit.ens.biz.iup.domain.QTbInputXit.tbInputXit; -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.QBillHist.billHist; +import static cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBillHist.billHist; import static cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.QIntgrnSendDetail.intgrnSendDetail; import static cokr.xit.ens.modules.kkoalimtalk.domain.QSendDetailKkoAlimtalk.sendDetailKkoAlimtalk; @@ -44,10 +44,8 @@ public class TbInputDataXitCustomRepositoryImpl implements TbInputDataXitCustomR @Override public List findAllFetchByLnkInputId(Long lnkInputId) { return query.selectFrom(tbInputDataXit) - .innerJoin(tbInputDataXit.tbInputXit, tbInputXit) - .fetchJoin() - .innerJoin(tbInputXit.fsJob, fsJob) - .fetchJoin() + .innerJoin(tbInputDataXit.tbInputXit, tbInputXit).fetchJoin() + .innerJoin(tbInputXit.fsJob, fsJob).fetchJoin() .where(tbInputDataXit.tbInputXit.lnkInputId.eq(lnkInputId)) .fetch(); } @@ -111,7 +109,7 @@ public class TbInputDataXitCustomRepositoryImpl implements TbInputDataXitCustomR // .innerJoin(kkoBillHist).on(kkoBillHist.billerUserKey.eq(tbInputDataXit.linkedUuid)).fetchJoin() .innerJoin(billHist).on(billHist.billSe.eq(BillSeCd.bpKko).and(billHist.linkedUuid.eq(tbInputDataXit.linkedUuid))).fetchJoin() .where( - billHist.reqSe.eq(BillReqSeCd.PAYRSLT) + billHist.reqSe.eq(BillReqSeCd.US_PAYRSLT) .and(tbInputXit.runDt.between(from, to)) .and(billHist.registDt.between(from, to)) ) diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbIupBillPayHistRepository.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbIupBillPayHistRepository.java new file mode 100644 index 0000000..2cc3432 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbIupBillPayHistRepository.java @@ -0,0 +1,9 @@ +package cokr.xit.ens.biz.iup.domain.repository; + +import cokr.xit.ens.biz.iup.domain.TbIupBillPayHist; +import org.springframework.data.jpa.repository.JpaRepository; + + +public interface TbIupBillPayHistRepository extends JpaRepository { + +} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbNaverPayResultRepository.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbNaverPayResultRepository.java new file mode 100644 index 0000000..a5e2367 --- /dev/null +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/TbNaverPayResultRepository.java @@ -0,0 +1,9 @@ +package cokr.xit.ens.biz.iup.domain.repository; + +import cokr.xit.ens.biz.iup.domain.TbKakaoPayResult; +import cokr.xit.ens.biz.iup.domain.TbNaverPayResult; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TbNaverPayResultRepository extends JpaRepository { + +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepository.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepository.java index 98187d7..d570022 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepository.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepository.java @@ -3,7 +3,7 @@ package cokr.xit.ens.biz.iup.domain.repository; import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfo; import org.springframework.data.jpa.repository.JpaRepository; -public interface VKakaoNoticeInfoRepository extends JpaRepository, VKakaoNoticeInfoRepositoryCustom { +public interface VKakaoNoticeInfoRepository extends JpaRepository { } diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryCustom.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryCustom.java deleted file mode 100644 index 44cd4df..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryCustom.java +++ /dev/null @@ -1,5 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -public interface VKakaoNoticeInfoRepositoryCustom { - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryImpl.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryImpl.java deleted file mode 100644 index b72a6d9..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoRepositoryImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class VKakaoNoticeInfoRepositoryImpl implements VKakaoNoticeInfoRepositoryCustom { - - private final JPAQueryFactory query; - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepository.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepository.java index 13228af..f689db7 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepository.java +++ b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepository.java @@ -3,7 +3,7 @@ package cokr.xit.ens.biz.iup.domain.repository; import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfoSn; import org.springframework.data.jpa.repository.JpaRepository; -public interface VKakaoNoticeInfoSnRepository extends JpaRepository, VKakaoNoticeInfoSnRepositoryCustom { +public interface VKakaoNoticeInfoSnRepository extends JpaRepository { } diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryCustom.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryCustom.java deleted file mode 100644 index e9435ef..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryCustom.java +++ /dev/null @@ -1,5 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -public interface VKakaoNoticeInfoSnRepositoryCustom { - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryImpl.java b/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryImpl.java deleted file mode 100644 index 9b92984..0000000 --- a/src/main/java/cokr/xit/ens/biz/iup/domain/repository/VKakaoNoticeInfoSnRepositoryImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package cokr.xit.ens.biz.iup.domain.repository; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class VKakaoNoticeInfoSnRepositoryImpl implements VKakaoNoticeInfoSnRepositoryCustom { - - private final JPAQueryFactory query; - - -} diff --git a/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillPayApiSigntalkService.java b/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillKkoPaySigntalkService.java similarity index 82% rename from src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillPayApiSigntalkService.java rename to src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillKkoPaySigntalkService.java index 165918d..b487542 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillPayApiSigntalkService.java +++ b/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/IupBillKkoPaySigntalkService.java @@ -1,17 +1,17 @@ package cokr.xit.ens.biz.iup.signtalk.service; -import cokr.xit.ens.biz.iup.billpay.service.IupBillPayApiServiceSupport; +import cokr.xit.ens.biz.iup.billpay.api.IupKkoPayUseSysApiSpec; +import cokr.xit.ens.biz.iup.billpay.service.IupBillKkoPayUseSysService; import cokr.xit.ens.biz.iup.domain.*; import cokr.xit.ens.biz.iup.domain.repository.*; import cokr.xit.ens.core.exception.EnsException; import cokr.xit.ens.core.exception.code.EnsErrCd; import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoClientApiSpec; import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.code.BillKkoErrCd; import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoPayResultDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoPayResultData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.repository.IntgrnSendDetailRepository; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; @@ -19,6 +19,7 @@ import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.TmpltMng; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.OrgMngRepository; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.TmpltMngRepository; import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -31,9 +32,9 @@ import java.util.Map; import java.util.Optional; @Slf4j -@Service("iupBillPayApiService_KP") +@Service("iupBillKkoPayUseSysService_KP") @RequiredArgsConstructor -public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { +public class IupBillKkoPaySigntalkService extends IupBillKkoPayUseSysService { private final IntgrnSendDetailRepository intgrnSendDetailRepository; @@ -42,10 +43,11 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { private final TbInputDataXitRepository tbInputDataXitRepository; private final VKakaoNoticeInfoRepository vKakaoNoticeInfoRepository; private final VKakaoNoticeInfoSnRepository vKakaoNoticeInfoSnRepository; - + // private final TbEnfrcLevRcivRepository tbEnfrcLevRcivRepository; private final TbEnfrcLevMastrRepository tbEnfrcLevMastrRepository; private final TbKakaoPayResultRepository tbKakaoPayResultRepository; - private final BillKkoClientApiSpec billKkoClientApi; + private final IupKkoPayUseSysApiSpec iupKkoPayApi; + private final JPAQueryFactory query; /** @@ -57,12 +59,12 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { @Transactional(propagation = Propagation.NEVER) public BillKkoApiRespDTO findNoticeInfo(Map mParam) { Map data = (Map) mParam.get("data"); -// data.get("biller_user_key"); -// data.get("billed_year_month"); -// data.get("ordinal"); -// data.get("biller_notice_key"); - Map parameters = (Map) data.get("parameters"); -// data.get("user_birth"); +// data.get("biller_user_key"); +// data.get("billed_year_month"); +// data.get("ordinal"); +// data.get("biller_notice_key"); + Map parameters = (Map) data.get("parameters"); +// data.get("user_birth"); Map respData = null; @@ -123,7 +125,7 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { // final String dataId = tbInputDataXit.get().getDataId(); final String dataId = billerUserKey; - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { + if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { Optional vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId); if (!vKakaoNoticeInfoSn.isPresent()) { kkoBillErrCd = BillKkoErrCd.E402; @@ -134,10 +136,10 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { throw new EnsException(EnsErrCd.ERR402, String.format("생년월일이 일치하지 않습니다. (요청: %s 실제: %s)", userBirth, vKakaoNoticeInfoSn.get().getUserBirth())); } - + respData = this.respNoticeSnData(sendTmpltMng.get().getTitle(), orgMng.get(), vKakaoNoticeInfoSn.get()); - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { + } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { if (dataId.length() < 20) { kkoBillErrCd = BillKkoErrCd.E402; throw new EnsException(EnsErrCd.ERR403, "빌러코드가 20자리 미만 입니다."); @@ -152,7 +154,7 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { throw new EnsException(EnsErrCd.ERR402, String.format("생년월일이 일치하지 않습니다. (요청: %s 실제: %s)", userBirth, vKakaoNoticeInfo.get().getUserBirth())); } - + respData = this.respNoticeData(sendTmpltMng.get().getTitle(), orgMng.get(), vKakaoNoticeInfo.get()); } else { @@ -196,13 +198,13 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { */ @Transactional(propagation = Propagation.NEVER) public BillKkoApiRespDTO findPrepayInfo(Map mParam) { - Map data = (Map) mParam.get("data"); -// data.get("biller_user_key"); -// data.get("billed_year_month"); -// data.get("ordinal"); -// data.get("biller_notice_key"); - Map parameters = (Map) data.get("parameters"); -// data.get("amount"); + Map data = (Map) mParam.get("data"); +// data.get("biller_user_key"); +// data.get("billed_year_month"); +// data.get("ordinal"); +// data.get("biller_notice_key"); + Map parameters = (Map) data.get("parameters"); +// data.get("amount"); BillKkoApiRespDTO respVO = null; @@ -232,32 +234,32 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { - - Optional orgMng = orgMngRepository.findById(orgCd); - if (!orgMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); - } - - Optional tbInputDataXit = tbInputDataXitRepository.findByLinkedUuid(billerUserKey); +// Optional orgMng = orgMngRepository.findById(orgCd); +// if (!orgMng.isPresent()) { +// kkoBillErrCd = BillKkoErrCd.E601; +// throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); +// } +// Optional tbInputDataXit = tbInputDataXitRepository.findByLinkedUuid(billerUserKey); + Optional tbInputDataXit = this.getTbInputDataXitByLinkedUuid(billerUserKey); if (!tbInputDataXit.isPresent()) { kkoBillErrCd = BillKkoErrCd.E402; throw new EnsException(EnsErrCd.ERR404, "일치하는 발송상세정보가 없습니다."); } + final FsJob fsJob = tbInputDataXit.get().getTbInputXit().getFsJob(); final String dataId = tbInputDataXit.get().getDataId(); - + Optional vKakaoNoticeInfo = Optional.ofNullable(null); -// List tbEnfrcLevRcivs = new ArrayList<>(); +// List tbEnfrcLevRcivs = new ArrayList<>(); - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { + if ("Y".equals(fsJob.getBpEntrustYn())) { Optional vKakaoNoticeInfoSn = vKakaoNoticeInfoSnRepository.findById(dataId); if (!vKakaoNoticeInfoSn.isPresent()) { kkoBillErrCd = BillKkoErrCd.E502; throw new EnsException(EnsErrCd.ERR404, "일치하는 단순미납 자료가 없습니다."); } - respVO = billKkoClientApi.callApiByOrg(orgMng.get().getKkoBpCsignPrepayApi(), mParam); + respVO = iupKkoPayApi.callApiByOrg(fsJob.getBpKkoPrepayApi(), mParam); if ("OK".equals(respVO.getRes_code())) this.modifyBillHistByRespInfo(billHist, respVO, null, null); @@ -266,7 +268,7 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { return respVO; - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { + } else if ("N".equals(fsJob.getBpEntrustYn())) { if (dataId.length() < 20) { kkoBillErrCd = BillKkoErrCd.E502; throw new EnsException(EnsErrCd.ERR403, "빌러코드가 20자리 미만 입니다."); @@ -278,7 +280,7 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { throw new EnsException(EnsErrCd.ERR404, "일치하는 강제징수 자료가 없습니다."); } - + // tbEnfrcLevRcivs = tbEnfrcLevRcivRepository.findAllByEnfrcLevMastrIdAndDeleteAt(dataId.substring(0, 20), "N"); Optional tbEnfrcLevMastr = tbEnfrcLevMastrRepository.findByEnfrcLevMastrIdAndEnfrcLevMastrProcessSttusAndDeleteAt(dataId.substring(0, 20), "04", "N"); if (!tbEnfrcLevMastr.isPresent()) { @@ -364,7 +366,7 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { Map data = (Map) mParam.get("data"); Gson gson = new Gson(); - BillKkoPayResultDTO kkoBillPayResultVO = gson.fromJson(gson.toJson(data), BillKkoPayResultDTO.class); + BillKkoPayResultData kkoBillPayResultVO = gson.fromJson(gson.toJson(data), BillKkoPayResultData.class); Map parameters = kkoBillPayResultVO.getParameters(); @@ -392,25 +394,31 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { - Optional orgMng = orgMngRepository.findById(orgCd); - if (!orgMng.isPresent()) { - kkoBillErrCd = BillKkoErrCd.E601; - throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); +// Optional orgMng = orgMngRepository.findById(orgCd); +// if (!orgMng.isPresent()) { +// kkoBillErrCd = BillKkoErrCd.E601; +// throw new EnsException(EnsErrCd.ERR404, "일치하는 기관정보가 없습니다."); +// } + Optional tbInputDataXit = this.getTbInputDataXitByLinkedUuid(kkoBillPayResultVO.getBiller_user_key()); + if (!tbInputDataXit.isPresent()) { + kkoBillErrCd = BillKkoErrCd.E402; + throw new EnsException(EnsErrCd.ERR404, "일치하는 발송상세정보가 없습니다."); } + final FsJob fsJob = tbInputDataXit.get().getTbInputXit().getFsJob(); if (!tbKakaoPayResultRepository.findById(kkoBillPayResultVO.getBiller_user_key()).isPresent()) tbKakaoPayResultRepository.save(this.createTbKakaoPayResult(kkoBillPayResultVO)); - if ("Y".equals(orgMng.get().getKkoBpCsignYn())) { - respVO = billKkoClientApi.callApiByOrg(orgMng.get().getKkoBpCsignPayresultApi(), mParam); + if ("Y".equals(fsJob.getBpEntrustYn())) { + respVO = iupKkoPayApi.callApiByOrg(fsJob.getBpKkoPayresultApi(), mParam); if (!"OK".equals(respVO.getRes_code())) this.modifyBillHistByRespInfo(kkoBillHist, respVO, EnsErrCd.ERR600, String.format("[%s] %s", respVO.getRes_code(), respVO.getMessage())); return respVO; - } else if ("N".equals(orgMng.get().getKkoBpCsignYn())) { + } else if ("N".equals(fsJob.getBpEntrustYn())) { } else { kkoBillErrCd = BillKkoErrCd.E601; @@ -444,33 +452,42 @@ public class IupBillPayApiSigntalkService extends IupBillPayApiServiceSupport { } - private TbKakaoPayResult createTbKakaoPayResult(BillKkoPayResultDTO kkoBillPayResultVO) { + private TbKakaoPayResult createTbKakaoPayResult(BillKkoPayResultData kkoBillPayResultVO) { + - final String jobSe = "EL".equals(kkoBillPayResultVO.getBiller_user_key().substring(0, 2)) ? "2" : "1"; return TbKakaoPayResult.builder() - .dataId(kkoBillPayResultVO.getBiller_user_key()) - .jobSe(jobSe) - .payMn(kkoBillPayResultVO.getPay_by()) - .payTy(kkoBillPayResultVO.getPay_type()) - .payDetail1(kkoBillPayResultVO.getPay_detail1()) - .payDetail2(kkoBillPayResultVO.getPay_detail2()) - .payDetail3(kkoBillPayResultVO.getPay_detail3()) - .payAmount(kkoBillPayResultVO.getPay_amount()) - .payFeeTy(kkoBillPayResultVO.getPay_fee_type()) - .payFeeAmount(kkoBillPayResultVO.getPay_fee()) - .payFeeVat(kkoBillPayResultVO.getPay_fee_tax()) + .dataId(kkoBillPayResultVO.getBiller_user_key()) + .jobSe(jobSe) + .payMn(kkoBillPayResultVO.getPay_by()) + .payTy(kkoBillPayResultVO.getPay_type()) + .payDetail1(kkoBillPayResultVO.getPay_detail1()) + .payDetail2(kkoBillPayResultVO.getPay_detail2()) + .payDetail3(kkoBillPayResultVO.getPay_detail3()) + .payAmount(kkoBillPayResultVO.getPay_amount()) + .payFeeTy(kkoBillPayResultVO.getPay_fee_type()) + .payFeeAmount(kkoBillPayResultVO.getPay_fee()) + .payFeeVat(kkoBillPayResultVO.getPay_fee_tax()) .excclcPrearngeDe(kkoBillPayResultVO.getAdjust_date()) - .payDt(kkoBillPayResultVO.getPaid_at()) - .payId(kkoBillPayResultVO.getPay_id()) - .payResultProcessSttus("0") -// .creatDt() - .crtr("ENS_SYS") -// .updtDt() -// .updusr() + .payDt(kkoBillPayResultVO.getPaid_at()) + .payId(kkoBillPayResultVO.getPay_id()) + .payResultProcessSttus("0") +// .creatDt() + .crtr("ENS_SYS") +// .updtDt() +// .updusr() .build(); } + + private Optional getTbInputDataXitByLinkedUuid(String linkedUuid) { + return Optional.ofNullable(query.select(QTbInputDataXit.tbInputDataXit) + .from(QTbInputDataXit.tbInputDataXit) + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit, QTbInputXit.tbInputXit).fetchJoin() + .innerJoin(QTbInputDataXit.tbInputDataXit.tbInputXit.fsJob, QFsJob.fsJob).fetchJoin() + .where(QTbInputDataXit.tbInputDataXit.linkedUuid.eq(linkedUuid)) + .fetchOne()); + } } diff --git a/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/support/IupSigntalkAcceptor.java b/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/support/IupSigntalkAcceptor.java index e6a626f..640578e 100644 --- a/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/support/IupSigntalkAcceptor.java +++ b/src/main/java/cokr/xit/ens/biz/iup/signtalk/service/support/IupSigntalkAcceptor.java @@ -14,10 +14,8 @@ import cokr.xit.ens.core.exception.code.EnsErrCd; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; import cokr.xit.ens.modules.common.code.VenderCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.config.CustomUrl; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.IntgrnNotiAcceptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.config.AcptData; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.config.Document; @@ -53,18 +51,9 @@ public class IupSigntalkAcceptor implements EnsPhaseProcSupport> createDetails(TbInputDataXit data) { -// return null; -// } - -// private BillLinkInfo createBillLinkInfo(TbInputDataXit data) { -// return BillLinkInfo.builder() -// .use_bill_mast_id(false) -// .bill_mast_id(null) -// .button_name("납부하기") -// .button_type("WL") -// .expire_at(data.getTbInputXit().getPayExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) -// .notice_url(this.BILL_HOST + this.BILL_NOTICE_URL) -// .prepay_url(this.BILL_HOST + this.BILL_PREPAY_URL) -// .pay_result_url(this.BILL_HOST + this.BILL_PAYREUSLT_URL) -// .build(); -// } - - private BillAcptReqDTO createBillAcptData(TbInputDataXit data) { - return BillAcptReqDTO.builder() - .use_bill_uid(false) - .bill_uid(null) - .bill_se(BillSeCd.bpKko) - .bill_kko(BillKkoAcptReqVO.builder() - .billUid(null) - .billerUserKey(data.getLinkedUuid()) - .billedYearMonth(null) - .ordinal(null) - .billerNoticeKey(null) - .expireAt(data.getTbInputXit().getPayExpiresDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))) - .parameters(null) - .customUrl(CustomUrl.builder() - .noticeUrl(this.BILL_HOST + this.BILL_NOTICE_URL) - .prepayUrl(this.BILL_HOST + this.BILL_PREPAY_URL) - .payResultUrl(this.BILL_HOST + this.BILL_PAYREUSLT_URL) - .build()) - .build()) + private EnsBillAcptReqDTO createBillAcptData(TbInputDataXit data) { + return EnsBillAcptReqDTO.builder() + .billUid(null) + .billerUserKey(data.getLinkedUuid()) + .billSe(BillSeCd.bpKko) .build(); } diff --git a/src/main/java/cokr/xit/ens/biz/traffic/cheonan/signtalk/service/support/TrafficCaSigntalkAcceptor.java b/src/main/java/cokr/xit/ens/biz/traffic/cheonan/signtalk/service/support/TrafficCaSigntalkAcceptor.java index 469a305..87adc6a 100644 --- a/src/main/java/cokr/xit/ens/biz/traffic/cheonan/signtalk/service/support/TrafficCaSigntalkAcceptor.java +++ b/src/main/java/cokr/xit/ens/biz/traffic/cheonan/signtalk/service/support/TrafficCaSigntalkAcceptor.java @@ -16,7 +16,7 @@ import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.core.utils.MapDeserailizer; import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; import cokr.xit.ens.modules.common.code.VenderCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.IntgrnNotiAcceptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.config.AcptData; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.config.Document; @@ -54,9 +54,9 @@ public class TrafficCaSigntalkAcceptor implements EnsPhaseProcSupport { @Schema(required = true, title = "에러 코드", example = " ") + @JsonProperty("errCode") + @JsonAlias({"err_code"}) + @SerializedName(value = "errCode", alternate = {"err_code"}) private EnsErrCd errCode = null; @Schema(required = true, title = "에러 메시지", example = " ") + @JsonProperty("errMsg") + @JsonAlias({"err_msg"}) + @SerializedName(value = "errMsg", alternate = {"err_msg"}) private String errMsg = null; @Schema(required = false, title = "결과 데이터", example = " ") + @JsonProperty("resultInfo") + @JsonAlias({"result_info"}) + @SerializedName(value = "resultInfo", alternate = {"result_info"}) private T resultInfo; @Builder(builderClassName = "okBuilder" ,builderMethodName = "okBuilder") diff --git a/src/main/java/cokr/xit/ens/core/config/SecurityConfig.java b/src/main/java/cokr/xit/ens/core/config/SecurityConfig.java new file mode 100644 index 0000000..4f1c08a --- /dev/null +++ b/src/main/java/cokr/xit/ens/core/config/SecurityConfig.java @@ -0,0 +1,14 @@ +package cokr.xit.ens.core.config; + +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.csrf().disable(); + } +} diff --git a/src/main/java/cokr/xit/ens/core/config/SpringDocConfig.java b/src/main/java/cokr/xit/ens/core/config/SpringDocConfig.java index 766d4fb..9630e1b 100644 --- a/src/main/java/cokr/xit/ens/core/config/SpringDocConfig.java +++ b/src/main/java/cokr/xit/ens/core/config/SpringDocConfig.java @@ -71,18 +71,34 @@ public class SpringDocConfig { @Profile({"local", "local-test", "local-maria", "local-oracle", "prod-iup"}) @Bean - public GroupedOpenApi cmmnFtBillApiDoc() { + public GroupedOpenApi cmmnFtBillPaysApiDoc() { return GroupedOpenApi.builder() - .group("CF. 공통기능-청구서(kakaopay)") + .group("CF. 부가기능-청구서 공통 서비스") + .pathsToMatch("/bill/pay/**") + .build(); + } + @Profile({"local", "local-test", "local-maria", "local-oracle", "prod-iup"}) + @Bean + public GroupedOpenApi cmmnFtBillKkopayApiDoc() { + return GroupedOpenApi.builder() + .group("CF. 부가기능-청구서(kakaopay)") .pathsToMatch("/bill/kko/**") .build(); } + @Profile({"local", "local-test", "local-maria", "local-oracle", "prod-iup"}) + @Bean + public GroupedOpenApi cmmnFtBillNvpayApiDoc() { + return GroupedOpenApi.builder() + .group("CF. 부가기능-청구서(naver 간편결제)") + .pathsToMatch("/bill/nv/ep/**") + .build(); + } @Profile({"local", "local-test", "local-maria", "local-oracle", "prod-traffic", "prod-traffic-cheonan", "prod-iup"}) @Bean public GroupedOpenApi cmmnFtNiceCiDiApiDoc() { return GroupedOpenApi.builder() - .group("CF. 공통기능-CI변환(나이스 CiDi)") + .group("CF. 부가기능-CI변환(나이스 CiDi)") .pathsToMatch("/cmft/nice/ci/**") .build(); } @@ -90,7 +106,7 @@ public class SpringDocConfig { @Bean public GroupedOpenApi cmmnFtMblPageApiDoc() { return GroupedOpenApi.builder() - .group("CF. 공통기능-모바일페이지") + .group("CF. 부가기능-모바일페이지") .pathsToMatch( "/cmft/mbl/page/**" ) diff --git a/src/main/java/cokr/xit/ens/core/config/redis/EmbeddedRedisConfig.java b/src/main/java/cokr/xit/ens/core/config/redis/EmbeddedRedisConfig.java index 578bc64..94796c1 100644 --- a/src/main/java/cokr/xit/ens/core/config/redis/EmbeddedRedisConfig.java +++ b/src/main/java/cokr/xit/ens/core/config/redis/EmbeddedRedisConfig.java @@ -1,6 +1,5 @@ package cokr.xit.ens.core.config.redis; -import cokr.xit.ens.core.utils.CmmnUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/cokr/xit/ens/core/exception/code/EnsErrCd.java b/src/main/java/cokr/xit/ens/core/exception/code/EnsErrCd.java index 51387fc..f139de8 100644 --- a/src/main/java/cokr/xit/ens/core/exception/code/EnsErrCd.java +++ b/src/main/java/cokr/xit/ens/core/exception/code/EnsErrCd.java @@ -8,127 +8,149 @@ import cokr.xit.ens.core.code.CodeMapperType; *
  • 설 명:
  • *
  • 작성일: 2021. 8. 4. 오후 3:51:43 * + * * @author 박민규 */ -public enum EnsErrCd implements CodeMapperType{ +public enum EnsErrCd implements CodeMapperType { OK("정상"), - UNKNOWN("알수없음") - - , ERR401("필수 파라미터가 없습니다.") - , ERR402("파라미터 유효성 검증 오류") - , ERR403("잘못된 파라미터 입니다.") - , ERR404("일치하는 자료가 없습니다.") - , ERR405("잘못된 요청 값.") - , ERR410("필수값 없음") - , ERR411("잘못된 JSON 포맷 문자열") - , ERR500("서버 오류") - , ERR501("HttpServer 오류") - , ERR502("HttpClient 오류") - , ERR503("RestClient 오류") - , ERR504("요청 데이터 Json 파싱 오류") - , ERR505("응답 데이터 Json 파싱 오류") - , ERR506("Hash 생성 오류") - , ERR507("유효하지 않은 데이터") - , ERR511("JSON 형식으로 변환 실패") - , ERR521("방화벽 설정 오류") - , ERR540("중복된 데이터") - , ERR600("API 오류") - , ERR601("API서버 응답 오류") - , ERR602("API서버 내부 오류") - , ERR603("유효하지 않은 토큰(OTT) 값") - , ERR610("응답 데이터에 필수값이 없음") - , ERR620("API Response Error") - , ERR699("API 기타 오류") - , ERR999("기타 오류") - , ERR901("권한 없음") - , ERR902("유효하지 않은 데이터") - , ERR903("처리 완료된 데이터") - , ERR904("CI 변환 실패") - - - , BILL401("duplicated \"bill_uid\"") - , BILL402("duplicated \"biller_user_key\"") - , BILL403("validation fail") - , BILL404("not found data") - , BILL405("invalid value") - , BILL501("json convert fail") //json 변환 실패 - , BILL511("청구서 URL 생성 병렬처리 중 ERROR") - , BILL512("청구서 URL 생성 실패") - , BILL601("json parsing fail") //json 분석 실패 - , BILL602("http status failure response") //http staus 오류 - , BILL603("response data is invalid") - , BILL604("client api failure response") - , BILL999("unknown error") - - - , ACPT402("유효성 검증 실패") - , ACPT404("일치하는 자료가 없습니다.") - , ACPT405("접수 가능한 자료가 아닙니다.") - , ACPT410("필수값 없음") - , ACPT411("잘못된 JSON 포맷 문자열") - , ACPT412("청구서 접수 실패") - , ACPT500("접수 처리 중 오류") - , ACPT511("JSON 형식으로 변환 실패") - , ACPT999("기타 오류") - - - , MAKE404("일치하는 자료가 없습니다.") - , MAKE410("필수값 없음") - , MAKE411("잘못된 JSON 포맷 문자열") - , MAKE500("제작 처리 중 오류") - , MAKE511("JSON 형식으로 변환 실패") - , MAKE512("청구서 제작 실패") - , MAKE513("CI 제작 실패") - , MAKE521("데이터 생성 실패") - , MAKE610("응답 데이터에 필수값이 없음") - , MAKE620("API Response Error") - , MAKE630("API Request Error") - - - , SEND404("일치하는 자료가 없습니다.") - , SEND405("잘못된 요청 값.") - , SEND410("필수값 없음") - , SEND411("잘못된 JSON 포맷 문자열") - , SEND500("전송 처리 중 오류") - , SEND502("발송메시지 생성 실패") - , SEND511("JSON 형식으로 변환 실패") - , SEND601("토큰생성 실패") - , SEND620("API Response Error") - , SEND630("API Request Error") - - - , RSLT404("일치하는 자료가 없습니다.") - , RSLT405("요청건수와 실제 자료의 건수가 상이 합니다.") - , RSLT406("일부 자료가 결과반영에 실패 했습니다.") - , RSLT407("전체 자료가 결과반영에 실패 했습니다.") - , RSLT410("필수값 없음") - , RSLT411("잘못된 JSON 포맷 문자열") - , RSLT500("전송결과 처리 중 오류") - , RSLT502("요청메시지 생성 실패") - , RSLT511("JSON 형식으로 변환 실패") - , RSLT512("제공되지 않는 서비스 입니다.") - , RSLT601("전송결과 조회 실패") - , RSLT620("API Response Error") - , RSLT630("API Request Error") - , RSLT999("기타 오류") - - - , PRVD404("일치하는 자료가 없습니다.") - , PRVD410("필수값 없음") - , PRVD411("잘못된 JSON 포맷 문자열") - , PRVD500("상태갱신 처리 중 오류") - , PRVD511("JSON 형식으로 변환 실패") - , PRVD502("요청메시지 생성 실패") - , PRVD601("상태 조회 실패") - , PRVD620("API Response Error") - , PRVD630("API Request Error") + UNKNOWN("알수없음"), + + NO_REQUIRED_PARAM("필수 파라미터가 없습니다."), + INVALID_REQUEST("유효하지 않은 요청데이터 입니다."), + INVALID_REQUEST_URL("유효하지 않은 요청 URL 입니다."), + NOT_FOUND_BEAN("빈(bean)을 찾을 수 없습니다."), + NO_DATA_FOUND("자료를 찾을 수 없습니다."), + INVALID_DATA("유효하지 않은 데이터 입니다."), + API_COMM_ERROR("API 통신 오류가 발생 했습니다."), + INVALID_RESPONSE("유효하지 않은 응답 입니다."), + INVALID_RES_CODE("유효하지 않은 응답코드 입니다."), + INVALID_RES_DATA("유효하지 않은 응답데이터 입니다."), + RESPONSED_FAILURE_CODE("실패코드가 응답 되었습니다."), + FAILED_CREATE_RESPONSE_DATA("응답데이터 생성 실패"), + URL_ALREADY_CREATED("URL이 이미 생성 되었습니다."), + PAYMENT_ALREADY_CMPLTED("결제가 완료된 자료 입니다."), + SERVICE_NOT_SUPPORTED("지원하지 않는 서비스 입니다."), + + + ERR401("필수 파라미터가 없습니다."), + ERR402("파라미터 유효성 검증 오류"), + ERR403("잘못된 파라미터 입니다."), + ERR404("일치하는 자료가 없습니다."), + ERR405("잘못된 요청 값."), + ERR410("필수값 없음"), + ERR411("잘못된 JSON 포맷 문자열"), + ERR500("서버 오류"), + ERR501("HttpServer 오류"), + ERR502("HttpClient 오류"), + ERR503("RestClient 오류"), + ERR504("요청 데이터 Json 파싱 오류"), + ERR505("응답 데이터 Json 파싱 오류"), + ERR506("Hash 생성 오류"), + ERR507("유효하지 않은 데이터"), + ERR511("JSON 형식으로 변환 실패"), + ERR512("JSON Parsing Fail"), + ERR513("Services Not Supported"), + ERR521("방화벽 설정 오류"), + ERR540("중복된 데이터"), + ERR600("API 오류"), + ERR601("API서버 응답 오류"), + ERR602("API서버 내부 오류"), + ERR603("유효하지 않은 토큰(OTT) 값"), + ERR604("API 통신 실패"), + ERR610("응답 데이터에 필수값이 없음"), + ERR620("API Response Error"), + ERR699("API 기타 오류"), + ERR999("기타 오류"), + ERR901("권한 없음"), + ERR902("유효하지 않은 데이터"), + ERR903("처리 완료된 데이터"), + ERR904("CI 변환 실패"), + + + + BILL401("duplicated \"bill_uid\""), + BILL402("duplicated \"biller_user_key\""), + BILL403("validation fail"), + BILL404("not found data"), + BILL405("invalid value"), + BILL501("json convert fail"), + BILL511("청구서 URL 생성 병렬처리 중 ERROR"), + BILL512("청구서 URL 생성 실패"), + BILL601("json parsing fail"), + BILL602("http status failure response"), + BILL603("response data is invalid"), + BILL604("client api failure response"), + BILL999("unknown error"), + + + ACPT402("유효성 검증 실패"), + ACPT404("일치하는 자료가 없습니다."), + ACPT405("접수 가능한 자료가 아닙니다."), + ACPT410("필수값 없음"), + ACPT411("잘못된 JSON 포맷 문자열"), + ACPT412("청구서 접수 실패"), + ACPT500("접수 처리 중 오류"), + ACPT511("JSON 형식으로 변환 실패"), + ACPT999("기타 오류"), + + + MAKE404("일치하는 자료가 없습니다."), + MAKE410("필수값 없음"), + MAKE411("잘못된 JSON 포맷 문자열"), + MAKE500("제작 처리 중 오류"), + MAKE511("JSON 형식으로 변환 실패"), + MAKE512("청구서 제작 실패"), + MAKE513("CI 제작 실패"), + MAKE521("데이터 생성 실패"), + MAKE610("응답 데이터에 필수값이 없음"), + MAKE620("API Response Error"), + MAKE630("API Request Error"), + + + SEND404("일치하는 자료가 없습니다."), + SEND405("잘못된 요청 값."), + SEND410("필수값 없음"), + SEND411("잘못된 JSON 포맷 문자열"), + SEND500("전송 처리 중 오류"), + SEND502("발송메시지 생성 실패"), + SEND511("JSON 형식으로 변환 실패"), + SEND601("토큰생성 실패"), + SEND620("API Response Error"), + SEND630("API Request Error"), + + + RSLT404("일치하는 자료가 없습니다."), + RSLT405("요청건수와 실제 자료의 건수가 상이 합니다."), + RSLT406("일부 자료가 결과반영에 실패 했습니다."), + RSLT407("전체 자료가 결과반영에 실패 했습니다."), + RSLT410("필수값 없음"), + RSLT411("잘못된 JSON 포맷 문자열"), + RSLT500("전송결과 처리 중 오류"), + RSLT502("요청메시지 생성 실패"), + RSLT511("JSON 형식으로 변환 실패"), + RSLT512("제공되지 않는 서비스 입니다."), + RSLT601("전송결과 조회 실패"), + RSLT620("API Response Error"), + RSLT630("API Request Error"), + RSLT999("기타 오류"), + + + PRVD404("일치하는 자료가 없습니다."), + PRVD410("필수값 없음"), + PRVD411("잘못된 JSON 포맷 문자열"), + PRVD500("상태갱신 처리 중 오류"), + PRVD511("JSON 형식으로 변환 실패"), + PRVD502("요청메시지 생성 실패"), + PRVD601("상태 조회 실패"), + PRVD620("API Response Error"), + PRVD630("API Request Error"), ; - private final String code; private final String codeNm; + EnsErrCd(String codeNm) { this.code = this.name(); this.codeNm = codeNm; @@ -145,14 +167,14 @@ public enum EnsErrCd implements CodeMapperType{ } - public static EnsErrCd valueOfEnum(String code){ - if(code == null) + public static EnsErrCd valueOfEnum(String code) { + if (code == null) return EnsErrCd.UNKNOWN; EnsErrCd ensErrCd = null; try { ensErrCd = EnsErrCd.valueOf(code); - } catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { ensErrCd = EnsErrCd.UNKNOWN; } return ensErrCd; diff --git a/src/main/java/cokr/xit/ens/core/init/InitJpaRunner.java b/src/main/java/cokr/xit/ens/core/init/InitJpaRunner.java index ef51f0b..d825e84 100644 --- a/src/main/java/cokr/xit/ens/core/init/InitJpaRunner.java +++ b/src/main/java/cokr/xit/ens/core/init/InitJpaRunner.java @@ -85,29 +85,29 @@ public abstract class InitJpaRunner implements ApplicationRunner { return OrgMngDTO.builder() .orgCd(orgCd) .orgNm(orgNm) - + .kkoMdAccessToken(KKO_MD_ACCESS_TOKEN) .kkoMdContractUuid(KKO_MD_CONTRACT_UUID) - + .kkoBpCsignYn(kkoBpCsignYn) .kkoBpBillerCode(KKO_BP_BILLER_CODE) .kkoBpAuthorization(KKO_BP_AUTHORIZATION) - .kkoBpCsignPrepayApi(kkoBpPrepayApi) - .kkoBpCsignPayResultApi(kkoBpPayResultApi) - + .kkoBpPrepayApi(kkoBpPrepayApi) + .kkoBpPayResultApi(kkoBpPayResultApi) + .kkoAtBsid(KKO_AT_BSID) .kkoAtPasswd(KKO_AT_PASSWD) .kkoAtSenderKey(KKO_AT_SENDER_KEY) - + .niceCdSiteCode(NICE_CD_SITE_CODE) .niceCdSitePw(NICE_CD_SITE_PW) .niceCdClientId(NICE_CD_CLIENT_ID) .niceCdClientSercet(NICE_CD_CLIENT_SECRET) - + .nvStXNaverClientId(NV_ST_X_NAVER_CLIENT_ID) .nvStXNaverClientSecret(NV_ST_X_NAVER_CLIENT_SECRET) .nvStOrgId(nvOrgId) - + .ktStAccessToken(KT_ST_ACCESS_TOKEN) .ktStServiceCd(KT_ST_SERVICE_CD) .ktStServiceKey(KT_ST_SERVICE_KEY) diff --git a/src/main/java/cokr/xit/ens/core/dialect/MariaDB103DialectCustom.java b/src/main/java/cokr/xit/ens/core/jpa/dialect/MariaDB103DialectCustom.java similarity index 93% rename from src/main/java/cokr/xit/ens/core/dialect/MariaDB103DialectCustom.java rename to src/main/java/cokr/xit/ens/core/jpa/dialect/MariaDB103DialectCustom.java index b2d99c4..004c2e2 100644 --- a/src/main/java/cokr/xit/ens/core/dialect/MariaDB103DialectCustom.java +++ b/src/main/java/cokr/xit/ens/core/jpa/dialect/MariaDB103DialectCustom.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.core.dialect; +package cokr.xit.ens.core.jpa.dialect; import org.hibernate.dialect.MariaDB103Dialect; import org.hibernate.dialect.function.StandardSQLFunction; diff --git a/src/main/java/cokr/xit/ens/core/dialect/Oracle10gDialectCustom.java b/src/main/java/cokr/xit/ens/core/jpa/dialect/Oracle10gDialectCustom.java similarity index 92% rename from src/main/java/cokr/xit/ens/core/dialect/Oracle10gDialectCustom.java rename to src/main/java/cokr/xit/ens/core/jpa/dialect/Oracle10gDialectCustom.java index 4a54670..6716818 100644 --- a/src/main/java/cokr/xit/ens/core/dialect/Oracle10gDialectCustom.java +++ b/src/main/java/cokr/xit/ens/core/jpa/dialect/Oracle10gDialectCustom.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.core.dialect; +package cokr.xit.ens.core.jpa.dialect; import org.hibernate.dialect.Oracle10gDialect; import org.hibernate.dialect.function.StandardSQLFunction; diff --git a/src/main/java/cokr/xit/ens/core/jpa/support/BooleanToYnConverter.java b/src/main/java/cokr/xit/ens/core/jpa/support/BooleanToYnConverter.java new file mode 100644 index 0000000..7f298e4 --- /dev/null +++ b/src/main/java/cokr/xit/ens/core/jpa/support/BooleanToYnConverter.java @@ -0,0 +1,18 @@ +package cokr.xit.ens.core.jpa.support; + +import javax.persistence.AttributeConverter; +import javax.persistence.Converter; + +@Converter +public class BooleanToYnConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(Boolean attribute) { + return (attribute != null && attribute) ? "Y" : "N"; + } + + @Override + public Boolean convertToEntityAttribute(String yn) { + return "Y".equalsIgnoreCase(yn); + } +} diff --git a/src/main/java/cokr/xit/ens/core/model/EnsBillAcptReqDTO.java b/src/main/java/cokr/xit/ens/core/model/EnsBillAcptReqDTO.java new file mode 100644 index 0000000..7c75b61 --- /dev/null +++ b/src/main/java/cokr/xit/ens/core/model/EnsBillAcptReqDTO.java @@ -0,0 +1,48 @@ +package cokr.xit.ens.core.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Builder +@Getter +@Setter +@Schema(name = "EnsBillAcptReqDTO") +public class EnsBillAcptReqDTO { + +// @NotNull(message = "청구서ID 사용 여부는 필수 입력값 입니다.") +// @Schema(hidden = true, required = true, title = "청구서ID 사용 여부", example = "false") +// private Boolean use_bill_uid; + + @Schema(hidden = true, required = false, title = "청구서 유니크ID", example = " ") + @JsonProperty("billUid") + @JsonAlias({"bill_uid"}) + @SerializedName(value = "billUid", alternate = {"bill_uid"}) + private String billUid; + + @NotNull(message = "청구서 타입은 필수 입력값 입니다.") + @Schema(required = true, title = "청구서 타입", example = "all") + @JsonProperty("billSe") + @JsonAlias({"bill_se"}) + @SerializedName(value = "billSe", alternate = {"bill_se"}) + private BillSeCd billSe; + + @NotBlank(message = "빌러유저키는 필수 입력값 입니다.") + @Length(max = 40, message = "빌러유저키의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ") + @JsonProperty("billerUserKey") + @JsonAlias({"biller_user_key"}) + @SerializedName(value = "billerUserKey", alternate = {"biller_user_key"}) + private String billerUserKey; + + +} diff --git a/src/main/java/cokr/xit/ens/core/model/config/XitBaseProperty.java b/src/main/java/cokr/xit/ens/core/model/config/XitBaseProperty.java index 3576bce..b61cfe9 100644 --- a/src/main/java/cokr/xit/ens/core/model/config/XitBaseProperty.java +++ b/src/main/java/cokr/xit/ens/core/model/config/XitBaseProperty.java @@ -1,6 +1,6 @@ package cokr.xit.ens.core.model.config; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.NoArgsConstructor; @@ -15,14 +15,14 @@ import java.util.Map; @NoArgsConstructor @Schema(name = "XitBaseProperty") public class XitBaseProperty { - @Schema(required = false, title = "모바일페이지 노출 데이터", example = "{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"]}},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"링크 이미지\":\"http://www.xit.co.kr/....\"},{\"Base64 이미지\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\",\"properties\":{\"billSe\":\"bpKko\"}}]}") + @Schema(required = false, title = "모바일페이지 노출 데이터", example = "{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"하하하\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"다라마\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"},\"1111-23123-12313\":{\"use-clipboard\":false,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\\n1111-23123-12313 카카오\\n카카오뱅크\\nhttp://www.naver.com\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"액\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"],\"highlight\":{\"전기료\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"key\":\"링크 이미지\",\"value\":\"http://www.xit.co.kr/....\"},{\"key\":\"Base64 이미지\",\"value\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\"}]}") private Map>> mbl_page_data; @Schema(required = false, title = "템플릿 메시지 데이터", example = "{\"#{TARGET_NAME}\":\"홍길동\",\"#{CAR_NO}\":\"12더1234\",\"#{HISTORY}\":\"2022-01-01\",\"#{FEE}\":\"1000\",\"#{YYYY}\":\"2022\",\"#{MM}\":\"03\",\"#{DD}\":\"30\",\"#{BANK}\":\"기업\",\"#{ACCOUNT}\":\"311-063233-01-123\",\"#{HOMEPAGE}\":\"http://www.xit.co.kr\",\"#{REP_CALL_NO}\":\"070-4490-7404\"}") private Map tmplt_msg_data; @Valid - private BillAcptReqDTO bill_acpt_data; + private EnsBillAcptReqDTO bill_acpt_data; } diff --git a/src/main/java/cokr/xit/ens/core/utils/ApplicationContextProvider.java b/src/main/java/cokr/xit/ens/core/utils/ApplicationContextProvider.java index 160194d..d03c545 100644 --- a/src/main/java/cokr/xit/ens/core/utils/ApplicationContextProvider.java +++ b/src/main/java/cokr/xit/ens/core/utils/ApplicationContextProvider.java @@ -7,15 +7,15 @@ import org.springframework.stereotype.Component; @Component public class ApplicationContextProvider implements ApplicationContextAware { - private static ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext ctx) throws BeansException { - applicationContext = ctx; - } + private static ApplicationContext applicationContext; - - public static ApplicationContext getApplicationContext() { - return applicationContext; - } + @Override + public void setApplicationContext(ApplicationContext ctx) throws BeansException { + applicationContext = ctx; + } + + + public static ApplicationContext getApplicationContext() { + return applicationContext; + } } diff --git a/src/main/java/cokr/xit/ens/core/utils/BeanUtils.java b/src/main/java/cokr/xit/ens/core/utils/BeanUtils.java index 9551480..888826c 100644 --- a/src/main/java/cokr/xit/ens/core/utils/BeanUtils.java +++ b/src/main/java/cokr/xit/ens/core/utils/BeanUtils.java @@ -3,15 +3,15 @@ package cokr.xit.ens.core.utils; import org.springframework.context.ApplicationContext; public class BeanUtils { - - - public static T getBean(Class type) { - ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext(); - - if( applicationContext == null ) { - throw new NullPointerException("no Initialize \"ApplicationContext\""); - } - - return applicationContext.getBean(type); - } + + + public static T getBean(Class type) { + ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext(); + + if (applicationContext == null) { + throw new NullPointerException("no Initialize \"ApplicationContext\""); + } + + return applicationContext.getBean(type); + } } diff --git a/src/main/java/cokr/xit/ens/core/utils/CmmnUtil.java b/src/main/java/cokr/xit/ens/core/utils/CmmnUtil.java index 57e4c9e..2aa3e53 100644 --- a/src/main/java/cokr/xit/ens/core/utils/CmmnUtil.java +++ b/src/main/java/cokr/xit/ens/core/utils/CmmnUtil.java @@ -33,179 +33,198 @@ public class CmmnUtil { // private final static Logger logger = LoggerFactory.getLogger(CmmnUtil.class); - /** - *
    메소드 설명: API 호출
    -	 * 	-.반환결과
    -	 * 	:result => 결과 코드(OK: 정상, others: 오류)
    -	 * 	:resultMsg	=> 결과 메시지
    -	 * 	:responseEntity => api 응답 메시지
    -	 * 
    - * @param method - * @param url - * @param param - * @param headers - * @return Map 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 8. 4. - * @apiNote: 사이트 참조 https://e2e2e2.tistory.com/15 - */ - public static Map callApi(HttpMethod method, String url, String param, HttpHeaders headers) { - log.debug("param ======================="); - log.debug(param); - - - Map resultMap = new HashMap(); - ResponseEntity responseEntity = null; - String result = EnsErrCd.OK.getCode(); - String resultMsg = EnsErrCd.OK.getCodeNm(); - - try { - HttpEntity entity = null; - UriComponents uri = null; - switch (method) { - case GET: - entity = new HttpEntity<>(headers); - uri = UriComponentsBuilder - .fromHttpUrl(String.format("%s?%s", url, param)) - .encode() - .build(); - break; - case POST: - entity = new HttpEntity<>(param, headers); - uri = UriComponentsBuilder - .fromHttpUrl(url) - .encode() - .build(); - break; - - default: - break; - } - - - HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); - factory.setConnectTimeout(3000); - factory.setReadTimeout(3000); - RestTemplate restTemplate = new RestTemplate(factory); - responseEntity = restTemplate.exchange(uri.toString(), method, entity, String.class); - - } catch (HttpServerErrorException e) { - result = EnsErrCd.ERR501.getCode(); - resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR501.getCodeNm(), e.getMessage()); - log.error(String.format("call API 서버오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); - } catch (HttpClientErrorException e) { - result = EnsErrCd.ERR502.getCode(); - resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR502.getCodeNm(), e.getMessage()); - log.error(String.format("call API 클라이언트오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); - } catch (RestClientException e) { - result = EnsErrCd.ERR503.getCode(); - resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR503.getCodeNm(), e.getMessage()); - log.error(String.format("RestAPI 호출 오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); + /** + *
    메소드 설명: API 호출
    +     * 	-.반환결과
    +     * 	:result => 결과 코드(OK: 정상, others: 오류)
    +     * 	:resultMsg	=> 결과 메시지
    +     * 	:responseEntity => api 응답 메시지
    +     * 
    + * + * @param method + * @param url + * @param param + * @param headers + * @return Map 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 4. + */ + public static Map callApi(HttpMethod method, String url, String param, HttpHeaders headers) { + log.debug("param ======================="); + log.debug(param); + + + Map resultMap = new HashMap(); + ResponseEntity responseEntity = null; + String result = EnsErrCd.OK.getCode(); + String resultMsg = EnsErrCd.OK.getCodeNm(); + + try { + + HttpEntity entity = null; + UriComponents uri = null; + switch (method) { + case GET: + entity = new HttpEntity<>(headers); + uri = UriComponentsBuilder + .fromHttpUrl(String.format("%s?%s", url, param)) + .encode() + .build(); + break; + case POST: + entity = new HttpEntity<>(param, headers); + uri = UriComponentsBuilder + .fromHttpUrl(url) + .encode() + .build(); + break; + + default: + break; + } + + + + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); + factory.setConnectTimeout(3000); + factory.setReadTimeout(3000); + RestTemplate restTemplate = new RestTemplate(factory); + responseEntity = restTemplate.exchange(uri.toString(), method, entity, String.class); + + +// 코드: responseEntity.getStatusCodeValue() +// 메시지: responseEntity.getStatusCode() + } catch ( + HttpServerErrorException e) { + result = EnsErrCd.ERR501.getCode(); + resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR501.getCodeNm(), e.getMessage()); + log.error(String.format("call API 서버오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); + } catch ( + HttpClientErrorException e) { + result = EnsErrCd.ERR502.getCode(); + resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR502.getCodeNm(), e.getMessage()); + log.error(String.format("call API 클라이언트오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); + } catch (RestClientException e) { + result = EnsErrCd.ERR503.getCode(); + resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR503.getCodeNm(), e.getMessage()); + log.error(String.format("RestAPI 호출 오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); } catch (Exception e) { - result = EnsErrCd.ERR999.getCode(); - resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR999.getCodeNm(), e.getMessage()); - log.error(String.format("call API 기타오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); - } - - - - resultMap.put("resCd" , result); - resultMap.put("resMsg" , resultMsg); - resultMap.put("responseEntity", responseEntity); - return resultMap; - } - - - - /** - *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    - * @param obj - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 8. 5. - */ - public static String toJsonString(Object obj) { - return toJsonString(obj, JsonInclude.Include.ALWAYS); - } - /** - *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    - * @param obj - * @param type JsonInclude.Include - *
    -	 * [type 종류]
    -	 * 	ALWAYS: 모든 필드
    -	 * 	NON_NULL: null제외
    -	 *  NON_ABSENT: null제외
    -	 *  NON_EMPTY: null/absent/isEmpty()==true/lenth==0 제외
    -	 *  NON_DEFAULT: empty는 제외된다.primitive 타입이 디폴트 값이면 제외한다. (int / Integer : 0 , boolean / Boolean : false 등)
    -	 * 
    - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 8. 5. - */ - public static String toJsonString(Object obj, JsonInclude.Include type) { - String result = null; - - try { - ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(type); - result = mapper.writeValueAsString(obj); - } catch (JsonProcessingException e) { + result = EnsErrCd.ERR999.getCode(); + resultMsg = String.format("%s [사유: %s]", EnsErrCd.ERR999.getCodeNm(), e.getMessage()); + log.error(String.format("call API 기타오류[url =>%s param => %s error => %s]", url, param, e.getMessage())); + } + + + + resultMap.put("resCd", result); + resultMap.put("resMsg", resultMsg); + resultMap.put("responseEntity", responseEntity); + return resultMap; + } + + + /** + *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    + * + * @param obj + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 5. + */ + public static String toJsonString(Object obj) { + return toJsonString(obj, JsonInclude.Include.ALWAYS); + } + + /** + *
    메소드 설명: 객체를 Json 포맷 String으로 반환 한다.
    + * + * @param obj + * @param type JsonInclude.Include + *
    +     *                                     [type 종류]
    +     *                                     	ALWAYS: 모든 필드
    +     *                                     	NON_NULL: null제외
    +     *                                      NON_ABSENT: null제외
    +     *                                      NON_EMPTY: null/absent/isEmpty()==true/lenth==0 제외
    +     *                                      NON_DEFAULT: empty는 제외된다.primitive 타입이 디폴트 값이면 제외한다. (int / Integer : 0 , boolean / Boolean : false 등)
    +     *                                     
    + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 5. + */ + public static String toJsonString(Object obj, JsonInclude.Include type) { + String result = null; + + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(type); + result = mapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { // throw new CustomException(RESP_CODE.INTERNAL_SERVER_ERROR, String.format("obj -> jsonString converting fail:: %s", e.getMessage())); - throw new RuntimeException(String.format("obj -> jsonString converting fail:: %s", e.getMessage()), e); - } - - return result; - } - /** - *
    메소드 설명: jsonString을 Object로 반환한다
    - * @param clz - * @param jsonStr - * @return Object 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 12. 23. - */ - public static Object jsonStringtoObj(Class clz, String jsonStr) { - Object result = null; - - try { - ObjectMapper mapper = new ObjectMapper(); - result = mapper.readValue(jsonStr, clz.getClass()); - } catch (JsonProcessingException e) { - throw new RuntimeException(String.format("jsonString -> obj converting fail:: %s", e.getMessage()), e); - } - - return result; - } - - public static boolean isEmpty(Object obj) { - if(obj == null) return true; - if ((obj instanceof String) && (((String)obj).trim().length() == 0)) { return true; } - if (obj instanceof Map) { return ((Map) obj).isEmpty(); } - if (obj instanceof Map) { return ((Map)obj).isEmpty(); } - if (obj instanceof List) { return ((List)obj).isEmpty(); } - if (obj instanceof Object[]) { return (((Object[])obj).length == 0); } - - return false; - } - - - public static String getServerUrl(){ - HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); - - return String.format("%s://%s:%s", request.getScheme(), request.getServerName(), request.getServerPort()); - } - - public static String printStackTraceToString(Exception e) { - try { - StringWriter errors = new StringWriter(); - e.printStackTrace(new PrintWriter(errors)); - - return errors.toString(); - } catch (Exception ex) { - return "printStackTrace 변환에 실패 했습니다. " + ex.getMessage(); - } - } + throw new RuntimeException(String.format("obj -> jsonString converting fail:: %s", e.getMessage()), e); + } + + return result; + } +// /** +// *
    메소드 설명: jsonString을 Object로 반환한다
    +// * @param clz +// * @param jsonStr +// * @return Object 요청처리 후 응답객체 +// * @author: 박민규 +// * @date: 2021. 12. 23. +// */ +// public static Object jsonStringtoObj(Class clz, String jsonStr) { +// Object result = null; +// +// try { +// ObjectMapper mapper = new ObjectMapper(); +// result = mapper.readValue(jsonStr, clz.getClass()); +// } catch (JsonProcessingException e) { +// throw new RuntimeException(String.format("jsonString -> obj converting fail:: %s", e.getMessage()), e); +// } +// +// return result; +// } + + public static boolean isEmpty(Object obj) { + if (obj == null) return true; + if ((obj instanceof String) && (((String) obj).trim().length() == 0)) { + return true; + } + if (obj instanceof Map) { + return ((Map) obj).isEmpty(); + } + if (obj instanceof Map) { + return ((Map) obj).isEmpty(); + } + if (obj instanceof List) { + return ((List) obj).isEmpty(); + } + if (obj instanceof Object[]) { + return (((Object[]) obj).length == 0); + } + + return false; + } + + + public static String getServerUrl() { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); + + return String.format("%s://%s:%s", request.getScheme(), request.getServerName(), request.getServerPort()); + } + + public static String printStackTraceToString(Exception e) { + try { + StringWriter errors = new StringWriter(); + e.printStackTrace(new PrintWriter(errors)); + + return errors.toString(); + } catch (Exception ex) { + return "printStackTrace 변환에 실패 했습니다. " + ex.getMessage(); + } + } } diff --git a/src/main/java/cokr/xit/ens/core/utils/DateUtil.java b/src/main/java/cokr/xit/ens/core/utils/DateUtil.java index 4f68733..ae46ec6 100644 --- a/src/main/java/cokr/xit/ens/core/utils/DateUtil.java +++ b/src/main/java/cokr/xit/ens/core/utils/DateUtil.java @@ -15,365 +15,396 @@ import java.util.Optional; public class DateUtil { + /** + *
    메소드 설명: 절대시간(단위: milliesecond)을 현재 시간으로 반환 한다.
    + * + * @param millisec + * @param fmt + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static String absTimeMillisecToDate(Long millisec, String fmt) { + if (millisec == null) + return null; + return absTimeToDate(millisec, fmt); + } + + /** + *
    메소드 설명: 절대시간(단위: second)을 현재 시간으로 반환 한다.
    + * + * @param sec + * @param fmt + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static String absTimeSecToDate(int sec, String fmt) { + return absTimeSecToDate(sec * 1L, fmt); + } + + /** + *
    메소드 설명: 절대시간(단위: second)을 현재 시간으로 반환 한다.
    + * + * @param sec + * @param fmt + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static String absTimeSecToDate(Long sec, String fmt) { + if (sec == null) + return null; + return absTimeToDate(sec * 1000L, fmt); + } + + /** + *
    메소드 설명: 절대시간(단위: ms)을 현재 시간으로 반환 한다.
    + * + * @param millionSec + * @param fmt + * @return String 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static String absTimeToDate(Long millionSec, String fmt) { + if (fmt == null || "".equals(fmt)) fmt = "yyyy-MM-dd HH:mm:ss"; + + Date date = new Date(millionSec); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fmt); + + return simpleDateFormat.format(date); + } + + + /** + *
    메소드 설명: 시간을 절대시간(단위: sec)로 반환 한다.
    + * + * @param expireDt 만료일시(yyyyMMddHHmmss) + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static Long dateToAbsTimeSec(String expireDt) { + return dateToAbsTime(expireDt) / 1000; + } + + /** + *
    메소드 설명: 시간을 절대시간(단위: sec)로 반환 한다.
    + * + * @param year + * @param month + * @param day + * @param hour + * @param minute + * @param sec + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static Long dateToAbsTimeSec(int year, int month, int day, int hour, int minute, int sec) { + return dateToAbsTime(year, month, day, hour, minute, sec) / 1000; + } + + /** + *
    메소드 설명: 시간을 절대시간(단위: ms)로 반환 한다.
    + * + * @param expireDt 만료일시(yyyyMMddHHmmss) + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + @SuppressWarnings("finally") + public static Long dateToAbsTime(String expireDt) { + if (expireDt == null) + return 0L; + + expireDt = expireDt.replaceAll("[^0-9]", ""); + if ("".equals(expireDt)) + return 0L; + + int year, month, day, hour, minute, sec; + year = month = day = hour = minute = sec = 0; + try { + year = Integer.parseInt(expireDt.substring(0, 4)); + month = Integer.parseInt(expireDt.substring(4, 6)); + day = Integer.parseInt(expireDt.substring(6, 8)); + hour = Integer.parseInt(expireDt.substring(8, 10)); + minute = Integer.parseInt(expireDt.substring(10, 12)); + sec = Integer.parseInt(expireDt.substring(12, 14)); + } catch (Exception e) { + log.error(String.format("dateToAbsTime fail... expireDt is [%s]", expireDt)); + } finally { + return dateToAbsTime(year, month, day, hour, minute, sec); + } + + } + + /** + *
    메소드 설명: 시간을 절대시간(단위: ms)로 반환 한다.
    + * + * @param year + * @param month + * @param day + * @param hour + * @param minute + * @param sec + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + @SuppressWarnings("deprecation") + public static Long dateToAbsTime(int year, int month, int day, int hour, int minute, int sec) { + if (month < 0) month = 1; + if (month > 11) month = 12; + if (day < 1 || day > 31) day = 1; + if (hour < 0 || hour > 23) hour = 0; + if (minute < 0 || minute > 59) minute = 0; + if (sec < 0 || sec > 59) sec = 0; + + Date curDate = new Date(year - 1900, month - 1, day, hour, minute, sec); + return curDate.getTime(); + } + + + /** + *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    + * + * @param expireDt 만료일시(yyyyMMddHHmmss) + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + @SuppressWarnings("finally") + public static Long dateToRelTime(String expireDt) { + if (expireDt == null) + return 0L; + + expireDt = expireDt.replaceAll("[^0-9]", ""); + if ("".equals(expireDt)) + return 0L; + + int year, month, day, hour, minute, sec; + year = month = day = hour = minute = sec = 0; + try { + year = Integer.parseInt(expireDt.substring(0, 4)); + month = Integer.parseInt(expireDt.substring(4, 6)); + day = Integer.parseInt(expireDt.substring(6, 8)); + hour = Integer.parseInt(expireDt.substring(8, 10)); + minute = Integer.parseInt(expireDt.substring(10, 12)); + sec = Integer.parseInt(expireDt.substring(12, 14)); + } catch (Exception e) { + log.error(String.format("dateToRelTime fail... expireDt is [%s]", expireDt)); + } finally { + return dateToRelTime(year, month, day, hour, minute, sec); + } + + } + + /** + *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    + * + * @param year + * @param month + * @param day + * @param hour + * @param minute + * @param sec + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + @SuppressWarnings("deprecation") + public static Long dateToRelTime(int year, int month, int day, int hour, int minute, int sec) { + if (month < 0) month = 1; + if (month > 11) month = 12; + if (day < 1 || day > 31) day = 1; + if (hour < 0 || hour > 23) hour = 0; + if (minute < 0 || minute > 59) minute = 0; + if (sec < 0 || sec > 59) sec = 0; + + return dateToRelTime(LocalDateTime.of(year, month, day, hour, minute, sec)); + } + + /** + *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    + * + * @param date + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static Long dateToRelTime(LocalDateTime date) { + Long fromDateMs = DateUtil.dateToAbsTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + Long toDateMs = DateUtil.dateToAbsTime(date.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + return toDateMs - fromDateMs; + } + + /** + *
    메소드 설명: 일수를 상대시간(단위: ms)로 반환 한다.
    + * + * @param days + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 11. 19. + */ + public static Long daysToRelTime(int days) { + if (days < 0) days = 0; + return days * 24L * 60L * 60L * 1000L; + } + + /** + *
    메소드 설명: 일시(yyyyMMddHHmmss)를 LocalDateTime 으로 반환 한다.
    + * + * @param yyyyMMddHHmmss + * @return Long 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2022. 3. 15. + */ + public static LocalDateTime toLocalDateTime(String yyyyMMddHHmmss) { + String date = Optional.ofNullable(yyyyMMddHHmmss).orElseGet(() -> null); + + if (date == null) return null; + date = date.replaceAll("[^0-9]", ""); + if (date.length() != 14) + return null; - /** - *
    메소드 설명: 절대시간(단위: milliesecond)을 현재 시간으로 반환 한다.
    - * @param millisec - * @param fmt - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static String absTimeMillisecToDate(Long millisec, String fmt) { - if(millisec==null) - return null; - return absTimeToDate(millisec, fmt); - } - /** - *
    메소드 설명: 절대시간(단위: second)을 현재 시간으로 반환 한다.
    - * @param sec - * @param fmt - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static String absTimeSecToDate(int sec, String fmt) { - return absTimeSecToDate(sec * 1L, fmt); - } - /** - *
    메소드 설명: 절대시간(단위: second)을 현재 시간으로 반환 한다.
    - * @param sec - * @param fmt - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static String absTimeSecToDate(Long sec, String fmt) { - if(sec==null) - return null; - return absTimeToDate(sec * 1000L, fmt); - } - /** - *
    메소드 설명: 절대시간(단위: ms)을 현재 시간으로 반환 한다.
    - * @param millionSec - * @param fmt - * @return String 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static String absTimeToDate(Long millionSec, String fmt) { - if(fmt == null || "".equals(fmt)) fmt = "yyyy-MM-dd HH:mm:ss"; - - Date date = new Date(millionSec); - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fmt); - - return simpleDateFormat.format(date); - } - - - /** - *
    메소드 설명: 시간을 절대시간(단위: sec)로 반환 한다.
    - * @param expireDt 만료일시(yyyyMMddHHmmss) - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static Long dateToAbsTimeSec(String expireDt) { - return dateToAbsTime(expireDt)/1000; - } - /** - *
    메소드 설명: 시간을 절대시간(단위: sec)로 반환 한다.
    - * @param year - * @param month - * @param day - * @param hour - * @param minute - * @param sec - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static Long dateToAbsTimeSec(int year, int month, int day, int hour, int minute, int sec) { - return dateToAbsTime(year, month, day, hour, minute, sec)/1000; - } - /** - *
    메소드 설명: 시간을 절대시간(단위: ms)로 반환 한다.
    - * @param expireDt 만료일시(yyyyMMddHHmmss) - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - @SuppressWarnings("finally") - public static Long dateToAbsTime(String expireDt) { - if(expireDt==null) - return 0L; - - expireDt = expireDt.replaceAll("[^0-9]", ""); - if("".equals(expireDt)) - return 0L; - - int year, month, day, hour, minute, sec; - year = month = day = hour = minute = sec = 0; - try { - year = Integer.parseInt(expireDt.substring(0,4)); - month = Integer.parseInt(expireDt.substring(4,6)); - day = Integer.parseInt(expireDt.substring(6,8)); - hour = Integer.parseInt(expireDt.substring(8,10)); - minute = Integer.parseInt(expireDt.substring(10,12)); - sec = Integer.parseInt(expireDt.substring(12,14)); - } catch(Exception e) { - log.error(String.format("dateToAbsTime fail... expireDt is [%s]", expireDt)); - } finally { - return dateToAbsTime(year, month, day, hour, minute, sec); - } - - } - /** - *
    메소드 설명: 시간을 절대시간(단위: ms)로 반환 한다.
    - * @param year - * @param month - * @param day - * @param hour - * @param minute - * @param sec - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - @SuppressWarnings("deprecation") - public static Long dateToAbsTime(int year, int month, int day, int hour, int minute, int sec) { - if(month < 0) month = 1; - if(month > 11) month = 12; - if(day < 1 || day > 31) day = 1; - if(hour < 0 || hour > 23) hour = 0; - if(minute < 0 || minute > 59) minute = 0; - if(sec < 0 || sec > 59) sec = 0; - - Date curDate = new Date (year-1900, month-1, day, hour, minute, sec); - return curDate.getTime(); - } - - - - - /** - *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    - * @param expireDt 만료일시(yyyyMMddHHmmss) - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - @SuppressWarnings("finally") - public static Long dateToRelTime(String expireDt) { - if(expireDt==null) - return 0L; - - expireDt = expireDt.replaceAll("[^0-9]", ""); - if("".equals(expireDt)) - return 0L; - - int year, month, day, hour, minute, sec; - year = month = day = hour = minute = sec = 0; - try { - year = Integer.parseInt(expireDt.substring(0,4)); - month = Integer.parseInt(expireDt.substring(4,6)); - day = Integer.parseInt(expireDt.substring(6,8)); - hour = Integer.parseInt(expireDt.substring(8,10)); - minute = Integer.parseInt(expireDt.substring(10,12)); - sec = Integer.parseInt(expireDt.substring(12,14)); - } catch(Exception e) { - log.error(String.format("dateToRelTime fail... expireDt is [%s]", expireDt)); - } finally { - return dateToRelTime(year, month, day, hour, minute, sec); - } - - } - /** - *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    - * @param year - * @param month - * @param day - * @param hour - * @param minute - * @param sec - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - @SuppressWarnings("deprecation") - public static Long dateToRelTime(int year, int month, int day, int hour, int minute, int sec) { - if(month < 0) month = 1; - if(month > 11) month = 12; - if(day < 1 || day > 31) day = 1; - if(hour < 0 || hour > 23) hour = 0; - if(minute < 0 || minute > 59) minute = 0; - if(sec < 0 || sec > 59) sec = 0; - - return dateToRelTime(LocalDateTime.of(year, month, day, hour, minute, sec)); - } - /** - *
    메소드 설명: 시간을 상대시간(단위: ms)로 반환 한다.
    - * @param date - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static Long dateToRelTime(LocalDateTime date){ - - Long fromDateMs = DateUtil.dateToAbsTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); - Long toDateMs = DateUtil.dateToAbsTime(date.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); - - return toDateMs - fromDateMs; - } - - /** - *
    메소드 설명: 일수를 상대시간(단위: ms)로 반환 한다.
    - * @param days - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 11. 19. - */ - public static Long daysToRelTime(int days) { - if(days<0) days=0; - return days * 24L * 60L * 60L * 1000L; - } - - /** - *
    메소드 설명: 일시(yyyyMMddHHmmss)를 LocalDateTime 으로 반환 한다.
    - * @param yyyyMMddHHmmss - * @return Long 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2022. 3. 15. - */ - public static LocalDateTime toLocalDateTime(String yyyyMMddHHmmss){ - String date = Optional.ofNullable(yyyyMMddHHmmss).orElseGet(()->null); - - if(date==null) return null; - - date = date.replaceAll("[^0-9]", ""); - if(date.length()!=14) - return null; - - - return LocalDateTime.of( - Integer.parseInt(date.substring(0,4)) - , Integer.parseInt(date.substring(4,6)) - , Integer.parseInt(date.substring(6,8)) - , Integer.parseInt(date.substring(8,10)) - , Integer.parseInt(date.substring(10,12)) - , Integer.parseInt(date.substring(12,14)) - ); - } - - - /** - * 날짜(date) 사이의 간격을 계산하여 일자(day)로 반환 한다. - * @param fromDate - * @param toDate - * @return - */ - public static int daysByFromBetweenTo(Date fromDate, Date toDate){ - return daysByFromBetweenTo(fromDate.getTime(), toDate.getTime()); - } - /** - * 날짜(date) 사이의 간격을 계산하여 일자(day)로 반환 한다. - * @param fromDate - * @param toDate - * @return - */ - public static int daysByFromBetweenTo(LocalDateTime fromDate, LocalDateTime toDate){ - return daysByFromBetweenTo(Timestamp.valueOf(fromDate).getTime(), Timestamp.valueOf(toDate).getTime()); - } - /** - * 초(sec) 사이의 간격을 계산하여 일자(day)로 반환 한다. - * @param fromSec - * @param toSec - * @return - */ - public static int daysByFromBetweenTo(int fromSec, int toSec){ - return daysByFromBetweenTo(fromSec*1000L, toSec*1000L); - } - /** - * 밀리초(ms) 사이의 간격을 계산하여 일자(day)로 반환 한다. - * @param fromMs - * @param toMs - * @return - */ - public static int daysByFromBetweenTo(long fromMs, long toMs){ - return (int) ((toMs - fromMs)/(24*60*60*1000)); - } - /** - * 밀리초(ms) 사이의 간격을 계산하여 초(second)로 반환 한다. - * @param fromDate - * @param toDate - * @toDate - */ - public static int secByFromBetweenTo(LocalDateTime fromDate, LocalDateTime toDate){ - return secByFromBetweenTo(Timestamp.valueOf(fromDate).getTime(), Timestamp.valueOf(toDate).getTime()); - } - /** - * 밀리초(ms) 사이의 간격을 계산하여 초(second)로 반환 한다. - * @param fromMs - * @param toMs - * @return - */ - public static int secByFromBetweenTo(long fromMs, long toMs){ - return (int) ((toMs - fromMs)/(1000)); - } - - - /** - * 초(sec)를 일수(day)로 반환 한다. - * @return - */ - public static int secToDays(int sec){ - return msToDays(sec*1000L); - } - /** - * 밀리초(ms)를 일수(day)로 반환 한다. - * @return - */ - public static int msToDays(long ms){ - return (int) (ms/(24*60*60*1000)); - } + return LocalDateTime.of( + Integer.parseInt(date.substring(0, 4)) + , Integer.parseInt(date.substring(4, 6)) + , Integer.parseInt(date.substring(6, 8)) + , Integer.parseInt(date.substring(8, 10)) + , Integer.parseInt(date.substring(10, 12)) + , Integer.parseInt(date.substring(12, 14)) + ); + } + + + /** + * 날짜(date) 사이의 간격을 계산하여 일자(day)로 반환 한다. + * + * @param fromDate + * @param toDate + * @return + */ + public static int daysByFromBetweenTo(Date fromDate, Date toDate) { + return daysByFromBetweenTo(fromDate.getTime(), toDate.getTime()); + } + + /** + * 날짜(date) 사이의 간격을 계산하여 일자(day)로 반환 한다. + * + * @param fromDate + * @param toDate + * @return + */ + public static int daysByFromBetweenTo(LocalDateTime fromDate, LocalDateTime toDate) { + return daysByFromBetweenTo(Timestamp.valueOf(fromDate).getTime(), Timestamp.valueOf(toDate).getTime()); + } + + /** + * 초(sec) 사이의 간격을 계산하여 일자(day)로 반환 한다. + * + * @param fromSec + * @param toSec + * @return + */ + public static int daysByFromBetweenTo(int fromSec, int toSec) { + return daysByFromBetweenTo(fromSec * 1000L, toSec * 1000L); + } + + /** + * 밀리초(ms) 사이의 간격을 계산하여 일자(day)로 반환 한다. + * + * @param fromMs + * @param toMs + * @return + */ + public static int daysByFromBetweenTo(long fromMs, long toMs) { + return (int) ((toMs - fromMs) / (24 * 60 * 60 * 1000)); + } + + /** + * 밀리초(ms) 사이의 간격을 계산하여 초(second)로 반환 한다. + * + * @param fromDate + * @param toDate + * @toDate + */ + public static int secByFromBetweenTo(LocalDateTime fromDate, LocalDateTime toDate) { + return secByFromBetweenTo(Timestamp.valueOf(fromDate).getTime(), Timestamp.valueOf(toDate).getTime()); + } + + /** + * 밀리초(ms) 사이의 간격을 계산하여 초(second)로 반환 한다. + * + * @param fromMs + * @param toMs + * @return + */ + public static int secByFromBetweenTo(long fromMs, long toMs) { + return (int) ((toMs - fromMs) / (1000)); + } + + + /** + * 초(sec)를 일수(day)로 반환 한다. + * + * @return + */ + public static int secToDays(int sec) { + return msToDays(sec * 1000L); + } + + /** + * 밀리초(ms)를 일수(day)로 반환 한다. + * + * @return + */ + public static int msToDays(long ms) { + return (int) (ms / (24 * 60 * 60 * 1000)); + } /** * 현재날짜에 초(sec)를 더한 날짜를 반환 한다. + * * @param sec * @param pattern * @return */ - public static String relTimeSecToDate(int sec, String pattern){ - if("".equals(pattern)||pattern==null) + public static String relTimeSecToDate(int sec, String pattern) { + if ("".equals(pattern) || pattern == null) pattern = "yyyyMMdd"; Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis((sec*1000L) + (new Date().getTime())); + calendar.setTimeInMillis((sec * 1000L) + (new Date().getTime())); Date date = calendar.getTime(); return new SimpleDateFormat(pattern).format(date); } + /** * 특정날짜에 초(sec)를 더한 날짜를 반환 한다. + * * @param sec * @param pattern * @return */ - public static String addRelTimeSecToDate(LocalDateTime localDateTime, int sec, String pattern){ - if("".equals(pattern)||pattern==null) + public static String addRelTimeSecToDate(LocalDateTime localDateTime, int sec, String pattern) { + if ("".equals(pattern) || pattern == null) pattern = "yyyyMMdd"; Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis((sec*1000L) + Timestamp.valueOf(localDateTime).getTime()); + calendar.setTimeInMillis((sec * 1000L) + Timestamp.valueOf(localDateTime).getTime()); Date date = calendar.getTime(); return new SimpleDateFormat(pattern).format(date); } - + } diff --git a/src/main/java/cokr/xit/ens/core/utils/IdGenerator.java b/src/main/java/cokr/xit/ens/core/utils/IdGenerator.java index 1f3fdff..0a164bc 100644 --- a/src/main/java/cokr/xit/ens/core/utils/IdGenerator.java +++ b/src/main/java/cokr/xit/ens/core/utils/IdGenerator.java @@ -19,8 +19,9 @@ public class IdGenerator { } while (!currentTime.compareAndSet(prev, next)); return next; } + public static Long getCurrentTimeSec() { - return IdGenerator.getCurrentTimeMs()/1000L; + return IdGenerator.getCurrentTimeMs() / 1000L; } public static String getRandomString(int length) { diff --git a/src/main/java/cokr/xit/ens/core/utils/JwtUtil.java b/src/main/java/cokr/xit/ens/core/utils/JwtUtil.java index ae4b694..af9efcc 100644 --- a/src/main/java/cokr/xit/ens/core/utils/JwtUtil.java +++ b/src/main/java/cokr/xit/ens/core/utils/JwtUtil.java @@ -1,112 +1,112 @@ package cokr.xit.ens.core.utils; -import java.util.Base64; -import java.util.Date; -import java.util.Iterator; -import java.util.Map; -import java.util.Base64.Decoder; - -import org.springframework.util.StringUtils; - import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; - import lombok.Builder; import lombok.Getter; +import org.springframework.util.StringUtils; + +import java.util.Base64; +import java.util.Base64.Decoder; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; @Getter public class JwtUtil { - @SuppressWarnings("unused") - public final static String DEFAULT_SECRET_KEY = "czovL3d3dy50ZXN0LmNvLmtyIiwicm9sZX"; - - private String token; - - private String header; - private String payload; - - private boolean isCertified = false; - private Map claims; - - @SuppressWarnings("deprecation") - @Builder(builderClassName = "createBuilder", builderMethodName = "createBuilder") - public JwtUtil(String secretKey, String iss, String sub, String aud, Date exp, Date nbf, Date iat, String jti, String uUuid, String[] roles) { - if(StringUtils.isEmpty(secretKey)) - throw new RuntimeException("SecretKey(은)는 필수조건 입니다."); - - this.token = JWT.create() - .withIssuer(iss) - .withSubject(sub) - .withAudience(aud) - .withExpiresAt(exp) - .withNotBefore(nbf) - .withIssuedAt(iat) - .withJWTId(jti) - .withClaim("uUuid", uUuid) - .withArrayClaim("roles", roles) - .sign(Algorithm.HMAC512(secretKey.getBytes())); - } - - - @Builder(builderClassName = "decodeBuilder", builderMethodName = "decodeBuilder") - public JwtUtil(String jwt) { - - Decoder decoder = Base64.getDecoder(); - final String[] splitJwt = jwt.split("\\."); - this.token = jwt; - this.header = new String(decoder.decode(splitJwt[0].getBytes())); - this.payload = new String(decoder.decode(splitJwt[1].getBytes())); - } - - - @Builder(builderClassName = "verifyBuilder", builderMethodName = "verifyBuilder") - public JwtUtil(String secretKey, String jwt) { - this.verify(secretKey, jwt, Algorithm.HMAC512(secretKey.getBytes())); - } - @Builder(builderClassName = "verifyBuilderByAlgorithm", builderMethodName = "verifyBuilderByAlgorithm") - public JwtUtil(String secretKey, String token, Algorithm algorithm) { - this.verify(secretKey, token, algorithm); - } - @SuppressWarnings("deprecation") - private void verify(String secretKey, String jwt, Algorithm algorithm) { - if(StringUtils.isEmpty(secretKey)) - throw new RuntimeException("SecretKey(은)는 필수조건 입니다."); - - try { - System.out.println(String.format("[Token] => %s", jwt)); - this.claims = JWT.require(algorithm) - .build() - .verify(jwt.replace("Bearer", "").trim()) - .getClaims(); - - this.isCertified = true; - }catch(Exception e) { - this.isCertified = false; - System.out.println(String.format("Token Verify Fail... %s", e.getMessage())); - } - } - - public void claimsToString() { - System.out.println("[Token Claims]"); - if(this.claims == null) - return; - - Iterator it = this.claims.keySet().iterator(); - while(it.hasNext()) { - String key = it.next(); - Claim claim = this.claims.get(key); + @SuppressWarnings("unused") + public final static String DEFAULT_SECRET_KEY = "czovL3d3dy50ZXN0LmNvLmtyIiwicm9sZX"; + + private String token; + + private String header; + private String payload; + + private boolean isCertified = false; + private Map claims; + + @SuppressWarnings("deprecation") + @Builder(builderClassName = "createBuilder", builderMethodName = "createBuilder") + public JwtUtil(String secretKey, String iss, String sub, String aud, Date exp, Date nbf, Date iat, String jti, String uUuid, String[] roles) { + if (StringUtils.isEmpty(secretKey)) + throw new RuntimeException("SecretKey(은)는 필수조건 입니다."); + + this.token = JWT.create() + .withIssuer(iss) + .withSubject(sub) + .withAudience(aud) + .withExpiresAt(exp) + .withNotBefore(nbf) + .withIssuedAt(iat) + .withJWTId(jti) + .withClaim("uUuid", uUuid) + .withArrayClaim("roles", roles) + .sign(Algorithm.HMAC512(secretKey.getBytes())); + } + + + @Builder(builderClassName = "decodeBuilder", builderMethodName = "decodeBuilder") + public JwtUtil(String jwt) { + + Decoder decoder = Base64.getDecoder(); + final String[] splitJwt = jwt.split("\\."); + this.token = jwt; + this.header = new String(decoder.decode(splitJwt[0].getBytes())); + this.payload = new String(decoder.decode(splitJwt[1].getBytes())); + } + + + @Builder(builderClassName = "verifyBuilder", builderMethodName = "verifyBuilder") + public JwtUtil(String secretKey, String jwt) { + this.verify(secretKey, jwt, Algorithm.HMAC512(secretKey.getBytes())); + } + + @Builder(builderClassName = "verifyBuilderByAlgorithm", builderMethodName = "verifyBuilderByAlgorithm") + public JwtUtil(String secretKey, String token, Algorithm algorithm) { + this.verify(secretKey, token, algorithm); + } + + @SuppressWarnings("deprecation") + private void verify(String secretKey, String jwt, Algorithm algorithm) { + if (StringUtils.isEmpty(secretKey)) + throw new RuntimeException("SecretKey(은)는 필수조건 입니다."); + + try { + System.out.println(String.format("[Token] => %s", jwt)); + this.claims = JWT.require(algorithm) + .build() + .verify(jwt.replace("Bearer", "").trim()) + .getClaims(); + + this.isCertified = true; + } catch (Exception e) { + this.isCertified = false; + System.out.println(String.format("Token Verify Fail... %s", e.getMessage())); + } + } + + public void claimsToString() { + System.out.println("[Token Claims]"); + if (this.claims == null) + return; + + Iterator it = this.claims.keySet().iterator(); + while (it.hasNext()) { + String key = it.next(); + Claim claim = this.claims.get(key); // System.out.println(String.format(" %s = %s", key, claim.asString())); - if(claim.asMap() != null) - System.out.println(String.format(" %s = %s", key, claim.asMap().toString())); - else if(claim.asArray(String.class) != null) { - StringBuilder sb = new StringBuilder(); - for(String str : claim.asArray(String.class)) - sb.append(",").append(str); - System.out.println(String.format(" %s = [%s]", key, sb.toString().substring(1))); - } else - System.out.println(String.format(" %s = %s", key, claim.as(String.class))); - } - } - + if (claim.asMap() != null) + System.out.println(String.format(" %s = %s", key, claim.asMap().toString())); + else if (claim.asArray(String.class) != null) { + StringBuilder sb = new StringBuilder(); + for (String str : claim.asArray(String.class)) + sb.append(",").append(str); + System.out.println(String.format(" %s = [%s]", key, sb.toString().substring(1))); + } else + System.out.println(String.format(" %s = %s", key, claim.as(String.class))); + } + } + } diff --git a/src/main/java/cokr/xit/ens/core/utils/MapDeserailizer.java b/src/main/java/cokr/xit/ens/core/utils/MapDeserailizer.java index d1abb9d..92b0d9b 100644 --- a/src/main/java/cokr/xit/ens/core/utils/MapDeserailizer.java +++ b/src/main/java/cokr/xit/ens/core/utils/MapDeserailizer.java @@ -7,47 +7,48 @@ import java.util.*; public class MapDeserailizer implements JsonDeserializer> { - @Override @SuppressWarnings("unchecked") + @Override + @SuppressWarnings("unchecked") public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { return (Map) read(json); } public Object read(JsonElement in) { - if(in.isJsonArray()){ - + if (in.isJsonArray()) { + List list = new ArrayList(); JsonArray arr = in.getAsJsonArray(); for (JsonElement anArr : arr) { - + list.add(read(anArr)); } return list; - }else if(in.isJsonObject()){ + } else if (in.isJsonObject()) { Map map = new HashMap(); JsonObject obj = in.getAsJsonObject(); Set> entitySet = obj.entrySet(); - for(Map.Entry entry: entitySet){ - + for (Map.Entry entry : entitySet) { + map.put(entry.getKey(), read(entry.getValue())); } return map; - }else if( in.isJsonPrimitive()){ + } else if (in.isJsonPrimitive()) { JsonPrimitive prim = in.getAsJsonPrimitive(); - if(prim.isBoolean()){ - + if (prim.isBoolean()) { + return prim.getAsBoolean(); - }else if(prim.isString()){ - + } else if (prim.isString()) { + return prim.getAsString(); - }else if(prim.isNumber()){ + } else if (prim.isNumber()) { Number num = prim.getAsNumber(); - - if(Math.ceil(num.doubleValue()) == num.longValue()) - + + if (Math.ceil(num.doubleValue()) == num.longValue()) + return num.longValue(); - else{ - + else { + return num.doubleValue(); } } diff --git a/src/main/java/cokr/xit/ens/core/utils/RequireValidator.java b/src/main/java/cokr/xit/ens/core/utils/RequireValidator.java index 522cb25..2725c00 100644 --- a/src/main/java/cokr/xit/ens/core/utils/RequireValidator.java +++ b/src/main/java/cokr/xit/ens/core/utils/RequireValidator.java @@ -1,79 +1,79 @@ package cokr.xit.ens.core.utils; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; +import lombok.Builder; +import lombok.Getter; +import org.springframework.util.StringUtils; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; - -import org.springframework.util.StringUtils; - -import lombok.Builder; -import lombok.Getter; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; @Builder @Getter public class RequireValidator { - - private Object obj; - - private List message = new ArrayList<>(); - - - /** - *
    메소드 설명: 객체 검증
    -	 * 	-.검증을 통과하지 못한 필드의 메시지를 message 필드에 설정한다.
    -	 * 
    - * @return RequireValidator 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 8. 6. - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public RequireValidator validate() { - Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); - Set> validate = validator.validate(this.obj); - - if(!validate.isEmpty()) { - this.message = new ArrayList(); - - Iterator it = validate.iterator(); - while(it.hasNext()) { - ConstraintViolation cv = (ConstraintViolation) it.next(); - this.message.add(cv.getMessage()); - } - } - - - return this; - } - - - /** - *
    메소드 설명: Exception 발생
    -	 * 	-.message가 null이 아닐 경우 Exception을 발생 시킨다.
    -	 * 
    - * void 요청처리 후 응답객체 - * @author: 박민규 - * @date: 2021. 8. 6. - */ - @SuppressWarnings("deprecation") - public RequireValidator throwableException() { - if(!StringUtils.isEmpty(this.message)) + + private Object obj; + + private List message = new ArrayList<>(); + + + /** + *
    메소드 설명: 객체 검증
    +     * 	-.검증을 통과하지 못한 필드의 메시지를 message 필드에 설정한다.
    +     * 
    + * + * @return RequireValidator 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 6. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + public RequireValidator validate() { + Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); + Set> validate = validator.validate(this.obj); + + if (!validate.isEmpty()) { + this.message = new ArrayList(); + + Iterator it = validate.iterator(); + while (it.hasNext()) { + ConstraintViolation cv = (ConstraintViolation) it.next(); + this.message.add(cv.getMessage()); + } + } + + + return this; + } + + + /** + *
    메소드 설명: Exception 발생
    +     * 	-.message가 null이 아닐 경우 Exception을 발생 시킨다.
    +     * 
    + * void 요청처리 후 응답객체 + * + * @author: 박민규 + * @date: 2021. 8. 6. + */ + @SuppressWarnings("deprecation") + public RequireValidator throwableException() { + if (!StringUtils.isEmpty(this.message)) // throw new CustomException(RESP_CODE.INVALID_PARAMETER, message.toString()); - throw new RuntimeException(String.format("유효성 검증 Fail::: %s", message.toString())); - - return this; - } - - @Override - public String toString() { - if(!StringUtils.isEmpty(this.message)) - return message.toString(); - else - return null; - } - + throw new RuntimeException(String.format("유효성 검증 Fail::: %s", message.toString())); + + return this; + } + + @Override + public String toString() { + if (!StringUtils.isEmpty(this.message)) + return message.toString(); + else + return null; + } + } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqDTO.java deleted file mode 100644 index 7198ce4..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqDTO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill; - -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO; -import com.fasterxml.jackson.annotation.JsonAlias; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -@Builder -@Getter -@Setter -@Schema(name = "BillAcptReqDTO") -public class BillAcptReqDTO { - - @NotNull(message = "청구서ID 사용 여부는 필수 입력값 입니다.") - @Schema(required = true, title = "청구서ID 사용 여부", example = "false") - private Boolean use_bill_uid; - - @Schema(required = false, title = "청구서 유니크ID", example = " ") - private String bill_uid; - - @NotNull - @Schema(required = true, title = "청구서 타입", example = "all") - private BillSeCd bill_se; - - @Valid - @JsonAlias({"bill_kko"}) - private BillKkoAcptReqVO bill_kko; -// @Valid -// @JsonAlias({"bill_nv"}) -// private BillNvAcptReqVO bill_nv; - -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqData.java deleted file mode 100644 index 4434b8b..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillAcptReqData.java +++ /dev/null @@ -1,6 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill; - -public interface BillAcptReqData { - - T get(); -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillMakerSupport.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillMakerSupport.java deleted file mode 100644 index ba0f20a..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillMakerSupport.java +++ /dev/null @@ -1,127 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill; - -import cokr.xit.ens.core.aop.EnsResponseVO; -import cokr.xit.ens.core.exception.EnsException; -import cokr.xit.ens.core.exception.code.EnsErrCd; -import cokr.xit.ens.core.monitor.slack.event.MonitorEvent; -import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; -import cokr.xit.ens.modules.common.monitor.MessageByBill; -import com.google.common.collect.Lists; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Function; - -public abstract class BillMakerSupport implements Consumer>, Function, EnsResponseVO> { - - @Autowired - private ApplicationEventPublisher applicationEventPublisher; - - @Transactional - @Override - public void accept(List bills) { - try { - Lists.partition(filter(bills), 500).stream() - .forEach(partBillUids -> { - List partBills = findBillsByBillUidsAndNotExists(partBillUids); - acceptProc(partBills); - }); - } catch (EnsException e) { - throw e; - } catch (Exception e) { - throw new EnsException(EnsErrCd.BILL999, e.getMessage()); - } - - } - - @Transactional(propagation = Propagation.REQUIRES_NEW) - @Override - public EnsResponseVO apply(List bills) { - try { - if (CmmnUtil.isEmpty(bills)) - return EnsResponseVO.okBuilder().build(); - - int cntTotFail = Lists.partition(filter(bills), 500).stream() - .map(partBillUids -> { - List partBills = findBillsByBillUidsAndUrlIsNull(partBillUids); - if (partBills.size() == 0) - return 0; - - - return generateUrlProc(partBills); - }) - .reduce(Integer::sum) - .get(); - - - if (cntTotFail == 0) - return EnsResponseVO.okBuilder().build(); - else - return EnsResponseVO.errBuilder() - .errCode(EnsErrCd.BILL512) - .errMsg(String.format("총 %d건 중 %d건 생성 실패", bills.size(), cntTotFail)) - .build(); - } catch (EnsException e) { - return EnsResponseVO.errBuilder() - .errCode(e.getErrCd()) - .errMsg(e.getMessage()) - .build(); - } catch (Exception e) { - return EnsResponseVO.errBuilder() - .errCode(EnsErrCd.BILL999) - .errMsg(e.getMessage()) - .build(); - } - } - - abstract protected BillSeCd getBillSeCd(); - - abstract protected List filter(List bills); - - /** - * 청구서 접수 처리 - * @param bills - * @throws EnsException - */ - abstract protected void acceptProc(List bills) throws EnsException; - - /** - * 미접수 청구서 조회 - * @param billUids - * @return - */ - abstract protected List findBillsByBillUidsAndNotExists(List billUids); - - /** - * 청구서 URL 생성 처리 - * @param bills - * @return - */ - abstract protected int generateUrlProc(List bills); - - /** - * URL 미생성 청구서 조회 - * @param billUids - * @return - */ - abstract protected List findBillsByBillUidsAndUrlIsNull(List billUids); - - protected void errSend(EnsErrCd ensErrCd, String message, Exception e) { - - applicationEventPublisher.publishEvent(MonitorEvent.builder() - .message(MessageByBill.builder() - .oClass(getClass().getSimpleName() + "." + new Throwable().getStackTrace()[0].getMethodName()) - .billSeCd(getBillSeCd()) - .errCd(ensErrCd) - .message(message + "\n" + CmmnUtil.printStackTraceToString(e)) - .build()) - .build()); - } - -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillService.java deleted file mode 100644 index 543383b..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillService.java +++ /dev/null @@ -1,8 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill; - -public interface BillService { - T accept(ACPTREQ acptreq); - - T createUrl(URLREQ urlreq); - -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillUrlReqData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillUrlReqData.java deleted file mode 100644 index 653e821..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/BillUrlReqData.java +++ /dev/null @@ -1,6 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill; - -public interface BillUrlReqData { - - T get(); -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillReqSeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillReqSeCd.java deleted file mode 100644 index 9536e11..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillReqSeCd.java +++ /dev/null @@ -1,41 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.code; - -import cokr.xit.ens.core.code.CodeMapperType; - - -/** - *
      - *
    • 업무 그룹명: 청구서API - 요청구분 코드
    • - *
    • 설 명:
    • - *
    • 작성일: 2022. 2. 15. 오후 3:51:43 - *
    - * @author 박민규 - */ - -public enum BillReqSeCd implements CodeMapperType { - - ACPT("요청 접수") - ,URL("청구서링크생성") - ,REURL("청구서링크재생성") - ,NOTICE("청구서조회") - ,PREPAY("납부가능조회") - ,PAYRSLT("납부결과전달") - ; - - private final String code; - private final String codeNm; - BillReqSeCd(String codeNm) { - this.code = this.name(); - this.codeNm = codeNm; - } - - @Override - public String getCode() { - return this.code; - } - - @Override - public String getCodeNm() { - return this.codeNm; - } -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/Bill.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/Bill.java deleted file mode 100644 index a230795..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/Bill.java +++ /dev/null @@ -1,50 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity; - -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; -import lombok.experimental.SuperBuilder; - -import javax.persistence.*; -import java.io.Serializable; - -@Entity -@Getter -@ToString -@NoArgsConstructor -@AllArgsConstructor -@SuperBuilder -//@Inheritance(strategy = InheritanceType.JOINED) -//@DiscriminatorColumn(name = "dtype") -//@DiscriminatorValue("master") -@Table(name = "ens_bill", schema = "", catalog = "") -public class Bill extends BillEntity implements Serializable { - @Id - @GeneratedValue(strategy = GenerationType.TABLE, generator = "Bill_Generator") - @TableGenerator(table = "ens_seq_generator", name = "Bill_Generator" - , pkColumnName = "seq_name", pkColumnValue = "Bill_id" - , initialValue = 0, allocationSize = 200) - - private Long billId; - - @Enumerated(EnumType.STRING) - - @Column(name = "bill_se_cd") - private BillSeCd billSeCd; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "org_cd") - @Setter - private OrgMng orgMng; - - - @Column(name = "doc_bill_kko", nullable = true) - @Lob - private String docBillKko; - - - @Column(name = "doc_bill_nv", nullable = true) - @Lob - private String docBillNv; -} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillHistRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillHistRepository.java deleted file mode 100644 index 4dc0b77..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillHistRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository; - -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist; -import org.springframework.data.jpa.repository.JpaRepository; - -public interface BillHistRepository extends JpaRepository { - - -} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillSeRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillSeRepository.java deleted file mode 100644 index b58472e..0000000 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillSeRepository.java +++ /dev/null @@ -1,10 +0,0 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository; - -public interface BillSeRepository { - - String findUrlByBillUid(String billUid); - - - - -} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApi.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApi.java similarity index 96% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApi.java rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApi.java index 67b1161..47d9840 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApi.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApi.java @@ -21,7 +21,7 @@ import java.nio.charset.StandardCharsets; @Slf4j @Component @Profile({"!local-test"}) -public class BillKkoApi implements BillKkoApiSpec { +public class BillKkoPayApi implements BillKkoPayApiSpec { @Value("${contract.kakao.pay.bill.dozn.host}") private String HOST; @@ -30,59 +30,6 @@ public class BillKkoApi implements BillKkoApiSpec { @Value("${contract.kakao.pay.bill.dozn.api.reurl}") private String API_RE_URL; - /** - * 청구서링크 생성 - * - * @param billerCode - * @param authorization - * @param jsonStr - * @return - */ - @Override - public ResponseEntity url(String billerCode, String authorization, String jsonStr) { - - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", authorization); - headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); - headers.set("X-Xit-BillerCode", billerCode); - - - StringBuilder url = new StringBuilder(); - url.append(this.HOST) - .append(this.API_URL.replace("{billerCode}", billerCode == null ? "" : billerCode)); - - - ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers); - return resp; - } - - - /** - * 청구서링크 재생성 - * - * @param billerCode - * @param authorization - * @param jsonStr - * @return - */ - @Override - public ResponseEntity reUrl(String billerCode, String authorization, String jsonStr) { - - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", authorization); - headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); - headers.set("X-Xit-BillerCode", billerCode); - - - StringBuilder url = new StringBuilder(); - url.append(this.HOST) - .append(this.API_RE_URL.replace("{billerCode}", billerCode == null ? "" : billerCode)); - - - ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers); - return resp; - } - /** *
    메소드 설명: API 호출
    @@ -95,7 +42,6 @@ public class BillKkoApi implements BillKkoApiSpec {
          * @return ResponseEntity 요청처리 후 응답객체
          * @author: 박민규
          * @date: 2021. 8. 4.
    -     * @apiNote: 사이트 참조 https://e2e2e2.tistory.com/15
          */
         private ResponseEntity callApi(HttpMethod method, String url, String body, HttpHeaders headers) {
     
    @@ -128,9 +74,8 @@ public class BillKkoApi implements BillKkoApiSpec {
     
     
                 HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    -            factory.setConnectTimeout(2000);
    -//            factory.setReadTimeout(2000);
    -            factory.setReadTimeout(10000);
    +            factory.setConnectTimeout(5000); 
    +            factory.setReadTimeout(60000);
                 RestTemplate restTemplate = new RestTemplate(factory);
                 sb.append("\n  url => " + uri.toString())
                         .append("\n  method => " + method)
    @@ -165,4 +110,57 @@ public class BillKkoApi implements BillKkoApiSpec {
         }
     
     
    +    /**
    +     * 청구서링크 생성
    +     *
    +     * @param billerCode
    +     * @param authorization
    +     * @param jsonStr
    +     * @return
    +     */
    +    @Override
    +    public ResponseEntity url(String billerCode, String authorization, String jsonStr) {
    +       
    +        HttpHeaders headers = new HttpHeaders();
    +        headers.set("Authorization", authorization);
    +        headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8")));
    +        headers.set("X-Xit-BillerCode", billerCode);
    +
    +       
    +        StringBuilder url = new StringBuilder();
    +        url.append(this.HOST)
    +                .append(this.API_URL.replace("{billerCode}", billerCode == null ? "" : billerCode));
    +
    +       
    +        ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers);
    +        return resp;
    +    }
    +
    +
    +    /**
    +     * 청구서링크 재생성
    +     *
    +     * @param billerCode
    +     * @param authorization
    +     * @param jsonStr
    +     * @return
    +     */
    +    @Override
    +    public ResponseEntity reUrl(String billerCode, String authorization, String jsonStr) {
    +       
    +        HttpHeaders headers = new HttpHeaders();
    +        headers.set("Authorization", authorization);
    +        headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8")));
    +        headers.set("X-Xit-BillerCode", billerCode);
    +
    +       
    +        StringBuilder url = new StringBuilder();
    +        url.append(this.HOST)
    +                .append(this.API_RE_URL.replace("{billerCode}", billerCode == null ? "" : billerCode));
    +
    +       
    +        ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers);
    +        return resp;
    +    }
    +
     }
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiSpec.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiSpec.java
    similarity index 94%
    rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiSpec.java
    rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiSpec.java
    index c2d83f2..912aa8f 100644
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiSpec.java
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiSpec.java
    @@ -2,7 +2,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api;
     
     import org.springframework.http.ResponseEntity;
     
    -public interface BillKkoApiSpec {
    +public interface BillKkoPayApiSpec {
     
         /**
          * 청구서링크 생성
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiTest.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiTest.java
    similarity index 98%
    rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiTest.java
    rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiTest.java
    index a7a01a8..535a38a 100644
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoApiTest.java
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/api/BillKkoPayApiTest.java
    @@ -16,7 +16,7 @@ import java.nio.charset.StandardCharsets;
     @Slf4j
     @Component
     @Profile({"local-test"})
    -public class BillKkoApiTest implements BillKkoApiSpec {
    +public class BillKkoPayApiTest implements BillKkoPayApiSpec {
     
         @Value("${contract.kakao.pay.bill.dozn.host}")
         private String HOST;
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKko.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKko.java
    deleted file mode 100644
    index a0d7110..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKko.java
    +++ /dev/null
    @@ -1,69 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity;
    -
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillEntity;
    -import cokr.xit.ens.modules.common.domain.support.FieldError;
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.*;
    -import lombok.experimental.SuperBuilder;
    -
    -import javax.persistence.*;
    -
    -@Entity
    -@Getter
    -@ToString
    -@SuperBuilder
    -@NoArgsConstructor
    -@AllArgsConstructor
    -@Table(name = "ens_bill_kko", schema = "", catalog = "")
    -@Schema(name = "BillKko")
    -public class BillKko extends BillEntity {
    -    @Id
    -    @GeneratedValue(strategy = GenerationType.TABLE, generator = "BillKko_Generator")
    -    @TableGenerator(table = "ens_seq_generator", name = "BillKko_Generator"
    -            , pkColumnName = "seq_name", pkColumnValue = "BillKko_id"
    -            , initialValue = 0, allocationSize = 200)
    -    @Schema(required = true, title = "PK", example = " ")
    -    private Long billId;
    -
    -    @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ")
    -    @Column(name = "biller_user_key", nullable = false, length = 40)
    -    private String billerUserKey;
    -
    -    @Schema(required = false, title = "청구 연월", example = " ")
    -    @Column(name = "billed_year_month", nullable = true)
    -    private String billedYearMonth;
    -
    -    @Schema(required = false, title = "동일 고객번호 구분 값", example = " ")
    -    @Column(name = "ordinal", nullable = true)
    -    private String ordinal;
    -
    -    @Schema(required = false, title = "개별 청구서를 식별하는 키 값", example = " ")
    -    @Column(name = "biller_notice_key", nullable = true)
    -    private String billerNoticeKey;
    -
    -    @Schema(required = true, title = "URL 만료일", example = "20200130235959")
    -    @Column(name = "expire_at", nullable = false)
    -    private String expireAt;
    -
    -    @Schema(required = false, title = "API 호출 시 함께 전달할 JSON형태의 문자열", example = " ")
    -    @Column(name = "parameters", nullable = true)
    -    @Lob
    -    private String parameters;
    -
    -    @Schema(required = false, title = "청구서조회/납부가능여부/납부결과 API Url정보 JSON형태의 문자열", example = " \"custom_url\": {\n" +
    -            "      \"notice_url\" : \" https://test-api.dozn.co.kr/kakao/notice\",\n" +
    -            "      \"prepay_url\": \"https://test-api.dozn.co.kr/kakao/prepay\",\n" +
    -            "      \"pay_result_url\": \" https://test-api.dozn.co.kr/kakao/pay-result\"\n" +
    -            "    }")
    -    @Column(name = "custom_url", nullable = true, length = 500)
    -    private String customUrl;
    -
    -    @Schema(required = false, title = "청구서URL", example = " ")
    -    @Column(name = "url", nullable = true)
    -    @Setter
    -    private String url;
    -
    -    @Embedded
    -    @Setter
    -    private FieldError error;
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKkoPay.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKkoPay.java
    new file mode 100644
    index 0000000..75d00ac
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/BillKkoPay.java
    @@ -0,0 +1,117 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity;
    +
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillBaseEntity;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import io.swagger.v3.oas.annotations.media.Schema;
    +import lombok.*;
    +import lombok.experimental.SuperBuilder;
    +
    +import javax.persistence.*;
    +
    +@Entity
    +@Getter
    +@ToString
    +@SuperBuilder
    +@NoArgsConstructor
    +@AllArgsConstructor
    +@Table(name = "ens_bill_kko", schema = "", catalog = "")
    +@Schema(name = "BillKkoPay")
    +public class BillKkoPay extends BillBaseEntity {
    +    @Id
    +    @GeneratedValue(strategy = GenerationType.TABLE, generator = "BillKko_Generator")
    +    @TableGenerator(table = "ens_seq_generator", name = "BillKko_Generator"
    +            , pkColumnName = "seq_name", pkColumnValue = "BillKko_id"
    +            , initialValue = 0, allocationSize = 200)
    +    @Schema(required = true, title = "PK", example = " ")
    +    private Long billId;               
    +
    +    
    +    @Schema(required = false, title = "청구 연월", example = " ")
    +    @Column(name = "billed_year_month", nullable = true)
    +    @Setter
    +    private String billedYearMonth;
    +    @Schema(required = false, title = "동일 고객번호 구분 값", example = " ")
    +    @Column(name = "ordinal", nullable = true)
    +    @Setter
    +    private String ordinal;
    +    @Schema(required = false, title = "개별 청구서를 식별하는 키 값", example = " ")
    +    @Column(name = "biller_notice_key", nullable = true)
    +    @Setter
    +    private String billerNoticeKey;
    +    @Schema(required = false, title = "URL 만료일", example = "20200130235959")
    +    @Column(name = "expire_at", nullable = true)
    +    @Setter
    +    private String expireAt;
    +    @Schema(required = false, title = "API 호출 시 함께 전달할 JSON형태의 문자열", example = " ")
    +    @Column(name = "parameters", nullable = true)
    +    @Lob
    +    @Setter
    +    private String parameters;
    +    @Schema(required = false, title = "청구서조회/납부가능여부/납부결과 API Url정보 JSON형태의 문자열", example = " \"custom_url\": {\n" +
    +            "      \"notice_url\" : \" https://test-api.dozn.co.kr/kakao/notice\",\n" +
    +            "      \"prepay_url\": \"https://test-api.dozn.co.kr/kakao/prepay\",\n" +
    +            "      \"pay_result_url\": \" https://test-api.dozn.co.kr/kakao/pay-result\"\n" +
    +            "    }")
    +    @Column(name = "custom_url", nullable = true, length = 500)
    +    @Setter
    +    private String customUrl;
    +    @Schema(required = false, title = "청구서URL", example = " ")
    +    @Column(name = "url", nullable = true)
    +    @Setter
    +    private String url;
    +    /* =====================================
    +    * 결제진행 - PayNotice 단계
    +    ===================================== */
    +    @Schema(required = false, title = "청구서명", example = "테스트청구서")
    +    @Column(name = "title", nullable = true)
    +    @Setter
    +    private String title;
    +    @Schema(required = false, title = "납부 요청금액", example = "1000")
    +    @Column(name = "amount", nullable = true)
    +    @Setter
    +    private Integer amount;
    +    @Schema(required = false, title = "비과세 금액", example = "0")
    +    @Column(name = "tax_free_amount", nullable = true)
    +    @Setter
    +    private Integer taxFreeAmount;
    +    @Schema(required = false, title = "부가세 금액", example = "0")
    +    @Column(name = "vat_amount", nullable = true)
    +    @Setter
    +    private Integer vatAmount;
    +    @Schema(required = false, title = "납기 안내타입", example = "D1")
    +    @Column(name = "expire_type", nullable = true, length = 10)
    +    @Setter
    +    private String expireType;
    +    @Schema(required = false, title = "첫번째 납기일", example = "20230212")
    +    @Column(name = "pay_expire_date", nullable = true, length = 8)
    +    @Setter
    +    private String payExpireDate;
    +    @Schema(required = false, title = "두번째 납기일", example = "20230212")
    +    @Column(name = "second_pay_expire_date", nullable = true, length = 8)
    +    @Setter
    +    private String secondPayExpireDate;
    +    @Schema(required = false, title = "계좌송금수단 사용 시 계좌정보", example = " ")
    +    @Lob
    +    @Column(name = "bank_accounts", nullable = true)
    +    @Setter
    +    private String bankAccounts;
    +    @Schema(required = false, title = "청구서 상세정보", example = " ")
    +    @Lob
    +    @Column(name = "details", nullable = true)
    +    @Setter
    +    private String details;
    +    @Schema(required = false, title = "결제일시(YYYYMMDDHH24MISS)", example = "20190220161656")
    +    @Column(name = "last_paid_at", nullable = true, length = 14)
    +    @Setter
    +    private String lastPaidAt;
    +    @Schema(required = false, title = "결제번호", example = "2748877")
    +    @Column(name = "last_pay_id", nullable = true)
    +    @Setter
    +    private Integer lastPayId;
    +
    +    @Embedded
    +    @Setter
    +    private FieldError error;
    +
    +
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoPayRepository.java
    similarity index 52%
    rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepository.java
    rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoPayRepository.java
    index a10f45b..6040273 100644
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepository.java
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoPayRepository.java
    @@ -1,12 +1,8 @@
     package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository;
     
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKko;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
     import org.springframework.data.jpa.repository.JpaRepository;
     
    -import java.util.Optional;
    -
    -public interface BillKkoRepository extends JpaRepository, BillKkoRepositoryCustom {
    -
    -    Optional findByBillUid(String billUid);
    +public interface BillKkoPayRepository extends JpaRepository {
     
     }
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryCustom.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryCustom.java
    deleted file mode 100644
    index 8f840c3..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryCustom.java
    +++ /dev/null
    @@ -1,11 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository;
    -
    -import java.util.List;
    -
    -public interface BillKkoRepositoryCustom {
    -
    -    List findBillUidsByBillUidIn(List billUids);
    -
    -    List findBillerUserKeysByBillerUserKeyIn(List billerUserKeys);
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryImpl.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryImpl.java
    deleted file mode 100644
    index 96b8354..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillKkoRepositoryImpl.java
    +++ /dev/null
    @@ -1,42 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository;
    -
    -import com.google.common.collect.Lists;
    -import com.querydsl.jpa.impl.JPAQueryFactory;
    -import lombok.RequiredArgsConstructor;
    -
    -import java.util.ArrayList;
    -import java.util.List;
    -
    -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKko.billKko;
    -
    -@RequiredArgsConstructor
    -public class BillKkoRepositoryImpl implements BillKkoRepositoryCustom {
    -
    -    private final JPAQueryFactory query;
    -
    -    @Override
    -    public List findBillUidsByBillUidIn(List billUids) {
    -        List result = new ArrayList<>();
    -        Lists.partition(billUids, 1000)
    -                .forEach(ids -> result.addAll(
    -                        query.select(billKko.billUid)
    -                                .from(billKko)
    -                                .where(billKko.billUid.in(ids))
    -                                .fetch())
    -                );
    -        return result;
    -    }
    -
    -    @Override
    -    public List findBillerUserKeysByBillerUserKeyIn(List billerUserKeys) {
    -        List result = new ArrayList<>();
    -        Lists.partition(billerUserKeys, 1000)
    -                .forEach(ids -> result.addAll(
    -                        query.select(billKko.billerUserKey)
    -                                .from(billKko)
    -                                .where(billKko.billerUserKey.in(ids))
    -                                .fetch())
    -                );
    -        return result;
    -    }
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillSeKkoRepositoryImpl.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillSeKkoRepositoryImpl.java
    deleted file mode 100644
    index d534dc7..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/entity/repository/BillSeKkoRepositoryImpl.java
    +++ /dev/null
    @@ -1,26 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository;
    -
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillSeRepository;
    -import com.querydsl.jpa.impl.JPAQueryFactory;
    -import lombok.RequiredArgsConstructor;
    -import org.springframework.stereotype.Repository;
    -
    -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKko.billKko;
    -
    -@Repository(value = "bpKko")
    -@RequiredArgsConstructor
    -public class BillSeKkoRepositoryImpl implements BillSeRepository {
    -
    -    private final JPAQueryFactory query;
    -
    -    @Override
    -    public String findUrlByBillUid(String billUid) {
    -        String url = query.select(billKko.url)
    -                .from(billKko)
    -                .where(billKko.billUid.eq(billUid)
    -                        .and(billKko.url.isNotNull())
    -                )
    -                .fetchOne();
    -        return url;
    -    }
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqDTO.java
    deleted file mode 100644
    index 9f86e7f..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqDTO.java
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import com.fasterxml.jackson.annotation.JsonAlias;
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.Builder;
    -import lombok.Getter;
    -import lombok.Setter;
    -
    -import javax.validation.Valid;
    -import javax.validation.constraints.NotBlank;
    -
    -@Builder
    -@Getter
    -@Setter
    -@Schema(name = "BillKkoAcptReqDTO")
    -public class BillKkoAcptReqDTO {
    -
    -    @NotBlank(message = "(계약정보)빌러코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)빌러코드", example = "LIF378880088002")
    -    @JsonAlias({"biller_code"})
    -    private String billerCode;
    -
    -    @NotBlank(message = "(계약정보)허가코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)허가코드", example = "LG7upsMTsXbQiMGP4htZi/IXS7LJvEOmAx2HmY6X6Q8jh1dpv6vgNxbA4a4H2n3r")
    -    @JsonAlias({"authorization"})
    -    private String authorization;
    -
    -    @Valid
    -    @JsonAlias({"documents"})
    -    private BillKkoAcptReqVO documents;
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqVO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqVO.java
    deleted file mode 100644
    index 1937ecc..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoAcptReqVO.java
    +++ /dev/null
    @@ -1,68 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.config.CustomUrl;
    -import com.fasterxml.jackson.annotation.JsonAlias;
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.Builder;
    -import lombok.Getter;
    -import lombok.Setter;
    -import org.hibernate.validator.constraints.Length;
    -
    -import javax.validation.Valid;
    -import javax.validation.constraints.NotEmpty;
    -import java.util.Map;
    -
    -@Builder
    -@Getter
    -@Schema(name = "BillKkoAcptReqVO")
    -public class BillKkoAcptReqVO {
    -
    -    @Length(max = 45, message = "청구서 유니크 아이디의 최대 길이를 초과 했습니다.")
    -    @Schema(required = false, title = "청구서 유니크 아이디", example = " ")
    -    @JsonAlias({"bill_uid"})
    -    @Setter
    -    private String billUid;
    -
    -    @NotEmpty(message = "계약번호는 필수 입력값 입니다.")
    -    @Length(max = 50, message = "계약번호의 최대 길이를 초과 했습니다.")
    -    @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ")
    -    @JsonAlias({"biller_user_key"})
    -    private String billerUserKey;
    -
    -    @Length(max = 6, message = "청구연월의 최대 길이를 초과 했습니다.")
    -    @Schema(required = false, title = "청구 연월", example = "202203")
    -    @JsonAlias({"billed_year_month"})
    -    private String billedYearMonth;
    -
    -    @Length(max = 24, message = "고객번호구분값의 최대 길이를 초과 했습니다.")
    -    @Schema(required = false, title = "동일 고객번호 구분 값", example = " ")
    -    @JsonAlias({"ordinal"})
    -    private String ordinal;
    -
    -    @Length(max = 80, message = "개별청구서식별키의 최대 길이를 초과 했습니다.")
    -    @Schema(required = false, title = "개별 청구서를 식별하는 키 값", example = " ")
    -    @JsonAlias({"biller_notice_key"})
    -    private String billerNoticeKey;
    -
    -    @NotEmpty(message = "URL만료일은 필수 입력값 입니다.")
    -    @Schema(required = true, title = "URL 만료일", example = "20200130235959")
    -    @JsonAlias({"expire_at"})
    -    private String expireAt;
    -
    -
    -//    @Valid
    -//    private Parameters parameters;
    -    @Schema(required = false, title = "API 호출 시 함께 전달할 JSON형태의 문자열", example = "{\"some_param\": \"...\"}")
    -    @JsonAlias({"parameters"})
    -    private Map parameters;
    -
    -
    -//            "      \"notice_url\" : \" https://test-api.dozn.co.kr/kakao/notice\",\n" +
    -//            "      \"prepay_url\": \"https:// test-api.dozn.co.kr/kakao/prepay\",\n" +
    -//            "      \"pay_result_url\": \" https:// test-api.dozn.co.kr/kakao/pay-result\"\n" +
    -//            "    }")
    -    @Valid
    -    @JsonAlias({"custom_url"})
    -    private CustomUrl customUrl;
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultData.java
    similarity index 97%
    rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultDTO.java
    rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultData.java
    index 1a8e304..c2ba333 100644
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultDTO.java
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoPayResultData.java
    @@ -10,8 +10,8 @@ import java.util.Map;
     @Getter
     @ToString
     @EqualsAndHashCode
    -@Schema(name = "BillKkoPayResultDTO")
    -public class BillKkoPayResultDTO {
    +@Schema(name = "BillKkoPayResultData")
    +public class BillKkoPayResultData {
     
         @Schema(required = true, title = "사용자 식별키", example = " ")
         private String biller_user_key;
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailDTO.java
    deleted file mode 100644
    index 1eac94a..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailDTO.java
    +++ /dev/null
    @@ -1,25 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.AllArgsConstructor;
    -import lombok.Builder;
    -import lombok.Data;
    -import lombok.NoArgsConstructor;
    -
    -import java.util.List;
    -
    -@Builder
    -@Data
    -@NoArgsConstructor
    -@AllArgsConstructor
    -@Schema(name = "BillKkoRsltFwdFailDTO")
    -public class BillKkoRsltFwdFailDTO {
    -
    -    @Schema(title = "기관코드", example = " ")
    -    private String org_cd;
    -    @Schema(title = "기관코드명", example = " ")
    -    private String org_nm;
    -    @Schema(title = "빌러유저키", example = " ")
    -    private List biller_user_key;
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailSearchDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailSearchDTO.java
    deleted file mode 100644
    index 3958c58..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoRsltFwdFailSearchDTO.java
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.Builder;
    -import lombok.Data;
    -
    -import java.util.List;
    -
    -@Builder
    -@Data
    -@Schema(name = "BillKkoRsltFwdFailSearchDTO")
    -public class BillKkoRsltFwdFailSearchDTO {
    -
    -    @Schema(title = "기관코드", example = "[]")
    -    private List schOrgCd;
    -    @Schema(title = "기관코드명", example = "[]")
    -    private List schOrgNm;
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqDTO.java
    deleted file mode 100644
    index 750e5a7..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqDTO.java
    +++ /dev/null
    @@ -1,32 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import com.fasterxml.jackson.annotation.JsonAlias;
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.Builder;
    -import lombok.Data;
    -
    -import javax.validation.constraints.NotBlank;
    -import javax.validation.constraints.NotNull;
    -import java.util.List;
    -
    -@Builder
    -@Data
    -@Schema(name = "BillKkoUrlReqDTO")
    -public class BillKkoUrlReqDTO {
    -
    -    @NotBlank(message = "(계약정보)빌러코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)빌러코드", example = "LIF378880088002")
    -    @JsonAlias({"biller_code"})
    -    private String billerCode;
    -
    -    @NotBlank(message = "(계약정보)허가코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)허가코드", example = "LG7upsMTsXbQiMGP4htZi/IXS7LJvEOmAx2HmY6X6Q8jh1dpv6vgNxbA4a4H2n3r")
    -    @JsonAlias({"authorization"})
    -    private String authorization;
    -
    -    @NotNull(message = "청구서 유니크 아이디는 필수 입력값 입니다.")
    -    @Schema(required = false, title = "청구서 유니크 아이디", example = " ")
    -    @JsonAlias({"bill_uids"})
    -    private List billUids;
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqVO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqVO.java
    deleted file mode 100644
    index 379fb49..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/BillKkoUrlReqVO.java
    +++ /dev/null
    @@ -1,33 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model;
    -
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import io.swagger.v3.oas.annotations.media.Schema;
    -import lombok.Builder;
    -import lombok.Data;
    -import org.hibernate.validator.constraints.Length;
    -
    -import javax.validation.constraints.NotBlank;
    -import javax.validation.constraints.NotNull;
    -
    -@Builder
    -@Data
    -@Schema(name = "BillKkoUrlReqVO")
    -public class BillKkoUrlReqVO {
    -
    -    @NotNull(message = "요청구분은 필수 입력값 입니다.")
    -    @Schema(required = true, title = "요청구분", example = "URL")
    -    private BillReqSeCd reqSe;
    -
    -    @NotBlank(message = "(계약정보)빌러코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)빌러코드", example = " ")
    -    private String billerCode;
    -
    -    @NotBlank(message = "(계약정보)허가코드는 필수 입력값 입니다.")
    -    @Schema(required = true, title = "(계약정보)허가코드", example = " ")
    -    private String authorization;
    -
    -    @Length(max = 45, message = "청구서 유니크 아이디의 최대 길이를 초과 했습니다.")
    -    @Schema(required = false, title = "청구서 유니크 아이디", example = " ")
    -    private String billUid;
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoClientController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoClientController.java
    deleted file mode 100644
    index 83b8e0e..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoClientController.java
    +++ /dev/null
    @@ -1,114 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.presentation;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoRsltFwdFailSearchDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.impl.BillKkoClientServiceImpl;
    -import io.swagger.v3.oas.annotations.Operation;
    -import io.swagger.v3.oas.annotations.media.Content;
    -import io.swagger.v3.oas.annotations.media.ExampleObject;
    -import io.swagger.v3.oas.annotations.responses.ApiResponse;
    -import io.swagger.v3.oas.annotations.responses.ApiResponses;
    -import io.swagger.v3.oas.annotations.tags.Tag;
    -import lombok.RequiredArgsConstructor;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.http.HttpStatus;
    -import org.springframework.http.MediaType;
    -import org.springframework.http.ResponseEntity;
    -import org.springframework.web.bind.annotation.*;
    -
    -import java.util.List;
    -import java.util.Map;
    -
    -@Tag(name = "BillKkoClientController")
    -@Slf4j
    -@RequiredArgsConstructor
    -@RestController
    -public class BillKkoClientController {
    -
    -    private final BillKkoClientServiceImpl billKkoClientServiceImpl;
    -
    -
    -    @Operation(summary = "납부결과 전달실패 자료 조회")
    -    @GetMapping(value = "/bill/kko/fwd/fail/{orgCd}", produces = MediaType.APPLICATION_JSON_VALUE)
    -    public ResponseEntity findAllByFwdFail(@PathVariable String orgCd) {
    -
    -        EnsResponseVO responseVO = billKkoClientServiceImpl.findBillerUserKeysByOrgCdAndPayresultFwdFail(orgCd);
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -
    -    @Operation(summary = "납부결과 전달실패 자료 조회(일괄)")
    -    @PostMapping(value = "/bill/kko/fwd/fail/bulk", produces = MediaType.APPLICATION_JSON_VALUE)
    -    public ResponseEntity findAllByFwdFailBulk(@RequestBody BillKkoRsltFwdFailSearchDTO searchDTO) {
    -
    -        EnsResponseVO responseVO = billKkoClientServiceImpl.findBillerUserKeysBySearchDTOAndPayresultFwdFail(searchDTO);
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -
    -
    -    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    -            @Content(mediaType = "application/json", examples = {
    -                    @ExampleObject(name = "Sample Example..."
    -                            , summary = "sample"
    -                            , value = "{ \"org_cd\" : \"EX_ORG001\", \"biller_user_key\" : [\"a1b2c3d4e5f6g7h8i9j0\", \"A1B2C3D4E5F6G7H8I9J0\"] }")
    -            })
    -    })
    -    @ApiResponses({
    -            @ApiResponse(responseCode = "200", content = {
    -                    @Content(mediaType = "application/json", examples = {
    -                            @ExampleObject(name = "Success Example..."
    -                                    , summary = "Success"
    -                                    , value = "{\n" +
    -                                    "\"res_code\": \"OK\",\n" +
    -                                    "\"message\": \"성공\",\n" +
    -                                    "\"data\": null\n" +
    -                                    "}"
    -                            )
    -                    })
    -            })
    -    })
    -    @Operation(summary = "납부 결과 재전달")
    -    @PostMapping(value = "/bill/kko/fwd/pay-reuslt", produces = MediaType.APPLICATION_JSON_VALUE)
    -    public ResponseEntity fwdPayRslt(@RequestBody Map mParam) {
    -
    -        EnsResponseVO responseVO = billKkoClientServiceImpl.fwdPayRslt((String) mParam.get("org_cd"), (List) mParam.get("biller_user_key"));
    -
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -
    -
    -    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    -            @Content(mediaType = "application/json", examples = {
    -                    @ExampleObject(name = "Sample Example..."
    -                            , summary = "sample"
    -                            , value = "{ \"targets\" : [{\"org_cd\" : \"EX_ORG001\", \"biller_user_key\" : [\"a1b2c3d4e5f6g7h8i9j0\", \"A1B2C3D4E5F6G7H8I9J0\"]}, {\"org_cd\" : \"0001\", \"biller_user_key\" : [\"fffffffffffffffffffff\"]} ] }")
    -            })
    -    })
    -    @ApiResponses({
    -            @ApiResponse(responseCode = "200", content = {
    -                    @Content(mediaType = "application/json", examples = {
    -                            @ExampleObject(name = "Success Example..."
    -                                    , summary = "Success"
    -                                    , value = "{\n" +
    -                                    "\"res_code\": \"OK\",\n" +
    -                                    "\"message\": \"성공\",\n" +
    -                                    "\"data\": null\n" +
    -                                    "}"
    -                            )
    -                    })
    -            })
    -    })
    -    @Operation(summary = "납부 결과 재전달(일괄)")
    -    @PostMapping(value = "/bill/kko/fwd/pay-reuslt/bulk", produces = MediaType.APPLICATION_JSON_VALUE)
    -    public ResponseEntity fwdPayRsltBulk(@RequestBody Map mParam) {
    -
    -        List> targets = (List>) mParam.get("targets");
    -
    -        EnsResponseVO responseVO = billKkoClientServiceImpl.fwdPayRsltBulk(targets);
    -
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoController.java
    deleted file mode 100644
    index cce9126..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/BillKkoController.java
    +++ /dev/null
    @@ -1,118 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.presentation;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.core.exception.code.EnsErrCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillUrlReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKko;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoUrlReqDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoUrlReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.BillKkoService;
    -import io.swagger.v3.oas.annotations.Operation;
    -import io.swagger.v3.oas.annotations.tags.Tag;
    -import lombok.RequiredArgsConstructor;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.http.HttpStatus;
    -import org.springframework.http.MediaType;
    -import org.springframework.http.ResponseEntity;
    -import org.springframework.transaction.annotation.Transactional;
    -import org.springframework.web.bind.annotation.PostMapping;
    -import org.springframework.web.bind.annotation.RequestBody;
    -import org.springframework.web.bind.annotation.RestController;
    -
    -import java.util.*;
    -import java.util.stream.Collectors;
    -
    -@Tag(name = "BillKkoController")
    -@Slf4j
    -@RequiredArgsConstructor
    -@RestController
    -public class BillKkoController {
    -
    -    private final BillKkoService billKkoService;
    -
    -    @Operation(summary = "청구서링크 생성")
    -    @PostMapping(value = "/bill/kko/url/bulk", produces = MediaType.APPLICATION_JSON_VALUE)
    -    @Transactional
    -    public ResponseEntity url(@RequestBody BillKkoAcptReqDTO reqDTO) {
    -        BillAcptReqData acptreq = new BillAcptReqData() {
    -            @Override
    -            public BillKkoAcptReqVO get() {
    -                return reqDTO.getDocuments();
    -            }
    -        };
    -        EnsResponseVO responseVO = billKkoService.accept(Arrays.asList(acptreq));
    -        if (!EnsErrCd.OK.equals(responseVO.getErrCode()))
    -            return new ResponseEntity(responseVO, HttpStatus.OK);
    -        List> result = (List>) responseVO.getResultInfo();
    -
    -        List> resultInfo = result.stream()
    -                .map(m -> {
    -                    Set billerUserKeys = m.keySet();
    -                    return billerUserKeys.stream()
    -                            .map(billerUserKey -> {
    -                                Map mOutput = new HashMap<>();
    -                                this.callUrlCreate(BillReqSeCd.URL, reqDTO.getBillerCode(), reqDTO.getAuthorization(), m.get(billerUserKey), mOutput);
    -                                mOutput.put("biller_user_key", billerUserKey);
    -                                mOutput.put("bill_uid", m.get(billerUserKey));
    -                                return mOutput;
    -                            })
    -                            .collect(Collectors.toList());
    -                }).collect(Collectors.toList())
    -                .get(0);
    -        responseVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build();
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -
    -    @Operation(summary = "청구서링크 재생성")
    -    @PostMapping(value = "/bill/kko/re/url/bulk", produces = MediaType.APPLICATION_JSON_VALUE)
    -    public ResponseEntity reUrl(@RequestBody BillKkoUrlReqDTO reqDTO) {
    -
    -        List> resultInfo = reqDTO.getBillUids().stream()
    -                .map(billUid -> {
    -                    Map mOutput = new HashMap<>();
    -                    this.callUrlCreate(BillReqSeCd.REURL, reqDTO.getBillerCode(), reqDTO.getAuthorization(), billUid, mOutput);
    -                    mOutput.put("bill_uid", billUid);
    -                    return mOutput;
    -                })
    -                .collect(Collectors.toList());
    -
    -
    -        EnsResponseVO responseVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build();
    -
    -
    -        return new ResponseEntity(responseVO, HttpStatus.OK);
    -    }
    -
    -    private void callUrlCreate(BillReqSeCd billReqSeCd, String billerCode, String authorization, String billUid, Map mOutput) {
    -
    -        BillUrlReqData urlreq = new BillUrlReqData() {
    -            @Override
    -            public BillKkoUrlReqVO get() {
    -                return BillKkoUrlReqVO.builder()
    -                        .reqSe(billReqSeCd)
    -                        .billerCode(billerCode)
    -                        .authorization(authorization)
    -                        .billUid(billUid)
    -                        .build();
    -            }
    -        };
    -
    -        try {
    -            EnsResponseVO response = billKkoService.createUrl(urlreq);
    -            mOutput.put("errCode", response.getErrCode().getCode());
    -            mOutput.put("errMsg", response.getErrMsg());
    -            if (EnsErrCd.OK.equals(response.getErrCode()))
    -                mOutput.put("url", ((BillKko) response.getResultInfo()).getUrl());
    -
    -        } catch (Exception e) {
    -            mOutput.put("errCode", EnsErrCd.ERR999);
    -            mOutput.put("errMsg", "청구서링크 생성 실패. " + e.getMessage());
    -        }
    -    }
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayProcessController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayProcessController.java
    new file mode 100644
    index 0000000..68b8bf2
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayProcessController.java
    @@ -0,0 +1,92 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.presentation;
    +
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.KkoPayProcessService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.PayController;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import io.swagger.v3.oas.annotations.Operation;
    +import io.swagger.v3.oas.annotations.media.Content;
    +import io.swagger.v3.oas.annotations.media.ExampleObject;
    +import io.swagger.v3.oas.annotations.tags.Tag;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.MediaType;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.web.bind.annotation.PostMapping;
    +import org.springframework.web.bind.annotation.RequestBody;
    +import org.springframework.web.bind.annotation.RestController;
    +
    +import java.util.Map;
    +
    +@Tag(name = "KkoPayProcessController")
    +@Slf4j
    +@RequiredArgsConstructor
    +@RestController
    +public class KkoPayProcessController implements PayController, Map> {
    +
    +    private final KkoPayProcessService kkoPayProcessService;
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "청구서링크 생성"
    +                            , value = "{\"billUid\":\"청구서UID\"}")
    +            })
    +    })
    +    @Operation(summary = "청구서링크 생성")
    +    @PostMapping(value = "/bill/kko/pay/gnrurl", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity gnrUrl(@RequestBody Map param) {
    +        return new ResponseEntity(kkoPayProcessService.gnrUrl(param), HttpStatus.OK);
    +    }
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "결제정보 요청"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"biller_notice_key\":\"청구서UID\",\"user_birth\":\"19861128\",\"parameters\":{\"파라미터1\":\"8자이내값\"}}}")
    +            })
    +    })
    +    @Operation(summary = "납부(결제)정보 요청")
    +    @PostMapping(value = "/bill/kko/pay/notice", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity payNotice(@RequestBody Map param) {
    +        return new ResponseEntity(kkoPayProcessService.payNotice(param), HttpStatus.OK);
    +    }
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "납부(결제)가능여부 확인"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"biller_notice_key\":\"청구서UID\",\"amount\":29000,\"parameters\":{\"파라미터1\":\"8자이내값\"}}}")
    +            })
    +    })
    +    @Operation(summary = "납부(결제)가능여부 확인")
    +    @PostMapping(value = "/bill/kko/pay/able", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity payAble(@RequestBody Map param) {
    +        return new ResponseEntity(kkoPayProcessService.payAble(param), HttpStatus.OK);
    +    }
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "결과전달"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"biller_notice_key\":\"청구서UID\",\"parameters\":{\"파라미터1\":\"8자이내값\"},\"pay_by\":\"MONEY\",\"pay_type\":\"P\",\"pay_detail1\":\"\",\"pay_detail2\":\"\",\"amount\":20000,\"pay_amount\":20000,\"pay_fee_type\":\"BEFORE\",\"pay_fee\":150,\"pay_fee_tax\":15,\"paid_at\":\"20190220161656\",\"pay_id\":2748877}}")
    +            })
    +    })
    +    @Operation(summary = "납부(결제)결과 전달")
    +    @PostMapping(value = "/bill/kko/pay/result", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity payResult(@RequestBody Map param) {
    +        return new ResponseEntity(kkoPayProcessService.payResult(param), HttpStatus.OK);
    +    }
    +
    +
    +    @Operation(summary = "결제취소")
    +    @PostMapping(value = "/bill/kko/pay/cancel", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity payCancel(Map param) {
    +        return new ResponseEntity(kkoPayProcessService.payCancel(param), HttpStatus.OK);
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayUseSysSampleController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayUseSysSampleController.java
    new file mode 100644
    index 0000000..3fdb081
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/presentation/KkoPayUseSysSampleController.java
    @@ -0,0 +1,195 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.presentation;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayNoticeRespData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayUrlRespData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.PayUseSysController;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import com.google.gson.Gson;
    +import io.swagger.v3.oas.annotations.Operation;
    +import io.swagger.v3.oas.annotations.media.Content;
    +import io.swagger.v3.oas.annotations.media.ExampleObject;
    +import io.swagger.v3.oas.annotations.tags.Tag;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.MediaType;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.web.bind.annotation.PostMapping;
    +import org.springframework.web.bind.annotation.RequestBody;
    +import org.springframework.web.bind.annotation.RestController;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +@Tag(name = "KkoPayUseSysSampleController")
    +@Slf4j
    +@RequiredArgsConstructor
    +@RestController
    +public class KkoPayUseSysSampleController implements PayUseSysController> {
    +
    +    private Gson gson = new Gson();
    +
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "청구서링크생성 정보"
    +                            , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}")
    +            })
    +    })
    +    @Operation(summary = "청구서링크생성 정보 샘플")
    +    @PostMapping(value = "/bill/kko/sample/gnrUrl", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity gnrUrl(@RequestBody Map param) {
    +        log.info("[Request Data] {}", param.toString());
    +
    +
    +        /* ============================================
    +        * [정상 응답코드]
    +        *   OK 
    +        * [실패 응답코드]
    +        *   GRNURL_FIND_FAILED   
    +        ============================================ */
    +        PayUseSysResCd resCd = PayUseSysResCd.OK;
    +
    +        
    +        String expireAt = "20231231235959";
    +        KkoPayUrlRespData data = KkoPayUrlRespData.builder()
    +                .billedYearMonth(null)
    +                .ordinal(null)
    +                .expireAt(expireAt)
    +                .parameters(null)
    +                .build();
    +        Map result = new HashMap<>();
    +        result.put("res_code", resCd.getCode());
    +        result.put("message", resCd.getCodeNm());
    +        result.put("data", data);
    +
    +        return new ResponseEntity>(result, HttpStatus.OK);
    +    }
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "납부(결제)정보"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"user_birth\":\"\",\"parameters\":{\"some_param\":\"\"}}}"),
    +            })
    +    })
    +    @Operation(summary = "납부(결제)정보 샘플")
    +    @PostMapping(value = "/bill/kko/sample/paynotice", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity> payNotice(@RequestBody Map param) {
    +        log.info("[Request Data] {}", param.toString());
    +
    +
    +
    +        /* ============================================
    +        * [정상 응답코드]
    +        *   OK 
    +        * [실패 응답코드]
    +        *   NOT_FOUND_PAYDATA   
    +        *   PAYDATA_FIND_FAILED   
    +        ============================================ */
    +        PayUseSysResCd resCd = PayUseSysResCd.OK;
    +
    +        
    +        String payExpireDate = "20231231"; 
    +        KkoPayNoticeRespData data = KkoPayNoticeRespData.builder()
    +                .title("테스트 청구서")
    +                .amount(1000)
    +                .taxFreeAmount(null)
    +                .vatAmount(null)
    +                .expireType("D1")
    +                .payExpireDate(payExpireDate)
    +                .secondPayExpireDate(null)
    +                .bankAccounts(null)
    +                .details(null)
    +                .build();
    +        Map result = new HashMap<>();
    +        result.put("res_code", resCd.getCode());
    +        result.put("message", resCd.getCodeNm());
    +        result.put("data", data);
    +
    +        return new ResponseEntity>(result, HttpStatus.OK);
    +    }
    +
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "납부(결제)가능여부"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"amount\":29000,\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"}}}")
    +            })
    +    })
    +    @Operation(summary = "납부(결제)가능여부 샘플")
    +    @PostMapping(value = "/bill/kko/sample/payable", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity> payAble(@RequestBody Map param) {
    +        log.info("[Request Data] {}", param.toString());
    +
    +
    +        /* ============================================
    +        * [정상 응답코드]
    +        *   OK 
    +        * [실패 응답코드]
    +        *   NO_AMOUNT_PAYABLE   
    +        *   OVERPAYABLE_AMOUNT  
    +        *   NO_TARGET_PAYABLE   
    +        *   EXPIRED_DATE        
    +        *   FAILED_CHECK_INFO   
    +        ============================================ */
    +        PayUseSysResCd resCd = PayUseSysResCd.OK;
    +
    +        
    +        Map result = new HashMap<>();
    +        result.put("res_code", resCd.getCode());
    +        result.put("message", resCd.getCodeNm());
    +        result.put("data", null);
    +
    +
    +        return new ResponseEntity>(result, HttpStatus.OK);
    +    }
    +
    +
    +    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +            @Content(mediaType = "application/json", examples = {
    +                    @ExampleObject(name = "Sample Example..."
    +                            , summary = "납부(결제)결과"
    +                            , value = "{\"data\":{\"biller_user_key\":\"빌러유저키\",\"parameters\":{\"pay_rqt_seq\":\"KT00000001\"},\"pay_by\":\"MONEY\",\"pay_type\":\"P\",\"pay_detail1\":\"\",\"pay_detail2\":\"\",\"amount\":20000,\"pay_amount\":20000,\"pay_fee_type\":\"BEFORE\",\"pay_fee\":150,\"pay_fee_tax\":15,\"paid_at\":\"20190220161656\",\"pay_id\":2748877}}")
    +            })
    +    })
    +    @Operation(summary = "납부(결제)결과 샘플")
    +    @PostMapping(value = "/bill/kko/sample/payresult", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity> payResult(@RequestBody Map param) {
    +        log.info("[Request Data] {}", param.toString());
    +
    +        PayUseSysResCd resCd = PayUseSysResCd.OK;
    +
    +        
    +        Map result = new HashMap<>();
    +        result.put("res_code", resCd.getCode());
    +        result.put("message", resCd.getCodeNm());
    +        result.put("data", null);
    +
    +        return new ResponseEntity>(result, HttpStatus.OK);
    +    }
    +
    +
    +    //    @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = {
    +//            @Content(mediaType = "application/json", examples = {
    +//                    @ExampleObject(name = "Sample Example..."
    +//                            , summary = "결제취소정보"
    +//                            , value = "{}")
    +//            })
    +//    })
    +    @Operation(summary = "결제취소정보 샘플")
    +    @PostMapping(value = "/bill/kko/sample/cancelresult", produces = MediaType.APPLICATION_JSON_VALUE)
    +    @Override
    +    public ResponseEntity> payCancel(Map param) {
    +        throw new EnsException(EnsErrCd.SERVICE_NOT_SUPPORTED, EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm());
    +    }
    +
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSpec.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSpec.java
    deleted file mode 100644
    index 768c6b4..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSpec.java
    +++ /dev/null
    @@ -1,35 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    -
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO;
    -
    -import java.util.Map;
    -
    -public interface BillKkoClientApiSpec {
    -
    -
    -    /**
    -     * 청구서 조회
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    BillKkoApiRespDTO findNoticeInfo(Map mParam);
    -
    -    /**
    -     * 납부 가능 조회
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    BillKkoApiRespDTO findPrepayInfo(Map mParam);
    -
    -    /**
    -     * 납부결과 저장
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    BillKkoApiRespDTO addPayReultIfno(Map mParam);
    -
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSupport.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSupport.java
    deleted file mode 100644
    index 6f2942b..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoClientApiSupport.java
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    -
    -import cokr.xit.ens.core.exception.EnsException;
    -import cokr.xit.ens.core.exception.code.EnsErrCd;
    -import cokr.xit.ens.core.utils.CmmnUtil;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillHistRepository;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoRsltFwdFailDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoRsltFwdFailSearchDTO;
    -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    -import cokr.xit.ens.modules.common.domain.support.FieldError;
    -import com.fasterxml.jackson.databind.ObjectMapper;
    -import com.querydsl.core.BooleanBuilder;
    -import com.querydsl.core.Tuple;
    -import com.querydsl.core.types.dsl.CaseBuilder;
    -import com.querydsl.jpa.impl.JPAQueryFactory;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.beans.factory.annotation.Autowired;
    -import org.springframework.stereotype.Component;
    -
    -import java.util.*;
    -import java.util.stream.Collectors;
    -
    -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.QBillHist.billHist;
    -import static cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng.orgMng;
    -
    -@Slf4j
    -@Component
    -public abstract class BillKkoClientApiSupport implements BillKkoClientApiSpec {
    -
    -    @Autowired
    -    private JPAQueryFactory query;
    -    @Autowired
    -    private BillHistRepository billHistRepository;
    -
    -
    -    /**
    -     * 청구서 이력 저장 - 요청
    -     *
    -     * @param reqSeCd
    -     * @param billerUserKey
    -     * @param orgCd
    -     * @param mParam
    -     * @return
    -     */
    -    protected BillHist addBillHistByReqInfo(BillReqSeCd reqSeCd, String billerUserKey, String orgCd, String billUid, Map mParam) {
    -        BillHist billHist = BillHist.builder()
    -                .billSe(BillSeCd.bpKko)
    -                .billUid(billUid)
    -                .reqSe(reqSeCd)
    -                .orgMng(orgCd == null ? null : OrgMng.builder().orgCd(orgCd).build())
    -                .linkedUuid(billerUserKey)
    -                .requestData(CmmnUtil.toJsonString(mParam))
    -                .build();
    -        billHistRepository.save(billHist);
    -        return billHist;
    -    }
    -
    -    /**
    -     * 청구서 이력 저장 - 응답
    -     *
    -     * @param billHist
    -     * @param respVO
    -     * @param errCd
    -     * @param errMsg
    -     */
    -    protected void modifyBillHistByRespInfo(BillHist billHist, BillKkoApiRespDTO respVO, EnsErrCd errCd, String errMsg) {
    -        billHist.setResponseData(CmmnUtil.toJsonString(respVO));
    -        billHist.setError(FieldError.initBuilder()
    -                .errorCode(CmmnUtil.isEmpty(errCd) ? null : errCd.getCode())
    -                .errorMessage(errMsg)
    -                .build());
    -        billHistRepository.save(billHist);
    -    }
    -
    -
    -    protected Optional findByOrgMngAndBillerUserKeyAndReqSeAndLast(OrgMng orgMng, String billerUserKey, BillReqSeCd reqSeCd) {
    -        return Optional.ofNullable(query.selectFrom(billHist)
    -                .where(
    -                        billHist.orgMng.eq(orgMng)
    -                                .and(billHist.linkedUuid.eq(billerUserKey))
    -                                .and(billHist.billSe.eq(BillSeCd.bpKko))
    -                                .and(billHist.reqSe.eq(reqSeCd))
    -                )
    -                .orderBy(billHist.id.desc())
    -                .fetchFirst());
    -    }
    -
    -    protected BillKkoRsltFwdFailDTO findBillerUserKeysByPayresultFwdFailAndOrgCd(String orgCd) {
    -        BillKkoRsltFwdFailSearchDTO searchDTO = BillKkoRsltFwdFailSearchDTO.builder().schOrgCd(Collections.singletonList(orgCd)).build();
    -        List result = this.findBillerUserKeysByPayresultFwdFail(searchDTO);
    -
    -        if (result.size() > 0)
    -            return result.get(0);
    -        else {
    -            OrgMng e = Optional.ofNullable(query.select(orgMng)
    -                            .from(orgMng)
    -                            .where(orgMng.orgCd.eq(orgCd))
    -                            .fetchOne())
    -                    .orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("등록되지 않은 기관(%s) 입니다.", orgCd)));
    -            return BillKkoRsltFwdFailDTO.builder().org_cd(e.getOrgCd()).org_nm(e.getOrgNm()).build();
    -        }
    -    }
    -
    -    protected List findBillerUserKeysByPayresultFwdFail(BillKkoRsltFwdFailSearchDTO searchDTO) {
    -        BooleanBuilder builder = new BooleanBuilder();
    -        builder.and(billHist.billSe.eq(BillSeCd.bpKko));
    -        builder.and(billHist.reqSe.eq(BillReqSeCd.PAYRSLT));
    -        if (!CmmnUtil.isEmpty(searchDTO.getSchOrgCd()))
    -            builder.and(billHist.orgMng.orgCd.in(searchDTO.getSchOrgCd()));
    -        if (!CmmnUtil.isEmpty(searchDTO.getSchOrgNm()))
    -            builder.and(billHist.orgMng.orgNm.in(searchDTO.getSchOrgNm()));
    -
    -
    -        List list = query.select(billHist.linkedUuid
    -                        , billHist.linkedUuid.count().longValue().as("totCnt")         
    -                        , new CaseBuilder().when(billHist.error.errorCode.isNotNull()
    -                                        .and((billHist.error.errorMessage.contains("REQUEST_TIMEOUT I/O error on")
    -                                                .or(billHist.error.errorMessage.contains("404 NOT_FOUND"))
    -                                        ))
    -                                )
    -                                .then(1)
    -                                .otherwise(0)
    -                                .sum().longValue().as("failCnt")   
    -                        , billHist.orgMng.orgCd
    -                        , billHist.orgMng.orgNm
    -                )
    -                .from(billHist)
    -                .innerJoin(billHist.orgMng, orgMng)
    -                .where(builder)
    -                .groupBy(billHist.orgMng, billHist.linkedUuid, orgMng.orgNm)
    -                .fetch();
    -
    -
    -        Map m = new HashMap<>();
    -        list.stream()
    -                .filter(tuple -> tuple.get(1, Long.class) == tuple.get(2, Long.class)) 
    -                .forEach(tuple -> {
    -                    BillKkoRsltFwdFailDTO dto = m.getOrDefault(tuple.get(billHist.orgMng.orgCd), BillKkoRsltFwdFailDTO.builder()
    -                            .org_cd(tuple.get(billHist.orgMng.orgCd))
    -                            .org_nm(tuple.get(billHist.orgMng.orgNm))
    -                            .biller_user_key(new ArrayList<>())
    -                            .build());
    -                    dto.getBiller_user_key().add(tuple.get(billHist.linkedUuid));
    -                    m.put(tuple.get(billHist.orgMng.orgCd), dto);
    -                });
    -
    -        ObjectMapper mapper = new ObjectMapper();
    -        return m.keySet().stream()
    -                .map(key -> mapper.convertValue(m.get(key), BillKkoRsltFwdFailDTO.class))
    -                .collect(Collectors.toList());
    -
    -    }
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoService.java
    deleted file mode 100644
    index 4300b09..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/BillKkoService.java
    +++ /dev/null
    @@ -1,13 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillService;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillUrlReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoUrlReqVO;
    -
    -import java.util.List;
    -
    -public interface BillKkoService extends BillService>, BillUrlReqData> {
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayProcessService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayProcessService.java
    new file mode 100644
    index 0000000..bc6d3d4
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayProcessService.java
    @@ -0,0 +1,102 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.KkoPayAbleService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.KkoPayNoticeService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.KkoPayResultService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.KkoPayUrlService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayNoticeRespData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayProcessService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayAbleData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayNoticeData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayResultData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayUrlData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template.PayHelper;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.log4j.Log4j2;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.Map;
    +
    +@Log4j2
    +@RequiredArgsConstructor
    +@Service
    +public class KkoPayProcessService implements PayProcessService> {
    +    private final KkoPayUrlService kkoPayUrlService;
    +    private final KkoPayNoticeService kkoPayNoticeService;
    +    private final KkoPayAbleService kkoPayAbleService;
    +    private final KkoPayResultService kkoPayResultService;
    +
    +
    +    @Override
    +    public PayApiRespDTO gnrUrl(Map data) {
    +
    +        String billUid = (String) data.get("billUid");
    +
    +        
    +        Pay>> pay = PayHelper., String, PayApiRespDTO>>builder()
    +                .param(billUid)
    +                .payHelperService(kkoPayUrlService)
    +                .build();
    +
    +        
    +        pay.exec();
    +
    +
    +        return pay.getResult();
    +    }
    +
    +    @Override
    +    public PayApiRespDTO payNotice(Map data) {
    +        
    +        Pay> pay = PayHelper., Map, PayApiRespDTO>builder()
    +                .param(data)
    +                .payHelperService(kkoPayNoticeService)
    +                .build();
    +
    +        
    +        pay.exec();
    +
    +
    +        return pay.getResult();
    +    }
    +
    +    @Override
    +    public PayApiRespDTO payAble(Map data) {
    +
    +        
    +        Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder()
    +                .param(data)
    +                .payHelperService(kkoPayAbleService)
    +                .build();
    +
    +        
    +        pay.exec();
    +
    +        return pay.getResult();
    +    }
    +
    +    @Override
    +    public PayApiRespDTO payResult(Map data) {
    +
    +        
    +        Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder()
    +                .param(data)
    +                .payHelperService(kkoPayResultService)
    +                .build();
    +
    +        
    +        pay.exec();
    +
    +        return pay.getResult();
    +    }
    +
    +    @Override
    +    public PayApiRespDTO payCancel(Map data) {
    +        throw new EnsException(EnsErrCd.SERVICE_NOT_SUPPORTED, EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm());
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayRepairService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayRepairService.java
    new file mode 100644
    index 0000000..74364ce
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPayRepairService.java
    @@ -0,0 +1,143 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    +
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.repair.kit.RepairKkoPayResultTransferFail;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.RepairPayResultService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.stereotype.Service;
    +import org.springframework.transaction.annotation.Transactional;
    +
    +import java.util.ArrayList;
    +import java.util.HashMap;
    +import java.util.List;
    +import java.util.Map;
    +
    +@Slf4j
    +@Service
    +@RequiredArgsConstructor
    +public class KkoPayRepairService implements RepairPayResultService {
    +
    +    private final JPAQueryFactory query;
    +    private final PayUseSysApi payUseSysApi;
    +    private final BillHistRepository billHistRepository;
    +
    +
    +    @Override
    +    @Transactional(readOnly = true)
    +    public Map> findTransferFailedPayResultDataList(RepairPayRsltFwdFailSearchDTO searchDTO) {
    +        Map> mResultByOrg = new HashMap<>();
    +        RepairKkoPayResultTransferFail.builder()
    +                .query(query)
    +                .searchDTO(searchDTO)
    +                .build()
    +                .findDatas()
    +                .forEach(failData -> {
    +                    /**
    +                     * 응답데이터 구조
    +                     * {
    +                     *   "기관코드" {
    +                     *     "orgCd": "aaaa",
    +                     *     "orgNm": "sdafsf",
    +                     *     "billSe": {
    +                     *       "nvBp": [
    +                     *         { "billerUserKey": "aaaaaaaaaaaaa" },
    +                     *         { "billerUserKey": "bbbbbbbbbbbbb" }
    +                     *       ],
    +                     *       "kkoBp": [
    +                     *         { "billerUserKey": "fffffffffffff" }
    +                     *       ]
    +                     *     }
    +                     *   }
    +                     * }
    +                     */
    +                    Map mOrg = mResultByOrg.get(failData.getOrgCd());
    +                    if (mOrg == null) {
    +                        mOrg = new HashMap<>();
    +                        mOrg.put("orgCd", failData.getOrgCd());
    +                        mOrg.put("orgNm", failData.getOrgNm());
    +                        Map data = new HashMap<>();
    +                        data.put("billerUserKey", failData.getBillerUserKey());
    +                        List> datas = new ArrayList<>();
    +                        datas.add(data);
    +                        Map billSe = new HashMap<>();
    +                        billSe.put(failData.getBillSe().getCode(), datas);
    +                        mOrg.put("billSe", billSe);
    +                        mResultByOrg.put(failData.getOrgCd(), mOrg);
    +                    } else {
    +                        Map billSe = (Map) mOrg.get("billSe");
    +                        List> datas = (List>) billSe.getOrDefault(failData.getBillSe().getCode(), new ArrayList<>());
    +                        Map data = new HashMap<>();
    +                        data.put("billerUserKey", failData.getBillerUserKey());
    +                        datas.add(data);
    +                        billSe.put(failData.getBillSe().getCode(), datas);
    +                    }
    +                });
    +        return mResultByOrg;
    +    }
    +
    +    @Override
    +    public Map> sendTransferFailedPayResultDataList(RepairPayRsltFwdFailSearchDTO searchDTO) {
    +        Map> mResultByOrg = new HashMap<>();
    +        RepairKkoPayResultTransferFail.builder()
    +                .query(query)
    +                .searchDTO(searchDTO)
    +                .build()
    +                .transferData(payUseSysApi, billHistRepository)
    +                .forEach(billHist -> {
    +                    /**
    +                     * 응답데이터 구조
    +                     * {
    +                     *   "기관코드" {
    +                     *     "orgCd": "aaaa",
    +                     *     "orgNm": "sdafsf",
    +                     *     "billSe": {
    +                     *       "nvBp": [
    +                     *         { "billerUserKey": "aaaaaaaaaaaaa", "code": "OK", "message": "성공" },
    +                     *         { "billerUserKey": "bbbbbbbbbbbbb", "code": "OK", "message": "성공" }
    +                     *       ],
    +                     *       "kkoBp": [
    +                     *         { "billerUserKey": "fffffffffffff", "code": "FAILED_SAVE_PAYRSLT", "message": "납부(결제)결과 저장 실패" }
    +                     *       ]
    +                     *     }
    +                     *   }
    +                     * }
    +                     */
    +                    Map mOrg = mResultByOrg.get(billHist.getOrgMng().getOrgCd());
    +                    FieldError error = billHist.getError() == null ? FieldError.initBuilder().errorCode(EnsErrCd.OK.getCode()).errorMessage(EnsErrCd.OK.getCodeNm()).build() : billHist.getError();
    +                    if (mOrg == null) {
    +
    +                        mOrg = new HashMap<>();
    +                        mOrg.put("orgCd", billHist.getOrgMng().getOrgCd());
    +                        mOrg.put("orgNm", billHist.getOrgMng().getOrgNm());
    +                        Map data = new HashMap<>();
    +                        data.put("billerUserKey", billHist.getLinkedUuid());
    +                        data.put("code", error.getErrorCode());
    +                        data.put("message", error.getErrorMessage());
    +                        List> datas = new ArrayList<>();
    +                        datas.add(data);
    +                        Map billSe = new HashMap<>();
    +                        billSe.put(billHist.getBillSe().getCode(), datas);
    +                        mOrg.put("billSe", billSe);
    +                        mResultByOrg.put(billHist.getOrgMng().getOrgCd(), mOrg);
    +                    } else {
    +                        Map billSe = (Map) mOrg.get("billSe");
    +                        List> datas = (List>) billSe.getOrDefault(billHist.getBillSe().getCode(), new ArrayList<>());
    +                        Map data = new HashMap<>();
    +                        data.put("billerUserKey", billHist.getLinkedUuid());
    +                        data.put("code", error.getErrorCode());
    +                        data.put("message", error.getErrorMessage());
    +                        datas.add(data);
    +                        billSe.put(billHist.getBillSe().getCode(), datas);
    +                    }
    +                });
    +
    +
    +        return mResultByOrg;
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPaymentTriggerService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPaymentTriggerService.java
    new file mode 100644
    index 0000000..845c533
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/KkoPaymentTriggerService.java
    @@ -0,0 +1,66 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoPayRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger.PaymentTriggerServiceTemplate;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +
    +
    +@Slf4j
    +@RequiredArgsConstructor
    +@Service(value = "kkoPaymentTriggerService")
    +public class KkoPaymentTriggerService extends PaymentTriggerServiceTemplate {
    +    private final KkoPayProcessService kkoPayProcessService;
    +    private final JPAQueryFactory query;
    +    private final BillKkoPayRepository billKkoPayRepository;
    +
    +    @Override
    +    protected boolean existsBill(String billUid) {
    +        return query.selectFrom(QBillKkoPay.billKkoPay)
    +                .where(QBillKkoPay.billKkoPay.billUid.eq(billUid))
    +                .fetchCount() > 0;
    +    }
    +
    +    @Override
    +    protected void generateBill(Bill bill) {
    +        billKkoPayRepository.save(BillKkoPay.builder()
    +                .billUid(bill.getBillUid())
    +                .billerUserKey(bill.getBillerUserKey())
    +                .build());
    +    }
    +
    +    @Override
    +    protected Map getPayInfo(Map param) {
    +        final Bill bill = (Bill) param.getOrDefault(PTriggerDataKeys.bill, new Bill());
    +        final String billUid = (String) param.getOrDefault(PTriggerDataKeys.billUid, "");
    +
    +        
    +        Map p = new HashMap<>();
    +        p.put("billUid", billUid);
    +        PayApiRespDTO payApiRespDTO = kkoPayProcessService.gnrUrl(p);
    +        if (PayUseSysResCd.OK.getCode().equals(payApiRespDTO.getResCode())) {
    +            Map data = (Map) payApiRespDTO.getData();
    +            Map resultInfo = new HashMap<>();
    +            resultInfo.put("url", data.get("url"));
    +
    +            return resultInfo;
    +        } else {
    +            throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, String.format("%s\n[실패사유]\n -.코드: %s\n -.메시지: %s", EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), payApiRespDTO.getResCode(), payApiRespDTO.getMessage()));
    +        }
    +
    +
    +    }
    +
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoClientServiceImpl.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoClientServiceImpl.java
    deleted file mode 100644
    index 29efed6..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoClientServiceImpl.java
    +++ /dev/null
    @@ -1,175 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.impl;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.core.exception.EnsException;
    -import cokr.xit.ens.core.exception.code.EnsErrCd;
    -import cokr.xit.ens.core.utils.CmmnUtil;
    -import cokr.xit.ens.core.utils.MapDeserailizer;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoClientApiSpec;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.code.BillKkoErrCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoRsltFwdFailDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoRsltFwdFailSearchDTO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.BillKkoClientApiSupport;
    -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    -import com.google.gson.Gson;
    -import com.google.gson.GsonBuilder;
    -import lombok.RequiredArgsConstructor;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.stereotype.Service;
    -import org.springframework.transaction.annotation.Propagation;
    -import org.springframework.transaction.annotation.Transactional;
    -
    -import java.util.HashMap;
    -import java.util.LinkedHashMap;
    -import java.util.List;
    -import java.util.Map;
    -import java.util.stream.Collectors;
    -
    -@Slf4j
    -@Service
    -@RequiredArgsConstructor
    -public class BillKkoClientServiceImpl extends BillKkoClientApiSupport {
    -
    -    private final BillKkoClientApiSpec billKkoClientApi;
    -
    -    private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create();
    -
    -
    -    /**
    -     * 청구서 조회
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    @Override
    -    @Transactional(propagation = Propagation.NEVER)
    -    public BillKkoApiRespDTO findNoticeInfo(Map mParam) {
    -        return null;
    -    }
    -
    -    /**
    -     * 납부가능 조회
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    @Override
    -    @Transactional(propagation = Propagation.NEVER)
    -    public BillKkoApiRespDTO findPrepayInfo(Map mParam) {
    -        return null;
    -    }
    -
    -    /**
    -     * 납부결과 전달
    -     *
    -     * @param mParam
    -     * @return
    -     */
    -    @Override
    -    @Transactional(propagation = Propagation.NEVER)
    -    public BillKkoApiRespDTO addPayReultIfno(Map mParam) {
    -        return null;
    -    }
    -
    -
    -    @Transactional(readOnly = true)
    -    public EnsResponseVO findBillerUserKeysByOrgCdAndPayresultFwdFail(String orgCd) {
    -        if (CmmnUtil.isEmpty(orgCd))
    -            throw new EnsException(EnsErrCd.BILL403, "기관코드는 필수조건 입니다.");
    -
    -        return EnsResponseVO.okBuilder()
    -                .resultInfo(super.findBillerUserKeysByPayresultFwdFailAndOrgCd(orgCd))
    -                .build();
    -    }
    -
    -    @Transactional(readOnly = true)
    -    public EnsResponseVO> findBillerUserKeysBySearchDTOAndPayresultFwdFail(BillKkoRsltFwdFailSearchDTO searchDTO) {
    -
    -        return EnsResponseVO.>okBuilder().resultInfo(super.findBillerUserKeysByPayresultFwdFail(searchDTO)).build();
    -    }
    -
    -
    -    @Transactional(propagation = Propagation.NEVER)
    -    public EnsResponseVO>> fwdPayRslt(String orgCd, List billerUserKeys) {
    -
    -        Map result = billerUserKeys.stream()
    -                .map(billerUserKey -> {
    -                    Map m = new HashMap<>();
    -                    m.put("key", billerUserKey);
    -                    m.put("value", this.fwdPayRsltProc(orgCd, billerUserKey));
    -                    return m;
    -                })
    -                .collect(Collectors.toMap(m -> (String) m.get("key"), m -> (BillKkoApiRespDTO) m.get("value"), (k1, k2) -> k1));
    -
    -
    -        Map data = new LinkedHashMap<>();
    -        data.put("org_cd", orgCd);
    -        data.put("biller_user_key", result);
    -
    -
    -        BillKkoApiRespDTO resultInfo = BillKkoApiRespDTO.>okBuilder().data(data).build();
    -        return EnsResponseVO.>>okBuilder().resultInfo(resultInfo).build();
    -    }
    -
    -    @Transactional(propagation = Propagation.NEVER)
    -    public EnsResponseVO>>> fwdPayRsltBulk(List> targets) {
    -        List> data = targets.stream()
    -                .map(m -> this.fwdPayRslt((String) m.get("org_cd"), (List) m.get("biller_user_key")).getResultInfo().getData())
    -                .collect(Collectors.toList());
    -
    -
    -        BillKkoApiRespDTO resultInfo = BillKkoApiRespDTO.okBuilder().data(data).build();
    -        return EnsResponseVO.>>>okBuilder().resultInfo(resultInfo).build();
    -
    -    }
    -
    -    private BillKkoApiRespDTO fwdPayRsltProc(String orgCd, String billerUserKey) {
    -        BillKkoErrCd billKkoErrCd = BillKkoErrCd.E601;
    -
    -        BillHist data = super.findByOrgMngAndBillerUserKeyAndReqSeAndLast(OrgMng.builder().orgCd(orgCd).build(), billerUserKey, BillReqSeCd.PAYRSLT).orElse(null);
    -        if (data == null)
    -            return BillKkoApiRespDTO.errDataBuilder()
    -                    .resCode(billKkoErrCd.getCode())
    -                    .message(billKkoErrCd.getCodeNm())
    -                    .data(String.format("%s 일치하는 납부결과 자료가 없습니다.", EnsErrCd.BILL404))
    -                    .build();
    -
    -
    -        BillKkoApiRespDTO respVO = null;
    -        BillHist billHist = null;
    -        try {
    -            Map mParam = gson.fromJson(data.getRequestData(), Map.class);
    -
    -            billHist = this.addBillHistByReqInfo(BillReqSeCd.PAYRSLT, billerUserKey, orgCd, data.getBillUid(), mParam);
    -
    -            respVO = billKkoClientApi.callApiByOrg(data.getOrgMng().getKkoBpCsignPayresultApi(), mParam);
    -            if (!"OK".equals(respVO.getRes_code())) {
    -                billKkoErrCd = BillKkoErrCd.valueOf(respVO.getRes_code());
    -                throw new EnsException(EnsErrCd.BILL604, String.format("[%s] %s", respVO.getRes_code(), respVO.getMessage()));
    -            }
    -
    -            billKkoErrCd = BillKkoErrCd.OK;
    -            this.modifyBillHistByRespInfo(billHist, respVO, null, null);
    -        } catch (EnsException e) {
    -            respVO = BillKkoApiRespDTO.errDataBuilder()
    -                    .resCode(billKkoErrCd.getCode())
    -                    .message(billKkoErrCd.getCodeNm())
    -                    .data(e.getMessage())
    -                    .build();
    -            this.modifyBillHistByRespInfo(billHist, respVO, e.getErrCd(), e.getMessage());
    -        } catch (Exception e) {
    -            respVO = BillKkoApiRespDTO.errDataBuilder()
    -                    .resCode(BillKkoErrCd.E601.getCode())
    -                    .message(BillKkoErrCd.E601.getCodeNm())
    -                    .data(e.getMessage())
    -                    .build();
    -            this.modifyBillHistByRespInfo(billHist, respVO, EnsErrCd.BILL999, e.getMessage());
    -        }
    -
    -        return respVO;
    -    }
    -
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoMaker.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoMaker.java
    deleted file mode 100644
    index 8cf1b4e..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoMaker.java
    +++ /dev/null
    @@ -1,163 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.impl;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.core.exception.EnsException;
    -import cokr.xit.ens.core.exception.code.EnsErrCd;
    -import cokr.xit.ens.core.utils.MapDeserailizer;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillMakerSupport;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillUrlReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoUrlReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.BillKkoService;
    -import com.google.gson.Gson;
    -import com.google.gson.GsonBuilder;
    -import com.querydsl.jpa.impl.JPAQueryFactory;
    -import lombok.RequiredArgsConstructor;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.beans.factory.annotation.Value;
    -import org.springframework.stereotype.Component;
    -
    -import java.util.Arrays;
    -import java.util.List;
    -import java.util.Map;
    -import java.util.Optional;
    -import java.util.concurrent.ExecutionException;
    -import java.util.concurrent.ForkJoinPool;
    -import java.util.stream.Collectors;
    -
    -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.QBill.bill;
    -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKko.billKko;
    -import static cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng.orgMng;
    -
    -@Slf4j
    -@Component
    -@RequiredArgsConstructor
    -public class BillKkoMaker extends BillMakerSupport {
    -
    -    private final JPAQueryFactory query;
    -
    -    private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create();
    -    private final BillKkoService billKkoService;
    -
    -    @Value("${app.pallel.thread.bill.cnt}")
    -    private int CNT_THREAD;
    -
    -
    -    @Override
    -    protected BillSeCd getBillSeCd() {
    -        return BillSeCd.bpKko;
    -    }
    -
    -    @Override
    -    protected List filter(List bills) {
    -        return bills.stream()
    -                .filter(bill -> bill.getDocBillKko() != null)
    -                .map(Bill::getBillUid)
    -                .collect(Collectors.toList());
    -    }
    -
    -    @Override
    -    protected void acceptProc(List bills) throws EnsException {
    -        if (bills.size() > 0) {
    -            List> acptreqs = bills.stream()
    -                    .map(bill -> {
    -                        BillAcptReqData acptreq = new BillAcptReqData() {
    -                            @Override
    -                            public BillKkoAcptReqVO get() {
    -                                BillKkoAcptReqVO billKkoAcptReqVO = gson.fromJson(bill.getDocBillKko(), BillKkoAcptReqVO.class);
    -                                billKkoAcptReqVO.setBillUid(bill.getBillUid());
    -                                return billKkoAcptReqVO;
    -                            }
    -                        };
    -                        return acptreq;
    -                    })
    -                    .collect(Collectors.toList());
    -            EnsResponseVO responseVO = billKkoService.accept(acptreqs);
    -            if (!EnsErrCd.OK.equals(responseVO.getErrCode()))  
    -//                            throw new EnsException(EnsErrCd.ACPT412, String.format("[%s] %s", responseVO.getErrCode(), responseVO.getErrMsg()));
    -                throw new EnsException(responseVO.getErrCode(), responseVO.getErrMsg());
    -        }
    -
    -    }
    -
    -    @Override
    -    protected List findBillsByBillUidsAndNotExists(List billUids) {
    -        return query.select(bill)
    -                .from(bill)
    -                .innerJoin(bill.orgMng, orgMng).fetchJoin()
    -                .leftJoin(billKko).on(bill.billUid.eq(billKko.billUid)).fetchJoin()
    -                .where(bill.billUid.in(billUids)
    -                        .and(bill.docBillKko.isNotNull())
    -                        .and(bill.billSeCd.in(Arrays.asList(BillSeCd.bpKko, BillSeCd.all)))
    -                        .and(billKko.billId.isNull())
    -                )
    -                .fetch();
    -    }
    -
    -
    -    @Override
    -    protected int generateUrlProc(List bills) {
    -
    -        ForkJoinPool forkJoinPool = new ForkJoinPool(CNT_THREAD);
    -        Optional cntSuccess = Optional.of(0);
    -        try {
    -            cntSuccess = forkJoinPool.submit(() -> {
    -                        return bills.stream()
    -                                .map(bill -> {
    -                                    BillUrlReqData urlreq = new BillUrlReqData() {
    -                                        @Override
    -                                        public BillKkoUrlReqVO get() {
    -                                            return BillKkoUrlReqVO.builder()
    -                                                    .reqSe(BillReqSeCd.URL)
    -                                                    .billerCode(bill.getOrgMng().getKkoBpBillerCode())
    -                                                    .authorization(bill.getOrgMng().getKkoBpAuthorization())
    -                                                    .billUid(bill.getBillUid())
    -                                                    .build();
    -                                        }
    -                                    };
    -
    -                                    try {
    -                                        if (EnsErrCd.OK.equals(billKkoService.createUrl(urlreq).getErrCode()))
    -                                            return 1;
    -                                        else
    -                                            return 0;
    -                                    } catch (Exception e) {
    -                                        return 0;
    -                                    }
    -                                })
    -                                .reduce(Integer::sum);
    -                    })
    -                    .get();
    -
    -            if (bills.size() == cntSuccess.get()) return 0;
    -            else return 1;
    -        } catch (InterruptedException e) {
    -           
    -            forkJoinPool.shutdown();
    -            this.errSend(EnsErrCd.BILL511, "-.BillUid: " + bills.stream().map(Bill::getBillUid).collect(Collectors.toList()).toString(), e);
    -            return bills.size();
    -        } catch (ExecutionException e) {
    -           
    -            forkJoinPool.shutdown();
    -            this.errSend(EnsErrCd.BILL511, "-.BillUid: " + bills.stream().map(Bill::getBillUid).collect(Collectors.toList()).toString(), e);
    -            return bills.size();
    -        }
    -    }
    -
    -
    -    @Override
    -    protected List findBillsByBillUidsAndUrlIsNull(List billUids) {
    -        return query.select(bill)
    -                .from(bill)
    -                .innerJoin(bill.orgMng, orgMng).fetchJoin()
    -                .innerJoin(billKko).on(bill.billUid.eq(billKko.billUid)).fetchJoin()
    -                .where(bill.billUid.in(billUids)
    -                        .and(billKko.url.isNull())
    -                )
    -                .fetch();
    -    }
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoServiceImpl.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoServiceImpl.java
    deleted file mode 100644
    index 77951e4..0000000
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/impl/BillKkoServiceImpl.java
    +++ /dev/null
    @@ -1,288 +0,0 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.impl;
    -
    -import cokr.xit.ens.core.aop.EnsResponseVO;
    -import cokr.xit.ens.core.exception.EnsException;
    -import cokr.xit.ens.core.exception.code.EnsErrCd;
    -import cokr.xit.ens.core.utils.CmmnUtil;
    -import cokr.xit.ens.core.utils.IdGenerator;
    -import cokr.xit.ens.core.utils.MapDeserailizer;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillUrlReqData;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.BillHist;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillHistRepository;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillRepository;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoApiSpec;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKko;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoRepository;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoAcptReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoUrlReqVO;
    -import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.BillKkoService;
    -import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    -import cokr.xit.ens.modules.common.domain.support.FieldError;
    -import com.google.gson.Gson;
    -import com.google.gson.GsonBuilder;
    -import lombok.RequiredArgsConstructor;
    -import lombok.extern.slf4j.Slf4j;
    -import org.springframework.http.HttpStatus;
    -import org.springframework.http.ResponseEntity;
    -import org.springframework.stereotype.Service;
    -import org.springframework.transaction.annotation.Propagation;
    -import org.springframework.transaction.annotation.Transactional;
    -
    -import javax.validation.ConstraintViolation;
    -import javax.validation.Validation;
    -import javax.validation.Validator;
    -import java.util.*;
    -import java.util.stream.Collectors;
    -
    -@Slf4j
    -@Service
    -@RequiredArgsConstructor
    -public class BillKkoServiceImpl implements BillKkoService {
    -
    -    private final BillRepository billRepository;
    -    private final BillKkoRepository billKkoRepository;
    -    private final BillHistRepository billHistRepository;
    -    private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create();
    -
    -
    -    private final BillKkoApiSpec billKkoApi;
    -
    -
    -    @Override
    -    @Transactional(propagation = Propagation.REQUIRED)
    -    public EnsResponseVO accept(List> acptreqList) {
    -        final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
    -        Map mValidate = new LinkedHashMap<>();
    -        acptreqList.forEach(reqData -> {
    -            Set> list = validator.validate(reqData.get());
    -            if (list.size() > 0) {
    -                {
    -                    mValidate.put(reqData.get().getBillerUserKey(), EnsResponseVO.errRsltBuilder()
    -                            .errCode(EnsErrCd.BILL405)
    -                            .errMsg("유효하지 않은 요청값 입니다.")
    -                            .resultInfo(list.stream()
    -                                    .map(row -> String.format("%s [ %s ]", row.getMessageTemplate(), row.getPropertyPath()))
    -                                    .collect(Collectors.toList()))
    -                            .build());
    -                }
    -            }
    -        });
    -        if (!mValidate.isEmpty())
    -            return EnsResponseVO.errRsltBuilder().errCode(EnsErrCd.BILL403).errMsg("유효하지 않은 청구서생성 요청값이 포함되어 있습니다.").resultInfo(mValidate).build();
    -
    -        List billUids = acptreqList.stream()
    -                .filter(reqData -> reqData.get().getBillUid() != null)
    -                .map(reqData -> reqData.get().getBillUid())
    -                .collect(Collectors.toList());
    -        billUids = billKkoRepository.findBillUidsByBillUidIn(billUids);
    -        if (billUids.size() > 0)
    -            return EnsResponseVO.errRsltBuilder().errCode(EnsErrCd.BILL401).errMsg("이미 등록된 청구서 UniqueID가 있습니다.").resultInfo(billUids).build();
    -
    -        List billerUserKeys = acptreqList.stream()
    -                .filter(reqData -> reqData.get().getBillerUserKey() != null)
    -                .map(reqData -> reqData.get().getBillerUserKey())
    -                .collect(Collectors.toList());
    -        billerUserKeys = billKkoRepository.findBillerUserKeysByBillerUserKeyIn(billerUserKeys);
    -        if (billerUserKeys.size() > 0)
    -            return EnsResponseVO.errRsltBuilder().errCode(EnsErrCd.BILL402).errMsg("이미 등록된 기관관리번호(=계약번호)가 있습니다.").resultInfo(billerUserKeys).build();
    -
    -
    -
    -
    -        String prefix = IdGenerator.getRandomString(6) + "-" + IdGenerator.getCurrentTimeSec();
    -        List billKkos = acptreqList.stream()
    -                .map(reqData -> reqData.get())
    -                .map(vo -> BillKko.builder()
    -                        .billUid(CmmnUtil.isEmpty(vo.getBillUid()) ? IdGenerator.getShortUUID(prefix) : vo.getBillUid())
    -                        .billerUserKey(vo.getBillerUserKey())
    -                        .billedYearMonth(vo.getBilledYearMonth())
    -                        .ordinal(vo.getOrdinal())
    -                        .billerNoticeKey(vo.getBillerNoticeKey())
    -                        .expireAt(vo.getExpireAt())
    -                        .parameters(CmmnUtil.isEmpty(vo.getParameters()) ? null : gson.toJson(vo.getParameters()))
    -                        .customUrl(CmmnUtil.isEmpty(vo.getCustomUrl()) ? null : gson.toJson(vo.getCustomUrl()))
    -                        .build())
    -                .collect(Collectors.toList());
    -        billKkoRepository.saveAll(billKkos);
    -        List billHists = billKkos.stream()
    -                .map(billKko -> BillHist.builder()
    -                        .billUid(billKko.getBillUid())
    -                        .billSe(BillSeCd.bpKko)
    -                        .reqSe(BillReqSeCd.ACPT)
    -                        .orgMng(null)
    -                        .linkedUuid(billKko.getBillerUserKey())
    -                        .requestData(null)
    -                        .responseData(null)
    -                        .error(null)
    -                        .build())
    -                .collect(Collectors.toList());
    -        billHistRepository.saveAll(billHists);
    -
    -
    -        List> resultInfo = billKkos.stream()
    -                .map(billKko -> {
    -                    Map ids = new HashMap<>();
    -                    ids.put(billKko.getBillerUserKey(), billKko.getBillUid());
    -                    return ids;
    -                })
    -                .collect(Collectors.toList());
    -        return EnsResponseVO.okBuilder().resultInfo(resultInfo).build();
    -    }
    -
    -    @Override
    -    @Transactional(propagation = Propagation.REQUIRED)
    -    public EnsResponseVO createUrl(BillUrlReqData billUrlReqData) {
    -        BillKkoUrlReqVO reqVO = billUrlReqData.get();
    -
    -        Bill bill = Bill.builder().build();
    -        BillKko billKko = null;
    -        BillHist billHist = null;
    -        EnsResponseVO respVO = null;
    -        String requestData = null;
    -        String responseData = null;
    -        try {
    -            if ((BillReqSeCd.URL.equals(reqVO.getBillerCode()) || BillReqSeCd.REURL.equals(reqVO.getBillerCode())))
    -                throw new EnsException(EnsErrCd.BILL405, "유효하지 않은 요청구분 입니다. 사용가능한 요청구분은 \"URL\" or \"REURL\" 입니다.");
    -
    -            bill = billRepository.findByBillUid(reqVO.getBillUid()).orElse(Bill.builder().build());
    -            billKko = billKkoRepository.findByBillUid(reqVO.getBillUid()).orElseThrow(() -> new EnsException(EnsErrCd.BILL404, "일치하는 청구서 자료가 없습니다."));
    -            if (BillReqSeCd.URL.equals(reqVO.getReqSe()) && !CmmnUtil.isEmpty(billKko.getUrl()))
    -                return EnsResponseVO.okBuilder().resultInfo(billKko).build();
    -            Map parameters = this.createParameters(billKko, bill.getOrgMng());
    -            try {
    -                requestData = gson.toJson(parameters);
    -            } catch (Exception e) {
    -                throw new EnsException(EnsErrCd.BILL501, String.format("청구서링크생성 파라미터 JSON 데이터로 변환 실패. [ data %s ]", parameters.toString()));
    -            }
    -
    -            ResponseEntity resp = BillReqSeCd.URL.equals(reqVO.getReqSe())
    -                    ? billKkoApi.url(reqVO.getBillerCode(), reqVO.getAuthorization(), requestData)
    -                    : billKkoApi.reUrl(reqVO.getBillerCode(), reqVO.getAuthorization(), requestData);
    -            responseData = resp.getBody();
    -            if (resp.getStatusCode() != HttpStatus.OK)
    -                throw new EnsException(EnsErrCd.BILL602, String.format("청구서링크생성 HttpStatus Fail..  [ response raw ]: %s %s", resp.getStatusCode().toString(), responseData));
    -            Map mResp = null;
    -            try {
    -                mResp = gson.fromJson(responseData, Map.class);
    -            } catch (Exception e) {
    -                throw new EnsException(EnsErrCd.BILL601, String.format("청구서링크생성 JSON 응답 메시지가 유효하지 않습니다. [ response raw ]: %s", responseData));
    -            }
    -            if (CmmnUtil.isEmpty(mResp.get("data")))
    -                throw new EnsException(EnsErrCd.BILL603, String.format("청구서링크생성 응답 데이터 중 data 키의 값이 없습니다. [ response raw ]: %s", responseData));
    -            Map data = (Map) mResp.get("data");
    -            String url = data.get("url");
    -
    -
    -            billKko.setUrl(url);
    -            billKko.setError(FieldError.initBuilder().build());
    -
    -            billHist = BillHist.builder()
    -                    .billUid(billKko.getBillUid())
    -                    .billSe(BillSeCd.bpKko)
    -                    .reqSe(billUrlReqData.get().getReqSe())
    -                    .orgMng(bill.getOrgMng())
    -                    .linkedUuid(billKko.getBillerUserKey())
    -                    .requestData(CmmnUtil.toJsonString(parameters))
    -                    .responseData(responseData)
    -                    .error(FieldError.initBuilder().build())
    -                    .build();
    -
    -
    -            respVO = EnsResponseVO.okBuilder().resultInfo(billKko).build();
    -
    -        } catch (EnsException e) {
    -            if (!CmmnUtil.isEmpty(billKko)) {
    -
    -                billKko.setError(FieldError.initBuilder()
    -                        .errorCode(e.getErrCd().getCode())
    -                        .errorMessage(e.getMessage())
    -                        .build());
    -
    -                billHist = BillHist.builder()
    -                        .billUid(billKko.getBillUid())
    -                        .billSe(BillSeCd.bpKko)
    -                        .reqSe(billUrlReqData.get().getReqSe())
    -                        .orgMng(bill.getOrgMng())
    -                        .linkedUuid(billKko.getBillerUserKey())
    -                        .requestData(requestData)
    -                        .responseData(responseData)
    -                        .error(FieldError.initBuilder()
    -                                .errorCode(e.getErrCd().getCode())
    -                                .errorMessage(e.getMessage())
    -                                .build())
    -                        .build();
    -            }
    -
    -            respVO = EnsResponseVO.errBuilder()
    -                    .errCode(e.getErrCd())
    -                    .errMsg(e.getMessage())
    -                    .build();
    -
    -
    -            if (BillReqSeCd.URL.equals(reqVO.getReqSe())
    -                    && EnsErrCd.BILL602.equals(e.getErrCd()) && e.getMessage().contains("Read timed out")) {
    -                return this.createUrl(
    -                        new BillUrlReqData() {
    -                            @Override
    -                            public BillKkoUrlReqVO get() {
    -                                return BillKkoUrlReqVO.builder()
    -                                        .reqSe(BillReqSeCd.REURL)
    -                                        .billerCode(reqVO.getBillerCode())
    -                                        .authorization(reqVO.getAuthorization())
    -                                        .billUid(reqVO.getBillUid())
    -                                        .build();
    -                            }
    -                        });
    -            }
    -        } finally {
    -            if (!CmmnUtil.isEmpty(billHist))
    -
    -                billHistRepository.save(billHist);
    -        }
    -
    -        return respVO;
    -    }
    -
    -
    -    /**
    -     * 청구서링크생성API body Message로 변환하여 반환 한다.
    -     *
    -     * @param dataset
    -     * @return
    -     */
    -    private Map createParameters(BillKko dataset, OrgMng orgMng) {
    -        Map parameters = null;
    -        Map customUrl = null;
    -        try {
    -            Gson gson = new GsonBuilder().disableHtmlEscaping().create();
    -            parameters = CmmnUtil.isEmpty(dataset.getParameters()) ? new HashMap<>() : gson.fromJson(dataset.getParameters(), Map.class);
    -
    -            parameters.put("orgCd", orgMng == null ? null : orgMng.getOrgCd());
    -//            parameters.put("billUid", dataset.getBillUid());
    -            customUrl = Optional.ofNullable(dataset.getCustomUrl()).isPresent() ? gson.fromJson(dataset.getCustomUrl(), Map.class) : null;
    -        } catch (Exception e) {
    -            log.info("=========================================");
    -            log.info("청구서링크 제작 중 parameters 변환(Json => Map) 실패.");
    -            log.info("Error: " + e.getMessage());
    -            log.info("=========================================");
    -        }
    -
    -        Map data = new HashMap();
    -        data.put("biller_user_key", dataset.getBillerUserKey());
    -        data.put("billed_year_month", dataset.getBilledYearMonth());
    -        data.put("ordinal", dataset.getOrdinal());
    -        data.put("biller_notice_key", dataset.getBillerNoticeKey());
    -        data.put("expire_at", dataset.getExpireAt());
    -        data.put("parameters", parameters);
    -        data.put("custom_url", customUrl);
    -
    -
    -        Map m = new HashMap();
    -        m.put("data", data);
    -        return m;
    -    }
    -}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayAbleService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayAbleService.java
    new file mode 100644
    index 0000000..7c21d3a
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayAbleService.java
    @@ -0,0 +1,261 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.core.utils.CmmnUtil;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoPayRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayAbleService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayAbleData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import com.google.gson.Gson;
    +import com.google.gson.reflect.TypeToken;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.Getter;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.Arrays;
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.Optional;
    +
    +@Slf4j
    +@RequiredArgsConstructor
    +@Service
    +public class KkoPayAbleService implements PayAbleService, Map, PayApiRespDTO>> {
    +    private final BillKkoPayRepository billKkoPayRepository;
    +
    +    private final JPAQueryFactory query;
    +    private final PayUseSysApi payUseSysApi;
    +    private final BillHistRepository billHistRepository;
    +
    +    private Gson gson = new Gson();
    +
    +    private enum KkoErrCd {
    +        E403(PayUseSysResCd.NO_AMOUNT_PAYABLE),
    +        E501(PayUseSysResCd.OVERPAYABLE_AMOUNT),
    +        E502(PayUseSysResCd.NO_TARGET_PAYABLE),
    +        E506(PayUseSysResCd.EXPIRED_DATE),
    +        E601(PayUseSysResCd.FAILED_CHECK_INFO),
    +        ;
    +        @Getter
    +        private PayUseSysResCd payUseSysResCd;
    +
    +        KkoErrCd(PayUseSysResCd payUseSysResCd) {
    +            this.payUseSysResCd = payUseSysResCd;
    +        }
    +
    +        static public KkoErrCd payUseSysResCdOf(String payUseSysResCd) {
    +            KkoErrCd result = null;
    +            for (KkoErrCd kkoErrCd : KkoErrCd.values()) {
    +                if (kkoErrCd.getPayUseSysResCd().getCode().equals(payUseSysResCd)) {
    +                    result = kkoErrCd;
    +                    break;
    +                }
    +            }
    +            return result;
    +        }
    +    }
    +
    +    @Override
    +    public PayAbleData getData(Map reqParam) {
    +
    +        Map data = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +        String billerUserKey = (String) data.get("biller_user_key");
    +        String billedYearMonth = (String) data.get("billed_year_month");
    +        String ordinal = (String) data.get("ordinal");
    +        String billerNoticeKey = (String) data.get("biller_notice_key");
    +        Map parameters = (Map) data.getOrDefault("parameters", new HashMap<>());
    +        Integer amount = (Integer) data.get("amount");
    +
    +        BillKkoPay billKkoPay = query.selectFrom(QBillKkoPay.billKkoPay)
    +                .where(QBillKkoPay.billKkoPay.billerNoticeKey.eq(billerNoticeKey))
    +                .fetchOne();
    +        String billUid = billKkoPay == null ? null : billKkoPay.getBillUid();
    +        if (billUid == null) billUid = "";
    +        Bill bill = query.selectFrom(QBill.bill)
    +                .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin()
    +                .where(QBill.bill.billUid.eq(billUid))
    +                .fetchOne();
    +
    +        return PayAbleData.builder()
    +                .bill(bill)
    +                .billDetail(billKkoPay)
    +                .build();
    +    }
    +
    +    @Override
    +    public void validate(Map reqParam, PayAbleData data) {
    +        Map m = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +       
    +        if (CmmnUtil.isEmpty(m.get("biller_user_key")))
    +            throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "빌러유저키는 필수값 입니다.");
    +        if (CmmnUtil.isEmpty(m.get("biller_notice_key")))
    +            throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "청구서식별키는 필수값 입니다.");
    +        if (CmmnUtil.isEmpty(m.get("amount")))
    +            throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "납부요청금액 필수값 입니다.");
    +       
    +        if (CmmnUtil.isEmpty(data.getBill()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다.");
    +        if (CmmnUtil.isEmpty(data.getBillDetail()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다.");
    +    }
    +
    +    @Override
    +    public void callApi(Map reqParam, PayAbleData data) {
    +        Bill bill = data.getBill();
    +        OrgMng orgMng = bill.getOrgMng();
    +        BillKkoPay billKkoPay = data.getBillDetail();
    +
    +
    +       
    +        final String useSysUrl = orgMng.getKkoBpPrepayApi();
    +
    +       
    +        Optional.of(reqParam)
    +                .map(param -> createMessage(param)) 
    +                .map(message -> loadReqData(data, useSysUrl, message))    
    +                .map(message -> payUseSysApi.payNotice(useSysUrl, message, null))   
    +                .map(response -> loadRespData(data, response))  
    +                .map(response -> checkResponse(response))
    +        ;
    +
    +    }
    +
    +    private Map createMessage(Map reqParam) {
    +//        Map data = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +//        Map param = new HashMap<>();
    +//        param.put("biller_user_key", data.get("biller_user_key"));
    +//        param.put("billed_year_month", data.get("billed_year_month"));
    +//        param.put("ordinal", data.get("ordinal"));
    +//        param.put("biller_notice_key", data.get("biller_notice_key"));
    +//        param.put("parameters", data.get("parameters"));
    +//        param.put("amount", data.get("amount"));
    +//        return param;
    +        return reqParam;
    +    }
    +
    +    private Map loadReqData(PayAbleData data, String url, Map param) {
    +        
    +        data.getReqAndRespInf().setUrl(url);
    +        data.getReqAndRespInf().setReqData(gson.toJson(param));
    +        return param;
    +    }
    +
    +    private ResponseEntity loadRespData(PayAbleData data, ResponseEntity response) {
    +        
    +        data.getReqAndRespInf().setRespRawData(response.getBody());
    +        return response;
    +    }
    +
    +
    +    private PayApiRespDTO> checkResponse(ResponseEntity response) {
    +        
    +        if (!HttpStatus.OK.equals(response.getStatusCode()))
    +            throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody());
    +        
    +        PayApiRespDTO> result = null;
    +        try {
    +            result = gson.fromJson(response.getBody(), new TypeToken>>() {
    +            }.getType());
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex);
    +        }
    +        
    +        try {
    +            PayUseSysResCd.valueOf(result.getResCode());
    +        } catch (Exception ex) {
    +            PayApiRespDTO> finalResult = result;
    +            
    +            if (Arrays.stream(KkoErrCd.values()).noneMatch(kkoErrCd -> kkoErrCd.name().equals(finalResult.getResCode())))
    +                throw new EnsException(EnsErrCd.INVALID_RES_CODE, EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex);
    +        }
    +
    +        return result;
    +    }
    +
    +    @Override
    +    public PayApiRespDTO> generateResult(Map reqParam, PayAbleData data, EnsException e) {
    +        if (e == null) {    
    +            Gson gson = new Gson();
    +            final String respRawData = data.getReqAndRespInf().getRespRawData();
    +
    +            PayApiRespDTO> resp = gson.fromJson(respRawData, new TypeToken>>() {
    +            }.getType());
    +            
    +            String resCode = resp.getResCode();
    +            String matchResCode = KkoErrCd.payUseSysResCdOf(resCode).name();
    +            if (matchResCode != null) resCode = matchResCode;
    +
    +            return PayApiRespDTO.>errDataBuilder()
    +                    .resCode(resCode)
    +                    .message(resp.getMessage())
    +                    .data(resp.getData())
    +                    .build();
    +        } else {   
    +            return PayApiRespDTO.>errDataBuilder()
    +                    .resCode(e.getErrCd().getCode())
    +                    .message(e.getMessage())
    +                    .data(null)
    +                    .build();
    +        }
    +    }
    +
    +    @Override
    +    public void saveHist(Map reqParam, PayAbleData data, EnsException e) {
    +        saveHistByUseSysPayAble(reqParam, data, e); 
    +
    +        if (e != null) {    
    +            if (data.getBillDetail() != null) {
    +                data.getBillDetail().setError(FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build());
    +                billKkoPayRepository.save(data.getBillDetail());
    +            }
    +        } else {
    +            data.getBillDetail().setError(FieldError.initBuilder().build());
    +            billKkoPayRepository.save(data.getBillDetail());
    +        }
    +    }
    +
    +    public void saveHistByUseSysPayAble(Map reqParam, PayAbleData data, EnsException e) {
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +
    +        BillHist billHist = BillHist.builder()
    +                .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                .billSe(BillSeCd.bpKko)  
    +                .reqSe(BillReqSeCd.US_PREPAY)  
    +                .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                .requestData(reqAndRespInf.getReqData())
    +                .responseData(reqAndRespInf.getRespRawData())
    +                .error(e == null
    +                        ? FieldError.initBuilder().build()
    +                        : FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build())
    +                .build();
    +
    +        billHistRepository.save(billHist);
    +    }
    +
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayNoticeService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayNoticeService.java
    new file mode 100644
    index 0000000..0e79fd5
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayNoticeService.java
    @@ -0,0 +1,287 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.core.utils.CmmnUtil;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoPayRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayNoticeRespData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillLogSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayNoticeService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayNoticeData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import com.google.gson.Gson;
    +import com.google.gson.reflect.TypeToken;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.Getter;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.Arrays;
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.Optional;
    +
    +@Slf4j
    +@RequiredArgsConstructor
    +@Service
    +public class KkoPayNoticeService implements PayNoticeService, Map, PayApiRespDTO> {
    +
    +    private final JPAQueryFactory query;
    +    private final PayUseSysApi payUseSysApi;
    +    private final BillKkoPayRepository billKkoPayRepository;
    +    private final BillHistRepository billHistRepository;
    +    private Gson gson = new Gson();
    +
    +
    +    private enum KkoErrCd {
    +        E402(PayUseSysResCd.NOT_FOUND_PAYDATA),
    +        E404(PayUseSysResCd.PAYDATA_FIND_FAILED),
    +        ;
    +        @Getter
    +        private PayUseSysResCd payUseSysResCd;
    +
    +        KkoErrCd(PayUseSysResCd payUseSysResCd) {
    +            this.payUseSysResCd = payUseSysResCd;
    +        }
    +
    +        static public KkoErrCd payUseSysResCdOf(String payUseSysResCd) {
    +            KkoErrCd result = null;
    +            for (KkoErrCd kkoErrCd : KkoErrCd.values()) {
    +                if (kkoErrCd.getPayUseSysResCd().getCode().equals(payUseSysResCd)) {
    +                    result = kkoErrCd;
    +                    break;
    +                }
    +            }
    +            return result;
    +        }
    +    }
    +
    +    @Override
    +    public PayNoticeData getData(Map reqParam) {
    +
    +        Map data = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +        String billerUserKey = (String) data.get("biller_user_key");
    +        String billerNoticeKey = (String) data.get("biller_notice_key");
    +        String userBirth = (String) data.get("user_birth");
    +        Map parameters = (Map) data.getOrDefault("parameters", new HashMap<>());
    +        String orgCd = (String) parameters.get("orgCd");
    +
    +        BillKkoPay billKkoPay = query.selectFrom(QBillKkoPay.billKkoPay)
    +                .where(QBillKkoPay.billKkoPay.billerNoticeKey.eq(billerNoticeKey))
    +                .fetchOne();
    +        String billUid = billKkoPay == null ? null : billKkoPay.getBillUid();
    +        if (billUid == null) billUid = "";
    +        Bill bill = query.selectFrom(QBill.bill)
    +                .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin()
    +                .where(QBill.bill.billUid.eq(billUid))
    +                .fetchOne();
    +
    +        return PayNoticeData.builder()
    +                .bill(bill)
    +                .billDetail(billKkoPay)
    +                .build();
    +    }
    +
    +    @Override
    +    public void validate(Map reqParam, PayNoticeData data) {
    +        Map m = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +       
    +        if (CmmnUtil.isEmpty(m.get("biller_user_key")))
    +            throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "빌러유저키는 필수값 입니다.");
    +        if (CmmnUtil.isEmpty(m.get("biller_notice_key")))
    +            throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "청구서식별키는 필수값 입니다.");
    +       
    +        if (CmmnUtil.isEmpty(data.getBill()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다.");
    +        if (CmmnUtil.isEmpty(data.getBillDetail()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다.");
    +        if (!data.getBillDetail().getBillerUserKey().equals(m.get("biller_user_key")))
    +            throw new EnsException(EnsErrCd.INVALID_DATA, "요청과 실제 빌러유저키가 일치하지 않습니다.");
    +    }
    +
    +    @Override
    +    public void callApi(Map reqParam, PayNoticeData data) {
    +        Bill bill = data.getBill();
    +        OrgMng orgMng = bill.getOrgMng();
    +        BillKkoPay billKkoPay = data.getBillDetail();
    +
    +       
    +        final String useSysUrl = orgMng.getKkoBpNoticeApi();
    +
    +       
    +        Optional.of(billKkoPay.getBillerUserKey())
    +                .map(billerUserKey -> createMessage(reqParam)) 
    +                .map(param -> loadReqData(data, useSysUrl, param))    
    +                .map(param -> payUseSysApi.payNotice(useSysUrl, param, null))   
    +                .map(response -> loadRespData(data, response))  
    +                .map(response -> checkResponse(response))
    +                .map(document -> savePayNoticeInfo(data, document))  
    +        ;
    +
    +    }
    +
    +    private Map createMessage(Map reqParam) {
    +//        Map m = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +//        Map mParam = new HashMap<>();
    +//        mParam.put("billerUserKey", m.get("biller_user_key"));
    +//        mParam.put("userBirth", m.get("user_birth"));
    +//        return mParam;
    +        return reqParam;
    +    }
    +
    +    private Map loadReqData(PayNoticeData data, String url, Map param) {
    +        
    +        data.getReqAndRespInf().setUrl(url);
    +        data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param));
    +        return param;
    +    }
    +
    +    private ResponseEntity loadRespData(PayNoticeData data, ResponseEntity response) {
    +        
    +        data.getReqAndRespInf().setRespRawData(response.getBody());
    +        return response;
    +    }
    +
    +
    +    private PayApiRespDTO checkResponse(ResponseEntity response) {
    +        
    +        if (!HttpStatus.OK.equals(response.getStatusCode()))
    +            throw new EnsException(EnsErrCd.API_COMM_ERROR, "["+ BillLogSeCd.US +"] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody());
    +        
    +        PayApiRespDTO result = null;
    +        try {
    +            result = gson.fromJson(response.getBody(), new TypeToken>() {
    +            }.getType());
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RESPONSE, "["+ BillLogSeCd.US +"] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex);
    +        }
    +        
    +        try {
    +            PayUseSysResCd.valueOf(result.getResCode());
    +        } catch (Exception ex) {
    +            PayApiRespDTO finalResult = result;
    +            
    +            if (Arrays.stream(KkoErrCd.values()).noneMatch(kkoErrCd -> kkoErrCd.name().equals(finalResult.getResCode())))
    +                throw new EnsException(EnsErrCd.INVALID_RES_CODE, "["+ BillLogSeCd.US +"] " + EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex);
    +        }
    +        if (!PayUseSysResCd.OK.getCode().equals(result.getResCode())) {
    +            result.setMessage("["+ BillLogSeCd.US +"] " + result.getMessage());
    +            throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result);
    +        }
    +
    +        return result;
    +    }
    +
    +    private PayApiRespDTO savePayNoticeInfo(PayNoticeData data, PayApiRespDTO document) {
    +        KkoPayNoticeRespData noticeData = document.getData();
    +
    +        data.getBillDetail().setTitle(noticeData.getTitle());
    +        data.getBillDetail().setAmount(noticeData.getAmount());
    +        data.getBillDetail().setTaxFreeAmount(noticeData.getTaxFreeAmount());
    +        data.getBillDetail().setVatAmount(noticeData.getVatAmount());
    +        data.getBillDetail().setExpireType(noticeData.getExpireType());
    +        data.getBillDetail().setPayExpireDate(noticeData.getPayExpireDate());
    +        data.getBillDetail().setSecondPayExpireDate(noticeData.getSecondPayExpireDate());
    +        data.getBillDetail().setBankAccounts(CmmnUtil.isEmpty(noticeData.getBankAccounts()) ? null : gson.toJson(noticeData.getBankAccounts()));
    +        data.getBillDetail().setDetails(CmmnUtil.isEmpty(noticeData.getDetails()) ? null : gson.toJson(noticeData.getDetails()));
    +        data.getBillDetail().setError(FieldError.initBuilder().build());
    +
    +        billKkoPayRepository.save(data.getBillDetail());
    +
    +        return document;
    +    }
    +
    +    @Override
    +    public PayApiRespDTO generateResult(Map reqParam, PayNoticeData data, EnsException e) {
    +        if (e == null) {    
    +            Gson gson = new Gson();
    +            final String respRawData = data.getReqAndRespInf().getRespRawData();
    +
    +            PayApiRespDTO resp = gson.fromJson(respRawData, new TypeToken>() {
    +            }.getType());
    +            
    +            String resCode = resp.getResCode();
    +            String matchResCode = KkoErrCd.payUseSysResCdOf(resCode).name();
    +            if (matchResCode != null) resCode = matchResCode;
    +
    +            return PayApiRespDTO.errDataBuilder()
    +                    .resCode(resCode)
    +                    .message(resp.getMessage())
    +                    .data(resp.getData())
    +                    .build();
    +        } else {   
    +            if (EnsErrCd.RESPONSED_FAILURE_CODE.equals(e.getErrCd())) {
    +                PayApiRespDTO respDTO = (PayApiRespDTO) e.getData();
    +                
    +                String resCode = respDTO.getResCode();
    +                String matchResCode = KkoErrCd.payUseSysResCdOf(resCode).name();
    +                if (matchResCode != null) resCode = matchResCode;
    +                return PayApiRespDTO.errDataBuilder()
    +                        .resCode(resCode)
    +                        .message(respDTO.getMessage())
    +                        .data(null)
    +                        .build();
    +            } else {
    +                return PayApiRespDTO.errDataBuilder()
    +                        .resCode(e.getErrCd().getCode())
    +                        .message(e.getMessage())
    +                        .data(null)
    +                        .build();
    +            }
    +        }
    +    }
    +
    +    @Override
    +    public void saveHist(Map reqParam, PayNoticeData data, EnsException e) {
    +        saveHistByUseSysNotice(reqParam, data, e);  
    +
    +        if (e != null) {    
    +            if (data.getBillDetail() != null) {
    +                data.getBillDetail().setError(FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build());
    +                billKkoPayRepository.save(data.getBillDetail());
    +            }
    +        }
    +    }
    +
    +    private void saveHistByUseSysNotice(Map reqParam, PayNoticeData data, EnsException e) {
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +
    +        BillHist billHist = BillHist.builder()
    +                .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                .billSe(BillSeCd.bpKko)  
    +                .reqSe(BillReqSeCd.US_NOTICE)  
    +                .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                .requestData(reqAndRespInf.getReqData())
    +                .responseData(reqAndRespInf.getRespRawData())
    +                .error(e == null
    +                        ? FieldError.initBuilder().build()
    +                        : FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build())
    +                .build();
    +
    +        billHistRepository.save(billHist);
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayResultService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayResultService.java
    new file mode 100644
    index 0000000..d7bd09b
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayResultService.java
    @@ -0,0 +1,233 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.core.utils.CmmnUtil;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoPayRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayResultReqData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayResultService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayResultData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import com.google.gson.Gson;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.Optional;
    +
    +@Slf4j
    +@RequiredArgsConstructor
    +@Service
    +public class KkoPayResultService implements PayResultService, Map, PayApiRespDTO>> {
    +
    +    private final JPAQueryFactory query;
    +    private final PayUseSysApi payUseSysApi;
    +    private final BillRepository billRepository;
    +    private final BillKkoPayRepository billKkoPayRepository;
    +    private final BillHistRepository billHistRepository;
    +
    +    private Gson gson = new Gson();
    +
    +    @Override
    +    public PayResultData getData(Map reqParam) {
    +
    +        Map data = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +        String billerNoticeKey = (String) data.get("biller_notice_key");
    +        Map parameters = (Map) data.getOrDefault("parameters", new HashMap<>());
    +
    +        BillKkoPay billKkoPay = query.selectFrom(QBillKkoPay.billKkoPay)
    +                .where(QBillKkoPay.billKkoPay.billerNoticeKey.eq(billerNoticeKey))
    +                .fetchOne();
    +        String billUid = billKkoPay == null ? null : billKkoPay.getBillUid();
    +        if (billUid == null) billUid = "";
    +        Bill bill = query.selectFrom(QBill.bill)
    +                .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin()
    +                .where(QBill.bill.billUid.eq(billUid))
    +                .fetchOne();
    +
    +        return PayResultData.builder()
    +                .bill(bill)
    +                .billDetail(billKkoPay)
    +                .build();
    +    }
    +
    +    @Override
    +    public void validate(Map reqParam, PayResultData data) {
    +       
    +        if (CmmnUtil.isEmpty(data.getBill()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다.");
    +        if (CmmnUtil.isEmpty(data.getBillDetail()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다.");
    +    }
    +
    +    @Override
    +    public void callApi(Map reqParam, PayResultData data) {
    +        Bill bill = data.getBill();
    +        OrgMng orgMng = bill.getOrgMng();
    +
    +       
    +        final String useSysUrl = orgMng.getKkoBpPayresultApi();
    +
    +       
    +        Optional.of(savePaidInfo(data, reqParam))   
    +                .map(param -> loadReqData(data, useSysUrl, param))    
    +                .map(param -> createMessage(param))   
    +                .map(message -> payUseSysApi.payResult(useSysUrl, message, null))   
    +                .map(response -> loadRespData(data, response))  
    +                .map(response -> checkResponse(response))//API 응답 검증
    +        ;
    +    }
    +
    +    private Map savePaidInfo(PayResultData data, Map reqParam) {
    +        Map reqData = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +        final String paidAt = CmmnUtil.isEmpty(reqData.get("paid_at")) ? data.getBillDetail().getLastPaidAt() : (String) reqData.get("paid_at");
    +        final Integer payId = CmmnUtil.isEmpty(reqData.get("pay_id")) ? data.getBillDetail().getLastPayId() : (Integer) reqData.get("pay_id");
    +
    +
    +        
    +        data.getBill().setPaidAt(true); 
    +        data.getBill().setPaidType(PaidTypeCd.kakaoPay);    
    +        data.getBill().setPaidDt(paidAt);   
    +        billRepository.save(data.getBill());
    +
    +        
    +        data.getBillDetail().setLastPaidAt(paidAt);
    +        data.getBillDetail().setLastPayId(payId);
    +        data.getBillDetail().setError(FieldError.initBuilder().build());
    +        billKkoPayRepository.save(data.getBillDetail());
    +
    +
    +        return reqParam;
    +    }
    +
    +
    +    private Map loadReqData(PayResultData data, String url, Map param) {
    +        
    +        data.getReqAndRespInf().setUrl(url);
    +        data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param));
    +        return param;
    +    }
    +
    +    private Map createMessage(Map reqParam) {
    +//        return reqParam;
    +        Map data = (Map) reqParam.getOrDefault("data", new HashMap<>());
    +        KkoPayResultReqData kkoPayResultReqData = gson.fromJson(gson.toJson(data), KkoPayResultReqData.class);
    +        Map result = new HashMap<>();
    +        result.put("data", kkoPayResultReqData);
    +        return result;
    +    }
    +
    +    private ResponseEntity loadRespData(PayResultData data, ResponseEntity response) {
    +        
    +        data.getReqAndRespInf().setRespRawData(response.getBody());
    +        return response;
    +    }
    +
    +    private PayApiRespDTO> checkResponse(ResponseEntity response) {
    +        
    +        if (!HttpStatus.OK.equals(response.getStatusCode()))
    +            throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody());
    +        
    +        PayApiRespDTO> result = null;
    +        try {
    +            result = gson.fromJson(response.getBody(), PayApiRespDTO.class);
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex);
    +        }
    +        
    +        try {
    +            PayUseSysResCd.valueOf(result.getResCode());
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RES_CODE, EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex);
    +        }
    +
    +        return result;
    +    }
    +
    +
    +    @Override
    +    public PayApiRespDTO> generateResult(Map reqParam, PayResultData data, EnsException e) {
    +        if (e == null) {    
    +            final String respRawData = data.getReqAndRespInf().getRespRawData();
    +            return gson.fromJson(respRawData, PayApiRespDTO.class);
    +        } else {   
    +            return PayApiRespDTO.>errDataBuilder()
    +                    .resCode(e.getErrCd().getCode())
    +                    .message(e.getMessage())
    +                    .data(null)
    +                    .build();
    +        }
    +    }
    +
    +    @Override
    +    public void saveHist(Map reqParam, PayResultData data, EnsException e) {
    +        saveHistByUseSysPayResult(reqParam, data, e); 
    +
    +        if (e != null) {    
    +            if (data.getBillDetail() != null) {
    +                data.getBillDetail().setError(FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build());
    +                billKkoPayRepository.save(data.getBillDetail());
    +            }
    +        }
    +
    +    }
    +
    +    private void saveHistByUseSysPayResult(Map reqParam, PayResultData data, EnsException e) {
    +
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +
    +        String requestData = reqAndRespInf.getReqData();
    +        if (e != null) {
    +            switch (e.getErrCd()) {
    +                case NO_DATA_FOUND:
    +                case INVALID_REQUEST:
    +                    requestData = gson.toJson(reqParam);
    +                    break;
    +            }
    +        }
    +
    +
    +        BillHist billHist = BillHist.builder()
    +                .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                .billSe(BillSeCd.bpKko)  
    +                .reqSe(BillReqSeCd.US_PAYRSLT)  
    +                .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                .requestData(requestData)
    +                .responseData(reqAndRespInf.getRespRawData())
    +                .error(e == null
    +                        ? FieldError.initBuilder().build()
    +                        : FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build())
    +                .build();
    +
    +        billHistRepository.save(billHist);
    +
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayUrlService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayUrlService.java
    new file mode 100644
    index 0000000..c82dcad
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/KkoPayUrlService.java
    @@ -0,0 +1,420 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process;
    +
    +import cokr.xit.ens.core.exception.EnsException;
    +import cokr.xit.ens.core.exception.code.EnsErrCd;
    +import cokr.xit.ens.core.utils.CmmnUtil;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.api.BillKkoPayApiSpec;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.BillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.QBillKkoPay;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.entity.repository.BillKkoPayRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model.KkoPayUrlRespData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillLogSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayUrlService;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayUrlData;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng;
    +import cokr.xit.ens.modules.common.domain.support.FieldError;
    +import com.google.gson.Gson;
    +import com.google.gson.GsonBuilder;
    +import com.google.gson.reflect.TypeToken;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.RequiredArgsConstructor;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.http.HttpStatus;
    +import org.springframework.http.ResponseEntity;
    +import org.springframework.stereotype.Service;
    +
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.Optional;
    +
    +@Slf4j
    +@RequiredArgsConstructor
    +@Service
    +public class KkoPayUrlService implements PayUrlService, String, PayApiRespDTO>> {
    +
    +    private final JPAQueryFactory query;
    +    private final BillKkoPayApiSpec billKkoPayApi;
    +    private final BillKkoPayRepository billKkoPayRepository;
    +    private final BillHistRepository billHistRepository;
    +    private final PayUseSysApi payUseSysApi;
    +
    +    private Gson gson = new GsonBuilder().disableHtmlEscaping().create();
    +
    +    private enum DataKeys {
    +        gnrUrlReqMessage,
    +        gnrUrlRespMessage,
    +        gnrReUrlReqMessage,
    +        gnrReUrlRespMessage,
    +    }
    +
    +    @Override
    +    public PayUrlData getData(String billUid) {
    +        if (billUid == null) billUid = "";
    +        Bill bill = query.selectFrom(QBill.bill)
    +                .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin()
    +                .where(QBill.bill.billUid.eq(billUid))
    +                .fetchOne();
    +        BillKkoPay billKkoPay = query.selectFrom(QBillKkoPay.billKkoPay)
    +                .where(QBillKkoPay.billKkoPay.billUid.eq(billUid))
    +                .fetchOne();
    +
    +        return PayUrlData.builder()
    +                .bill(bill)
    +                .billDetail(billKkoPay)
    +                .build();
    +    }
    +
    +    @Override
    +    public void validate(String billUid, PayUrlData data) {
    +       
    +        if (CmmnUtil.isEmpty(data.getBill()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다.");
    +        if (CmmnUtil.isEmpty(data.getBillDetail()))
    +            throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다.");
    +        if (!CmmnUtil.isEmpty(data.getBillDetail().getLastPayId()))
    +            throw new EnsException(EnsErrCd.PAYMENT_ALREADY_CMPLTED, "결제가 완료된 자료 입니다.");
    +        if (!CmmnUtil.isEmpty(data.getBillDetail().getUrl()))
    +            throw new EnsException(EnsErrCd.URL_ALREADY_CREATED, "결제URL이 생성된 자료 입니다.");
    +    }
    +
    +    @Override
    +    public void callApi(String billUid, PayUrlData data) {
    +        Bill bill = data.getBill();
    +        OrgMng orgMng = bill.getOrgMng();
    +
    +       
    +        final String useSysUrl = orgMng.getKkoBpUrlApi();
    +        final String billerCode = orgMng.getKkoBpBillerCode();
    +        final String authorization = orgMng.getKkoBpAuthorization();
    +
    +
    +       
    +        Optional.ofNullable(data.getBillDetail())
    +                .map(billKkoPay -> createMessage(billKkoPay.getBillerUserKey()))            
    +                .map(param -> loadReqData(data, useSysUrl, param))                   
    +                .map(param -> payUseSysApi.payUrl(useSysUrl, param, null))   
    +                .map(response -> loadRespData(data, response))                      
    +                .map(response -> checkResponse(response))                          
    +                .map(document -> savePayUrlInfo(data, document))                    
    +                .map(document -> createGnrUrlMessage(data, document))               
    +                .map(param -> loadGnrUrlReqData(data, param))                       
    +                .map(param -> billKkoPayApi.url(billerCode, authorization, param))  
    +                .map(response -> loadGnrUrlRespData(data, response))                
    +                .map(response -> checkGnrUrlResponse(false, response))       
    +                .map(respData -> saveUrl(data, respData))                           
    +                .filter(respData -> respData == null)                               
    +                .map(respData -> loadGnrReUrlReqData(data))                         
    +                .map(param -> billKkoPayApi.reUrl(billerCode, authorization, param))
    +                .map(response -> checkGnrUrlResponse(true, response))        
    +                .map(respData -> saveUrl(data, respData))                           
    +        ;
    +    }
    +
    +    private Map createMessage(String billerUserKey) {
    +        Map data = new HashMap<>();
    +        data.put("billerUserKey", billerUserKey);
    +        Map param = new HashMap<>();
    +        param.put("data", data);
    +        return param;
    +    }
    +
    +    private Map loadReqData(PayUrlData data, String url, Map param) {
    +        
    +        data.getReqAndRespInf().setUrl(url);
    +        data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param));
    +        return param;
    +    }
    +
    +    private ResponseEntity loadRespData(PayUrlData data, ResponseEntity response) {
    +        
    +        data.getReqAndRespInf().setRespRawData(response.getBody());
    +        return response;
    +    }
    +
    +
    +    private PayApiRespDTO checkResponse(ResponseEntity response) {
    +        
    +        if (!HttpStatus.OK.equals(response.getStatusCode()))
    +            throw new EnsException(EnsErrCd.API_COMM_ERROR, "["+ BillLogSeCd.US +"] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody());
    +        
    +        PayApiRespDTO result = null;
    +        try {
    +            result = gson.fromJson(response.getBody(), new TypeToken>() {
    +            }.getType());
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RESPONSE, "["+ BillLogSeCd.US +"] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex);
    +        }
    +        
    +        try {
    +            PayUseSysResCd.valueOf(result.getResCode());
    +        } catch (Exception ex) {
    +            throw new EnsException(EnsErrCd.INVALID_RES_CODE, "["+ BillLogSeCd.US +"] " + EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex);
    +        }
    +        if (!PayUseSysResCd.OK.getCode().equals(result.getResCode())) {
    +            result.setMessage("["+ BillLogSeCd.US +"] " + result.getMessage());
    +            throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result);
    +        }
    +
    +        return result;
    +    }
    +
    +    private PayApiRespDTO savePayUrlInfo(PayUrlData data, PayApiRespDTO document) {
    +        final KkoPayUrlRespData urlData = document.getData();
    +
    +        data.getBillDetail().setBilledYearMonth(urlData.getBilledYearMonth());
    +        data.getBillDetail().setOrdinal(urlData.getOrdinal());
    +        data.getBillDetail().setBillerNoticeKey(data.getBillDetail().getBillUid());
    +        data.getBillDetail().setExpireAt(urlData.getExpireAt());
    +        data.getBillDetail().setParameters(CmmnUtil.isEmpty(urlData.getParameters()) ? null : gson.toJson(urlData.getParameters()));
    +        data.getBillDetail().setCustomUrl(CmmnUtil.isEmpty(urlData.getCustomUrl()) ? null : gson.toJson(urlData.getCustomUrl()));
    +
    +        billKkoPayRepository.save(data.getBillDetail());
    +
    +        return document;
    +    }
    +
    +    private String createGnrUrlMessage(PayUrlData data, PayApiRespDTO document) {
    +        final OrgMng orgMng = data.getBill().getOrgMng();
    +        final BillKkoPay billKkoPay = data.getBillDetail();
    +        final KkoPayUrlRespData urlData = document.getData();
    +
    +        Map parameters = null;  
    +        parameters = CmmnUtil.isEmpty(urlData.getParameters()) ? new HashMap<>() : urlData.getParameters();
    +        parameters.put("orgCd", orgMng == null ? null : orgMng.getOrgCd());
    +
    +        Map param = new HashMap();
    +        param.put("biller_user_key", billKkoPay.getBillerUserKey());    //[필수] 기관에서 관리하는 해당 고객번호 혹은 계약번호
    +        param.put("billed_year_month", urlData.getBilledYearMonth());   //[선택] 청구 연월(YYYYMM) 형식, 없을 시 생략
    +        param.put("ordinal", urlData.getOrdinal());                     //[선택] 동일 고객번호, 청구 연월의 복수개 청구서 발생 등 몇번째 청구인지 구분
    +        param.put("biller_notice_key", billKkoPay.getBillerNoticeKey());//[선택] 개별 청구서를 식별하는 키 값. 처리 결과 조회에 사용되므로, 유니크한 값을 가지도록 생성
    +        param.put("expire_at", urlData.getExpireAt());                  //[필수] URL 만료일, YYYYMMDDHH24MISS
    +        param.put("parameters", parameters);                          //[선택] key/value 형태의 청구서 조회 등 API 호출 시 함께 전달할 값
    +//        param.put("parameters", urlData.getParameters());               //[선택] key/value 형태의 청구서 조회 등 API 호출 시 함께 전달할 값
    +        param.put("custom_url", urlData.getCustomUrl());                             //[선택] 사용자가 청구서 결제 시 호출(KKO -> 이용시스템)할 청구서조회/납부가능조회/납부결과전달 API URL
    +
    +
    +        Map m = new HashMap();
    +        m.put("data", param);
    +
    +        return gson.toJson(m);
    +    }
    +
    +    private String loadGnrUrlReqData(PayUrlData data, String message) {
    +        
    +        data.getReqAndRespInf().getEtc().put(DataKeys.gnrUrlReqMessage.name(), message);
    +
    +        return message;
    +    }
    +
    +    private ResponseEntity loadGnrUrlRespData(PayUrlData data, ResponseEntity response) {
    +        
    +        data.getReqAndRespInf().getEtc().put(DataKeys.gnrUrlRespMessage.name(), response.getBody());
    +        return response;
    +    }
    +
    +    private PayApiRespDTO> checkGnrUrlResponse(boolean isReurl, ResponseEntity response) {
    +        
    +        if (!HttpStatus.OK.equals(response.getStatusCode()))
    +            throw new EnsException(EnsErrCd.API_COMM_ERROR, "["+ BillLogSeCd.VD +"] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody());
    +        
    +        if (!isReurl && response.getBody().contains("Read timed out"))  
    +            return null;
    +        PayApiRespDTO> result = null;
    +        try {
    +            result = gson.fromJson(response.getBody(), new TypeToken>>() {
    +            }.getType());
    +        } catch (Exception ex) {
    +            if (isReurl)
    +                throw new EnsException(EnsErrCd.INVALID_RESPONSE, "["+ BillLogSeCd.VD +"] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex);
    +            else
    +                return null;    
    +        }
    +        
    +        if (!"OK".equals(result.getResCode()))
    +            if (!isReurl && "E818".equals(result.getResCode())) 
    +                return null;
    +            else {
    +                result.setMessage("["+ BillLogSeCd.VD +"] " + result.getMessage());
    +                throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result);
    +            }
    +
    +        return result;
    +    }
    +
    +    private PayApiRespDTO> saveUrl(PayUrlData data, PayApiRespDTO> respData) {
    +        if (!CmmnUtil.isEmpty(respData)) {
    +            Map body = respData.getData();
    +            data.getBillDetail().setUrl((String) body.get("url"));
    +            data.getBillDetail().setError(FieldError.initBuilder().build());
    +            billKkoPayRepository.save(data.getBillDetail());
    +        }
    +
    +        return respData;
    +    }
    +
    +    private String loadGnrReUrlReqData(PayUrlData data) {
    +        
    +        final String message = (String) data.getReqAndRespInf().getEtc().get(DataKeys.gnrReUrlReqMessage.name());
    +        data.getReqAndRespInf().getEtc().put(DataKeys.gnrReUrlReqMessage.name(), message);
    +
    +        return message;
    +    }
    +
    +    @Override
    +    public PayApiRespDTO> generateResult(String billUid, PayUrlData data, EnsException e) {
    +        if (e == null) {    
    +            final String urlResponse = (String) data.getReqAndRespInf().getEtc().get(DataKeys.gnrUrlRespMessage.name());
    +            final String reurlResponse = (String) data.getReqAndRespInf().getEtc().get(DataKeys.gnrReUrlRespMessage.name());
    +            if (CmmnUtil.isEmpty(reurlResponse))
    +                return gson.fromJson(urlResponse, new TypeToken>>() {
    +                }.getType());
    +            else
    +                return gson.fromJson(reurlResponse, new TypeToken>>() {
    +                }.getType());
    +        } else {   
    +            if (EnsErrCd.URL_ALREADY_CREATED.equals(e.getErrCd())) {
    +                Map m = new HashMap<>();
    +                m.put("url", data.getBillDetail().getUrl());
    +                return PayApiRespDTO.>okBuilder()
    +                        .data(m)
    +                        .build();
    +            } else if (EnsErrCd.RESPONSED_FAILURE_CODE.equals(e.getErrCd())) {
    +                PayApiRespDTO respDTO = (PayApiRespDTO) e.getData();
    +                return PayApiRespDTO.>errDataBuilder()
    +                        .resCode(respDTO.getResCode())
    +                        .message(respDTO.getMessage())
    +                        .data(null)
    +                        .build();
    +            } else {
    +                return PayApiRespDTO.>errDataBuilder()
    +                        .resCode(e.getErrCd().getCode())
    +                        .message(e.getMessage())
    +                        .data(null)
    +                        .build();
    +            }
    +        }
    +    }
    +
    +    @Override
    +//    @Transactional(propagation = Propagation.REQUIRED)
    +    public void saveHist(String billUid, PayUrlData data, EnsException e) {
    +        saveHistByGetUrlInf(data, e);   
    +        saveHistByGnrUrl(data, e);      
    +        saveHistByGnrReUrl(data, e);    
    +
    +        if (e != null) {    
    +            if (data.getBillDetail() != null) {
    +                data.getBillDetail().setError(FieldError.initBuilder()
    +                        .errorCode(e.getErrCd().getCode())
    +                        .errorMessage(e.getMessage())
    +                        .build());
    +                billKkoPayRepository.save(data.getBillDetail());
    +            }
    +        }
    +    }
    +
    +    private void saveHistByGetUrlInf(PayUrlData data, EnsException e) {
    +
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +        final String requestData = reqAndRespInf.getReqData();
    +        final String responseData = reqAndRespInf.getRespRawData();
    +
    +        if (!CmmnUtil.isEmpty(requestData)) {
    +            BillHist billHist = BillHist.builder()
    +                    .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                    .billSe(BillSeCd.bpKko)  
    +                    .reqSe(BillReqSeCd.US_URLINF)  
    +                    .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                    .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                    .requestData(requestData)
    +                    .responseData(responseData)
    +                    .error(e == null
    +                            ? FieldError.initBuilder().build()
    +                            : FieldError.initBuilder()
    +                            .errorCode(e.getErrCd().getCode())
    +                            .errorMessage(e.getMessage())
    +                            .build())
    +                    .build();
    +
    +            billHistRepository.save(billHist);
    +        }
    +
    +    }
    +
    +    private void saveHistByGnrUrl(PayUrlData data, EnsException e) {
    +
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +        final String requestData = (String) reqAndRespInf.getEtc().get(DataKeys.gnrUrlReqMessage.name());
    +        final String responseData = (String) reqAndRespInf.getEtc().get(DataKeys.gnrUrlRespMessage.name());
    +
    +        if (!CmmnUtil.isEmpty(requestData)) {
    +            BillHist billHist = BillHist.builder()
    +                    .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                    .billSe(BillSeCd.bpKko)  
    +                    .reqSe(BillReqSeCd.VD_URL)  
    +                    .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                    .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                    .requestData(requestData)
    +                    .responseData(responseData)
    +                    .error(e == null
    +                            ? FieldError.initBuilder().build()
    +                            : FieldError.initBuilder()
    +                            .errorCode(e.getErrCd().getCode())
    +                            .errorMessage(e.getMessage())
    +                            .build())
    +                    .build();
    +
    +            billHistRepository.save(billHist);
    +        }
    +
    +    }
    +
    +    private void saveHistByGnrReUrl(PayUrlData data, EnsException e) {
    +
    +        ReqAndRespInf reqAndRespInf = data.getReqAndRespInf();
    +        final String requestData = (String) reqAndRespInf.getEtc().get(DataKeys.gnrReUrlReqMessage.name());
    +        final String responseData = (String) reqAndRespInf.getEtc().get(DataKeys.gnrReUrlRespMessage.name());
    +
    +        if (!CmmnUtil.isEmpty(requestData)) {
    +            BillHist billHist = BillHist.builder()
    +                    .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid())
    +                    .billSe(BillSeCd.bpKko)  
    +                    .reqSe(BillReqSeCd.VD_REURL)  
    +                    .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng())
    +                    .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey())
    +                    .requestData(requestData)
    +                    .responseData(responseData)
    +                    .error(e == null
    +                            ? FieldError.initBuilder().build()
    +                            : FieldError.initBuilder()
    +                            .errorCode(e.getErrCd().getCode())
    +                            .errorMessage(e.getMessage())
    +                            .build())
    +                    .build();
    +
    +            billHistRepository.save(billHist);
    +
    +            if (e != null) {    
    +                if (data.getBillDetail() != null) {
    +                    data.getBillDetail().setError(FieldError.initBuilder()
    +                            .errorCode(e.getErrCd().getCode())
    +                            .errorMessage(e.getMessage())
    +                            .build());
    +                    billKkoPayRepository.save(data.getBillDetail());
    +                }
    +            }
    +        }
    +
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/config/CustomUrl.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/CustomUrl.java
    similarity index 94%
    rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/config/CustomUrl.java
    rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/CustomUrl.java
    index 2477d1e..25a7e47 100644
    --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/model/config/CustomUrl.java
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/CustomUrl.java
    @@ -1,4 +1,4 @@
    -package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.config;
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model;
     
     import com.fasterxml.jackson.annotation.JsonAlias;
     import com.fasterxml.jackson.annotation.JsonProperty;
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayBankAccounts.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayBankAccounts.java
    new file mode 100644
    index 0000000..02291c0
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayBankAccounts.java
    @@ -0,0 +1,43 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model;
    +
    +import com.fasterxml.jackson.annotation.JsonAlias;
    +import com.fasterxml.jackson.annotation.JsonProperty;
    +import com.google.gson.annotations.SerializedName;
    +import io.swagger.v3.oas.annotations.media.Schema;
    +import lombok.*;
    +
    +import javax.validation.constraints.NotBlank;
    +
    +/**
    + * 카카오페이 계좌송금수단 사용 시 계좌정보
    + */
    +@Builder
    +@NoArgsConstructor
    +@AllArgsConstructor
    +@Getter
    +@ToString
    +public class KkoPayBankAccounts {
    +
    +    @NotBlank(message = "청구서명은 필수 입력값 입니다.")
    +    @Schema(required = true, title = "청구서명", example = "테스트청구서")
    +    @JsonProperty("bank_code")  
    +    @JsonAlias({"bankCode"})
    +    @SerializedName(value = "bank_code", alternate = {"bankCode"})
    +    private String bankCode;
    +    @JsonProperty("account_no")  
    +    @JsonAlias({"accountNo"})
    +    @SerializedName(value = "account_no", alternate = {"accountNo"})
    +    private String accountNo;
    +    @JsonProperty("holder_name")  
    +    @JsonAlias({"holderName"})
    +    @SerializedName(value = "holder_name", alternate = {"holderName"})
    +    private String holderName;
    +    @JsonProperty("sender_name")  
    +    @JsonAlias({"senderName"})
    +    @SerializedName(value = "sender_name", alternate = {"senderName"})
    +    private String senderName;
    +    @JsonProperty("account_type")  
    +    @JsonAlias({"accountType"})
    +    @SerializedName(value = "account_type", alternate = {"accountType"})
    +    private String accountType;
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayNoticeRespData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayNoticeRespData.java
    new file mode 100644
    index 0000000..cddb301
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayNoticeRespData.java
    @@ -0,0 +1,68 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model;
    +
    +import com.fasterxml.jackson.annotation.JsonAlias;
    +import com.fasterxml.jackson.annotation.JsonProperty;
    +import com.google.gson.annotations.SerializedName;
    +import io.swagger.v3.oas.annotations.media.Schema;
    +import lombok.*;
    +import org.hibernate.validator.constraints.Length;
    +
    +import javax.validation.Valid;
    +import javax.validation.constraints.NotBlank;
    +import javax.validation.constraints.NotNull;
    +import java.util.List;
    +import java.util.Map;
    +
    +/**
    + * 카카오페이 결제정보 응답데이터
    + */
    +@Builder
    +@NoArgsConstructor
    +@AllArgsConstructor
    +@Getter
    +@ToString
    +public class KkoPayNoticeRespData {
    +
    +    @NotBlank(message = "청구서명은 필수 입력값 입니다.")
    +    @Schema(required = true, title = "청구서명", example = "테스트청구서")
    +    private String title;
    +    @NotNull(message = "납부 요청금액은 필수 입력값 입니다.")
    +    @Schema(required = true, title = "납부 요청금액", example = "1000")
    +    private Integer amount;
    +    @Schema(required = false, title = "비과세 금액", example = "0")
    +    @JsonProperty("tax_free_amount")  
    +    @JsonAlias({"taxFreeAmount"})
    +    @SerializedName(value = "tax_free_amount", alternate = {"taxFreeAmount"})
    +    private Integer taxFreeAmount;
    +    @Schema(required = false, title = "부가세 금액", example = "0")
    +    @JsonProperty("vat_amount")  
    +    @JsonAlias({"vatAmount"})
    +    @SerializedName(value = "vat_amount", alternate = {"vatAmount"})
    +    private Integer vatAmount;
    +    @Schema(required = false, title = "납기 안내타입", example = "D1")
    +    @JsonProperty("expire_type")  
    +    @JsonAlias({"expireType"})
    +    @SerializedName(value = "expire_type", alternate = {"expireType"})
    +    private String expireType;
    +    @NotNull(message = "첫번째 납기일은 필수 입력값 입니다.")
    +    @Length(max = 8, message = "첫번째 납기일의 최대 길이를 초과 했습니다.")
    +    @Schema(required = true, title = "첫번째 납기일", example = "20230212")
    +    @JsonProperty("pay_expire_date")  
    +    @JsonAlias({"payExpireDate"})
    +    @SerializedName(value = "pay_expire_date", alternate = {"payExpireDate"})
    +    private String payExpireDate;
    +    @Length(max = 8, message = "두번째 납기일의 최대 길이를 초과 했습니다.")
    +    @Schema(required = false, title = "두번째 납기일", example = "20230212")
    +    @JsonProperty("second_pay_expire_date")  
    +    @JsonAlias({"secondPayExpireDate"})
    +    @SerializedName(value = "second_pay_expire_date", alternate = {"secondPayExpireDate"})
    +    private String secondPayExpireDate;
    +    @Valid
    +    @Schema(required = false, title = "계좌송금수단 사용 시 계좌정보", example = " ")
    +    @JsonProperty("bank_accounts")  
    +    @JsonAlias({"bankAccounts"})
    +    @SerializedName(value = "bank_accounts", alternate = {"bankAccounts"})
    +    private List bankAccounts;
    +    @Schema(required = false, title = "청구서 상세정보", example = " ")
    +    private List> details;
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayResultReqData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayResultReqData.java
    new file mode 100644
    index 0000000..f814954
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayResultReqData.java
    @@ -0,0 +1,124 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model;
    +
    +import com.fasterxml.jackson.annotation.JsonAlias;
    +import com.fasterxml.jackson.annotation.JsonProperty;
    +import com.google.gson.annotations.SerializedName;
    +import io.swagger.v3.oas.annotations.media.Schema;
    +import lombok.EqualsAndHashCode;
    +import lombok.Getter;
    +import lombok.ToString;
    +import org.hibernate.validator.constraints.Length;
    +
    +import javax.validation.constraints.NotBlank;
    +import javax.validation.constraints.NotNull;
    +import javax.validation.constraints.Pattern;
    +import java.util.Map;
    +
    +@Getter
    +@ToString
    +@EqualsAndHashCode
    +@Schema(name = "KkoPayResultReqData")
    +public class KkoPayResultReqData {
    +
    +    @Length(max = 50, message = "사용자 식별키의 최대 길이를 초과 했습니다.")
    +    @NotBlank( message = "사용자 식별키는 필수 조건 입니다.")
    +    @Schema(required = true, title = "사용자 식별키", example = " ")
    +    @JsonProperty("biller_user_key")  
    +    @JsonAlias({"billerUserKey"})
    +    @SerializedName(value = "biller_user_key", alternate = {"billerUserKey"})
    +    private String billerUserKey;
    +    @Length(max = 6, message = "청구연월의 최대 길이를 초과 했습니다.")
    +    @Schema(required = false, title = "청구연월(YYYYMM 형식), 없을 시 생략", example = " ")
    +    @JsonProperty("billed_year_month")  
    +    @JsonAlias({"billedYearMonth"})
    +    @SerializedName(value = "billed_year_month", alternate = {"billedYearMonth"})
    +    private String billedYearMonth;
    +    @Length(max = 24, message = "동일 고객번호의 최대 길이를 초과 했습니다.")
    +    @Schema(required = false, title = "동일 고객번호, 청구 연월의 복수 개 청구서 발생 등 몇 번째 청구인지 구분을 위해 사용", example = " ")
    +    private String ordinal;
    +    @Length(max = 80, message = "개별 청구서 식별키의 최대 길이를 초과 했습니다.")
    +    @Schema(required = false, title = "개별 청구서를 식별하는 키 값", example = " ")
    +    @JsonProperty("biller_notice_key")  
    +    @JsonAlias({"billerNoticeKey"})
    +    @SerializedName(value = "biller_notice_key", alternate = {"billerNoticeKey"})
    +    private String billerNoticeKey;
    +    @Schema(required = false, title = "URL 생성 시 전달한 파라미터", example = " ")
    +    private Map parameters;
    +    @NotBlank(message = "결제수단은 필수 조건 입니다.")
    +    @Schema(required = true, title = "결제수단(CARD/MONEY/MONEY_TRANSFER)", example = " ")
    +    @JsonProperty("pay_by")  
    +    @JsonAlias({"payBy"})
    +    @SerializedName(value = "pay_by", alternate = {"payBy"})
    +    private String payBy;
    +    @NotBlank(message = "결제타입은 필수 조건 입니다.")
    +    @Length(max = 1, message = "결제타입의 최대길이를 초과 했습니다.")
    +    @Pattern(regexp = "(P|C)", message = "결제타입의 값은 P 또는 C 만 입력 하실 수 있습니다.")
    +    @Schema(required = true, title = "결제타입(P:결제, C:취소)", example = " ")
    +    @JsonProperty("pay_type")  
    +    @JsonAlias({"payType"})
    +    @SerializedName(value = "pay_type", alternate = {"payType"})
    +    private String payType;
    +    @Length(max = 6, message = "결제수단 상세1의 최대길이를 초과 했습니다.")
    +    @Schema(required = false, title = "결제수단 상세1(카드번호 앞 6자리). 카드인 경우 카드번호 앞 6자리", example = " ")
    +    @JsonProperty("pay_detail1")  
    +    @JsonAlias({"payDetail1"})
    +    @SerializedName(value = "pay_detail1", alternate = {"payDetail1"})
    +    private String payDetail1;
    +    @Length(max = 20, message = "결제수단 상세2(카드사 구분 코드)의 최대길이를 초과 했습니다.")
    +    @Schema(required = false, title = "결제수단 상세2. 카드사 구분 코드", example = " ")
    +    @JsonProperty("pay_detail2")  
    +    @JsonAlias({"payDetail2"})
    +    @SerializedName(value = "pay_detail2", alternate = {"payDetail2"})
    +    private String payDetail2;
    +    @Schema(required = false, title = "결제수단 상세3. 공백", example = " ")
    +    @JsonProperty("pay_detail3")  
    +    @JsonAlias({"payDetail3"})
    +    @SerializedName(value = "pay_detail3", alternate = {"payDetail3"})
    +    private String payDetail3;
    +    @NotNull(message = "납부요청 금액은 필수 조건 입니다.")
    +    @Schema(required = true, title = "납부요청 금액", example = " ")
    +    private Integer amount;
    +    @NotNull(message = "결제금액/취소금액은 필수 조건 입니다.")
    +    @Schema(required = true, title = "거래구분이 P 인 경우 양수(결제금액), C 인 경우 음수(-취소금액)", example = " ")
    +    @JsonProperty("pay_amount")  
    +    @JsonAlias({"payAmount"})
    +    @SerializedName(value = "pay_amount", alternate = {"payAmount"})
    +    private Integer payAmount;
    +    @Length(max = 10, message = "결제 수수료 부과구분은 필수 조건 입니다.")
    +    @Schema(required = true, title = "결제 수수료 금액 부과구분(BEFORE: 선취, AFTER: 후취, NONE: 부과 안함)", example = " ")
    +    @JsonProperty("pay_fee_type")  
    +    @JsonAlias({"payFeeType"})
    +    @SerializedName(value = "pay_fee_type", alternate = {"payFeeType"})
    +    private String payFeeType;
    +    @NotNull(message = "결제 수수료 공급가액은 필수 조건 입니다.")
    +    @Schema(required = true, title = "결제 수수료 금액_공급가액", example = " ")
    +    @JsonProperty("pay_fee")  
    +    @JsonAlias({"payFee"})
    +    @SerializedName(value = "pay_fee", alternate = {"payFee"})
    +    private Integer payFee;
    +    @NotNull(message = "결제 수수료 부가세는 필수 조건 입니다.")
    +    @Schema(required = true, title = "결제 수수료 금액_부가세", example = " ")
    +    @JsonProperty("pay_fee_tax")  
    +    @JsonAlias({"payFeeTax"})
    +    @SerializedName(value = "pay_fee_tax", alternate = {"payFeeTax"})
    +    private Integer payFeeTax;
    +    @Length(max = 8, message = "정산예정일의 최대 길이를 초과 했습니다.")
    +    @Schema(required = false, title = "정산예정일(YYYYMMDD)", example = " ")
    +    @JsonProperty("adjust_date")  
    +    @JsonAlias({"adjustDate"})
    +    @SerializedName(value = "adjust_date", alternate = {"adjustDate"})
    +    private String adjustDate;
    +    @NotBlank(message = "결제일시는 필수 조건 입니다.")
    +    @Length(max = 8, message = "결제일시의 최대 길이를 초과 했습니다.")
    +    @Schema(required = true, title = "결제일시(YYYYMMDDHH24MISS)", example = " ")
    +    @JsonProperty("paid_at")  
    +    @JsonAlias({"paidAt"})
    +    @SerializedName(value = "paid_at", alternate = {"paidAt"})
    +    private String paidAt;
    +    @NotNull(message = "카카오페이 결제번호는 필수 조건 입니다.")
    +    @Schema(required = true, title = "카카오페이 결제번호", example = " ")
    +    @JsonProperty("pay_id")  
    +    @JsonAlias({"payId"})
    +    @SerializedName(value = "pay_id", alternate = {"payId"})
    +    private Integer payId;
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayUrlRespData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayUrlRespData.java
    new file mode 100644
    index 0000000..9d4d4c3
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/process/model/KkoPayUrlRespData.java
    @@ -0,0 +1,46 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.process.model;
    +
    +import com.fasterxml.jackson.annotation.JsonAlias;
    +import com.fasterxml.jackson.annotation.JsonProperty;
    +import com.google.gson.annotations.SerializedName;
    +import io.swagger.v3.oas.annotations.media.Schema;
    +import lombok.*;
    +
    +import javax.validation.Valid;
    +import javax.validation.constraints.NotBlank;
    +import java.util.Map;
    +
    +/**
    + * 카카오페이 결제정보 응답데이터
    + */
    +@Builder
    +@NoArgsConstructor
    +@AllArgsConstructor
    +@Getter
    +@ToString
    +public class KkoPayUrlRespData {
    +    @Schema(required = false, title = "청구 연월", example = " ")
    +    @JsonProperty("billed_year_month")  
    +    @JsonAlias({"billedYearMonth"})
    +    @SerializedName(value = "billed_year_month", alternate = {"billedYearMonth"})
    +    private String billedYearMonth;
    +
    +    @Schema(required = false, title = "동일 고객번호 구분 값", example = " ")
    +    private String ordinal;
    +
    +    @NotBlank(message = "URL 만료일은 필수 조건 입니다.")
    +    @Schema(required = true, title = "URL 만료일", example = "20200130235959")
    +    @JsonProperty("expire_at")  
    +    @JsonAlias({"expireAt"})
    +    @SerializedName(value = "expire_at", alternate = {"expireAt"})
    +    private String expireAt;
    +
    +    @Schema(required = false, title = "API 호출 시 함께 전달할 JSON형태의 문자열", example = " ")
    +    private Map parameters;
    +
    +    @Valid
    +    @JsonProperty("expire at")  
    +    @JsonAlias({"customUrl"})
    +    @SerializedName(value = "custom_url", alternate = {"customUrl"})
    +    private CustomUrl customUrl;
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/repair/kit/RepairKkoPayResultTransferFail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/repair/kit/RepairKkoPayResultTransferFail.java
    new file mode 100644
    index 0000000..f29ec3e
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/kko/service/repair/kit/RepairKkoPayResultTransferFail.java
    @@ -0,0 +1,27 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.service.repair.kit;
    +
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.kit.RepairPayResultTransferFail;
    +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO;
    +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
    +import com.querydsl.jpa.impl.JPAQueryFactory;
    +import lombok.Builder;
    +
    +
    +public class RepairKkoPayResultTransferFail extends RepairPayResultTransferFail {
    +    @Builder
    +    public RepairKkoPayResultTransferFail(JPAQueryFactory query, RepairPayRsltFwdFailSearchDTO searchDTO) {
    +        this.query = query;
    +        this.searchDTO = searchDTO;
    +    }
    +
    +    @Override
    +    protected String getPayResultApiUrl(OrgMng orgMng) {
    +        return orgMng.getKkoBpPayresultApi();
    +    }
    +
    +    @Override
    +    protected BillSeCd getBillSeCd() {
    +        return BillSeCd.bpKko;
    +    }
    +}
    diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApi.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApi.java
    new file mode 100644
    index 0000000..d11c6bd
    --- /dev/null
    +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApi.java
    @@ -0,0 +1,265 @@
    +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.api;
    +
    +import cokr.xit.ens.core.utils.CmmnUtil;
    +import lombok.extern.slf4j.Slf4j;
    +import org.springframework.beans.factory.annotation.Value;
    +import org.springframework.http.*;
    +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    +import org.springframework.stereotype.Component;
    +import org.springframework.util.LinkedMultiValueMap;
    +import org.springframework.util.MultiValueMap;
    +import org.springframework.web.client.HttpClientErrorException;
    +import org.springframework.web.client.HttpServerErrorException;
    +import org.springframework.web.client.RestClientException;
    +import org.springframework.web.client.RestTemplate;
    +import org.springframework.web.util.UriComponents;
    +import org.springframework.web.util.UriComponentsBuilder;
    +
    +import java.net.URI;
    +import java.nio.charset.Charset;
    +import java.nio.charset.StandardCharsets;
    +import java.util.ArrayList;
    +import java.util.HashMap;
    +import java.util.List;
    +import java.util.Map;
    +
    +@Slf4j
    +@Component
    +//@Profile({"!local-test"})
    +public class BillNvEasyPayApi implements BillNvEasyPayApiSpec {
    +
    +    @Value("${contract.naver.pay.easy.host}")
    +    private String HOST;
    +    @Value("${contract.naver.pay.easy.api.pay-apply}")
    +    private String API_PAY_APPLY;
    +    @Value("${contract.naver.pay.easy.api.pay-cancel}")
    +    private String API_PAY_CANCEL;
    +    @Value("${contract.naver.pay.easy.api.pay-hist}")
    +    private String API_PAY_HIST;
    +    @Value("${contract.naver.pay.easy.api.purchase-confirm}")
    +    private String API_PURCHASE_CONFIRM;
    +    @Value("${contract.naver.pay.easy.api.point-save}")
    +    private String API_POINT_SAVE;
    +    @Value("${contract.naver.pay.easy.api.cash-amount}")
    +    private String API_CASH_AMOUNT;
    +
    +
    +    /**
    +     * 
    메소드 설명: API 호출
    +     * 
    + * + * @param method + * @param url + * @param body + * @param headers + * @return ResponseEntity 요청처리 후 응답객체 + * @author: 박민규 + * @date: 2021. 8. 4. + * @apiNote: 사이트 참조 https://e2e2e2.tistory.com/15 + */ + private ResponseEntity callApi(HttpMethod method, String url, Object body, HttpHeaders headers) { + + StringBuffer sb = new StringBuffer(); + ResponseEntity responseEntity = null; + try { + + HttpEntity entity = null; + UriComponents uri = null; + switch (method) { + case GET: + entity = new HttpEntity<>(headers); + uri = UriComponentsBuilder + .fromHttpUrl(String.format("%s?%s", url, body == null ? "" : body)) +// .encode(StandardCharsets.UTF_8) //"%"기호가 "%25"로 인코딩 발생하여 주석처리 함. + .build(false); + break; + case POST: + entity = new HttpEntity<>(body, headers); + uri = UriComponentsBuilder + .fromHttpUrl(url) + .encode(StandardCharsets.UTF_8) + .build(); + break; + + default: + break; + } + + + + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); + factory.setConnectTimeout(5000); + factory.setReadTimeout(60000); + RestTemplate restTemplate = new RestTemplate(factory); + sb.append("\n url => " + uri.toString()) + .append("\n method => " + method) + .append("\n headers => " + entity.getHeaders().toString()) + .append("\n body => " + entity.getBody()); + responseEntity = restTemplate.exchange(URI.create(uri.toString()), method, entity, String.class); + + /* + * HttpStatus 정보 확인 방법 + * -.코드: responseEntity.getStatusCodeValue() + * -.메시지: responseEntity.getStatusCode() + */ + + } catch (HttpServerErrorException e) { + responseEntity = new ResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); + log.error("call API 서버오류\n[ url ]: {} \n[ param ]: {} \n[ error ]: {}", url, body, CmmnUtil.printStackTraceToString(e)); + } catch (HttpClientErrorException e) { + responseEntity = new ResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); + log.error("call API 클라이언트오류\n[ url ]: {} \n[ param ]: {} \n[ error ]: {}", url, body, CmmnUtil.printStackTraceToString(e)); + } catch (RestClientException e) { + responseEntity = new ResponseEntity(e.getMessage(), HttpStatus.REQUEST_TIMEOUT); + log.error("RestAPI 호출 오류\n[ url ]: {} \n[ param ]: {} \n[ error ]: {}", url, body, CmmnUtil.printStackTraceToString(e)); + } catch (Exception e) { + responseEntity = new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + log.error("call API 기타오류\n[ url ]: {} \n[ param ]: {} \n[ error ]: {}", url, body, CmmnUtil.printStackTraceToString(e)); + } finally { + log.info("네이버페이 간편결제 API\n[ REQUEST ]-----------------------------------------------------------------------\n{}\n[ RESPONSE ]-----------------------------------------------------------------------\n{}", sb.toString(), responseEntity.getBody()); + } + + + return responseEntity; + } + + + @Override + public ResponseEntity payApply(String partnerId, String clientId, String clientSecret, LinkedMultiValueMap param) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_FORM_URLENCODED, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_PAY_APPLY.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + MultiValueMap body = param; + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), body, headers); + return resp; + } + + @Override + public ResponseEntity payCancel(String partnerId, String clientId, String clientSecret, LinkedMultiValueMap param) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_FORM_URLENCODED, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_PAY_CANCEL.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + MultiValueMap body = param; + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), body, headers); + return resp; + } + + @Override + public ResponseEntity payHist(String partnerId, String clientId, String clientSecret, Map param) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_PAY_HIST.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + String jsonStr = CmmnUtil.toJsonString(param); + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers); + return resp; + } + + @Override + public ResponseEntity purchaseConfirm(String partnerId, String clientId, String clientSecret, String paymentId, String requester) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_FORM_URLENCODED, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_PURCHASE_CONFIRM.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + MultiValueMap param = new LinkedMultiValueMap<>(); + param.add("paymentId", paymentId); + param.add("requester", requester); + MultiValueMap body = param; + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), body, headers); + return resp; + } + + @Override + public ResponseEntity pointSave(String partnerId, String clientId, String clientSecret, String paymentId) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_FORM_URLENCODED, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_POINT_SAVE.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + MultiValueMap param = new LinkedMultiValueMap<>(); + param.add("paymentId", paymentId); + MultiValueMap body = param; + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), body, headers); + return resp; + } + + @Override + public ResponseEntity cashAmount(String partnerId, String clientId, String clientSecret, ArrayList paymentIds) { + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + headers.set("X-Naver-Client-Id", clientId); + headers.set("X-Naver-Client-Secret", clientSecret); + headers.set("X-Xit-PartnerId", partnerId); + + + StringBuilder url = new StringBuilder() + .append(this.HOST) + .append(this.API_POINT_SAVE.replace("{partnerId}", partnerId == null ? "" : partnerId)); + + + Map> param = new HashMap<>(); + param.put("paymentIds", paymentIds); + String jsonStr = CmmnUtil.toJsonString(param); + + + ResponseEntity resp = this.callApi(HttpMethod.POST, url.toString(), jsonStr, headers); + return resp; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApiSpec.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApiSpec.java new file mode 100644 index 0000000..c3d63fc --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/api/BillNvEasyPayApiSpec.java @@ -0,0 +1,80 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.api; + +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; + +import java.util.ArrayList; +import java.util.Map; + +/** + * 네이버페이 간편결제 API + */ +public interface BillNvEasyPayApiSpec { + /** + * 결제 승인 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param param 요청파라미터 + * @return + */ + ResponseEntity payApply(String partnerId, String clientId, String clientSecret, LinkedMultiValueMap param); + + /** + * 결제취소 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param param 요청파라미터 + * @return + */ + ResponseEntity payCancel(String partnerId, String clientId, String clientSecret, LinkedMultiValueMap param); + + /** + * 결제내역조회 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param param 요청파라미터 + * @return + */ + ResponseEntity payHist(String partnerId, String clientId, String clientSecret, Map param); + + + /** + * 거래완료 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param paymentId 네이버페이 결제번호 + * @param requester 요청자(1:구매자, 2:가맹점 관리자). 구분이 애매한 경우 가맹점 관리자로 입력합니다. + * @return + */ + ResponseEntity purchaseConfirm(String partnerId, String clientId, String clientSecret, String paymentId, String requester); + + /** + * 포인트 적립 요청 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param paymentId 네이버페이 결제번호 + * @return + */ + ResponseEntity pointSave(String partnerId, String clientId, String clientSecret, String paymentId); + + /** + * 현금영수증 발행대상 금액조회 + * + * @param partnerId 파트너 ID + * @param clientId 발급된 client id + * @param clientSecret 발급된 client secret + * @param paymentIds 네이버페이 결제번호 목록 + * @return + */ + ResponseEntity cashAmount(String partnerId, String clientId, String clientSecret, ArrayList paymentIds); +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpBankCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpBankCd.java new file mode 100644 index 0000000..a46b3f6 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpBankCd.java @@ -0,0 +1,90 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.code; + +import cokr.xit.ens.core.code.CodeMapperType; +import lombok.Getter; + + +/** + *
      + *
    • 업무 그룹명: 네이버페이 간편결제API - 지원은행코드
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 07. 오후 1:57:43 + *
    + * + * @author 박민규 + */ + +public enum NvEpBankCd implements CodeMapperType { + B002("산업은행"), + B003("기업은행"), + B004("국민은행"), + B005("외환은행"), + B007("수협"), + B011("농협"), + B012("지역농축협"), + B020("우리은행"), + B023("SC제일은행"), + B027("씨티은행"), + B031("대구은행"), + B032("부산은행"), + B034("광주은행"), + B035("제주은행"), + B037("전북은행"), + B039("경남은행"), + B045("새마을금고"), + B048("신협"), + B050("저축은행"), + B071("우체국"), + B081("하나은행"), + B088("신한은행"), + B089("케이뱅크"), + B090("카카오뱅크"), + B092("토스뱅크"), + B102("대신저축은행"), + B103("에스비아이저축은행"), + B104("에이치케이저축은행"), + B105("웰컴저축은행"), + B106("신한저축은행"), + B209("유안타증권"), + B218("KB증권"), + B221("상상인증권"), + B222("한양증권"), + B223("리딩투자증권"), + B224("BNK투자증권"), + B225("IBK투자증권"), + B227("다올투자증권"), + B238("미래에셋"), + B240("삼성증권"), + B243("한국투자증권"), + B247("NH투자증권"), + B261("교보증권"), + B262("하이투자증권"), + B263("현대차증권"), + B264("키움증권"), + B265("이베스트투자증권"), + B266("SK증권"), + B267("대신증권"), + B269("한화증권"), + B270("하나금융투자"), + B278("신한금융투자"), + B279("DB금융투자"), + B280("유진투자증권"), + B287("메리츠증권"), + B288("카카오페이증권"), + B290("부국증권"), + B291("신영증권"), + B292("케이프투자증권"), + B293("한국증권금융"), + B294("한국포스증권"), + B295("우리종합금융"), + ; + @Getter + private String code; + @Getter + private String codeNm; + + NvEpBankCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpCardCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpCardCd.java new file mode 100644 index 0000000..6344d04 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/code/NvEpCardCd.java @@ -0,0 +1,44 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.code; + +import cokr.xit.ens.core.code.CodeMapperType; +import lombok.Getter; + + +/** + *
      + *
    • 업무 그룹명: 네이버페이 간편결제API - 지원카드코드
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 07. 오후 1:57:43 + *
    + * + * @author 박민규 + */ + +public enum NvEpCardCd implements CodeMapperType { + C0("신한"), + C1("비씨"), + C2("광주"), + C3("KB국민"), + C4("NH"), + C5("롯데"), + C6("산업"), + C7("삼성"), + C8("수협"), + C9("씨티"), + CA("외환"), + CB("우리"), + CC("전북"), + CD("제주"), + CF("하나-외환"), + CH("현대"), + ; + @Getter + private String code; + @Getter + private String codeNm; + + NvEpCardCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/BillNvEasyPay.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/BillNvEasyPay.java new file mode 100644 index 0000000..014d166 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/BillNvEasyPay.java @@ -0,0 +1,83 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillBaseEntity; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; + +@Entity +@Getter +@ToString +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "ens_bill_nv_ep", schema = "", catalog = "") +@Schema(name = "BillNvEasyPay") +public class BillNvEasyPay extends BillBaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "BillNv_Generator") + @TableGenerator(table = "ens_seq_generator", name = "BillNv_Generator" + , pkColumnName = "seq_name", pkColumnValue = "BillNv_id" + , initialValue = 0, allocationSize = 200) + @Schema(required = true, title = "PK", example = " ") + private Long billId; + + + @Schema(required = true, title = "결제 타입", example = "normal") + @Column(name = "pay_type", nullable = false, length = 10) + private String payType; + + @Schema(required = true, title = "결제창 Open 타입", example = "page") + @Column(name = "open_type", nullable = false, length = 10) + private String openType; + + /* ===================================== + * 결제진행 - PayNotice 단계 + ===================================== */ + @Schema(required = false, title = "상품명", example = "테스트상품") + @Column(name = "product_name", nullable = true, length = 128) + @Setter + private String productName; + @Schema(required = false, title = "총 결제 금액", example = "1000") + @Column(name = "total_pay_amount", nullable = true) + @Setter + private Integer totalPayAmount; + @Schema(required = false, title = "과세 대상 금액", example = "1000") + @Column(name = "tax_scope_amount", nullable = true) + @Setter + private Integer taxScopeAmount; + @Schema(required = false, title = "면세 대상 금액", example = "0") + @Column(name = "tax_ex_scope_amount", nullable = true) + @Setter + private Integer taxExScopeAmount; + @Schema(required = false, title = "컵 보증금 대상 금액", example = "0") + @Column(name = "environment_deposit_amount", nullable = true) + @Setter + private Integer environmentDepositAmount; + @Lob + @Schema(required = false, title = "상품 목록", example = " ") + @Column(name = "product_items", nullable = true) + private String productItems; + @Schema(required = false, title = "리턴URL(이용자 결제완료 후 네이버측에서 승인 하기전 오인결제,이중결제 등을 예방하기 위해 가맹점 검증을 위한 가맹점URL)", example = " ") + @Column(name = "return_url", nullable = true, length = 1000) + @Setter + private String returnUrl; + @Schema(required = false, title = "결제번호", example = "20170201NP1043587746") + @Column(name = "last_payment_id", nullable = true, length = 100) + @Setter + private String lastPaymentId; + @Schema(required = false, title = "결제취소번호", example = "20230208NP1041112193") + @Column(name = "last_pay_hist_id", nullable = true, length = 100) + @Setter + private String lastPayHistId; + @Schema(required = false, title = "취소 결제번호", example = "20170201NP1043587746") + @Column(name = "last_cancel_payment_id", nullable = true, length = 100) + @Setter + private String lastCancelPaymentId; + @Embedded + @Setter + private FieldError error; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/repository/BillNvEasyPayRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/repository/BillNvEasyPayRepository.java new file mode 100644 index 0000000..0c86642 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/entity/repository/BillNvEasyPayRepository.java @@ -0,0 +1,9 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BillNvEasyPayRepository extends JpaRepository { + + +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/model/BillNvAcptReqVO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/model/BillNvAcptReqVO.java new file mode 100644 index 0000000..3f12337 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/model/BillNvAcptReqVO.java @@ -0,0 +1,57 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotEmpty; + +@Builder +@Getter +@Schema(name = "BillNvAcptReqVO") +public class BillNvAcptReqVO { + + @Length(max = 45, message = "청구서 유니크 아이디의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "청구서 유니크 아이디", example = " ") + @JsonProperty("billUid") + @JsonAlias({"bill_uid"}) + @SerializedName(value = "billUid", alternate = "bill_uid") + @Setter + private String billUid; + + @NotEmpty(message = "계약번호는 필수 입력값 입니다.") + @Length(max = 40, message = "계약번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ") + @JsonProperty("billerUserKey") + @JsonAlias({"biller_user_key"}) + @SerializedName(value = "billerUserKey", alternate = "biller_user_key") + private String billerUserKey; + + +// @Pattern(regexp = "(normal|recurrent)", message = "결제타입은 normal(default) 또는 recurrent 만 입력 할 수 있습니다.") +// @Length(max = 10, message = "결제 타입의 최대 길이를 초과 했습니다.") +// @Schema(required = true, title = "결제 타입", example = "normal") +// @JsonAlias({"pay_type"}) +// private String payType; +// +// @Pattern(regexp = "(page|popup)", message = "결제창 Open 타입은 page(default) 또는 popup 만 입력 할 수 있습니다.") +// @Length(max = 10, message = "결제창 Open 타입의 최대 길이를 초과 했습니다.") +// @Schema(required = true, title = "결제창 Open 타입", example = "page") +// @JsonAlias({"open_type"}) +// private String openType; +// @NotBlank(message = "리턴URL는 필수조건 입니다.") +// @Length(max = 1000, message = "리턴URL의 최대 길이를 초과 했습니다.") +// @Schema(required = true, title = "네이버페이 결제 후 리턴URL", example = " ") +// @JsonProperty("returnUrl") +// @JsonAlias({"return_url"}) +// @SerializedName(value = "returnUrl", alternate = "return_url") +// private String returnUrl; +// @Schema(required = false, title = "상품 목록", example = " ") +// @JsonAlias({"product_items"}) +// private List> productItems; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayProcessController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayProcessController.java new file mode 100644 index 0000000..3e4c248 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayProcessController.java @@ -0,0 +1,96 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.presentation; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.NvPayProcessService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.PayController; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; + +@Tag(name = "NvPayProcessController") +@Slf4j +@RequiredArgsConstructor +@RestController +public class NvPayProcessController implements PayController, Map> { + + private final NvPayProcessService nvPayProcessService; + + + @Operation(summary = "청구서링크 생성") + @PostMapping(value = "/bill/nv/ep/gnrurl", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity gnrUrl(Map param) { + return new ResponseEntity(nvPayProcessService.gnrUrl(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "결제정보 요청" + , value = "{\"billUid\":\"청구서UID\"}") + }) + }) + @Operation(summary = "납부(결제)정보 요청") + @PostMapping(value = "/bill/nv/ep/notice", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity payNotice(@RequestBody Map param) { + return new ResponseEntity(nvPayProcessService.payNotice(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Success Example..." + , summary = "납부(결제)가능여부 확인" + , value = "{\"billUid\":\"청구서UID\",\"resultCode\":\"Success\",\"paymentId\":\"네이버페이 결제번호\"}"), + @ExampleObject(name = "Fail Example..." + , summary = "납부(결제)가능여부 확인" + , value = "{\"billUid\":\"청구서UID\",\"resultCode\":\"TimeExpired\",\"resultMessage\":\"결제 시간 초과(reserveId 생성 후 30분을 초과한 경우)\",\"reserveId\":\"결제예약ID\"}") + }) + }) + @Operation(summary = "납부(결제)가능여부 확인") + @PostMapping(value = "/bill/nv/ep/able", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity payAble(@RequestBody Map param) { + return new ResponseEntity(nvPayProcessService.payAble(param), HttpStatus.OK); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "결과전달" + , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"paymentId\":\"네이버페이 결제번호\",\"detail\":{\"productName\":\"샘플상품\",\"merchantId\":\"loginId\",\"merchantName\":\"가맹점명\",\"cardNo\":\"465887**********\",\"admissionYmdt\":\"20170201151722\",\"payHistId\":\"20170201NP1043587781\",\"totalPayAmount\":1000,\"primaryPayAmount\":1000,\"npointPayAmount\":0,\"giftCardAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"primaryPayMeans\":\"CARD\",\"merchantPayKey\":\"청구서UID\",\"merchantUserKey\":\"빌러유저키\",\"cardCorpCode\":\"C0\",\"paymentId\":\"20170201NP1043587746\",\"admissionTypeCode\":\"01\",\"settleExpectAmount\":971,\"payCommissionAmount\":29,\"admissionState\":\"SUCCESS\",\"tradeConfirmYmdt\":\"20170201152510\",\"cardAuthNo\":\"17545616\",\"cardInstCount\":0,\"usedCardPoint\":false,\"bankCorpCode\":\"\",\"bankAccountNo\":\"\",\"settleExpected\":false,\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}}}") + }) + }) + @Operation(summary = "납부(결제)결과 전달") + @PostMapping(value = "/bill/nv/ep/result", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity payResult(@RequestBody Map param) { + return new ResponseEntity(nvPayProcessService.payResult(param), HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "결제취소" + , value = "{\"billUid\":\"청구서UID\",\"cancelReason\":\"결제취소 테스트\",\"cancelRequester\":\"2\"}") + }) + }) + @Operation(summary = "결제취소") + @PostMapping(value = "/bill/nv/ep/cancel", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity payCancel(@RequestBody Map param) { + return new ResponseEntity(nvPayProcessService.payCancel(param), HttpStatus.OK); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayUseSysSampleController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayUseSysSampleController.java new file mode 100644 index 0000000..9ca4cbb --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPayUseSysSampleController.java @@ -0,0 +1,216 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.presentation; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyIdCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayAbleReqData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.notice.ProductItem; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.PayUseSysController; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.bytebuddy.utility.RandomString; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Tag(name = "NvPayUseSysSampleController") +@Slf4j +@RequiredArgsConstructor +@RestController +public class NvPayUseSysSampleController implements PayUseSysController> { + + @Value("${contract.naver.pay.easy.api.validate.host}") + private String BILL_HOST; + @Value("${contract.naver.pay.easy.api.validate.prepay}") + private String BILL_PAYABLE_URL; + + private Gson gson = new Gson(); + + + // @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { +// @Content(mediaType = "application/json", examples = { +// @ExampleObject(name = "Sample Example..." +// , summary = "청구서링크생성 정보" +// , value = "{}") +// }) +// }) + @Operation(summary = "청구서링크생성 정보 샘플") + @PostMapping(value = "/bill/nv/ep/sample/gnrUrl", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity gnrUrl(Map param) { + throw new EnsException(EnsErrCd.SERVICE_NOT_SUPPORTED, EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm()); + } + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "납부(결제)정보" + , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\"}}") + }) + }) + @Operation(summary = "납부(결제)정보 샘플") + @PostMapping(value = "/bill/nv/ep/sample/paynotice", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity> payNotice(@RequestBody Map param) { + log.info("[Request Data] {}", param.toString()); + Map reqData = (Map) param.getOrDefault("data", new HashMap<>()); + + + + /* ============================================ + * [정상 응답코드] + * OK + * [실패 응답코드] + * NOT_FOUND_PAYDATA + * PAYDATA_FIND_FAILED + ============================================ */ + PayUseSysResCd resCd = PayUseSysResCd.OK; + + + final String productName = "테스트 상품 - " + RandomString.make(7); + final int taxScopeAmount = 100; + final int taxExScopeAmount = 0; + final Integer environmentDepositAmount = null; + final int totalPayAmount = taxScopeAmount + taxExScopeAmount + (environmentDepositAmount == null ? 0 : environmentDepositAmount); + final List productItemList = Arrays.asList(ProductItem.builder() + .categoryType(NvEpCtgyTypeCd.ETC) + .categoryId(NvEpCtgyIdCd.ETC_ETC.getCode()) + .uid((String) reqData.get("billerUserKey")) + .name(productName) + .payReferrer(null) + .startDate(null) + .endDate(null) + .sellerId(null) + .count(1) + .build()); + final int productCount = productItemList.stream().map(productItem -> productItem.getCount()).reduce(Integer::sum).get(); + NvPayNoticeRespData data = NvPayNoticeRespData.builder() + .productName(productName) + .productCount(productCount) + .totalPayAmount(totalPayAmount) + .taxScopeAmount(taxScopeAmount) + .taxExScopeAmount(taxExScopeAmount) + .environmentDepositAmount(environmentDepositAmount) + .productItems(productItemList) + .returnUrl(BILL_HOST + BILL_PAYABLE_URL) + .purchaserName(null) + .purchaserBirthday(null) + .build(); + Map result = new HashMap<>(); + result.put("res_code", resCd.getCode()); + result.put("message", resCd.getCodeNm()); + result.put("data", data); + + return new ResponseEntity>(result, HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "납부(결제)가능여부" + , value = "{\"data\":{\"billerUserKey\":\"빌러유저키\",\"productName\":\"\",\"totalPayAmount\":1000,\"taxScopeAmount\":1000,\"taxExScopeAmount\":null}}") + }) + }) + @Operation(summary = "납부(결제)가능여부 샘플") + @PostMapping(value = "/bill/nv/ep/sample/payable", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity> payAble(@RequestBody Map param) { + + Map data = gson.fromJson(gson.toJson(param), new TypeToken>() { + }.getType()); + + log.info("[Request Data] {}", data.toString()); + + + /* ============================================ + * [정상 응답코드] + * OK + * [실패 응답코드] + * NO_AMOUNT_PAYABLE + * OVERPAYABLE_AMOUNT + * NO_TARGET_PAYABLE + * EXPIRED_DATE + * FAILED_CHECK_INFO + ============================================ */ + PayUseSysResCd resCd = PayUseSysResCd.OK; + + + Map result = new HashMap<>(); + result.put("res_code", resCd.getCode()); + result.put("message", resCd.getCodeNm()); + result.put("data", null); + + + return new ResponseEntity>(result, HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "납부(결제)결과" + , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"paymentId\":\"네이버페이 결제번호\",\"detail\":{\"productName\":\"샘플상품\",\"merchantId\":\"loginId\",\"merchantName\":\"가맹점명\",\"cardNo\":\"465887**********\",\"admissionYmdt\":\"20170201151722\",\"payHistId\":\"20170201NP1043587781\",\"totalPayAmount\":1000,\"primaryPayAmount\":1000,\"npointPayAmount\":0,\"giftCardAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"primaryPayMeans\":\"CARD\",\"merchantPayKey\":\"청구서UID\",\"merchantUserKey\":\"빌러유저키\",\"cardCorpCode\":\"C0\",\"paymentId\":\"20170201NP1043587746\",\"admissionTypeCode\":\"01\",\"settleExpectAmount\":971,\"payCommissionAmount\":29,\"admissionState\":\"SUCCESS\",\"tradeConfirmYmdt\":\"20170201152510\",\"cardAuthNo\":\"17545616\",\"cardInstCount\":0,\"usedCardPoint\":false,\"bankCorpCode\":\"\",\"bankAccountNo\":\"\",\"settleExpected\":false,\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}}}") + }) + }) + @Operation(summary = "납부(결제)결과 샘플") + @PostMapping(value = "/bill/nv/ep/sample/payresult", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity> payResult(@RequestBody Map param) { + log.info("[Request Data] {}", param.toString()); + + PayUseSysResCd resCd = PayUseSysResCd.OK; + + + Map result = new HashMap<>(); + result.put("res_code", resCd.getCode()); + result.put("message", resCd.getCodeNm()); + result.put("data", null); + + return new ResponseEntity>(result, HttpStatus.OK); + } + + + @io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = { + @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "Sample Example..." + , summary = "결제취소정보" + , value = "{\"code\":\"Success\",\"message\":\"detail message(optional)\",\"body\":{\"responseCount\":1,\"totalCount\":1,\"totalPageCount\":1,\"currentPageNumber\":1,\"list\":[{\"cardAuthNo\":\"00000000\",\"bankAccountNo\":\"\",\"bankCorpCode\":\"\",\"paymentId\":\"20170000NP1000229665\",\"cardCorpCode\":\"C0\",\"cardInstCount\":0,\"usedCardPoint\":false,\"settleInfo\":{\"primaryCommissionAmount\":30,\"npointCommissionAmount\":20,\"giftCardCommissionAmount\":0,\"primarySettleAmount\":470,\"npointSettleAmount\":480,\"giftCardSettleAmount\":0,\"totalSettleAmount\":850,\"totalCommissionAmount\":50,\"settleCreated\":true},\"merchantName\":\"나의가맹점\",\"productName\":\"나의상품\",\"payHistId\":\"20170000NP1000229668\",\"merchantId\":\"MID12345\",\"admissionYmdt\":\"20170914163930\",\"tradeConfirmYmdt\":\"20170915163956\",\"totalPayAmount\":1000,\"merchantPayKey\":\"orderKey-91516397\",\"merchantUserKey\":\"빌러유저키\",\"admissionTypeCode\":\"01\",\"primaryPayMeans\":\"CARD\",\"admissionState\":\"SUCCESS\",\"primaryPayAmount\":500,\"npointPayAmount\":500,\"giftCardPayAmount\":0,\"taxScopeAmount\":1000,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"cardNo\":\"123456**********\",\"extraDeduction\":false,\"useCfmYmdt\":\"20180703\"}]}}") + }) + }) + @Operation(summary = "결제취소정보 샘플") + @PostMapping(value = "/bill/nv/ep/sample/cancelresult", produces = MediaType.APPLICATION_JSON_VALUE) + @Override + public ResponseEntity> payCancel(@RequestBody Map param) { + log.info("[Request Data] {}", param.toString()); + + PayUseSysResCd resCd = PayUseSysResCd.OK; + + + Map result = new HashMap<>(); + result.put("res_code", resCd.getCode()); + result.put("message", resCd.getCodeNm()); + result.put("data", null); + + return new ResponseEntity>(result, HttpStatus.OK); + } + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPaymentPageController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPaymentPageController.java new file mode 100644 index 0000000..5f1ca17 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/presentation/NvPaymentPageController.java @@ -0,0 +1,84 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.presentation; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.NvPayProcessService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import java.util.Map; + +@Tag(name = "NvPaymentPageController") +@Slf4j +@RequiredArgsConstructor +@Controller +public class NvPaymentPageController { + private final NvPayProcessService nvPayProcessService; + + @GetMapping(value = "/bill/nv/ep/test/page") + public String nvEpTestPage(ModelMap model) { + + return "modules/bill/nvEpTest"; + } + + @Parameter(name = "flag", example = "ok", in = ParameterIn.PATH) + @Operation(summary = "네이버페이 납부(결제)결과 테스트페이지 출력") + @GetMapping(value = "/bill/nv/ep/test/rslt/prnt/{flag}") + public String nvEpTestRsltPrnt(@PathVariable String flag, ModelMap modelMap) throws JsonProcessingException { + Gson gson = new Gson(); + + if ("ok".equals(flag)) { + Map param = gson.fromJson("{\"code\":\"Success\",\"message\":\"성공\",\"body\":{\"paymentId\":\"20230206NP1041083209\",\"detail\":{\"paymentId\":\"20230206NP1041083209\",\"payHistId\":\"20230206NP1041083231\",\"merchantName\":\"민자도로 관리지원센터_테스트\",\"merchantId\":\"np_mtbfw423545\",\"merchantPayKey\":\"gamengUserKey-00001\",\"merchantUserKey\":\"gamengUserKey-00001\",\"admissionTypeCode\":\"01\",\"admissionYmdt\":\"20230206142529\",\"tradeConfirmYmdt\":\"20230206142529\",\"admissionState\":\"SUCCESS\",\"totalPayAmount\":100,\"primaryPayAmount\":0,\"npointPayAmount\":100,\"giftCardAmount\":0,\"taxScopeAmount\":100,\"taxExScopeAmount\":0,\"environmentDepositAmount\":0,\"primaryPayMeans\":\"CARD\",\"cardCorpCode\":\"C3\",\"cardNo\":\"5570-****-****-****\",\"cardAuthNo\":\"\",\"cardInstCount\":3,\"usedCardPoint\":false,\"bankCorpCode\":\"020\",\"bankAccountNo\":\"1002-***-***-***\",\"productName\":\"테스트상품\",\"settleExpected\":false,\"settleExpectAmount\":0,\"payCommissionAmount\":0,\"merchantExtraParameter\":\"\",\"extraDeduction\":false,\"useCfmYmdt\":\"\"}},\"LPGEX\":\"TnYSG\"}", new TypeToken>() { + }.getType()); + modelMap.putAll(param); + } else if ("fail".equals(flag)) { + modelMap.put("code", PayUseSysResCd.NO_TARGET_PAYABLE.getCode()); + modelMap.put("message", PayUseSysResCd.NO_TARGET_PAYABLE.getCodeNm()); + } else { + throw new EnsException(EnsErrCd.ERR405, "유효하지 않은 요청 입니다"); + } + + return "modules/bill/nvEpApply"; + } + + @Parameters({ + @Parameter(name = "billUid", example = "청구서UID", required = true, in = ParameterIn.QUERY), + @Parameter(name = "paymentId", example = "결제번호", required = true, in = ParameterIn.QUERY), + @Parameter(name = "resultCode", example = "Success", required = true, in = ParameterIn.QUERY), + @Parameter(name = "resultMessage", example = "성공", required = false, in = ParameterIn.QUERY), + @Parameter(name = "reserveId", example = "결제 예약ID", required = false, in = ParameterIn.QUERY) + }) + @Operation(summary = "네이버페이 간편결제 승인") + @GetMapping(value = "/bill/nv/ep/apply") + public String nvEpApply(@RequestParam Map param, ModelMap modelMap) { + PayApiRespDTO payApiRespDTO = nvPayProcessService.payAble(param); + + StringBuffer message = new StringBuffer(); + if (PayUseSysResCd.OK.getCode().equals(payApiRespDTO.getResCode())) { + if (payApiRespDTO.getData() != null) + modelMap.putAll((Map) payApiRespDTO.getData()); + } else { + modelMap.put("code", payApiRespDTO.getResCode()); + modelMap.put("message", payApiRespDTO.getMessage()); + } + + return "modules/bill/nvEpApply"; + } + + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayProcessService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayProcessService.java new file mode 100644 index 0000000..612327b --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayProcessService.java @@ -0,0 +1,99 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.NvPayAbleService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.NvPayCancelService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.NvPayNoticeService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.NvPayResultService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayProcessService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayAbleData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayCancelData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayNoticeData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayResultData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template.PayHelper; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Log4j2 +@RequiredArgsConstructor +@Service +public class NvPayProcessService implements PayProcessService> { + private final NvPayNoticeService nvPayNoticeService; + private final NvPayAbleService nvPayAbleService; + private final NvPayResultService nvPayResultService; + private final NvPayCancelService nvPayCancelService; + + @Override + public PayApiRespDTO gnrUrl(Map stringObjectMap) { + throw new EnsException(EnsErrCd.SERVICE_NOT_SUPPORTED, EnsErrCd.SERVICE_NOT_SUPPORTED.getCodeNm()); + } + + @Override + public PayApiRespDTO payNotice(Map data) { + String billUid = (String) data.get("billUid"); + + + Pay> pay = PayHelper., String, PayApiRespDTO>builder() + .param(billUid) + .payHelperService(nvPayNoticeService) + .build(); + + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payAble(Map data) { + + + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(data) + .payHelperService(nvPayAbleService) + .build(); + + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payResult(Map data) { + + + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(data) + .payHelperService(nvPayResultService) + .build(); + + + pay.exec(); + + return pay.getResult(); + } + + @Override + public PayApiRespDTO payCancel(Map data) { + + + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(data) + .payHelperService(nvPayCancelService) + .build(); + + + pay.exec(); + + return pay.getResult(); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayRepairService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayRepairService.java new file mode 100644 index 0000000..083333c --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPayRepairService.java @@ -0,0 +1,139 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.repair.kit.RepairNvPayResultTransferFail; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.RepairPayResultService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Slf4j +@Service +@RequiredArgsConstructor +public class NvPayRepairService implements RepairPayResultService { + + private final JPAQueryFactory query; + private final PayUseSysApi payUseSysApi; + private final BillHistRepository billHistRepository; + + + @Override + @Transactional(readOnly = true) + public Map> findTransferFailedPayResultDataList(RepairPayRsltFwdFailSearchDTO searchDTO) { + Map> mResultByOrg = new HashMap<>(); + RepairNvPayResultTransferFail.builder() + .query(query) + .searchDTO(searchDTO) + .build() + .findDatas() + .forEach(failData -> { + /** + * 응답데이터 구조 + * { + * "기관코드" { + * "orgCd": "aaaa", + * "orgNm": "sdafsf", + * "billSe": { + * "nvBp": [ + * { "billerUserKey": "aaaaaaaaaaaaa" }, + * { "billerUserKey": "bbbbbbbbbbbbb" } + * ], + * "kkoBp": [ + * { "billerUserKey": "fffffffffffff" } + * ] + * } + * } + * } + */ + Map mOrg = mResultByOrg.get(failData.getOrgCd()); + if (mOrg == null) { + mOrg = new HashMap<>(); + mOrg.put("orgCd", failData.getOrgCd()); + mOrg.put("orgNm", failData.getOrgNm()); + Map data = new HashMap<>(); + data.put("billerUserKey", failData.getBillerUserKey()); + List> datas = new ArrayList<>(); + datas.add(data); + Map billSe = new HashMap<>(); + billSe.put(failData.getBillSe().getCode(), datas); + mOrg.put("billSe", billSe); + mResultByOrg.put(failData.getOrgCd(), mOrg); + } else { + Map billSe = (Map) mOrg.get("billSe"); + List> datas = (List>) billSe.getOrDefault(failData.getBillSe().getCode(), new ArrayList<>()); + Map data = new HashMap<>(); + data.put("billerUserKey", failData.getBillerUserKey()); + datas.add(data); + billSe.put(failData.getBillSe().getCode(), datas); + } + }); + + + return mResultByOrg; + } + + @Override + public Map> sendTransferFailedPayResultDataList(RepairPayRsltFwdFailSearchDTO searchDTO) { + Map> mResultByOrg = new HashMap<>(); + RepairNvPayResultTransferFail.builder() + .query(query) + .searchDTO(searchDTO) + .build() + .transferData(payUseSysApi, billHistRepository) + .forEach(billHist -> { + /** + * 응답데이터 구조 + * { + * "기관코드" { + * "orgCd": "aaaa", + * "orgNm": "sdafsf", + * "billSe": { + * "nvBp": [ + * { "billerUserKey": "aaaaaaaaaaaaa", "code": "OK", "message": "성공" }, + * { "billerUserKey": "bbbbbbbbbbbbb", "code": "OK", "message": "성공" } + * ], + * "kkoBp": [ + * { "billerUserKey": "fffffffffffff", "code": "FAILED_SAVE_PAYRSLT", "message": "납부(결제)결과 저장 실패" } + * ] + * } + * } + * } + */ + Map mOrg = mResultByOrg.get(billHist.getOrgMng().getOrgCd()); + if (mOrg == null) { + mOrg = new HashMap<>(); + mOrg.put("orgCd", billHist.getOrgMng().getOrgCd()); + mOrg.put("orgNm", billHist.getOrgMng().getOrgNm()); + Map data = new HashMap<>(); + data.put("billerUserKey", billHist.getLinkedUuid()); + data.put("code", billHist.getError().getErrorCode()); + data.put("message", billHist.getError().getErrorMessage()); + List> datas = new ArrayList<>(); + datas.add(data); + Map billSe = new HashMap<>(); + billSe.put(billHist.getBillSe().getCode(), datas); + mOrg.put("billSe", billSe); + mResultByOrg.put(billHist.getOrgMng().getOrgCd(), mOrg); + } else { + Map billSe = (Map) mOrg.get("billSe"); + List> datas = (List>) billSe.getOrDefault(billHist.getBillSe().getCode(), new ArrayList<>()); + Map data = new HashMap<>(); + data.put("billerUserKey", billHist.getLinkedUuid()); + data.put("code", billHist.getError().getErrorCode()); + data.put("message", billHist.getError().getErrorMessage()); + datas.add(data); + billSe.put(billHist.getBillSe().getCode(), datas); + } + }); + return mResultByOrg; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPaymentTriggerService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPaymentTriggerService.java new file mode 100644 index 0000000..37967ee --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/NvPaymentTriggerService.java @@ -0,0 +1,87 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.QBillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository.BillNvEasyPayRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger.PaymentTriggerServiceTemplate; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service(value = "nvPaymentTriggerService") +public class NvPaymentTriggerService extends PaymentTriggerServiceTemplate { + private final NvPayProcessService nvPayProcessService; + private final JPAQueryFactory query; + private final BillNvEasyPayRepository billNvEasyPayRepository; + @Value("${contract.naver.pay.easy.ep-sdk-mode}") + private String EP_SDK_MODE; + + @Override + protected boolean existsBill(String billUid) { + return query.selectFrom(QBillNvEasyPay.billNvEasyPay) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchCount() > 0; + } + + @Override + protected void generateBill(Bill bill) { + billNvEasyPayRepository.save(BillNvEasyPay.builder() + .billUid(bill.getBillUid()) + .billerUserKey(bill.getBillerUserKey()) + .payType("normal") + .openType("page") + .build()); + } + + @Override + protected Map getPayInfo(Map param) { + final Bill bill = (Bill) param.getOrDefault(PTriggerDataKeys.bill, new Bill()); + final String billUid = (String) param.getOrDefault(PTriggerDataKeys.billUid, ""); + + + if (CmmnUtil.isEmpty(bill.getOrgMng().getNvBpClientId())) + throw new EnsException(EnsErrCd.INVALID_DATA, "네이버 간편결제 계약정보가 없습니다."); + + + Map p = new HashMap<>(); + p.put("billUid", billUid); + PayApiRespDTO payApiRespDTO = nvPayProcessService.payNotice(p); + if (!PayUseSysResCd.OK.getCode().equals(payApiRespDTO.getResCode())) + throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, String.format("%s\n[실패사유]\n -.코드: %s\n -.메시지: %s", EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), payApiRespDTO.getResCode(), payApiRespDTO.getMessage())); + + BillNvEasyPay billNvEasyPay = Optional.ofNullable(query.selectFrom(QBillNvEasyPay.billNvEasyPay) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchOne()) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다.")); + + + + Map resultInfo = new HashMap<>(); + resultInfo.put("mode", EP_SDK_MODE); + resultInfo.put("payType", billNvEasyPay.getPayType()); + resultInfo.put("openType", billNvEasyPay.getOpenType()); + resultInfo.put("clientId", bill.getOrgMng().getNvBpClientId()); + resultInfo.put("billUid", billUid); + resultInfo.put("merchantUserKey", billNvEasyPay.getBillerUserKey()); + resultInfo.put("merchantPayKey", billNvEasyPay.getBillUid()); + resultInfo.put("payinf", payApiRespDTO.getData()); + + return resultInfo; + } + + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayAbleService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayAbleService.java new file mode 100644 index 0000000..404bf33 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayAbleService.java @@ -0,0 +1,380 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.core.utils.MapDeserailizer; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.api.BillNvEasyPayApiSpec; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.QBillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository.BillNvEasyPayRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayAbleReqData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayApplyRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillLogSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayAbleService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayAbleData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayCancelData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template.PayHelper; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class NvPayAbleService implements PayAbleService, Map, PayApiRespDTO>> { + private final BillNvEasyPayRepository billNvEasyPayRepository; + + private final JPAQueryFactory query; + private final BillNvEasyPayApiSpec billNvEasyPayApi; + private final PayUseSysApi payUseSysApi; + private final BillHistRepository billHistRepository; + private final NvPayCancelService nvPayCancelService; + private final NvPayResultService nvPayResultService; + + // private Gson gson = new Gson(); + private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).disableHtmlEscaping().create(); + + + private enum DataKeys { + payApplyReqMessage, + payApplyRespMessage, + } + + @Override + public PayAbleData getData(Map reqParam) { + String billUid = (String) reqParam.getOrDefault("billUid", ""); + + Bill bill = query.selectFrom(QBill.bill) + .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin() + .where(QBill.bill.billUid.eq(billUid)) + .fetchOne(); + BillNvEasyPay billNvEasyPay = query.selectFrom(QBillNvEasyPay.billNvEasyPay) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchOne(); + + return PayAbleData.builder() + .bill(bill) + .billDetail(billNvEasyPay) + .build(); + } + + @Override + public void validate(Map reqParam, PayAbleData data) { + + if (CmmnUtil.isEmpty(reqParam.get("resultCode"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "결과코드는 필수값 입니다."); + if (!"Success".equals(reqParam.get("resultCode"))) +// throw new EnsException(EnsErrCd.INVALID_REQUEST, String.format("[%s] %s %s", BillLogSeCd.VD, reqParam.get("resultCode"), reqParam.get("resultMessage"))); + //2023.03.09 네이버페이 검수 결과 - 결제창 실패응답 화면에 resultMessage 원문만 노출 요함 + throw new EnsException(EnsErrCd.INVALID_REQUEST, String.format("[%s] %s", BillLogSeCd.VD, reqParam.get("resultMessage"))); + if (CmmnUtil.isEmpty(reqParam.get("billUid"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "청구서UID는 필수값 입니다."); + if (CmmnUtil.isEmpty(reqParam.get("paymentId"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "결제ID는 필수값 입니다."); + + if (CmmnUtil.isEmpty(data.getBill())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다."); + if (CmmnUtil.isEmpty(data.getBillDetail())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다."); + } + + @Override + public void callApi(Map reqParam, PayAbleData data) { + Bill bill = data.getBill(); + OrgMng orgMng = bill.getOrgMng(); + + + final String partnerId = orgMng.getNvBpPartnerId(); + final String clientId = orgMng.getNvBpClientId(); + final String clientSecret = orgMng.getNvBpClientSecret(); + final String useSysUrl = orgMng.getNvBpPrepayApi(); + final String paymentId = (String) reqParam.get("paymentId"); + LinkedMultiValueMap reqData = new LinkedMultiValueMap<>(); + reqData.add("paymentId", paymentId); + + + Optional.of(data.getBillDetail()) + .map(billDetail -> createMessage(billDetail)) + .map(param -> loadReqData(data, useSysUrl, param)) + .map(param -> payUseSysApi.payAble(useSysUrl, param, null)) + .map(response -> loadRespData(data, response)) + .map(response -> checkResponse(response)) + .map(respDto -> loadPayApplyReqData(data, reqData)) + .map(respDto -> billNvEasyPayApi.payApply(partnerId, clientId, clientSecret, reqData)) + .map(response -> loadPayApplyRespData(data, response)) + .map(response -> checkApplyResponse(response)) + .map(respDto -> { + try { + + validateApplyData(data, respDto); + } catch (EnsException e) { + + callPayCancelService(data, respDto, e); + throw e; + } + return respDto; + }) + .map(respDto -> callPayResultService(respDto)) + ; + } + + protected Map createMessage(BillNvEasyPay billDetail) { + NvPayAbleReqData nvPayAbleReqData = NvPayAbleReqData.builder() + .billerUserKey(billDetail.getBillerUserKey()) + .productName(billDetail.getProductName()) + .taxExScopeAmount(billDetail.getTaxExScopeAmount()) + .taxScopeAmount(billDetail.getTaxScopeAmount()) + .totalPayAmount(billDetail.getTotalPayAmount()) + .build(); + Map m = new HashMap<>(); + m.put("data", nvPayAbleReqData); + return m; + } + + protected Map loadReqData(PayAbleData data, String url, Map param) { + + data.getReqAndRespInf().setUrl(url); + data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param)); + + return gson.fromJson(gson.toJson(param), Map.class); + } + + protected ResponseEntity loadRespData(PayAbleData data, ResponseEntity response) { + + data.getReqAndRespInf().setRespRawData(response.getBody()); + return response; + } + + protected PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, "[" + BillLogSeCd.US + "] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, "[" + BillLogSeCd.US + "] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + try { + PayUseSysResCd.valueOf(result.getResCode()); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RES_CODE, "[" + BillLogSeCd.US + "] " + EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex); + } + if (!PayUseSysResCd.OK.getCode().equals(result.getResCode())) { + result.setMessage("[" + BillLogSeCd.US + "] " + result.getMessage()); + throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result); + } + + return result; + } + + protected LinkedMultiValueMap loadPayApplyReqData(PayAbleData data, LinkedMultiValueMap reqData) { + data.getReqAndRespInf().getEtc().put(DataKeys.payApplyReqMessage.name(), gson.toJson(reqData)); + return reqData; + } + + protected ResponseEntity loadPayApplyRespData(PayAbleData data, ResponseEntity response) { + data.getReqAndRespInf().getEtc().put(DataKeys.payApplyRespMessage.name(), response.getBody()); + return response; + } + + protected PayApiRespDTO checkApplyResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, "[" + BillLogSeCd.VD + "] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO result = null; + try { + result = gson.fromJson(response.getBody(), new TypeToken>() { + }.getType()); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, "[" + BillLogSeCd.VD + "] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + if (!"Success".equals(result.getResCode())) { + result.setMessage("[" + BillLogSeCd.VD + "] " + result.getMessage()); + throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result); + } + + return result; + } + + protected void validateApplyData(PayAbleData data, PayApiRespDTO respDTO) { + final BillNvEasyPay billNvEasyPay = data.getBillDetail(); + if (!billNvEasyPay.getTotalPayAmount().equals(respDTO.getData().getDetail().getTotalPayAmount())) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "요청한 총결제금액과 결제승인된 금액이 상이 합니다."); + if (!billNvEasyPay.getTaxScopeAmount().equals(respDTO.getData().getDetail().getTaxScopeAmount())) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "요청한 과세금액과 결제승인된 금액이 상이 합니다."); + if (!billNvEasyPay.getTaxExScopeAmount().equals(respDTO.getData().getDetail().getTaxExScopeAmount())) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "요청한 면세금액과 결제승인된 금액이 상이 합니다."); + } + + protected void callPayCancelService(PayAbleData data, PayApiRespDTO respDTO, EnsException e) { + + data.getBillDetail().setLastPaymentId(respDTO.getData().getPaymentId()); + data.getBillDetail().setTotalPayAmount(respDTO.getData().getDetail().getTotalPayAmount()); + data.getBillDetail().setTaxScopeAmount(respDTO.getData().getDetail().getTaxScopeAmount()); + data.getBillDetail().setTaxExScopeAmount(respDTO.getData().getDetail().getTaxExScopeAmount()); + data.getBillDetail().setEnvironmentDepositAmount(respDTO.getData().getDetail().getEnvironmentDepositAmount()); + billNvEasyPayRepository.save(data.getBillDetail()); + + + Map param = new HashMap<>(); + param.put("billUid", data.getBillDetail().getBillUid()); + param.put("cancelReason", e.getMessage()); + param.put("cancelRequester", "2"); + + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(nvPayCancelService) + .build(); + + pay.exec(); + } + + + protected PayApiRespDTO> callPayResultService(PayApiRespDTO respDTO) { + Map param = new HashMap<>(); + param.put("code", respDTO.getResCode()); + param.put("message", respDTO.getMessage()); + param.put("body", gson.fromJson(gson.toJson(respDTO.getData()), Map.class)); + + Pay>> pay = PayHelper., Map, PayApiRespDTO>>builder() + .param(param) + .payHelperService(nvPayResultService) + .build(); + pay.exec(); + + return pay.getResult(); + } + + + @Override + public PayApiRespDTO> generateResult(Map reqParam, PayAbleData data, EnsException e) { + if (e == null) { + final String respRawData = (String) data.getReqAndRespInf().getEtc().get(DataKeys.payApplyRespMessage.name()); + Map result = gson.fromJson(respRawData, Map.class); + return PayApiRespDTO.>okBuilder() + .data(result) + .build(); + } else { + if (EnsErrCd.RESPONSED_FAILURE_CODE.equals(e.getErrCd())) { + PayApiRespDTO respDTO = (PayApiRespDTO) e.getData(); + return respDTO; + } else { + return PayApiRespDTO.>errDataBuilder() + .resCode(e.getErrCd().getCode()) + .message(e.getMessage()) + .data(null) + .build(); + } + } + } + + @Override + public void saveHist(Map reqParam, PayAbleData data, EnsException e) { + saveHistByUseSysPayAble(reqParam, data, e); + saveHistByPayApply(data, e); + + + if (e != null) { + if (data.getBillDetail() != null) { + data.getBillDetail().setError(FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()); + billNvEasyPayRepository.save(data.getBillDetail()); + } + } else { + data.getBillDetail().setError(FieldError.initBuilder().build()); + billNvEasyPayRepository.save(data.getBillDetail()); + } + } + + + protected void saveHistByUseSysPayAble(Map reqParam, PayAbleData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + + String requestData = reqAndRespInf.getReqData(); + if (e != null) { + switch (e.getErrCd()) { + case NO_DATA_FOUND: + case NO_REQUIRED_PARAM: + case INVALID_REQUEST: + requestData = gson.toJson(reqParam); + break; + } + } + BillHist billHist = BillHist.builder() + .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid()) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.US_PREPAY) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(requestData) + .responseData(reqAndRespInf.getRespRawData()) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + .build(); + + billHistRepository.save(billHist); + } + + protected void saveHistByPayApply(PayAbleData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + final String requestData = (String) reqAndRespInf.getEtc().get(DataKeys.payApplyReqMessage.name()); + final String responseData = (String) reqAndRespInf.getEtc().get(DataKeys.payApplyRespMessage.name()); + + if (!CmmnUtil.isEmpty(requestData)) { + BillHist billHist = BillHist.builder() + .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid()) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.VD_PAYAPPLY) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(requestData) + .responseData(responseData) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + .build(); + + billHistRepository.save(billHist); + } + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayCancelService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayCancelService.java new file mode 100644 index 0000000..8725186 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayCancelService.java @@ -0,0 +1,308 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.core.utils.MapDeserailizer; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.api.BillNvEasyPayApiSpec; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.QBillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository.BillNvEasyPayRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayCancelService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayCancelData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicReference; + +@Slf4j +@RequiredArgsConstructor +@Service +public class NvPayCancelService implements PayCancelService, Map, PayApiRespDTO>> { + + private final JPAQueryFactory query; + private final BillNvEasyPayApiSpec billNvEasyPayApi; + private final BillRepository billRepository; + private final BillNvEasyPayRepository billNvEasyPayRepository; + private final BillHistRepository billHistRepository; + private final PayUseSysApi payUseSysApi; + + private Gson gson = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserailizer()).create(); + + private enum DataKeys { + useSysPayCancelReqMessage, + useSysPayCancelRespMessage, + } + + @Override + public PayCancelData getData(Map reqParam) { + String billUid = (String) reqParam.getOrDefault("billUid", ""); + + Bill bill = query.selectFrom(QBill.bill) + .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin() + .where(QBill.bill.billUid.eq(billUid)) + .fetchOne(); + BillNvEasyPay billNvEasyPay = query.selectFrom(QBillNvEasyPay.billNvEasyPay) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchOne(); + + return PayCancelData.builder() + .bill(bill) + .billDetail(billNvEasyPay) + .build(); + } + + @Override + public void validate(Map reqParam, PayCancelData data) { + + if (CmmnUtil.isEmpty(reqParam.get("billUid"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "청구서UID는 필수값 입니다."); + if (CmmnUtil.isEmpty(reqParam.get("cancelReason"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "취소사유는 필수값 입니다."); + if (String.valueOf(reqParam.get("cancelReason")).length() > 80) + throw new EnsException(EnsErrCd.INVALID_REQUEST, "취소사유는 최대 80자까지 가능 합니다."); + if (CmmnUtil.isEmpty(reqParam.get("cancelRequester"))) + throw new EnsException(EnsErrCd.NO_REQUIRED_PARAM, "취소요청자는 필수값 입니다."); + if (!("1".equals(reqParam.get("cancelRequester")) || "2".equals(reqParam.get("cancelRequester")))) + throw new EnsException(EnsErrCd.INVALID_REQUEST, "유효하지 않은 취소요청자 구분값 입니다."); //1:구매자, 2:가맹점 관리자 - 애매할 경우 가맹점관리자로 설정 + + if (CmmnUtil.isEmpty(data.getBill())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다."); + if (CmmnUtil.isEmpty(data.getBillDetail())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다."); + if (CmmnUtil.isEmpty(data.getBillDetail().getLastPaymentId())) + throw new EnsException(EnsErrCd.INVALID_DATA, "미결제(또는 결제취소) 자료 입니다."); + final Integer sumAmount = data.getBillDetail().getTaxScopeAmount() + data.getBillDetail().getTaxExScopeAmount() + (data.getBillDetail().getEnvironmentDepositAmount() == null ? 0 : data.getBillDetail().getEnvironmentDepositAmount()); + if (!data.getBillDetail().getTotalPayAmount().equals(sumAmount)) + throw new EnsException(EnsErrCd.INVALID_DATA, "결제금액과 세부(과세/면세/컵보증금)금액 합계 불일치."); + } + + @Override + public void callApi(Map reqParam, PayCancelData data) { + Bill bill = data.getBill(); + OrgMng orgMng = bill.getOrgMng(); + BillNvEasyPay billNvEasyPay = data.getBillDetail(); + + + final String partnerId = orgMng.getNvBpPartnerId(); + final String clientId = orgMng.getNvBpClientId(); + final String clientSecret = orgMng.getNvBpClientSecret(); + + final String useSysUrl = orgMng.getNvBpPaycancelApi(); + AtomicReference> fwdData = new AtomicReference<>(); + + + + Optional.of(createMessage(reqParam, billNvEasyPay)) + .map(param -> loadReqData(data, param)) + .map(param -> billNvEasyPayApi.payCancel(partnerId, clientId, clientSecret, param)) + .map(response -> loadRespData(data, response)) + .map(response -> checkResponse(response)) + .map(respData -> savePayCancelInfo(data, respData)) + .filter(respData -> useSysUrl != null) + .map(respData -> { + fwdData.set(respData); + return respData; + }) + .map(respData -> loadFwdUseSysPayCancelReqData(data, respData)) + .map(respData -> payUseSysApi.payCancelResult(useSysUrl, respData, null)) + .map(response -> loadFwdUseSysPayCancelRespData(data, response)) + ; + + } + + protected LinkedMultiValueMap createMessage(Map reqParam, BillNvEasyPay billNvEasyPay) { + LinkedMultiValueMap reqData = new LinkedMultiValueMap<>(); + reqData.add("paymentId", billNvEasyPay.getLastPaymentId()); + reqData.add("merchantUserKey", billNvEasyPay.getBillerUserKey()); + reqData.add("cancelReason", reqParam.get("cancelReason")); + reqData.add("cancelRequester", reqParam.get("cancelRequester")); + reqData.add("cancelAmount", billNvEasyPay.getTotalPayAmount()); + reqData.add("taxScopeAmount", billNvEasyPay.getTaxScopeAmount()); + reqData.add("taxExScopeAmount", billNvEasyPay.getTaxExScopeAmount()); + if (!CmmnUtil.isEmpty(billNvEasyPay.getEnvironmentDepositAmount())) + reqData.add("environmentDepositAmount", billNvEasyPay.getEnvironmentDepositAmount()); + reqData.add("doCompareRest", 0); + reqData.add("expectedRestAmount", null); + return reqData; + } + + protected LinkedMultiValueMap loadReqData(PayCancelData data, LinkedMultiValueMap param) { + + data.getReqAndRespInf().setUrl(""); + data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param)); + + return param; + } + + protected ResponseEntity loadRespData(PayCancelData data, ResponseEntity response) { + + data.getReqAndRespInf().setRespRawData(response.getBody()); + return response; + } + + protected Map checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + Map result = null; + try { + result = gson.fromJson(response.getBody(), Map.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + //※응답코드 중 CancelNotComplete는 네이버페이 취소 진행 중 상태로 빠른 시일 내에 자동 취소될 예정이므로 가맹점에서는 취소 성공으로 처리 필요 + if (!("Success".equals(result.get("code")) || "CancelNotComplete".equals(result.get("code")))) +// throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, String.format("[%s] %s", result.get("code"), result.get("message"))); + //2023.03.09 네이버페이 검수 결과 - 결제창 실패응답 화면에 resultMessage 원문만 노출 요함 + throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, (String) result.get("message")); + + return result; + } + + protected Map savePayCancelInfo(PayCancelData data, Map respData) { + + Map body = (Map) respData.getOrDefault("body", new HashMap<>()); + final String cancelYmdt = (String) body.get("cancelYmdt"); + + + if (PaidTypeCd.naverPay.equals(data.getBill().getPaidType())) { + data.getBill().setPaidAt(false); + data.getBill().setPaidType(PaidTypeCd.naverPay); + data.getBill().setPaidCancelDt(cancelYmdt); + billRepository.save(data.getBill()); + } + + + data.getBillDetail().setLastPaymentId(null); + data.getBillDetail().setLastPayHistId((String) body.get("payHistId")); + data.getBillDetail().setLastCancelPaymentId((String) body.get("paymentId")); + data.getBillDetail().setError(FieldError.initBuilder().build()); + billNvEasyPayRepository.save(data.getBillDetail()); + + return respData; + } + + protected Map loadFwdUseSysPayCancelReqData(PayCancelData data, Map respData) { + data.getReqAndRespInf().getEtc().put(DataKeys.useSysPayCancelReqMessage.name(), gson.toJson(respData)); + return respData; + } + + protected ResponseEntity loadFwdUseSysPayCancelRespData(PayCancelData data, ResponseEntity response) { + data.getReqAndRespInf().getEtc().put(DataKeys.useSysPayCancelRespMessage.name(), response.getBody()); + return response; + } + + + @Override + public PayApiRespDTO> generateResult(Map reqParam, PayCancelData data, EnsException e) { + if (e == null) { + Gson gson = new Gson(); + final String respRawData = data.getReqAndRespInf().getRespRawData(); + return PayApiRespDTO.>errDataBuilder() + .resCode(PayUseSysResCd.OK.getCode()) + .message(PayUseSysResCd.OK.getCodeNm()) + .data(gson.fromJson(respRawData, Map.class)) + .build(); + } else { + return PayApiRespDTO.>errDataBuilder() + .resCode(e.getErrCd().getCode()) + .message(e.getMessage()) + .data(null) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, PayCancelData data, EnsException e) { + saveHistByPayCancel(reqParam, data, e); + saveHistByFwdUseSysPayCancel(data, e); + + + if (e != null) { + if (data.getBillDetail() != null) { + data.getBillDetail().setError(FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()); + billNvEasyPayRepository.save(data.getBillDetail()); + } + } + + } + + protected void saveHistByPayCancel(Map reqParam, PayCancelData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + + BillHist billHist = BillHist.builder() + .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid()) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.VD_PAYCANCEL) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(reqAndRespInf.getReqData()) + .responseData(reqAndRespInf.getRespRawData()) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + .build(); + + billHistRepository.save(billHist); + } + + protected void saveHistByFwdUseSysPayCancel(PayCancelData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + final String requestData = (String) reqAndRespInf.getEtc().get(DataKeys.useSysPayCancelReqMessage.name()); + final String responseData = (String) reqAndRespInf.getEtc().get(DataKeys.useSysPayCancelRespMessage.name()); + + if (!CmmnUtil.isEmpty(requestData)) { + BillHist billHist = BillHist.builder() + .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid()) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.US_CANCELRSLT) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(requestData) + .responseData(responseData) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + .build(); + + billHistRepository.save(billHist); + } + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayNoticeService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayNoticeService.java new file mode 100644 index 0000000..ae888e3 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayNoticeService.java @@ -0,0 +1,485 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.QBillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository.BillNvEasyPayRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyIdCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpPayReferrerCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.NvPayNoticeRespData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillLogSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayNoticeService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayNoticeData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.*; +import java.util.stream.Collectors; + +@Slf4j +@RequiredArgsConstructor +@Service +public class NvPayNoticeService implements PayNoticeService, String, PayApiRespDTO> { + + private final JPAQueryFactory query; + private final PayUseSysApi payUseSysApi; + private final BillNvEasyPayRepository billNvEasyPayRepository; + private final BillHistRepository billHistRepository; + + private Gson gson = new Gson(); + + @Override + public PayNoticeData getData(String billUid) { + if (billUid == null) billUid = ""; + Bill bill = query.selectFrom(QBill.bill) + .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin() + .where(QBill.bill.billUid.eq(billUid)) + .fetchOne(); + BillNvEasyPay billNvEasyPay = query.selectFrom(QBillNvEasyPay.billNvEasyPay) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchOne(); + + return PayNoticeData.builder() + .bill(bill) + .billDetail(billNvEasyPay) + .build(); + } + + @Override + public void validate(String billUid, PayNoticeData data) { + + if (CmmnUtil.isEmpty(data.getBill())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다."); + if (CmmnUtil.isEmpty(data.getBillDetail())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다."); + if (!CmmnUtil.isEmpty(data.getBillDetail().getLastPaymentId())) + throw new EnsException(EnsErrCd.PAYMENT_ALREADY_CMPLTED, "결제가 완료된 자료 입니다."); + } + + @Override + public void callApi(String billUid, PayNoticeData data) { + Bill bill = data.getBill(); + OrgMng orgMng = bill.getOrgMng(); + BillNvEasyPay billNvEasyPay = data.getBillDetail(); + + + final String useSysUrl = orgMng.getNvBpNoticeApi(); + + + Optional.of(billNvEasyPay.getBillerUserKey()) + .map(billerUserKey -> createMessage(billerUserKey)) + .map(param -> loadReqData(data, useSysUrl, param)) + .map(param -> payUseSysApi.payNotice(useSysUrl, param, null)) + .map(response -> loadRespData(data, response)) + .map(response -> checkResponse(response)) + .map(respDTO -> validateData(respDTO)) + .map(respDTO -> savePayNoticeInfo(data, respDTO)) + ; + + } + + protected Map createMessage(String billerUserKey) { + Map data = new HashMap<>(); + data.put("billerUserKey", billerUserKey); + Map param = new HashMap<>(); + param.put("data", data); + return param; + } + + protected Map loadReqData(PayNoticeData data, String url, Map param) { + + data.getReqAndRespInf().setUrl(url); + data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param)); + return param; + } + + protected ResponseEntity loadRespData(PayNoticeData data, ResponseEntity response) { + + data.getReqAndRespInf().setRespRawData(response.getBody()); + return response; + } + + + protected PayApiRespDTO checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, "[" + BillLogSeCd.US + "] " + EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO result = null; + try { + result = gson.fromJson(response.getBody(), new TypeToken>() { + }.getType()); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, "[" + BillLogSeCd.US + "] " + EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + try { + PayUseSysResCd.valueOf(result.getResCode()); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RES_CODE, "[" + BillLogSeCd.US + "] " + EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex); + } + if (!PayUseSysResCd.OK.getCode().equals(result.getResCode())) { + result.setMessage("[" + BillLogSeCd.US + "] " + result.getMessage()); + throw new EnsException(EnsErrCd.RESPONSED_FAILURE_CODE, EnsErrCd.RESPONSED_FAILURE_CODE.getCodeNm(), result); + } + + return result; + } + + protected PayApiRespDTO validateData(PayApiRespDTO respDTO) { + final Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); + Set> list = validator.validate(respDTO.getData()); + if (list.size() > 0) { + throw new EnsException(EnsErrCd.INVALID_RES_DATA, EnsErrCd.INVALID_RES_DATA.getCodeNm(), list.stream() + .map(row -> String.format("%s [ %s ]", row.getMessageTemplate(), row.getPropertyPath())) + .collect(Collectors.toList())); + } + + Optional.ofNullable(respDTO.getData()) + .filter(respData -> respData != null) + .map(respData -> validProductCount(respData)) + .map(respData -> validMinimumTotalPayAmount(respData)) + .map(respData -> validTaxAndTaxExAmount(respData)) + .map(respData -> validRequirePurchaserNameAndBirthday(respData)) + .map(respData -> validRequireExtraDeduction(respData)) + .map(respData -> validRequireUseCfmYmdt(respData)) + .map(respData -> validProductItems(respData)) + .map(respData -> validFieldTypeCdInProductItems(respData)) + .map(respData -> validFieldTypeCdInPayReferrer(respData)) + .map(respData -> validRequireNameAndCountInProductItems(respData)) + .map(respData -> validRequireStartAndEndDate(respData)) + ; + + + return respDTO; + } + + /** + * + * productCount(상품 수량)은 총 수량으로 전달하는지 확인 + * ex. "A 상품 2개 + B 상품 1개 + 사은품 1개"의 경우 productCount(상품 수량) 4로 전달 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validProductCount(NvPayNoticeRespData respData) { + final Integer productCount = respData.getProductCount(); + final Integer sumCount = respData.getProductItems().stream() + .map(productItem -> productItem.getCount()) + .reduce(Integer::sum) + .orElseGet(() -> 0); + if (!productCount.equals(sumCount)) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, String.format("상품수량과 결제상품수량 합계가 일치하지 않습니다.(상품수량: %d 실제합계: %d)", productCount, sumCount)); + + return respData; + } + + /** + * + * totalPayAmount 최소 결제금액(100원)에 대한 예외처리 확인 + * (가맹점 주문서 페이지 총 결제금액이 100원 미만일 경우 결제창 호출을 지양하고, 최소 결제금액에 대한 사용자 안내 처리 필요) + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validMinimumTotalPayAmount(NvPayNoticeRespData respData) { + if (respData.getTotalPayAmount() < 100) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "최소 결제금액은 100원 입니다."); + + return respData; + } + + /** + * + * taxScopeAmount(과세), taxExScopeAmount(면세) 해당 금액 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validTaxAndTaxExAmount(NvPayNoticeRespData respData) { + final Integer totalPayAmount = respData.getTotalPayAmount(); + final Integer sumAmount = respData.getTaxScopeAmount() + respData.getTaxExScopeAmount() + (respData.getEnvironmentDepositAmount() == null ? 0 : respData.getEnvironmentDepositAmount()); + if (!totalPayAmount.equals(sumAmount)) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "결제금액과 세부(과세/면세/컵보증금)금액 합계 불일치."); + + return respData; + } + + /** + * + * purchaserName, purchaserBirthday (구매자 성명, 생년월일) 결제 상품이 보험 및 게임 업종 등인 경우 필수 전달하는지 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validRequirePurchaserNameAndBirthday(NvPayNoticeRespData respData) { + boolean isTarget = respData.getProductItems().stream().anyMatch(productItem -> NvEpCtgyTypeCd.INSURANCE.equals(productItem.getCategoryType())); + if (isTarget) + if (CmmnUtil.isEmpty(respData.getPurchaserName()) || CmmnUtil.isEmpty(respData.getPurchaserBirthday())) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "구매자 성명/생년월일 정보가 없습니다. (보험 및 위험 업종인 경우 필수)"); + + return respData; + } + + /** + * + * 도서/공연비 소득공제 대상 가맹점인 경우 extraDeduction 전달하는지 확인 + * (true : 대상, false : 비 대상) + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validRequireExtraDeduction(NvPayNoticeRespData respData) { + /** + * TODO 향후 소득공제 대상 가맹점 여부 관리 필요 시 네이버페이와 협의된 계약사항에 해당 하므로 아래의 해결안 참고 + * 해결안 1. ENS 에서 가맹/비가맹점 관리 + * -. 기관관리 테이블(ENS_ORG_MNG)에 컬럼 추가 + * 해결안 2. 이용시스템으로부터 데이터 응답 + * -. 응답데이터 클래스(NvPayNoticeRespData) 에 필드 추가 + */ + return respData; + } + + /** + * + * 가맹점 타입이 이용완료일 정산 또는 이용완료일 포인트 적립인 경우 useCfmYmdt 전달하는지 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validRequireUseCfmYmdt(NvPayNoticeRespData respData) { + /** + * TODO 향후 정산/포인트적립 기준 관리 필요 시 네이버페이와 협의된 계약사항에 해당 하므로 아래의 해결안 참고 + * 해결안 1. ENS 에서 정산/포인트적립 기준 관리 + * -. 기관관리 테이블(ENS_ORG_MNG)에 컬럼 추가 + * 해결안 2. 이용시스템으로부터 데이터 응답 + * -. 응답데이터 클래스(NvPayNoticeRespData) 에 필드 추가 + * + * ※ 정산/포인트적립 기준 항목 참고 + * -. 정산 기준: 결제일, 이용완료일, 거래완료일 + * -. 포인트적립 기준: 결제일 기준 자동적립, 이용완료일 기준 적립, 포인트 적립 요청 API 적립, 거래 완료 API 적립, 포인트 적립 대상 아님 + */ + return respData; + } + + /** + * + * productItems 상품정보 개발 유무 확인 + * (categoryType, categoryId, uid, payReferrer 값 등) + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validProductItems(NvPayNoticeRespData respData) { + /** + * TODO 선행처리하는 Spring Validation 으로 대체 함. 향후 필요 시 로직 추가 + */ + return respData; + } + + /** + * + * categoryType, categoryId, uid 값이 상품정보 연동가이드 (Naverpay_Payments_Product_Items_Integration_Guide) 식별값으로 전달하는지 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validFieldTypeCdInProductItems(NvPayNoticeRespData respData) { + respData.getProductItems() + .forEach(productItem -> { + final String ctgyId = productItem.getCategoryType().getCode() + "_" + productItem.getCategoryId(); + if (Arrays.stream(NvEpCtgyIdCd.values()).noneMatch(cd -> cd.getCode().equals(ctgyId))) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "유효하지 않은 결제상품 분류 입니다."); + if (!productItem.getCategoryType().equals(NvEpCtgyIdCd.valueOf(ctgyId).getCategoryTypeCd())) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "결제상품 유형의 분류가 유효하지 않습니다."); + if (NvEpCtgyTypeCd.INSURANCE.equals(productItem.getCategoryType())) { + if (Arrays.asList("001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", "016") + .stream() + .noneMatch(uid -> uid.equals(productItem.getUid()))) + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "보험상품의 식별값이 유효하지 않습니다."); + } + }); + + return respData; + } + + /** + * + * payReferrer 값이 상품정보 연동가이드(Naverpay_Payments_Product_Items_Integration_Guide) 식별값으로 전달하는지 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validFieldTypeCdInPayReferrer(NvPayNoticeRespData respData) { + respData.getProductItems().stream() + .filter(productItem -> !CmmnUtil.isEmpty(productItem.getPayReferrer())) + .forEach(productItem -> { + try { + NvEpPayReferrerCd.valueOf(productItem.getPayReferrer()); + } catch (Exception e) { + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "유효하지 않은 유입경로 입니다."); + } + }); + return respData; + } + + /** + * + * productItems 상품정보 내 name(상품명), count(결제 상품 개수) 확인 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validRequireNameAndCountInProductItems(NvPayNoticeRespData respData) { + /** + * TODO 선행처리하는 Spring Validation 으로 대체 함. 향후 필요 시 로직 추가 + */ + return respData; + } + + /** + * + * startDate(시작일), endDate(종료일) 필드는 결제상품이 공연, 영화, 보험, 여행, 항공, 숙박 등인 경우 입력을 권장 + * + * + * @param respData + * @return + */ + private NvPayNoticeRespData validRequireStartAndEndDate(NvPayNoticeRespData respData) { + respData.getProductItems().stream() + .filter(productItem -> + NvEpCtgyTypeCd.PLAY.equals(productItem.getCategoryType()) + || NvEpCtgyTypeCd.MOVIE.equals(productItem.getCategoryType()) + || NvEpCtgyTypeCd.INSURANCE.equals(productItem.getCategoryType()) + || NvEpCtgyTypeCd.TRAVEL.equals(productItem.getCategoryType()) + || NvEpCtgyTypeCd.FLIGHT.equals(productItem.getCategoryType()) + ) + .filter(productItem -> CmmnUtil.isEmpty(productItem.getStartDate()) || CmmnUtil.isEmpty(productItem.getEndDate())) + .forEach(productItem -> { + throw new EnsException(EnsErrCd.INVALID_RES_DATA, "시작일(또는 종료일)이 없습니다. (공연/영화/보험/여행/항공 상품인 경우 필수)"); + }); + + + return respData; + } + + protected PayApiRespDTO savePayNoticeInfo(PayNoticeData data, PayApiRespDTO respDTO) { + NvPayNoticeRespData noticeData = respDTO.getData(); + + data.getBillDetail().setProductName(noticeData.getProductName()); + data.getBillDetail().setTotalPayAmount(noticeData.getTotalPayAmount()); + data.getBillDetail().setTaxScopeAmount(noticeData.getTaxScopeAmount()); + data.getBillDetail().setTaxExScopeAmount(noticeData.getTaxExScopeAmount()); + data.getBillDetail().setEnvironmentDepositAmount(noticeData.getEnvironmentDepositAmount()); + data.getBillDetail().setReturnUrl(noticeData.getReturnUrl()); + data.getBillDetail().setError(FieldError.initBuilder().build()); + billNvEasyPayRepository.save(data.getBillDetail()); + + return respDTO; + } + + @Override + public PayApiRespDTO generateResult(String billUid, PayNoticeData data, EnsException e) { + if (e == null) { + Gson gson = new Gson(); + final String respRawData = data.getReqAndRespInf().getRespRawData(); + return gson.fromJson(respRawData, new TypeToken>() { + }.getType()); + } else { + if (EnsErrCd.RESPONSED_FAILURE_CODE.equals(e.getErrCd())) { + PayApiRespDTO respDTO = (PayApiRespDTO) e.getData(); + return PayApiRespDTO.errDataBuilder() + .resCode(respDTO.getResCode()) + .message(respDTO.getMessage()) + .data(null) + .build(); + } else { + return PayApiRespDTO.errDataBuilder() + .resCode(e.getErrCd().getCode()) + .message(e.getMessage()) + .data(null) + .build(); + } + } + } + + @Override + public void saveHist(String billUid, PayNoticeData data, EnsException e) { + saveHistByUseSysNotice(billUid, data, e); + + if (e != null) { + if (data.getBillDetail() != null) { + data.getBillDetail().setError(FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()); + billNvEasyPayRepository.save(data.getBillDetail()); + } + } + } + + private void saveHistByUseSysNotice(String billUid, PayNoticeData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + + String errDetail = ""; + if (e != null) + if (EnsErrCd.INVALID_RES_DATA.equals(e.getErrCd())) { + if (e.getData() != null && e.getData() instanceof List) + errDetail = gson.toJson(e.getData()); + } + + BillHist billHist = BillHist.builder() + .billUid(billUid) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.US_NOTICE) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(reqAndRespInf.getReqData()) + .responseData(reqAndRespInf.getRespRawData()) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage() + errDetail) + .build()) + .build(); + + billHistRepository.save(billHist); + + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayResultService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayResultService.java new file mode 100644 index 0000000..87700a1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/NvPayResultService.java @@ -0,0 +1,231 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.BillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.QBillNvEasyPay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.entity.repository.BillNvEasyPayRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit.PayResultService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.PayResultData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model.ReqAndRespInf; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Slf4j +@RequiredArgsConstructor +@Service +public class NvPayResultService implements PayResultService, Map, PayApiRespDTO>> { + private final BillNvEasyPayRepository billNvEasyPayRepository; + + private final JPAQueryFactory query; + private final PayUseSysApi payUseSysApi; + private final BillRepository billRepository; + private final BillHistRepository billHistRepository; + + private Gson gson = new Gson(); + + @Override + public PayResultData getData(Map reqParam) { + Map body = (Map) reqParam.getOrDefault("body", new HashMap<>()); + Map detail = (Map) body.getOrDefault("detail", new HashMap<>()); +// final String paymentId = (String) body.getOrDefault("paymentId", ""); +// final String billerUserKey = (String) detail.getOrDefault("merchantUserKey", ""); + final String billUid = (String) detail.getOrDefault("merchantPayKey", ""); + + BillNvEasyPay billNvEasyPay = query.selectFrom(QBillNvEasyPay.billNvEasyPay) +// .where(QBillNvEasyPay.billNvEasyPay.lastPaymentId.eq(paymentId) +// .and(QBillNvEasyPay.billNvEasyPay.billerUserKey.eq(billerUserKey)) +// ) + .where(QBillNvEasyPay.billNvEasyPay.billUid.eq(billUid)) + .fetchOne(); + Bill bill = null; + if (billNvEasyPay != null) + bill = query.selectFrom(QBill.bill) + .innerJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin() + .where(QBill.bill.billUid.eq(billNvEasyPay.getBillUid())) + .fetchOne(); + return PayResultData.builder() + .bill(bill) + .billDetail(billNvEasyPay) + .build(); + } + + @Override + public void validate(Map reqParam, PayResultData data) { + + if (!"Success".equals(reqParam.get("code"))) + throw new EnsException(EnsErrCd.INVALID_REQUEST, String.format("[%s] %s", reqParam.get("code"), reqParam.get("message"))); + + if (CmmnUtil.isEmpty(data.getBill())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 자료가 없습니다."); + if (CmmnUtil.isEmpty(data.getBillDetail())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "일치하는 청구서 상세 자료가 없습니다."); + } + + @Override + public void callApi(Map reqParam, PayResultData data) { + Bill bill = data.getBill(); + OrgMng orgMng = bill.getOrgMng(); + + + final String useSysUrl = orgMng.getNvBpPayresultApi(); + + + Optional.of(savePaidInfo(data, reqParam)) + .map(param -> loadReqData(data, useSysUrl, param)) + .map(param -> createMessage(param)) + .map(param -> payUseSysApi.payResult(useSysUrl, param, null)) + .map(response -> loadRespData(data, response)) + .map(response -> checkResponse(response)) + ; + } + + protected Map savePaidInfo(PayResultData data, Map reqParam) { + Map body = (Map) reqParam.getOrDefault("body", new HashMap<>()); + Map detail = (Map) body.getOrDefault("detail", new HashMap<>()); + final String admissionYmdt = (String) detail.get("admissionYmdt"); + final String paymentId = (String) body.getOrDefault("paymentId", ""); + + + + data.getBill().setPaidAt(true); + data.getBill().setPaidType(PaidTypeCd.naverPay); + data.getBill().setPaidDt(admissionYmdt); + billRepository.save(data.getBill()); + + + data.getBillDetail().setLastPaymentId(paymentId); + data.getBillDetail().setError(FieldError.initBuilder().build()); + billNvEasyPayRepository.save(data.getBillDetail()); + + return reqParam; + } + + + protected Map loadReqData(PayResultData data, String url, Map param) { + + data.getReqAndRespInf().setUrl(url); + data.getReqAndRespInf().setReqData(CmmnUtil.toJsonString(param)); + return param; + } + + protected Map createMessage(Map reqParam) { + return reqParam; + } + + + protected ResponseEntity loadRespData(PayResultData data, ResponseEntity response) { + + data.getReqAndRespInf().setRespRawData(response.getBody()); + return response; + } + + protected PayApiRespDTO> checkResponse(ResponseEntity response) { + + if (!HttpStatus.OK.equals(response.getStatusCode())) + throw new EnsException(EnsErrCd.API_COMM_ERROR, EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString(), response.getBody()); + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RESPONSE, EnsErrCd.INVALID_RESPONSE.getCodeNm(), ex); + } + + try { + PayUseSysResCd.valueOf(result.getResCode()); + } catch (Exception ex) { + throw new EnsException(EnsErrCd.INVALID_RES_CODE, EnsErrCd.INVALID_RES_CODE.getCodeNm(), ex); + } + + return result; + } + + + @Override + public PayApiRespDTO> generateResult(Map reqParam, PayResultData data, EnsException e) { + if (e == null) { + final String respRawData = data.getReqAndRespInf().getRespRawData(); + return gson.fromJson(respRawData, PayApiRespDTO.class); + } else { + return PayApiRespDTO.>errDataBuilder() + .resCode(e.getErrCd().getCode()) + .message(e.getMessage()) + .data(null) + .build(); + } + } + + @Override + public void saveHist(Map reqParam, PayResultData data, EnsException e) { + saveHistByUseSysPayResult(reqParam, data, e); + + if (e != null) { + if (data.getBillDetail() != null) { + data.getBillDetail().setError(FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()); + billNvEasyPayRepository.save(data.getBillDetail()); + } + } + + } + + protected void saveHistByUseSysPayResult(Map reqParam, PayResultData data, EnsException e) { + ReqAndRespInf reqAndRespInf = data.getReqAndRespInf(); + + String requestData = reqAndRespInf.getReqData(); + if (e != null) { + switch (e.getErrCd()) { + case NO_DATA_FOUND: + case INVALID_REQUEST: + requestData = gson.toJson(reqParam); + break; + } + } + + + BillHist billHist = BillHist.builder() + .billUid(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getBillUid()) + .billSe(BillSeCd.bpNv) + .reqSe(BillReqSeCd.US_PAYRSLT) + .orgMng(CmmnUtil.isEmpty(data.getBill()) ? null : data.getBill().getOrgMng()) + .linkedUuid(CmmnUtil.isEmpty(data.getBillDetail()) ? null : data.getBillDetail().getBillerUserKey()) + .requestData(requestData) + .responseData(reqAndRespInf.getRespRawData()) + .error(e == null + ? FieldError.initBuilder().build() + : FieldError.initBuilder() + .errorCode(e.getErrCd().getCode()) + .errorMessage(e.getMessage()) + .build()) + .build(); + + billHistRepository.save(billHist); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyIdCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyIdCd.java new file mode 100644 index 0000000..ed8a190 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyIdCd.java @@ -0,0 +1,69 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code; + +import cokr.xit.ens.core.code.CodeMapperType; +import lombok.Getter; + + +/** + *
      + *
    • 업무 그룹명: 네이버페이 간편결제API - 결제상품 분류
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 22. 오후 2:47:43 + *
    + * + * @author 박민규 + */ + +public enum NvEpCtgyIdCd implements CodeMapperType { + BOOK_GENERAL("일반 도서", NvEpCtgyTypeCd.BOOK), + BOOK_EBOOK("전자책", NvEpCtgyTypeCd.BOOK), + BOOK_USED("중고 도서", NvEpCtgyTypeCd.BOOK), + MUSIC_CD("음악 CD", NvEpCtgyTypeCd.MUSIC), + MUSIC_LP("음악 LP", NvEpCtgyTypeCd.MUSIC), + MUSIC_USED("중고 음반", NvEpCtgyTypeCd.MUSIC), + MOVIE_DVD("영화 DVD", NvEpCtgyTypeCd.MOVIE), + MOVIE_BLUERAY("영화 블루레이", NvEpCtgyTypeCd.MOVIE), + MOVIE_VOD("영화 VOD", NvEpCtgyTypeCd.MOVIE), + MOVIE_TICKET("영화 티켓", NvEpCtgyTypeCd.MOVIE), + MOVIE_USED("중고 DVD, 블루레이 등", NvEpCtgyTypeCd.MOVIE), + PRODUCT_GENERAL("일반 상품", NvEpCtgyTypeCd.PRODUCT), + PRODUCT_CASHABLE("환금성 상품", NvEpCtgyTypeCd.PRODUCT), + PRODUCT_CLAIM("클레임", NvEpCtgyTypeCd.PRODUCT), + PRODUCT_DIGITAL_CONTENT("디지털 컨텐츠", NvEpCtgyTypeCd.PRODUCT), + PRODUCT_SUPPORT("후원", NvEpCtgyTypeCd.PRODUCT), + PLAY_TICKET("공연/전시", NvEpCtgyTypeCd.PLAY), + TRAVEL_DOMESTIC("국내 숙박", NvEpCtgyTypeCd.TRAVEL), + TRAVEL_OVERSEA("해외 숙박", NvEpCtgyTypeCd.TRAVEL), + INSURANCE_CAR("자동차보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_DRIVER("운전자보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_HEALTH("건강보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_CHILD("어린이보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_TRAVELER("여행자보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_GOLF("골프보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_ANNUITY("연금보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_ANNUITY_SAVING("연금저축보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_SAVING("저축보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_VARIABLE_ANNUITY("변액적립보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_CANCER("암보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_DENTIST("치아보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_ACCIDENT("상해보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_SEVERANCE("퇴직연금", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_PHONE("휴대폰 보험", NvEpCtgyTypeCd.INSURANCE), + INSURANCE_PET("펫보험", NvEpCtgyTypeCd.INSURANCE), + FLIGHT_TICKET("항공", NvEpCtgyTypeCd.FLIGHT), + FOOD_DELIVERY("음식", NvEpCtgyTypeCd.FOOD), + ETC_ETC("기타", NvEpCtgyTypeCd.ETC), + ; + @Getter + private String code; + @Getter + private String codeNm; + @Getter + private NvEpCtgyTypeCd categoryTypeCd; + + NvEpCtgyIdCd(String codeNm, NvEpCtgyTypeCd categoryTypeCd) { + this.code = this.name(); + this.codeNm = codeNm; + this.categoryTypeCd = categoryTypeCd; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyTypeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyTypeCd.java new file mode 100644 index 0000000..78cee66 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpCtgyTypeCd.java @@ -0,0 +1,38 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code; + +import cokr.xit.ens.core.code.CodeMapperType; +import lombok.Getter; + + +/** + *
      + *
    • 업무 그룹명: 네이버페이 간편결제API - 결제상품 유형
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 22. 오후 2:47:43 + *
    + * + * @author 박민규 + */ + +public enum NvEpCtgyTypeCd implements CodeMapperType { + BOOK("도서"), + MUSIC("음악"), + MOVIE("영화"), + PRODUCT("상품"), + PLAY("공연"), + TRAVEL("여행"), + INSURANCE("보험"), + FLIGHT("항공"), + FOOD("음식"), + ETC("기타"), + ; + @Getter + private String code; + @Getter + private String codeNm; + + NvEpCtgyTypeCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpPayReferrerCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpPayReferrerCd.java new file mode 100644 index 0000000..a21f209 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/code/NvEpPayReferrerCd.java @@ -0,0 +1,39 @@ + +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code; + +import cokr.xit.ens.core.code.CodeMapperType; +import lombok.Getter; + + +/** + *
      + *
    • 업무 그룹명: 네이버페이 간편결제API - 결제 유입경로
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 22. 오후 2:47:43 + *
    + * + * @author 박민규 + */ + +public enum NvEpPayReferrerCd implements CodeMapperType { + NAVER_BOOK("네이버 책 서비스를 통해 유입 후 결제가 발생한 경우"), + NAVER_MUSIC("네이버 뮤직 서비스를 통해 유입 후 결제가 발생한 경우"), + NAVER_SHOPPING("네이버 쇼핑 서비스를 통해 유입 후 결제가 발생한 경우"), + NAVER_MAP("네이버 지도 서비스를 통해 유입 후 결제가 발생한 경우"), + NAVER_PLACE("네이버 플레이스 서비스를 통해 유입 후 결제가 발생한 경우"), + SEARCH_AD("검색 광고를 통해 유입 후 결제가 발생한 경우"), + NAVER_SEARCH("네이버 통합 검색 바로가기를 통해 유입 후 결제가 발생한 경우"), + BRAND_SEARCH("브랜드 검색을 통해 유입 후 결제가 발생한 경우"), + PARTNER_DIRECT("가맹점 사이트에 바로 접속하여 결제가 발생한 경우"), + ETC("그 외의 유입을 통해 결제가 발생한 경우"), + ; + @Getter + private String code; + @Getter + private String codeNm; + + NvEpPayReferrerCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayAbleReqData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayAbleReqData.java new file mode 100644 index 0000000..c6628bf --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayAbleReqData.java @@ -0,0 +1,55 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 네이버페이 결제가능여부 요청데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class NvPayAbleReqData { + @NotEmpty(message = "계약번호는 필수 입력값 입니다.") + @Length(max = 50, message = "계약번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ") + @JsonProperty("billerUserKey") + @JsonAlias({"biller_user_key"}) + @SerializedName(value = "billerUserKey", alternate = {"biller_user_key"}) + private String billerUserKey; + @NotBlank(message = "상품명은 필수 입력값 입니다.") + @Length(max = 128, message = "상품명의 최대길이를 초과 했습니다.") + @Schema(required = true, title = "상품명", example = "테스트상품") + @JsonProperty("productName") + @JsonAlias({"product_name"}) + @SerializedName(value = "productName", alternate = {"product_name"}) + private String productName; + @NotNull(message = "총 결제 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "총 결제 금액", example = "1000") + @JsonProperty("totalPayAmount") + @JsonAlias({"total_pay_amount"}) + @SerializedName(value = "totalPayAmount", alternate = {"total_pay_amount"}) + private Integer totalPayAmount; + @NotNull(message = "과세 대상 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "과세 대상 금액", example = "1000") + @JsonProperty("taxScopeAmount") + @JsonAlias({"tax_scope_amount"}) + @SerializedName(value = "taxScopeAmount", alternate = {"tax_scope_amount"}) + private Integer taxScopeAmount; + @NotNull(message = "면세 대상 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "면세 대상 금액", example = "0") + @JsonProperty("taxExScopeAmount") + @JsonAlias({"tax_ex_scope_amount"}) + @SerializedName(value = "taxExScopeAmount", alternate = {"tax_ex_scope_amount"}) + private Integer taxExScopeAmount; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayApplyRespData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayApplyRespData.java new file mode 100644 index 0000000..61f7aeb --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayApplyRespData.java @@ -0,0 +1,35 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.able.Detail; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 네이버페이 결제승인 응답데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class NvPayApplyRespData { + @NotEmpty(message = "결제번호는 필수 입력값 입니다.") + @Length(max = 50, message = "결제번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "네이버페이 결제번호", example = " ") + @JsonProperty("paymentId") + @JsonAlias({"payment_id"}) + @SerializedName(value = "paymentId", alternate = {"payment_id"}) + private String paymentId; + @NotNull(message = "결제결과 상세정보는 필수 입력값 입니다.") + @Schema(required = true, title = "결제결과 상세정보", example = " ") + @Valid + private Detail detail; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayNoticeRespData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayNoticeRespData.java new file mode 100644 index 0000000..f068b6d --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayNoticeRespData.java @@ -0,0 +1,96 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.notice.ProductItem; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 네이버페이 결제정보 응답데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) //2023.03.14 네이버페이 검수 결과 - 요청대상이 아닌 null 값 제외 +public class NvPayNoticeRespData { + @NotBlank(message = "상품명은 필수 입력값 입니다.") + @Length(max = 128, message = "상품명의 최대길이를 초과 했습니다.") + @Schema(required = true, title = "상품명", example = "테스트상품") + @JsonProperty("productName") + @JsonAlias({"product_name"}) + @SerializedName(value = "productName", alternate = {"product_name"}) + private String productName; + @NotNull(message = "상품 수량은 필수 입력값 입니다.") + @Schema(required = true, title = "상품 수량", example = "") + @JsonProperty("productCount") + @JsonAlias({"product_count"}) + @SerializedName(value = "productCount", alternate = {"product_count"}) + private Integer productCount; + @NotNull(message = "총 결제 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "총 결제 금액", example = "1000") + @JsonProperty("totalPayAmount") + @JsonAlias({"total_pay_amount"}) + @SerializedName(value = "totalPayAmount", alternate = {"total_pay_amount"}) + private Integer totalPayAmount; + @NotNull(message = "과세 대상 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "과세 대상 금액", example = "1000") + @JsonProperty("taxScopeAmount") + @JsonAlias({"tax_scope_amount"}) + @SerializedName(value = "taxScopeAmount", alternate = {"tax_scope_amount"}) + private Integer taxScopeAmount; + @NotNull(message = "면세 대상 금액은 필수 입력값 입니다.") + @Schema(required = true, title = "면세 대상 금액", example = "0") + @JsonProperty("taxExScopeAmount") + @JsonAlias({"tax_ex_scope_amount"}) + @SerializedName(value = "taxExScopeAmount", alternate = {"tax_ex_scope_amount"}) + private Integer taxExScopeAmount; + @Schema(required = false, title = "컵 보증금 대상 금액", example = "0") + @JsonProperty("environmentDepositAmount") + @JsonAlias({"environment_deposit_amount"}) + @SerializedName(value = "environmentDepositAmount", alternate = {"environment_deposit_amount"}) + private Integer environmentDepositAmount; + @NotNull(message = "상품 목록은 필수조건 입니다.") + @Schema(required = false, title = "상품 목록", example = " ") + @JsonProperty("productItems") + @JsonAlias({"product_items"}) + @SerializedName(value = "productItems", alternate = {"product_items"}) + @Valid +// private List> productItems; + private List productItems; + @NotBlank(message = "리턴URL는 필수조건 입니다.") + @Length(max = 1000, message = "리턴URL의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "네이버페이 결제 후 리턴URL", example = " ") + @JsonProperty("returnUrl") + @JsonAlias({"return_url"}) + @SerializedName(value = "returnUrl", alternate = "return_url") + private String returnUrl; + + @Length(max = 64, message = "구매자 성명의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "구매자 성명", example = " ") + @JsonProperty("purchaserName") + @JsonAlias({"purchaser_name"}) + @SerializedName(value = "purchaserName", alternate = "purchaser_name") + private String purchaserName; + @Length(max = 64, message = "구매자 생년월일의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "구매자 생년월일(yyyyMMdd)", example = " ") + @JsonProperty("purchaserBirthday") + @JsonAlias({"purchaser_birthday"}) + @SerializedName(value = "purchaserBirthday", alternate = "purchaser_birthday") + private String purchaserBirthday; +// @Schema(required = false, title = "도서/공연비 소득공제 대상 여부", example = " ") +// @JsonProperty("extraDeduction") +// @JsonAlias({"extra_deduction"}) +// @SerializedName(value = "extraDeduction", alternate = "extra_deduction") +// private Boolean extraDeduction; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultDetail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultDetail.java new file mode 100644 index 0000000..0afa076 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultDetail.java @@ -0,0 +1,211 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +/** + * 네이버페이 결제결과 요청데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class NvPayResultDetail { + @NotBlank(message = "결제번호는 필수 입력값 입니다.") + @Length(max = 50, message = "결제번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "네이버페이 결제번호", example = " ") + @JsonProperty("paymentId") + @JsonAlias({"payment_id"}) + @SerializedName(value = "paymentId", alternate = {"payment_id"}) + private String paymentId; + + @NotBlank(message = "결제 이력번호는 필수 입력값 입니다.") + @Length(max = 50, message = "결제 이력번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "네이버페이 결제 이력 번호", example = " ") + @JsonProperty("payHistId") + @JsonAlias({"pay_hist_id"}) + @SerializedName(value = "payHistId", alternate = {"pay_hist_id"}) + private String payHistId; + @Length(max = 50, message = "가맹점 아이디의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "가맹점 아이디(가맹점센터 로그인 아이디)", example = " ") + @JsonProperty("merchantId") + @JsonAlias({"merchant_id"}) + @SerializedName(value = "merchantId", alternate = {"merchant_id"}) + private String merchantId; + @Length(max = 50, message = "가맹점명의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "가맹점명", example = " ") + @JsonProperty("merchantName") + @JsonAlias({"merchant_name"}) + @SerializedName(value = "merchantName", alternate = {"merchant_name"}) + private String merchantName; + @Length(max = 64, message = "가맹점의 결제번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "가맹점의 결제번호", example = " ") + @JsonProperty("merchantPayKey") + @JsonAlias({"merchant_pay_key"}) + @SerializedName(value = "merchantPayKey", alternate = {"merchant_pay_key"}) + private String merchantPayKey; + @Length(max = 50, message = "가맹점의 사용자 키의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "가맹점의 사용자 키", example = " ") + @JsonProperty("merchantUserKey") + @JsonAlias({"merchant_user_key"}) + @SerializedName(value = "merchantUserKey", alternate = {"merchant_user_key"}) + private String merchantUserKey; + @Length(max = 2, message = "결제승인 유형의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제승인 유형", example = " ") + @JsonProperty("admissionTypeCode") + @JsonAlias({"admission_type_code"}) + @SerializedName(value = "admissionTypeCode", alternate = {"admission_type_code"}) + private String admissionTypeCode; + @Length(max = 14, message = "결제/취소일시의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제/취소 일시(YYYYMMDDHH24MISS)", example = " ") + @JsonProperty("admissionYmdt") + @JsonAlias({"admission_ymdt"}) + @SerializedName(value = "admissionYmdt", alternate = {"admission_ymdt"}) + private String admissionYmdt; + @Length(max = 50, message = "거래완료 일시의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "거래완료 일시(정산기준날짜, YYYYMMDDHH24MISS)", example = " ") + @JsonProperty("tradeConfirmYmdt") + @JsonAlias({"trade_confirm_ymdt"}) + @SerializedName(value = "tradeConfirmYmdt", alternate = {"trade_confirm_ymdt"}) + private String tradeConfirmYmdt; + @Length(max = 10, message = "결제/취소 시도 최종결과의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제/취소 시도에 대한 최종결과", example = " ") + @JsonProperty("admissionState") + @JsonAlias({"admission_state"}) + @SerializedName(value = "admissionState", alternate = {"admission_state"}) + private String admissionState; + @Schema(required = true, title = "총 결제 금액", example = " ") + @JsonProperty("totalPayAmount") + @JsonAlias({"total_pay_amount"}) + @SerializedName(value = "totalPayAmount", alternate = {"total_pay_amount"}) + private Integer totalPayAmount; + @Schema(required = true, title = "주 결제 수단 결제 금액", example = " ") + @JsonProperty("primaryPayAmount") + @JsonAlias({"primary_pay_amount"}) + @SerializedName(value = "primaryPayAmount", alternate = {"primary_pay_amount"}) + private Integer primaryPayAmount; + @Schema(required = true, title = "네이버페이 포인트/머니 결제 금액", example = " ") + @JsonProperty("npointPayAmount") + @JsonAlias({"npoint_pay_amount"}) + @SerializedName(value = "npointPayAmount", alternate = {"npoint_pay_amount"}) + private Integer npointPayAmount; + @Schema(required = true, title = "기프트카드 결제 금액", example = " ") + @JsonProperty("giftCardAmount") + @JsonAlias({"gift_card_amount"}) + @SerializedName(value = "giftCardAmount", alternate = {"gift_card_amount"}) + private Integer giftCardAmount; + @Schema(required = true, title = "과세 결제 금액", example = " ") + @JsonProperty("taxScopeAmount") + @JsonAlias({"tax_scope_amount"}) + @SerializedName(value = "taxScopeAmount", alternate = {"tax_scope_amount"}) + private Integer taxScopeAmount; + @Schema(required = true, title = "면세 결제 금액", example = " ") + @JsonProperty("taxExScopeAmount") + @JsonAlias({"tax_ex_scope_amount"}) + @SerializedName(value = "taxExScopeAmount", alternate = {"tax_ex_scope_amount"}) + private Integer taxExScopeAmount; + @Schema(required = true, title = "컵 보증금 결제 금액", example = " ") + @JsonProperty("environmentDepositAmount") + @JsonAlias({"environment_deposit_amount"}) + @SerializedName(value = "environmentDepositAmount", alternate = {"environment_deposit_amount"}) + private Integer environmentDepositAmount; + @Length(max = 10, message = "주 결제 수단의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "주 결제 수단", example = " ") + @JsonProperty("primaryPayMeans") + @JsonAlias({"primary_pay_means"}) + @SerializedName(value = "primaryPayMeans", alternate = {"primary_pay_means"}) + private String primaryPayMeans; + @Length(max = 10, message = "주 결제 수단 카드사의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "주 결제 수단 카드사", example = " ") + @JsonProperty("cardCorpCode") + @JsonAlias({"card_corp_code"}) + @SerializedName(value = "cardCorpCode", alternate = {"card_corp_code"}) + private String cardCorpCode; + @Length(max = 50, message = "일부 마스킹 된 신용카드 번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "일부 마스킹 된 신용카드 번호", example = " ") + @JsonProperty("cardNo") + @JsonAlias({"card_no"}) + @SerializedName(value = "cardNo", alternate = {"card_no"}) + private String cardNo; + @Length(max = 30, message = "카드승인번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "카드승인번호", example = " ") + @JsonProperty("cardAuthNo") + @JsonAlias({"card_auth_no"}) + @SerializedName(value = "cardAuthNo", alternate = {"card_auth_no"}) + private String cardAuthNo; + @Schema(required = true, title = "할부 개월 수(일시불은 0)", example = " ") + @JsonProperty("cardInstCount") + @JsonAlias({"card_inst_count"}) + @SerializedName(value = "cardInstCount", alternate = {"card_inst_count"}) + private Integer cardInstCount; + @Schema(required = true, title = "카드사 포인트 사용유무", example = " ") + @JsonProperty("usedCardPoint") + @JsonAlias({"used_card_point"}) + @SerializedName(value = "usedCardPoint", alternate = {"used_card_point"}) + private Boolean usedCardPoint; + @Length(max = 10, message = "주 결제 수단 은행의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "주 결제 수단 은행", example = " ") + @JsonProperty("bankCorpCode") + @JsonAlias({"bank_corp_code"}) + @SerializedName(value = "bankCorpCode", alternate = {"bank_corp_code"}) + private String bankCorpCode; + @Length(max = 50, message = "일부 마스킹 된 계좌번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "일부 마스킹 된 계좌번호", example = " ") + @JsonProperty("bankAccountNo") + @JsonAlias({"bank_account_no"}) + @SerializedName(value = "bankAccountNo", alternate = {"bank_account_no"}) + private String bankAccountNo; + @Length(max = 128, message = "상품명의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "상품명", example = " ") + @JsonProperty("productName") + @JsonAlias({"product_name"}) + @SerializedName(value = "productName", alternate = {"product_name"}) + private String productName; + @Schema(required = true, title = "정산예정금액과 결제 수수료금액 계산 여부(true/false)", example = " ") + @JsonProperty("settleExpected") + @JsonAlias({"settle_expected"}) + @SerializedName(value = "settleExpected", alternate = {"settle_expected"}) + private Boolean settleExpected; + @Schema(required = true, title = "정산 예정 금액", example = " ") + @JsonProperty("settleExpectAmount") + @JsonAlias({"settle_expect_amount"}) + @SerializedName(value = "settleExpectAmount", alternate = {"settle_expect_amount"}) + private Integer settleExpectAmount; + @Schema(required = true, title = "결제 수수료 금액", example = " ") + @JsonProperty("payCommissionAmount") + @JsonAlias({"pay_commission_amount"}) + @SerializedName(value = "payCommissionAmount", alternate = {"pay_commission_amount"}) + private Integer payCommissionAmount; + @Schema(required = true, title = "도서/공연 소득공제 여부", example = " ") + @JsonProperty("extraDeduction") + @JsonAlias({"extra_deduction"}) + @SerializedName(value = "extraDeduction", alternate = {"extra_deduction"}) + private Boolean extraDeduction; + @Length(max = 8, message = "이용완료일의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "이용완료일(yyyymmdd)", example = " ") + @JsonProperty("useCfmYmdt") + @JsonAlias({"use_cfm_ymdt"}) + @SerializedName(value = "useCfmYmdt", alternate = {"use_cfm_ymdt"}) + private String useCfmYmdt; + @Length(max = 400, message = "별도 예비필드의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "별도 예비필드", example = " ") + @JsonProperty("merchantExtraParameter") + @JsonAlias({"merchant_extra_parameter"}) + @SerializedName(value = "merchantExtraParameter", alternate = {"merchant_extra_parameter"}) + private String merchantExtraParameter; + @Length(max = 28, message = "암호화된 사용자 구분값의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "암호화된 사용자 구분값", example = " ") + @JsonProperty("userIdentifier") + @JsonAlias({"user_identifier"}) + @SerializedName(value = "userIdentifier", alternate = {"user_identifier"}) + private String userIdentifier; +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultReqData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultReqData.java new file mode 100644 index 0000000..437efae --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/NvPayResultReqData.java @@ -0,0 +1,31 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; + +/** + * 네이버페이 결제결과 요청데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class NvPayResultReqData { + @NotBlank(message = "결제번호는 필수 입력값 입니다.") + @Length(max = 50, message = "결제번호의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "네이버페이 결제번호", example = " ") + @JsonProperty("paymentId") + @JsonAlias({"payment_id"}) + @SerializedName(value = "paymentId", alternate = {"payment_id"}) + private String paymentId; + @Valid + private NvPayResultDetail detail; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/able/Detail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/able/Detail.java new file mode 100644 index 0000000..644c1e1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/able/Detail.java @@ -0,0 +1,240 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.able; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 네이버페이 결제승인 응답데이터 상세 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class Detail { + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("paymentId") + @JsonAlias({"payment_id"}) + @SerializedName(value = "paymentId", alternate = "payment_id") + private String paymentId; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("payHistId") + @JsonAlias({"pay_hist_id"}) + @SerializedName(value = "payHistId", alternate = "pay_hist_id") + private String payHistId; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("merchantId") + @JsonAlias({"merchant_id"}) + @SerializedName(value = "merchantId", alternate = "merchant_id") + private String merchantId; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("merchantName") + @JsonAlias({"merchant_name"}) + @SerializedName(value = "merchantName", alternate = "merchant_name") + private String merchantName; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 64, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("merchantPayKey") + @JsonAlias({"merchant_pay_key"}) + @SerializedName(value = "merchantPayKey", alternate = "merchant_pay_key") + private String merchantPayKey; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("merchantUserKey") + @JsonAlias({"merchant_user_key"}) + @SerializedName(value = "merchantUserKey", alternate = "merchant_user_key") + private String merchantUserKey; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 2, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("admissionTypeCode") + @JsonAlias({"admission_type_code"}) + @SerializedName(value = "admissionTypeCode", alternate = "admission_type_code") + private String admissionTypeCode; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 14, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("admissionYmdt") + @JsonAlias({"admission_ymdt"}) + @SerializedName(value = "admissionYmdt", alternate = "admission_ymdt") + private String admissionYmdt; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("tradeConfirmYmdt") + @JsonAlias({"trade_confirm_ymdt"}) + @SerializedName(value = "tradeConfirmYmdt", alternate = "trade_confirm_ymdt") + private String tradeConfirmYmdt; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 10, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("admissionState") + @JsonAlias({"admission_state"}) + @SerializedName(value = "admissionState", alternate = "admission_state") + private String admissionState; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("totalPayAmount") + @JsonAlias({"total_pay_amount"}) + @SerializedName(value = "totalPayAmount", alternate = "total_pay_amount") + private Integer totalPayAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("primaryPayAmount") + @JsonAlias({"primary_pay_amount"}) + @SerializedName(value = "primaryPayAmount", alternate = "primary_pay_amount") + private Integer primaryPayAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("npointPayAmount") + @JsonAlias({"npoint_pay_amount"}) + @SerializedName(value = "npointPayAmount", alternate = "npoint_pay_amount") + private Integer npointPayAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("giftCardAmount") + @JsonAlias({"gift_card_amount"}) + @SerializedName(value = "giftCardAmount", alternate = "gift_card_amount") + private Integer giftCardAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("taxScopeAmount") + @JsonAlias({"tax_scope_amount"}) + @SerializedName(value = "taxScopeAmount", alternate = "tax_scope_amount") + private Integer taxScopeAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("taxExScopeAmount") + @JsonAlias({"tax_ex_scope_amount"}) + @SerializedName(value = "taxExScopeAmount", alternate = "tax_ex_scope_amount") + private Integer taxExScopeAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("environmentDepositAmount") + @JsonAlias({"environment_deposit_amount"}) + @SerializedName(value = "environmentDepositAmount", alternate = "environment_deposit_amount") + private Integer environmentDepositAmount; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 10, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("primaryPayMeans") + @JsonAlias({"primary_pay_means"}) + @SerializedName(value = "primaryPayMeans", alternate = "primary_pay_means") + private String primaryPayMeans; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 10, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("cardCorpCode") + @JsonAlias({"card_corp_code"}) + @SerializedName(value = "cardCorpCode", alternate = "card_corp_code") + private String cardCorpCode; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("cardNo") + @JsonAlias({"card_no"}) + @SerializedName(value = "cardNo", alternate = "card_no") + private String cardNo; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 30, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("cardAuthNo") + @JsonAlias({"card_auth_no"}) + @SerializedName(value = "cardAuthNo", alternate = "card_auth_no") + private String cardAuthNo; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("cardInstCount") + @JsonAlias({"card_inst_count"}) + @SerializedName(value = "cardInstCount", alternate = "card_inst_count") + private Integer cardInstCount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("usedCardPoint") + @JsonAlias({"used_card_point"}) + @SerializedName(value = "usedCardPoint", alternate = "used_card_point") + private Boolean usedCardPoint; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 10, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("bankCorpCode") + @JsonAlias({"bank_corp_code"}) + @SerializedName(value = "bankCorpCode", alternate = "bank_corp_code") + private String bankCorpCode; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 50, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("bankAccountNo") + @JsonAlias({"bank_account_no"}) + @SerializedName(value = "bankAccountNo", alternate = "bank_account_no") + private String bankAccountNo; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 128, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("productName") + @JsonAlias({"product_name"}) + @SerializedName(value = "productName", alternate = "product_name") + private String productName; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("settleExpected") + @JsonAlias({"settle_expected"}) + @SerializedName(value = "settleExpected", alternate = "settle_expected") + private Boolean settleExpected; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("settleExpectAmount") + @JsonAlias({"settle_expect_amount"}) + @SerializedName(value = "settleExpectAmount", alternate = "settle_expect_amount") + private Integer settleExpectAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("payCommissionAmount") + @JsonAlias({"pay_commission_amount"}) + @SerializedName(value = "payCommissionAmount", alternate = "pay_commission_amount") + private Integer payCommissionAmount; + @NotNull(message = "은 필수조건 입니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("extraDeduction") + @JsonAlias({"extra_deduction"}) + @SerializedName(value = "extraDeduction", alternate = "extra_deduction") + private Boolean extraDeduction; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 8, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("useCfmYmdt") + @JsonAlias({"use_cfm_ymdt"}) + @SerializedName(value = "useCfmYmdt", alternate = "use_cfm_ymdt") + private String useCfmYmdt; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 4000, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("merchantExtraParameter") + @JsonAlias({"merchant_extra_parameter"}) + @SerializedName(value = "merchantExtraParameter", alternate = "merchant_extra_parameter") + private String merchantExtraParameter; + @NotBlank(message = "은 필수조건 입니다.") + @Length(max = 28, message = "의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "", example = " ") + @JsonProperty("userIdentifier") + @JsonAlias({"user_identifier"}) + @SerializedName(value = "userIdentifier", alternate = "user_identifier") + private String userIdentifier; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/notice/ProductItem.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/notice/ProductItem.java new file mode 100644 index 0000000..3e634c4 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/process/model/config/notice/ProductItem.java @@ -0,0 +1,74 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.model.config.notice; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.process.code.NvEpCtgyTypeCd; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 네이버페이 결제정보 응답데이터 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) //2023.03.14 네이버페이 검수 결과 - 요청대상이 아닌 null 값 제외 +public class ProductItem { + @NotNull(message = "결제상품 유형은 필수조건 입니다.") +// @Length(max = 10, message = "결제상품 유형의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제상품 유형", example = " ") + @JsonProperty("categoryType") + @JsonAlias({"category_type"}) + @SerializedName(value = "categoryType", alternate = "category_type") + private NvEpCtgyTypeCd categoryType; + @NotBlank(message = "결제상품 분류는 필수조건 입니다.") + @Length(max = 16, message = "결제상품 분류의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제상품 분류", example = " ") + @JsonProperty("categoryId") + @JsonAlias({"category_id"}) + @SerializedName(value = "categoryId", alternate = "category_id") + private String categoryId; + @NotBlank(message = "결제상품 식별값은 필수조건 입니다.") + @Length(max = 100, message = "결제상품 식별값의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "결제상품 식별값", example = " ") + private String uid; + @NotBlank(message = "상품명은 필수조건 입니다.") + @Length(max = 128, message = "상품명의 최대 길이를 초과 했습니다.") + @Schema(required = true, title = "상품명", example = " ") + private String name; + @Length(max = 20, message = "결제상품유형의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "결제상품유형", example = " ") + @JsonProperty("payReferrer") + @JsonAlias({"pay_referrer"}) + @SerializedName(value = "payReferrer", alternate = "pay_referrer") + private String payReferrer; + @Length(max = 8, message = "시작일의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "시작일(yyyyMMdd)", example = "20160701") + @JsonProperty("startDate") + @JsonAlias({"start_date"}) + @SerializedName(value = "startDate", alternate = "start_date") + private String startDate; + @Length(max = 8, message = "종료일의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "종료일(yyyMMdd)", example = "20160701") + @JsonProperty("endDate") + @JsonAlias({"end_date"}) + @SerializedName(value = "endDate", alternate = "end_date") + private String endDate; + @Length(max = 30, message = "하위판매자식별키의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "하위판매자식별키", example = " ") + @JsonProperty("sellerId") + @JsonAlias({"seller_id"}) + @SerializedName(value = "sellerId", alternate = "seller_id") + private String sellerId; + @NotNull(message = "결제 상품 개수는 필수조건 입니다.") + @Schema(required = true, title = "결제 상품 개수", example = "1") + private Integer count; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/repair/kit/RepairNvPayResultTransferFail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/repair/kit/RepairNvPayResultTransferFail.java new file mode 100644 index 0000000..68849d1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/nv/service/repair/kit/RepairNvPayResultTransferFail.java @@ -0,0 +1,27 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.nv.service.repair.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.kit.RepairPayResultTransferFail; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.Builder; + + +public class RepairNvPayResultTransferFail extends RepairPayResultTransferFail { + @Builder + public RepairNvPayResultTransferFail(JPAQueryFactory query, RepairPayRsltFwdFailSearchDTO searchDTO) { + this.query = query; + this.searchDTO = searchDTO; + } + + @Override + protected String getPayResultApiUrl(OrgMng orgMng) { + return orgMng.getNvBpPayresultApi(); + } + + @Override + protected BillSeCd getBillSeCd() { + return BillSeCd.bpNv; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayApi.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayApi.java new file mode 100644 index 0000000..e660465 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayApi.java @@ -0,0 +1,170 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support; + +import cokr.xit.ens.core.utils.CmmnUtil; +import org.springframework.http.*; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +public interface PayApi { + + /** + * 결제 URL 생성정보 요청 + * + * @param uri + * @param mParam + * @return + */ + ResponseEntity payUrl(String uri, Map mParam, HttpHeaders headers); + + /** + * 결제정보 요청 + * + * @param uri + * @param mParam + * @return + */ + ResponseEntity payNotice(String uri, Map mParam, HttpHeaders headers); + + /** + * 납부가능여부 + * + * @param uri + * @param mParam + * @return + */ + ResponseEntity payAble(String uri, Map mParam, HttpHeaders headers); + + /** + * 납부결과 + * + * @param uri + * @param mParam + * @return + */ + ResponseEntity payResult(String uri, Map mParam, HttpHeaders headers); + + /** + * 결제취소 + * + * @param uri + * @param mParam + * @return + */ + ResponseEntity payCancelResult(String uri, Map mParam, HttpHeaders headers); + + + /** + * API 호출 + * + * @param method 호출메소드(GET/POST/PUT/DELETE) + * @param url 호출 URL + * @param body 파라미터 + * @param headers 요청헤더정보 + * @return + * @author 박민규 + */ + default ResponseEntity callApi(HttpMethod method, String url, String body, HttpHeaders headers) { + return this.callApi(method, url, body, headers, 5000, 30000); + } + + /** + * API 호출 + * + * @param method 호출메소드(GET/POST/PUT/DELETE) + * @param url 호출 URL + * @param body 파라미터 + * @param headers 요청헤더정보 + * @param connectTimeout 통신 연결 제한시간(ms) + * @param readTimeout 응답데이터 read 제한시간(ms) + * @return + * @author 박민규 + */ + default ResponseEntity callApi(HttpMethod method, String url, String body, HttpHeaders headers, int connectTimeout, int readTimeout) { + StringBuffer sb = new StringBuffer(); + StringBuffer log = new StringBuffer(); + log.append(getClass().getSimpleName()); + ResponseEntity responseEntity = null; + try { + + HttpEntity entity = null; + UriComponents uri = null; + switch (method) { + case GET: + entity = new HttpEntity<>(headers); + uri = UriComponentsBuilder + .fromHttpUrl(String.format("%s?%s", url, body == null ? "" : body)) +// .encode(StandardCharsets.UTF_8) //"%"기호가 "%25"로 인코딩 발생하여 주석처리 함. + .build(false); + break; + case POST: + entity = new HttpEntity<>(body, headers); + uri = UriComponentsBuilder + .fromHttpUrl(url) + .encode(StandardCharsets.UTF_8) + .build(); + break; + + default: + break; + } + + sb.append("url => " + uri.toString()) + .append("\n method => " + method) + .append("\n headers => " + entity.getHeaders().toString()) + .append("\n body => " + entity.getBody()); + + + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); + factory.setConnectTimeout(connectTimeout); + factory.setReadTimeout(readTimeout); + RestTemplate restTemplate = new RestTemplate(factory); + responseEntity = restTemplate.exchange(URI.create(uri.toString()), method, entity, String.class); + + } catch (HttpServerErrorException e) { + responseEntity = new ResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); + log.append(System.getProperty("line.separator")) + .append("call API 서버오류") + .append("[ error ]: ") + .append(CmmnUtil.printStackTraceToString(e)); + } catch (HttpClientErrorException e) { + responseEntity = new ResponseEntity(e.getResponseBodyAsString(), e.getStatusCode()); + log.append(System.getProperty("line.separator")) + .append("call API 클라이언트오류") + .append("[ error ]: ") + .append(CmmnUtil.printStackTraceToString(e)); + } catch (RestClientException e) { + responseEntity = new ResponseEntity(e.getMessage(), HttpStatus.REQUEST_TIMEOUT); + log.append(System.getProperty("line.separator")) + .append("RestAPI 호출 오류") + .append("[ error ]: ") + .append(CmmnUtil.printStackTraceToString(e)); + } catch (Exception e) { + responseEntity = new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + log.append(System.getProperty("line.separator")) + .append("call API 기타오류") + .append("[ error ]: ") + .append(CmmnUtil.printStackTraceToString(e)); + } finally { + log.append(System.getProperty("line.separator")) + .append("[ REQUEST ]-----------------------------------------------------------------------") + .append(System.getProperty("line.separator")) + .append(sb.toString()) + .append(System.getProperty("line.separator")) + .append("[ RESPONSE ]-----------------------------------------------------------------------") + .append(System.getProperty("line.separator")) + .append(responseEntity.getBody()); + System.out.println(log.toString()); + } + + return responseEntity; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayController.java new file mode 100644 index 0000000..46897d1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayController.java @@ -0,0 +1,51 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support; + +/** + * 결제 컨트롤러 + * + * @param 리턴타입 + * @param

    파라미터 + */ +public interface PayController { + + /** + * 청구서링크 생성 + * + * @param p + * @return + */ + T gnrUrl(P p); + + /** + * 결제정보 + * + * @param p + * @return + */ + T payNotice(P p); + + /** + * 결제 전 납부가능여부 + * + * @param p + * @return + */ + T payAble(P p); + + /** + * 결제 후 납부결과 + * + * @param p + * @return + */ + T payResult(P p); + + /** + * 결제취소 + * + * @param p + * @return + */ + T payCancel(P p); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayRepairController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayRepairController.java new file mode 100644 index 0000000..6ee4d47 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayRepairController.java @@ -0,0 +1,84 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support; + +import cokr.xit.ens.core.aop.EnsResponseVO; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.PayRepairServiceFactory; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.Map; + +@Tag(name = "PayRepairController") +@Slf4j +@RestController +@RequiredArgsConstructor +public class PayRepairController { + private final PayRepairServiceFactory payRepairServiceFactory; + + @Parameters({ + @Parameter(name = "paySe", example = "kko", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "납부(결제)결과전달 실패자료 조회") + @PostMapping(value = "/bill/pay/repair/{paySe}/trsf/fail/payresult/find", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity findTransferFailData(@PathVariable String paySe, @RequestBody RepairPayRsltFwdFailSearchDTO searchDTO) { + + EnsResponseVO> result = null; + try { + + if (Arrays.stream(PayRepairServiceFactory.PRepairPaySe.values()).noneMatch(pTriggerPaySe -> pTriggerPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + final PayRepairServiceFactory.PRepairPaySe pTriggerPaySe = PayRepairServiceFactory.PRepairPaySe.valueOf(paySe); + + result = EnsResponseVO.>okBuilder() + .resultInfo((Map) payRepairServiceFactory.getService(pTriggerPaySe).findTransferFailedPayResultDataList(searchDTO)) + .build(); + } catch (EnsException e) { + result = EnsResponseVO.>errBuilder() + .errCode(e.getErrCd()) + .errMsg(e.getMessage()) + .build(); + } + return new ResponseEntity>>(result, HttpStatus.OK); + } + + @Parameters({ + @Parameter(name = "paySe", example = "kko", required = true, in = ParameterIn.PATH), + }) + @Operation(summary = "납부(결제)결과전달 실패자료 전송") + @PostMapping(value = "/bill/pay/repair/{paySe}/trsf/fail/payresult", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity sendTransferFailData(@PathVariable String paySe, @RequestBody RepairPayRsltFwdFailSearchDTO searchDTO) { + + EnsResponseVO> result = null; + try { + + if (Arrays.stream(PayRepairServiceFactory.PRepairPaySe.values()).noneMatch(pTriggerPaySe -> pTriggerPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + final PayRepairServiceFactory.PRepairPaySe pTriggerPaySe = PayRepairServiceFactory.PRepairPaySe.valueOf(paySe); + + result = EnsResponseVO.>okBuilder() + .resultInfo((Map) payRepairServiceFactory.getService(pTriggerPaySe).sendTransferFailedPayResultDataList(searchDTO)) + .build(); + } catch (EnsException e) { + result = EnsResponseVO.>errBuilder() + .errCode(e.getErrCd()) + .errMsg(e.getMessage()) + .build(); + } + return new ResponseEntity>>(result, HttpStatus.OK); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayUseSysController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayUseSysController.java new file mode 100644 index 0000000..929be5e --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PayUseSysController.java @@ -0,0 +1,11 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support; + +/** + * 결제이용시스템 컨트롤러 + * + * @param 리턴타입 + * @param

    파라미터 + */ +public interface PayUseSysController extends PayController { + +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PaymentTriggerController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PaymentTriggerController.java new file mode 100644 index 0000000..1e4aea6 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/PaymentTriggerController.java @@ -0,0 +1,95 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support; + +import cokr.xit.ens.core.aop.EnsResponseVO; +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger.PaymentTriggerService; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger.PaymentTriggerServiceFactory; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng; +import com.querydsl.jpa.impl.JPAQueryFactory; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Tag(name = "PaymentTriggerController") +@Slf4j +@RestController +@RequiredArgsConstructor +public class PaymentTriggerController { + + private final JPAQueryFactory query; + private final PaymentTriggerServiceFactory paymentTriggerServiceFactory; + + @CrossOrigin(origins = "*") +// @CrossOrigin(origins = {"http://localhost:8080", "https://localhost:8080"}) +// @CrossOrigin(originPatterns = {"http:**", "https:**"}) + @Parameters({ + @Parameter(name = "paySe", example = "kko", required = true, in = ParameterIn.PATH), + @Parameter(name = "billUid", example = "청구서UID", required = true, in = ParameterIn.PATH) + }) + @Operation(summary = "납부(결제)정보 요청") + @GetMapping(value = "/bill/pay/trg/{paySe}/{billUid}/payinf", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity payInfo(@PathVariable String paySe, @PathVariable String billUid) { + + EnsResponseVO> result = null; + try { + + if (Arrays.stream(PaymentTriggerServiceFactory.PTriggerPaySe.values()).noneMatch(pTriggerPaySe -> pTriggerPaySe.name().equals(paySe))) + throw new EnsException(EnsErrCd.INVALID_REQUEST_URL, EnsErrCd.INVALID_REQUEST_URL.getCodeNm()); + final PaymentTriggerServiceFactory.PTriggerPaySe pTriggerPaySe = PaymentTriggerServiceFactory.PTriggerPaySe.valueOf(paySe); + + + Bill bill = Optional.ofNullable(query.selectFrom(QBill.bill).leftJoin(QBill.bill.orgMng, QOrgMng.orgMng).fetchJoin().where(QBill.bill.billUid.eq(billUid)).fetchOne()) + .filter(entity -> entity != null) + .map(entity -> { + if (entity.getPaidAt()) { + throw new EnsException(EnsErrCd.PAYMENT_ALREADY_CMPLTED + , String.format("%s\n -.결제수단: %s\n -.결제일시: %s" + , EnsErrCd.PAYMENT_ALREADY_CMPLTED.getCodeNm(), entity.getPaidType().getCodeNm(), entity.getPaidDt())); + } + return entity; + }) + .orElseThrow(() -> new EnsException(EnsErrCd.NO_DATA_FOUND, "청구 자료를 찾을 수 없습니다.")); + + if (CmmnUtil.isEmpty(bill.getOrgMng())) + throw new EnsException(EnsErrCd.NO_DATA_FOUND, "청구결제 위탁기관을 찾을 수 없습니다."); + + + Map param = new HashMap<>(); + param.put(PaymentTriggerService.PTriggerDataKeys.bill, bill); + param.put(PaymentTriggerService.PTriggerDataKeys.billUid, billUid); + + + result = EnsResponseVO.>okBuilder() + .resultInfo(paymentTriggerServiceFactory.getService(pTriggerPaySe).payInfo(param)) + .build(); + } catch (EnsException e) { + result = EnsResponseVO.>errBuilder() + .errCode(e.getErrCd()) + .errMsg(e.getMessage()) + .build(); + } + + + return new ResponseEntity>>(result, HttpStatus.OK); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/api/PayUseSysApi.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/api/PayUseSysApi.java new file mode 100644 index 0000000..ebcd852 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/api/PayUseSysApi.java @@ -0,0 +1,91 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api; + +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.PayApi; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import java.nio.charset.Charset; +import java.util.Map; + +/** + * 페이결제 이용시스템 API + * + * @Description 결제에 필요한 정보를 이용시스템측에 요청 한다. 이용시스템측은 요청을 수신 할 수 있도록 API를 구축해야 한다. + */ +@Slf4j +@Component +//@Profile({"!local-test"}) +public class PayUseSysApi implements PayApi { + + + @Override + public ResponseEntity payUrl(String uri, Map mParam, HttpHeaders headers) { + + if (headers == null) + headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + + + String param = CmmnUtil.toJsonString(mParam); + + return callApi(HttpMethod.POST, uri, param, headers); + } + + @Override + public ResponseEntity payNotice(String uri, Map mParam, HttpHeaders headers) { + + if (headers == null) + headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + + + String param = CmmnUtil.toJsonString(mParam); + + return callApi(HttpMethod.POST, uri, param, headers); + } + + @Override + public ResponseEntity payAble(String uri, Map mParam, HttpHeaders headers) { + + if (headers == null) + headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + + + String param = CmmnUtil.toJsonString(mParam); + + return callApi(HttpMethod.POST, uri, param, headers); + } + + @Override + public ResponseEntity payResult(String uri, Map mParam, HttpHeaders headers) { + + if (headers == null) + headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + + + String param = CmmnUtil.toJsonString(mParam); + + return callApi(HttpMethod.POST, uri, param, headers); + } + + @Override + public ResponseEntity payCancelResult(String uri, Map mParam, HttpHeaders headers) { + + if (headers == null) + headers = new HttpHeaders(); + headers.setContentType(new MediaType(MediaType.APPLICATION_JSON, Charset.forName("utf-8"))); + + + String param = CmmnUtil.toJsonString(mParam); + + return callApi(HttpMethod.POST, uri, param, headers); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillLogSeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillLogSeCd.java new file mode 100644 index 0000000..a9219a1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillLogSeCd.java @@ -0,0 +1,38 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; + +import cokr.xit.ens.core.code.CodeMapperType; + + +/** + *

      + *
    • 업무 그룹명: 청구서API - 청구서 로그 구분
    • + *
    • 설 명: 이용시스템과 벤더사의 연계 오류를 구분하기 위한 코드 값. 응답메시지에 사용하며 업무 로직에는 사용되지 않는다.
    • + *
    • 작성일: 2023. 2. 25. 오후 3:51:43 + *
    + * + * @author 박민규 + */ +public enum BillLogSeCd implements CodeMapperType { + + US("이용시스템"), + VD("벤더") + ; + + private final String code; + private final String codeNm; + + BillLogSeCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getCodeNm() { + return this.codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillReqSeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillReqSeCd.java new file mode 100644 index 0000000..7cc861e --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillReqSeCd.java @@ -0,0 +1,55 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; + +import cokr.xit.ens.core.code.CodeMapperType; + + +/** + *
      + *
    • 업무 그룹명: 청구서API - 요청구분 코드
    • + *
    • 설 명:
    • + *
    • 작성일: 2022. 2. 15. 오후 3:51:43 + *
    + * + * @author 박민규 + */ + +public enum BillReqSeCd implements CodeMapperType { + + + ACPT("요청 접수"), + + + VD_URL("청구서링크생성"), + VD_REURL("청구서링크재생성"), + VD_PAYAPPLY("결제승인요청"), + VD_PAYCANCEL("결제취소"), + + + US_URLINF("이용시스템 청구서링크생성 정보"), + NOTICE("결제정보조회"),//TODO feat.NaverPay 민자고속도로 ENS_BILL_HIST DB에서 NOTICE -> GETNOTICE로 update 이후 코드삭제 요함 + US_NOTICE("이용시스템 결제정보"), + PREPAY("납부가능확인"),//TODO feat.NaverPay 민자고속도로 ENS_BILL_HIST DB에서 PREPAY -> CHKPREPAY로 update 이후 코드삭제 요함 + US_PREPAY("이용시스템 납부가능확인"), + PAYRSLT("납부결과전달"),//TODO feat.NaverPay 민자고속도로 ENS_BILL_HIST DB에서 PAYRSLT -> FWDPAYRSLT로 update 이후 코드삭제 요함 + US_PAYRSLT("이용시스템 납부결과전달"), + US_CANCELRSLT("이용시스템 결제취소결과전달"), + ; + + private final String code; + private final String codeNm; + + BillReqSeCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getCodeNm() { + return this.codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillSeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillSeCd.java similarity index 70% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillSeCd.java rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillSeCd.java index e8d0411..b3d6c8c 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/code/BillSeCd.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/BillSeCd.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.code; +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; import cokr.xit.ens.core.code.CodeMapperType; @@ -14,9 +14,11 @@ import cokr.xit.ens.core.code.CodeMapperType; */ public enum BillSeCd implements CodeMapperType { - bpKko("카카오페이"), - bpNv("네이버페이"), - all("모든 벤더사의 청구서"); + bpKko("카카오페이 청구서"), + bpNv("네이버페이 간편결제"), + privt("전자문서 벤더사의 결제시스템"), + all("모든 벤더사의 결제시스템"), + ; private final String code; private final String codeNm; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PaidTypeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PaidTypeCd.java new file mode 100644 index 0000000..1864d2a --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PaidTypeCd.java @@ -0,0 +1,38 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; + +import cokr.xit.ens.core.code.CodeMapperType; + + +/** + *
      + *
    • 업무 그룹명: 요금 납부(결제) 구분
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 15. 오전 8:28:43 + *
    + * + * @author 박민규 + */ +public enum PaidTypeCd implements CodeMapperType { + + kakaoPay("카카오페이"), + naverPay("네이버페이"), + ; + + private final String code; + private final String codeNm; + + PaidTypeCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getCodeNm() { + return this.codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysHisSeCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysHisSeCd.java new file mode 100644 index 0000000..63daa2d --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysHisSeCd.java @@ -0,0 +1,41 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; + +import cokr.xit.ens.core.code.CodeMapperType; + + +/** + *
      + *
    • 업무 그룹명: 이용시스템 페이결제 이력구분코드
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 15. 오전 8:38:43 + *
    + * + * @author 박민규 + */ +public enum PayUseSysHisSeCd implements CodeMapperType { + + gnrUrl("청구서링크생성"), + payNotice("납부(결제)정보"), + payAble("납부(결제)가능여부"), + payResult("납부(결제)결과"), + payCancel("결제취소결과"), + ; + + private final String code; + private final String codeNm; + + PayUseSysHisSeCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getCodeNm() { + return this.codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysResCd.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysResCd.java new file mode 100644 index 0000000..3dd7bb2 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/code/PayUseSysResCd.java @@ -0,0 +1,61 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code; + +import cokr.xit.ens.core.code.CodeMapperType; + + +/** + *
      + *
    • 업무 그룹명: 결제API - 이용시스템 응답 코드
    • + *
    • 설 명:
    • + *
    • 작성일: 2023. 2. 01. 오후 5:47:43 + *
    + * + * @author 박민규 + */ +public enum PayUseSysResCd implements CodeMapperType { + + + OK("성공"), + + + GRNURL_FIND_FAILED("청구서링크생성 정보 조회 실패"), + + + NOT_FOUND_PAYDATA("결제 정보 없음"), + PAYDATA_FIND_FAILED("결제 정보 조회 실패"), + + + + NO_AMOUNT_PAYABLE("납부 가능 금액 없음"), + OVERPAYABLE_AMOUNT("납부 가능 금액 초과"), + NO_TARGET_PAYABLE("납부가능 대상 없음"), + EXPIRED_DATE("납부기한 지나서 납부 불가"), + FAILED_CHECK_INFO("납부 요청정보 조회 실패"), + + + FAILED_SAVE_PAYRSLT("납부(결제)결과 저장 실패"), + + + FAILED_SAVE_CANCELRSLT("결제취소결과 저장 실패"), + + + ; + + private final String code; + private final String codeNm; + + PayUseSysResCd(String codeNm) { + this.code = this.name(); + this.codeNm = codeNm; + } + + @Override + public String getCode() { + return this.code; + } + + @Override + public String getCodeNm() { + return this.codeNm; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/Bill.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/Bill.java new file mode 100644 index 0000000..dee6e61 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/Bill.java @@ -0,0 +1,72 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity; + +import cokr.xit.ens.core.jpa.support.BooleanToYnConverter; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import lombok.experimental.SuperBuilder; + +import javax.persistence.*; +import java.io.Serializable; + +@Entity +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +@SuperBuilder +//@Inheritance(strategy = InheritanceType.JOINED) +//@DiscriminatorColumn(name = "dtype") +//@DiscriminatorValue("master") +@Table(name = "ens_bill", schema = "", catalog = "") +@Schema(name = "Bill") +public class Bill extends BillBaseEntity implements Serializable { + @Id + @GeneratedValue(strategy = GenerationType.TABLE, generator = "Bill_Generator") + @TableGenerator(table = "ens_seq_generator", name = "Bill_Generator" + , pkColumnName = "seq_name", pkColumnValue = "Bill_id" + , initialValue = 0, allocationSize = 200) + @Schema(required = true, title = "PK", example = " ") + private Long billId; + + @Enumerated(EnumType.STRING) + @Schema(required = true, title = "청구서 타입", example = " ") + @Column(name = "bill_se_cd", nullable = false) + private BillSeCd billSeCd; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "org_cd", nullable = false) + @Setter + private OrgMng orgMng; + + @Convert(converter = BooleanToYnConverter.class) + @Schema(required = false, title = "납부(결제)여부", example = " ") + @Column(name = "paid_at", nullable = true, length = 1) + @Setter + private Boolean paidAt; + @Schema(required = false, title = "지불 유형", example = " ") + @Column(name = "paid_type", nullable = true, length = 15) + @Enumerated(EnumType.STRING) + @Setter + private PaidTypeCd paidType; + @Schema(required = false, title = "납부(결제) 날짜", example = " ") + @Column(name = "paid_dt", nullable = true, length = 14) + @Setter + private String paidDt; + @Schema(required = false, title = "납부(결제) 취소 날짜", example = " ") + @Column(name = "paid_cancel_dt", nullable = true, length = 14) + @Setter + private String paidCancelDt; + + @Schema(required = false, title = "카카오 청구서", example = " ") + @Column(name = "doc_bill_kko", nullable = true) + @Lob + private String docBillKko; + + @Schema(required = false, title = "네이버 청구서", example = " ") + @Column(name = "doc_bill_nv", nullable = true) + @Lob + private String docBillNv; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillEntity.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillBaseEntity.java similarity index 57% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillEntity.java rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillBaseEntity.java index 13adf29..9c2cd41 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillEntity.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillBaseEntity.java @@ -1,4 +1,4 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity; +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity; import cokr.xit.ens.modules.common.domain.BaseEntity; import io.swagger.v3.oas.annotations.media.Schema; @@ -15,8 +15,12 @@ import javax.persistence.MappedSuperclass; @MappedSuperclass @SuperBuilder @NoArgsConstructor -public abstract class BillEntity extends BaseEntity { +public abstract class BillBaseEntity extends BaseEntity { @Column(name = "bill_uid", nullable = true, unique = true, length = 45) private String billUid; + + @Schema(required = true, title = "기관에서 관리하는 해당 고객번호 혹은 계약번호", example = " ") + @Column(name = "biller_user_key", nullable = false, length = 40) + private String billerUserKey; } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillHist.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHist.java similarity index 55% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillHist.java rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHist.java index 2b8ee12..5d4a1a5 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/BillHist.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHist.java @@ -1,7 +1,8 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity; +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillReqSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHistBaseEntity; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; import cokr.xit.ens.modules.common.domain.BaseEntity; import cokr.xit.ens.modules.common.domain.support.FieldError; @@ -21,50 +22,36 @@ import javax.persistence.*; @Index(name = "idx_bill_his_01", columnList = "linked_uuid, req_se"), @Index(name = "idx_bill_his_02", columnList = "bill_uid") }) -public class BillHist extends BaseEntity { +@Schema(name = "BillHist") +public class BillHist extends BillHistBaseEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "id", nullable = false) - + @Schema(required = true, title = "PK", example = " ") private Long id; - + @Schema(required = false, title = "청구서 유니크 아이디", example = " ") @Column(name = "bill_uid", nullable = true, unique = false, length = 45) private String billUid; - - @Column(name = "bill_se", nullable = false) + @Schema(required = true, title = "청구서구분", example = " ") + @Column(name = "bill_se", nullable = false, length = 15) @Enumerated(EnumType.STRING) private BillSeCd billSe; - - @Column(name = "req_se", nullable = false) + @Schema(required = true, title = "요청구분", example = " ") + @Column(name = "req_se", nullable = false, length = 15) @Enumerated(EnumType.STRING) private BillReqSeCd reqSe; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "org_cd") - + @Schema(required = false, title = "기관코드", example = " ") private OrgMng orgMng; - + @Schema(required = false, title = "연계식별키", example = "") @Column(name = "linked_uuid") @Setter private String linkedUuid; - - @Column(name = "request_data", nullable = true) - @Lob - private String requestData; - - - @Column(name = "response_data", nullable = true) - @Lob - @Setter - private String responseData; - - @Embedded - @Setter - private FieldError error; - } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistBaseEntity.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistBaseEntity.java new file mode 100644 index 0000000..f71e6d1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistBaseEntity.java @@ -0,0 +1,38 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity; + +import cokr.xit.ens.modules.common.domain.BaseEntity; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; + +@Getter +@Setter +@MappedSuperclass +@SuperBuilder +@NoArgsConstructor +public abstract class BillHistBaseEntity extends BaseEntity { + + + @Schema(required = false, title = "요청", example = " ") + @Column(name = "request_data", nullable = true) + @Lob + private String requestData; + + @Schema(required = false, title = "응답", example = " ") + @Column(name = "response_data", nullable = true) + @Lob + @Setter + private String responseData; + + @Embedded + @Setter + private FieldError error; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistPayUseSysBaseEntity.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistPayUseSysBaseEntity.java new file mode 100644 index 0000000..1878156 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/BillHistPayUseSysBaseEntity.java @@ -0,0 +1,33 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysHisSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; + +import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.MappedSuperclass; + +@Getter +@Setter +@MappedSuperclass +@SuperBuilder +@NoArgsConstructor +public abstract class BillHistPayUseSysBaseEntity extends BillHistBaseEntity { + + + @Schema(required = true, title = "지불 유형", example = " ") + @Column(name = "paid_type", nullable = false, length = 15) + @Enumerated(EnumType.STRING) + private PaidTypeCd paidType; + + @Schema(required = true, title = "이력구분", example = " ") + @Column(name = "his_se_cd", nullable = false, length = 15) + @Enumerated(EnumType.STRING) + private PayUseSysHisSeCd hisSeCd; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillHistRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillHistRepository.java new file mode 100644 index 0000000..caa02eb --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillHistRepository.java @@ -0,0 +1,9 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface BillHistRepository extends JpaRepository { + + +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillRepository.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillRepository.java similarity index 73% rename from src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillRepository.java rename to src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillRepository.java index 1016852..2bf57e6 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/entity/repository/BillRepository.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/entity/repository/BillRepository.java @@ -1,6 +1,6 @@ -package cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository; +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/model/PayApiRespDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/model/PayApiRespDTO.java new file mode 100644 index 0000000..70d88e0 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/model/PayApiRespDTO.java @@ -0,0 +1,56 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +@Getter +@ToString +@EqualsAndHashCode +@NoArgsConstructor +@Schema(name = "PayApiRespDTO") +public class PayApiRespDTO { + + @Schema(title = "응답코드", example = " ") + @JsonProperty("res_code") + @JsonAlias({"resCode", "code"}) + @SerializedName(value = "res_code", alternate = {"resCode", "code"}) + private String resCode; + + @Schema(title = "응답메시지", example = " ") + @Setter + private String message; + + @Schema(title = "응답데이터", example = " ") + @Setter + @JsonProperty("data") + @JsonAlias({"body"}) + @SerializedName(value = "data", alternate = {"body"}) + private T data; + + + @Builder(builderClassName = "okBuilder", builderMethodName = "okBuilder") + PayApiRespDTO(T data) { + this.resCode = PayUseSysResCd.OK.getCode(); + this.message = PayUseSysResCd.OK.getCodeNm(); + this.data = data; + } + + @Builder(builderClassName = "errBuilder", builderMethodName = "errBuilder") + PayApiRespDTO(String resCode, String message) { + this.resCode = resCode; + this.message = message; + this.data = null; + } + + @Builder(builderClassName = "errDataBuilder", builderMethodName = "errDataBuilder") + PayApiRespDTO(String resCode, String message, T data) { + this.resCode = resCode; + this.message = message; + this.data = data; + } + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/Pay.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/Pay.java new file mode 100644 index 0000000..cc9f9d3 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/Pay.java @@ -0,0 +1,21 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process; + +import cokr.xit.ens.core.exception.EnsException; + +/** + * 결제 처리자 + */ +public interface Pay { + + /** + * 실행 + * + * @return + */ + void exec(); + + RSLT getResult(); + + EnsException getException(); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayHelperService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayHelperService.java new file mode 100644 index 0000000..0437fc7 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayHelperService.java @@ -0,0 +1,53 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process; + +import cokr.xit.ens.core.exception.EnsException; + +/** + * 결제 서비스 + */ +public interface PayHelperService { + + /** + * 데이터 조회 + * + * @param param + * @return + */ + D getData(PARAM param); + + /** + * 유효성 검사 + * + * @param param + * @param data + */ + void validate(PARAM param, D data); + + /** + * API 호출 + * + * @param param + * @param data + */ + void callApi(PARAM param, D data); + + /** + * 처리결과 생성 + *s + * @param param + * @param data + * @param e + * @return + */ + RSLT generateResult(PARAM param, D data, EnsException e); + + /** + * 이력 저장 + * + * @param param + * @param data + * @param e + */ + void saveHist(PARAM param, D data, EnsException e); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayProcessService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayProcessService.java new file mode 100644 index 0000000..046e3fa --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/PayProcessService.java @@ -0,0 +1,51 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process; + +/** + * 결제 서비스 + * + * @param 리턴타입 + * @param

    파라미터 + */ +public interface PayProcessService { + + /** + * 결제 URL 생성 + * + * @param p + * @return + */ + T gnrUrl(P p); + + /** + * 결제정보 + * + * @param p + * @return + */ + T payNotice(P p); + + /** + * 결제 전 납부가능여부 + * + * @param p + * @return + */ + T payAble(P p); + + /** + * 결제 후 납부결과 + * + * @param p + * @return + */ + T payResult(P p); + + /** + * 결제취소 + * + * @param p + * @return + */ + T payCancel(P p); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayAbleService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayAbleService.java new file mode 100644 index 0000000..bc6fbcd --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayAbleService.java @@ -0,0 +1,10 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; + +/** + * 결제가능확인 서비스 + */ +public interface PayAbleService extends PayHelperService { + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayCancelService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayCancelService.java new file mode 100644 index 0000000..9af83fe --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayCancelService.java @@ -0,0 +1,10 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; + +/** + * 결제결과 서비스 + */ +public interface PayCancelService extends PayHelperService { + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayNoticeService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayNoticeService.java new file mode 100644 index 0000000..955bddf --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayNoticeService.java @@ -0,0 +1,10 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; + +/** + * 결제정보 서비스 + */ +public interface PayNoticeService extends PayHelperService { + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayResultService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayResultService.java new file mode 100644 index 0000000..76cc974 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayResultService.java @@ -0,0 +1,10 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; + +/** + * 결제결과 서비스 + */ +public interface PayResultService extends PayHelperService { + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayUrlService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayUrlService.java new file mode 100644 index 0000000..acb521e --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/kit/PayUrlService.java @@ -0,0 +1,11 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.kit; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; + +/** + * 결제URL 생성 서비스 + */ +public interface PayUrlService extends PayHelperService { + + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayAbleData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayAbleData.java new file mode 100644 index 0000000..56bc77c --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayAbleData.java @@ -0,0 +1,24 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@EqualsAndHashCode +@Builder +public class PayAbleData { + private Bill bill; + private DTL billDetail; + + @Setter + private ReqAndRespInf reqAndRespInf; + + public ReqAndRespInf getReqAndRespInf() { + if (this.reqAndRespInf == null) + this.reqAndRespInf = ReqAndRespInf.builder().build(); + return this.reqAndRespInf; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayCancelData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayCancelData.java new file mode 100644 index 0000000..ed82ac6 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayCancelData.java @@ -0,0 +1,24 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@EqualsAndHashCode +@Builder +public class PayCancelData { + private Bill bill; + private DTL billDetail; + + @Setter + private ReqAndRespInf reqAndRespInf; + + public ReqAndRespInf getReqAndRespInf() { + if (this.reqAndRespInf == null) + this.reqAndRespInf = ReqAndRespInf.builder().build(); + return this.reqAndRespInf; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayNoticeData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayNoticeData.java new file mode 100644 index 0000000..2d632d9 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayNoticeData.java @@ -0,0 +1,24 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@EqualsAndHashCode +@Builder +public class PayNoticeData { + private Bill bill; + private DTL billDetail; + + @Setter + private ReqAndRespInf reqAndRespInf; + + public ReqAndRespInf getReqAndRespInf() { + if (this.reqAndRespInf == null) + this.reqAndRespInf = ReqAndRespInf.builder().build(); + return this.reqAndRespInf; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayResultData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayResultData.java new file mode 100644 index 0000000..13cee07 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayResultData.java @@ -0,0 +1,24 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@EqualsAndHashCode +@Builder +public class PayResultData { + private Bill bill; + private DTL billDetail; + + @Setter + private ReqAndRespInf reqAndRespInf; + + public ReqAndRespInf getReqAndRespInf() { + if (this.reqAndRespInf == null) + this.reqAndRespInf = ReqAndRespInf.builder().build(); + return this.reqAndRespInf; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayUrlData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayUrlData.java new file mode 100644 index 0000000..53949f9 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/PayUrlData.java @@ -0,0 +1,24 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +@Getter +@EqualsAndHashCode +@Builder +public class PayUrlData { + private Bill bill; + private DTL billDetail; + + @Setter + private ReqAndRespInf reqAndRespInf; + + public ReqAndRespInf getReqAndRespInf() { + if (this.reqAndRespInf == null) + this.reqAndRespInf = ReqAndRespInf.builder().build(); + return this.reqAndRespInf; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/ReqAndRespInf.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/ReqAndRespInf.java new file mode 100644 index 0000000..2f2f741 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/model/ReqAndRespInf.java @@ -0,0 +1,26 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.model; + +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; + +import java.util.HashMap; +import java.util.Map; + +@Getter +@Setter +@EqualsAndHashCode +@Builder +public class ReqAndRespInf { + private String url; + private String reqData; + private String respRawData; + private Map etc; + + public Map getEtc() { + if (this.etc == null) + this.etc = new HashMap<>(); + return this.etc; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/template/PayHelper.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/template/PayHelper.java new file mode 100644 index 0000000..48ca01b --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/process/template/PayHelper.java @@ -0,0 +1,56 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.template; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.Pay; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.process.PayHelperService; +import lombok.Builder; + +public class PayHelper implements Pay { + + private final PARAM param; + private final PayHelperService payHelperService; + private D data; + private RSLT result; + private EnsException e; + + @Builder + PayHelper(PARAM param, PayHelperService payHelperService) { + this.param = param; + this.payHelperService = payHelperService; + } + + @Override + public void exec() { + try { + + this.data = payHelperService.getData(param); + + payHelperService.validate(param, data); + + payHelperService.callApi(param, data); + + this.result = payHelperService.generateResult(param, data, null); + + } catch (EnsException e) { + this.e = e; + this.result = payHelperService.generateResult(param, data, this.e); + } catch (Exception e) { + this.e = new EnsException(EnsErrCd.ERR999, "정의되지 않은 오류 입니다", e); + this.result = payHelperService.generateResult(param, data, this.e); + } finally { + payHelperService.saveHist(param, data, e); + } + + } + + @Override + public RSLT getResult() { + return this.result; + } + + @Override + public EnsException getException() { + return this.e; + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/PayRepairServiceFactory.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/PayRepairServiceFactory.java new file mode 100644 index 0000000..f9cefe1 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/PayRepairServiceFactory.java @@ -0,0 +1,28 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.RepairPayResultService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class PayRepairServiceFactory { + private final Map repairPayResultServiceMap; + + public enum PRepairPaySe { + kko, + nv, + } + + public RepairPayResultService getService(PRepairPaySe PTriggerPaySe) { + String beanName = PTriggerPaySe.name() + "PayRepairService"; + if (repairPayResultServiceMap.containsKey(beanName)) + return repairPayResultServiceMap.get(beanName); + else + throw new EnsException(EnsErrCd.NOT_FOUND_BEAN, EnsErrCd.NOT_FOUND_BEAN.getCodeNm()); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/RepairPayResultService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/RepairPayResultService.java new file mode 100644 index 0000000..8ff01e7 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/RepairPayResultService.java @@ -0,0 +1,23 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair; + +import java.util.Map; + +public interface RepairPayResultService

    { + + /** + * 전송 실패한 납부(결제)결과 데이터 목록 조회 + * + * @param p + * @return + */ + Map> findTransferFailedPayResultDataList(P p); + + /** + * 전송 실패한 납부(결제)결과 데이터 목록 전송 + * + * @param p + * @return + */ + Map> sendTransferFailedPayResultDataList(P p); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/kit/RepairPayResultTransferFail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/kit/RepairPayResultTransferFail.java new file mode 100644 index 0000000..ce6291f --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/kit/RepairPayResultTransferFail.java @@ -0,0 +1,176 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.kit; + +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.api.PayUseSysApi; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PayUseSysResCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.model.PayApiRespDTO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.PayResultTransferFailData; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.PayResultTransferProcessVO; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model.RepairPayRsltFwdFailSearchDTO; +import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import com.google.gson.Gson; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.dsl.CaseBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBillHist.billHist; +import static cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng.orgMng; + + +public abstract class RepairPayResultTransferFail { + + protected JPAQueryFactory query; + protected RepairPayRsltFwdFailSearchDTO searchDTO; + private List transferFailDatas = null; + private Gson gson = new Gson(); + + + /** + * 납부(결제)결과 전달에 실패한 청구서 목록 조회 + * + * @return + */ + public List findDatas() { + + BooleanBuilder builder = new BooleanBuilder(); + builder.and(billHist.reqSe.in(Arrays.asList(BillReqSeCd.US_PAYRSLT, BillReqSeCd.PAYRSLT))); + builder.and(billHist.billSe.eq(getBillSeCd())); + if (!CmmnUtil.isEmpty(searchDTO.getSchOrgCd())) + builder.and(billHist.orgMng.orgCd.in(searchDTO.getSchOrgCd())); + if (!CmmnUtil.isEmpty(searchDTO.getSchOrgNm())) + builder.and(billHist.orgMng.orgNm.in(searchDTO.getSchOrgNm())); + if (!CmmnUtil.isEmpty(searchDTO.getSchBillUid())) + builder.and(billHist.billUid.in(searchDTO.getSchBillUid())); + + + + List list = query + .select(billHist.linkedUuid + , billHist.linkedUuid.count().longValue().as("totCnt") + , new CaseBuilder().when(billHist.error.errorCode.isNotNull() + .and((billHist.error.errorMessage.contains("REQUEST_TIMEOUT I/O error on") + .or(billHist.error.errorMessage.contains("404 NOT_FOUND")) + .or(billHist.error.errorCode.eq(PayUseSysResCd.FAILED_SAVE_PAYRSLT.getCode())) + )) + ) + .then(1) + .otherwise(0) + .sum().longValue().as("failCnt") + , billHist.orgMng.orgCd + , billHist.orgMng.orgNm + , billHist.billSe + , billHist.id.max().as(billHist.id) + ) + .from(billHist) + .innerJoin(billHist.orgMng, orgMng) + .where(builder) + .groupBy(billHist.orgMng, orgMng.orgNm, billHist.linkedUuid, billHist.billSe) + .fetch() + .stream() + .filter(tuple -> tuple.get(1, Long.class) == tuple.get(2, Long.class)) + .map(tuple -> + PayResultTransferFailData.builder() + .orgCd(tuple.get(billHist.orgMng.orgCd)) + .orgNm(tuple.get(billHist.orgMng.orgNm)) + .billSe(tuple.get(billHist.billSe)) + .billerUserKey(tuple.get(billHist.linkedUuid)) + .id(tuple.get(billHist.id)) + .build() + ) + .collect(Collectors.toList()); + + this.transferFailDatas = list; + return list; + } + + public List transferData(PayUseSysApi api, BillHistRepository billHistRepository) { + if (this.transferFailDatas == null) + this.findDatas(); + + List billHistList = this.transferFailDatas.stream() + .map(data -> PayResultTransferProcessVO + .builder() + .data(data) + .build() + ) + .map(vo -> { + vo.setReqBillHist(query.selectFrom(billHist) + .where(billHist.id.eq(vo.getData().getId())) + .fetchOne()); + return vo; + }) + .filter(vo -> !CmmnUtil.isEmpty(vo.getReqBillHist())) + .map(vo -> { + final String apiUrl = getPayResultApiUrl(vo.getReqBillHist().getOrgMng()); + ResponseEntity response = api.payResult(apiUrl, gson.fromJson(vo.getReqBillHist().getRequestData(), Map.class), null); + vo.setResponse(response); + return vo; + }) + .map(vo -> { + ResponseEntity response = vo.getResponse(); + + if (!HttpStatus.OK.equals(response.getStatusCode())) { + vo.setError(FieldError.initBuilder() + .errorCode(EnsErrCd.API_COMM_ERROR.getCode()) + .errorMessage(EnsErrCd.API_COMM_ERROR.getCodeNm() + " " + response.getStatusCode().toString()) + .build()); + return vo; + } + + PayApiRespDTO> result = null; + try { + result = gson.fromJson(response.getBody(), PayApiRespDTO.class); + } catch (Exception ex) { + vo.setError(FieldError.initBuilder() + .errorCode(EnsErrCd.INVALID_RESPONSE.getCode()) + .errorMessage(EnsErrCd.INVALID_RESPONSE.getCodeNm() + " " + ex.getMessage()) + .build()); + return vo; + } + + try { + PayUseSysResCd.valueOf(result.getResCode()); + } catch (Exception ex) { + vo.setError(FieldError.initBuilder() + .errorCode(EnsErrCd.INVALID_RES_CODE.getCode()) + .errorMessage(EnsErrCd.INVALID_RES_CODE.getCodeNm() + " " + ex.getMessage()) + .build()); + return vo; + } + return vo; + }) + .map(vo -> BillHist.builder() + .billUid(vo.getReqBillHist().getBillUid()) + .billSe(vo.getReqBillHist().getBillSe()) + .reqSe(BillReqSeCd.US_PAYRSLT) + .orgMng(vo.getReqBillHist().getOrgMng()) + .linkedUuid(vo.getReqBillHist().getLinkedUuid()) + .requestData(vo.getReqBillHist().getRequestData()) + .responseData(vo.getResponse().getBody()) + .error(vo.getError()) + .build()) + .collect(Collectors.toList()); + + billHistRepository.saveAll(billHistList); + return billHistList; + } + + + abstract protected String getPayResultApiUrl(OrgMng orgMng); + + abstract protected BillSeCd getBillSeCd(); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferFailData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferFailData.java new file mode 100644 index 0000000..5ed34e5 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferFailData.java @@ -0,0 +1,43 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "RepairPayRsltFwdFailRespData") +public class PayResultTransferFailData { + + @Schema(title = "기관코드", example = " ") + @JsonProperty("orgCd") + @JsonAlias({"org_cd"}) + @SerializedName(value = "orgCd", alternate = {"org_cd"}) + private String orgCd; + @Schema(title = "기관코드명", example = " ") + @JsonProperty("orgNm") + @JsonAlias({"org_nm"}) + @SerializedName(value = "orgNm", alternate = {"org_nm"}) + private String orgNm; + @Schema(title = "빌러유저키", example = " ") + @JsonProperty("billSe") + @JsonAlias({"bill_se"}) + @SerializedName(value = "billSe", alternate = {"bill_se"}) + private BillSeCd billSe; + @Schema(title = "빌러유저키", example = " ") + @JsonProperty("billerUserKey") + @JsonAlias({"biller_user_key"}) + @SerializedName(value = "billerUserKey", alternate = {"biller_user_key"}) + private String billerUserKey; + @Schema(title = "청구서이력식별키(PK)") + private Long id; + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferProcessVO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferProcessVO.java new file mode 100644 index 0000000..8e8bf32 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/PayResultTransferProcessVO.java @@ -0,0 +1,23 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist; +import cokr.xit.ens.modules.common.domain.support.FieldError; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.http.ResponseEntity; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "PayResultTransferVO") +public class PayResultTransferProcessVO { + + private PayResultTransferFailData data; + private BillHist reqBillHist; + private ResponseEntity response; + private FieldError error; +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/RepairPayRsltFwdFailSearchDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/RepairPayRsltFwdFailSearchDTO.java new file mode 100644 index 0000000..ee21e3e --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/repair/model/RepairPayRsltFwdFailSearchDTO.java @@ -0,0 +1,34 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.repair.model; + +import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@SuperBuilder +@Data +@NoArgsConstructor +@Schema(name = "RepairPayRsltFwdFailSearchDTO") +public class RepairPayRsltFwdFailSearchDTO { + + @Schema(title = "기관코드", example = "[]") + @JsonProperty("schOrgCd") + @JsonAlias({"sch_org_cd"}) + @SerializedName(value = "schOrgCd", alternate = {"sch_org_cd"}) + protected List schOrgCd; + @Schema(title = "기관코드명", example = "[]") + @JsonProperty("schOrgNm") + @JsonAlias({"sch_org_nm"}) + @SerializedName(value = "schOrgNm", alternate = {"sch_org_nm"}) + protected List schOrgNm; + @Schema(title = "청구서UID", example = "[]") + @JsonProperty("schBillUid") + @JsonAlias({"sch_bill_uid"}) + @SerializedName(value = "schBillUid", alternate = {"sch_bill_uid"}) + protected List schBillUid; +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerService.java new file mode 100644 index 0000000..20096c6 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerService.java @@ -0,0 +1,23 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger; + +import java.util.Map; + +/** + * 결제 이벤트 시점 트리거 서비스 + */ +public interface PaymentTriggerService { + + enum PTriggerDataKeys { + bill, + billUid, + } + + /** + * 결제정보 + * + * @param p + * @return + */ + Map payInfo(Map p); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceFactory.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceFactory.java new file mode 100644 index 0000000..febaa51 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceFactory.java @@ -0,0 +1,28 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger; + +import cokr.xit.ens.core.exception.EnsException; +import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger.PaymentTriggerService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +@RequiredArgsConstructor +public class PaymentTriggerServiceFactory { + private final Map paymentTriggerServiceMap; + + public enum PTriggerPaySe { + kko, + nv, + } + + public PaymentTriggerService getService(PTriggerPaySe PTriggerPaySe) { + String beanName = PTriggerPaySe.name() + "PaymentTriggerService"; + if (paymentTriggerServiceMap.containsKey(beanName)) + return paymentTriggerServiceMap.get(beanName); + else + throw new EnsException(EnsErrCd.NOT_FOUND_BEAN, EnsErrCd.NOT_FOUND_BEAN.getCodeNm()); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceTemplate.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceTemplate.java new file mode 100644 index 0000000..b303297 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnbill/support/service/trigger/PaymentTriggerServiceTemplate.java @@ -0,0 +1,48 @@ +package cokr.xit.ens.modules.common.ctgy.intgrnbill.support.service.trigger; + +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; + +import java.util.Map; + +/** + * 결제 이벤트 시점 트리거 서비스 템플릿 + */ +public abstract class PaymentTriggerServiceTemplate implements PaymentTriggerService { + + /** + * 결제정보 + * + * @param param + * @return + */ + @Override + public Map payInfo(Map param) { + if (!existsBill((String) param.get(PTriggerDataKeys.billUid))) + generateBill((Bill) param.get(PTriggerDataKeys.bill)); + return getPayInfo(param); + } + + /** + * 청구서데이터 유무 확인 + * + * @param billUid 청구서UID + * @return + */ + abstract protected boolean existsBill(String billUid); + + /** + * 청구서데이터 생성 + * + * @param bill + */ + abstract protected void generateBill(Bill bill); + + /** + * 청구서 납부(결제)정보 가져오기 + * + * @param param + * @return + */ + abstract protected Map getPayInfo(Map param); + +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/domain/IntgrnSendDetail.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/domain/IntgrnSendDetail.java index f156b47..3c34e76 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/domain/IntgrnSendDetail.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/domain/IntgrnSendDetail.java @@ -2,7 +2,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain; import cokr.xit.ens.modules.common.code.IntgrnDtlStatCd; import cokr.xit.ens.modules.common.code.PostSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; import cokr.xit.ens.modules.common.domain.BaseEntity; import cokr.xit.ens.modules.common.domain.support.FieldError; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/model/config/XitProperty.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/model/config/XitProperty.java index 57615f7..9fc2611 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/model/config/XitProperty.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/model/config/XitProperty.java @@ -1,6 +1,6 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.config; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -18,14 +18,14 @@ import java.util.Map; @Schema(name = "XitProperty") public class XitProperty { - @Schema(required = false, title = "모바일페이지 노출 데이터", example = "{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"]}},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"링크 이미지\":\"http://www.xit.co.kr/....\"},{\"Base64 이미지\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\",\"properties\":{\"billSe\":\"bpKko\"}}]}") + @Schema(required = false, title = "모바일페이지 노출 데이터", example = "{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"하하하\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"다라마\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"},\"1111-23123-12313\":{\"use-clipboard\":false,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\\n1111-23123-12313 카카오\\n카카오뱅크\\nhttp://www.naver.com\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"액\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"],\"highlight\":{\"전기료\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"key\":\"링크 이미지\",\"value\":\"http://www.xit.co.kr/....\"},{\"key\":\"Base64 이미지\",\"value\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\"}]}") private Map>> mbl_page_data; @Schema(required = false, title = "템플릿 메시지 데이터", example = "{\"#{TARGET_NAME}\":\"홍길동\",\"#{CAR_NO}\":\"12더1234\",\"#{HISTORY}\":\"2022-01-01\",\"#{FEE}\":\"1000\",\"#{YYYY}\":\"2022\",\"#{MM}\":\"03\",\"#{DD}\":\"30\",\"#{BANK}\":\"기업\",\"#{ACCOUNT}\":\"311-063233-01-123\",\"#{HOMEPAGE}\":\"http://www.xit.co.kr\",\"#{REP_CALL_NO}\":\"070-4490-7404\"}") private Map tmplt_msg_data; @Valid - private BillAcptReqDTO bill_acpt_data; + private EnsBillAcptReqDTO bill_acpt_data; // @Schema(required = false, title = "카카오페이 청구서링크 정보", example = " ") // @Valid diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/presentation/IntgrnNotiMblPageController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/presentation/IntgrnNotiMblPageController.java index c05df87..38fbc0c 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/presentation/IntgrnNotiMblPageController.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/presentation/IntgrnNotiMblPageController.java @@ -8,6 +8,7 @@ import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.repository.IntgrnSendD import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @@ -23,6 +24,15 @@ public class IntgrnNotiMblPageController { private final IntgrnSendDetailRepository intgrnSendDetailRepository; + @Value("${xit.mblpage.postse.kkomd.path}") + private String KKOMD_MBL_PATH; + @Value("${xit.mblpage.postse.nvst.path}") + private String NVST_MBL_PATH; + @Value("${xit.mblpage.postse.ktst.path}") + private String KTST_MBL_PATH; + @Value("${xit.mblpage.postse.ktgbs.path}") + private String KTGBS_MBL_PATH; + @GetMapping(value = "/intgrn/noti/page/prnt") public String mblPagePrnt(@RequestParam Map mParam, ModelMap model) { @@ -53,14 +63,10 @@ public class IntgrnNotiMblPageController { String url = null; -// if (PostSeCd.kkoMydoc.equals(intgrnSendDetail.getCurPostSe())) url = "/kko/mydoc/page/prnt"; -// else if (PostSeCd.nvSigntalk.equals(intgrnSendDetail.getCurPostSe())) url = "/nv/signtalk/page/prnt"; -// else if (PostSeCd.ktSigntalk.equals(intgrnSendDetail.getCurPostSe())) url = "/kt/signtalk/page/prnt"; -// else if (PostSeCd.ktGibis.equals(intgrnSendDetail.getCurPostSe())) url = "/kt/gibis/page/prnt"; - if (PostSeCd.kkoMydoc.equals(postSeCd)) url = "/kko/mydoc/page/prnt"; - else if (PostSeCd.nvSigntalk.equals(postSeCd)) url = "/nv/signtalk/page/prnt"; - else if (PostSeCd.ktSigntalk.equals(postSeCd)) url = "/kt/signtalk/page/prnt"; - else if (PostSeCd.ktGibis.equals(postSeCd)) url = "/kt/gibis/page/prnt"; + if (PostSeCd.kkoMydoc.equals(postSeCd)) url = KKOMD_MBL_PATH; + else if (PostSeCd.nvSigntalk.equals(postSeCd)) url = NVST_MBL_PATH; + else if (PostSeCd.ktSigntalk.equals(postSeCd)) url = KTST_MBL_PATH; + else if (PostSeCd.ktGibis.equals(postSeCd)) url = KTGBS_MBL_PATH; else throw new EnsException(EnsErrCd.ERR500, String.format("정의되지 않은 우편구분 입니다. [linkedUuid %s]", finalLinkedUuid)); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/AcceptData.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/AcceptData.java index 5c7b216..18ab592 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/AcceptData.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/AcceptData.java @@ -19,7 +19,7 @@ public abstract class AcceptData { protected final List intgrnSendDetails; protected final Boolean isReserveSend; - public abstract T make(); + public abstract T createReqDto(); public List getIntgrnSendDetails() { return this.intgrnSendDetails; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiAcceptor.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiAcceptor.java index 6f496ed..6d253bd 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiAcceptor.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiAcceptor.java @@ -14,9 +14,8 @@ import cokr.xit.ens.modules.common.code.IntgrnDtlStatCd; import cokr.xit.ens.modules.common.code.PostSeCd; import cokr.xit.ens.modules.common.code.StatCd; import cokr.xit.ens.modules.common.code.VenderCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillMakerSupport; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillRepository; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.code.TryStatCd; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; @@ -46,7 +45,6 @@ import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class IntgrnNotiAcceptor implements EnsPhaseProcSupport { - private final Map billMakerMap; private final IntgrnSendMastRepository intgrnSendMastRepository; private final IntgrnSendDetailRepository intgrnSendDetailRepository; private final BillRepository billRepository; @@ -193,18 +191,20 @@ public class IntgrnNotiAcceptor implements EnsPhaseProcSupport new RuntimeException("등록된 청구서가 없습니다.")); } else { bill = Bill.builder() // .billId(document.getXit_property().getBill_acpt_data().getBill_id()) .billId(null) .billUid(IdGenerator.getShortUUID(prefixBillUid)) - .billSeCd(document.getXit_property().getBill_acpt_data().getBill_se()) + .billerUserKey(document.getXit_property().getBill_acpt_data().getBillerUserKey()) + .billSeCd(document.getXit_property().getBill_acpt_data().getBillSe()) .orgMng(OrgMng.builder().orgCd(reqDTO.getOrg_cd()).build()) - .docBillKko(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_kko())) -// .docBillNv(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_nv())) +// .docBillKko(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_kko())) +// .docBillNv(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_nv())) .build(); } bills.add(bill); @@ -249,22 +249,13 @@ public class IntgrnNotiAcceptor implements EnsPhaseProcSupport CmmnUtil.isEmpty(row.getBillId())) .collect(Collectors.toList()) ); - billMakerMap.keySet().stream() - .forEach(key -> { - try { - billMakerMap.get(key).accept(bills); - } catch (EnsException e) { - throw new EnsException(EnsErrCd.ACPT412, String.format("[%s] %s", e.getErrCd(), e.getMessage())); - } - }); - intgrnSendDetailRepository.saveAll(intgrnSendDetails); // MakerFactory makerFactory = new AcceptDataMakerFactory(intgrnSendMast, intgrnSendDetails, true); -// +// // applicationEventPublisher.publishEvent(makerFactory.get(reqDTO.getTry1())); -// +// // intgrnSendMast.setTrySeq(1); // intgrnSendMast.setTryStatCd(TryStatCd.sndRsrv); // intgrnSendMastRepository.save(intgrnSendMast); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiMaker.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiMaker.java index 44843d3..c04d95b 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiMaker.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/IntgrnNotiMaker.java @@ -9,8 +9,6 @@ import cokr.xit.ens.modules.common.biztmplt.MakeProcTemplate; import cokr.xit.ens.modules.common.code.IntgrnDtlStatCd; import cokr.xit.ens.modules.common.code.PostSeCd; import cokr.xit.ens.modules.common.code.StatCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillMakerSupport; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.code.TryStatCd; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; @@ -28,7 +26,6 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -36,7 +33,6 @@ import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class IntgrnNotiMaker extends MakeProcTemplate { - private final Map billMakerMap; private final IntgrnSendMastRepository intgrnSendMastRepository; private final IntgrnSendDetailRepository intgrnSendDetailRepository; private final TmpltMngStrategyIntegration tmpltMngService; @@ -71,13 +67,13 @@ public class IntgrnNotiMaker extends MakeProcTemplate { }) .collect(Collectors.toList()); ; - + respVO = EnsResponseVO.okBuilder().resultInfo(resultInfo).build(); } catch (EnsException e) { - + respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); } catch (Exception e) { - + respVO = EnsResponseVO.errBuilder().errCode(EnsErrCd.MAKE500).errMsg(e.getMessage()).build(); } @@ -110,13 +106,13 @@ public class IntgrnNotiMaker extends MakeProcTemplate { IntgrnSendMast intgrnSendMast = intgrnSendMastRepository.findById(intSendMastId).orElseThrow(() -> new EnsException(EnsErrCd.MAKE404, String.format("일치하는 발송마스터 자료가 없습니다. [ intSendMastId %s ]", intSendMastId))); intgrnSendMast.setStatCd(StatCd.making); - + respVO = EnsResponseVO.okBuilder().resultInfo(intSendMastId).build(); } catch (EnsException e) { - + respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); } catch (Exception e) { - + respVO = EnsResponseVO.errBuilder().errCode(EnsErrCd.MAKE500).errMsg(e.getMessage()).build(); } @@ -144,30 +140,13 @@ public class IntgrnNotiMaker extends MakeProcTemplate { throw new EnsException(EnsErrCd.MAKE521, String.format("미사용 상태의 템플릿 입니다. [ intSendMastId %s orgCd %s TmpltCd %s ]", intSendMastId, finalIntgrnSendMast.getOrgCd(), finalIntgrnSendMast.getTmpltCd())); - - try { - List bills = intgrnSendDetails.stream() - .filter(sendDetail -> sendDetail.getBill() != null) - .map(IntgrnSendDetail::getBill) - .collect(Collectors.toList()); - billMakerMap.keySet().stream() - .map(key -> billMakerMap.get(key).apply(bills)) - .forEach(responseVO -> { - if (!EnsErrCd.OK.equals(responseVO.getErrCode())) - throw new EnsException(EnsErrCd.MAKE512, String.format("[%s] %s", responseVO.getErrCode(), responseVO.getErrMsg())); - }); - } catch (EnsException e) { - throw e; - } catch (Exception e) { - throw new EnsException(EnsErrCd.MAKE512, e.getMessage()); - } Optional cntSuccess = intgrnSendDetails.stream() .map(row -> { try { - row.setCurStatCd(IntgrnDtlStatCd.MAKING); - + row.setError(FieldError.initBuilder().build()); + return 1; } catch (EnsException e) { row.setError(FieldError.initBuilder() @@ -180,16 +159,16 @@ public class IntgrnNotiMaker extends MakeProcTemplate { .reduce(Integer::sum); - + if (cntSuccess.get() > 0) respVO = EnsResponseVO.okBuilder().resultInfo(String.format("총 %d건 중 %d건 제작 성공. [ intSendMastId %s ]", intgrnSendDetails.size(), cntSuccess.get(), intSendMastId)).build(); else throw new EnsException(EnsErrCd.MAKE500, String.format("총 %d 건 제작 실패", intgrnSendDetails.size())); } catch (EnsException e) { - + respVO = EnsResponseVO.errBuilder().errCode(e.getErrCd()).errMsg(e.getMessage()).build(); } catch (Exception e) { - + respVO = EnsResponseVO.errBuilder().errCode(EnsErrCd.MAKE500).errMsg(e.getMessage()).build(); } finally { if (!CmmnUtil.isEmpty(intgrnSendMast)) diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptByKkoAlimtalkEventListener.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptByKkoAlimtalkEventListener.java index 2f49a0f..5ec118e 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptByKkoAlimtalkEventListener.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptByKkoAlimtalkEventListener.java @@ -40,7 +40,7 @@ public class AcceptByKkoAlimtalkEventListener implements AcceptDataEventListener EnsResponseVO responseVO = null; try { - responseVO = kkoAlimtalkService.accept(ev.make()); + responseVO = kkoAlimtalkService.accept(ev.createReqDto()); Map resultInfo = (Map) responseVO.getResultInfo(); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptDataByKkoAlimtalk.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptDataByKkoAlimtalk.java index 0a298df..58cd687 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptDataByKkoAlimtalk.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkoalimtalk/AcceptDataByKkoAlimtalk.java @@ -1,7 +1,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.kkoalimtalk; import cokr.xit.ens.core.utils.CmmnUtil; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.AcceptData; @@ -23,7 +23,7 @@ public class AcceptDataByKkoAlimtalk extends AcceptData } @Override - public KkoAlimtalkAcceptReqDTO make() { + public KkoAlimtalkAcceptReqDTO createReqDto() { KkoAlimtalkAcceptReqDTO acceptReqDTO = KkoAlimtalkAcceptReqDTO.builder() .vender(intgrnSendMast.getVender().getCode()) .org_cd(intgrnSendMast.getOrgCd()) @@ -58,29 +58,18 @@ public class AcceptDataByKkoAlimtalk extends AcceptData protected XitProperty createXitProperty(IntgrnSendDetail intgrnSendDetail) { return XitProperty.builder() -// .bill_link_info(this.createBillLinkInfo(intgrnSendDetail)) .bill_acpt_data(this.createBillAcptData(intgrnSendDetail)) .tmplt_msg_data(this.createTmpltMsgData(intgrnSendDetail)) .build(); } - -// if (CmmnUtil.isEmpty(intgrnSendDetail.getKkoBillMast())) -// return null; -// else -// return BillLinkInfo.builder() -// .use_bill_mast_id(true) -// .bill_mast_id(intgrnSendDetail.getKkoBillMast().getBillMastId()) -// .build(); -// } - protected BillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { + protected EnsBillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { if (CmmnUtil.isEmpty(intgrnSendDetail.getBill())) return null; - return BillAcptReqDTO.builder() - .use_bill_uid(true) - .bill_uid(intgrnSendDetail.getBill().getBillUid()) - .bill_se(intgrnSendDetail.getBill().getBillSeCd()) - .bill_kko(null) + return EnsBillAcptReqDTO.builder() + .billUid(intgrnSendDetail.getBill().getBillUid()) + .billerUserKey(intgrnSendDetail.getBill().getBillerUserKey()) + .billSe(intgrnSendDetail.getBill().getBillSeCd()) .build(); } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptByKkoMydocEventListener.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptByKkoMydocEventListener.java index 37c3657..dff3ba7 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptByKkoMydocEventListener.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptByKkoMydocEventListener.java @@ -40,7 +40,7 @@ public class AcceptByKkoMydocEventListener implements AcceptDataEventListener resultInfo = (Map) responseVO.getResultInfo(); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptDataByKkoMydoc.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptDataByKkoMydoc.java index d9fbdd9..af9709d 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptDataByKkoMydoc.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/kkomydoc/AcceptDataByKkoMydoc.java @@ -3,7 +3,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.kkomydoc; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.core.utils.crypto.AES256; import cokr.xit.ens.core.utils.crypto.Crypto; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.AcceptData; @@ -27,7 +27,7 @@ public class AcceptDataByKkoMydoc extends AcceptData { } @Override - public KkoMydocAcceptReqDTO make() { + public KkoMydocAcceptReqDTO createReqDto() { KkoMydocAcceptReqDTO acceptReqDTO = KkoMydocAcceptReqDTO.builder() .vender(intgrnSendMast.getVender().getCode()) .org_cd(intgrnSendMast.getOrgCd()) @@ -79,23 +79,13 @@ public class AcceptDataByKkoMydoc extends AcceptData { .build(); } - -// if (CmmnUtil.isEmpty(intgrnSendDetail.getKkoBillMast())) -// return null; -// else -// return BillLinkInfo.builder() -// .use_bill_mast_id(true) -// .bill_mast_id(intgrnSendDetail.getKkoBillMast().getBillMastId()) -// .build(); -// } - protected BillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { + protected EnsBillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { if (CmmnUtil.isEmpty(intgrnSendDetail.getBill())) return null; - return BillAcptReqDTO.builder() - .use_bill_uid(true) - .bill_uid(intgrnSendDetail.getBill().getBillUid()) - .bill_se(intgrnSendDetail.getBill().getBillSeCd()) - .bill_kko(null) + return EnsBillAcptReqDTO.builder() + .billUid(intgrnSendDetail.getBill().getBillUid()) + .billerUserKey(intgrnSendDetail.getBill().getBillerUserKey()) + .billSe(intgrnSendDetail.getBill().getBillSeCd()) .build(); } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktGibis/AcceptByKtGibisEventListener.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktGibis/AcceptByKtGibisEventListener.java index 282eb59..19396db 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktGibis/AcceptByKtGibisEventListener.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktGibis/AcceptByKtGibisEventListener.java @@ -40,7 +40,7 @@ public class AcceptByKtGibisEventListener implements AcceptDataEventListener { } @Override - public KtGibisAcceptReqDTO make() { + public KtGibisAcceptReqDTO createReqDto() { KtGibisAcceptReqDTO acceptReqDTO = KtGibisAcceptReqDTO.builder() .vender(intgrnSendMast.getVender().getCode()) .org_cd(intgrnSendMast.getOrgCd()) @@ -66,14 +66,13 @@ public class AcceptDataByKtGibis extends AcceptData { .build(); } - protected BillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { + protected EnsBillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { if (CmmnUtil.isEmpty(intgrnSendDetail.getBill())) return null; - return BillAcptReqDTO.builder() - .use_bill_uid(true) - .bill_uid(intgrnSendDetail.getBill().getBillUid()) - .bill_se(intgrnSendDetail.getBill().getBillSeCd()) - .bill_kko(null) + return EnsBillAcptReqDTO.builder() + .billUid(intgrnSendDetail.getBill().getBillUid()) + .billerUserKey(intgrnSendDetail.getBill().getBillerUserKey()) + .billSe(intgrnSendDetail.getBill().getBillSeCd()) .build(); } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptByKtSigntalkEventListener.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptByKtSigntalkEventListener.java index 9682c5c..bae43d5 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptByKtSigntalkEventListener.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptByKtSigntalkEventListener.java @@ -40,7 +40,7 @@ public class AcceptByKtSigntalkEventListener implements AcceptDataEventListener< EnsResponseVO responseVO = null; try { - responseVO = ktSigntalkService.accept(ev.make()); + responseVO = ktSigntalkService.accept(ev.createReqDto()); if (EnsErrCd.OK.equals(responseVO.getErrCode())) { @@ -58,13 +58,13 @@ public class AcceptByKtSigntalkEventListener implements AcceptDataEventListener< Map resultInfo = (Map) responseVO.getResultInfo(); Long sendMastId = (Long) resultInfo.get("sendMastId"); - if (ev.IsReserveSend()) { + if (ev.IsReserveSend()) { KtSigntalkSendReserveEvent event = KtSigntalkSendReserveEvent.builder() .sendMastIds(Arrays.asList(sendMastId)) .build(); applicationEventPublisher.publishEvent(event); - } else { + } else { KtSigntalkSendRealtimeEvent event = KtSigntalkSendRealtimeEvent.builder() .sendMastIds(Arrays.asList(sendMastId)) // .callback(() -> this.fetch(sendMastId, ev.getSendDetails())) @@ -93,7 +93,7 @@ public class AcceptByKtSigntalkEventListener implements AcceptDataEventListener< @Override public Map convertSendDetailIdMap(List sendDetails) { - + Map sendDetailIdMap = sendDetails.stream() .map(row -> { Map m = new HashMap<>(); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptDataByKtSigntalk.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptDataByKtSigntalk.java index 7c0ed91..00459df 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptDataByKtSigntalk.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/ktSigntalk/AcceptDataByKtSigntalk.java @@ -3,7 +3,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.ktSigntalk; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.core.utils.crypto.AES256; import cokr.xit.ens.core.utils.crypto.Crypto; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.AcceptData; @@ -26,7 +26,7 @@ public class AcceptDataByKtSigntalk extends AcceptData { } @Override - public KtSigntalkAcceptReqDTO make() { + public KtSigntalkAcceptReqDTO createReqDto() { KtSigntalkAcceptReqDTO acceptReqDTO = KtSigntalkAcceptReqDTO.builder() .vender(intgrnSendMast.getVender().getCode()) .org_cd(intgrnSendMast.getOrgCd()) @@ -78,23 +78,13 @@ public class AcceptDataByKtSigntalk extends AcceptData { .build(); } - -// if (CmmnUtil.isEmpty(intgrnSendDetail.getKkoBillMast())) -// return null; -// else -// return BillLinkInfo.builder() -// .use_bill_mast_id(true) -// .bill_mast_id(intgrnSendDetail.getKkoBillMast().getBillMastId()) -// .build(); -// } - protected BillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { + protected EnsBillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { if (CmmnUtil.isEmpty(intgrnSendDetail.getBill())) return null; - return BillAcptReqDTO.builder() - .use_bill_uid(true) - .bill_uid(intgrnSendDetail.getBill().getBillUid()) - .bill_se(intgrnSendDetail.getBill().getBillSeCd()) - .bill_kko(null) + return EnsBillAcptReqDTO.builder() + .billUid(intgrnSendDetail.getBill().getBillUid()) + .billerUserKey(intgrnSendDetail.getBill().getBillerUserKey()) + .billSe(intgrnSendDetail.getBill().getBillSeCd()) .build(); } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptByNvSigntalkEventListener.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptByNvSigntalkEventListener.java index 46c418b..8658622 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptByNvSigntalkEventListener.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptByNvSigntalkEventListener.java @@ -40,7 +40,7 @@ public class AcceptByNvSigntalkEventListener implements AcceptDataEventListener< EnsResponseVO responseVO = null; try { - responseVO = nvSigntalkService.accept(ev.make()); + responseVO = nvSigntalkService.accept(ev.createReqDto()); if (EnsErrCd.OK.equals(responseVO.getErrCode())) { @@ -58,13 +58,13 @@ public class AcceptByNvSigntalkEventListener implements AcceptDataEventListener< Map resultInfo = (Map) responseVO.getResultInfo(); Long sendMastId = (Long) resultInfo.get("sendMastId"); - if (ev.IsReserveSend()) { + if (ev.IsReserveSend()) { NvSigntalkSendReserveEvent event = NvSigntalkSendReserveEvent.builder() .sendMastIds(Arrays.asList(sendMastId)) .build(); applicationEventPublisher.publishEvent(event); - } else { + } else { NvSigntalkSendRealtimeEvent event = NvSigntalkSendRealtimeEvent.builder() .sendMastIds(Arrays.asList(sendMastId)) // .callback(() -> this.fetch(sendMastId, ev.getSendDetails())) @@ -93,7 +93,7 @@ public class AcceptByNvSigntalkEventListener implements AcceptDataEventListener< @Override public Map convertSendDetailIdMap(List sendDetails) { - + Map sendDetailIdMap = sendDetails.stream() .map(row -> { Map m = new HashMap<>(); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptDataByNvSigntalk.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptDataByNvSigntalk.java index cb7cd86..f47ecc3 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptDataByNvSigntalk.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/intgrnnoti/service/support/nvsigntalk/AcceptDataByNvSigntalk.java @@ -3,7 +3,7 @@ package cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.nvsigntalk; import cokr.xit.ens.core.utils.CmmnUtil; import cokr.xit.ens.core.utils.crypto.AES256; import cokr.xit.ens.core.utils.crypto.Crypto; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendDetail; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast; import cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support.AcceptData; @@ -26,7 +26,7 @@ public class AcceptDataByNvSigntalk extends AcceptData { } @Override - public NvSigntalkAcceptReqDTO make() { + public NvSigntalkAcceptReqDTO createReqDto() { NvSigntalkAcceptReqDTO acceptReqDTO = NvSigntalkAcceptReqDTO.builder() .vender(intgrnSendMast.getVender().getCode()) .org_cd(intgrnSendMast.getOrgCd()) @@ -63,32 +63,19 @@ public class AcceptDataByNvSigntalk extends AcceptData { protected XitProperty createXitProperty(IntgrnSendDetail intgrnSendDetail) { return XitProperty.builder() .mbl_page_data(CmmnUtil.isEmpty(intgrnSendDetail.getJMblPageData()) ? null : gson.fromJson(intgrnSendDetail.getJMblPageData(), Map.class)) -// .bill_link_info(this.createBillLinkInfo(intgrnSendDetail)) .bill_acpt_data(this.createBillAcptData(intgrnSendDetail)) -// .jid(intgrnSendDetail.getJids()) .jid(aes256.decrypt(intgrnSendDetail.getJid())) .tmplt_msg_data(this.createTmpltMsgData(intgrnSendDetail)) .build(); } -// protected BillLinkInfo createBillLinkInfo(IntgrnSendDetail intgrnSendDetail) { -// if (CmmnUtil.isEmpty(intgrnSendDetail.getKkoBillMast())) -// return null; -// else -// return BillLinkInfo.builder() -// .use_bill_mast_id(true) -// .bill_mast_id(intgrnSendDetail.getKkoBillMast().getBillMastId()) -// .build(); -// } - - protected BillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { + protected EnsBillAcptReqDTO createBillAcptData(IntgrnSendDetail intgrnSendDetail) { if (CmmnUtil.isEmpty(intgrnSendDetail.getBill())) return null; - return BillAcptReqDTO.builder() - .use_bill_uid(true) - .bill_uid(intgrnSendDetail.getBill().getBillUid()) - .bill_se(intgrnSendDetail.getBill().getBillSeCd()) - .bill_kko(null) + return EnsBillAcptReqDTO.builder() + .billUid(intgrnSendDetail.getBill().getBillUid()) + .billerUserKey(intgrnSendDetail.getBill().getBillerUserKey()) + .billSe(intgrnSendDetail.getBill().getBillSeCd()) .build(); } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/model/SendDetailMblPageDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/model/SendDetailMblPageDTO.java index 1c67154..34c8f8c 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/model/SendDetailMblPageDTO.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/model/SendDetailMblPageDTO.java @@ -27,7 +27,7 @@ public class SendDetailMblPageDTO { private Long sendDetailId; @NotNull(message = "페이지데이터는 필수 입력값 입니다.") - @Schema(required = true, title = "페이지 내에 보여줄 상세 정보", example = "{\"postSe\":\"testMblPage\",\"sendDetailId\":1,\"document\":{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"하하하\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"다라마\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"},\"1111-23123-12313\":{\"use-clipboard\":false,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\\n1111-23123-12313 카카오\\n카카오뱅크\\nhttp://www.naver.com\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"액\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"],\"highlight\":{\"전기료\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"링크 이미지\":\"http://www.xit.co.kr/....\"},{\"Base64 이미지\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\"}]}}") + @Schema(required = true, title = "페이지 내에 보여줄 상세 정보", example = "{\"details\":[{\"title\":\"텍스트 타입\",\"item_type\":\"TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"하하하\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[\"test\",\"하하하\"]},{\"title\":\"PRE 텍스트 타입\",\"item_type\":\"PRE_TEXT\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"다라마\":{\"use-clipboard\":true,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"},\"1111-23123-12313\":{\"use-clipboard\":false,\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":\"가나다라마\\r\\nABCDEFGHI\\n1234567890\\n1111-23123-12313 카카오\\n카카오뱅크\\nhttp://www.naver.com\"},{\"title\":\"키-밸류 타입\",\"item_type\":\"KEY_VALUE\",\"properties\":{\"use_toggle\":false,\"style\":{\"highlight\":{\"액\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":[{\"key\":\"당월 부과 금액\",\"value\":\"200,203원\",\"level\":1},{\"key\":\"미납액\",\"value\":\"1,200원\",\"level\":1}]},{\"title\":\"테이블 타입\",\"item_type\":\"TABLE\",\"properties\":{\"use_toggle\":false,\"style\":{\"text_align\":[\"center\",\"left\",\"right\"],\"highlight\":{\"전기료\":{\"font-size\":\"large\",\"font-color\":\"red\",\"font-weight\":\"bold\",\"font-style\":\"italic\"}}},\"hyperlink\":[\"http://www.naver.com\",\"http://www.xit.co.kr\"]},\"elements\":{\"head\":[\"항목\",\"당월금액\",\"전월대비\"],\"rows\":[[\"전기료\",\"1,000,000원\",\"+500,000\"],[\"수도료\",\"300,000원\",\"-100,000\"]]}},{\"title\":\"이미지 타입\",\"item_type\":\"IMAGE\",\"print_type\":\"이미지출력타입(공백: img태그(default), SLIDE: 슬라이드 기능 적용)\",\"properties\":{\"use_toggle\":false},\"elements\":[{\"key\":\"링크 이미지\",\"value\":\"http://www.xit.co.kr/....\"},{\"key\":\"Base64 이미지\",\"value\":\"data:image/png;base64,iVBORw0KGgoAAAAN....\"}]},{\"title\":\"링크버튼 타입\",\"item_type\":\"BUTTON\",\"link_url\":\"https://www.naver.com\"},{\"title\":\"결제버튼 타입\",\"item_type\":\"PAY_BUTTON\"}]}") private Map>> document; } diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/MblPageControllerSupport.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/MblPageControllerSupport.java new file mode 100644 index 0000000..80d0032 --- /dev/null +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/MblPageControllerSupport.java @@ -0,0 +1,37 @@ +package cokr.xit.ens.modules.common.ctgy.mblpage.presentation; + +import cokr.xit.ens.core.utils.CmmnUtil; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.domain.SendMast; +import com.google.gson.Gson; +import org.springframework.beans.factory.annotation.Value; + +import java.util.HashMap; +import java.util.Map; + + +public abstract class MblPageControllerSupport { + private Gson gson = new Gson(); + @Value("${xit.mblpage.payinf.host}") + private String payInfHost; + + /** + * 페이버튼 결제정보 + * + * @param bill + * @param sendMast + * @return + */ + protected String getJsonPayBtnInf(Bill bill, SendMast sendMast) { + if (CmmnUtil.isEmpty(bill)) + return null; + + Map payBtnInf = new HashMap<>(); + payBtnInf.put("billUid", bill.getBillUid()); + payBtnInf.put("billSe", bill.getBillSeCd().getCode()); + payBtnInf.put("postSe", sendMast.getPostSe().getCode()); + payBtnInf.put("payInfHost", payInfHost); + + return gson.toJson(payBtnInf); + } +} diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/SendDetailMblPageController.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/SendDetailMblPageController.java index e7e454c..6440887 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/SendDetailMblPageController.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/mblpage/presentation/SendDetailMblPageController.java @@ -1,9 +1,13 @@ package cokr.xit.ens.modules.common.ctgy.mblpage.presentation; import cokr.xit.ens.core.exception.code.EnsErrCd; +import cokr.xit.ens.modules.common.code.PostSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; import cokr.xit.ens.modules.common.ctgy.mblpage.domain.SendDetailMblPage; import cokr.xit.ens.modules.common.ctgy.mblpage.domain.ids.SendDetailMblPageIds; import cokr.xit.ens.modules.common.ctgy.mblpage.domain.repository.SendDetailMblPageRepository; +import cokr.xit.ens.modules.common.domain.SendMast; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -12,29 +16,43 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import java.util.Arrays; import java.util.Optional; @Tag(name = "SendDetailMblPageTestController") @Slf4j @RequiredArgsConstructor @Controller -public class SendDetailMblPageController { +public class SendDetailMblPageController extends MblPageControllerSupport { private final SendDetailMblPageRepository sendDetailMblPageRepository; @Operation(summary = "모바일페이지 출력") @GetMapping(value = "/cmft/mbl/page/{postSe}/{sendDetailId}") - public String mblPagePrnt(@PathVariable String postSe, @PathVariable Long sendDetailId, ModelMap model) { + public String mblPagePrnt(@PathVariable String postSe, @PathVariable Long sendDetailId, ModelMap model, @RequestParam(required = false, defaultValue = "") String billUid, @RequestParam(required = false, defaultValue = "") String billSe) { Optional sendDetailMblPage = sendDetailMblPageRepository.findById(SendDetailMblPageIds.builder() .postSe(postSe) .sendDetailId(sendDetailId) .build()); - model.put("details", sendDetailMblPage.isPresent() ? sendDetailMblPage.get().getDetails() : "{}"); - model.put("payButtonLinks", "{}"); + Bill bill = Bill.builder() + .billUid(billUid) + .billSeCd(Arrays.stream(BillSeCd.values()) + .noneMatch(billSeCd -> billSeCd.getCode().equals(billSe)) + ? BillSeCd.all + : BillSeCd.valueOf(billSe)) + .build(); + SendMast sendMast = SendMast.builder() + .postSe(Arrays.stream(PostSeCd.values()) + .noneMatch(postSeCd -> postSeCd.getCode().equals(postSe)) + ? PostSeCd.kkoMydoc + : PostSeCd.valueOf(postSe)) + .build(); + model.put("payBtnInf", getJsonPayBtnInf(bill, sendMast)); model.put("errCode", EnsErrCd.OK); model.put("errMsg", EnsErrCd.OK.getCodeNm()); diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/domain/OrgMng.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/domain/OrgMng.java index 89b1336..6a2931f 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/domain/OrgMng.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/domain/OrgMng.java @@ -34,24 +34,19 @@ public class OrgMng { @Column(name = "org_cd", nullable = false, length = 20) private String orgCd; - + @Column(name = "org_nm", nullable = false, length = 30) @Setter private String orgNm; - @Column(name = "sub_org_id", nullable = true) - @Setter - private Long subOrgId; - - @Column(name = "regist_dt", nullable = true) @CreationTimestamp @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonDeserialize(using = LocalDateTimeDeserializer.class) private LocalDateTime registDt; - + @Column(name = "last_updt_dt", nullable = true) @UpdateTimestamp @JsonSerialize(using = LocalDateTimeSerializer.class) @@ -60,81 +55,114 @@ public class OrgMng { - @Column(name = "kko_md_access_token", nullable = true) + @Column(name = "kko_md_access_token", nullable = true, length = 50) @Setter private String kkoMdAccessToken; - @Column(name = "kko_md_contract_uuid", nullable = true) + @Column(name = "kko_md_contract_uuid", nullable = true, length = 50) @Setter private String kkoMdContractUuid; - @Column(name = "kko_bp_biller_code", nullable = true) + @Column(name = "kko_bp_biller_code", nullable = true, length = 30) @Setter private String kkoBpBillerCode; - @Column(name = "kko_bp_authorization", nullable = true) + @Column(name = "kko_bp_authorization", nullable = true, length = 64) @Setter private String kkoBpAuthorization; - + @Column(name = "kko_bp_csign_yn", nullable = true, length = 1) @Setter private String kkoBpCsignYn; - @Column(name = "kko_bp_csign_prepay_api", nullable = true) + @Column(name = "kko_bp_url_api", nullable = true, length = 100) + @Setter + private String kkoBpUrlApi; + + @Column(name = "kko_bp_notice_api", nullable = true, length = 100) @Setter - private String kkoBpCsignPrepayApi; + private String kkoBpNoticeApi; - @Column(name = "kko_bp_csign_payresult_api", nullable = true) + @Column(name = "kko_bp_prepay_api", nullable = true, length = 100) @Setter - private String kkoBpCsignPayresultApi; + private String kkoBpPrepayApi; + + @Column(name = "kko_bp_payresult_api", nullable = true, length = 100) + @Setter + private String kkoBpPayresultApi; - @Column(name = "kko_at_bsid", nullable = true) + @Column(name = "kko_at_bsid", nullable = true, length = 30) @Setter private String kkoAtBsid; - @Column(name = "kko_at_passwd", nullable = true) + @Column(name = "kko_at_passwd", nullable = true, length = 50) @Setter private String kkoAtPasswd; - @Column(name = "kko_at_sender_key", nullable = true) + @Column(name = "kko_at_sender_key", nullable = true, length = 50) @Setter private String kkoAtSenderKey; - @Column(name = "nice_cd_site_code", nullable = true) + @Column(name = "nice_cd_site_code", nullable = true, length = 30) @Setter private String niceCdSiteCode; - @Column(name = "nice_cd_site_pw", nullable = true) + @Column(name = "nice_cd_site_pw", nullable = true, length = 30) @Setter private String niceCdSitePw; - @Column(name = "nice_cd_client_id", nullable = true) + @Column(name = "nice_cd_client_id", nullable = true, length = 50) @Setter private String niceCdClientId; - @Column(name = "nice_cd_client_sercet", nullable = true) + @Column(name = "nice_cd_client_sercet", nullable = true, length = 50) @Setter private String niceCdClientSercet; - @Column(name = "nv_st_x_naver_client_id", nullable = true) + @Column(name = "nv_st_x_naver_client_id", nullable = true, length = 30) @Setter private String nvStXNaverClientId; - @Column(name = "nv_st_x_naver_client_secret", nullable = true) + @Column(name = "nv_st_x_naver_client_secret", nullable = true, length = 30) @Setter private String nvStXNaverClientSecret; - @Column(name = "nv_st_org_id", nullable = true) + @Column(name = "nv_st_org_id", nullable = true, length = 50) @Setter private String nvStOrgId; -// @Column(name = "nv_st_org_id", nullable = true) -// @Setter -// private String nvStOrgId; + + @Column(name = "nv_bp_partner_id", nullable = true, length = 30) + @Setter + private String nvBpPartnerId; + + @Column(name = "nv_bp_client_id", nullable = true, length = 30) + @Setter + private String nvBpClientId; + + @Column(name = "nv_bp_client_secret", nullable = true, length = 30) + @Setter + private String nvBpClientSecret; + + @Column(name = "nv_bp_notice_api", nullable = true, length = 100) + @Setter + private String nvBpNoticeApi; + + @Column(name = "nv_bp_prepay_api", nullable = true, length = 100) + @Setter + private String nvBpPrepayApi; + + @Column(name = "nv_bp_payresult_api", nullable = true, length = 100) + @Setter + private String nvBpPayresultApi; + + @Column(name = "nv_bp_paycancel_api", nullable = true, length = 100) + @Setter + private String nvBpPaycancelApi; @Column(name = "kt_st_access_token", nullable = true, length = 1000) @@ -146,15 +174,15 @@ public class OrgMng { private String ktStServiceCd; - @Column(name = "kt_st_service_key", nullable = true) + @Column(name = "kt_st_service_key", nullable = true, length = 100) @Setter private String ktStServiceKey; - @Column(name = "kt_st_clientId", nullable = true, length = 255) + @Column(name = "kt_st_clientId", nullable = true, length = 50) @Setter private String ktStClientId; - @Column(name = "kt_st_client_secret", nullable = true, length = 255) + @Column(name = "kt_st_client_secret", nullable = true, length = 50) @Setter private String ktStClientSecret; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/model/OrgMngDTO.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/model/OrgMngDTO.java index 2277121..6b14800 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/model/OrgMngDTO.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/model/OrgMngDTO.java @@ -25,58 +25,103 @@ public class OrgMngDTO { private String orgNm; - - - + @Length(max = 50, message = "(계약정보)엑세스토큰의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)엑세스토큰", example = " ") private String kkoMdAccessToken; + @Length(max = 50, message = "(계약정보)계약Uuid의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)계약Uuid", example = " ") private String kkoMdContractUuid; + @Length(max = 30, message = "(계약정보)빌러코드의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)빌러코드", example = " ") private String kkoBpBillerCode; + @Length(max = 64, message = "(계약정보)허가코드의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)허가코드", example = " ") private String kkoBpAuthorization; -// @NotEmpty(message = "납부요청 위탁여부는 필수 입력값 입니다.") @Pattern(regexp = "(Y|N)", message = "납부요청 위탁여부는 Y 또는 N 만 입력 할 수 있습니다.") @Schema(required = false, title = "납부요청 위탁여부", example = " ") private String kkoBpCsignYn; + @Length(max = 100, message = "청구서링크생성정보API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 청구서링크생성정보API URL", example = " ") + private String kkoBpUrlApi; + @Length(max = 100, message = "납부정보조회API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 납부정보조회API URL", example = " ") + private String kkoBpNoticeApi; + @Length(max = 100, message = "납부가능조회API의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "이용시스템의 납부가능조회API URL", example = " ") - private String kkoBpCsignPrepayApi; + private String kkoBpPrepayApi; + @Length(max = 100, message = "납부결과API의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "이용시스템의 납부결과API URL", example = " ") - private String kkoBpCsignPayResultApi; + private String kkoBpPayResultApi; + @Length(max = 30, message = "(계약정보)bs아이디의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)bs아이디", example = " ") private String kkoAtBsid; + @Length(max = 50, message = "(계약정보)패스워드의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)패스워드", example = " ") private String kkoAtPasswd; + @Length(max = 50, message = "(계약정보)발송자키의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)발송자키", example = " ") private String kkoAtSenderKey; + @Length(max = 30, message = "(계약정보)사이트코드(socket)의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)사이트코드(socket)", example = " ") private String niceCdSiteCode; + @Length(max = 30, message = "(계약정보)사이트패스워드(socket)의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)사이트패스워드(socket)", example = " ") private String niceCdSitePw; + @Length(max = 50, message = "(계약정보)클라이언트ID(rest)의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)클라이언트ID(rest)", example = " ") private String niceCdClientId; + @Length(max = 50, message = "(계약정보)클라이언트패스워드(rest)의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)클라이언트패스워드(rest)", example = " ") private String niceCdClientSercet; + @Length(max = 30, message = "(계약정보)클라이언트 아이디의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)클라이언트 아이디", example = " ") private String nvStXNaverClientId; + @Length(max = 30, message = "(계약정보)클라이언트 패스워드의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)클라이언트 패스워드", example = " ") private String nvStXNaverClientSecret; + @Length(max = 50, message = "(계약정보)하위기관명의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)하위기관명", example = " ") private String nvStOrgId; + @Length(max = 30, message = "(계약정보)파트너ID의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "(계약정보)파트너ID", example = " ") + private String nvBpPartnerId; + @Length(max = 30, message = "(계약정보)클라이언트ID의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "(계약정보)클라이언트ID", example = " ") + private String nvBpClientId; + @Length(max = 30, message = "(계약정보)클라이언트Pwd의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "(계약정보)클라이언트Pwd", example = " ") + private String nvBpClientSecret; + @Length(max = 100, message = "납부정보조회API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 납부정보조회API URL", example = " ") + private String nvBpNoticeApi; + @Length(max = 100, message = "납부가능조회API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 납부가능조회API URL", example = " ") + private String nvBpPrepayApi; + @Length(max = 100, message = "납부결과API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 납부결과API URL", example = " ") + private String nvBpPayresultApi; + @Length(max = 100, message = "결제취소API의 최대 길이를 초과 했습니다.") + @Schema(required = false, title = "이용시스템의 결제취소API URL", example = " ") + private String nvBpPaycancelApi; + + @Length(max = 1000, message = "(계약정보)엑세스토큰의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)엑세스토큰", example = " ") private String ktStAccessToken; + @Length(max = 5, message = "(계약정보)서비스코드의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)서비스코드", example = " ") private String ktStServiceCd; + @Length(max = 100, message = "(계약정보)서비스키의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)서비스키", example = " ") private String ktStServiceKey; + @Length(max = 50, message = "(계약정보)고객ID의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)고객ID", example = " ") private String ktStClientId; + @Length(max = 50, message = "(계약정보)고객비밀번호의 최대 길이를 초과 했습니다.") @Schema(required = false, title = "(계약정보)고객비밀번호", example = " ") private String ktStClientSecret; diff --git a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/service/OrgMngService.java b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/service/OrgMngService.java index 6a8bde7..9c17bfa 100644 --- a/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/service/OrgMngService.java +++ b/src/main/java/cokr/xit/ens/modules/common/ctgy/sys/mng/service/OrgMngService.java @@ -68,7 +68,7 @@ public class OrgMngService { .build(); } if ("Y".equals(dto.getKkoBpCsignYn())) { - if (CmmnUtil.isEmpty(dto.getKkoBpCsignPrepayApi()) || CmmnUtil.isEmpty(dto.getKkoBpCsignPayResultApi())) + if (CmmnUtil.isEmpty(dto.getKkoBpPrepayApi()) || CmmnUtil.isEmpty(dto.getKkoBpPayResultApi())) return EnsResponseVO.errRsltBuilder() .errCode(EnsErrCd.ERR410) .errMsg("납부요청 위탁여부(kkoBpCsignYn)가 Y 일 경우 \"납부가능조회API\"와 \"납부결과API\"의 URL은 필수 입니다.") @@ -80,38 +80,41 @@ public class OrgMngService { orgMngRepository.save(OrgMng.builder() - .orgCd(dto.getOrgCd()) - .orgNm(dto.getOrgNm()) - .subOrgId(null) - - .kkoMdAccessToken(dto.getKkoMdAccessToken()) - .kkoMdContractUuid(dto.getKkoMdContractUuid()) - - .kkoBpBillerCode(dto.getKkoBpBillerCode()) - .kkoBpAuthorization(dto.getKkoBpAuthorization()) - .kkoBpCsignYn(dto.getKkoBpCsignYn()) - .kkoBpCsignPrepayApi(dto.getKkoBpCsignPrepayApi()) - .kkoBpCsignPayresultApi(dto.getKkoBpCsignPayResultApi()) - - .kkoAtBsid(dto.getKkoAtBsid()) - .kkoAtPasswd(dto.getKkoAtPasswd()) - .kkoAtSenderKey(dto.getKkoAtSenderKey()) - - .niceCdSiteCode(dto.getNiceCdSiteCode()) - .niceCdSitePw(dto.getNiceCdSitePw()) - .niceCdClientId(dto.getNiceCdClientId()) - .niceCdClientSercet(dto.getNiceCdClientSercet()) - - .nvStXNaverClientId(dto.getNvStXNaverClientId()) - .nvStXNaverClientSecret(dto.getNvStXNaverClientSecret()) - .nvStOrgId(dto.getNvStOrgId()) - - .ktStAccessToken(dto.getKtStAccessToken()) - .ktStServiceCd(dto.getKtStServiceCd()) - .ktStServiceKey(dto.getKtStServiceKey()) - .ktStClientId(dto.getKtStClientId()) - .ktStClientSecret(dto.getKtStClientId()) - .build() + .orgCd(dto.getOrgCd()) + .orgNm(dto.getOrgNm()) +// .subOrgId(null) + .kkoMdAccessToken(dto.getKkoMdAccessToken()) + .kkoMdContractUuid(dto.getKkoMdContractUuid()) + .kkoBpBillerCode(dto.getKkoBpBillerCode()) + .kkoBpAuthorization(dto.getKkoBpAuthorization()) + .kkoBpCsignYn(dto.getKkoBpCsignYn()) + .kkoBpUrlApi(dto.getKkoBpUrlApi()) + .kkoBpNoticeApi(dto.getKkoBpNoticeApi()) + .kkoBpPrepayApi(dto.getKkoBpPrepayApi()) + .kkoBpPayresultApi(dto.getKkoBpPayResultApi()) + .kkoAtBsid(dto.getKkoAtBsid()) + .kkoAtPasswd(dto.getKkoAtPasswd()) + .kkoAtSenderKey(dto.getKkoAtSenderKey()) + .niceCdSiteCode(dto.getNiceCdSiteCode()) + .niceCdSitePw(dto.getNiceCdSitePw()) + .niceCdClientId(dto.getNiceCdClientId()) + .niceCdClientSercet(dto.getNiceCdClientSercet()) + .nvStXNaverClientId(dto.getNvStXNaverClientId()) + .nvStXNaverClientSecret(dto.getNvStXNaverClientSecret()) + .nvStOrgId(dto.getNvStOrgId()) + .nvBpPartnerId(dto.getNvBpPartnerId()) + .nvBpClientId(dto.getNvBpClientId()) + .nvBpClientSecret(dto.getNvBpClientSecret()) + .nvBpNoticeApi(dto.getNvBpNoticeApi()) + .nvBpPrepayApi(dto.getNvBpPrepayApi()) + .nvBpPayresultApi(dto.getNvBpPayresultApi()) + .nvBpPaycancelApi(dto.getNvBpPaycancelApi()) + .ktStAccessToken(dto.getKtStAccessToken()) + .ktStServiceCd(dto.getKtStServiceCd()) + .ktStServiceKey(dto.getKtStServiceKey()) + .ktStClientId(dto.getKtStClientId()) + .ktStClientSecret(dto.getKtStClientId()) + .build() ); return EnsResponseVO.okBuilder().build(); @@ -144,7 +147,7 @@ public class OrgMngService { .build(); } if ("Y".equals(dto.getKkoBpCsignYn())) { - if (CmmnUtil.isEmpty(dto.getKkoBpCsignPrepayApi()) || CmmnUtil.isEmpty(dto.getKkoBpCsignPayResultApi())) + if (CmmnUtil.isEmpty(dto.getKkoBpPrepayApi()) || CmmnUtil.isEmpty(dto.getKkoBpPayResultApi())) return EnsResponseVO.errRsltBuilder() .errCode(EnsErrCd.ERR410) .errMsg("납부요청 위탁여부(kkoBpCsignYn)가 Y 일 경우 \"납부가능조회API\"와 \"납부결과API\"의 URL은 필수 입니다.") @@ -154,16 +157,17 @@ public class OrgMngService { orgMng.setOrgNm(dto.getOrgNm()); - orgMng.setSubOrgId(null); - +// orgMng.setSubOrgId(null); orgMng.setKkoMdAccessToken(dto.getKkoMdAccessToken()); orgMng.setKkoMdContractUuid(dto.getKkoMdContractUuid()); - orgMng.setKkoBpBillerCode(dto.getKkoBpBillerCode()); + orgMng.setKkoBpAuthorization(dto.getKkoBpAuthorization()); orgMng.setKkoBpCsignYn(dto.getKkoBpCsignYn()); - orgMng.setKkoBpCsignPrepayApi(dto.getKkoBpCsignPrepayApi()); - orgMng.setKkoBpCsignPayresultApi(dto.getKkoBpCsignPayResultApi()); + orgMng.setKkoBpUrlApi(dto.getKkoBpUrlApi()); + orgMng.setKkoBpNoticeApi(dto.getKkoBpNoticeApi()); + orgMng.setKkoBpPrepayApi(dto.getKkoBpPrepayApi()); + orgMng.setKkoBpPayresultApi(dto.getKkoBpPayResultApi()); orgMng.setKkoAtBsid(dto.getKkoAtBsid()); orgMng.setKkoAtPasswd(dto.getKkoAtPasswd()); diff --git a/src/main/java/cokr/xit/ens/modules/common/domain/support/FieldError.java b/src/main/java/cokr/xit/ens/modules/common/domain/support/FieldError.java index 5b81707..b41e173 100644 --- a/src/main/java/cokr/xit/ens/modules/common/domain/support/FieldError.java +++ b/src/main/java/cokr/xit/ens/modules/common/domain/support/FieldError.java @@ -6,22 +6,24 @@ import lombok.RequiredArgsConstructor; import javax.persistence.Column; import javax.persistence.Embeddable; +import javax.persistence.Lob; @Embeddable @Getter @RequiredArgsConstructor public class FieldError { - @Column(name = "error_code") - private String errorCode; - - @Column(name = "error_message", length = 4000) - private String errorMessage; - - - @Builder(builderMethodName = "initBuilder") - public FieldError(String errorCode, String errorMessage) { - this.errorCode = errorCode; - this.errorMessage = errorMessage; - } + @Column(name = "error_code", length = 30) + private String errorCode; + + @Column(name = "error_message") + @Lob + private String errorMessage; + + + @Builder(builderMethodName = "initBuilder") + public FieldError(String errorCode, String errorMessage) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + } } diff --git a/src/main/java/cokr/xit/ens/modules/common/monitor/MessageByBill.java b/src/main/java/cokr/xit/ens/modules/common/monitor/MessageByBill.java index 6f39c03..674dbb6 100644 --- a/src/main/java/cokr/xit/ens/modules/common/monitor/MessageByBill.java +++ b/src/main/java/cokr/xit/ens/modules/common/monitor/MessageByBill.java @@ -2,7 +2,7 @@ package cokr.xit.ens.modules.common.monitor; import cokr.xit.ens.core.exception.code.EnsErrCd; import cokr.xit.ens.core.monitor.Message; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd; import lombok.Builder; import java.time.LocalDateTime; diff --git a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/SendDetailKkoAlimtalk.java b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/SendDetailKkoAlimtalk.java index 097a1ff..acf87c7 100644 --- a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/SendDetailKkoAlimtalk.java +++ b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/SendDetailKkoAlimtalk.java @@ -1,6 +1,6 @@ package cokr.xit.ens.modules.kkoalimtalk.domain; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; import cokr.xit.ens.modules.common.domain.BaseEntity; import cokr.xit.ens.modules.common.domain.SendMast; import cokr.xit.ens.modules.common.domain.support.FieldError; diff --git a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/repository/SendDetailKkoAlimtalkRepositoryImpl.java b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/repository/SendDetailKkoAlimtalkRepositoryImpl.java index 7972fea..9be0c54 100644 --- a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/repository/SendDetailKkoAlimtalkRepositoryImpl.java +++ b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/domain/repository/SendDetailKkoAlimtalkRepositoryImpl.java @@ -6,7 +6,7 @@ import lombok.RequiredArgsConstructor; import java.util.List; -import static cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.QBill.bill; +import static cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.QBill.bill; import static cokr.xit.ens.modules.common.domain.QSendMast.sendMast; import static cokr.xit.ens.modules.kkoalimtalk.domain.QSendDetailKkoAlimtalk.sendDetailKkoAlimtalk; diff --git a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/model/config/XitProperty.java b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/model/config/XitProperty.java index cc1c3f1..cfe70c7 100644 --- a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/model/config/XitProperty.java +++ b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/model/config/XitProperty.java @@ -1,6 +1,6 @@ package cokr.xit.ens.modules.kkoalimtalk.model.config; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillAcptReqDTO; +import cokr.xit.ens.core.model.EnsBillAcptReqDTO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; @@ -21,7 +21,7 @@ public class XitProperty { // private BillLinkInfo bill_link_info; @Valid - private BillAcptReqDTO bill_acpt_data; + private EnsBillAcptReqDTO bill_acpt_data; @Schema(required = false, title = "템플릿 메시지 데이터", example = "{\"#{TARGET_NAME}\":\"홍길동\",\"#{CAR_NO}\":\"12더1234\",\"#{HISTORY}\":\"2022-01-01\",\"#{FEE}\":\"1000\",\"#{YYYY}\":\"2022\",\"#{MM}\":\"03\",\"#{DD}\":\"30\",\"#{BANK}\":\"기업\",\"#{ACCOUNT}\":\"311-063233-01-123\",\"#{HOMEPAGE}\":\"http://www.xit.co.kr\",\"#{REP_CALL_NO}\":\"070-4490-7404\"}") private Map tmplt_msg_data; diff --git a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/service/support/KkoAlimtalkAcceptor.java b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/service/support/KkoAlimtalkAcceptor.java index d119b2a..503c251 100644 --- a/src/main/java/cokr/xit/ens/modules/kkoalimtalk/service/support/KkoAlimtalkAcceptor.java +++ b/src/main/java/cokr/xit/ens/modules/kkoalimtalk/service/support/KkoAlimtalkAcceptor.java @@ -11,10 +11,9 @@ import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport; import cokr.xit.ens.modules.common.code.PostSeCd; import cokr.xit.ens.modules.common.code.StatCd; import cokr.xit.ens.modules.common.code.VenderCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.BillMakerSupport; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.code.BillSeCd; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.Bill; -import cokr.xit.ens.modules.common.ctgy.intgrnbill.entity.repository.BillRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.Bill; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillRepository; +import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.PaidTypeCd; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng; import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.ids.TmpltMngIds; import cokr.xit.ens.modules.common.ctgy.sys.mng.service.OrgMngService; @@ -49,7 +48,6 @@ import java.util.stream.Collectors; @Component @RequiredArgsConstructor public class KkoAlimtalkAcceptor implements EnsPhaseProcSupport { - private final Map billMakerMap; private final SendMastRepository sendMastRepository; private final SendDetailKkoAlimtalkRepository sendDetailKkoAlimtalkRepository; private final BillRepository billRepository; @@ -134,18 +132,20 @@ public class KkoAlimtalkAcceptor implements EnsPhaseProcSupport new RuntimeException("등록된 청구서가 없습니다.")); } else { bill = Bill.builder() // .billId(document.getXit_property().getBill_acpt_data().getBill_id()) .billId(null) .billUid(IdGenerator.getShortUUID(prefixBillUid)) - .billSeCd(document.getXit_property().getBill_acpt_data().getBill_se()) + .billerUserKey(document.getXit_property().getBill_acpt_data().getBillerUserKey()) + .billSeCd(document.getXit_property().getBill_acpt_data().getBillSe()) .orgMng(OrgMng.builder().orgCd(reqDTO.getOrg_cd()).build()) - .docBillKko(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_kko())) -// .docBillNv(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_nv())) +// .docBillKko(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_kko())) +// .docBillNv(CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv()) ? null : gson.toJson(document.getXit_property().getBill_acpt_data().getBill_nv())) .build(); } bills.add(bill); @@ -188,20 +188,10 @@ public class KkoAlimtalkAcceptor implements EnsPhaseProcSupport CmmnUtil.isEmpty(row.getBillId())) .collect(Collectors.toList()) ); - billMakerMap.keySet().stream() - .forEach(key -> { - try { - billMakerMap.get(key).accept(bills); - } catch (EnsException e) { - throw new EnsException(EnsErrCd.ACPT412, String.format("[%s] %s", e.getErrCd(), e.getMessage())); - } - }); - sendDetailKkoAlimtalkRepository.saveAll(sendDetails); @@ -235,19 +225,42 @@ public class KkoAlimtalkAcceptor implements EnsPhaseProcSupport buttons = new ArrayList<>(); - if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko())) - buttons.add(this.createBillButton("납부하기(카카오페이)", String.format("#{billlink_url_%s}", BillSeCd.bpKko.getCode()))); -// if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv())) -// buttons.add(this.createBillButton("납부하기(네이버페이)", String.format("#{billlink_url_%s}", BillSeCd.nv.getCode()))); +// if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko())) +// buttons.add(this.createBillButton("납부하기(카카오페이)", String.format("#{billlink_url_%s}", BillSeCd.bpKko.getCode()))); + if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data())) { + switch (document.getXit_property().getBill_acpt_data().getBillSe()) { + case privt: + case bpKko: + buttons.add(this.createBillButton(String.format("납부하기(%s)", PaidTypeCd.kakaoPay.getCodeNm()), String.format("#{billlink_url_%s}", PaidTypeCd.kakaoPay.getCode()))); + break; + case bpNv: + buttons.add(this.createBillButton(String.format("납부하기(%s)", PaidTypeCd.naverPay.getCodeNm()), String.format("#{billlink_url_%s}", PaidTypeCd.naverPay.getCode()))); + break; + default: + Arrays.stream(PaidTypeCd.values()).forEach(paidTypeCd -> this.createBillButton(String.format("납부하기(%s)", paidTypeCd.getCodeNm()), String.format("#{billlink_url_%s}", paidTypeCd.getCode()))); + break; + } + } document.getAttach().setButton(buttons); } } else { - if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_kko())) - document.getAttach().getButton().add(this.createBillButton("납부하기(카카오페이)", String.format("#{billlink_url_%s}", BillSeCd.bpKko.getCode()))); -// if (!CmmnUtil.isEmpty(document.getXit_property().getBill_acpt_data().getBill_nv())) -// document.getAttach().getButton().add(this.createBillButton("납부하기(네이버페이)", String.format("#{billlink_url_%s}", BillSeCd.nv.getCode()))); + List