java服务端集成支付宝

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33556185/article/details/97642550

在蚂蚁金服开放平台注册了账号并签约支付等需要用到的权限之后,开始集成。

一:设置密钥

在账户中心-密钥管理-开放平台密钥里设置下应用公钥,支付宝会根据我们设置的应用公钥,生成支付宝公钥。

可以使用支付宝提供的:RSA签名验签工具 去生成一对公钥和私钥

工具下载页面,提供了windows版本和mac版本https://docs.open.alipay.com/291/105971/

二:集成SDK

服务端SDK下载地址:https://docs.open.alipay.com/54/106370

 

这里我们使用maven方式集成

引入依赖

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

三:写配置文件

配置文件AlipayConfig.java

public class AlipayConfig {
		
	/**
	 * 支付宝分配给开发者的应用ID
	 * 
	 */
	public static String APP_ID = "appId;
	/**
	 * 商户私钥
	 */
	public static String APP_PRIVATE_KEY="应用私钥";
	/**
	 * 仅支持JSON
	 */
	public static String FORMAT = "JSON";
	/**
	 * 请求使用的编码格式
	 */
	public static String CHARSET = "utf-8";
	/**
	 * 商户生成签名字符串所使用的签名算法类型
	 */
	public static String SIGN_TYPE="RSA2";
	/**
	 * 支付宝公钥
	 */
	public static String ALIPAY_PUBLIC_KEY="支付宝公钥";

	/**
	 * 回调地址
	 */
	public static String CALLBACK_URL = "外网可以访问的不需要参数的接口地址";
}

四:写充值和回调接口

/**
	 * 充值
	 * @param token
	 * @param req
	 * @param resp
	 * @throws AlipayApiException
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/recharge.json")
	@AuthorizationApi
	public void recharge(@CurrentToken Token token,String amount,HttpServletRequest request,HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException{
		AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",AlipayConfig.APP_ID,AlipayConfig.APP_PRIVATE_KEY,AlipayConfig.FORMAT,
		AlipayConfig.CHARSET,AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGN_TYPE);
		if(StringUtil.isBlank(amount)) {
			apiData(request, response, ReqJson.error(BusinessError.AMOUNT_IS_NULL));
			return;
		}
		if(!ToolUtils.isNumeric(amount)) {
			apiData(request, response, ReqJson.error(BusinessError.AMOUNT_IS_ILLEGAL));
			return;
		}else {
			double number=Double.parseDouble(amount);
			if(number<0.01||number>10000) {
				apiData(request, response, ReqJson.error(BusinessError.EXCEEDING_THE_QUOTA));
				return;
			}
		}
		String body="测试充值";
		String subject="钱包充值";
		String tradeNo=generateOrderNo(token.getUserId());
		String goodsType="0";
		String tradeStaue="1";
		String userId=token.getUserId();
		tradeBiz.save(new TradeLog(Double.parseDouble(amount), body, subject, tradeNo, goodsType,tradeStaue,userId,"recharge"));
		//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
		AlipayTradeAppPayRequest aliPayRequest = new AlipayTradeAppPayRequest();
		//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		model.setBody(body);
		model.setSubject(subject);
		model.setOutTradeNo(tradeNo);
		model.setTimeoutExpress("30m");
		model.setTotalAmount(amount);
		model.setProductCode("QUICK_MSECURITY_PAY");
		//公用回传参数,本参数必须进行 UrlEncode 之后才可以发送给支付宝
		String passbackParams="access_token="+token.getAccessToken();
		model.setPassbackParams(URLEncoder.encode(passbackParams,"utf-8"));
		aliPayRequest.setBizModel(model);
		aliPayRequest.setNotifyUrl(basePath+AlipayConfig.CALLBACK_URL);
		String result="";
		try {
			// 这里和普通的接口调用不同,使用的是sdkExecute
			AlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliPayRequest);
			result = aliResponse.getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		apiData(request, response, ReqJson.ok(result));
		return;
	}
 
	/**
	 * 生成订单id
	 * @param userId
	 * @return
	 */
	private String generateOrderNo(String userId) {
		String orderNo="";
		String date=DateUtil.formatDate(new Date(), "yyMMddHHmmss");
		int hashCode=userId.hashCode();
		orderNo=(date+hashCode).replace("-", "");
		return orderNo;
	}
	private static Map<String,Object> getParamMap(String params){
		if(StringUtil.isBlank(params)) {
			return null;
		}
		Map<String,Object> paramMap=new HashMap<>();
		String param[]=null;
		if(params.contains("&")) {
			String paramArray[]=params.split("&");
			for (int i = 0; i < paramArray.length; i++) {
				param=paramArray[i].split("=");
				paramMap.put(param[0], param[1]);
			}
		}else {
			param=params.split("=");
			paramMap.put(param[0], param[1]);
		}		
		return paramMap;
	}
	/**
	 * 支付宝充值结果通知接口
	 * @param request
	 * @param response
	 * @throws AlipayApiException 
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/getAlipayNotify.json")
	public void getAlipayNotify(HttpServletRequest request,HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException {
		logger.info("********进入回调*******"+request.getMethod());
		Map<String, String> params = new HashMap<String, String>();
		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);
		}
		logger.info("********参数map是*******"+params.toString());
		// 切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
		TradeLog temp=null;
		boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET,AlipayConfig.SIGN_TYPE);
		if (flag) {
			String trade_status = params.get("trade_status");
			String out_trade_no = params.get("out_trade_no");
			String trade_no = params.get("trade_no");
			String passback_params = URLDecoder.decode(params.get("passback_params"), "utf-8");
			Map<String, Object> map = getParamMap(passback_params);
		    //省略业务代码
			if ("TRADE_SUCCESS".equals(trade_status) && temp.getTradeState().equals("1")) { // 交易支付成功的执行相关业务逻辑
			
			} else if ("TRADE_CLOSED".equals(trade_status)) { // 未付款交易超时关闭,或支付完成后全额退款,执行相关业务逻辑
			
			}
		} else {
			logger.info("********签名不正确*******");
		}
		apiData(request, response, ReqJson.ok(null));
		return;
	}

到此服务端集成支付宝就算大功告成了。

若是验签不通过,重点检查公钥私钥。用支付宝提供的工具,复制进去商户公钥和商户私钥,不匹配,则重新生成一对,并更新进配置。然后将更新后的支付宝公钥更改到配置文件里。

若商户公钥和私钥是匹配的,那再比对开放平台里的支付宝公钥和代码里的支付宝公钥是否一致。

 

展开阅读全文

没有更多推荐了,返回首页