Java对接第三方支付渠道之支付宝支付

提示:支付宝相对于微信支付更人性化,且细节做得更好。


一、前期准备工作

支付宝支付分为正式环境和沙箱环境,我这里使用的是正式环境。
沙箱环境和正式环境差距不是很大,唯一的差距就是正式环境需要营业执照。沙箱环境就可以很好避免这个问题。

  1. 创建应用
  2. 绑定应⽤
  3. 配置秘钥
  4. 上线应⽤
  5. 签约功能

官方API文档地址: https://opendocs.alipay.com/open/270/01didh?ref=api


二、导入依赖

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

三、书写配置类

/**
 * description:支付宝支付配置类
 * author:maozl
 * date:2022/8/1
 */
@Configuration
@PropertySource("classpath:alipay.properties") //读取配置文件
@ConfigurationProperties(prefix="alipay") //读取wxpay节点
@Data //使用set方法将alipay节点中的值填充到当前类的属性中
@Slf4j
public class AliPayClientConfig {

    /**
     * APPID
     */
    private String appId;

    /**
     * 商户PID
     */
    private String sellerId;

    /**
     * 支付宝网关
     */
    private String gatewayUrl;

    /**
     * 商户私钥
     */
    private String merchantPrivateKey;

    /**
     * 支付宝公钥
     */
    private String aliPayPublicKey;

    /**
     * 接口加密秘钥
     */
    private String contentKey;

    /**
     * 页面跳转同步通知页面路径
     */
    private String returnUrl;

    /**
     * 回调地址
     */
    private String notifyUrl;

    @Bean
    public AlipayClient alipayClient() throws AlipayApiException {

        AlipayConfig alipayConfig=new AlipayConfig();
        //设置appId
        alipayConfig.setAppId(appId);
        //设置商户私钥
        alipayConfig.setPrivateKey(merchantPrivateKey);
        //设置支付宝公钥
        alipayConfig.setAlipayPublicKey(aliPayPublicKey);
        //设置支付宝网关
        alipayConfig.setServerUrl(gatewayUrl);
        //设置请求格式,固定值json.
        alipayConfig.setFormat(AlipayConstants.FORMAT_JSON);
        //设置字符集
        alipayConfig.setCharset(AlipayConstants.CHARSET_UTF8);
        //设置签名类型
        alipayConfig.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
        //构造client
        AlipayClient alipayClient=new DefaultAlipayClient(alipayConfig);
        return alipayClient;
    }

}


四、书写配置文件

# 支付宝支付相关参数

# 应用ID,你的APPID
alipay.app-id=

# 商户PID
alipay.seller-id=

# 支付宝网关
alipay.gateway-url=

# 商户私钥
alipay.merchant-private-key=

# 支付宝公钥
aliPay.aliPay-public-key=

# 接口内容加密秘钥,对称秘钥
alipay.content-key=

# 页面跳转同步通知页面路径
alipay.return-url=

# 支付宝支付成功回调地址
alipay.notify-url=


五、调用相关支付接口

1.流程图

在这里插入图片描述

2.创建支付

https://opendocs.alipay.com/apis/028r8t?scene=22

 /**
     * 发起支付
     * @param orderNo
     * @param uid
     * @return
     */
    @Override
    public String createPay(String orderNo, String uid) {

        //根据orderNo获取orderInfo
        OrderInfo orderInfo = orderInfoService.getOne(new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getOrderNo, orderNo)
                .eq(OrderInfo::getUid, uid));

        if (Objects.isNull(orderInfo)){
            throw new ServiceErrorException(ResultCode.ERROR, "发起支付请求失败 - 订单不存在");
        }

        //更新订单的支付类型
        orderInfoService.updatePayTypeByOrderNo(orderInfo.getOrderNo(), PayType.ALIPAY);

        //创建支付宝请求对象
        AlipayTradePagePayRequest request=new AlipayTradePagePayRequest();
        //数据
        AlipayTradePagePayModel bizModel=new AlipayTradePagePayModel();
        bizModel.setOutTradeNo(orderInfo.getOrderNo());
        //单位是元
        bizModel.setTotalAmount(orderInfo.getTotalFee().toString());
        bizModel.setSubject(orderInfo.getTitle());
        //默认的
        bizModel.setProductCode("FAST_INSTANT_TRADE_PAY");
        request.setBizModel(bizModel);

        request.setNotifyUrl(aliPayClientConfig.getNotifyUrl());
        //用户支付后支付宝会以GET方法请求returnUrl,并且携带out_trade_no,trade_no,total_amount等参数.
        request.setReturnUrl(aliPayClientConfig.getReturnUrl());

        AlipayTradePagePayResponse response=null;
        try{
            //完成签名并执行请求
            response=alipayClient.pageExecute(request);
            if(response.isSuccess()){
                log.debug("支付宝支付 - 调用成功");
                return response.getBody();
            }
            else{
                log.error("支付宝支付 - 调用失败");
                log.error(response.getMsg());
                return null;
            }
        }
        catch(AlipayApiException e){
            log.error("支付宝支付 - 创建支付交易失败");
            throw new ServiceErrorException(ResultCode.ERROR, "支付宝支付 - 创建支付交易失败");
        }
    }

3.支付通知

https://opendocs.alipay.com/open/270/105902

 /**
     * 支付成功回调函数
     * @param params
     * @return
     */
    @PostMapping("/callback")
    public String callback(@RequestParam Map<String,String> params){

        log.debug("收到支付宝回调");

        try{
            //验签
            boolean signVerified = AlipaySignature.rsaCheckV1(params,
                    aliPayClientConfig.getAliPayPublicKey(),
                    AlipayConstants.CHARSET_UTF8,
                    AlipayConstants.SIGN_TYPE_RSA2) ; //调用SDK验证签名

            //验签成功
            if(signVerified){
                log.debug("验签成功");

                //1.商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号
                String orderNo = params.get("out_trade_no");
                OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
                if (orderInfo == null){
                    log.error("订单不存在");
                    return "failure";
                }

                //2.判断 total_amount 是否确实为该订单的实际金额(即商家订单创建时的金额)
                String totalAmount = params.get("total_amount");
                if (!totalAmount.equals(orderInfo.getTotalFee().toString())){
                    log.error("金额校验失败");
                    return "failure";
                }

                //3.校验通知中的 seller_id(或者 seller_email ) 是否为 out_trade_no 这笔单据的对应的操作方
                String sellerId = params.get("seller_id");
                if (!aliPayClientConfig.getSellerId().equals(sellerId)){
                    log.error("商家PID校验失败");
                    return "failure";
                }

                //4.验证 app_id 是否为该商家本身
                String appId = params.get("app_id");
                if (!aliPayClientConfig.getAppId().equals(appId)){
                    log.error("应用APPID校验失败");
                    return "failure";
                }

                //5.在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,
                // 支付宝才会认定为买家付款成功。
                String tradeStatus = params.get("trade_status");
                if (!"TRADE_SUCCESS".equals(tradeStatus)){
                    log.error("支付未成功");
                    return "failure";
                }

                //支付成功后 - 处理订单
                aliPayService.processOrder(params);

                //除了success外其他返回均认为是失败
                return "success";
            }else{
                log.error("验签失败");
                return "failure";
            }
        }
        catch(AlipayApiException e){
            log.error("验签异常");
            e.printStackTrace();
            return "failure";
        }
    }

4.查询支付

https://opendocs.alipay.com/open/028woa

/**
     * 查询订单
     * @param orderNo
     * @return
     */
    @Override
    public boolean query(String orderNo) {

        //请求
        AlipayTradeQueryRequest request=new AlipayTradeQueryRequest();
        //数据
        AlipayTradeQueryModel bizModel=new AlipayTradeQueryModel();
        bizModel.setOutTradeNo(orderNo);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayTradeQueryResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.debug("查询订单{}成功",orderNo);

                Gson gson = new Gson();
                HashMap<String,Object> resultMap=gson.fromJson(response.getBody(),HashMap.class);

                String tradeStatus = (String) resultMap.get("trade_status");

                if (tradeStatus.equals("TRADE_SUCCESS")){ //订单支付已完成
                    log.info("调用订单查询接口 - 订单已支付完成");
                    return true;
                }
                return false;
            }
            else{
                log.error("查询订单{}失败,响应数据是{}.",orderNo,response.getBody());
                return false;
            }
        }
        catch(AlipayApiException e){
            log.error("查询订单{}异常",orderNo);
            return false;
        }
    }

5.取消支付

https://opendocs.alipay.com/open/028wob

/**
     * 支付宝取消订单接口
     * @param orderNo
     */
    @Override
    public void closeOrder(String orderNo) {

        //请求
        AlipayTradeCloseRequest request=new AlipayTradeCloseRequest();
        //数据
        AlipayTradeCloseModel bizModel=new AlipayTradeCloseModel();
        bizModel.setOutTradeNo(orderNo);
        request.setBizModel(bizModel);
        try{
            //完成签名并执行请求
            AlipayTradeCloseResponse response=alipayClient.execute(request);
            if(response.isSuccess()){
                log.debug("订单:{}取消成功",orderNo);
            }
            else{
                log.debug("订单:{}未创建,因此也可认为本次取消成功.",orderNo);
            }
        }
        catch(AlipayApiException e){
            log.error("订单{}取消异常",orderNo);
            throw new ServiceErrorException(ResultCode.ERROR, "订单取消异常");
        }
    }

总结

支付回调中可能会存在验签一直失败的问题,出现这个问题的可能是公钥使用出错,验签使用的是支付宝公钥而不是应用公钥,如果开发者在开发过程中,出现验证一直不通过的问题可以尝试检查一下
以上就是就是全部内容,本文仅仅简单介绍了支付宝支付的部分API的使用,还有退款以及账单等相关操作后续使用到了会继续更新。

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java聚合支付第三方平台是基于Java语言开发的一种支付解决方案。它通过整合多个支付渠道的功能和服务,为商家提供了一种统一的支付接口,从而简化了支付流程,提高了支付效率和用户体验。 首先,Java聚合支付第三方平台可以支持不同的支付渠道,包括支付、微信支付、银联等,以满足不同用户的支付需求。通过一个统一的接口,商家可以轻松接入多个支付渠道,不再需要针对每个支付方式单独开发和维护支付接口,极大地减轻了开发和运维的负担。 其次,Java聚合支付第三方平台提供了丰富的支付功能和服务。商家可以通过该平台实现支付、退款、查询订单、对账等常见的支付操作,满足不同的支付场景和业务需求。同时,该平台还提供了安全性较高的支付环境和风控系统,保障交易的安全性和可靠性。 另外,Java聚合支付第三方平台还提供了一些附加功能,如支付数据分析、统计和报表等,帮助商家实时掌握支付情况和用户支付行为,从而进行数据驱动的经营决策,提升收益和用户满意度。 最后,Java聚合支付第三方平台还具有良好的扩展性和定制化能力。平台可以根据商家的具体需求进行定制开发和二次开发,满足个性化的支付需求。而且,平台还支持与其他系统的集成,如订单系统、会员系统等,实现支付和业务的无缝对接。 综上所述,Java聚合支付第三方平台是一种高效、灵活和安全的支付解决方案,为商家提供了便捷快速的支付接入和支付服务,助力商家提升营收和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值