diff --git a/wfc-common/wfc-common-core/src/main/resources/i18n/messages_en_US.properties b/wfc-common/wfc-common-core/src/main/resources/i18n/messages_en_US.properties index eafd71c..1be2e48 100644 --- a/wfc-common/wfc-common-core/src/main/resources/i18n/messages_en_US.properties +++ b/wfc-common/wfc-common-core/src/main/resources/i18n/messages_en_US.properties @@ -179,6 +179,9 @@ common.request.parameter.type.not.match=Request parameter''{0}'' requires type: common.demo.mode=Demo mode, no operation is allowed common.system.error=Internal error, please contact the administrator +## wfc-payment +payment.pay.error=pay error + ## system portal menu menu.system.management=System Management menu.system.config=System Config diff --git a/wfc-common/wfc-common-core/src/main/resources/i18n/messages_zh_CN.properties b/wfc-common/wfc-common-core/src/main/resources/i18n/messages_zh_CN.properties index 181159f..c42374f 100644 --- a/wfc-common/wfc-common-core/src/main/resources/i18n/messages_zh_CN.properties +++ b/wfc-common/wfc-common-core/src/main/resources/i18n/messages_zh_CN.properties @@ -181,6 +181,9 @@ common.request.parameter.type.not.match=请求参数类型不匹配,参数''{0 common.demo.mode=演示模式,不允许操作 common.system.error=内部错误,请联系管理员 +## wfc-payment +payment.pay.error=支付错误 + ## system portal menu menu.system.management=系统管理 menu.system.config=系统配置 diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/controller/AliPayController.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/controller/AliPayController.java index 46ad5c3..b62bd8d 100644 --- a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/controller/AliPayController.java +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/controller/AliPayController.java @@ -19,12 +19,10 @@ import com.alipay.api.domain.AlipayTradeCancelModel; import com.alipay.api.domain.AlipayTradeCloseModel; import com.alipay.api.domain.AlipayTradeCreateModel; import com.alipay.api.domain.AlipayTradeOrderSettleModel; -import com.alipay.api.domain.AlipayTradePagePayModel; import com.alipay.api.domain.AlipayTradePayModel; import com.alipay.api.domain.AlipayTradePrecreateModel; import com.alipay.api.domain.AlipayTradeQueryModel; import com.alipay.api.domain.AlipayTradeRefundModel; -import com.alipay.api.domain.AlipayTradeWapPayModel; import com.alipay.api.domain.Participant; import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.response.AlipayFundAuthOrderFreezeResponse; @@ -35,31 +33,29 @@ import com.ijpay.alipay.AliPayApiConfig; import com.ijpay.alipay.AliPayApiConfigKit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import org.wfc.common.core.domain.R; +import org.springframework.web.bind.annotation.RestController; import org.wfc.payment.domain.AliPayBean; -import org.wfc.payment.utils.StringUtils; import org.wfc.payment.domain.vo.AjaxResult; -import org.wfc.user.api.RemoteUUserService; -import org.wfc.user.api.domain.vo.UOrderVo; +import org.wfc.payment.pay.alipay.service.IAliPayService; +import org.wfc.payment.utils.StringUtils; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.math.RoundingMode; import java.util.HashMap; import java.util.Map; /** * - *

支付宝支付 Demo

+ *

支付宝支付

* * @author cyc */ -@Controller +@RestController @RequestMapping("/aliPay") public class AliPayController extends AbstractAliPayApiController { private static final Logger log = LoggerFactory.getLogger(AliPayController.class); @@ -68,7 +64,7 @@ public class AliPayController extends AbstractAliPayApiController { private AliPayBean aliPayBean; @Resource - private RemoteUUserService remoteUUserService; + private IAliPayService aliPayService; private final AjaxResult result = new AjaxResult(); // 普通公钥模式 @@ -110,8 +106,7 @@ public class AliPayController extends AbstractAliPayApiController { return aliPayApiConfig; } - @RequestMapping("/test") - @ResponseBody + @GetMapping("/test") public AliPayApiConfig test() { AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig(); String charset = aliPayApiConfig.getCharset(); @@ -123,8 +118,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * app支付 */ - @RequestMapping(value = "/appPay") - @ResponseBody + @PostMapping(value = "/appPay") public AjaxResult appPay() { try { AlipayTradeAppPayModel model = new AlipayTradeAppPayModel(); @@ -144,97 +138,36 @@ public class AliPayController extends AbstractAliPayApiController { return result; } - @RequestMapping(value = "/wapPay") - @ResponseBody + @PostMapping(value = "/wapPay") public void wapPay(HttpServletResponse response, @RequestParam Long orderId) { - R orderRes = remoteUUserService.getOrderById(orderId); - UOrderVo orderVo = orderRes.getData(); - if (orderVo == null) { - return; - } - String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString(); - String body = "WANFI WAP PAY"; - String subject = "WANFI PAY"; -// String totalAmount = "1"; - String passBackParams = "1"; String returnUrl = aliPayBean.getDomain() + RETURN_URL; -// String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL; String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL; if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) { notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL; } + aliPayService.wapPay(response, orderId, returnUrl, notifyUrl); - - AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); - model.setBody(body); - model.setSubject(subject); - model.setTotalAmount(totalAmount); - model.setPassbackParams(passBackParams); - System.out.println("wap outTradeNo>" + orderId); - model.setOutTradeNo(orderId.toString()); - model.setProductCode("QUICK_WAP_PAY"); - - log.info("wap notifyUrl>" + notifyUrl); - try { - AliPayApi.wapPay(response, model, returnUrl, notifyUrl); - } catch (Exception e) { - e.printStackTrace(); - } } /** * PC支付 */ - @RequestMapping(value = "/pcPay") - @ResponseBody + @PostMapping(value = "/pcPay") public void pcPay(HttpServletResponse response, @RequestParam Long orderId) { - try { - R orderRes = remoteUUserService.getOrderById(orderId); - UOrderVo orderVo = orderRes.getData(); - if (orderVo == null) { - return; - } - String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString(); -// String outTradeNo = StringUtils.getOutTradeNo(); - log.info("pc outTradeNo>" + orderId); - String returnUrl = aliPayBean.getDomain() + RETURN_URL; - String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL; - if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) { - notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL; - } - AlipayTradePagePayModel model = new AlipayTradePagePayModel(); - - model.setOutTradeNo(orderId.toString()); - model.setProductCode("FAST_INSTANT_TRADE_PAY"); - model.setTotalAmount(totalAmount); - model.setSubject("WANFI PAY"); -// model.setBody("Javen IJPay PC支付测试"); - model.setPassbackParams("passback_params"); - /** - * 花呗分期相关的设置,测试环境不支持花呗分期的测试 - * hb_fq_num代表花呗分期数,仅支持传入3、6、12,其他期数暂不支持,传入会报错; - * hb_fq_seller_percent代表卖家承担收费比例,商家承担手续费传入100,用户承担手续费传入0,仅支持传入100、0两种,其他比例暂不支持,传入会报错。 - */ -// ExtendParams extendParams = new ExtendParams(); -// extendParams.setHbFqNum("3"); -// extendParams.setHbFqSellerPercent("0"); -// model.setExtendParams(extendParams); - log.info("pc notifyUrl>" + notifyUrl); - AliPayApi.tradePage(response, model, notifyUrl, returnUrl); - // https://opensupport.alipay.com/support/helpcenter/192/201602488772?ant_source=antsupport - // Alipay Easy SDK(新版)目前只支持输出form表单,不支持打印出url链接。 - // AliPayApi.tradePage(response, "GET", model, notifyUrl, returnUrl); - } catch (Exception e) { - e.printStackTrace(); + String returnUrl = aliPayBean.getDomain() + RETURN_URL; + String notifyUrl = aliPayBean.getDomain() + PRE_NOTIFY_URL + NOTIFY_URL; + if (StrUtil.isNotBlank(aliPayBean.getTestDomain())) { + notifyUrl = aliPayBean.getTestDomain() + PRE_NOTIFY_URL + NOTIFY_URL; } + aliPayService.pcPay(response, orderId, returnUrl, notifyUrl); + } - @RequestMapping(value = "/tradePay") - @ResponseBody + @PostMapping(value = "/tradePay") public String tradePay(@RequestParam("authCode") String authCode, @RequestParam("scene") String scene) { String subject = null; String waveCode = "wave_code"; @@ -265,8 +198,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 扫码支付 */ - @RequestMapping(value = "/tradePreCreatePay") - @ResponseBody + @PostMapping(value = "/tradePreCreatePay") public String tradePreCreatePay() { String subject = "Javen 支付宝扫码支付测试"; String totalAmount = "86"; @@ -294,8 +226,7 @@ public class AliPayController extends AbstractAliPayApiController { * 单笔转账到支付宝账户 * https://docs.open.alipay.com/309/106235/ */ - @RequestMapping(value = "/transfer") - @ResponseBody + @PostMapping(value = "/transfer") public String transfer() { String totalAmount = "66"; AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel(); @@ -315,8 +246,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/transferQuery") - @ResponseBody + @GetMapping(value = "/transferQuery") public String transferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo, @RequestParam(required = false, name = "orderId") String orderId) { AlipayFundTransOrderQueryModel model = new AlipayFundTransOrderQueryModel(); @@ -335,8 +265,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/uniTransfer") - @ResponseBody + @PostMapping(value = "/uniTransfer") public String uniTransfer() { String totalAmount = "1"; AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel(); @@ -361,8 +290,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/uniTransferQuery") - @ResponseBody + @GetMapping(value = "/uniTransferQuery") public String uniTransferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo, @RequestParam(required = false, name = "orderId") String orderId) { AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel(); @@ -381,8 +309,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/accountQuery") - @ResponseBody + @GetMapping(value = "/accountQuery") public String accountQuery(@RequestParam(required = true, name = "aliPayUserId") String aliPayUserId) { AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel(); model.setAlipayUserId(aliPayUserId); @@ -398,8 +325,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 资金授权冻结接口 */ - @RequestMapping(value = "/authOrderFreeze") - @ResponseBody + @PostMapping(value = "/authOrderFreeze") public AlipayFundAuthOrderFreezeResponse authOrderFreeze(@RequestParam("auth_code") String authCode) { try { AlipayFundAuthOrderFreezeModel model = new AlipayFundAuthOrderFreezeModel(); @@ -423,8 +349,7 @@ public class AliPayController extends AbstractAliPayApiController { * 红包协议支付接口 * https://docs.open.alipay.com/301/106168/ */ - @RequestMapping(value = "/agreementPay") - @ResponseBody + @PostMapping(value = "/agreementPay") public AlipayFundCouponOrderAgreementPayResponse agreementPay() { try { AlipayFundCouponOrderAgreementPayModel model = new AlipayFundCouponOrderAgreementPayModel(); @@ -444,8 +369,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 下载对账单 */ - @RequestMapping(value = "/dataDataServiceBill") - @ResponseBody + @PostMapping(value = "/dataDataServiceBill") public String dataDataServiceBill(@RequestParam("billDate") String billDate) { try { AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel(); @@ -461,8 +385,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 退款 */ - @RequestMapping(value = "/tradeRefund") - @ResponseBody + @PostMapping(value = "/tradeRefund") public String tradeRefund(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) { try { @@ -473,7 +396,7 @@ public class AliPayController extends AbstractAliPayApiController { if (StringUtils.isNotEmpty(tradeNo)) { model.setTradeNo(tradeNo); } - model.setRefundAmount("86.00"); + model.setRefundAmount("0.01"); model.setRefundReason("正常退款"); return AliPayApi.tradeRefundToResponse(model).getBody(); } catch (AlipayApiException e) { @@ -485,8 +408,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 交易查询 */ - @RequestMapping(value = "/tradeQuery") - @ResponseBody + @GetMapping(value = "/tradeQuery") public String tradeQuery(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) { try { AlipayTradeQueryModel model = new AlipayTradeQueryModel(); @@ -503,8 +425,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/tradeQueryByStr") - @ResponseBody + @GetMapping(value = "/tradeQueryByStr") public String tradeQueryByStr(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) { AlipayTradeQueryModel model = new AlipayTradeQueryModel(); if (StringUtils.isNotEmpty(outTradeNo)) { @@ -527,8 +448,7 @@ public class AliPayController extends AbstractAliPayApiController { * 创建订单 * {"alipay_trade_create_response":{"code":"10000","msg":"Success","out_trade_no":"081014283315033","trade_no":"2017081021001004200200274066"},"sign":"ZagfFZntf0loojZzdrBNnHhenhyRrsXwHLBNt1Z/dBbx7cF1o7SZQrzNjRHHmVypHKuCmYifikZIqbNNrFJauSuhT4MQkBJE+YGPDtHqDf4Ajdsv3JEyAM3TR/Xm5gUOpzCY7w+RZzkHevsTd4cjKeGM54GBh0hQH/gSyhs4pEN3lRWopqcKkrkOGZPcmunkbrUAF7+AhKGUpK+AqDw4xmKFuVChDKaRdnhM6/yVsezJFXzlQeVgFjbfiWqULxBXq1gqicntyUxvRygKA+5zDTqE5Jj3XRDjVFIDBeOBAnM+u03fUP489wV5V5apyI449RWeybLg08Wo+jUmeOuXOA=="} */ - @RequestMapping(value = "/tradeCreate") - @ResponseBody + @PostMapping(value = "/tradeCreate") public String tradeCreate(@RequestParam("outTradeNo") String outTradeNo) { String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL; @@ -552,8 +472,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 撤销订单 */ - @RequestMapping(value = "/tradeCancel") - @ResponseBody + @PostMapping(value = "/tradeCancel") public String tradeCancel(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) { try { AlipayTradeCancelModel model = new AlipayTradeCancelModel(); @@ -574,8 +493,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 关闭订单 */ - @RequestMapping(value = "/tradeClose") - @ResponseBody + @PostMapping(value = "/tradeClose") public String tradeClose(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("tradeNo") String tradeNo) { try { AlipayTradeCloseModel model = new AlipayTradeCloseModel(); @@ -596,8 +514,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 结算 */ - @RequestMapping(value = "/tradeOrderSettle") - @ResponseBody + @PostMapping(value = "/tradeOrderSettle") public String tradeOrderSettle(@RequestParam("tradeNo") String tradeNo) { try { AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel(); @@ -614,8 +531,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 获取应用授权URL并授权 */ - @RequestMapping(value = "/toOauth") - @ResponseBody + @PostMapping(value = "/toOauth") public void toOauth(HttpServletResponse response) { try { String redirectUri = aliPayBean.getDomain() + "/aliPay/redirect_uri"; @@ -629,8 +545,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 应用授权回调 */ - @RequestMapping(value = "/redirect_uri") - @ResponseBody + @PostMapping(value = "/redirect_uri") public String redirectUri(@RequestParam("app_id") String appId, @RequestParam("app_auth_code") String appAuthCode) { try { System.out.println("app_id:" + appId); @@ -649,8 +564,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 查询授权信息 */ - @RequestMapping(value = "/openAuthTokenAppQuery") - @ResponseBody + @GetMapping(value = "/openAuthTokenAppQuery") public String openAuthTokenAppQuery(@RequestParam("appAuthToken") String appAuthToken) { try { AlipayOpenAuthTokenAppQueryModel model = new AlipayOpenAuthTokenAppQueryModel(); @@ -665,8 +579,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 批量付款到支付宝账户有密接口 */ - @RequestMapping(value = "/batchTrans") - @ResponseBody + @PostMapping(value = "/batchTrans") public void batchTrans(HttpServletResponse response) { try { String signType = "MD5"; @@ -692,8 +605,7 @@ public class AliPayController extends AbstractAliPayApiController { /** * 地铁购票核销码发码 */ - @RequestMapping(value = "/voucherGenerate") - @ResponseBody + @PostMapping(value = "/voucherGenerate") public String voucherGenerate(@RequestParam("tradeNo") String tradeNo) { try { //需要支付成功的订单号 @@ -715,8 +627,7 @@ public class AliPayController extends AbstractAliPayApiController { return null; } - @RequestMapping(value = "/return_url") - @ResponseBody + @PostMapping(value = "/return_url") public String returnUrl(HttpServletRequest request) { try { // 获取支付宝GET过来反馈信息 @@ -729,13 +640,13 @@ public class AliPayController extends AbstractAliPayApiController { "RSA2"); if (verifyResult) { - // TODO 请在这里加上商户的业务逻辑程序代码 + // 请在这里加上商户的业务逻辑程序代码 System.out.println("return_url 验证成功"); return "success"; } else { System.out.println("return_url 验证失败"); - // TODO + // return "failure"; } } catch (AlipayApiException e) { @@ -744,8 +655,7 @@ public class AliPayController extends AbstractAliPayApiController { } } - @RequestMapping(value = "/cert_return_url") - @ResponseBody + @PostMapping(value = "/cert_return_url") public String certReturnUrl(HttpServletRequest request) { try { // 获取支付宝GET过来反馈信息 @@ -758,13 +668,13 @@ public class AliPayController extends AbstractAliPayApiController { "RSA2"); if (verifyResult) { - // TODO 请在这里加上商户的业务逻辑程序代码 + // 请在这里加上商户的业务逻辑程序代码 System.out.println("certReturnUrl 验证成功"); return "success"; } else { System.out.println("certReturnUrl 验证失败"); - // TODO + // return "failure"; } } catch (AlipayApiException e) { @@ -774,38 +684,13 @@ public class AliPayController extends AbstractAliPayApiController { } - @RequestMapping(value = "/callback") - @ResponseBody + @PostMapping(value = "/callback") public String notifyUrl(HttpServletRequest request) { - try { - // 获取支付宝POST过来反馈信息 - Map params = AliPayApi.toMap(request); - for (Map.Entry entry : params.entrySet()) { - System.out.println(entry.getKey() + " = " + entry.getValue()); - } - - boolean verifyResult = AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2"); - - if (verifyResult) { - // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理 - System.out.println("notify_url 验证成功succcess"); - String outTradeNo = params.get("out_trade_no"); - remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner"); - return "success"; - } else { - System.out.println("notify_url 验证失败"); - // TODO - return "failure"; - } - } catch (AlipayApiException e) { - e.printStackTrace(); - return "failure"; - } + return aliPayService.notifyUrl(request, aliPayBean.getPublicKey()); } - @RequestMapping(value = "/cert_notify_url") - @ResponseBody + @PostMapping(value = "/cert_notify_url") public String certNotifyUrl(HttpServletRequest request) { try { // 获取支付宝POST过来反馈信息 @@ -818,12 +703,12 @@ public class AliPayController extends AbstractAliPayApiController { boolean verifyResult = AlipaySignature.rsaCertCheckV1(params, aliPayBean.getAliPayCertPath(), "UTF-8", "RSA2"); if (verifyResult) { - // TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理 + // 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理 System.out.println("certNotifyUrl 验证成功succcess"); return "success"; } else { System.out.println("certNotifyUrl 验证失败"); - // TODO + // return "failure"; } } catch (AlipayApiException e) { diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/IAliPayService.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/IAliPayService.java new file mode 100644 index 0000000..4c52e5f --- /dev/null +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/IAliPayService.java @@ -0,0 +1,18 @@ +package org.wfc.payment.pay.alipay.service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @description: 支付宝支付Service + * @author: cyc + * @since: 2025-03-21 + */ +public interface IAliPayService { + + void pcPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl); + + void wapPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl); + + String notifyUrl(HttpServletRequest request, String publicKey); +} diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/impl/AliPayServiceImpl.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/impl/AliPayServiceImpl.java new file mode 100644 index 0000000..f20126e --- /dev/null +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/alipay/service/impl/AliPayServiceImpl.java @@ -0,0 +1,111 @@ +package org.wfc.payment.pay.alipay.service.impl; + +import com.alipay.api.AlipayApiException; +import com.alipay.api.domain.AlipayTradePagePayModel; +import com.alipay.api.domain.AlipayTradeWapPayModel; +import com.alipay.api.internal.util.AlipaySignature; +import com.ijpay.alipay.AliPayApi; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.wfc.common.core.domain.R; +import org.wfc.payment.pay.alipay.service.IAliPayService; +import org.wfc.user.api.RemoteUUserService; +import org.wfc.user.api.domain.vo.UOrderVo; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.RoundingMode; +import java.util.Map; + +/** + * @description: 支付宝支付ServiceImpl + * @author: cyc + * @since: 2025-03-21 + */ +@Service +@Slf4j +public class AliPayServiceImpl implements IAliPayService { + + @Resource + private RemoteUUserService remoteUUserService; + + @Override + public void pcPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl) { + try { + R orderRes = remoteUUserService.getOrderById(orderId); + UOrderVo orderVo = orderRes.getData(); + if (orderVo == null) { + return; + } + String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString(); + log.info("pc outTradeNo>" + orderId); + + AlipayTradePagePayModel model = new AlipayTradePagePayModel(); + + model.setOutTradeNo(orderId.toString()); + model.setProductCode("FAST_INSTANT_TRADE_PAY"); + model.setTotalAmount(totalAmount); + model.setSubject("WANFI PAY"); + model.setPassbackParams("passback_params"); + + log.info("pc notifyUrl>" + notifyUrl); + AliPayApi.tradePage(response, model, notifyUrl, returnUrl); + } catch (Exception e) { + log.error("alipay pc pay error", e); + } + } + + @Override + public void wapPay(HttpServletResponse response, Long orderId, String returnUrl, String notifyUrl) { + R orderRes = remoteUUserService.getOrderById(orderId); + UOrderVo orderVo = orderRes.getData(); + if (orderVo == null) { + return; + } + String totalAmount = orderVo.getOrderAmount().setScale(2, RoundingMode.HALF_UP).toString(); + + String body = "WANFI WAP PAY"; + String subject = "WANFI PAY"; + String passBackParams = "1"; + + AlipayTradeWapPayModel model = new AlipayTradeWapPayModel(); + model.setBody(body); + model.setSubject(subject); + model.setTotalAmount(totalAmount); + model.setPassbackParams(passBackParams); + System.out.println("wap outTradeNo>" + orderId); + model.setOutTradeNo(orderId.toString()); + model.setProductCode("QUICK_WAP_PAY"); + + log.info("wap notifyUrl>" + notifyUrl); + try { + AliPayApi.wapPay(response, model, returnUrl, notifyUrl); + } catch (Exception e) { + log.error("alipay wap pay error", e); + } + } + + @Override + public String notifyUrl(HttpServletRequest request, String publicKey) { + try { + // 获取支付宝POST过来反馈信息 + Map params = AliPayApi.toMap(request); + + boolean verifyResult = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", "RSA2"); + + if (verifyResult) { + // 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理 + String outTradeNo = params.get("out_trade_no"); + remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner"); + return "success"; + } else { + log.error("notify_url 验证失败"); + return "failure"; + } + } catch (AlipayApiException e) { + log.error("alipay notifyUrl error", e); + return "failure"; + } + } +} diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/controller/WxPayController.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/controller/WxPayController.java index 8f25179..f5b8271 100644 --- a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/controller/WxPayController.java +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/controller/WxPayController.java @@ -1,6 +1,5 @@ package org.wfc.payment.pay.wxpay.controller; -import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.google.zxing.BarcodeFormat; @@ -28,41 +27,33 @@ import com.ijpay.wxpay.model.UnifiedOrderModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.multipart.MultipartFile; -import org.wfc.common.core.domain.R; +import org.springframework.web.bind.annotation.RestController; import org.wfc.payment.domain.H5SceneInfo; import org.wfc.payment.domain.WxPayBean; import org.wfc.payment.domain.vo.AjaxResult; -import org.wfc.payment.utils.MultipartFileUtil; -import org.wfc.system.api.RemoteFileService; -import org.wfc.system.api.domain.SysFile; -import org.wfc.user.api.RemoteUUserService; -import org.wfc.user.api.domain.vo.UOrderVo; +import org.wfc.payment.pay.wxpay.service.IWxPayService; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** - *

微信支付 Demo

+ *

微信支付

* * @author cyc */ -@Controller +@RestController @RequestMapping("/wxPay") public class WxPayController extends AbstractWxPayApiController { private final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -71,10 +62,7 @@ public class WxPayController extends AbstractWxPayApiController { private WxPayBean wxPayBean; @Autowired - private RemoteUUserService remoteUUserService; - - @Autowired - private RemoteFileService remoteFileService; + private IWxPayService wxPayService; private String notifyUrl; private String refundNotifyUrl; @@ -373,76 +361,8 @@ public class WxPayController extends AbstractWxPayApiController { @ResponseBody public AjaxResult scanCode2(HttpServletRequest request, HttpServletResponse response, @RequestParam("orderId") Long orderId) { - R orderRes = remoteUUserService.getOrderById(orderId); - UOrderVo orderVo = orderRes.getData(); - if (orderVo == null) { - return new AjaxResult().addError("订单不能为空"); - } - - String totalFee = orderVo.getOrderAmount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).toString(); -// String totalFee = "0.01"; - if (StrUtil.isBlank(totalFee)) { - return new AjaxResult().addError("支付金额不能为空"); - } - - String ip = IpKit.getRealIp(request); - if (StrUtil.isBlank(ip)) { - ip = "127.0.0.1"; - } - WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); - - Map params = UnifiedOrderModel - .builder() - .appid(wxPayApiConfig.getAppId()) - .mch_id(wxPayApiConfig.getMchId()) - .nonce_str(WxPayKit.generateStr()) - .body("WANFI PAY") - .out_trade_no(WxPayKit.generateStr()) - .total_fee(totalFee) - .spbill_create_ip(ip) - .notify_url(notifyUrl) - .trade_type(TradeType.NATIVE.getTradeType()) - .build() - .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256); - - String xmlResult = WxPayApi.pushOrder(false, params); - log.info("统一下单:" + xmlResult); - - Map result = WxPayKit.xmlToMap(xmlResult); - - String returnCode = result.get("return_code"); - String returnMsg = result.get("return_msg"); - System.out.println(returnMsg); - if (!WxPayKit.codeIsOk(returnCode)) { - return new AjaxResult().addError("error:" + returnMsg); - } - String resultCode = result.get("result_code"); - if (!WxPayKit.codeIsOk(resultCode)) { - return new AjaxResult().addError("error:" + returnMsg); - } - //生成预付订单success - - String qrCodeUrl = result.get("code_url"); - String name = "payQRCode2.png"; - - String basePath = System.getProperty("user.dir") + File.separator + name; -// String url = fileBean.getDomain() + fileBean.getPrefix() + File.separator + orderId + File.separator + name; - FileUtil.mkdir(basePath); - - boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200, - basePath); - File uploadFile = new File(basePath); - MultipartFile multipartFile = MultipartFileUtil.getMultipartFile(uploadFile); - R fileResult = remoteFileService.upload(multipartFile); - String url = fileResult.getData().getUrl(); - log.info("qr code file: {}", basePath); - FileUtil.del(uploadFile); - - if (encode) { - //在页面上显示 - return new AjaxResult().success(url); - } - return null; + String url = wxPayService.scanCode2(request, orderId, notifyUrl); + return new AjaxResult().success(url); } /** @@ -973,26 +893,6 @@ public class WxPayController extends AbstractWxPayApiController { @RequestMapping(value = "/callback", method = {RequestMethod.POST, RequestMethod.GET}) @ResponseBody public String payNotify(HttpServletRequest request) { - String xmlMsg = HttpKit.readData(request); - log.info("支付通知=" + xmlMsg); - Map params = WxPayKit.xmlToMap(xmlMsg); - - String returnCode = params.get("return_code"); - - // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态 - // 注意此处签名方式需与统一下单的签名类型一致 - if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) { - if (WxPayKit.codeIsOk(returnCode)) { - // 更新订单信息 - // 发送通知等 - Map xml = new HashMap(2); - String outTradeNo = params.get("out_trade_no"); - remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner"); - xml.put("return_code", "SUCCESS"); - xml.put("return_msg", "OK"); - return WxPayKit.toXml(xml); - } - } - return null; + return wxPayService.payNotify(request); } } diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/IWxPayService.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/IWxPayService.java new file mode 100644 index 0000000..4a16f0f --- /dev/null +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/IWxPayService.java @@ -0,0 +1,15 @@ +package org.wfc.payment.pay.wxpay.service; + +import javax.servlet.http.HttpServletRequest; + +/** + * @description: 微信支付Service + * @author: cyc + * @since: 2025-03-21 + */ +public interface IWxPayService { + + String scanCode2(HttpServletRequest request, Long orderId, String notifyUrl); + + String payNotify(HttpServletRequest request); +} diff --git a/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/impl/WxPayServiceImpl.java b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/impl/WxPayServiceImpl.java new file mode 100644 index 0000000..fc879b6 --- /dev/null +++ b/wfc-modules/wfc-payment/src/main/java/org/wfc/payment/pay/wxpay/service/impl/WxPayServiceImpl.java @@ -0,0 +1,151 @@ +package org.wfc.payment.pay.wxpay.service.impl; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.StrUtil; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import com.ijpay.core.enums.SignType; +import com.ijpay.core.enums.TradeType; +import com.ijpay.core.kit.HttpKit; +import com.ijpay.core.kit.IpKit; +import com.ijpay.core.kit.QrCodeKit; +import com.ijpay.core.kit.WxPayKit; +import com.ijpay.wxpay.WxPayApi; +import com.ijpay.wxpay.WxPayApiConfig; +import com.ijpay.wxpay.WxPayApiConfigKit; +import com.ijpay.wxpay.model.UnifiedOrderModel; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import org.wfc.common.core.domain.R; +import org.wfc.common.core.exception.ServiceException; +import org.wfc.payment.pay.wxpay.service.IWxPayService; +import org.wfc.payment.utils.MultipartFileUtil; +import org.wfc.system.api.RemoteFileService; +import org.wfc.system.api.domain.SysFile; +import org.wfc.user.api.RemoteUUserService; +import org.wfc.user.api.domain.vo.UOrderVo; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.HashMap; +import java.util.Map; + +/** + * @description: 微信支付ServiceImpl + * @author: cyc + * @since: 2025-03-21 + */ +@Service +@Slf4j +public class WxPayServiceImpl implements IWxPayService { + + @Resource + private RemoteUUserService remoteUUserService; + + @Resource + private RemoteFileService remoteFileService; + + @Override + public String scanCode2(HttpServletRequest request, Long orderId, String notifyUrl) { + R orderRes = remoteUUserService.getOrderById(orderId); + UOrderVo orderVo = orderRes.getData(); + if (orderVo == null) { + throw new ServiceException("payment.pay.error"); + } + + String totalFee = orderVo.getOrderAmount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP).toString(); + if (StrUtil.isBlank(totalFee)) { + throw new ServiceException("payment.pay.error"); + } + + String ip = IpKit.getRealIp(request); + if (StrUtil.isBlank(ip)) { + ip = "127.0.0.1"; + } + WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig(); + + Map params = UnifiedOrderModel + .builder() + .appid(wxPayApiConfig.getAppId()) + .mch_id(wxPayApiConfig.getMchId()) + .nonce_str(WxPayKit.generateStr()) + .body("WANFI PAY") + .out_trade_no(WxPayKit.generateStr()) + .total_fee(totalFee) + .spbill_create_ip(ip) + .notify_url(notifyUrl) + .trade_type(TradeType.NATIVE.getTradeType()) + .build() + .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256); + + String xmlResult = WxPayApi.pushOrder(false, params); + log.info("统一下单:" + xmlResult); + + Map result = WxPayKit.xmlToMap(xmlResult); + + String returnCode = result.get("return_code"); + String returnMsg = result.get("return_msg"); + System.out.println(returnMsg); + if (!WxPayKit.codeIsOk(returnCode)) { + log.error("error:{}", returnMsg); + throw new ServiceException("payment.pay.error"); + } + String resultCode = result.get("result_code"); + if (!WxPayKit.codeIsOk(resultCode)) { + log.error("error:{}", returnMsg); + throw new ServiceException("payment.pay.error"); + } + //生成预付订单success + + String qrCodeUrl = result.get("code_url"); + String name = "payQRCode2.png"; + + String basePath = System.getProperty("user.dir") + File.separator + name; +// String url = fileBean.getDomain() + fileBean.getPrefix() + File.separator + orderId + File.separator + name; + FileUtil.mkdir(basePath); + + boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200, + basePath); + File uploadFile = new File(basePath); + MultipartFile multipartFile = MultipartFileUtil.getMultipartFile(uploadFile); + R fileResult = remoteFileService.upload(multipartFile); + String url = fileResult.getData().getUrl(); + log.info("qr code file: {}", basePath); + FileUtil.del(uploadFile); + + if (encode) { + //在页面上显示 + return url; + } + throw new ServiceException("payment.pay.error"); + } + + @Override + public String payNotify(HttpServletRequest request) { + String xmlMsg = HttpKit.readData(request); + log.info("支付通知=" + xmlMsg); + Map params = WxPayKit.xmlToMap(xmlMsg); + + String returnCode = params.get("return_code"); + + // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态 + // 注意此处签名方式需与统一下单的签名类型一致 + if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) { + if (WxPayKit.codeIsOk(returnCode)) { + // 更新订单信息 + // 发送通知等 + Map xml = new HashMap(2); + String outTradeNo = params.get("out_trade_no"); + remoteUUserService.paySuccess(Long.valueOf(outTradeNo), "inner"); + xml.put("return_code", "SUCCESS"); + xml.put("return_msg", "OK"); + return WxPayKit.toXml(xml); + } + } + return null; + } +}