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

相关文章

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Java Spring ApplicationEvent 代码示例解析

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、... 目录一、Spring 事件机制核心概念1. 事件驱动架构模型2. 核心组件二、代码示例解析1. 事件定义

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

python使用库爬取m3u8文件的示例

《python使用库爬取m3u8文件的示例》本文主要介绍了python使用库爬取m3u8文件的示例,可以使用requests、m3u8、ffmpeg等库,实现获取、解析、下载视频片段并合并等步骤,具有... 目录一、准备工作二、获取m3u8文件内容三、解析m3u8文件四、下载视频片段五、合并视频片段六、错误

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的