java实现支付宝支付(电脑网站端支付,手机端网站支付)

1.前言

最近有在弄支付宝和微信的支付,现在我们来弄下支付宝的支付

首先注册蚂蚁金服开放平台账号这个就不多说了(个人用的是支付宝账号)

配置好沙箱环境(一般来说沙箱环境跑通,到时候换上线上应用的配置就可以了)

详细过程:https://openclub.alipay.com/read.php?tid=1513&fid=28

2.准备

下载相关的jar(sdk)

https://alipay.open.taobao.com/doc2/detail?treeId=54&articleId=103419&docType=1

maven导包

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

3.配置类

public class AlipayConfig {
	//网关地址
    //public static final String URL = "https://openapi.alipay.com/gateway.do"; //(正式环境)
    public static final String URL = "https://openapi.alipaydev.com/gateway.do"; //沙箱(测试环境)
    
    //APPID
    public static final String ALIPAY_APPID = ""; 
    //私钥
    public static String APP_PRIVATE_KEY = "";
    //支付宝公钥
    public static String ALIPAY_PUBLIC_KEY = "";
    
    //签名算法类型(根据生成私钥的算法,RSA2或RSA)
    public static final String SIGNTYPE = "RSA2";
    
    public static final String FORMAT = "json";//请求数据格式
    public static final String CHARSET = "utf-8";//编码集
    
    // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    public static final String OWnotify_url = "";//网站扫码
    // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
    public static final String OWreturn_url = "";//网站扫码
    
    // 统一收单交易创建接口
    private static AlipayClient alipayClient = null;
 
    /**获得初始化的AlipayClient
     * @return 支付宝客户端
     */
    public static AlipayClient getAlipayClient() {
        if (alipayClient == null) {
            synchronized (AlipayConfig.class) {
                if (null == alipayClient) {
                    alipayClient = new DefaultAlipayClient(URL, ALIPAY_APPID, APP_PRIVATE_KEY, FORMAT, CHARSET,ALIPAY_PUBLIC_KEY,SIGNTYPE);
                }
            }
        }
        return alipayClient;
    }
}

4.支付宝电脑网站支付

4.1方法一:(返回的是from表单)

     // 扫码支付
    @ResponseBody
    @RequestMapping(value = "/pagePay")
    public static String pagePay() {
            int money = 100 ;//充值金额
            //逻辑
            long timeStart = Calendar.getInstance().getTimeInMillis();
            String out_trade_no = timeStart+"";// 订单号
            // 获得初始化的AlipayClient
            AlipayClient alipayClient = AlipayConfig.getAlipayClient(); 
            // 创建API对应的request
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
            alipayRequest.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("out_trade_no", out_trade_no );// 订单号
            map.put("product_code", "FAST_INSTANT_TRADE_PAY");// 销售产品码
            map.put("total_amount", money);// 交易金额,单位:元
            map.put("subject", "电子门票");// 订单标题
            alipayRequest.setBizContent(JSON.toJSONString(map));
            try {
                // 调用SDK生成表单
                String form = alipayClient.pageExecute(alipayRequest).getBody();
                // 就是orderString可以直接给客户端请求,无需再做处理。
                System.out.println("---------支付宝扫码---------> " + form);
                return form;
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
    }

4.2 方法二: 返回的二维码地址

可以前端生成二维码也可后端生成二维码传输前端,这里我就只生成二维码地址.

public static String alipay() throws AlipayApiException{
        AlipayClient alipayClient = AlipayConfig.getAlipayClient();
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
        Map<String,Object> map=new HashMap<String,Object>();
        //设置回调地址
        request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
        request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
        //根据订单号查询订单信息
        Map<String,Object> maps=new HashMap<String,Object>();
        long timeStart = Calendar.getInstance().getTimeInMillis();
        String out_trade_no =  timeStart ;
        maps.put("out_trade_no",out_trade_no);
        maps.put("total_amount","0.01");
        maps.put("subject",tpWxPay.getBody());
        maps.put("timeout_express","5m");
        //把订单信息转换为json对象的字符串
        String postdata = JSONObject.fromObject(maps).toString();
        request.setBizContent(postdata);
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        String body = response.getBody();
        JSONObject jsonObject = JSONObject.fromObject(body);
        String qr_code = jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
        map.put("qr_code", qr_code);
        return qr_code;
    }

5. 手机网站支付

返回一样的是from表单,这样前端直接掉起支付宝

/**
    * 封装好参数,前台通过form表单来调起支付宝
	 * @throws AlipayApiException 
	 * @throws IOException 
    */
	@RequestMapping("/getContext1")
   public String alipayPayChongRequest(WxPayDto tpWxPay) throws AlipayApiException{
	   AlipayClient alipayClient = AlipayConfig.getAlipayClient();
       //创建API对应的request类(主要是这里变化了)
	   AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
       request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
       request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
       AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
       long timeStart = Calendar.getInstance().getTimeInMillis();
       model.setOutTradeNo(timeStart +"");
       model.setSubject("测试商品");
       model.setTotalAmount("0.01");
       model.setBody("测试商品");
       model.setTimeoutExpress("30m");
       model.setProductCode("QUICK_WAP_PAY");
       request.setBizModel(model);
	   String form = alipayClient.pageExecute(request).getBody(); //调用SDK生成表单
	   System.out.println(form);
	   return form;
   }

6. 回调

支付异步回调(支付成功后,支付宝会调用这个接口)

    @RequestMapping(value = "/OWnotify", method = RequestMethod.POST)
    public void OWnotify(HttpServletRequest request, HttpServletResponse httpResponse) {
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        Set<String> keySet = requestParams.keySet();
        String out_trade_no = "";
        String trade_status = "";
        String total_amount = "";
        for (String key : keySet) {
            StringBuffer buffer = new StringBuffer();
            for (String string : requestParams.get(key)) {
                buffer.append(string);
            }
            params.put(key, buffer.toString());
            if (key.equals("out_trade_no")) {
                out_trade_no = buffer.toString();// 商户订单号
                System.out.println(key + " : " + buffer.toString());
            } else if (key.equals("trade_status")) {
                trade_status = buffer.toString();// 交易状态
                System.out.println(key + " : " + buffer.toString());
            } else if (key.equals("total_amount")) {
                total_amount = buffer.toString().substring(0,buffer.toString().length()-3) + "";// 充值金额
                System.out.println(key + " : " + total_amount);
            }
        }
        System.out.println("支付异步回调");
        try {
            // 计算得出通知验证结果
            boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY,
                    AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
            if (verify_result) {// 验证成功
                if (trade_status.equals("TRADE_SUCCESS")) { // 交易支付成功
                    //逻辑
                	httpResponse.getWriter().println("success");
                }
            } else {// 验证失败
                httpResponse.getWriter().println("fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

有异步当然就有同步啦(同步接口一般用于跳转网页,执行部分逻辑)

注意: 返回的是from表单的才会主动调用(当然需要在配置类中配置啦)

使用request.getParameter能够获取到值或者用实体类

@RequestMapping("/OWreturn")
	public ModelAndView OWreturn(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView();
		System.out.println("支付同步回调");
		mav.setViewName("");
    	return mav;
	}

from表单发到前端,前端ajax请求成功后用$('#payFrom').html(from); 就会执行该from表单

好了!大概就是这样吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章