编程语言
首页 > 编程语言> > JAVA集成支付宝支付 周期扣费 (证书方式)

JAVA集成支付宝支付 周期扣费 (证书方式)

作者:互联网

依赖

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

上代码

package com.yuren.yoga.common.vendor.template;

import com.alibaba.fastjson.JSON;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @author YSM
 * @user Admin
 * @data 2021/10/13
 * @ProjectName 新建文件夹
 */
@Slf4j
public class AliPayTemplate {

    private AliPayProperties aliPayProperties;

    private String PRODUCT_CODE = "CYCLE_PAY_AUTH";
    private String SIGN_SCENE = "INDUSTRY|CARRENTAL";
    private String url = "https://openapi.alipay.com/gateway.do";

    public AliPayTemplate(AliPayProperties aliPayProperties) {
        this.aliPayProperties = aliPayProperties;
    }


    public CertAlipayRequest getCertAlipayRequest() {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl("https://openapi.alipay.com/gateway.do");
        certAlipayRequest.setAppId(aliPayProperties.getAppId());
        certAlipayRequest.setPrivateKey(aliPayProperties.getPrivateKey());
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset("UTF-8");
        certAlipayRequest.setSignType("RSA2");
        certAlipayRequest.setCertPath(aliPayProperties.getCertPath() + "appCertPublicKey_" + aliPayProperties.getAppId() + ".crt");
        certAlipayRequest.setAlipayPublicCertPath(aliPayProperties.getCertPath() + "alipayCertPublicKey_RSA2.crt");
        certAlipayRequest.setRootCertPath(aliPayProperties.getCertPath() + "alipayRootCert.crt");
        return certAlipayRequest;
    }


    public String getOrder(String name, double price, Double originPrice, String courseId, String userId, String type) {
        return getOrder(name, price, originPrice, courseId, userId, type, null);
    }

    public String getOrder(String name, double price, Double originPrice, String courseId, String userId, String type, String contactPhone) {
        CertAlipayRequest certAlipayRequest = getCertAlipayRequest();
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        if (originPrice == null || 0 == originPrice) {
            originPrice = price;
        }

        if (StringUtils.isEmpty(contactPhone)) {
            contactPhone = "";
        }
        model.setBody(courseId + "-" + userId + "-" + type + "-" + originPrice + "-" + contactPhone);

        model.setSubject("YUREN-" + name);
        model.setGoodsType("0");//虚拟类商品

        String outTradeNo = DateUtils.format(new Date(), "yyyyMMddHHmmss")
                + new Random().nextInt(8999) + 1000;
        model.setOutTradeNo(outTradeNo);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(price + "");
        model.setProductCode("QUICK_MSECURITY_PAY");

        request.setBizModel(model);
        request.setNotifyUrl(aliPayProperties.getCallbackUrl());
        try {
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            return response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    public AlipayTradePrecreateResponse getQROrder(String name, double price, Double originPrice, String goodsId, String userId, String type) {
        CertAlipayRequest certAlipayRequest = getCertAlipayRequest();
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); //创建API对应的request类

        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        if (originPrice == null || 0 == originPrice) {
            originPrice = price;
        }
        model.setBody(goodsId + "-" + userId + "-" + type + "-" + originPrice);
        model.setSubject("YUREN-" + name);
        String outTradeNo = DateUtils.format(new Date(), "yyyyMMddHHmmss")
                + new Random().nextInt(8999) + 1000;
//        log.info(outTradeNo);
        model.setOutTradeNo(outTradeNo);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(price + "");
        request.setBizModel(model);
        request.setNotifyUrl(aliPayProperties.getCallbackUrl() + "Admin");

//        log.info("callbackUrl:{},certPath:{}",callbackUrl,certPath);

        AlipayTradePrecreateResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return response;
    }


    /**
     * H5 支付
     *
     * @param name        商品名称
     * @param price       商品现价
     * @param originPrice 原价
     * @param goodsId     商品ID
     * @param userId      购买用户ID
     * @param type        商品属性
     * @param outTradeNo  商户号
     * @return
     */
    public String getH5Pay(String name, double price, Double originPrice, String goodsId, String userId, String type, String outTradeNo) {
        return getH5Pay(name, price, originPrice, goodsId, userId, type, outTradeNo, null);
    }

    /**
     * H5 支付
     *
     * @param name        商品名称
     * @param price       商品现价
     * @param originPrice 原价
     * @param goodsId     商品ID
     * @param userId      购买用户ID
     * @param type        商品属性
     * @param outTradeNo  商户号
     * @return
     */
    public String getH5Pay(String name, double price, Double originPrice, String goodsId, String userId, String type, String outTradeNo, String contactPhone) {

        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        request.setNotifyUrl(aliPayProperties.getCallbackUrl());
     /*   JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", System.currentTimeMillis());
        bizContent.put("total_amount", 0.01);
        bizContent.put("subject", "测试商品6666");
        bizContent.put("product_code", "QUICK_WAP_WAY");*/
        if (originPrice == null || 0 == originPrice) {
            originPrice = price;
        }

        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(goodsId + "-" + userId + "-" + type + "-" + originPrice);
      /*  String outTradeNo = DateUtils.format(new Date(), "yyyyMMddHHmmss")
                + new Random().nextInt(8999) + 1000;*/
        model.setOutTradeNo(outTradeNo);
        model.setProductCode("QUICK_WAP_WAY");
        model.setTimeoutExpress("30m");
        model.setTotalAmount(price + "");
        model.setSubject("YUREN-" + name);
        if (StringUtils.isNotEmpty(contactPhone)) {
            model.setBody(goodsId + "-" + userId + "-" + type + "-" + originPrice + "-" + contactPhone);
        } else {
            model.setBody(goodsId + "-" + userId + "-" + type + "-" + originPrice);
        }
        //bizContent.put("time_expire", "2022-08-01 22:00:00");

// 商品明细信息,按需传入
    /*    JSONArray goodsDetail = new JSONArray();
        JSONObject goods1 = new JSONObject();
        goods1.put("goods_id", "goodsNo1");
        goods1.put("goods_name", "子商品1");
        goods1.put("quantity", 1);
        goods1.put("price", 0.01);
        goodsDetail.add(goods1);
        bizContent.put("goods_detail", goodsDetail);*/

// 扩展信息,按需传入
      /*  JSONObject extendParams = new JSONObject();
        extendParams.put("sys_service_provider_id", "2088511833207846");
        bizContent.put("extend_params", extendParams);
*/

        request.setBizModel(model);
        AlipayTradeWapPayResponse response = null;
        try {
            response = alipayClient.pageExecute(request, "GET");
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (!org.springframework.util.StringUtils.isEmpty(response) && response.isSuccess()) {
            log.debug("调用成功");
        } else {
            log.debug("调用失败");
        }
        return response.getBody();
    }

    /**
     * 根据商户订单号查询 支付状态
     *
     * @param outTradeNo
     * @return
     */
    public boolean queryOrder(String outTradeNo) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());

            AlipayTradeQueryRequest alipayTradeQueryRequest = new AlipayTradeQueryRequest();
            alipayTradeQueryRequest.setBizContent("{" +
                    "\"out_trade_no\":\"" + outTradeNo + "\"" +
                    "}");
            AlipayTradeQueryResponse alipayTradeQueryResponse = alipayClient.certificateExecute(alipayTradeQueryRequest);
            return "TRADE_SUCCESS".equals(alipayTradeQueryResponse.getTradeStatus());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 退款
     *
     * @param refundAmount 退款金额 0.01
     * @param tradeNo      订单号 (订单号 商户号 2选1)
     * @param outTradeNo   商户号
     * @param refundReason 退款说明
     */
    public Map<String, Object> refund(String refundAmount, String tradeNo, String outTradeNo, String refundReason) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();

        if (StringUtils.isNotEmpty(outTradeNo)) {
            refundModel.setOutTradeNo(outTradeNo);
        } else {
            refundModel.setTradeNo(tradeNo);
        }

        refundModel.setRefundAmount(refundAmount);
        refundModel.setRefundReason(refundReason);

        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizModel(refundModel);
        try {
            AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
            System.out.println("response.getBody() = " + response.getBody());
            Map<String, Object> result = JSON.parseObject(response.getBody(), Map.class);

            return result;
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param externalAgreementNo
     * @param money               签约金额
     * @param num                 周期  1  【月】
     * @param isWeb               true 页面   false-->sdk
     * @return
     */
    public String signUp(String externalAgreementNo, String money, int num, boolean isWeb) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayUserAgreementPageSignRequest request = new AlipayUserAgreementPageSignRequest();
        request.setNotifyUrl(aliPayProperties.getSignUpUrl());
        request.setReturnUrl(aliPayProperties.getSignReturnUrl());
        Map<String, Object> optionalArgs = new HashMap<>();
        //周期扣款销售产品码固定为CYCLE_PAY_AUTH。
        optionalArgs.put("product_code", PRODUCT_CODE);
        //周期扣款个人签约产品码固定为CYCLE_PAY_AUTH_P
        optionalArgs.put("personal_product_code", "CYCLE_PAY_AUTH_P");
        //协议签约场景,参见下文sign_scene参数说明  INDUSTRY|EDU教育行业
        optionalArgs.put("sign_scene", SIGN_SCENE);
        // 商户签约号,代扣协议中标示用户的唯一签约号(确保在商户系统中唯一
        optionalArgs.put("external_agreement_no", externalAgreementNo);

        /**请按当前接入的方式进行填充,且输入值必须为文档中的参数取值范围,
         * 1. ALIPAYAPP (钱包h5页面签约)
         * 2. QRCODE(扫码签约)
         * 3. QRCODEORSMS(扫码签约或者短信签约)*/
        Map<String, Object> accessParams = new HashMap<>();
        accessParams.put("channel", "ALIPAYAPP");
        optionalArgs.put("access_params", accessParams);

        /**周期管控规则参数period_rule_params,在签约周期扣款产品(如CYCLE_PAY_AUTH_P)时必传,在签约其他产品时无需传入。
         周期扣款产品,会按照这里传入的参数提示用户,并对发起扣款的时间、金额、次数等做相应限制 */
        Map<String, Object> periodRuleParams = new HashMap<>();
        //周期类型period_type是周期扣款产品必填,枚举值为DAY和MONTH
        periodRuleParams.put("period_type", "MONTH");
        //30天为一个扣款周期
        periodRuleParams.put("period", String.valueOf(num));
        /**首次执行时间execute_time是周期扣款产品必填,即商户发起首次扣款的时间。精确到日,格式为yyyy-MM-dd
         结合其他必填的扣款周期参数,会确定商户以后的扣款计划。发起扣款的时间需符合这里的扣款计划
         首次扣款日期:当前时间+30  ; 目前允许商户在约定日期之前5天(不含扣款日当天)开始扣款
         */
        Date date = new Date();
        String dd = DateUtils.format(date, "dd");
        //如果当天大于28号 修改到下月1号
        if (Integer.valueOf(dd) > 28){
            date = DateUtils.getTimesMonthmorning(DateUtils.addDateMonths(date, 1));
        }
        periodRuleParams.put("execute_time", DateUtils.format(date));

        /**单次扣款最大金额single_amount是周期扣款产品必填,即每次发起扣款时限制的最大金额,单位为元。商户每次发起扣款都不允许大于此金额*/
        periodRuleParams.put("single_amount", money);
        optionalArgs.put("period_rule_params", periodRuleParams);

        //签约参数。如果希望在sdk中支付并签约,需要在这里传入签约信息。周期扣款场景 product_code 为 CYCLE_PAY_AUTH 时必填
        String requestJson = JSON.toJSONString(optionalArgs);
        log.info("用户{}:发起周期扣款签约请求,入参:{}", externalAgreementNo, requestJson);

        request.setBizContent(requestJson);

        AlipayUserAgreementPageSignResponse response;
        try {
            if (isWeb) {
                response = alipayClient.pageExecute(request, "get");
            } else {
                response = alipayClient.sdkExecute(request);
            }
            if (response.isSuccess()) {
                log.info("用户{}:周期扣款,发起签约成功", externalAgreementNo);
                //获取需提交的form表单
                return response.getBody();
            }
            log.info("用户{}:周期扣款,发起签约失败:{}", externalAgreementNo, response.getSubMsg());
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("用户{}:周期扣款,发起签约异常:{}", externalAgreementNo, e);
        }
        return null;
    }

    /**
     * 商户订单号
     *
     * @return
     */
    public String getOutTradeNo() {
        return "Y" + DateUtils.format(new Date(), "yyyyMMddHHmmss") + new Random().nextInt(8999) + 1000;
    }

    /**
     * 查询签约结果
     *
     * @param externalAgreementNo 签约号
     */
    public AlipayUserAgreementQueryResponse querySign(String externalAgreementNo) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayUserAgreementQueryRequest request = new AlipayUserAgreementQueryRequest();
        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("personal_product_code", "CYCLE_PAY_AUTH_P");
        requestMap.put("sign_scene", SIGN_SCENE);
        requestMap.put("external_agreement_no", externalAgreementNo);
        String requestJson = JSON.toJSONString(requestMap);
        log.info("{}:查询周期扣款签约结果入参:{}", externalAgreementNo, requestJson);
        request.setBizContent(requestJson);
        AlipayUserAgreementQueryResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                log.info("{}:查询周期扣款签约结果,调用成功", externalAgreementNo);
                return response;
            } else {
                log.info("{}:查询周期扣款签约结果,调用失败:{}", externalAgreementNo, response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 签约成功,根据签约协议号,发起主动扣款
     *
     * @param agreementNo 用户签约号
     * @param outTradeNo  商户订单号
     * @param title       订单标题
     * @param totalAmount 本次扣款金额
     * @return
     */
    public AlipayTradePayResponse aliPayTradePayByAuthCode(String agreementNo, String outTradeNo, String title, String totalAmount) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        request.setNotifyUrl(aliPayProperties.getPayNotifyUrl());
        Map<String, String> requestMap = new HashMap<>();
        //商户订单号
        requestMap.put("out_trade_no", outTradeNo);
        //必填,周期扣款代扣场景固定值
        requestMap.put("scene", "deduct_pay");
        //用户签约号 agreement_no
        requestMap.put("auth_code", agreementNo);
        //周期扣款固定
        requestMap.put("product_code", "CYCLE_PAY_AUTH");
        //订单标题
        requestMap.put("subject", title);
        //本次扣款金额
        requestMap.put("total_amount", totalAmount);
        String requestJson = JSON.toJSONString(requestMap);
        log.info("{}:查询签约用户,进行自动续期扣费:{}", "", requestJson);

        request.setBizContent(requestJson);
        AlipayTradePayResponse response = null;
        try {
            response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                log.info("{}:周期扣款,主动扣费成功", agreementNo);
            } else {
                log.info("{}:周期扣款,主动扣费失败:{}", agreementNo, response.getSubMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 变更签约
     *
     * @param agreementNo 签约服务号
     * @param deductTime  扣费时间
     * @return
     */
    public AlipayUserAgreementExecutionplanModifyResponse aliPayModifyPlan(String agreementNo, String deductTime) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayUserAgreementExecutionplanModifyRequest request = new AlipayUserAgreementExecutionplanModifyRequest();
        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("agreement_no", agreementNo);
        requestMap.put("deduct_time", deductTime);
        String requestJson = JSON.toJSONString(requestMap);
        log.info("{}:周期扣款-修改协议执行计划入参:{}", agreementNo, requestJson);
        request.setBizContent(requestJson);

        try {
            AlipayUserAgreementExecutionplanModifyResponse response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                log.info("{}:周期扣款-修改协议执行计划,调用成功", agreementNo);
                return response;
            } else {
                log.info("{}:周期扣款-修改协议执行计划,调用失败:{}", agreementNo, response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("{}:周期扣款-修改协议执行计划,调用异常:{}", agreementNo, e);
        }
        return null;
    }

    /**
     * 解除签约     取消签约协议
     *
     * @param externalAgreementNo
     * @return
     */
    public AlipayUserAgreementUnsignResponse aliPayUnSign(String externalAgreementNo) {
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(getCertAlipayRequest());
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        AlipayUserAgreementUnsignRequest request = new AlipayUserAgreementUnsignRequest();
        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("personal_product_code", "CYCLE_PAY_AUTH_P");
        requestMap.put("sign_scene", SIGN_SCENE);
        requestMap.put("external_agreement_no", externalAgreementNo);
        String requestJson = JSON.toJSONString(requestMap);
        log.info("{}:周期扣款-解除签约入参:{}", externalAgreementNo, requestJson);
        request.setBizContent(requestJson);
        try {
            AlipayUserAgreementUnsignResponse response = alipayClient.execute(request);
            if (response.isSuccess()) {
                log.info("{}:周期扣款-解除签约,调用成功", externalAgreementNo);
                return response;
            } else {
                log.info("{}:周期扣款-解除签约,调用失败:{}", externalAgreementNo, response.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("{}:周期扣款-解除签约,调用异常:{}", externalAgreementNo, e);
        }
        return null;
    }

}

配置类

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * 支付宝支付配置类
 *
 * @author YSM
 * @user Admin
 * @data 2021/10/13
 * @ProjectName 新建文件夹
 */
@ConfigurationProperties(prefix = "payment.ali")
@Data
public class AliPayProperties {


    private String appId;

    private String privateKey;

    private String publicKey;

    private String certPath;

    private String callbackUrl;

    private String signUpUrl;
    private String signReturnUrl;
    private String payNotifyUrl;
}

标签:支付宝,JAVA,String,request,扣费,扣款,put,new,response
来源: https://blog.csdn.net/ysm00985/article/details/121175341