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依赖

<dependency>
    <groupId>alipay-sdk-java</groupId>
    <artifactId>alipay</artifactId>
    <version>3.0.1</version>
</dependency>
<dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.38</version>
 </dependency>

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

5.工具类

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

package io.renren.common.utils;

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

/**
 * 返回数据
 * 
 * @author chenshun
 * @email sunlightcs@gmail.com
 * @date 2016年10月27日 下午9:59:27
 */
public class R extends HashMap<String, Object> {
	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<String, Object> 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 sunlightcs@gmail.com
 * @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("416032133@qq.com"); // 商家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<String, String> params = new HashMap<String, String>();
	Map<String, String[]> requestParams = request.getParameterMap();
	for (Iterator<String> 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集成第三方微信支付

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
APP客户使用第三方支付服务时,以下是数据流向的过程: 首先,APP客户打开应用并选择使用第三方支付服务完成支付操作。客户端向服务端发送请求,包含支付金额和相关订单信息。 接下来,服务端将请求转发给第三方支付服务提供商的服务器。同时,客户端与第三方支付服务提供商的服务器建立安全连接,以确保数据传输的安全性。 第三方支付服务提供商的服务器接收到请求后,会对该请求进行验证和处理。首先,它会验证请求的合法性,包括订单是否存在、金额是否正确等。然后,它会使用可信的支付网关与付款渠道进行交互,将支付请求传递给付款渠道。 付款渠道收到支付请求后,会进行一系列的安全验证和支付处理。这包括验证支付账户的有效性、检查付款渠道的可用性等。一旦付款成功,付款渠道会将支付结果返回给第三方支付服务提供商的服务器。 第三方支付服务提供商的服务器接收到付款渠道返回的支付结果后,会对支付结果进行处理和验证。如果支付成功,它将通知服务端支付成功,并将支付相关信息返回给服务端服务端接收到支付成功的通知后,会更新订单状态并向客户端返回支付成功的消息。 同时,支付结果和相关支付信息还会被第三方支付服务提供商记录和存储。这可以用于后续的支付查询、退款处理等业务。 总结而言,APP客户调用第三方支付的数据流向包括客户端向服务端发送支付请求,服务端转发请求至第三方支付服务提供商的服务器,第三方支付服务提供商与付款渠道进行交互完成支付操作,并将支付结果返回给服务端,最终服务端向客户端返回支付结果。同时,支付相关数据也会被第三方支付服务提供商记录和存储。这个过程中,数据的传输和安全性非常重要,必须确保支付信息的保密性和完整性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值