Springboot写服务端App集成第三方支付宝支付(二次修改)

1.省略以下过程

1.1、在支付宝开发者平台创建app应用并获取APPID
1.2、配置密钥
1.3、下载服务端SDK
下载服务端SDK
参数说明

2.application.yml文件的配置如下(只需要这些就够了)

#支付宝支付配置
#APPID 商户appid 
#RSA_PRIVATE_KEY 私钥 pkcs8格式的
#notify_url 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
#return_url 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
#URL 请求网关地址
#CHARSET 编码
#FORMAT 返回格式
#ALIPAY_PUBLIC_KEY 支付宝公钥
#SIGNTYPE RSA2


alipayconfig:
   appid: 2011111296241128
   rsa_private_key: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCYfefhdTCK9uyJGOM3JYlI5PyDgbvTwSB84uGALP6ICJv5bT2+huzdLnImpudoAQVdGS5H3c0NcoWSlQlvFedaRNGEt5O+WfMcP0oLfVhKPmUMNsGOLCNLUnRjQfhRLqdr5kmY+AUBZlATtbNBK59Ye6KJ0uMp9X/AWyXa2GMR9Le+C9SYQ8vqk7ddIBPi0zYKWZPMI2JSvXsh2fB889EAFsO+Y9n7+G1yOC1K8p/JUwPu6gT6tXSlBoIypUrs/fZeyp4OmOU+bq2alZyg3c2T2oQIWYkwMt8WUliI4pRn/wMhga3wbbHWNRdGl4fptbWRcTLjQ0M5LmsJF67DlKd/AgMBAAE11111111111111111114N2xAxGOG6TeyKuyzBWWWCxFftFEt65q0YuDvoUrAotog9iyz5gXuHR/S5CHhJMHIC8FyKZI91iYFg+uWaAZlceCpFn7RDJKureEpE+mj3ryRICxvIcoiIZLEv8BJZ+1oQXbQK4pIPfkejEGQeHXAIBYcWJJL4geNDs/vCRynBbjXGHjOxL0XUw9QjrLcxcnEOyDs6ZLuulkemo0phOoW2YrbVoO7JQSLaqKut3YW8RMk1fhuC8lV4QKBgQDfvnqvD9hqEA+25Mao3MSyNMiwD4gA7zqOltEQaMnMxsGbEby6d0nmZet3m3YwFs6pAs2JDQrOa/j4sayMc1p16YCtGz+WFuGHAME+JHNNrAuSdNcpR+SyR5eq6OZFMfeUegN/8M2LRW8Kzp/gBy46i+o48ln/BsWN52OybpVjHQKBgQCuecjCIbtDCOC8YSFVIDBPFHTt/ZbhCJbd/JwiKvIFHVPDOrCr+A4CWsIFhxfO/qEtRMMnFxC+n5B9afIvYspxfbxnEDz4/w47ZAIUT8jo+b01x83jl/8wDDs+n1fuL8Acf8OAaoHTZlV3NtFxmPN9O8MhEtis8AMOQioTZaK2SwKBgEzGN6LKdSAv0rSXW/OljXj408RWD/0CGb3D0okm69fwe46ST4hMVndQkbPBDJUDvnYQGCbm6sZaFlx/2w12p5u+PAEqUG9X+pswjx6bs1T7rBzdKtdna/ogxtJGiH1F4AZ6t6i3IFChyrCSphlhXWOJjx1rS6ZO1IsU0wjvGSOhAoGAUuOao9fgnh02n2hJrKZpLPicAICsUGaDPh0HlBfw+MsRAzv7uQdUqHuzl2qxve4sZlQ3nnePxfAKdfqCS07UvIwumIwXW3fYrBB8CGhLG5uh703oG4sXeh0lfD+5R3g5/ZAZMgXnfaYtTkClyiEO9F0S+8B3Xdl8qiZ21NZBMfcCgYBktqNuymf5zstIqHfSThhzZTbiFbHRRMMY4vYcjU90eDi0FA/jg7jkXuAkZ0PZRnlHiaVKbmJeSYBSeYLWSfEK82ABILTu4YSvXj/EC5g6FrblNKqukKE7a5bVrGXiZEznTVMocz9G5Rxrjt5sjRVUyfyRN800mM/vnHYYs1NI9A==
   notify_url: http://域名:端口/api/alinotifyUrl
   return_url: http://域名:端口/alipay/returnUrl
   url: https://openapi.alipay.com/gateway.do
   charset: UTF-8
   format: JSON
   alipay_public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv9I0K84RWWoJm26xHNPBGDHBPxxkjwaHgMNPNqjVXfD36n57yuLRAu8207Dar+Nu04bktrKJ6XgKBXMZ9Wgbxvc4YtBqFAkvxY9nTdSAolwZgR0/75hR2IrkAPwdv31aOI6v5sMXD91Ksts9tDYZqYobIHWAJ/gxwG11uoSA3mx0BXWXev222222KCG8buFpFM11M1Im2SiocuKY28E66blZw6tqQ71Il3I9lk8kB2rwnBrfx3gVHDbm15OCfNzSTB6TvjfVo+Q0RyQIgTly7cpZY5QFEgINTDq25EqKghzS+v09ytRDOyWDiLKnrzqFe8g0fwUIFqxz4kw4DNhRYQHQIDAQAB
   signtype: RSA2

3.支付宝支付配置文件

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 支付宝支付配置文件
 * @author Administrator
 *
 */
@Component
@ConfigurationProperties(prefix="alipayconfig")
public class AlipayProperties {

	private String appid; // 商户appid
	
	private String rsa_private_key; // 私钥 pkcs8格式的
	
	private String notify_url; // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	
	private String return_url; // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
	
	private String url; // 请求网关地址
	
	private String charset; // 编码
	
	private String format; // 返回格式
	
	private String alipay_public_key; // 支付宝公钥
	
	private String signtype;  // RSA2  签名方式

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	public String getRsa_private_key() {
		return rsa_private_key;
	}

	public void setRsa_private_key(String rsa_private_key) {
		this.rsa_private_key = rsa_private_key;
	}

	public String getNotify_url() {
		return notify_url;
	}

	public void setNotify_url(String notify_url) {
		this.notify_url = notify_url;
	}

	public String getReturn_url() {
		return return_url;
	}

	public void setReturn_url(String return_url) {
		this.return_url = return_url;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getCharset() {
		return charset;
	}

	public void setCharset(String charset) {
		this.charset = charset;
	}

	public String getFormat() {
		return format;
	}

	public void setFormat(String format) {
		this.format = format;
	}

	public String getAlipay_public_key() {
		return alipay_public_key;
	}

	public void setAlipay_public_key(String alipay_public_key) {
		this.alipay_public_key = alipay_public_key;
	}

	public String getSigntype() {
		return signtype;
	}

	public void setSigntype(String signtype) {
		this.signtype = signtype;
	}

	@Override
	public String toString() {
		return "AlipayProperties [appid=" + appid + ", rsa_private_key=" + rsa_private_key + ", notify_url="
				+ notify_url + ", return_url=" + return_url + ", url=" + url + ", charset=" + charset + ", format="
				+ format + ", alipay_public_key=" + alipay_public_key + ", signtype=" + signtype + "]";
	}
}

4.maven添加jar依赖


    alipay-sdk-java
    alipay
    3.0.1


        com.alibaba
        fastjson
        1.2.38
 

这里是将支付宝java sdk jar包转成maven本地仓库的jar包
具体操作步骤请看我另外一篇文章
转成maven到本地仓库的jar包

5.工具类

可以去下载我上传的资源
我项目的使用的工具类

package io.renren.common.utils;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回数据
 * 
 * @author chenshun
 * @email [email protected]
 * @date 2016年10月27日 下午9:59:27
 */
public class R extends HashMap {
	private static final long serialVersionUID = 1L;
	
	public R() {
		put("code", 0);
		put("msg", "success");
	}
	
	public static R error() {
		return error(500, "未知异常,请联系管理员");
	}
	
	public static R error(String msg) {
		return error(500, msg);
	}
	
	public static R error(int code, String msg) {
		R r = new R();
		r.put("code", code);
		r.put("msg", msg);
		return r;
	}

	public static R ok(String msg) {
		R r = new R();
		r.put("msg", msg);
		return r;
	}
	
	public static R ok(Map map) {
		R r = new R();
		r.putAll(map);
		return r;
	}
	
	public static R ok() {
		return new R();
	}

	@Override
	public R put(String key, Object value) {
		super.put(key, value);
		return this;
	}
}

	
	/**
	 * 字符串转日期对象
	 * @param str
	 * @param format
	 * @return
	 * @throws Exception
	 */
	public static Date formatString(String str,String format) throws Exception{
		if(StringUtil.isEmpty(str)){
			return null;
		}
		SimpleDateFormat sdf=new SimpleDateFormat(format);
		return sdf.parse(str);
	}
	
	/**
	 * 生成当前日期时间串
	 * @return
	 * @throws Exception
	 */
	public static String getCurrentDateStr(){
		Date date=new Date();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmssSSS");
		return sdf.format(date);
	}
	/**
	 * 生成当前日期时间串
	 * @param args
	 * @throws Exception
	 */
	public static String getCurrentDateString() {
		Date d = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
		String s = sdf.format(d);
		return s;
	}
	public static void main(String[] args) throws Exception {
		System.out.println(getCurrentDateString());
	}
	
}


package io.renren.common.utils;

import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期处理
 * 
 * @author chenshun
 * @email [email protected]
 * @date 2016年12月21日 下午12:53:33
 */
public class DateUtils {
	/** 时间格式(yyyy-MM-dd) */
	public final static String DATE_PATTERN = "yyyy-MM-dd";
	/** 时间格式(yyyy-MM-dd HH:mm:ss) */
	public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式化 日期格式为:yyyy-MM-dd
     * @param date  日期
     * @return  返回yyyy-MM-dd格式日期
     */
	public static String format(Date date) {
        return format(date, DATE_PATTERN);
    }

    /**
     * 日期格式化 日期格式为:yyyy-MM-dd
     * @param date  日期
     * @param pattern  格式,如:DateUtils.DATE_TIME_PATTERN
     * @return  返回yyyy-MM-dd格式日期
     */
    public static String format(Date date, String pattern) {
        if(date != null){
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            return df.format(date);
        }
        return null;
    }

    /**
     * 字符串转换成日期
     * @param strDate 日期字符串
     * @param pattern 日期的格式,如:DateUtils.DATE_TIME_PATTERN
     */
    public static Date stringToDate(String strDate, String pattern) {
        if (StringUtils.isBlank(strDate)){
            return null;
        }

        DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);
        return fmt.parseLocalDateTime(strDate).toDate();
    }

    /**
     * 根据周数,获取开始日期、结束日期
     * @param week  周期  0本周,-1上周,-2上上周,1下周,2下下周
     * @return  返回date[0]开始日期、date[1]结束日期
     */
    public static Date[] getWeekStartAndEnd(int week) {
        DateTime dateTime = new DateTime();
        LocalDate date = new LocalDate(dateTime.plusWeeks(week));

        date = date.dayOfWeek().withMinimumValue();
        Date beginDate = date.toDate();
        Date endDate = date.plusDays(6).toDate();
        return new Date[]{beginDate, endDate};
    }

    /**
     * 对日期的【秒】进行加/减
     *
     * @param date 日期
     * @param seconds 秒数,负数为减
     * @return 加/减几秒后的日期
     */
    public static Date addDateSeconds(Date date, int seconds) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusSeconds(seconds).toDate();
    }

    /**
     * 对日期的【分钟】进行加/减
     *
     * @param date 日期
     * @param minutes 分钟数,负数为减
     * @return 加/减几分钟后的日期
     */
    public static Date addDateMinutes(Date date, int minutes) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMinutes(minutes).toDate();
    }

    /**
     * 对日期的【小时】进行加/减
     *
     * @param date 日期
     * @param hours 小时数,负数为减
     * @return 加/减几小时后的日期
     */
    public static Date addDateHours(Date date, int hours) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusHours(hours).toDate();
    }

    /**
     * 对日期的【天】进行加/减
     *
     * @param date 日期
     * @param days 天数,负数为减
     * @return 加/减几天后的日期
     */
    public static Date addDateDays(Date date, int days) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusDays(days).toDate();
    }

    /**
     * 对日期的【周】进行加/减
     *
     * @param date 日期
     * @param weeks 周数,负数为减
     * @return 加/减几周后的日期
     */
    public static Date addDateWeeks(Date date, int weeks) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusWeeks(weeks).toDate();
    }

    /**
     * 对日期的【月】进行加/减
     *
     * @param date 日期
     * @param months 月数,负数为减
     * @return 加/减几月后的日期
     */
    public static Date addDateMonths(Date date, int months) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusMonths(months).toDate();
    }

    /**
     * 对日期的【年】进行加/减
     *
     * @param date 日期
     * @param years 年数,负数为减
     * @return 加/减几年后的日期
     */
    public static Date addDateYears(Date date, int years) {
        DateTime dateTime = new DateTime(date);
        return dateTime.plusYears(years).toDate();
    }
    /**
     * 将日期转换成十进制数字
     * @param expireDate
     * @return
     */
    public static int getSecondsFromDate(String expireDate) {
		if (expireDate == null || expireDate.trim().equals(""))
			return 0;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
		Date date = null;
		try {
			date = sdf.parse(expireDate);
			return  (int)(date.getTime()/1000);
		} catch (ParseException e) {
			e.printStackTrace();
			return 0;
		}
	}
   
}

5.请求支付宝支付

/**
	 * 支付请求
	 * 
	 * @param alipayTradeWapPayModel
	 * @param response
	 * @throws IOException
	 * @throws ServletException
	 */
	@RequestMapping("/alipay")
	public R pay(TpOrder order, HttpServletRequest request, HttpServletResponse response)
			throws ServletException, Exception {
		// 获取订单号
		String orderNo = order.getOrderSn();
		// 订单总价
		BigDecimal totalAmount = order.getTotalAmount();
		double price = totalAmount.doubleValue();
		System.out.println("price:" + price);
		String form = ""; // 生成支付表单
		// 封装请求客户端 // 实例化客户端
		AlipayClient client = new DefaultAlipayClient(alipayProperties.getUrl(), alipayProperties.getAppid(),
				alipayProperties.getRsa_private_key(), alipayProperties.getFormat(), alipayProperties.getCharset(),
				alipayProperties.getAlipay_public_key(), alipayProperties.getSigntype());

		// 支付请求
		// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
		AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
		// SDK已经封装掉了公共参数,这里只需要传入业务参数。
		// 以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradePayModel model = new AlipayTradePayModel();
		// 描述信息 添加附加数据
		model.setProductCode("QUICK_MSECURITY_PAY"); // 设置销售产品码
		model.setOutTradeNo(orderNo); // 设置订单号
		model.setSubject("--龙英app订单支付--"); // 订单名称
		model.setTotalAmount("" + price + ""); // 支付总金额
		model.setBody("body"); // 设置商品描述
		model.setTimeoutExpress("30m"); // 超时关闭该订单时间
		// model.setSellerId("[email protected]"); // 商家id
		alipayRequest.setBizModel(model);
		// 异步回调地址
		alipayRequest.setNotifyUrl(alipayProperties.getNotify_url());
		/* AlipayTradeAppPayResponse responses = */
		AlipayTradeAppPayResponse responses = client.sdkExecute(alipayRequest);
		form = responses.getBody();// 生成支付表单
		System.out.println(form); // 就是orderString 可以直接给客户端请求,无需再做处理
		return R.ok().put("form", form);
	}

5.支付宝服务器异步通知

这个是提供给支付宝调用的接口 在*.yml文件中需要把这个接口完整路径配置上去
接口里面主要写你的业务逻辑代码
支付宝会多次请求这个接口 所以你需要在支付宝第一次成功请求完成后返回给支付宝请求成功的标识 )

/**
 * 支付宝服务器异步通知
 * 
 * @param request
 * @return
 */
@RequestMapping("/alinotifyUrl")
//@Transactional(isolation = Isolation.SERIALIZABLE)
public void notifyUrl(HttpServletRequest request,HttpServletResponse response) throws Exception {
	String result ="";
	BigDecimal platfor = null;
	System.out.println("11111111111111111111111111111111");
	logger.info("notifyUrl");
	// 获取支付宝GET过来反馈信息
	Map params = new HashMap();
	Map requestParams = request.getParameterMap();
	for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
		String name = (String) iter.next();
		String[] values = (String[]) requestParams.get(name);
		String valueStr = "";
		for (int i = 0; i < values.length; i++) {
			valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
		}
		/* valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); */

		params.put(name, valueStr);
		System.out.println("name:" + name + ",valueStr:" + valueStr);
	}

	boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayProperties.getAlipay_public_key(),
			alipayProperties.getCharset(), alipayProperties.getSigntype()); // 调用SDK验证签名

	// 商户订单号
	String out_trade_no = request.getParameter("out_trade_no");
	// 交易状态
	String trade_status = request.getParameter("trade_status");
	String trade_no = request.getParameter("trade_no");// 交易流水号
	if (signVerified) { // 验证成功 更新订单信息
		if (trade_status.equals("TRADE_FINISHED")) {
			logger.info("TRADE_FINISHED");
		}
		if (trade_status.equals("TRADE_SUCCESS")) {
			if (StringUtil.isNotEmpty(out_trade_no)) {
		             //业务逻辑处理
				//返回给支付宝的 说明接口处理成功 不然会一天24小时调用你接口
						result="success";
					}
					
				}
			}
			logger.info("TRADE_SUCCESS");
		}
		
	} else {
	//返回给支付宝的 说明接口处理失败 会就行调接口
		result="fail";
		//下面代码放在业务处理之后,不然业务代码不会执行
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());  
		out.write(result.getBytes());  
		out.flush();  
	    out.close();
	}
	//下面代码放在业务处理之后,不然业务代码不会执行
	BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());  
	out.write(result.getBytes());  
	out.flush();  
    out.close();
}

调支付宝支付还是比较简单的 微信就比较“构思”了,他的接口文档写的稀巴烂看得伤脑筋
下一篇文章 springboot写服务端App集成第三方微信支付

你可能感兴趣的:(springboot,第三方支付)