准备
1.支付宝接口文档地址
2.准备好相对应的证书(普通公钥模式也行,但是B2C打款需要证书,所以在这里我用的是证书模式),文件如下:
3.准备好 appId,应用私钥、支付宝公钥及网关地址
开始
1.加入maven依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.9.124.ALL</version>
</dependency>
2.定义一个创建支付宝客户端的公用方法
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import org.apache.logging.log4j.util.PropertiesUtil;
import org.springframework.util.ResourceUtils;
public class AliPayCreateClient {
/**
* 创建支付宝客户端
*
* @throws Exception
*/
public static AlipayClient createAlipayClient(AlipayClient alipayClient) throws Exception {
if (alipayClient == null) {
//构造client
CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
//设置网关地址
certAlipayRequest.setServerUrl("网关地址");
//设置应用AppId
certAlipayRequest.setAppId("AppId");
//设置应用私钥
certAlipayRequest.setPrivateKey("应用私钥");
certAlipayRequest.setFormat("JSON");
//设置字符集
certAlipayRequest.setCharset("UTF-8");
//设置签名类型
certAlipayRequest.setSignType("RSA2");
if(PropertiesUtil.getSystemProperties().getProperty("os.name").equals("Linux")){
//设置应用公钥证书路径
certAlipayRequest.setCertPath("./aliPay/appCertPublicKey_****.crt");
//设置支付宝公钥证书路径
certAlipayRequest.setAlipayPublicCertPath("./aliPay/alipayCertPublicKey_RSA2.crt");
//设置支付宝根证书路径
certAlipayRequest.setRootCertPath("./aliPay/alipayRootCert.crt");
}else{
//设置应用公钥证书路径
certAlipayRequest.setCertPath(ResourceUtils.getURL("classpath:").getPath() + "/aliPay/appCertPublicKey_****.crt");
//设置支付宝公钥证书路径
certAlipayRequest.setAlipayPublicCertPath(ResourceUtils.getURL("classpath:").getPath() + "/aliPay/alipayCertPublicKey_RSA2.crt");
//设置支付宝根证书路径
certAlipayRequest.setRootCertPath(ResourceUtils.getURL("classpath:").getPath() + "/aliPay/alipayRootCert.crt");
}
alipayClient = new DefaultAlipayClient(certAlipayRequest);
}
return alipayClient;
}
}
3.定义一个请求支付宝的公用方法
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AccessParams;
import com.alipay.api.domain.Participant;
import com.alipay.api.domain.PeriodRuleParams;
import com.alipay.api.domain.SignParams;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class AliPayTool {
/**
* 生成支付宝分享码
* @param alipayClient
* @param url 分享路径
* @param shareCode 分享码
* @return
* @throws Exception
* @return shareCodeUrl 二维码路径 shareCodeUrlText 二维码里面的字符串
*/
public static AjaxResult aliCreateQR(AlipayClient alipayClient,String url, String shareCode) throws Exception {
AlipayOpenAppQrcodeCreateRequest request = new AlipayOpenAppQrcodeCreateRequest();
Map<String, Object> params = new HashMap<String, Object>();
params.put("url_param", url + "?shareCode=" + shareCode);
params.put("query_param", "shareCode=" + shareCode);
params.put("describe", "分享二维码");
Object obj = JSONObject.toJSON(params);
request.setBizContent(obj.toString());
AlipayOpenAppQrcodeCreateResponse response = alipayClient.certificateExecute(request);
Map<String, String> map = new HashMap<>();
map.put("shareCodeUrl", response.getQrCodeUrl());
HttpURLConnection httpUrl = (HttpURLConnection) new URL(response.getQrCodeUrl()).openConnection();
httpUrl.connect();
File pdfFile = FileUtils.inputStreamToFile(httpUrl.getInputStream(), "url.png");
FileInputStream fileInputStream = new FileInputStream(pdfFile);
MultipartFile multipartFile = new MockMultipartFile(pdfFile.getName(), pdfFile.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
BufferedImage image = ImageIO.read(multipartFile.getInputStream());
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
// 定义二维码的参数:
HashMap<DecodeHintType, Object> hints = new HashMap<>();
// 定义字符集
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);
map.put("shareCodeUrlText", result.getText());
if (response.isSuccess()) {
return AjaxResult.success().data(map);
} else {
return AjaxResult.success().data("");
}
}
/**
* 支付宝小程序授权
*
* @param code 前端传过来的授权code
* @return
* @throws AlipayApiException
*/
public static AlipaySystemOauthTokenResponse aliPayAuthorization(AlipayClient alipayClient,String code) throws Exception {
AlipaySystemOauthTokenRequest requestToken = new AlipaySystemOauthTokenRequest();
requestToken.setGrantType("authorization_code");
requestToken.setCode(code);
System.out.println(requestToken.getTextParams());
//request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
AlipaySystemOauthTokenResponse responseToken = alipayClient.certificateExecute(requestToken);
System.out.println(responseToken.getParams());
if (responseToken.isSuccess()) {
return responseToken;
} else {
return null;
}
}
/**
* 支付宝创建订单
*
* @param orderSn 商户订单编号
* @param subject 主体
* @param totalAmount 总额
* @param logUserId 支付宝userId
* @param notifyUrl 第四步创建的回调地址
* @return
* @throws Exception
*/
public static String aliPayTradeCreate(AlipayClient alipayClient,String orderSn, String subject, double totalAmount, String logUserId,String notifyUrl) throws Exception {
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.create.
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
request.setNotifyUrl(notifyUrl);
Map<String, Object> params = new HashMap<String, Object>();
params.put("out_trade_no", orderSn);
params.put("total_amount", totalAmount);
params.put("subject", subject);
params.put("buyer_id", logUserId);
Object obj = JSONObject.toJSON(params);
System.err.println("创建订单成功");
System.out.println(params);
//SDK已经封装掉了公共参数,这里只需要传入业务参数。
request.setBizContent(obj.toString());
AlipayTradeCreateResponse response = alipayClient.certificateExecute(request);
if (response.isSuccess()) {
return response.getTradeNo();// 获取返回的tradeNO。
} else {
return null;
}
}
/**
* 支付宝查找订单
*
* @param outTradeNo 商户支付宝订单号
* @return
* @throws Exception
*/
public static AlipayTradeQueryResponse alipayTradeQuery(AlipayClient alipayClient,String outTradeNo) throws Exception {
Map<String, Object> map = new HashMap<>();
Map<String, Object> params = new HashMap<String, Object>();
params.put("out_trade_no", outTradeNo);//支付宝订单号
Object obj = JSONObject.toJSON(params);
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizContent(obj.toString());
return alipayClient.certificateExecute(request);
}
/**
* 支付宝退款
*
* @param orderSn 商户订单号
* @param moeny
* @throws Exception
*/
public static AlipayTradeRefundResponse alipayTradeRefund(AlipayClient alipayClient,String orderSn, double moeny) throws Exception {
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
Map<String, Object> params = new HashMap<String, Object>();
params.put("out_trade_no", orderSn);
params.put("refund_amount", moeny);
params.put("refund_reason", "正常退款");
Object obj = JSONObject.toJSON(params);
request.setBizContent(obj.toString());
AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
return response;
}
/**
* 支付宝b2c打钱
*
* @param aliPayUserId
* @param titel 标题
* @param money 金额
* @param orderSn 商户订单编号
* @return
* @throws Exception
*/
public static AlipayFundTransUniTransferResponse aliPayB2C(AlipayClient alipayClient,String aliPayUserId, String titel, double money, String orderSn) throws Exception {
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
Participant participant = new Participant();
participant.setIdentity(aliPayUserId);
participant.setIdentityType("ALIPAY_USER_ID");
Map<String, Object> params = new HashMap<String, Object>();
params.put("out_biz_no", orderSn);
params.put("trans_amount", money);
params.put("product_code", "TRANS_ACCOUNT_NO_PWD");
params.put("biz_scene", "DIRECT_TRANSFER");
params.put("order_title", titel);
params.put("payee_info", participant);
Object obj = JSONObject.toJSON(params);
request.setBizContent(obj.toString());
AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
return response;
}
}
4.在controller里面定义一个接口,用于接收支付宝的回调
/**
* 支付宝异步通知
*
* @param response
* @param request
* @throws Exception
*/
@PostMapping(value = "/notifyUrl")
@ResponseBody
public void notifyUrl(HttpServletResponse response, HttpServletRequest request) throws Exception {
PrintWriter out = response.getWriter();
Long startDate = System.currentTimeMillis();
System.out.println("异步通知");
request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
System.out.println();
for (String personkey : request.getParameterMap().keySet()) {
System.out.println(personkey + ", 来自: " + request.getParameterMap().get(personkey));
}
//获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String str : requestParams.keySet()) {
String name = str;
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] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, "你的支付宝公钥", "UTF-8", "RSA2"); //调用SDK验证签名
if (!signVerified) {
System.out.println("验签失败");
out.print("fail");
return;
}
String notifyType = params.get("notify_type");
//付款异步通知
if ("trade_status_sync".equals(notifyType)) {
String outTradeNo = params.get("out_trade_no");
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
if (trade_status.equals("TRADE_SUCCESS")) {
//主动查询
AlipayTradeQueryResponse alipayTradeQueryResponse = aliPayAppService.alipayTradeQueryApp(outTradeNo);
if (alipayTradeQueryResponse.isSuccess()) {
alipayTradeQueryResponse.getTradeStatus();
if (!"TRADE_SUCCESS".equals(alipayTradeQueryResponse.getTradeStatus())) {
return;
}
}
/**
*
*
*你的业务逻辑
*
*
*/
System.out.println(outTradeNo + "支付回调总花费:" + (System.currentTimeMillis() - startDate) + "毫秒;" + DateUtils.parseDateToStr("yyyy-MM-dd", new Date()));
}
}
}