登录支付宝开放平台
https://open.alipay.com/platform/manageHome.htm
进入开发者中心,选择沙箱(这里用沙箱测试)
配置沙箱环境
下载沙箱版支付宝,登录沙箱账号
开始代码
pom.xml
<!-- 支付宝 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.8.10.ALL</version>
</dependency>
<!-- 谷歌生成二维码 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
AlipayConfig.java
package com.feifei.taotao.util;
/**
* @author xupf@wangreat.com
* @create 2019-11-08 16:53
*/
public class AlipayConfig {
// 商户appid
public static String APPID = "APPID";
// 私钥 pkcs8格式的
public static String RSA_PRIVATE_KEY = "应用私钥"; // 应用私钥";
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://localhost:8002/taotao/restapi/pay/noticUrl";
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
public static String return_url = "http://localhost:8004/views/pay/success.html";
// 请求网关地址
public static String URL = "https://openapi.alipaydev.com/gateway.do";
// 编码
public static String CHARSET = "UTF-8";
// 返回格式
public static String FORMAT = "json";
// 支付宝公钥
public static String ALIPAY_PUBLIC_KEY = "支付宝公钥,一定是支付宝公钥,别填错了";
// 日志记录目录
public static String log_path = "/log";
// RSA2
public static String SIGNTYPE = "RSA2";
// 是否成功
public static String SUCCESS = "SUCCESS";
// 消息
public static String MSG = "MSG";
// 结果
public static String RESULT = "RESULT";
}
AlipayHelper.java
package com.feifei.taotao.util;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 支付宝当面付帮助类
*/
public class AlipayHelper {
private static Logger logger = LoggerFactory.getLogger(AlipayHelper.class);
private static AlipayClient alipayClient;
static {
alipayClient = new DefaultAlipayClient(AlipayConfig.URL,
AlipayConfig.APPID,
AlipayConfig.RSA_PRIVATE_KEY,
AlipayConfig.FORMAT,
AlipayConfig.CHARSET,
AlipayConfig.ALIPAY_PUBLIC_KEY,
AlipayConfig.SIGNTYPE);
}
/**
* 测试支付宝支付接口使用
* @return
* @throws AlipayApiException
*/
public static Map<String, Object> pay() throws AlipayApiException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String format = sdf.format(new Date());
String outTradeNo = format + "-" + (int)((Math.random()*9+1)*100000);
logger.debug("outTradeNo:" + outTradeNo);
String json = "{" +
"\"out_trade_no\":\"" + outTradeNo + "\"," + // 商户网站唯一订单号
"\"subject\":\"测试支付\"," + // 商品的标题/交易标题/订单标题/订单关键字等。
"\"total_amount\":\"0.01\"," + // 订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
"\"store_id\":\"2088102179841180\"," +
"\"timeout_express\":\"90m\"}";
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
request.setNotifyUrl(AlipayConfig.notify_url);
request.setReturnUrl(AlipayConfig.return_url);
request.setBizContent(json);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
logger.info("response.getBody():" + response.getBody());
Map<String, Object> resultMap = new HashMap<>();
if (response.isSuccess()) {
logger.info("预下单成功");
logger.debug("qrCode:" + response.getQrCode() + ",outTradeNo:" + response.getOutTradeNo());
resultMap.put(AlipayConfig.SUCCESS, true);
resultMap.put(AlipayConfig.MSG, "预下单成功");
resultMap.put(AlipayConfig.RESULT, response.getQrCode());
resultMap.put("outTradeNo", outTradeNo);
return resultMap;
} else {
logger.info("支付失败");
resultMap.put(AlipayConfig.SUCCESS, false);
resultMap.put(AlipayConfig.MSG, "预下单失败");
return resultMap;
}
}
/**
* 预下单,返回二维码生成地址,供用户扫描支付
* 入参:
* out_trade_no:商户订单号,需要保证不重复;
* total_amount:订单金额;
* subject:订单标题;
* store_id:商户门店编号;
* timeout_express:交易超时时间;
* 出参:
* qr_code:订单二维码(有效时间 2 小时)以字符串的格式返回,开发者需要自己使用工具根据内容生成二维码图片;
* @param json 入参
* @return
* @throws AlipayApiException
*/
public static Map<String, Object> payTrade(String json) throws AlipayApiException {
Map<String, Object> resultMap = new HashMap<>();
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
// 设置成功回调的地址
request.setNotifyUrl(AlipayConfig.notify_url);
request.setBizContent(json);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
logger.info("response.getBody():" + response.getBody());
if (response.isSuccess()) {
logger.info("预下单成功");
logger.debug("qrCode:" + response.getQrCode() + ",outTradeNo:" + response.getOutTradeNo());
resultMap.put(AlipayConfig.SUCCESS, true);
resultMap.put(AlipayConfig.MSG, "支付成功");
resultMap.put(AlipayConfig.RESULT, response.getQrCode());
return resultMap;
} else {
logger.info("预下单失败");
resultMap.put(AlipayConfig.SUCCESS, false);
resultMap.put(AlipayConfig.MSG, "支付失败");
return resultMap;
}
}
/**
* 查询交易
* 入参:out_trade_no:支付时传入的商户订单号,与 trade_no 必填一个;
* trade_no:支付时返回的支付宝交易号,与 out_trade_no 必填一个;
* 出参:
* trade_no:支付宝 28 位交易号;
* out_trade_no:支付时传入的商户订单号;
* trade_status:交易当前状态
* @param json 入参
* @throws AlipayApiException
*/
public static void queryTrade(String json) throws AlipayApiException {
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();//创建API对应的request类
request.setBizContent(json);
AlipayTradeQueryResponse response = alipayClient.execute(request);//通过alipayClient调用API,获得对应的response类
logger.info("body:" + response.getBody());
if (response.isSuccess()) {
logger.debug("查询成功");
} else {
logger.debug("查询失败");
}
}
/**
* 撤销交易
* 入参:
* out_trade_no:支付时传入的商户订单号,与 trade_no 必填一个;
* trade_no:支付时返回的支付宝交易号,与 out_trade_no 必填一个;
* 出参:
* retry_flag:是否需要重试,Y/N;
* action:本次撤销触发的交易动作 close:关闭交易,无退款 refund:产生了退款;
* @param json 入参
* @throws AlipayApiException
*/
public static void cancelTrade(String json) throws AlipayApiException {
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();//创建API对应的request类
request.setBizContent(json); //设置业务参数
AlipayTradeCancelResponse response = alipayClient.execute(request);//通过alipayClient调用API,获得对应的response类
logger.info("body:" + response.getBody());
if (response.isSuccess()) {
logger.debug("查询成功");
} else {
logger.debug("查询失败");
}
}
/**
* pc支付
* @param response
* @param model
* @throws AlipayApiException
* @throws IOException
*/
public static void pcPay(HttpServletResponse response, AlipayTradePayModel model) throws AlipayApiException, IOException {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(AlipayConfig.notify_url);
request.setReturnUrl(AlipayConfig.return_url);
request.setBizModel(model);
String form = alipayClient.pageExecute(request).getBody();
logger.info("form:{}" + form);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(form);//直接将完整的表单html输出到页面
response.getWriter().flush();
response.getWriter().close();
}
}
生成验证码
package com.feifei.taotao.util;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.HashMap;
/**
* 二维码生成与解析帮助类
*/
public class QRCodeHelper {
private static final int WIDTH = 300;
private static final int HEIGHT = 300;
/**
* 生成二维码,存放到本地路径中
* @param content
*/
public static void setQR(String content){
// 定义二维码的配置,使用HashMap
HashMap hints = new HashMap();
// 字符集,内容使用的编码
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 容错等级,H、L、M、Q
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
// 边距,二维码距离边的空白宽度
hints.put(EncodeHintType.MARGIN, 2);
try {
// 生成二维码对象,传入参数:内容、码的类型、宽高、配置
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
// 定义一个路径对象
Path file = new File("D:/project/taotao_project/erweima").toPath();
// 生成二维码,传入二维码对象、生成图片的格式、生成的路径
MatrixToImageWriter.writeToPath(bitMatrix, "png", file);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成二维码
* @param content
* @param request
* @param response
*/
public static void setQRUp (String content, HttpServletRequest request, HttpServletResponse response) {
// 定义二维码的配置,使用HashMap
HashMap hints = new HashMap();
// 字符集,内容使用的编码
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 容错等级,H、L、M、Q
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
// 边距,二维码距离边的空白宽度
hints.put(EncodeHintType.MARGIN, 2);
try {
// 生成二维码对象,传入参数:内容、码的类型、宽高、配置
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, WIDTH, HEIGHT, hints);
OutputStream outputStream = response.getOutputStream();
// 生成二维码,传入二维码对象、生成图片的格式、生成的路径
MatrixToImageWriter.writeToStream(bitMatrix, "jpeg", outputStream);
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
前端得到form后的处理
w=window.open('about:blank');
w.document.write(datas);
w.document.close();
w.print();
之后用沙箱版支付宝支付就可以了。