手机APP如何接入支付宝支付(java后台)

可以看到有一个(网页&移动应用的),进入开放平台创建一个这样的应用就可以了

如果你是首次会看到一个让你填写信息加入平台的页面。

创建完应用后你将得到以下页面:

也可以给你创建的应用增加能力,比如APP支付能力,获取会员信息等等。需要注意的是有些功能是需要签约的。如下图所示:

2、接入支付sdk,服务端jar包

<dependency>
  <groupid>com.alipay.sdk</groupid>
  <artifactid>alipay-sdk-java</artifactid>
  <version>4.3.0.ALL</version>
</dependency>

3、下单处理代码

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("购买["+placeOrderForm.getProductName()+"]");
model.setSubject("购买xxx["+placeOrderForm.getProductName()+"]");
model.setOutTradeNo(order.getUuid());
model.setTotalAmount(String.valueOf(order.getTotalOrderPrice()));
try {
	String orderString = alipaySao.createALipayTrade(model);
	Map<string,object> resultMap = ImmutableMap.of("orderString",orderString,"orderNo",order.getUuid());
	//更新订单为支付中
	this.updatePayStatus(order.getUuid(),PayStatusEnum.PAYING.getCode(),"");
	return ResponseVo.buildSuccessResponse(resultMap);
} catch (AlipayApiException e) {
	log.error("AlipayApiException e={}",e);
	return ResponseVo.buildResponse(ResponseEnum.ALIPAY_ERROR);
}

4、与支付宝进行通信

初始化:
// 实例化客户端
alipayClient = new DefaultAlipayClient(
        AlipayConfig.ALIPAY_URL,
        AlipayConfig.APP_ID,
        AlipayConfig.PRIVATE_KEY,
        AlipayConfig.FORMAT,
        AlipayConfig.CHARSET,
        AlipayConfig.ALIPAY_PUBLIC_KEY,
        AlipayConfig.SIGN_TYPE);

/**
 * 支付客户端
 * @throws AlipayApiException
 * @return
 */
@Override
public String createALipayTrade(AlipayTradeAppPayModel model) throws AlipayApiException {
    // 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
    AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
    // SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
    model.setTimeoutExpress("60m");
    model.setProductCode("QUICK_MSECURITY_PAY");
    request.setBizModel(model);
    request.setNotifyUrl(AlipayConfig.CALLBACK_URL);
    //异步回调url
    // 这里和普通的接口调用不同,使用的是sdkExecute
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
    log.info("apliay.response.body={}",response.getBody());
    //就是orderString 可以直接给客户端请求,无需再做处理。
    return response.getBody();
}

5、支付宝相关配置(实际应用建议使用配置项管理)

package com.fast.tpp.dto;

public class AlipayConfig {

        /**
         * 签约的支付宝账号对应的支付宝唯一用户号,以2088开头的16位纯数字组成
         */
        public static final String PID = "xx";

        /**
         * 正式环境请求地址
         */
        public static String ALIPAY_URL = "https://openapi.alipay.com/gateway.do";

        /**
         * 支付宝分配给开发者的应用ID
         *
         */
        public static String APP_ID = "xxx";

        /**
         * 仅支持JSON
         */
        public static String FORMAT = "JSON";

        /**
         * 请求使用的编码格式
         */
        public static String CHARSET = "utf-8";

        /**
         * 商户生成签名字符串所使用的签名算法类型
         */
        public static String SIGN_TYPE = "RSA2";

        /**
         * 支付宝公钥
         */
        public static String ALIPAY_PUBLIC_KEY =xxx;
        /**
         * 商户私钥
         */
        public static String PRIVATE_KEY =XXX";

        /**
         * 回调地址
         */
        public static String CALLBACK_URL = "xxx";
}

6、支付状态设置

package com.fast.common.enums;

/**
 * 支付状态
 */
public enum PayStatusEnum {


	NOT_PAY(0,"未支付"),

	PAYING(1, "支付中"),

	SUCCESS(2,"支付成功"),

	FAILUE(3, "支付失败"),

    ;

	private int code;
	private String value;

	PayStatusEnum(int code, String value){
		this.code = code;
		this.value = value;
	}
	
	// 获取对应的文本
	public static String getName(int code) {
		for (PayStatusEnum c : PayStatusEnum.values()) {
		  if (c.getCode() == code) {
		     return c.value;
		  }
		}
		return null;
	}
	
	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}
}

7、回调通知接口

/**
	 * 支付宝支付通知
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value="/alipayNotice.do",method = RequestMethod.POST)
	@ResponseBody
	@NoneAuth
	@SysLog(actionName = "支付宝支付通知")
	public String alipayNotice(HttpServletRequest request, HttpServletResponse response) throws IOException {
		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 &lt; values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
			}

			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 tradeStatus = params.get("trade_status");
				String outTradeNo = params.get("out_trade_no");
				String tradeNo = params.get("trade_no");
				//购买者用户ID
				String openId = params.get("buyer_logon_id");
				this.orderService.alipayNotice(tradeStatus,outTradeNo,tradeNo,openId);
				if ("TRADE_SUCCESS".equals(tradeStatus)){
					return "success";
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "fail";
	}
	
	
	对应的service方法为:
	/**
	 * 支付宝支付通知
	 * @param tradeStatus
	 * @param outTradeNo
	 * @param tradeNo
	 * @param openId
	 */
	public void alipayNotice(String tradeStatus, String outTradeNo, String tradeNo, String openId){
		log.info("alipayNotice outTradeNo={} tradeStatus={}",outTradeNo,tradeNo);
		String orderNo = outTradeNo;
		if ("TRADE_SUCCESS".equals(tradeStatus)) {
			// 交易支付成功的执行相关业务逻辑
			Order order = this.getOrderByOrderNo(orderNo);
			if(null==order){
				return;
			}
			//只有在未支付成功的状态下才可以发短信和更新生效时间
			if (order.getPayStatus()!=PayStatusEnum.SUCCESS.getCode()){
				this.orderMapper.updatePrepayId(tradeNo,orderNo);
				//处理支付成功逻辑
				handlePaySuccess(order,openId);
			}
		} else if ("TRADE_CLOSED".equals(tradeStatus)) {
			// 未付款交易超时关闭,或支付完成后全额退款,执行相关业务逻辑
            //失败 更改订单状态为支付失败
			this.updatePayStatus(outTradeNo,PayStatusEnum.FAILUE.getCode(),openId);
		}
	}
	
```</string,></string,></string,object>