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