java实现支付宝App支付功能

maven依赖

支付宝支付SDK依赖

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

前端代码示例

前端采用的是mui.js

	mui.init();
		var urltemp = "";//请支付宝充值接口
		var wxChannel = null; // 微信支付
		var aliChannel = null; // 支付宝支付  
		$(function() {
			mui.plusReady(function() {
				//获取支付通道
				plus.payment.getChannels(function(channels) {
					for (var i in channels) {
						if (channels[i].id == "wxpay") {
							wxChannel = channels[i];
						} else {
							aliChannel = channels[i];
						}
					}
				}, function(e) {
					alert("获取支付通道失败:" + e.message);
				});

	//点击充值按钮
	document.getElementById("rechargeBtn").addEventListener('tap', function() {
					mui.ajax({
						url: urltemp,
						data: dataInfo,//请求参数,按下面支付宝充值接口参数要求传入即可
						async: false, // 异步 || 同步
						dataType: 'json',
						type: 'post',
						timeout: 5000,
						success: function(data) {
							//表示调用支付宝支付接口成功
							if (data.status == 0) {
								var data = data.data;//数据为支付宝充值接口返回的response.getBody()
								plus.payment.request(aliChannel , data, function(result) {
									plus.nativeUI.alert("充值成功!", function() {
										var list = plus.webview.currentWebview().opener();
										//触发父页面的自定义事件(refresh),从而进行刷新
										mui.fire(list, 'refresh');
										mui.back();
									});
								}, function(error) {
									console.log("[" + error.code + "]:" + error.message);
									plus.nativeUI.alert("充值失败:已取消支付");
								});
							} else if (data.status == 1000) {
								plus.nativeUI.toast(data.msg);
							}
						},
						error: function(xhr, type, errorThrown) {
						}
					});
				});
			});
		})

请求接口

支付宝充值接口

 @ApiOperation(httpMethod = "POST", value = "支付宝充值", produces = MediaType.APPLICATION_JSON_VALUE, notes = "充值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "广告主token", required = true, paramType = "query"),
            @ApiImplicitParam(name = "advertUserId", value = "广告主id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "payAmount", value = "付款金额", required = true, paramType = "query"),
            @ApiImplicitParam(name = "giveAmount", value = "赠送金额", required = true, paramType = "query"),
    })
    @ApiResponses({@ApiResponse(code = 0, message = "OK"), @ApiResponse(code = 1, message = "ERROR"),})
    @RequestMapping(value = "/zfbPayRecharge")
    public HoneyResult zfbPayRecharge(String token, String advertUserId, double payAmount, double giveAmount) {
        String tokenKey = "token" + advertUserId;
        if (token == null || !token.equals(jedisClient.get(tokenKey))) {
            return HoneyResult.build(StatusCode.CODE_NOTLOGIN, "请先登录");
        }
        if (advertUserId == null || "".equals(advertUserId)) {
            return HoneyResult.build(StatusCode.CODE_NOLL_ERROR, "请求参数存在空值");
        }
        if (payAmount / 1000 < 0.1) {
            return HoneyResult.build(StatusCode.CODE_ERROR, "充值金额不得低于0.1元");
        }
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET_UTF8, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

        String orderId = UUIDUtils.getCurrentDateStr();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(String.format("ZFB_%s_%.2f_%.2f", advertUserId, payAmount / 1000, giveAmount / 1000));//交易描述
        model.setSubject("订单编号  " + orderId);//商品的标题/交易标题/订单标题/订单关键字等。
        model.setOutTradeNo(orderId);//商户网站唯一订单号
        model.setTimeoutExpress("30m");//该笔订单允许的最晚付款时间,逾期将关闭交易。

        model.setTotalAmount(String.format("%.2f", payAmount / 1000.00));//支付宝支付单位为元
        model.setProductCode("QUICK_MSECURITY_PAY");//销售产品码,商家和支付宝签约的产品码
        request.setBizModel(model);
        request.setNotifyUrl(AlipayConfig.notify_url);//支付宝回调地址

        try {
            // 这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            logger.info("AlipayTradeAppPayResponse return :" + response.getBody());// -

            if (response.isSuccess()) {
                return HoneyResult.build(StatusCode.CODE_SUCCESS, "获取支付宝支付参数成功", response.getBody());
            } else {
                return HoneyResult.build(StatusCode.CODE_ERROR, "调用失败");
            }
        } catch (AlipayApiException e) {
            return HoneyResult.build(StatusCode.CODE_ERROR, "调用失败");
        }
    }

支付宝回调地址接口

 @ApiOperation(httpMethod = "GET", value = "支付宝充值回调", produces = MediaType.APPLICATION_JSON_VALUE, notes = "充值回调")
    @RequestMapping(value = "/zfbNotify")
    public String zfbNotify(HttpServletRequest request) throws Exception {
        //获取支付宝POST过来反馈信息
        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] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
        String trade_body = new String(request.getParameter("body").getBytes("ISO-8859-1"), "UTF-8");
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET_UTF8, AlipayConfig.SIGNTYPE);
        String returnParam = "fail";
        if (verify_result) {//验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                returnParam = "success";
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //付款用户编号
                String advertUserId = trade_body.split("_")[1];
                //支付金额
                double payAmount = Double.valueOf(trade_body.split("_")[2]);
                //赠送金额
                double giveAmount = Double.valueOf(trade_body.split("_")[3]);
                //充值记录插入
                honeyRecharGerecordService.saveRechargerecord(advertUserId, payAmount, giveAmount, "0", trade_no);
                returnParam = "success";
            }
        } else {//验证失败
            logger.error("支付宝签名验证失败");
            returnParam = "fail";
        }
        return returnParam;
    }

}

工具类

1.错误状态码工具类

package com.zhhong.honey.common;

public class StatusCode {
    public static int CODE_SUCCESS = 0;          //成功返回
    public static int CODE_ERROR = 1000;         //通用返回
}

2.通用返回值工具类

package com.zhhong.honey.common;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

/**
 * 自定义响应结构
 */
public class HoneyResult {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    // 响应业务状态
    private Integer status;

    // 响应消息
    private String msg;

    // 响应中的数据
    private Object data;

    private long count;

    public long getCount() {
        return count;
    }

    public HoneyResult(Integer status, String msg, Object data, long count) {
        this.status = status;
        this.msg = msg;
        this.data = data;
        this.count = count;
    }

    public void setCount(long count) {
        this.count = count;
    }

    public static HoneyResult build(Integer status, String msg, Object data) {
        return new HoneyResult(status, msg, data);
    }

    public static HoneyResult build(Integer status, String msg, Object data,long count) {
        return new HoneyResult(status, msg, data,count);
    }

    public static HoneyResult ok(Object data) {
        return new HoneyResult(data);
    }

    public static HoneyResult ok() {
        return new HoneyResult(null);
    }

    public HoneyResult() {

    }

    public static HoneyResult build(Integer status, String msg) {
        return new HoneyResult(status, msg, null);
    }


    public HoneyResult(Integer status, String msg, Object data) {
        this.status = status;
        this.msg = msg;
        this.data = data;
    }

    public HoneyResult(Object data) {
        this.status = 200;
        this.msg = "OK";
        this.data = data;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    /**
     * 将json结果集转化为QPsssResult对象
     * 
     * @param jsonData json数据
     * @param clazz HandyExpressResult中的object类型
     * @return
     */
    public static HoneyResult formatToPojo(String jsonData, Class<?> clazz) {
        try {
            if (clazz == null) {
                return MAPPER.readValue(jsonData, HoneyResult.class);
            }
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (clazz != null) {
                if (data.isObject()) {
                    obj = MAPPER.readValue(data.traverse(), clazz);
                } else if (data.isTextual()) {
                    obj = MAPPER.readValue(data.asText(), clazz);
                }
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 没有object对象的转化
     * 
     * @param json
     * @return
     */
    public static HoneyResult format(String json) {
        try {
            return MAPPER.readValue(json, HoneyResult.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Object是集合转化
     * 
     * @param jsonData json数据
     * @param clazz 集合中的类型
     * @return
     */
    public static HoneyResult formatToList(String jsonData, Class<?> clazz) {
        try {
            JsonNode jsonNode = MAPPER.readTree(jsonData);
            JsonNode data = jsonNode.get("data");
            Object obj = null;
            if (data.isArray() && data.size() > 0) {
                obj = MAPPER.readValue(data.traverse(),
                        MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
            }
            return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
        } catch (Exception e) {
            return null;
        }
    }

}

3.支付宝公用参数配置工具类

package com.zhhong.honey.utils.config.zfb;

public class AlipayConfig {
    // 商户appid
    public static String APPID = "";
    //私钥 pkcs8格式的
    public static String RSA_PRIVATE_KEY =";

    // 支付宝回调地址
    public static String notify_url = "";

    //页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
    public static String return_url = "";

    // 请求网关地址
    public static String URL = "https://openapi.alipay.com/gateway.do";
    // 编码
    public static String CHARSET_UTF8 = "UTF-8";

    public static String CHARSET_GBK = "GBK";
    // 返回格式
    public static String FORMAT = "json";
    // 支付宝公钥
    public static String ALIPAY_PUBLIC_KEY ="";
    // 日志记录目录
    public static String log_path = "/log";
    // RSA2
    public static String SIGNTYPE = "RSA2";
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值