alipay 证书 java_Java 支付宝使用公钥证书加签 进行支付-查询-退款-转账

本文主要是介绍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包放到同一个文件夹下

0e0037ba3160ae6f29cd1af5dc610de9.png

# 支付

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 支付宝使用公钥证书加签 进行支付-查询-退款-转账的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/259399

相关文章

使用Python创建一个功能完整的Windows风格计算器程序

《使用Python创建一个功能完整的Windows风格计算器程序》:本文主要介绍如何使用Python和Tkinter创建一个功能完整的Windows风格计算器程序,包括基本运算、高级科学计算(如三... 目录python实现Windows系统计算器程序(含高级功能)1. 使用Tkinter实现基础计算器2.

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

Git可视化管理工具(SourceTree)使用操作大全经典

《Git可视化管理工具(SourceTree)使用操作大全经典》本文详细介绍了SourceTree作为Git可视化管理工具的常用操作,包括连接远程仓库、添加SSH密钥、克隆仓库、设置默认项目目录、代码... 目录前言:连接Gitee or github,获取代码:在SourceTree中添加SSH密钥:Cl

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

CentOS和Ubuntu系统使用shell脚本创建用户和设置密码

《CentOS和Ubuntu系统使用shell脚本创建用户和设置密码》在Linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设置密码,本文写了一个shell... 在linux系统中,你可以使用useradd命令来创建新用户,使用echo和chpasswd命令来设

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib