支付宝PC二维码支付(Java开发)全部流程沙箱环境

最近在做一个小的购物网站,需要支付宝在线支付,这个博客就是总结一下方便记忆,在线支付的坑对我这种的小白来说坑还是挺多的。步骤如下:

一、准备:

1、先去 支付宝开发者中心 注册个人号或者商户号
2、接下来的步骤可按照东北溜达滑的博客(转载):沙箱环境设置链接
3、测试需要用内网穿透软件,我用的是natapp,可以搜一下natapp使用教程安装,这个是测试必须要安装的。
4、pom.xml添加依赖:


<dependency>
    <groupId>com.alipay.sdkgroupId>
    <artifactId>alipay-sdk-javaartifactId>
    <version>3.1.0version>
dependency>
二、代码:

我的是沙箱环境,正式环境与沙箱环境的支付宝网关是不一样的,需要注意。

1、AlipayConfig.java:这个添加的时候要看清用的是哪个。

public class AlipayConfig {
    //支付宝商户号的APPID
    public static String APPID = "";
 
    //用支付宝密钥生成工具生成的私钥
    public static String RSA_PRIVATE_KEY = "";
 
    //电脑网站支付结果异步通知,可以参考异步文档,一定要是外网能访问的
    public static String notify_url = "http://74hr52.natappfree.cc/venus/notifyUrl.do"; 
 
    //电脑网站支付结果同步通知,用于转跳到用户自己的页面,一定要是外网能访问的
    public static String return_url = "http://74hr52.natappfree.cc/venus/returnUrl.do"; 
 
    //沙箱接口,正式上线时请改用正式支付接口
    public static String URL = "https://openapi.alipaydev.com/gateway.do"; 
 
    //固定的参数
    public static String CHARSET = "UTF-8";
 
    //固定的参数
    public static String FORMAT = "json";
 
    //用支付宝密钥生成工具生成的公钥
    public static String ALIPAY_PUBLIC_KEY = "";
 
    //固定的参数
    public static String log_path = "C:\\";
 
    //固定的参数
    public static String SIGNTYPE = "RSA2";
 
    public AlipayConfig() {
    }
}

2、AlipayService.java

public interface AlipayService {
	
	public String toAlipay(Map<String, String> sourceMap) throws IOException;
}

3、AlipayServiceImpl.java

@Service
public class AlipayServiceImpl implements AlipayService {

	@Override
    public String toAlipay(Map<String, String> sourceMap) throws IOException {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID,AlipayConfig.RSA_PRIVATE_KEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        AlipayTradeWapPayModel alipayTradeWapPayModel = new AlipayTradeWapPayModel();
        alipayTradeWapPayModel.setOutTradeNo(sourceMap.get("out_trade_no"));
        alipayTradeWapPayModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        alipayTradeWapPayModel.setTotalAmount(sourceMap.get("total_amount"));
        alipayTradeWapPayModel.setSubject("Alipay");
        alipayTradeWapPayModel.setBody(sourceMap.get("body"));
        alipayRequest.setBizModel(alipayTradeWapPayModel);
        String form="";
        try {
            form = alipayClient.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return form;
    }
}

4、AlipayController.java

@Controller
public class AlipayController {
 
    @Autowired
    public AlipayService alipayService;
 
 
    @RequestMapping("pay.do")
    public void toAlipay(HttpServletRequest httpRequest , HttpServletResponse httpResponse, String payId, String totalFee, String body) throws IOException {
 
        //生成一笔支付记录,支付完成时将支付状态改为成功
 
        Map<String, String> sourceMap = new HashMap<>();
        sourceMap.put("out_trade_no",payId);
        sourceMap.put("total_amount",totalFee);
        sourceMap.put("body",getUTF8XMLString(body));
 
 
        String form = alipayService.toAlipay(sourceMap);
        httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        httpResponse.getWriter().write(form);
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
 
 
    //注意异步返回结果通知是以post请求形式返回的
    @RequestMapping("notifyUrl.do")
    public String notify_url(HttpServletRequest request) throws UnsupportedEncodingException{
    	request.setCharacterEncoding("utf-8");
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        String out_trade_no= paramsMap.get("out_trade_no");
        String trade_status= paramsMap.get("trade_status");
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
            //无论同步异步都要验证签名
            if(signVerified){
                if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){
                    //处理自己系统的业务逻辑,如:将支付记录状态改为成功,需要返回一个字符串success告知支付宝服务器
                    
                    return "success";
                } else {
                    //支付失败不处理业务逻辑
                    return "failure";
                }
            }else {
               //签名验证失败不处理业务逻辑
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return "failure";
        }
    }
 
    //注意同步返回结果是以get请求形式返回的
    @RequestMapping("returnUrl.do")
    public String return_url(HttpServletRequest request) throws UnsupportedEncodingException{
    	request.setCharacterEncoding("utf-8");
        Map<String, String> paramsMap = convertRequestParamsToMap(request);
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
            if(signVerified){
                //跳转支付成功界面
                return "success";
 
            }else {
                //跳转支付失败界面
                return "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "success";
    }
 
 
    //将请求中的参数转换为Map
    public static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap();
        Set<Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
        Iterator var3 = entrySet.iterator();
 
        while(true) {
            while(var3.hasNext()) {
                Entry<String, String[]> entry = (Entry)var3.next();
                String name = (String)entry.getKey();
                String[] values = (String[])entry.getValue();
                int valLen = values.length;
                if(valLen == 1) {
                    retMap.put(name, values[0]);
                } else if(valLen <= 1) {
                    retMap.put(name, "");
                } else {
                    StringBuilder sb = new StringBuilder();
                    String[] var9 = values;
                    int var10 = values.length;
 
                    for(int var11 = 0; var11 < var10; ++var11) {
                        String val = var9[var11];
                        sb.append(",").append(val);
                    }
 
                    retMap.put(name, sb.toString().substring(1));
                }
            }
 
            return retMap;
        }
    }
 
    //将字符串转换为UTF-8编码以防出现乱码错误
    public static String getUTF8XMLString(String xml) {
        StringBuffer sb = new StringBuffer();
        sb.append(xml);
        String xmString = "";
        String xmlUTF8="";
        try {
            xmString = new String(sb.toString().getBytes("UTF-8"));
            xmlUTF8 = URLEncoder.encode(xmString, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return xmlUTF8;
    }
}
三、测试:

buy.jsp:

<%@ page isELIgnored="false"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
	pageContext.setAttribute("path",request.getContextPath());
%>

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title heretitle>
	head>
	<body>
		<div class="form-container">
		    <form id="form" action="${path }/pay.do" method="post" >
		        
		           *订单号 :
		           <input type="text" name="payId" value="23719246981264"><br>
		           *付款金额 :
		           <input type="text" name="totalFee" value="0.02" ><br>
		           *商品描述 :
		           <input type="text" name="body" value="移动的0.02元"><br>
		           <input type="submit" value="支付宝支付" >
		    form>
		div>
	body>
html>

结果如下:
支付宝PC二维码支付(Java开发)全部流程沙箱环境_第1张图片
点击支付:
支付宝PC二维码支付(Java开发)全部流程沙箱环境_第2张图片
付款成功后到成功界面success.jsp:
支付宝PC二维码支付(Java开发)全部流程沙箱环境_第3张图片
至此完成!!!

四、注意:

1、不能用127.0.0.1测试,需要用内网穿透软件给的ip地址。
2、如下图:支付宝PC二维码支付(Java开发)全部流程沙箱环境_第4张图片

你可能感兴趣的:(SSM)