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

相关文章

springboot健康检查监控全过程

《springboot健康检查监控全过程》文章介绍了SpringBoot如何使用Actuator和Micrometer进行健康检查和监控,通过配置和自定义健康指示器,开发者可以实时监控应用组件的状态,... 目录1. 引言重要性2. 配置Spring Boot ActuatorSpring Boot Act

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

使用Python绘制蛇年春节祝福艺术图

《使用Python绘制蛇年春节祝福艺术图》:本文主要介绍如何使用Python的Matplotlib库绘制一幅富有创意的“蛇年有福”艺术图,这幅图结合了数字,蛇形,花朵等装饰,需要的可以参考下... 目录1. 绘图的基本概念2. 准备工作3. 实现代码解析3.1 设置绘图画布3.2 绘制数字“2025”3.3

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2