@TOC
1、环境配置
-
访问支付宝开放平台链接:https://open.alipay.com
-
点击 登录 或 立即入驻, 打开手机支付宝扫描登录
-
如果第一次进入, 需要选择入驻身份. 否则, 选择 进入我的开发平台
-
注册成功后, 点击 开发者中心
-
点击 研发服务
-
设置密钥
-
点击 设置
设置之后就可以查看
-
选择 公钥, 并下载 支付宝密钥生成器
保存之后会是一个exe文件
-
安装并使用 支付宝密钥生成器.
-
将生成的应用公钥复制到支付宝窗口中
- 设置 应用网关
开发环境网关链接为:https://openapi.alipaydev.com/gateway.do
应用环境网关链接为:https://openapi.alipay.com/gateway.do
- 扫码下载 支付宝沙箱钱包
下载完安装一下
关于沙箱账号
账号不能修改,但是可以充值取现
相关说明文档和应用案例
2、代码实操
配置接口
package com.util;
/**
* 支付宝配置参数
*/
public class AlipayConfig {
//应用的APPID
public static final String APP_ID = "2016102300747343";
//应用私钥
public static final String APP_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC0ct4VcwFoLn2WfcbD9OVRqsxZMoH0o3occjSFVF1JgxenidV9s5gJZqMOeFMkIM29LEJGOi2+ZjBAA0D6ug4939HklrXyJQxW05nCzH4wdAZ5ZjbhFXu3tEOuqWnS4UZTnze2koXk405jTDTfcO0P3kpojMgGZ5tw/G2umpvEVFh1xP0IIGBFTRgGMtXMEyAhpK/5cCUX0i7v4LNI/OAEF5fhnly0et3PALmhtliUsRIfL2rdrq0VsRxdNkPy1Jpl03g7rPUS/c8Dd0/5qOlAK4iSTAbrFpaI2qW3jvLelSvO30bIQ9hSTISqnxcunCzNg5wH+6kDXV1aOsjkEkZNAgMBAAECggEBAKitj6ghPzlx6/fXTwwySoLS0/61VgGnJyicIThZKnLjViNIlwbP8Nko1ldaZu2otGmXi8Q18ji/MW9FG2LEtTdll8DEmQPnWed4GY2ctoD4lGy6/aXd/S42FeaZetCjwKe+d8f0o7DYQphTzkDoQNHKi2e74ecKxqURcj37TIxycSWlnlaoVxxID8VimKzbNLR3d5B2Woy8dFd4SKTHWMrLLReKtFIRY2QabGy2/P0CR/pgkZpFsLiya/lSl6n98rAqrFxv5DlU2KjsgzPaa0cItum6H5lpRz89KUaHcKpI+Syoosfpwx4JDlembq41AhAd+Xafa34lDUqvpoMFawkCgYEA5X/db/s+BabaLtKBqh5tedIj5EQ4ct8uQmkWszg+iYXmzJ+01wubq/V/I5mNCcsG2gjYbLC2ZcBr/J8+Ja+0obXMX7VoHha1HhpZ2rh00TFNX4lr5Y3BRbAzxSKNRZPrbCQ0heBgDWqqwxQk96wGDgR05IrDwP+/tVAJ3RdDj28CgYEAyUkIp8BkoeO2GNedjiHq8aN0NYovVZtScRPYWYUn4xmGKrKZDEE0wNDhyZ5GETwEE0cjImbw0/J6onJhlhk/MUBBrhQA4+Jpse5iP5soR7ClFjp03TGrdm+2eomnbVlmIUrunoD9S6dWJvqFoUqxQ7Iqf73m8Bsl/tNeuUrl6AMCgYBrhSxJenvkSfeOWDFHcln36OvH1e5cYxNZKcLo1ED4TTOESo5+8YFNXwbhtt7M58GeBObghSnvIed1w2VqYpdN686ESIkvD5RrNg1C24hfOan2SHu0YGVcMOEQSs/E+TgiwhOZZTWbE45NNvLa1k0/4/af3CM6GJfIamc0neGZIQKBgF2LFHupXNsjkUgARFd+icpclTAglRjqwyiL+Xq4+C2BeimzsI7SaurE6HmjlZqC0r4GzFw7jOZjBP0jvRhdiVGhNCTrZPKDEW3AhGZc/B49CKvI5PC7GZ1EE4DlIiseZelJApYlChIzpUUeHiY0KSd10GxnW8DwTPsdTiM8nJXzAoGAA8P56i43ZgD5mQ1kefSiS2zhdtz1mG3GuPwcwghT8LJNyTRLvtcmb3Tzc4d16r77JHyJagJYxg9rxsXsiSJ4Aq2awlEZNgfGGy0HTrwjv8fis9lHsCanmQXFLTVw3vcX6baYzWaZ/VOQJjWLgMv7OQLvbOOAP8A4vkPiIOHt0Eg=";
//支付宝公钥
public static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxXDQpVl3hzQvSaCOq0dnR/WYPD8455/X0Wt5nmeed/m1eGAOHGvHIkwLl8xruAYR2SIYZZ+OI6pEuLEUzUCOSNfs+KLO+T+pYL//y3NaKzmzQiTAbD7LfMYMXwtYoud+dxYPn7Fl9zCpIuaOE/sQXEOgEMwBvvjGyxUV6X7jjrTYRV9udtbTy4sN2BAQkFuzgM/R/UDWCrmEGGHi0ve9EW3xNbLQM5PJ33Som9DGNqSjT5cZa3Ignc7fRax5IF8ScPPobPZPvFGbayMYkKhliJiKwE+Rv8JMP46ERqpTjEFyECn1FwfiW6PtjZK3perxiFPJsCkIVZXTZVqd3XeZeQIDAQAB";
//网关. 这是沙箱接口路径,正式路径为https://openapi.alipay.com/gateway.do
public static final String GATEWAY_URL ="https://openapi.alipaydev.com/gateway.do";
//字符集
public static final String CHARSET = "UTF-8";
//参数格式
public static final String FORMAT = "JSON";
//签名方式
public static final String SIGN_TYPE = "RSA2";
//支付宝异步通知路径,付款完毕后会异步调用本项目的方法,必须为公网地址. 沙箱环境可以不配置
public static final String NOTIFY_URL = "";
//支付宝同步通知路径,也就是当付款完毕后跳转本项目的页面,可以不是公网地址
public static final String RETURN_URL = "http://127.0.0.1:8080/alipayReturnNotice";
}
应用私钥和应用公钥有对应关系
支付宝公钥
依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com</groupId>
<artifactId>demo-alipay</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-alipay</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.3.49.ALL</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
后台AlipayController .java
三个方法
package com.controller;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.util.AlipayConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
@Controller
public class AlipayController {
@RequestMapping("alipay")
public void alipay(HttpServletResponse httpResponse) throws IOException {
//实例化客户端,填入所需参数
AlipayClient alipayClient = new DefaultAlipayClient
(AlipayConfig.GATEWAY_URL, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY,
AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
//在公共参数中设置回跳和通知地址
request.setReturnUrl(AlipayConfig.RETURN_URL);
request.setNotifyUrl(AlipayConfig.NOTIFY_URL);
//商户订单号,商户网站订单系统中唯一订单号,必填
//生成随机Id
String out_trade_no = UUID.randomUUID().toString();
//付款金额,必填
String total_amount =Integer.toString(999);
//订单名称,必填
String subject ="奥迪A8 2016款 A8L 60 TFSl quattro豪华型";
//商品描述,可空
String body = "尊敬的会员欢迎购买奥迪A8 2016款 A8L 60 TFSl quattro豪华型";
/* 获取页面内容对象 */
// AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
// model.setOutTradeNo(out_trade_no);
// model.setSubject(subject);
// model.setTotalAmount(total_amount);
// model.setTimeoutExpress("15");
//
// model.setBody(body);
// model.setProductCode("FAST_INSTANT_TRADE_PAY");
// request.setBizModel(model);
request.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String form = "";
try {
form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@GetMapping("alipayReturnNotice")
public String alipayReturnNotice(HttpServletRequest request, HttpServletResponse response)
throws IOException, AlipayApiException {
System.out.println("支付成功, 进入同步通知接口...");
// 获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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("utf-8"), "utf-8");
params.put(name, valueStr);
}
//查看参数都有哪些
System.out.println(params);
// 调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE);
//验证签名通过
if(signVerified){
// 商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 付款金额
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
System.out.println("********************** 支付成功(支付宝同步通知) **********************");
System.out.println("* 商户订单号: "+out_trade_no);
System.out.println("* 支付宝交易号: "+trade_no);
System.out.println("* 付款金额: "+total_amount);
System.out.println("*********************************************************************");
}else{
System.out.println("支付, 验签失败...");
}
return "redirect:/ok.html";//跳转付款成功页面
}
@PostMapping("alipayNotifyNotice")
public String alipayNotifyNotice(HttpServletRequest request, HttpServletRequest response) throws Exception {
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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);
}
//调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE);
//——请在这里编写您的程序(以下代码仅作参考)——
/* 实际验证过程建议商户务必添加以下校验:
1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
if(signVerified) {//验证成功
// 商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 付款金额
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
System.out.println("商户订单号="+out_trade_no);
System.out.println("支付宝交易号="+trade_no);
System.out.println("付款金额="+total_amount);
}else{
}
return "suc";
}
}
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/alipay">支付</a>
</body>
</html>
注意事项
开发者界面不要和项目测试支付界面同一个浏览器,重新开一个浏览器,可能会报错
然后用沙箱账号的支付宝去扫码支付,支付成功就会跳转到商家给出的界面