나는 얼마 전에 Alipay의 QR 코드 지불을 연구 해 왔습니다. 나는 Alipay 문서가 정말 나쁘다고 말해야합니다 (적어도 처음 읽을 때 Mengbi에서 나왔습니다). 문서 위의 예는 데모의 예제와 완전히 다르게 보입니다. 종종 문서 위의 예제는 매우 간단하지만 데모 코드는 매우 복잡하므로 처음에는 어떤 코드를 사용할 것인지 몰랐습니다. 나중에, 나는 데모 패키지의 코드를주의 깊게 살펴보고 문서 예제의 인터페이스도 호출되었음을 발견했습니다. 그래야만 나는 그것들이 똑같다는 것을 깨달았지만 데모는 문서의 인터페이스 만 포장했습니다.
먼저 회사의 Alipay 계정을 신청하십시오. 이 계정에는 PID가 있으며이 계정에 응용 프로그램을 추가해야합니다. 각 응용 프로그램에는 appid와 공개 및 개인 키가 있습니다. Alipay가 제공하는 도구를 통해 공개 및 개인 키를 생성 할 수 있습니다. 또한 Java 개발자는 PKCS6 형식으로 개인 키를 사용해야합니다. 응용 프로그램이 스캔 기능을 사용해야하는 경우 응용 프로그램에 직접 지불 옵션을 추가해야하며 계약에 서명해야합니다. 직접 결제 기능에 서명 한 후에는 응용 프로그램을 사용하기 전에 온라인으로 있어야하므로 직접 사용할 수 없습니다. 따라서 개발 중에 응용 프로그램의 샌드 박스 버전을 사용할 수 있습니다. Alipay는 Gateway, Alipay Public Key, PID 및 AppID의 샌드 박스 버전을 구성하는 동안 수정해야합니다.
코드는 데모에서 코드를 직접 사용할 수 있고, 먼저 프로젝트에서 Alipay가 제공 한 API를 가져 오기 (데모 코드가 아님) 그림과 같이 데모 코드를 가져올 수 있습니다.
이 com.alipay.demo.trade.main 파일은 직접 실행할 수 있지만 리소스 파일을 구성해야합니다.
# Alipay Gateway 이름, 파트너 및 Appid# 이것은 샌드 박스 환경을위한 게이트웨이 Open_api_domain = https://openapi.alipaydev.com/gateway.domcloud_api_domain = http://mcloudmonitor.com/gateway.do#이 샌드 albox# 208102172298 샌드 박스 환경에 대한 AppIdAppid는 여기에서 직접 = 2016082000300485 # RSA 개인 키, 공개 키 및 Alipay 공개 키 # 여기에 판매자 개인 키를 여기에 작성하여 PKCS8 Format Private_key로 전송하십시오. miiceqibadanbgkqhkhkig9w0baqecamamwggjfageaoogbamkxzrfr+rnvygbs9qz2ce1mcsibreaqan+5pf5+02hyj4hzcnttwqhfm91ih 3wypyhpm7xlbgj5ywjtgc4g1lz75r8a+ucyuxp8by1lv/44gi/tiflsgatfq73ocm9imxocrdyz2zcwqi1gv+b3udoy/da5w07grwizfzs6vq 1RAGMBAECGYEAQHHC4GRBSRCKEINYTK1VHQCJ0YG11LVY85Z3SI0FNY26DVS8R5GFYDZC/MX5F8RNPUYUHQN+4CQOR3D/C291X1ITOV2NEV LHEJROUDKNP4OQRIQT2W9PZ8RZWZWZP2JCWVRVUF4ZTPEIMPPMORP6SPRFX6DLZG29SFI6GZWU6TKCQCQDP3MIM1BHUS3YONEZGQC69ZN0/DGOFK eix0s18qau1x4i1fejvtky4hpdwihpgyajm0ufg1lk8mtiunhpzrcnakea1qf6u1akjm6zsvdenrxedtccccccccccccccc75uvjgsyfjwhhx9pjyd9vx8nszv 0z0u4v0zg0n0n0yvhj5lro6u5fcqfrw1wixnqjbalmckz8svf/h9n6liwmspy6w5q82knrlrc7wcenspqt0wql5+sacg98m0xxy5j1hmiolhxg ctvyrixowobivqcqcqctnanb4uz3q/86r/kukbvd3dirwlfryaho6yxp8oy+je/bv/359+vr3cxzyyldhzor9/tvspwr/y9q4jlem Q1takealbu7+4edzfap7e/fmgykd5dml8h2iaeumrrcpl84ghffk/7psq/40ngkxptgy44nlelhxcrpw5czu6gqdinjoa ==#제발 Merchant Public_key를 여기에 채우십시오 = MIGFMA0GCSQGSIBDQEBAQUAA4GNADCBIQKKBGQDCL2AXUFQ572IABPAS9NBNZGKIAUXMQMP/UT3+FTNH8O+B83DU01QHXZVDSB98GD8OOTO15W4 ceclibyauinzc ++ a/gvlasrst/g8ts1f+obov0yhy0oae30o9zndpypl6Hexwm9mqskotyffm91a6mvw2ucno4evosxc0ulatawidaqab#this 샌드 박스 환경의 공개 키 ALIPAY_PUBLIC_KEY = MIGFMA0GCSQGSIB3DQEBAQUAAA4GNADCBIQKKBGQDIGHNON7LLILLILKKKFRJ0GQGQGS2Y3MN1WMQMYH9ZEYWLZ5P1ZRAHBXAFCFSQSHSNFQ OMAQZSHRVJCQJSAW1JYQRXAPDKBMR90DIPIXMIYKXV4GGAKPYJ/6FTFY99UHPIQ0QADD/USZQSEFWO0ATVP/65ZI3EOF7TCZ32OWPWIDAQAB# 최대 쿼리 및 쿼리 간격 (밀리 초) max_query_retry = 5Query_duration = 5000# 최대 취소 간격 (MS) 직원의 최대 횟수 max_cancel_retry = 3cancel_duration = 2000# 트랜잭션 보증 스레드 첫 번째 일정 지연 및 스케줄링 (sec
그런 다음 main.java 파일을 실행하십시오. 실제 응용 프로그램의 스캔 코드 결제 코드는 main.java 파일에서 test_trade_precreate () 함수를 직접 복사하고 컨트롤러에서 함수를 만들 수 있습니다.
@requestmapping (value = "/pay/alipay", method = requestmethod.post) public map <string, string> alipay (@requestparam string monet, @requestparam int userid) {map <string, string> map = new Hashmap <String, String> (); // (필수) 가맹점 웹 사이트 주문 시스템의 고유 주문 번호는 64 자만 문자, 숫자 및 밑줄 만 포함 할 수 있습니다. // 판매자 시스템을 반복 할 수 없도록해야합니다. 데이터베이스 시퀀스, String outtradeno = "xxxxx" + system.currenttimeMillis () + (long) (math.random () * 100000000L)을 통해이를 생성하는 것이 좋습니다. // (필수) 주문 제목은 사용자의 지불 목적을 대략적으로 설명합니다. 예를 들어, "xxx brand xxx store는 직접 지불하고 코드를 스캔하여"String subject = "pay"를 소비합니다. // (필수) 주문의 총 금액은 RMB 1 억이며, [할인 된 금액], [할인 된 금액] 및 [총 주문 금액] 및 [총 주문 금액]이 동시에 전송되는 경우 RMB 1 억을 초과 할 수 없습니다. 다음 조건을 충족해야합니다. // (선택 사항) 주문은 할인 된 금액이 될 수 없으며, 할인 활동을 구성하기 위해 판매자 플랫폼으로 구성 할 수 있습니다. 알코올이 할인에 참여하지 않으면 해당 금액 이이 필드에 채워집니다. // 값이 전송되지 않았지만 [총 주문 금액] 및 [할인 된 금액]이 전송되면 값은 [총 주문 금액]-[할인 된 금액] String undiscountableAmount = "0"; // Seller의 Alipay 계정 ID는 계약 계정 (SellerId에 해당하는 Alipay 계정에 지불) //이 필드가 비어 있으면 Apid String SellerId = "2088102172983에 해당하는 PID"; // 순서 설명, 거래 또는 제품을 "총 15.00 위안"문자열 Body = "2 개 구매"3 개 구매 총 20.00 위안에서 3 개 구매 "; // 판매자 운영자 번호,이 매개 변수를 추가하여 판매자 운영자에 대한 판매 통계를 수행하십시오. String Operatorid = "test_operator_id"; // (필수) 상인 상점 번호, 상점 번호 및 판매자 백엔드를 통해 할인 정보를 상점에 정확하게 구성 할 수 있습니다. 자세한 내용은 Alipay Technical Support String Storid = "2088102172329883"; // 비즈니스 확장 매개 변수, 현재 Alipay에서 할당 한 시스템 제공자 번호를 추가 할 수 있습니다 (SetSysServiceProvideRid 메서드를 통해). 자세한 내용은 Alipay Technical Support ExtendParams ExtendParams = New ExtendParams (); ExtendParams.SetSysServiceProviderID ( "2088100200300400500"); // 지불 시간 초과, 120 분 스트링 timeoutexpress = timeout; // // 제품 세부 사항 목록으로 정의되면, 구매 제품의 세부 사항을 작성해야합니다. // 목록 <goodsDetail> goodsDetaillist = new ArrayList <goodsDetail> (); // 제품 정보 생성, 매개 변수는 국가 표준, 이름, Quantity를 사용합니다. 제품 카테고리를 추가 해야하는 경우 goodsDetail // goodsDetail goods1 = goodsDetail.newinstance ( "goods_id001", "xxx small bread", 1000, 1); // // 제품 세부 정보 목록에 추가 // goodsdetaillist.add (goods1); /// // 최초 제품 정보를 추가하십시오. 사용자가 구매 한 제품은 "검은 칫솔"이며 단가는 5.00 위안입니다. 나는 두 조각을 구입했습니다. // 요청 빌더를 지불하기 위해 스캔 코드를 작성하고 요청 매개 변수를 설정합니다. .SetSellerID (sellerId) .SetBody (body) .setOperatorId (OperatorId) .SetStoreId (storeid) .setextendParams (ExtendParams) .settimeoutExpress (timeOutexpress) .setNotifyUrl ( "http://xxx.xx.xxx.xxx.xxx:8080/baobiao/ponify"; 서버는 판매자 서버에 지정된 페이지 HTTP 경로에 적극적으로 알립니다. 필요에 따라 설정하십시오. 여기서 우리는 우리 자신을 쓴 인터페이스를 설정했습니다. 나중에 소개하겠습니다. // .SetGoodSdetaillist (GoodsDetaillist); alipayf2fprecReateResult result = tradeservice.tradeprecreate (builder); switch (result.getTradestatus ()) {case success : log.info ( "Alipay는 성공적으로 선주문 :)); System.out.println ( "Alipay는 성공적으로 선주문 :)); alipaytradeprecrepeateresponse response = result.getResponse (); // dumpresponse (response); // system.out.println (responese.getbody ()); // // // 실행중인 기계의 경로로 수정되어야합니다. response.getouttradeno ()); // log.info ( "filepath :" + filepath); // zxingutils.getQrcodeimge (response.getQrcode (), 256, filepath); // system.out.println (response.getQrcode ()); // 주문을 생성하고 데이터베이스 BaobiaOorder Order = New BaobiaOorder (userId, outtradeno, "", double.parsedouble (금액), new date (), 1); baobiaoorderservice.insertorder (Order); map.put ( "상태", "true"); map.put ( "qrcode", response.getQrcode ()); // 클라이언트 QR 코드 맵으로 돌아갑니다. 리턴 맵; 사례 실패 : log.error ( "Alipay 선주문 실패 !!!"); System.out.println ( "Alipay 선주문 실패 !!!"); System.out.println (result.getResponse (). getBody ()); 부서지다; 알 수없는 경우 : log.error ( "시스템 예외, 선주문 상태 알 수없는 !!!"); System.out.println ( "시스템 예외, 선주문 상태 알 수없는 !!!"); 부서지다; 기본값 : log.error ( "지원되지 않는 트랜잭션 상태, 트랜잭션은 예외를 반환합니다 !!!"); System.out.println ( "지원되지 않는 트랜잭션 상태, 트랜잭션은 예외를 반환합니다 !!!"); 부서지다; } map.put ( "status", "false"); map.put ( "msg", "시스템은 예외가 있습니다. 나중에 다시 시도하십시오!"); 리턴 맵; }논리는 사용자가 자신의 휴대 전화에서 코드를 스캔하여 Alipay를 지불 한 다음 Alipay가 수신 한 후 다음과 같이 Notify_url을 설정하도록 성공적인 지불 메시지를 보냅니다.
@requestmapping (value = "/pay/notify", method = requestmethod.post) public string notifyresult (httpservletrequest request, httpservletResponse 응답) {log.info ( "Alipay Asynchronous Notification!"); map <string, string> params = new Hashmap <String, String> (); // 서명 열거 <string> parameternames = request.getParameterNames ()를 확인하기 위해 모든 매개 변수를 검색합니다. while (parameternames.hasmoreElements ()) {string parametername = parameternames.nextElement (); params.put (parametername, request.getParameter (parametername)); } 부울 대표; try {signverified = alipaysignature.rsacheckv1 (params, configs.getalipaypublickey (), "utf-8"); } catch (alipayApiexception e) {e.printstacktrace (); "실패"를 반환합니다. } if (signverified) {String outtradeno = params.get ( "out_trade_no"); log.info (outtradeno + "주문 콜백 알림"); // system.out.println ( "서명을 성공적으로 확인하십시오!"); log.info ( "서명을 성공적으로 확인하십시오!"); // 매개 변수의 AppID가 채워진 AppID와는 다른 경우 (! configs.getAppid (). equals (params.get ( "app_id")))) {log.warn ( "결제 시점의 AppID와 다르므로 무시해야합니다!"). "실패"를 반환합니다. } // 데이터베이스의 순서 번호에 해당하는 순서를 찾아서 그 금액을 데이터베이스의 금액과 비교하십시오. 일치하지 않으면 Baobiaoorder Order = Baobiaoorderservice.findorderByOutTradeno (OutTradeno)를 제외하고는 알 수 있습니다. if (order == null) {log.warn (outtradeno + "확인 없이이 주문을 확인하십시오!"); "실패"를 반환합니다. } if (order.getAmount ()! = double.parsEdouble (params.get ( "total_amount"))) {log.warn ( "지불 시점의 금액과 다르면 예외 알림이며 무시해야합니다!"); "실패"를 반환합니다. } if (order.getStatus () == baobiaoorder.trade_success) 반환 "성공"; // 주문이 성공적으로 지불 된 경우,이 알림 문자열 상태 = params.get ( "trade_status")을 무시하십시오. if (status.equals ( "wait_buyer_pay")) {// 상태가 사용자 지불을 기다리는 경우 (order.getStatus ()! = baobiaoorder.wait_buyer_pay) baobiaoorderservice.modifytradestatus (baobiorder.wait_buyer_pay, outtradeno); } else if (status.equals ( "trade_closed")) {// 상태가 무급 거래 시간 초과가 닫히거나 지불이 완전히 환불됩니다. (order.getStatus ()! = baobiaoorder.trade_closed) baobiaoorderservice.modifyTradestatus (baobioorder.trade.trade_closed, outtradeno); } else if (status.equals ( "trade_success") || status.equals ( "trade_finished")) {// 상태가 성공적으로 지불 된 경우 (order.getStatus ()! = baobiaoorder.trade_success) baobiaoorderService.ModifyTradestatus (baobiaOor); } else {baobiaoorderservice.modifytradestatus (baobiaoorder.unknown_state, outtradeno); } log.info (OutTradeno + "주문 상태는" + 상태로 수정되었습니다); } else {// 확인 서명이 "실패"를 전달하지 않는 경우; } 반환 "성공"; }아마도 그렇습니다. 그러나 고객에게 성공적인 지불에 대한 알림이 적으며 몇 가지 보안 문제도 있습니다.
마지막 으로이 과정에서 발생하는 문제를 요약하겠습니다.
1. Alipay가 반환 한 QR 코드는 브라우저에서 직접 열 수 없지만 QR 코드를 변환하여 QR 코드를 생성하는 데 사용해야합니다. 그렇지 않으면 Cli.im 웹 사이트를 통해이를 볼 수 있습니다.
2. Alipay 샌드 박스 환경에서 생성 된 QR 코드는 Alipay 휴대 전화의 샌드 박스 버전을 사용하여 스캔 할 수 있습니다. Alipay의 일반 버전이 스캔되면 QR 코드가 만료되고 다른 오류가 발생합니다.
3. 결제 후 Alipay에서 보낸 비동기 통지를받을 수없는 경우 Postman 및 기타 도구를 사용하여 공개 IP를 사용하여 작성한 Notify_URL에 액세스 할 수 있는지 확인할 수 있습니다.
4. ISV 권한이 불충분 한 문제가 발생하면 계약 서명이 없거나 응용 프로그램이 해당 기능을 추가하지 않았으며 온라인 없이는 응용 프로그램을 사용할 수 없습니다. 개발 중에 샌드 박스 응용 프로그램을 선택할 수 있습니다.
5. Alipay 휴대 전화의 샌드 박스 버전을 등록 할 때 고객 서비스에 문의하여 계정을 요청할 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.