APP接入支付宝支付之服务端实现

最近公司接了一个外包项目,开发过程中用到了调用微信和支付宝的第三方支付接口,因为之前没用集成过,所以这次用到了之后就想总结一下分享给大家,这里只介绍支付宝的APP支付和提现接口的服务端接入实现。 

首先,要接入第三方的接口,最重要的还是先看官方文档,因为不管你从哪里搜索到的文章都是基于官方的文档API说明和使用方法。以前我刚做开发的时间遇到新的东西就喜欢百度找现成其他博主写的教程然后拷过来改。后来发现如果官方API变动或者更新了的话那还是要根据说明官方API文档来的(因为我以前就遇到过这样的坑!)。

先去 https://docs.open.alipay.com/204看一下大概的产品介绍和整个调用流程,这个也是蛮重要的。因为支付宝APP支付接口的调用是服务端和客户端一起联合完成的。

接入过程中IOS那边遇到了点小问题,就是由于没仔细看说明文档,他一开始把服务器端生成订单信息的事情也做了,后来我跟他又对了一下他才恍然大悟,客户端那边其实只要拿到服务端传过来的orderString再唤起支付宝就ok了。

第一步:企业商户先在支付宝开放平台创建应用,然后上传商户公钥,之后会生成一个支付宝公钥。关于公私钥的生成和上传请移步官方文档:https://docs.open.alipay.com/291/105972

第二步:项目集成支付宝SDK

在pom.xml里添加依赖:

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

第三步:封装一个配置信息类

public class AlipayConfig {
	
	/**
	 * 正式环境请求地址
	 */
	 public static String ALIPAY_URL = "https://openapi.alipay.com/gateway.do";
    /**
      * 支付宝分配给开发者的应用ID
      * 
     */
    public static String APP_ID = "APP_ID";
	
    /**
      * 支付接口名称
     */
    public static String PAY_METHOD = "alipay.trade.app.pay";
    /**
      * 提现接口名称
     */
    public static String TRANSFER_METHOD = "alipay.fund.trans.toaccount.transfer";
    /**
     * 仅支持JSON
     */
    public static String FORMAT = "JSON";
    /**
      * 请求使用的编码格式
     */
    public static String CHARSET = "utf-8";
    /**
      * 商户生成签名字符串所使用的签名算法类型
     */
    public static String SIGN_TYPE = "RSA2";
    /**
      * 支付宝公钥
     */
   public static String ALIPAY_PUBLIC_KEY = "ALIPAY_PUBLIC_KEY";
    /**
      * 商户私钥
     */
    public static String PRIVATE_KEY = "PRIVATE_KEY";
   
    /**
     * 回调地址
    */
   public static String CALLBACK_URL = "https://xxx.com/xxx/xx";
}

注意:服务器端需要的公钥是支付宝公钥而不是商户公钥。服务器端用商户私钥加密后将数据传过去。支付宝那边会根据appid找到你上传的公钥进行解密。解密成功会生成订单信息响应给我们的服务器,然后项目集成的支付宝SDK会根据你配置的支付宝公钥进行验签,没抛出异常就说明验签成功然后你就可以把orderString传给客户端。

第四步:开始写调用的代码咯

// 实例化客户端
	AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.ALIPAY_URL, AlipayConfig.APP_ID,
			AlipayConfig.PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
		AlipayConfig.SIGN_TYPE);
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
	AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
// SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
	AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
	model.setBody("用户充值");
	model.setSubject("XX平台APP");
	model.setOutTradeNo("自己系统内的订单编号");// outtradeno 生存订单
	model.setTimeoutExpress("60m");
	model.setTotalAmount("支付金额");
	model.setProductCode("QUICK_MSECURITY_PAY");
	request.setBizModel(model);
	request.setNotifyUrl(AlipayConfig.CALLBACK_URL);//异步回调url
		
// 这里和普通的接口调用不同,使用的是sdkExecute
	AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
// System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。

第五步:编写异步回调接口将支付宝那边返回的数据进行分析然后根据返回码判断支付成功还是失败等编写自己项目的剩下业务逻辑,这个我就不写了。

/**
	 * @author:Jack
	 * @function:支付宝充值结果通知接口
	 * @date 2018年9月17日
	 */
	@RequestMapping(value = "/getAlipayNotify", produces = "application/json;charset=UTF-8", method = {
			RequestMethod.GET, RequestMethod.POST })
	public void getAlipayNotify(HttpServletRequest request) {
		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);
		}
		// 切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
		try {
			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");
			if ("TRADE_SUCCESS".equals(trade_status)) { // 交易支付成功的执行相关业务逻辑

				} else if ("TRADE_CLOSED".equals(trade_status)) { // 未付款交易超时关闭,或支付完成后全额退款,执行相关业务逻辑
					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

猜你喜欢

转载自blog.csdn.net/King__Jack/article/details/83037535
今日推荐