Java网上支付之对接支付宝(PC端)

一,支付宝文档中心 :https://docs.open.alipay.com
在这里插入图片描述

在这里插入图片描述
二,可以查看官方的示例代码:就是将必要的参数封装到请求对象里,然后调取接口。
在这里插入图片描述
pom.xml 依赖的jar包
在这里插入图片描述

一 :请求支付宝SDK

1 配置类

public final class AliPayConfig {
    /**
     * 应用号
     */
    public static String APP_ID = "xxxxxxxxxxxxxxx";
    /**
     * 商户的私钥
     */
    public static String APP_PRIVATE_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    /**
     * 编码
     */
    public static String CHARSET = "UTF-8";
    /**
     * 支付宝公钥
     */
    public static String ALIPAY_PUBLIC_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    /**
     * 支付宝网关地址
     */
    private static String GATEWAY = "https://openapi.alipay.com/gateway.do";
    /**
     * 成功付款回调
     */
    public static String PAY_NOTIFY = "http://xxxxxxxxxxx.com/sysControl/portals/alipayNotify.action";
   /**
     * 前台通知地址
     */
    public static String RETURN_URL ="http://xxxxxxxxxxxxxxxxxxxx";
    /**
     * 参数类型
     */
    public static String PARAM_TYPE = "json";
    /**
     * 成功标识
     */
    public static final String SUCCESS_REQUEST = "TRADE_SUCCESS";
    /**
     * 收款方账号
     */
    public static final String SELLER_ID = "jntnaj0136@sandbox.com";
    /**
     * 产品销售吗
     */
    public static final String PRODUCT_CODE= "FAST_INSTANT_TRADE_PAY";
    /**
     * 仅支持json
     */
    public static final String FORMAT= "JSON";
    /**
     * 仅支持json
     */
    public static final String SIGN_TYPE= "RSA2";
    /**
     * 支付宝请求客户端入口
     */
    private volatile static AlipayClient alipayClient = null;

    /**
     * 不可实例化
     */
    private AliPayConfig(){};

    /**
     * 双重锁单例
     * @return 支付宝请求客户端实例
     */
    public static AlipayClient getInstance(){
        if (alipayClient == null){
            synchronized (AliPayConfig.class){
                if (alipayClient == null){
                    alipayClient = new DefaultAlipayClient(GATEWAY,APP_ID,APP_PRIVATE_KEY,PARAM_TYPE,CHARSET,ALIPAY_PUBLIC_KEY,SIGN_TYPE);
                }
            }
        }
        return alipayClient;
    }

}

2.业务类

 /**
     * 支付宝
     * @param payment
     * @return
     */
    @Override
    public String alipayFrom(Payment payment) {

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AliPayConfig.RETURN_URL);
        alipayRequest.setNotifyUrl(AliPayConfig.PAY_NOTIFY);
        // 待请求参数数组
        Map alipayData= new HashMap<>(6);
        alipayData.put("out_trade_no",payment.getOrderNumber());
        alipayData.put("product_code",AliPayConfig.PRODUCT_CODE);
        alipayData.put("total_amount",payment.getCost());
        alipayData.put("subject",payment.getMessage());
        alipayData.put("body",payment.getMessage());
        alipayRequest.setBizContent(JSON.toJSONString(alipayData));
        String form = "";
        try {
         	//GET方法返回的是url,直接返给前端。
            form = AliPayConfig.getInstance().pageExecute(alipayRequest,"**GET**").getBody();
        } catch (AlipayApiException e) {
            logger.error("支付宝构造表单失败",e);
        }
        logger.debug("支付宝支付表单构造:{}",form);

        return form;
    }

这里是将所需要的参数放在map里,转成JSON。和官网示例差不多。“GET”给前端返回url

二 回调接口

1.controller层

/**
     * 支付宝支付回调
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/alipayNotify", method = RequestMethod.POST)
    @ResponseBody
    public String alipayChange(HttpServletRequest request) {

        LOGGER.info("线程ID<{}>收到支付宝回调请求", Thread.currentThread().getId());
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name =  iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            // 乱码解决,这段代码在出现乱码时使用
            /*
             * try {
             * valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
             * } catch (UnsupportedEncodingException e) {
             * logger.error("回调接收参数乱码",e);
             * }
             */
            params.put(name, valueStr);
        }
     PaymentServiceImpl.alipayVerifyNotify( payment)
        }

2.service业务层

public class PaymentServiceImpl extends BaseService implements PaymentService {
/**
     * 
     * @param payment
     * @return
     */
    @Override
    public String alipayVerifyNotify(Map<String,String> payment) throws Exception {

        boolean signVerified = checkRSA(payment);
        // 验证失败
        if (!signVerified) {
            logger.error("不是支付宝的合法请求!");
            return FAILURE;
        }
        // 验证通知是否有效
        boolean checkedTrustiness = checkedTrustiness(payment);
        if (!checkedTrustiness) {
            logger.error("支付宝请求异常!");
            return FAILURE;
        }
        String trade_status =payment.get("trade_status");
        if (TRADE_SUCCESS.equals(trade_status)) {
            //防止重复提交 做判断(支付宝可能会多次回调请求)
            Order order = iOrderService.selectOrderByOrderNum(payment.get("out_trade_no"));
            if(order==null){
                logger.error("订单信息查询异常");
                return FAILURE;
            }
            logger.info("订单编号:{}",order.getOrderNumber()+"-订单状态:"+order.getOrderStatus());
            if(order.getOrderStatus()==0){
                //调查询接口查账号
                String buyerLogonId = alipayQuery(payment);
                Payment pay =new Payment();
                pay.setPayWay(STATUS0);
                pay.setCost(new BigDecimal(payment.get("total_amount")));
                pay.setOrderId(order.getOrderId());
                pay.setPaySerialNum(payment.get("trade_no"));
                pay.setUserBankNum(buyerLogonId);
                try {
                    //支付成功修改数据库信息
                    insertDatabase(pay);
                }catch (Exception e){
                    logger.error("支付宝回调修改数据失败");
                    PayAnomaly payAnomaly = new PayAnomaly();
                    payAnomaly.setOrderNumber(payment.get("out_trade_no"));
                    payAnomaly.setPaySerialNum(payment.get("trade_no"));
                    payAnomaly.setOrderCost(new BigDecimal(payment.get("total_amount")));
                    payAnomaly.setPaymentTime(payment.get("gmt_payment"));
                    payAnomaly.setNotifyTime(payment.get("notify_time"));
                    payAnomaly.setUserId(order.getUserId());
                    logger.error("异常订单信息入库");
                    insertPayAnomaly(payAnomaly);
                }

            }

        }
        return SUCCESS;
    }

/**
     * 验证是否为支付宝的合法请求 --验证签名
     * @param requestParams  获取到的请求
     * @return
     */
    private boolean checkRSA(Map<String,String> requestParams) {
        logger.info("收到支付宝验证:{}",requestParams.toString());
        boolean isVerify = false;
        try {
            //调用SDK验证签名
            isVerify = AlipaySignature.rsaCheckV1(requestParams, ALIPAY_PUBLIC_KEY, CHARSET,SIGN_TYPE);
            logger.debug("支付宝验签结果:{}",isVerify);
            return isVerify;
        } catch (AlipayApiException e) {
            e.printStackTrace();
            logger.error("支付宝回调验证签名异常:{}", e);
            return isVerify;
        }

    }
    // 验证支付
    private boolean checkedTrustiness(Map<String,String> request) {
        String out_trade_no = "";
        String trade_status = "";
        String seller_id = "";
        String app_id ;
        BigDecimal total_amount;
        try {
            out_trade_no = request.get("out_trade_no");
            total_amount = new BigDecimal(request.get("buyer_pay_amount"));
            seller_id = request.get("seller_id");
            app_id = request.get("app_id");
            trade_status = request.get("trade_status");
        } catch (Exception e) {
            logger.error("回调参数格式转换异常(orderNum=" + out_trade_no + ")", e);
            return false;
        }
        if (!"TRADE_FINISHED".equals(trade_status) && !"TRADE_SUCCESS".equals(trade_status)) {
            logger.error("支付宝返回的交易状态不正确(orderNum=" + out_trade_no + ")");
            return false;
        }
        Order order;
        try {
            //根据订单id查询订单信息
            order = iOrderService.selectOrderByOrderNum(request.get("out_trade_no"));
            if(order==null){
                logger.error("回调查询订单信息失败(orderNum=" + out_trade_no + ")");
               return false;
            }

        } catch (Exception e) {
            logger.error("paybill 查询订单情况异常 (orderNum=" + out_trade_no + ")", e);
            return false;
        }
        // 1.判断totalamount
        if (!total_amount.equals(order.getOrderCost())) {
            logger.error("支付宝返回的订单金额不正确(orderNum=" + out_trade_no + ")");
            return false;
        }
        // 2.验证app_id
        if (!APP_ID.equals(app_id)) {
            logger.error("支付宝返回的app_id不正确(orderNum=" + out_trade_no + ")");
            return false;
        }
        // 3.验证order_id
        if (!out_trade_no.equals(order.getOrderNumber())) {
            logger.error("支付宝返回的订单id不正确(orderNum=" + out_trade_no + ")");
            return false;
        }
        // 4.验证seller_id
       /* if (!seller_id.equals(SELLER_ID)) {
            logger.error("支付宝返回的订单id不正确(payid=" + out_trade_no + ")");
            return false;
        }*/
        return true;
    }
}

1.支付成功,支付宝还多次请求服务器
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值