1. 分别导入项目依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.17</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.40.272.ALL</version>
</dependency>
2.创建微信支付配置类(WxPayConfig),以及支付宝配置类(AliYunPayConfig)
2.1.WxPayConfig
package com.medical.config;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.RSAPublicKeyConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.io.File;
@Data
@Component
public class WxPayConfig {
private String appId = "wx28ac4252e8c40813";
private String mchId = "1718689836";
private String apiKey;
private String publicKeyId = "PUB_KEY_ID_0117186898362025062500391568000000";
private String privateKeyPath = "/cert/wx/apiclient_key.pem";
private String publicKeyPath = "/cert/wx/pub_key.pem";
private String serialNumber = "701DDAE073165BB8DC17B4B0EC398DEB0F2718C9";
private String apiV3Key = "9de0e123f2124e54a4c08be458d5b44d";
private String notifyUrl = "https://api.doctooi.com/medical-api/service/notify/wxpay";
private String domain = "https://api.mch.weixin.qq.com/v3/pay/";
private String path;
@Bean("config")
public Config getConfig() {
// 获取当前项目路径
if (path == null) {
path = loadPath();
}
// 使用微信支付公钥的RSA配置构建器
return new RSAPublicKeyConfig.Builder()
.merchantId(mchId)
.privateKeyFromPath(path + privateKeyPath)
.publicKeyFromPath(path + publicKeyPath)
.publicKeyId(publicKeyId)
.merchantSerialNumber(serialNumber)
.apiV3Key(apiV3Key)
.build();
}
private String loadPath() {
path = System.getProperty("user.dir") + "/src/main/resources";
File file = new File(path);
if (!file.exists()) {
path = System.getProperty("user.dir") + "/medical-server/src/main/resources";
}
return path;
}
}
2.2 AliYunPayConfig
package com.medical.config;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayAccount;
import lombok.Data;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.io.File;
@Component
@Data
public class AliYunPayConfig {
private String appId = "2021005164622150";
private String privateKey="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnQKma64LQN3VTFLAdx76EE/VuWcRAQZXtH09oeTu9eweCYsCzhcQmuNyl0X+rfXylwMxTkVzkBwWWVooWiggja/dUfErwrQY/L0E5OcRTMW4ZnDghz8lREcZxlAfvi/Q+cC34x3XcTudGN55LkJLZaAMI7vSqLsZSc2GDOUqS2jMgOuZ8c2Uk4grvd7giZCJQStlTF8L05S19OYy55h5bwoFZG+r0m4g2W6Kqnu0oZDIBf9U54E8KOHSGYUKC1EprPSYbllImQoi2tRMEh4RgOWTrnDfSHeYhUpbiBf+C+0vPl2Djf4my94wp0PsEsMUD4hGXNzXKFW7nET8orKM9AgMBAAECggEAQE23J832jHFWFWw1zi1WzVcTHKs8revJZdKM6ED8O/yKRZIMPrlmUfDvPH2QlXF4tA2tQU/5I96jQkrhaosFWAERpZToByKu7SoQ7JyOI+I0T3plhnJqF1Y7Mr3UU0A+1qawth6R7PMVLkUCAlGCdD3uNMgSnz++lkKwMhCb4FuMzQHf4U4/ZdPM+4kYykiCZKQPxJL89SK/nnr2WAzDNshiqyX071Ixr1f/JE92Wm61dhlogUEP1qsHIB1+qvqtO8+eORb/oHFw3LOlfOM9rHCCNSQGb2DTxPq4AIAFRc5S8wdGw+668EIKZO0IgxNtvn/RdGpXIC6b2owRQMY6jQKBgQD0XRGPgSkqe32y3fCs7SiRtMQCWGA1XA5G+D72FZWg2aZkuG8Fk4qNNaNWHl0g9iU41BeimauC8Ib55YhFfgvR8eAeUKhOyfPUO3k2Xp4k8U81bIT7U0HM1TJqZfn9W+bxUj6rts3gmPxvEpOEl6aCb5P4rgpP1hN7QSn9NeISjwKBgQCvN5E0uwmGBGcW0WMTBF7X7cRNoX6xVAoRg5S/Ow5tewB+FiX90jddWxC56AaO9qB4HhuDudLnwiqwbxPy3TTlM2dP3DBxEsJKojj24sMinn3vWaOMpKmIAx8eCO8/eDsliE6KKlongFzi4oQMplKKKr9r90okqkeWbdTZjn9jcwKBgHA8UvV7mIHHqIs//uweHXUW9rQxDTdU6cXU/W4fqdLwRMmcIHoKMyf6i+PhHFsoUx5P4+8t76W7ffNHZpisdRdfpdWmrDdL8K75Bgpf2PkU0JG0HzwkGGPRRE+0OOcSj/clFF3gH51aBw+pE5Jh6Pud7fPZVCkpJVeGLZf8aLKnAoGAKauLawD4WNj/M1wEtecaLzwqrVO077NO2a9zVq9S1RKloVbfHig6ZodbyPq3ZJSewTJX1NICqH9y65bfJakaBVBeR43UL3AIqPs/lOeFBNywkpW84ZvffatQYTI6w9tyJZDvLMi5vB849/Rq9x8vDhDwiVq8VU/xyoLAViUfgqUCgYEAyLM70mV0nG/GaJn/uuKagJbgUMSOK4DlJ01Bsid3yHwnN9mNG0kZAyfGZSKIZtaWbnAXxlldlNwTPkeGFs3iu/TKxJHRbukL5K77lain4iy0m1+1YH+4+SwnHhOloHq2EwEA9Fb/5jCbIaF6kkVcxAmg8MsIyBA/riC5btAxI0k=";
private String certPath="/cert/alipay/appCertPublicKey_2021005164622150.crt";
private String alipayPublicKeyPath="/cert/alipay/alipayCertPublicKey_RSA2.crt";
private String alipayRootCertPath="/cert/alipay/alipayRootCert.crt";
private String serverUrl = "https://openapi.alipay.com/gateway.do";
private String notifyUrl = "http://t85c84dd.natappfree.cc/medical-api/service/notify/alipay";
private String signType = "RSA2";
private String format = "json";
private String charset = "utf-8";
private String path;
@Bean
private AlipayClient alipayClient() throws AlipayApiException {
if(path == null) {
path = loadPath();
}
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl(serverUrl);
certAlipayRequest.setAppId(appId);
certAlipayRequest.setPrivateKey(privateKey);
certAlipayRequest.setFormat(format);
certAlipayRequest.setCharset(charset);
certAlipayRequest.setSignType(signType);
certAlipayRequest.setCertPath(path+certPath);
certAlipayRequest.setAlipayPublicCertPath(path+alipayPublicKeyPath);
certAlipayRequest.setRootCertPath(path+alipayRootCertPath);
return new DefaultAlipayClient(certAlipayRequest);
}
private String loadPath() {
path = System.getProperty("user.dir") + "/src/main/resources";
File file = new File(path);
if (!file.exists()) {
path = System.getProperty("user.dir") + "/medical-server/src/main/resources";
}
return path;
}
}
3.微信App支付实现
@Override
public Map<String, Object> wxAppPay(String outTradeNo) throws ServiceException {
OrderInfo orderInfo = orderService.getBeanByOrderNo(outTradeNo);
if (orderInfo == null) {
throw new ServiceException("订单不存在");
}
BigDecimal payAmount = orderInfo.getPayAmount();
// 将金额转换为分
BigDecimal multiply = payAmount.multiply(new BigDecimal("100"));
// 转换成整型
Integer intValue = multiply.intValue();
Integer number = orderInfo.getNumber();
// 总价
Integer total = intValue * number;
// 订单描述
String packageName = orderInfo.getPackageName();
// 构建service
AppServiceExtension service = new AppServiceExtension.Builder().config(config).build();
// request.setXxx(val)设置所需参数,具体参数可见Request定义
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal(total); // 单位分
amount.setCurrency("CNY");
request.setAmount(amount);
request.setOutTradeNo(outTradeNo);
request.setDescription(packageName);
request.setNotifyUrl(wxPayConfig.getNotifyUrl());
request.setAppid(wxPayConfig.getAppId());
request.setMchid(wxPayConfig.getMchId());
request.setNotifyUrl(wxPayConfig.getNotifyUrl());
// 调用下单方法,得到应答
PrepayWithRequestPaymentResponse paymentResponse = service.prepayWithRequestPayment(request);
// 组装App支付参数信息
Map<String, Object> appPayParams = new HashMap<>();
appPayParams.put("appid", wxPayConfig.getAppId());
appPayParams.put("mchid", wxPayConfig.getMchId());
appPayParams.put("partner", paymentResponse.getPartnerId());
appPayParams.put("prepayid", paymentResponse.getPrepayId());
appPayParams.put("package", "Sign=WXPay");
appPayParams.put("noncestr", paymentResponse.getNonceStr());
appPayParams.put("timestamp", paymentResponse.getTimestamp());
appPayParams.put("sign", paymentResponse.getSign());
return appPayParams;
}
4.支付宝App支付实现
@Override
public Map<String, Object> alipayAppPay(String orderNo) throws ServiceException {
try {
OrderInfo orderInfo = orderService.getBeanByOrderNo(orderNo);
if (orderInfo == null) {
throw new ServiceException("订单不存在");
}
BigDecimal payAmount = orderInfo.getPayAmount();
// 将金额转换为元 1元=100分
Integer number = orderInfo.getNumber();
// 总价
BigDecimal multiply = payAmount.multiply(new BigDecimal(number.toString()));
String total = multiply.toString();
// 订单描述
String packageName = orderInfo.getPackageName();
// 构造请求参数以调用接口
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// 设置商户订单号
model.setOutTradeNo(orderNo);
// 设置订单总金额
model.setTotalAmount(total);
// 设置订单标题
model.setSubject(packageName);
// 设置产品码
model.setProductCode("QUICK_MSECURITY_PAY");
// 设置订单绝对超时时间,格式为yyyy-MM-dd HH:mm:ss 日历类
// model.setTimeExpire("2016-12-31 10:05:00");
request.setBizModel(model);
request.setNotifyUrl(aliYunPayConfig.getNotifyUrl());
// 调用接口,获取支付结果
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderStr = response.getBody();
boolean success = response.isSuccess();
Map<String, Object> map = new HashMap<>();
map.put("orderStr", orderStr);
return map;
} catch (Exception e) {
throw new ServiceException("支付宝支付失败", e);
}
}
5.支付回调通知
package com.medical.service.impl;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.medical.config.AliYunPayConfig;
import com.medical.config.WxPayConfig;
import com.medical.model.OrderInfo;
import com.medical.service.OrderService;
import com.medical.service.PayService;
import com.shiant.rmi.exception.ServiceException;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.service.payments.app.AppServiceExtension;
import com.wechat.pay.java.service.payments.app.model.Amount;
import com.wechat.pay.java.service.payments.app.model.PrepayRequest;
import com.wechat.pay.java.service.payments.app.model.PrepayWithRequestPaymentResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
public class PayServiceImpl implements PayService {
@Autowired
private OrderService orderService;
@Autowired
private Config config;
@Autowired
private WxPayConfig wxPayConfig;
@Autowired
private AlipayClient alipayClient;
@Autowired
private AliYunPayConfig aliYunPayConfig;
@Override
public Map<String, Object> alipayAppPay(String orderNo) throws ServiceException {
try {
OrderInfo orderInfo = orderService.getBeanByOrderNo(orderNo);
if (orderInfo == null) {
throw new ServiceException("订单不存在");
}
BigDecimal payAmount = orderInfo.getPayAmount();
// 将金额转换为元 1元=100分
Integer number = orderInfo.getNumber();
// 总价
BigDecimal multiply = payAmount.multiply(new BigDecimal(number.toString()));
String total = multiply.toString();
// 订单描述
String packageName = orderInfo.getPackageName();
// 构造请求参数以调用接口
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// 设置商户订单号
model.setOutTradeNo(orderNo);
// 设置订单总金额
model.setTotalAmount(total);
// 设置订单标题
model.setSubject(packageName);
// 设置产品码
model.setProductCode("QUICK_MSECURITY_PAY");
// 设置订单绝对超时时间,格式为yyyy-MM-dd HH:mm:ss 日历类
// model.setTimeExpire("2016-12-31 10:05:00");
request.setBizModel(model);
request.setNotifyUrl(aliYunPayConfig.getNotifyUrl());
// 调用接口,获取支付结果
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
String orderStr = response.getBody();
boolean success = response.isSuccess();
Map<String, Object> map = new HashMap<>();
map.put("orderStr", orderStr);
return map;
} catch (Exception e) {
throw new ServiceException("支付宝支付失败", e);
}
}
@Override
public Map<String, Object> wxAppPay(String outTradeNo) throws ServiceException {
OrderInfo orderInfo = orderService.getBeanByOrderNo(outTradeNo);
if (orderInfo == null) {
throw new ServiceException("订单不存在");
}
BigDecimal payAmount = orderInfo.getPayAmount();
// 将金额转换为分
BigDecimal multiply = payAmount.multiply(new BigDecimal("100"));
// 转换成整型
Integer intValue = multiply.intValue();
Integer number = orderInfo.getNumber();
// 总价
Integer total = intValue * number;
// 订单描述
String packageName = orderInfo.getPackageName();
// 构建service
AppServiceExtension service = new AppServiceExtension.Builder().config(config).build();
// request.setXxx(val)设置所需参数,具体参数可见Request定义
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal(total); // 单位分
amount.setCurrency("CNY");
request.setAmount(amount);
request.setOutTradeNo(outTradeNo);
request.setDescription(packageName);
request.setNotifyUrl(wxPayConfig.getNotifyUrl());
request.setAppid(wxPayConfig.getAppId());
request.setMchid(wxPayConfig.getMchId());
request.setNotifyUrl(wxPayConfig.getNotifyUrl());
// 调用下单方法,得到应答
PrepayWithRequestPaymentResponse paymentResponse = service.prepayWithRequestPayment(request);
// 组装App支付参数信息
Map<String, Object> appPayParams = new HashMap<>();
appPayParams.put("appid", wxPayConfig.getAppId());
appPayParams.put("mchid", wxPayConfig.getMchId());
appPayParams.put("partner", paymentResponse.getPartnerId());
appPayParams.put("prepayid", paymentResponse.getPrepayId());
appPayParams.put("package", "Sign=WXPay");
appPayParams.put("noncestr", paymentResponse.getNonceStr());
appPayParams.put("timestamp", paymentResponse.getTimestamp());
appPayParams.put("sign", paymentResponse.getSign());
return appPayParams;
}
}