Java(三)Spring Boot 整合支付宝支付

背景

  1. 支付宝开放平台 创建一个第三方应用,此时该移动应用会被分发一个 AppID。
  2. 添加 APP支付、小程序基础包(服务商版)、第三方应用授权等功能。
  3. 设置授权回调地址。
  4. 商家授权应用中发起授权,引导商户授权。
  5. 发起商户自主签约。
  6. 利用 RSARSA 签名验签工具生成公钥、私钥并保存。
  7. 详细可参照 蚂蚁金服官方文档

配置

application.properties 配置

alipay.app_id=**************
alipay.alipay_public_key=***************
alipay.merchant_private_key=**************
alipay.charset=utf-8
alipay.sign_type=RSA2
alipay.gatewayUrl=https://openapi.alipay.com/gateway.do
alipay.log_path=/xxx/xxxx/xxx/xxx/
alipay.notify_url=http://ip:prot/xxx/xxxxx
alipay.return_url=http://ip:prot/xxx/xxxxx

配置文件对应的 Config

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Data
@Component
public class AlipayConfig {
    // 第三方
    // 应用 ID,你的 APPID,收款账号是你的 APPID 对应支付宝账号
    @Value("${alipay.app_id}")
    private String app_id;

    // 服务器异步通知页面路径  需 http:// 格式的完整路径,不能加 ?id=123 这类自定义参数,必须外网可以正常访问
    @Value("${alipay.notify_url}")
    private String notify_url;

    // 页面跳转同步通知页面路径 需 http://格式的完整路径,不能加 ?id=123 这类自定义参数,必须外网可以正常访问
    @Value("${alipay.return_url}")
    private String return_url;

    // 签名方式
    @Value("${alipay.sign_type}")
    private String sign_type;

    // 字符编码格式
    @Value("${alipay.charset}")
    private String charset;

    // 支付宝网关
    @Value("${alipay.gatewayUrl}")
    private String gatewayUrl;

    // 支付宝网关
    @Value("${alipay.log_path}")
    private String log_path;

    @Value("${alipay.merchant_private_key}")
    private String merchant_private_key;

    @Value("${alipay.alipay_public_key}")
    private String alipay_public_key;

    // 商户授权 token
    @Value("${alipay.app_auth_token}")
    private String app_auth_token;
}

在 pom.xml 中添加支付宝 SDK 依赖

<!-- 支付宝 -->
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>3.4.49.ALL</version>
</dependency>

请求支付宝支付

发起支付请求

@Override
public Map<String, Object> payRequest(double totalAmount, String orderId) throws Exception {

    Map<String, Object> map = new HashMap<>();
    //支付宝
    //实例化客户端
    AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(), alipayConfig.getMerchant_private_key(), "json", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSign_type());
    AlipayTradeAppPayRequest aliPayRequest = new AlipayTradeAppPayRequest();

    AlipayMerchants merchants = userMapper.findAppAlipayMerchantsByCityCode(cityCode, mid);
    aliPayRequest.putOtherTextParam("app_auth_token", alipayConfig.getApp_auth_token());

    AlipayTradePayModel model = new AlipayTradePayModel();
    //支付编号
    model.setOutTradeNo(orderId);
    //订单名称
    model.setSubject(is);
    //支付总金额
    model.setTotalAmount("" + totalAmount);
    //超时则关闭订单
    model.setTimeoutExpress("3000m");
    aliPayRequest.setBizModel(model);
    //异步回调地址
    aliPayRequest.setReturnUrl(alipayConfig.getReturn_url());
    aliPayRequest.setNotifyUrl(alipayConfig.getNotify_url());

    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(aliPayRequest);
    map.put("aliPaySdk", response.getBody());
    return map;
}

支付宝支付订单回调

@Override
public AliPayVO aliPayCallBack(HttpServletRequest request) throws Exception {
    //获取支付宝反馈信息
    Map<String, String> params = new HashMap<String, String>();
    Map<String, String[]> requestParams = request.getParameterMap();
    for (Iterator<String> 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] + ",";
        }
        params.put(name, valueStr);
    }
    //调用SDK验证签名
    boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(), alipayConfig.getCharset(), alipayConfig.getSign_type());
    //校验签名
    if (!signVerified) {
        logger.info("支付宝支付回调签名不正确");
    }
    //校验支付状态
    if (!request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
        logger.info("支付宝支付回调支付状态不正确");
    }
    AliPayVO aliPayVo = new AliPayVO();
    //商户订单号
    String outTradeNo = request.getParameter("out_trade_no");
    aliPayVo.setOutTradeNo(outTradeNo);
    //交易流水号
    String tradeNo = request.getParameter("trade_no");
    aliPayVo.setTradeNo(tradeNo);
    //交易状态
    String tradeStatus = request.getParameter("trade_status");
    aliPayVo.setTradeStatus(tradeStatus);
    //资金总额
    String totalAmount = request.getParameter("total_amount");
    aliPayVo.setTotalAmount(totalAmount);
    //卖家支付宝账户
    String sellerId = request.getParameter("seller_id");
    aliPayVo.setSellerId(sellerId);
    //买家支付宝账户
    String buyerLogonId = request.getParameter("buyer_logon_id");
    aliPayVo.setBuyerLogoinId(buyerLogonId);
    //签名方式
    aliPayVo.setSignType(alipayConfig.getSign_type());
    //签名
    String sign = request.getParameter("sign");
    aliPayVo.setSign(sign);
    //订单名称
    String subject = request.getParameter("subject");
    aliPayVo.setIs(subject);
    return aliPayVo;
}

支付宝订单支付回调业务处理

@Transactional
@Override
public void aliPayOrderCallBack(AliPayVO aliPayVo) throws Exception {
    if (aliPayVo != null && aliPayVo.getOutTradeNo() != null) {
        // 根据交易编号加锁,处理高并发
        synchronized (aliPayVo.getOutTradeNo()) {
            Integer status = payLogMapper.getOneOrderStatusByPayNo(aliPayVo.getOutTradeNo());
            if (status == null || status != 2) {
                if (aliPayVo.getTradeStatus().equals("TRADE_SUCCESS")) {// 交易支付成功
                    SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    // 支付宝交易记录表
                    PayLog payLog = new PayLog();
                    // 签名方式
                    payLog.setSignType(aliPayVo.getSignType());
                    // 交易编码
                    payLog.setOutTradeNo(aliPayVo.getTradeNo());
                    // 订单号
                    payLog.setOrderId(aliPayVo.getOutTradeNo());
                    // 买家支付宝账户
                    payLog.setBuyerId(aliPayVo.getBuyerLogoinId());
                    // 支付金额
                    BigDecimal depthBig = new BigDecimal(aliPayVo.getTotalAmount());
                    payLog.setTotalFee(depthBig);
                    // 支付方式
                    payLog.setPayType(2);
                    // 交易创建时间
                    Date date1 = new Date();
                    payLog.setCreateTime(ft.format(date1));
                    // 交易付款时间
                    Date date2 = new Date();
                    payLog.setPayTime(ft.format(date2));
                    if (payLogMapper.getOneOrderCountByPayNo(aliPayVo.getOutTradeNo()) == null) {
                        payLog.setStatus(2);
                        payLogMapper.insertPayLog(payLog);
                    } else {
                        payLogMapper.updateOrderStatusByPayNo(2, aliPayVo.getOutTradeNo());
                    }
                    // 修改订单状态
                    orderBiz.order(aliPayVo.getIs(),aliPayVo.getOutTradeNo());
                    logger.info("TRADE_SUCCESS");
                }
            } else {
                logger.info("该订单已支付处理,交易编号为: " + aliPayVo.getOutTradeNo());
            }
        }
    }
}

支付宝支付订单、回调

@PostMapping(value = "/xxxxx")
public String aliPayOrderCallBack(HttpServletRequest request) {
    try {
        AliPayVO aliPayVo = alipayBiz.aliPayCallBack(request);
        alipayBiz.aliPayOrderCallBack(aliPayVo);
    } catch (Exception e) {
        e.printStackTrace();
        logger.error("aliPayOrderCallBack Error.", e);
    }
    return "";
}

支付宝定时回调方法

/**
 * 定时任务:每十五分钟触发一次主动调用订单支付回调
 */
@Scheduled(cron = "0 */15 * * * ?")
public void initiativeOrderPayCallBack() {
    //主动调用订单支付回调
    try {
        alipayBiz.initiativeOrderPayCallBack();
    } catch (Exception e) {
        logger.error("timer initiativeOrderPayCallBack Error.", e);
        e.printStackTrace();
    }
}
/**
 * @Description: 主动调用订单支付回调
 */
@Override
public void initiativeOrderPayCallBack() throws Exception {
    // 查询订单表里订单状态为待付款的支付编号
    List<String> onePayNoByStatus = payLogMapper.getOnePayNoByStatus(1);
    for (String no : onePayNoByStatus) {
        try {
            // 支付宝
            AliPayVO aliPayVO = this.aliPayQueryCallBack(no);
            // 订单回调处理
            this.aliPayOrderCallBack(aliPayVO);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }
}
/**
 * @Description: 支付宝支付主动查询回调
 */
@Override
public AliPayVO aliPayQueryCallBack(String payNo) throws Exception {
    //实例化客户端
    AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(), alipayConfig.getMerchant_private_key(), "json", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSign_type());
    AlipayTradeQueryRequest aliPayRequest = new AlipayTradeQueryRequest();
    AlipayTradePayModel model = new AlipayTradePayModel();
    model.setOutTradeNo(payNo);
    aliPayRequest.setBizModel(model);
    AlipayTradeQueryResponse response = alipayClient.execute(aliPayRequest);
    AliPayVO aliPayVO = new AliPayVO();
    if (response.isSuccess()) {
        // logger.info("支付宝支付主动调用请求成功");
        // 支付状态
        aliPayVO.setTradeStatus(response.getTradeStatus());
        // 支付金额
        aliPayVO.setTotalAmount(response.getTotalAmount());
        // 买家支付宝账户
        aliPayVO.setBuyerLogoinId(response.getBuyerLogonId());
        // 订单号
        aliPayVO.setOutTradeNo(response.getOutTradeNo());
    }
    return aliPayVO;
}

更新时间:2021-04-29 14:45:43

本文由 caroly 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载 / 出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://caroly.fun/archives/springboot整合支付宝支付
最后更新:2021-04-29 14:45:43

评论

Your browser is out of date!

Update your browser to view this website correctly. Update my browser now

×