springboot+vue+도 킹 알 리 페 이 인터페이스+QR 코드 스 캔 결제 기능(샌 드 박스 환경)

1.알 리 페 이 인터페이스(샌 드 박스 환경)는 무엇 입 니까?
기록 시간:2020 년 10 월 15 일 3:55
현재 휴대 전화 결 제 는 상당히 보편적 이 며 개발 자로 서 휴대 전화 결제 조작 에 대해 알 아야 한다.한편,알 리 페 이 인 터 페 이 스 는 알 리 페 이 가 제공 하 는 인터페이스 로 소프트웨어 응용 프로그램 을 연결 하여 돈 거래 를 하 는 데 사용 된다.그리고 프로 그래 밍 애호가 들 에 게 이 점 을 배우 기 란 좀 어렵다.알 리 페 이 인 터 페 이 스 를 사용 하려 면 반드시 소프트웨어 응용 프로그램 을 사용 해 야 하기 때문이다.소프트웨어 응용 프로그램 은 알 리 페 이에 신청 하고 일련의 자 료 를 제출 해 야 한 다 는 점 은 실현 할 수 없다.이 는 개발 자 에 게 어느 정도 어려움 을 주 었 습 니 다.제품 이 출시 되 지 않 았 기 때문에 알 리 페 이 인 터 페 이 스 를 연결 해 야 하 는 것 이 큰 문제 입 니 다.그래서 샌 드 박스 환경 이 발생 했 고 가상 사용자 와 관리자 계 정 을 가지 고 도 킹 에 성 공 했 는 지 테스트 합 니 다.다음은 제 경험 에 따라 제 사용 과 학습 과정 을 간단하게 소개 하 겠 습 니 다.
기술+프로 그래 밍 소프트웨어 사용:
springboot(idea)vue+elementui(HBuilderX)+vue-qr(vue QR 코드 프레임 워 크 생 성)NATAPP(외부 네트워크 연결,알 리 페 이 리 셋 실현)websocket(전단 응답 실현)
단계:
샌 드 박스 환경 준비 JAVA+springboot 에서 SDK 연결 알 리 페 이 인터페이스 설정 전단 사용 vue+elementui 페이지 디자인 주의 점 결과 테스트
먼저 응용 프로그램 을 만 듭 니 다.여 기 는 샌 드 박스 환경 입 니 다.먼저 샌 드 박스 환경 을 준비 합 니 다.
바 이 두 검색**알 리 페 이 개미 금 복**,결제 팩 계 정 에 로그 인하 면 다음 과 같이 표 시 됩 니 다.
在这里插入图片描述
애플 리 케 이 션 을 만 드 는 곳 입 니 다.즉,프로젝트 가 출시 될 때 여기 서 신청 하 는 것 입 니 다.샌 드 박스 환경 을 사용 하면 왼쪽 상단 오픈 플랫폼 을 클릭 하고 아래로 당기 면 샌 드 박스 라 는 글자 가 나 옵 니 다.클릭 하여 들 어가 면 됩 니 다.
在这里插入图片描述
그리고 알 리 페 이 홈 페이지 에 소 개 된 샌 드 박스 환경의 사용 을 볼 수 있 습 니 다.사실 홈 페이지 에 소 개 된 것 은 매우 상세 합 니 다.만약 에 친구 들 이 보기 가 귀 찮 으 면 제 가 배 운 절차 에 따라 참고 할 수 있 습 니 다.샌 드 박스 환경 에서 샌 드 박스 응용 링크 를 클릭 하여 자신의 샌 드 박스 환경 을 설정 합 니 다.
在这里插入图片描述
i 기 호 를 누 르 면 위 에 알림 링크 가 있 습 니 다.RSA 2 키 를 어떻게 만 드 는 지 자세히 소개 하지 않 겠 습 니 다.홈 페이지 에 잘 쓰 여 있 습 니 다.저 는 이렇게 멍청 한 사람 도 배 울 수 있 고 친구 들 도 배 울 수 있 을 거 라 고 믿 습 니 다.절차 에 따라 두 개의 파일 을 생 성 합 니 다.공개 키 와 비밀 키 를 사용 합 니 다.알 리 페 이 공개 키 가 아니 라 공개 키 를 사용 한 다 는 것 을 기억 하 세 요.이 학습 과정 에서 인증서 모드 를 사용 하지 않 았 습 니 다.
在这里插入图片描述
그리고 RSA 2 의 설정/보 기 를 클릭 합 니 다.생 성 된 응용 키 를 복사 하면 됩 니 다.다음은 알 리 페 이 공개 키 를 생 성 합 니 다.후속 연결 과정 에서 매우 중요 합 니 다.알 리 페 이 공개 키 를 사용 하 는 지,공개 키 를 사용 하 는 지 구분 해 야 합 니 다.
在这里插入图片描述
JAVA+springboot 에서 SDK 로 알 리 페 이 인터페이스 설정 연결
在这里插入图片描述  
여 기 는 홈 페이지 에서 SDK 를 사용 하 는 방법 입 니 다.여 기 는 구형 방식 을 사용 합 니 다.새로운 방식 은 제 가 사용 하 는 과정 에서 어떤 문제 가 발생 하면 해결 되 지 않 습 니 다.
사용 하기 전에 몇 개의 설정 을 봉인 하고 첫 번 째 는 알 리 페 이 를 연결 하 는 설정 입 니 다.

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 *         
 */
@Configuration
public class PayConfig {
 //      AppId,  :2019091767145019(  )
 private static final String appID = "2016102500758313";
 //    ,           (  )
 private static final String privateKey = "";
 //     ,      (  )
 public static final String publicKey = "";
	//    (  )
 public static final String charset = "utf-8";
	//    (  )
 public static final String signType = "RSA2";
 @Bean
 public AlipayClient alipayClient(){
 	//      https://openapi.alipaydev.com/gateway.do,      https://openapi.alipay.com/gateway.do
  return new DefaultAlipayClient("https://openapi.alipaydev.com/gateway.do", appID, privateKey, "json", charset, publicKey, signType);
 }
	/**
	 *   ,    
	 */
 public static boolean checkSign(HttpServletRequest request){
  Map<String, String[]> requestMap = request.getParameterMap();
  Map<String, String> paramsMap = new HashMap<>();
  requestMap.forEach((key, values) -> {
   String strs = "";
   for(String value : values) {
    strs = strs + value;
   }
   System.out.println(key +"===>"+strs);
   paramsMap.put(key, strs);
  });
  System.out.println();
  //  SDK    
  try {
   return AlipaySignature.rsaCheckV1(paramsMap, PayConfig.publicKey, PayConfig.charset, PayConfig.signType);
  } catch (AlipayApiException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   System.out.println("*********************    ********************");
   return false;
  }

 }
}
그 다음 에 알 리 페 이 리 턴 의 매개 변수 대상 을 봉 인 했 습 니 다.여 기 는 수 동 으로 파 라 메 터 를 얻 을 필요 가 없습니다.

import java.io.Serializable;

/**
 *        
 */
public class AliReturnPayBean implements Serializable {
 /**
  *
  */
 private static final long serialVersionUID = 1L;

 /**
  *     app_id
  */
 private String app_id;

 /**
  *      
  */
 private String out_trade_no;

 /**
  *   
  */
 private String sign;

 /**
  *     
  */
 private String trade_status;

 /**
  *       
  */
 private String trade_no;

 /**
  *      
  */
 private String total_amount;

 public String getTotal_amount() {
  return total_amount;
 }

 public void setTotal_amount(String total_amount) {
  this.total_amount = total_amount;
 }

 public String getApp_id() {
  return app_id;
 }

 public void setApp_id(String app_id) {
  this.app_id = app_id;
 }

 public String getOut_trade_no() {
  return out_trade_no;
 }

 public void setOut_trade_no(String out_trade_no) {
  this.out_trade_no = out_trade_no;
 }

 public String getSign() {
  return sign;
 }

 public void setSign(String sign) {
  this.sign = sign;
 }

 public String getTrade_status() {
  return trade_status;
 }

 public void setTrade_status(String trade_status) {
  this.trade_status = trade_status;
 }

 public String getTrade_no() {
  return trade_no;
 }

 public void setTrade_no(String trade_no) {
  this.trade_no = trade_no;
 }

 @Override
 public String toString() {
  return "AliReturnPayBean [app_id=" + app_id + ", out_trade_no=" + out_trade_no + ", sign=" + sign
    + ", trade_status=" + trade_status + ", trade_no=" + trade_no + "]";
 }
}
그리고 제어 층 을 써 서 알 리 페 이 를 연결 해 야 합 니 다.제어 층 은@Controller 수식 이 아니 라@RestController 수식 이 어야 합 니 다.알 리 페 이의 리 셋 함수 에서 요청 을 되 돌려 주기 때 문 입 니 다.구체 적 인 사례 는 다음 과 같다.
전제:pom.xml 에서 SDK 의존 도 를 가 져 옵 니 다.

<dependency>
 <groupId>com.alipay.sdk</groupId>
 <artifactId>alipay-sdk-java</artifactId>
 <version>4.10.145.ALL</version>
</dependency>

package com.example.zhifubaozhifu.controller;


import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.example.zhifubaozhifu.config.PayConfig;
import com.example.zhifubaozhifu.util.AliReturnPayBean;
import com.example.zhifubaozhifu.util.Shop;
import com.example.zhifubaozhifu.util.WebSocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;

@Controller
@Slf4j
public class Test {
 @Autowired
 private AlipayClient alipayClient;
 @Autowired
 private WebSocket webSocket;


 @RequestMapping("/createQR")
 @ResponseBody
 public String send() throws AlipayApiException {
  AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); //  API   request 
  //       notifyUrl    
  request.setNotifyUrl("http://cv95x3.natappfree.cc/call");
  //      
//  request.setReturnUrl("");
  request.setBizContent(" {" +
				" \"primary_industry_name\":\"IT  /IT     \"," +
				" \"primary_industry_code\":\"10001/20102\"," +
				" \"secondary_industry_code\":\"10001/20102\"," +
				" \"secondary_industry_name\":\"IT  /IT     \"" +
				" }");;
  AlipayTradePrecreateResponse response = alipayClient.execute(request);
  String path = "zhifu.jpg";
  if (response.isSuccess()) {
   System.out.println("    ");
   return response.getQrCode();
  } else {
   System.out.println("    ");
  }
  return "";
 }


 /**
  *        
  * @param request
  * @param response
  * @param returnPay
  * @throws IOException
  */
 @RequestMapping("/call")
 public void call(HttpServletRequest request, HttpServletResponse response, AliReturnPayBean returnPay) throws IOException {
  response.setContentType("type=text/html;charset=UTF-8");
  log.info("            ");
  if (!PayConfig.checkSign(request)) {
   log.info("    ");
   response.getWriter().write("failture");
   return;
  }
  if (returnPay == null) {
   log.info("    returnPay    ");
   response.getWriter().write("success");
   return;
  }
  log.info("    returnPay" + returnPay.toString());
  //            
  if (returnPay.getTrade_status().equals("TRADE_SUCCESS")) {
   log.info("         TRADE_SUCCESS");
   //       ,webSocket         
   webSocket.sendMessage("true");
  }
  response.getWriter().write("success");
 }
}
전단 사용 vue+elementui 페이지 디자인:
vue 프로젝트 의 구축 은 여기 서 소개 하지 않 습 니 다.먼저 환경 을 준비 하고 vue-qr 플러그 인 을 추가 합 니 다.

npm install vue-qr --save
전단 코드:

<template>
	<div>
		<!--     ,       -->
		<van-button type="primary" @click="pay">  </van-button>

		<el-dialog :title="paySucc?'    ':'    '" :visible.sync="dialogVisible" width="16%" center>
			<!--         -->
			<vueQr :text="text" :size="200" v-if="!paySucc"></vueQr>
			<!--   websocket      ,              -->
			<span class="iconfont icon-success" style="position: relative;font-size: 100px;color:#42B983;margin-left: 50px;top:-10px;" v-else></span>
		</el-dialog>

	</div>
</template>

<script>
	import vueQr from 'vue-qr'
	export default {
		data() {
			return {
				dialogVisible: false,
				text: "",
				paySucc: false
			}
		},
		components: {
			vueQr
		},
		methods: {
			pay() {
				let _this = this;
				_this.paySucc = false;
				_this.dialogVisible = true;
				this.axios.request("http://localhost:8081/createQR")
					.then((response) => {
						_this.text = response.data;
						_this.dialogVisible = true;
						//  webSocket    ,       websocket  
						if ("WebSocket" in window) {
							//      web socket
							var ws = new WebSocket("ws://localhost:8081/bindingRecord");

							ws.onopen = function() {
								// Web Socket     ,   send()       
								// ws.send("data");
								// alert("     ...");
							};

							ws.onmessage = function(evt) {
								var received_msg = evt.data;
								// alert("     ..." + evt.data);
								if (Boolean(evt.data)) {
									_this.paySucc = true;
									setTimeout(() => {
										_this.dialogVisible = false;
									}, 3 * 1000);
								}
								ws.close();

							};
							
							ws.onclose = function() {
								// //    websocket
								console.log("     ...");
							};
						} else {
							//        WebSocket
							alert("         WebSocket!");
						}
					}).catch((err) => {
						console.log(err)
					})
			},
			back(dataUrl, id) {
				console.log(dataUrl, id)
			}
		}
	}
</script>

<style>
	.btn {
		margin-left: 100px;
	}
</style>
이렇게 하면 앞 뒤 엔 드 코드 가 준비 되 었 고 위의 코드 중 두 가지 주의해 야 할 것 이 있 습 니 다.첫 번 째 문 제 는 notifyUrl 이 사용 하 는 url 은 외부 네트워크 주소 이 며 IP 주소 가 아 닙 니 다.그렇지 않 으 면 되 돌 릴 수 없습니다.하지만 학습 환경 에 서 는 외부 인터넷 주 소 를 사용 할 수 없다.이것 은**NATAPP**를 사용 해 야 합 니 다.바 이 두 는 NATAPp 홈 페이지 를 검색 하고 눌 러 서 다운로드 합 니 다.이것 은 natapp.exe 응용 프로그램 입 니 다.이것 이 있 습 니 다.홈 페이지 에 계 정 을 등록 하고 클릭 하여 무료 터널(무료 터널 은 두 개 만 구 매 할 수 있 으 니 아 껴 야 합 니 다.터널 프로 토 콜 은 웹 을 쓰 고 다른 것 은 로 컬 환경 설정 을 누 르 면 됩 니 다).구 매 하 시 면 다음 터널 이 있 습 니 다.
在这里插入图片描述
natapp.exe 를 더 블 클릭 하여 콘 솔 에 들 어가 다음 명령 을 입력 하고 터널 을 엽 니 다.

#         authtoken  
natapp --authtoken= 
다음은 다음 과 같 습 니 다.
在这里插入图片描述
이곳 의 외부 네트워크 연결 주 소 는 바로 notifyUrl 의 주소 입 니 다.그리고 방법 mapping 경 로 를 추가 하면 됩 니 다.예 를 들 어 제 것 은:http://cv95x3.natappfree.cc/call
두 번 째 문 제 는 결제 가 성공 한 후에 리 셋 함수 가 실 행 했 습 니 다.전단 에 제 가 결 제 했 음 을 어떻게 알려 주 는 지,그리고 QR 코드 단 추 를 닫 는 지,여 기 는 websocket 을 사 용 했 습 니 다.여 기 는 websocket 이 무엇 인지 상세 하 게 소개 하지 않 습 니 다.조금 만 알 면 백 엔 드 에서 메 시 지 를 보 내 는 지 확인 할 수 있 습 니 다.우선 pom.xml 에서 의존 도 를 가 져 옵 니 다:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-websocket</artifactId>
 <version>2.3.4.RELEASE</version>
</dependency>
그리고 웹 config 설정 클래스 를 만 듭 니 다:

package com.example.zhifubaozhifu.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @desc: WebSocket  
 *
 **/
//  webSocket   URL
@ServerEndpoint("/bindingRecord")
@Component
@Slf4j
public class WebSocket {

 private Session session;
 private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();

 /**
  *   webSocket   
  * @return
  */
 @Bean
 public ServerEndpointExporter serverEndpointExporter() {
  return new ServerEndpointExporter();
 }
 /**
  *     
  * @param session
  */
 @OnOpen
 public void onOpen(Session session) {
  this.session = session;
  webSockets.add(this);
  log.info("【    】,    :{}", webSockets.size());
 }

 /**
  *     
  */
 @OnClose
 public void onClose(){
  webSockets.remove(this);
  log.info("【    】,    :{}", webSockets.size());
 }

 /**
  *      
  * @param message
  */
 @OnMessage
 public void onMessage(String message){
  log.info("【  】,      :{},    :{}", message, webSockets.size());
 }

 /**
  *     
  * @param message
  */
 public void sendMessage(String message){
  log.info("【    】,  :{},    :{}", message, webSockets.size());
  for (WebSocket webSocket : webSockets) {
   try {
    webSocket.session.getBasicRemote().sendText(message);
   } catch (IOException e) {
    log.info("【    】,    :{}", e.fillInStackTrace());
   }
  }
 }

}
그리고 사용 할 때 방법 인 onMessage 를 호출 하면 메 시 지 를 받 을 수 있 고 onMessage 를 사용 하면 메 시 지 를 널리 보 낼 수 있 습 니 다.
전단 사용 절차:

<script type="text/javascript">
 function WebSocketTest()
 {
  if ("WebSocket" in window)
  {
   alert("        WebSocket!");
   
   //      web socket
   var ws = new WebSocket("ws://localhost:9998/echo");
   
   ws.onopen = function()
   {
   // Web Socket     ,   send()       
   ws.send("    ");
   alert("     ...");
   };
   
   ws.onmessage = function (evt) 
   { 
   var received_msg = evt.data;
   alert("     ...");
   };
   
   ws.onclose = function()
   { 
   //    websocket
   alert("     ..."); 
   };
  }
  
  else
  {
   //        WebSocket
   alert("         WebSocket!");
  }
 }
</script>
자세히 알 고 싶 으 면초보 강좌가서 공부 하 세 요.
사용 방향:전단 에 웹 소켓 을 만 들 고 백 엔 드 웹 소켓 에 연결 해 야 웹 소켓 채널 을 연결 할 수 있 습 니 다.결제 가 성공 한 후에 백 엔 드 는 전단 에 결제 성공 정 보 를 피드백 하고 전단 모니터링 이 메 시 지 를 받 은 후에 처리 합 니 다.즉,QR 코드 대화 상 자 를 닫 습 니 다.
테스트 결과:
在这里插入图片描述
그 다음 에 알 리 페 이 샌 드 박스 버 전 핸드폰 을 다운로드 하면 모 의 결 제 를 스 캔 할 수 있 습 니 다.개미 금 복 의 샌 드 박스 환경 에서 QR 코드 를 다운로드 할 수 있 습 니 다.다음 과 같은 그림 입 니 다.
加粗样式
리 셋 처리 에 지불 하 는 작업 을 기록 한 다음 에 그 위 에 진일보 한 포장 을 할 수 있다 는 것 을 말한다.
끝났어,기록 끝났어.
종료 시간:2020 년 10 월 15 일 6:12
springboot+vue+도 킹 알 리 페 이 인터페이스+QR 코드 스 캔 결제(샌 드 박스 환경)에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 springboot 도 킹 알 리 페 이 결제 인터페이스 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 지원 바 랍 니 다!

좋은 웹페이지 즐겨찾기