feat:支付宝付款码支付

This commit is contained in:
dzc committed 2025-06-19 12:10:54 +08:00
1 parent b517ae0a06
commit 8689937409
11 files changed
+444 -5

No files matched your search

@@ -0,0 +1,42 @@
package com.bsd.pjcloud.hard.api.dto.ali;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 付款码支付入参
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AliMicropayDto {
/**
* 商户id
*/
private Long merId;
/**
* 订单id
*/
private Long orderId;
/**
* 订单支付金额(分)
*/
private Integer price;
/**
* 订单标题
*/
private String subject;
/**
* 支付授权码
*/
private String authCode;
}
@@ -0,0 +1,24 @@
package com.bsd.pjcloud.hard.api.dto.ali;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AliQueryDto {
/**
* 订单id
*/
private String orderId;
/**
* 阿里订单id
*/
private String aliOrderId;
}
@@ -0,0 +1,37 @@
package com.bsd.pjcloud.hard.api.dto.ali;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 支付宝退款入参
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AliRefundDto {
/**
* 退款金额(分)
*/
private Integer refundPrice;
/**
* 订单id
*/
private Long orderId;
/**
* 支付宝订单id
*/
private String aliOrderId;
/**
* 退款id
*/
private Long refundId;
}
@@ -0,0 +1,22 @@
package com.bsd.pjcloud.hard.api.dto.ali;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 支付宝退款查询入参
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AliRefundQueryDto {
/**
* 退款单号
*/
private Long refundId;
}
@@ -0,0 +1,25 @@
package com.bsd.pjcloud.hard.api.dto.ali;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 支付宝订单撤销入参
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AliReverseDto {
/**
* 订单id
*/
private Long orderId;
/**
* 阿里订单id
*/
private String aliOrderId;
}
@@ -160,6 +160,11 @@
<version>2.12.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.251.ALL</version>
</dependency>
</dependencies>
<profiles>
<profile>
@@ -0,0 +1,30 @@
package com.bsd.pjcloud.hard.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 支付宝支付配置
*/
@Component
@ConfigurationProperties(prefix = "ali-pay")
@Data
public class AlipayConf {
/**
* 应用ID
*/
private String appId;
/**
* 私钥
*/
private String privateKey;
/**
* 公钥
*/
private String alipayPublicKey;
}
@@ -0,0 +1,42 @@
package com.bsd.pjcloud.hard.service;
import com.alipay.api.response.*;
import com.bsd.pjcloud.hard.api.dto.ali.*;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.RequestHeader;
import java.util.Map;
public interface AlipayService {
/**
* 付款码支付
*/
AlipayTradePayResponse micropay(AliMicropayDto dto);
/**
* 查询订单
*/
AlipayTradeQueryResponse query(AliQueryDto dto);
/**
* 撤销订单
*/
AlipayTradeCancelResponse reverse(AliReverseDto dto);
/**
* 申请退款
*/
AlipayTradeRefundResponse refund(AliRefundDto dto);
/**
* 查询退款
*/
AlipayTradeFastpayRefundQueryResponse refundQuery(AliRefundQueryDto dto);
/**
* 退款回调
*/
String refundCallback(HttpEntity<String> httpEntity, @RequestHeader Map<String, String> headers);
}
@@ -0,0 +1,197 @@
package com.bsd.pjcloud.hard.service.impl.ali;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.bsd.pjcloud.hard.api.dto.ali.*;
import com.bsd.pjcloud.hard.config.AlipayConf;
import com.bsd.pjcloud.hard.service.AlipayService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
/**
* 支付宝支付
*/
@Service
@AllArgsConstructor
@Slf4j
public class AlipayServiceImpl implements AlipayService {
private final AlipayConf conf;
static private AlipayClient client = null;
private void initClient() {
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(conf.getAppId());
alipayConfig.setPrivateKey(conf.getPrivateKey());
alipayConfig.setFormat("json");
alipayConfig.setCharset("UTF-8");
alipayConfig.setAlipayPublicKey(conf.getAlipayPublicKey());
alipayConfig.setSignType("RSA2");
try {
AlipayServiceImpl.client = new DefaultAlipayClient(alipayConfig);
} catch (Exception e) {
log.error("初始化支付宝客户端异常", e);
}
}
private AlipayClient getClient() {
if (ObjectUtil.isEmpty(AlipayServiceImpl.client)) initClient();
return AlipayServiceImpl.client;
}
/**
* 付款码支付
*/
public AlipayTradePayResponse micropay(AliMicropayDto dto) {
AlipayClient alipayClient = getClient();
AlipayTradePayRequest request = new AlipayTradePayRequest();
AlipayTradePayModel model = new AlipayTradePayModel();
BigDecimal payPrice = BigDecimal.valueOf(dto.getPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
// 订单号
model.setOutTradeNo(String.valueOf(dto.getOrderId()));
// 支付金额单位元
model.setTotalAmount(payPrice.toString());
// 订单标题
model.setSubject(dto.getSubject());
// 支付授权码
model.setAuthCode(dto.getAuthCode());
// 支付场景
model.setScene("bar_code");
request.setBizModel(model);
try {
AlipayTradePayResponse response = alipayClient.execute(request);
String body = response.getBody();
log.debug("申请退款,json|{}", body);
return response;
} catch (Exception e) {
log.error("支付宝支付异常", e);
return null;
}
}
/**
* 查询订单
*/
@Override
public AlipayTradeQueryResponse query(AliQueryDto dto) {
AlipayClient alipayClient = getClient();
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
// 订单号
model.setOutTradeNo(dto.getOrderId());
// 支付宝订单号
model.setTradeNo(dto.getAliOrderId());
request.setBizModel(model);
try {
AlipayTradeQueryResponse response = alipayClient.execute(request);
String body = response.getBody();
log.debug("查询订单,json|{}", body);
return response;
} catch (Exception e) {
log.error("查询订单异常", e);
}
return null;
}
/**
* 撤销订单
*/
@Override
public AlipayTradeCancelResponse reverse(AliReverseDto dto) {
AlipayClient alipayClient = getClient();
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
AlipayTradeCancelModel model = new AlipayTradeCancelModel();
// 订单号
model.setOutTradeNo(String.valueOf(dto.getOrderId()));
// 支付宝订单号
model.setTradeNo(dto.getAliOrderId());
request.setBizModel(model);
try {
AlipayTradeCancelResponse response = alipayClient.execute(request);
String body = response.getBody();
log.debug("撤销订单,json|{}", body);
return response;
} catch (Exception e) {
log.error("撤销订单", e);
}
return null;
}
/**
* 申请退款
*/
@Override
public AlipayTradeRefundResponse refund(AliRefundDto dto) {
AlipayClient alipayClient = getClient();
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
BigDecimal refundPrice = BigDecimal.valueOf(dto.getRefundPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
// 退款金额(元)
model.setRefundAmount(String.valueOf(refundPrice));
// 订单号
model.setOutTradeNo(String.valueOf(dto.getOrderId()));
// 支付宝订单id
model.setTradeNo(dto.getAliOrderId());
// 退款单号
model.setOutRequestNo(String.valueOf(dto.getRefundId()));
request.setBizModel(model);
try {
AlipayTradeRefundResponse response = alipayClient.execute(request);
String body = response.getBody();
log.debug("申请退款,json|{}", body);
return response;
} catch (Exception e) {
log.error("申请退款", e);
}
return null;
}
/**
* 查询退款
*/
@Override
public AlipayTradeFastpayRefundQueryResponse refundQuery(AliRefundQueryDto dto) {
AlipayClient alipayClient = getClient();
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
AlipayTradeFastpayRefundQueryModel model = new AlipayTradeFastpayRefundQueryModel();
// 退款单号
model.setOutRequestNo(String.valueOf(dto.getRefundId()));
request.setBizModel(model);
try {
AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
String body = response.getBody();
log.debug("查询退款,json|{}", body);
return response;
} catch (Exception e) {
log.error("查询退款", e);
}
return null;
}
/**
* 退款回调
*/
@Override
public String refundCallback(HttpEntity<String> httpEntity, Map<String, String> headers) {
AlipayClient alipayClient = getClient();
try {
} catch (Exception e) {
log.error("退款回调", e);
}
return "";
}
}
@@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.response.AlipayTradePayResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -27,6 +28,8 @@ import com.bsd.pjcloud.hard.api.constant.HardTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderTypeEnum;
import com.bsd.pjcloud.hard.api.constant.order.HardPayTypeEnum;
import com.bsd.pjcloud.hard.api.dto.ali.AliMicropayDto;
import com.bsd.pjcloud.hard.api.dto.ali.AliReverseDto;
import com.bsd.pjcloud.hard.api.dto.manager.HardManagerDto;
import com.bsd.pjcloud.hard.api.dto.hard.HandCancelCodeDto;
import com.bsd.pjcloud.hard.api.dto.hard.HardCreateOrderDto;
@@ -36,7 +39,6 @@ import com.bsd.pjcloud.hard.api.dto.order.app.HardAppCreateOrderDto;
import com.bsd.pjcloud.hard.api.dto.spu.DeductionSpuStockDto;
import com.bsd.pjcloud.hard.api.dto.wechat.WechantReverseDto;
import com.bsd.pjcloud.hard.api.dto.wechat.WechatMicropayDto;
import com.bsd.pjcloud.hard.api.dto.wechat.WechatRefundDto;
import com.bsd.pjcloud.hard.api.entity.HardApptEntity;
import com.bsd.pjcloud.hard.api.entity.manager.HardManagerEntity;
import com.bsd.pjcloud.hard.api.entity.order.HardCarEntity;
@@ -48,9 +50,7 @@ import com.bsd.pjcloud.hard.api.vo.HardDoorFlowVo;
import com.bsd.pjcloud.hard.api.vo.manager.HardManagerVo;
import com.bsd.pjcloud.hard.api.vo.order.HardCarVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechantReverseVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechatMicropayVo;
import com.bsd.pjcloud.hard.api.vo.wechat.WechatRefundVo;
import com.bsd.pjcloud.hard.mapper.manager.HardManagerMapper;
import com.bsd.pjcloud.hard.mapper.order.HardOrderMapper;
import com.bsd.pjcloud.hard.service.*;
@@ -112,6 +112,7 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
private final HardSpuService hardSpuService;
private final HardApptService hardApptService;
private final WechatPayService wechatPayService;
private final AlipayService alipayService;
private final RemoteMchService remoteMchService;
private final RemoteCodeUseService remoteCodeUseService;
@@ -323,10 +324,19 @@ public class HardOrderServiceImpl extends ServiceImpl<HardOrderMapper, HardOrder
}
// 支付宝支付
if (isAliPay) {
throw new RuntimeException("支付宝支付失败,暂不支持");
AliMicropayDto wechatPayDto = AliMicropayDto.builder().merId(orderObj.getMerchantId()).orderId(orderObj.getId()).price(payPrice).authCode(String.valueOf(dto.getOrderSourceTypeId())).build();
AlipayTradePayResponse micropay = alipayService.micropay(wechatPayDto);
boolean success = micropay.isSuccess();
if (!success) {
// 如果支付宝支付订单返回不明确(不是支付成功)直接撤销支付
alipayService.reverse(AliReverseDto.builder().orderId(orderObj.getId()).build());
throw new RuntimeException(micropay.getSubMsg());
} else {
getSelf().orderSuccess(orderObj, Boolean.TRUE);
}
}
// 发送mq消息
getSelf().createOrderAfterSendMqMsg(orderObj.getId(), userDetail);
// getSelf().createOrderAfterSendMqMsg(orderObj.getId(), userDetail);
return orderObj.getId();
}
@@ -33,3 +33,8 @@ spring:
# refund-callback-url: https://rj4jv5rwqs.by.takin.cc/hard/hard-wechant-pay/callback/refund
# merchant-serial-path: /Users/dengzhangchen/Desktop/backups/pay/cert/apiclient_cert.p12
# spbill-create-ip: 59.202.170.152
ali-pay:
app-id: 2021005157648588
private-key: MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCJYA4MxEy5rmAJwUw1A7Izxr7EyF0Q1iKZ7mFqzC6skLysXPGNbC2LDE1dPi0580YFjE2E+e9T7FlU4cZH3oAUw8UpQ4Eh/MRVnsW6rTKO+kYB2bvMyehIS9/I/eg3PjBWtjG6a2a9kP1ijcKP4E90Yxc7W6yoCxF7XeWp0Qvw/sxhqglEfJZlms5L/FIpY1uMNuPeQCkTo5/mk13rB9L0R2p36EJkiPNwGpv8yiUoIAfGNYiqLcelccukZVmLhEBNSGBAdVnoz/bYzzRwHJyw63/bGsw7Rz3debm73Izs5dWEWDHGaz7dA3bNaOgMGsq47DGsbbaUNfZ5V+QBqytPAgMBAAECggEANAhc6fsEMKRanfdIHSBsQ+44XaKilXj2HCXNYj06RISB4itGFtHtoigjuXiOes+pKvrMddyRCNGRuHPXvWsKSlMof4uhArWRy/haXm2xo7QqBhNpbZTgVVnfxmpdpWb5ui5CQaDihlS/lK+rDQHiNmw95W7Aw9mFYpvbHGogwsPAzBew33x/3XPm9mAJodEi+Uw5JG3IDlVeNeXL+E6ZkO6iCfURwORPmTZDHLACoO/EM3zOd2IiH0buY/sosw3LYyALFeQi8uzjevIw7cbQnXGHTSmb+zwmlJYVCaJA04JYN8CtAdmpTl00J7lNLNA3QiFN42GTdGTyf3xADTiI4QKBgQDRU7+riJfMXmHuXomBiD9qK9eQZfTqwrT8LLYgGPohLfP42YeFydGUsC2RWhNKAr//fE2dpo+SoUJ6HligkG5vup2/cyLEyROKQhgegp+GzHjVh8hkDjoZSZk8bs/Kv3X7s2heQdEedQHzZTCSfkhMYxAiU3a8Wdsnw01tDh1qPwKBgQCoAVbBnRsC6lEy5zgs0apgDR+oxb7WRvnK6ao8E5jesVY/z58U93iMaQzvtXZLFYJ3U4nIAoIhPffWfYE+CYIOPDqLSi4Teni8VKdES5ubpkeR4wY+a5FGcCAKycW/pztcQ7YjQLcDAOwL69cik1iSgQtytNQMiKro5tWYN2Ba8QKBgAqMxQE5LiVfsGHaI+YCXufT89ZUPSbDz2lSO4+ckqavcTdeh0UH6ecrhfBocMZvIwwWULccWOoT9IzBEMhu3xIEfsTSYbM3SyPRtvN6s92QWpqwcDoSuXzix7VTBGf8hE6+OQlfGdIGJaYFuI/5i11GNN72A+r0QGZdon5XksXzAoGAeT3WHQ1Ck/0DMif4uydnu79czJBAIyS/WXb9OjOuS29Q3eX4WMoqfbHF+ytKPe884t4vfV6KCHFO7MRPw7Ra3ekLGsAitj3Y6ZhxyXCC0HXUCmz6cYtxIJMEHKT2B1QpG3Fl/NTT/d/peMTu0W3iKn/kAhiLOqxaIo+LLzkvWRECgYBtl1uraKNnnS3kuVPNWDyyuDBJHutYSlvZ5n2825Nvjm2yoInAo++YbRIAmIOw7r4OpJdUZdGi1Agm/+c1Dg19Qoi+PxfHY04J5bUb4UNyODsyNGKHYHKoksl14lyUnYAih5i5xa+WO+Ss2f0HaAJ+i6Eja121yGFVIKWK2OmxNg==
alipay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiWAODMRMua5gCcFMNQOyM8a+xMhdENYime5haswurJC8rFzxjWwtiwxNXT4tOfNGBYxNhPnvU+xZVOHGR96AFMPFKUOBIfzEVZ7Fuq0yjvpGAdm7zMnoSEvfyP3oNz4wVrYxumtmvZD9Yo3Cj+BPdGMXO1usqAsRe13lqdEL8P7MYaoJRHyWZZrOS/xSKWNbjDbj3kApE6Of5pNd6wfS9Edqd+hCZIjzcBqb/MolKCAHxjWIqi3HpXHLpGVZi4RATUhgQHVZ6M/22M80cBycsOt/2xrMO0c93Xm5u9yM7OXVhFgxxms+3QN2zWjoDBrKuOwxrG22lDX2eVfkAasrTwIDAQAB