本文主要是介绍alipay 证书 java_Java 支付宝使用公钥证书加签 进行支付-查询-退款-转账,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
1、引入相关依赖 pom.xml
com.alipay.sdk
alipay-sdk-java
4.9.79.ALL
commons-configuration
commons-configuration
1.10
com.google.zxing
core
3.2.1
2、配置文件 application.yml
[注意] 证书文件必须放到服务器上,放到项目里的证书,在win环境下可以根据路径找到,但打成jar包后就找不到项目里的证书文件了,解决办法是判断服务器环境,根据不同环境拼接证书路径
证书文件目录结构如下,在Linux服务器上部署时,将pay文件夹和jar包放到同一个文件夹下
# 支付
pay:
alipay:
gatewayUrl: https://openapi.alipay.com/gateway.do
appid: *****
appPrivateKey:
alipayPublicKey:
appCertPath: /pay/alipay/cert/appCertPublicKey****.crt
alipayCertPath: /pay/alipay/cert/alipayCertPublicKey_RSA2.crt
alipayRootCertPath: /pay/alipay/cert/alipayRootCert.crt
returnUrl: ****
notifyUrl: ****
3、读取配置文件
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import javax.annotation.PostConstruct;
@Data
@Slf4j
@ConfigurationProperties(prefix = "pay.alipay")
public class AlipayProperties {
/**
* 支付宝gatewayUrl
*/
private String gatewayUrl;
/**
* 商户应用id
*/
private String appid;
/**
* RSA私钥,用于对商户请求报文加签
*/
private String appPrivateKey;
/**
* 支付宝RSA公钥,用于验签支付宝应答
*/
private String alipayPublicKey;
/**
* 签名类型
*/
private String signType = "RSA2";
/**
* 格式
*/
private String formate = "json";
/**
* 编码
*/
private String charset = "UTF-8";
/**
* 同步地址
*/
private String returnUrl;
/**
* 异步地址
*/
private String notifyUrl;
/**
* 应用公钥证书
*/
private String appCertPath;
/**
* 支付宝公钥证书
*/
private String alipayCertPath;
/**
* 支付宝根证书
*/
private String alipayRootCertPath;
/**
* 最大查询次数
*/
private static int maxQueryRetry = 5;
/**
* 查询间隔(毫秒)
*/
private static long queryDuration = 5000;
/**
* 最大撤销次数
*/
private static int maxCancelRetry = 3;
/**
* 撤销间隔(毫秒)
*/
private static long cancelDuration = 3000;
private AlipayProperties() {
}
/**
* PostContruct是spring框架的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法。
*/
@PostConstruct
public void init() {
log.info(description());
}
public String description() {
StringBuilder sb = new StringBuilder("\n支付宝Configs{");
sb.append("支付宝网关: ").append(gatewayUrl).append("\n");
sb.append(", appid: ").append(appid).append("\n");
sb.append(", 商户RSA私钥: ").append(getKeyDescription(appPrivateKey)).append("\n");
sb.append(", 应用公钥证书: ").append(appCertPath).append("\n");
sb.append(", 支付宝公钥证书: ").append(alipayCertPath).append("\n");
sb.append(", 支付宝根证书: ").append(alipayRootCertPath).append("\n");
sb.append(", 支付宝RSA公钥: ").append(getKeyDescription(alipayPublicKey)).append("\n");
sb.append(", 签名类型: ").append(signType).append("\n");
sb.append(", 查询重试次数: ").append(maxQueryRetry).append("\n");
sb.append(", 查询间隔(毫秒): ").append(queryDuration).append("\n");
sb.append(", 撤销尝试次数: ").append(maxCancelRetry).append("\n");
sb.append(", 撤销重试间隔(毫秒): ").append(cancelDuration).append("\n");
sb.append("}");
return sb.toString();
}
private String getKeyDescription(String key) {
int showLength = 6;
if (StringUtils.isNotEmpty(key) && key.length() > showLength) {
return new StringBuilder(key.substring(0, showLength)).append("******")
.append(key.substring(key.length() - showLength)).toString();
}
return null;
}
}
4、在启动时初始化支付宝客户端
import com.alipay.api.AlipayApiException;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import java.io.IOException;
@Configuration
@Slf4j
@EnableConfigurationProperties(AlipayProperties.class)
public class AlipayConfiguration {
@Autowired
private AlipayProperties properties;
// /**
// * 支付宝接口加签模式为公钥时使用
// *
// * @return
// */
// @Bean
// public AlipayClient alipayClient() {
// return new DefaultAlipayClient(properties.getGatewayUrl(),
// properties.getAppid(),
// properties.getAppPrivateKey(),
// properties.getFormate(),
// properties.getCharset(),
// properties.getAlipayPublicKey(),
// properties.getSignType());
// }
/**
* 支付宝接口加签模式为公钥证书时使用
*
* @return
*/
@Bean
public DefaultAlipayClient alipayClient() throws AlipayApiException, IOException {
log.info("---------创建支付宝客户端--------");
//判断系统环境
String osName = System.getProperty("os.name");
log.info("-------系统环境--------" + osName);
String serverpath = null;
if (osName.startsWith("Windows")) {
// windows
serverpath = ResourceUtils.getURL("classpath:").getPath();
serverpath += "static/app";
log.info("-------------win文件路径----------" + serverpath);
// } else if (osName.startsWith("Mac OS")) {
// // 苹果
} else {
// unix or linux
serverpath = System.getProperty("user.dir");
log.info("-------------unix or linux文件路径----------" + serverpath);
}
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl(properties.getGatewayUrl());
certAlipayRequest.setAppId(properties.getAppid());
certAlipayRequest.setFormat(properties.getFormate());
certAlipayRequest.setPrivateKey(properties.getAppPrivateKey());
certAlipayRequest.setCharset(properties.getCharset());
certAlipayRequest.setSignType(properties.getSignType());
certAlipayRequest.setCertPath(serverpath + properties.getAppCertPath());
certAlipayRequest.setAlipayPublicCertPath(serverpath + properties.getAlipayCertPath());
certAlipayRequest.setRootCertPath(serverpath + properties.getAlipayRootCertPath());
return new DefaultAlipayClient(certAlipayRequest);
}
}
5、APP支付
import cn.hutool.core.date.DateUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayFundTransPayModel;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
/**
* app支付
*/
@Slf4j
@Controller
@RequestMapping("/app/alipay/app")
public class AlipayAppPayController {
@Autowired
private AlipayProperties alipayProperties;
@Autowired
private AlipayClient alipayClient;
@Autowired
private AlipayProperties aliPayProperties;
/**
* 去支付
*
*
* @param response
* @throws Exception
*/
@RequestMapping("/createOrder")
public void createOrder(HttpServletRequest request, HttpServletResponse response,
@RequestBody Map mapParams) throws AlipayApiException {
BaseResault resPo = new BaseResault();
// 订单模型
String productCode = "QUICK_MSECURITY_PAY";
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
Order bean = orderService.getOrderByNum(mapParams.get("orderNum"));
model.setOutTradeNo(bean.getOrderNum());
log.info("----订单编号----" + model.getOutTradeNo());
model.setSubject(bean.getShopName());
log.info("----subject----" + model.getSubject());
model.setTotalAmount(bean.getTotalMoney().toString());
log.info("----金额----" + model.getTotalAmount());
model.setTimeoutExpress("30m");
model.setProductCode(productCode);
AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
appPayRequest.setNotifyUrl(‘服务器域名’ + alipayProperties.getNotifyUrl());
log.info("----notifyUrl----" + appPayRequest.getNotifyUrl());
appPayRequest.setBizModel(model);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayResponse ali_response = alipayClient.sdkExecute(appPayRequest); //这里和使用公钥加签支付使用的方法不同
//就是orderString 可以直接给客户端请求,无需再做处理。
log.info("---------支付宝返回---------{}", ali_response.getBody());
resPo.setObj(ali_response.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SUCCESS.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SUCCESS.getMessage());
ResponseJsonUtils.json(response, resPo);
}
}
6、查询订单
/**
* 订单查询(最主要用于查询订单的支付状态)
*
* @param orderNo 商户订单号
* @return
*/
@GetMapping("/query")
public void query(HttpServletRequest request, HttpServletResponse response, String orderNo) throws AlipayApiException {
BaseResault resPo = new BaseResault();
AlipayTradeQueryRequest aliRequest = new AlipayTradeQueryRequest();
AlipayTradeQueryModel bizModel = new AlipayTradeQueryModel();
bizModel.setTradeNo(orderNo);
aliRequest.setBizModel(bizModel);
AlipayTradeQueryResponse aliResponse = alipayClient.certificateExecute(aliRequest);
if (aliResponse.isSuccess()) {
log.info("查询支付宝支付状态-----调用成功{}", aliResponse.getBody());
if (aliResponse.getTradeStatus().equals("TRADE_SUCCESS") || aliResponse.getTradeStatus().equals("TRADE_FINISHED")) {
//订单编号
String orderNum = aliResponse.getOutTradeNo();
// 处理业务
resPo.setObj(aliResponse.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SUCCESS.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SUCCESS.getMessage());
ResponseJsonUtils.json(response, resPo);
return;
} else {
log.error("支付宝订单" + orderNo + "交易失败,交易状态:" + aliResponse.getTradeStatus());
resPo.setObj(aliResponse.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getMessage());
ResponseJsonUtils.json(response, resPo);
return;
}
} else {
log.info("查询支付宝支付状态------调用失败{}", aliResponse.getBody());
resPo.setObj(aliResponse.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getMessage());
ResponseJsonUtils.json(response, resPo);
return;
}
}
7、转账给用户
/**
* alipay.fund.trans.uni.transfer(单笔转账接口)
*
文档地址
* https://docs.open.alipay.com/api_28/alipay.fund.trans.uni.transfer/
*
* @param response
* @throws Exception
*/
@RequestMapping("/alipayToUser")
public void alipayToUser(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException {
BaseResault resPo = new BaseResault();
//转账金额 不能少于0.1元
String money = request.getParameter("money");
//支付宝账号,支持邮箱、电话号码
String phone = request.getParameter("phone");
//支付宝账户名称
String name = request.getParameter("name");
// 订单模型
AlipayFundTransPayModel model = new AlipayFundTransPayModel();
//商户端的唯一订单号
String orderNum = UUID.randomUUID().toString().replace("-", "");
log.info("============支付宝转账给用户-订单号:" + orderNum + "==============");
model.setOutBizNo(orderNum);
//订单总金额,单位为元,精确到小数点后两位
model.setTransAmount(money);
//业务产品码,
//收发现金红包固定为:STD_RED_PACKET;
//单笔无密转账到支付宝账户固定为:TRANS_ACCOUNT_NO_PWD;
//单笔无密转账到银行卡固定为:TRANS_BANKCARD_NO_PWD
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
//收款方信息
Participant participant = new Participant();
//参与方的唯一标识
participant.setIdentity(phone);
//参与方的标识类型,目前支持如下类型:
//1、ALIPAY_USER_ID 支付宝的会员ID
//2、ALIPAY_LOGON_ID:支付宝登录号,支持邮箱和手机号格式
participant.setIdentityType("ALIPAY_LOGON_ID");
//参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。当identity_type=ALIPAY_LOGON_ID时,本字段必填。
participant.setName(name);
model.setPayeeInfo(participant);
//业务备注
model.setRemark("转账测试");
model.setBizScene("DIRECT_TRANSFER");
AlipayFundTransUniTransferRequest appPayRequest = new AlipayFundTransUniTransferRequest();
appPayRequest.setBizModel(model);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.fund.trans.uni.transfer(单笔转账接口)
AlipayFundTransUniTransferResponse ali_response = alipayClient.certificateExecute(appPayRequest);
if (ali_response.isSuccess()) {
log.info("========支付宝转账给用户-调用成功=======" + ali_response.getBody());
resPo.setObj(ali_response.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SUCCESS.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SUCCESS.getMessage());
ResponseJsonUtils.json(response, resPo);
} else {
log.info("========支付宝转账给用户-调用失败=======" + ali_response.getBody());
resPo.setObj(ali_response.getBody());
resPo.setCode(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getCode());
resPo.setMessage(ConstantApp.AppTokenValidResult.SYSTEM_ERROR.getMessage());
ResponseJsonUtils.json(response, resPo);
}
}
8、异步通知
/**
* 证书支付异步通知
* https://docs.open.alipay.com/194/103296
*/
@RequestMapping("/notify")
public String notify(HttpServletRequest request) {
log.info("-----------支付异步通知----------------");
Map requestParams = request.getParameterMap();
log.info(">>>支付宝回调参数:" + requestParams);
Map params = new HashMap<>();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
log.info(">>>支付宝回调参数解析:" + params);
try {
String alipayCertPath = System.getProperty("user.dir") + aliPayProperties.getAlipayCertPath();
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
boolean flag = AlipaySignature.rsaCertCheckV1(
params,
alipayCertPath,
aliPayProperties.getCharset(),
aliPayProperties.getSignType());
if (flag) {
log.info(">>>支付宝回调签名认证成功");
//商户订单号
String out_trade_no = params.get("out_trade_no");
//交易状态
String trade_status = params.get("trade_status");
//交易金额
String amount = params.get("total_amount");
//商户app_id
String app_id = params.get("app_id");
if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) {
/**
* 自己的业务处理,一定要判断是否已经处理过订单
*/
log.info("-----------^v^支付成功^v^------------");
}
} else {
log.error("没有处理支付宝回调业务,支付宝交易状态:{},params:{}", trade_status, params);
}
} else {
log.info("支付宝回调签名认证失败,signVerified=false, params:{}", params);
return "failure";
}
} catch (Exception e) {
log.error(e.getMessage(), e);
log.info("支付宝回调签名认证失败,signVerified=false, params:{}", params);
return "failure";
}
return "success";
}
9、退款
/**
* 同一订单多次退款
*
* @param orderNo 商户订单号
* @return
*/
@Override
public String multipleRefunds(String orderNo, String refundAmount, String refundReason) throws AlipayApiException {
log.info("------------支付宝退款开始--------------");
AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
// 商户订单号
model.setOutTradeNo(orderNo);
// 退款金额 单位元
model.setRefundAmount(refundAmount);
// 退款原因
model.setRefundReason(refundReason);
// 退款订单号(同一个订单可以分多次部分退款,当分多次时必传)
model.setOutRequestNo(UUID.randomUUID().toString());
log.info("------退款参数-----{}-----{}-----{}------{}", orderNo, refundAmount, refundReason, model.getOutRequestNo());
alipayRequest.setBizModel(model);
AlipayTradeRefundResponse alipayResponse = alipayClient.certificateExecute(alipayRequest);
log.info("--------支付宝退款结果---------" + alipayResponse.getBody() + "---------订单号--" + orderNo);
return alipayResponse.getBody();
}
这篇关于alipay 证书 java_Java 支付宝使用公钥证书加签 进行支付-查询-退款-转账的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!