Java对接支付宝支付

Java对接支付宝支付

准备工具
SpringBoot工程构建
导入支付宝支付的maven依赖
获取支付宝的API 密钥,支付宝公钥,支付宝私钥等配置文件
定义当面支付的地址
https://openapi.alipay.com/gateway.do

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

        <dependency>
            <groupId>com.ibeetl</groupId>
            <artifactId>beetl</artifactId>
            <version>${beetl.version}</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.10</version>
        </dependency>

        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
    </dependencies>
package com.jowim.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.ZolozAuthenticationCustomerSmilepayInitializeRequest;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.ZolozAuthenticationCustomerSmilepayInitializeResponse;
import com.jowim.constant.ResultConstants;
import com.jowim.entity.Orders;
import com.jowim.entity.Product;
import com.jowim.entity.ProductInOrders;
import com.jowim.entity.Site;
import com.jowim.mapper.ProductInOrdersMapper;
import com.jowim.mapper.ProductMapper;
import com.jowim.service.IAliPayMethod;
import com.jowim.service.IOrdersService;
import com.jowim.service.IRedisCache;
import com.jowim.service.ISiteService;
import com.jowim.tool.FavoritesHelper;
import com.jowim.util.ResponseMessage;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

@Service
public class AlipayMethodImpl implements IAliPayMethod {


    /**
     * 站点
     */
    @Autowired
    private ISiteService iSiteService;
    /**
     * 订单
     */
    @Autowired
    private IOrdersService iOrdersService;

    /**
     * 订单内商品
     */
    @Autowired
    private ProductInOrdersMapper productInOrdersMapper;

    /**
     * 产品
     */
    @Autowired
    private ProductMapper productMapper;
    /**
     * 缓存
     */
    @Autowired
    private IRedisCache iRedisCache;
    private final static Logger log = LoggerFactory.getLogger(AlipayMethodImpl.class);

    public static String siteID = "355e307afbe95a9c85cfb9732fef204d";
    //当面支付
    private static final String URL = "https://openapi.alipay.com/gateway.do";

    //通知地址,自己的实际回调接口
    private static final String notify_url = "";
    // 编码
    public static String CHARSET = "UTF-8";
    // 返回格式
    public static String FORMAT = "json";
    public static String SIGNTYPE = "RSA2";

    /**
     * 支付宝支付码支付
     *
     * @param json
     * @param httpRequest
     * @param httpResponse
     * @return
     */
    @Override
    @Transactional
    public ResponseMessage<Object> doPost(String json, HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws AlipayApiException {
        //商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
        String orderNo = JSON.parseObject(json).getString("orderNo");
        //支付授权码,25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准
        String authCode = JSON.parseObject(json).getString("authCode");
        //订单标题
        String subject = JSON.parseObject(json).getString("subject");
        if (FavoritesHelper.isNull(orderNo) || FavoritesHelper.isNull(subject)) {
            return ResponseMessage.error(ResultConstants.RESULT_NULL);
        }
        Site site = iSiteService.selectById(siteID);
        String appId = site.getAppId();
        String publicKey = site.getAliPublicKey();
        String privateKey = site.getAliPrivateKey();
        Orders orders = iOrdersService.selectById(orderNo);
        if (null == orders) {
            return ResponseMessage.error("未查询到该订单,请重试!");
        }
        BigDecimal moneys = orders.getSalesAmount();
        AlipayClient alipayClient = new DefaultAlipayClient(URL, appId, privateKey, FORMAT, CHARSET, publicKey, SIGNTYPE); //获得初始化的AlipayClient
        AlipayTradePayRequest alipayRequest = new AlipayTradePayRequest();//创建API对应的request
        alipayRequest.setBizContent("{" +
                "\"out_trade_no\":\"" + orderNo + "\"," +        //	商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
                "\"scene\":\"bar_code\"," +
                "\"auth_code\":\"" + authCode + "\"," +
                "\"product_code\":\"FACE_TO_FACE_PAYMENT\"," +
                "\"subject\":\"" + subject + "\"," +
                "\"total_amount\":\"" + moneys + "\"," +
                "  }");//填充业务参数
        AlipayTradePayResponse response = alipayClient.execute(alipayRequest);
        String form = response.getBody();
        if (response.isSuccess()) {
            System.out.println("调用成功");
            log.info("调用成功");
            BigDecimal totalMoney = new BigDecimal(response.getTotalAmount());
            //更新订单
            orders.setPayState("0");
            orders.setActualPayment(totalMoney);
            //查出订单内的商品
            List<ProductInOrders> productInOrdersList = productInOrdersMapper.selectProductInorders(
                    orders.getSupermarketId(), orders.getId());
            //查出商品信息
            List<Product> productList = productMapper.selectProductByIdList(productInOrdersList);
            List<Product> relaProductList = new ArrayList<>();
            for (ProductInOrders productInOrders : productInOrdersList) {
                for (Product product : productList) {
                    //如果未关联装箱
                    if ("1".equals(product.getRelateOrNot())) {
                        product.setStock(product.getStock() - productInOrders.getNum());
                    }
                    //如果关联装箱
                    if ("0".equals(product.getRelateOrNot())) {
                        //查出所关联的单品
                        Product relaProduct = productMapper.selectById(product.getRelationId());
                        relaProduct.setStock(relaProduct.getStock() - (relaProduct.getRelateNum() * productInOrders.getNum()));
                        relaProductList.add(relaProduct);
                    }
                }

            }
            productList.addAll(relaProductList);

            try {
                iOrdersService.updateById(orders);
                productMapper.updateProductByList(productList);
            } catch (Exception e) {
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return ResponseMessage.error("支付成功,更新数据库失败!");
            }
            log.info("支付宝免密支付成功!");
            return ResponseMessage.ok(2, "支付成功");
        } else {
            System.out.println("调用失败");
            log.info("调用失败");
            return ResponseMessage.error("调用失败");

        }
    }

    /**
     * 支付宝扫码支付
     *
     * @param json
     * @param httpRequest
     * @return
     */
    @Override
    public ResponseMessage<Object> doPost2(String json, HttpServletRequest httpRequest) throws AlipayApiException {
        //商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
        String orderNo = JSON.parseObject(json).getString("orderNo");
//        //	支付授权码,25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准
//        String authCode = JSON.parseObject(json).getString("authCode");
        //订单标题
        String subject = JSON.parseObject(json).getString("subject");
        if (FavoritesHelper.isNull(orderNo) || FavoritesHelper.isNull(subject)) {
            return ResponseMessage.error(ResultConstants.RESULT_NULL);
        }
        Site site = iSiteService.selectById(siteID);
        String appId = site.getAppId();
        String publicKey = site.getAliPublicKey();
        String privateKey = site.getAliPrivateKey();
        Orders orders = iOrdersService.selectById(orderNo);
        if (null == orders) {
            return ResponseMessage.error("未查询到该订单,请重试!");
        }
        BigDecimal moneys = orders.getSalesAmount();
        AlipayClient alipayClient = new DefaultAlipayClient(URL, appId, privateKey, FORMAT, CHARSET, publicKey, SIGNTYPE); //获得初始化的AlipayClient
        AlipayTradePrecreateRequest alipayRequest = new AlipayTradePrecreateRequest();//创建API对应的request
        alipayRequest.setNotifyUrl(notify_url);
        alipayRequest.setBizContent("{" +
                "\"out_trade_no\":\"" + orderNo + "\"," +        //	商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
                "\"subject\":\"" + subject + "\"," +
                "\"total_amount\":\"" + moneys + "\"," +
                "  }");//填充业务参数
        AlipayTradePrecreateResponse response = alipayClient.execute(alipayRequest);
        if (response.isSuccess()) {
            System.out.println("调用成功");
            return ResponseMessage.ok(response.getQrCode());
        } else {
            System.out.println("调用失败");
            return ResponseMessage.error("请求失败!");
        }
    }


    /**
     * 回调
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
     * 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
     * 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
     *
     * @param request
     * @return
     */
    @Override
    public String getNotify(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        Site site = iSiteService.selectById(siteID);
        String appId = site.getAppId();
        String publicKey = site.getAliPublicKey();
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
        log.info("支付宝回调,{}", paramsJson);
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, publicKey, CHARSET, SIGNTYPE);
            if (signVerified) {
                // 按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success,校验失败返回failure
                String outTradeNo = params.get("out_trade_no");
                // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
                Orders orders = iOrdersService.selectById(outTradeNo);
                //判断订单是否存在
                if (orders == null) {
                    return "failure";
                }
                //判断是否已更改过数据库
                if ("0".equals(orders.getPayState())){
                    return "success";
                }
                BigDecimal amout = new BigDecimal(params.get("total_amount"));
                //判断金额是否正确
                if (0!=amout.compareTo(orders.getSalesAmount())){
                    return "failure";
                }
                if (!params.get("app_id").equals(appId)) {
                    return "failure";
                }
                //更新订单
                orders.setPayState("0");
                orders.setActualPayment(amout);
                //查出订单内的商品
                List<ProductInOrders> productInOrdersList = productInOrdersMapper.selectProductInorders(
                        orders.getSupermarketId(), orders.getId());
                //查出商品信息
                List<Product> productList = productMapper.selectProductByIdList(productInOrdersList);
                List<Product> relaProductList = new ArrayList<>();
                for (ProductInOrders productInOrders : productInOrdersList) {
                    for (Product product : productList) {
                        //如果未关联装箱
                        if ("1".equals(product.getRelateOrNot())) {
                            product.setStock(product.getStock() - productInOrders.getNum());
                        }
                        //如果关联装箱
                        if ("0".equals(product.getRelateOrNot())) {
                            //查出所关联的单品
                            Product relaProduct = productMapper.selectById(product.getRelationId());
                            relaProduct.setStock(relaProduct.getStock() - (relaProduct.getRelateNum() * productInOrders.getNum()));
                            relaProductList.add(relaProduct);
                        }
                    }

                }
                productList.addAll(relaProductList);
                try {
                    iOrdersService.updateById(orders);
                    productMapper.updateProductByList(productList);
                }catch (Exception e){
                    e.printStackTrace();
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return "failure";
                }
                return "success";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "failure";
    }

    /**
     * 刷脸支付初始化
     * @param json
     * @return
     */
    @Override
    public ResponseMessage<Object> doPost3(String json,HttpServletRequest httpRequest) throws AlipayApiException {

        return null;
    }





    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }


}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值