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

相关文章

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

SpringBoot中使用 ThreadLocal 进行多线程上下文管理及注意事项小结

《SpringBoot中使用ThreadLocal进行多线程上下文管理及注意事项小结》本文详细介绍了ThreadLocal的原理、使用场景和示例代码,并在SpringBoot中使用ThreadLo... 目录前言技术积累1.什么是 ThreadLocal2. ThreadLocal 的原理2.1 线程隔离2

springboot将lib和jar分离的操作方法

《springboot将lib和jar分离的操作方法》本文介绍了如何通过优化pom.xml配置来减小SpringBoot项目的jar包大小,主要通过使用spring-boot-maven-plugin... 遇到一个问题,就是每次maven package或者maven install后target中的ja

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装

如何利用Java获取当天的开始和结束时间

《如何利用Java获取当天的开始和结束时间》:本文主要介绍如何使用Java8的LocalDate和LocalDateTime类获取指定日期的开始和结束时间,展示了如何通过这些类进行日期和时间的处... 目录前言1. Java日期时间API概述2. 获取当天的开始和结束时间代码解析运行结果3. 总结前言在J

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH