一、准备工作
我们先做测试版本的,线上的需要注册商家账号 注册地址 https://openhome.alipay.com/platform/appDaily.htm?tab=info
在这里登上自己支付宝账号就行。
- 设置自己的APPID
- 设置支付宝网关
- 设置RSA2秘钥
可以下载沙箱支付宝,功能跟支付宝差不多,就负责支付功能,里面的金额可以随便充值,可以享受一下千万富翁的感觉。
在沙箱账号里面,有我们商家信息和买家信息,里面的账号密码可用于我们测试账号
二、集成Spring Boot
1.集成pom文件
我做的时候最新版本是3.0.0,应该没啥问题,有最新的可以用最新的,这支付的谁也不知道支付宝会突然出BUG,需要出最新的支付接口
<!-- 支付宝支付 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.0</version>
</dependency>
2.支付宝工具类
我们刚刚配置的APPID和私钥公钥,直接配置上就行,我自己的就先不叫你们看了哈
https://docs.open.alipay.com/api 可以参考支付宝官方文档,里面的接口很详细
public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String APP_ID = "";
// 商户私钥,您的PKCS8格式RSA2私钥,这些就是我们刚才设置的
public static String MERCHANT_PRIVATE_KEY = "";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。,这些就是我们刚才设置的
public static String ALIPAY_PUBLIC_KEY = "";
//异步通知,再这里我们设计自己的后台代码
public static String notify_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";
// 签名方式
public static String SIGN_TYPE = "RSA2";
// 字符编码格式
public static String CHARSET = "utf-8";
// 支付宝网关
public static String GATEWAYURL = "https://openapi.alipay.com/gateway.do";
// 支付宝网关
public static String LOG_PATH = "C:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(LOG_PATH + "alipay_log_" + System.currentTimeMillis()+".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.支付宝整合
service书写
/**
* 支付接口
* @author lcc
* @data :2018年6月4日 上午10:18:39
*/
public interface AlipayService {
/**
* web端订单支付
* @param outTradeNo 订单编号(唯一)
* @param totalAmount 订单价格
* @param subject 商品名称
*/
String webPagePay(String outTradeNo,Integer totalAmount,String subject) throws Exception;
/**
* app端订单支付
* @param outTradeNo 订单编号
* @param totalAmount 订单价格
* @param subject 商品名称
*/
String appPagePay(String outTradeNo,Integer totalAmount,String subject) throws Exception;
/**
* 退款
* @param outTradeNo 订单编号
* @param refundReason 退款原因
* @param refundAmount 退款金额
* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
*/
String refund(String outTradeNo,String refundReason,Integer refundAmount,String outRequestNo) throws AlipayApiException;
/**
* 交易查询
* @param outTradeNo 订单编号(唯一)
*/
String query(String outTradeNo) throws AlipayApiException;
/**
* 交易关闭
* @param outTradeNo订单编号(唯一)
*/
String close(String outTradeNo) throws AlipayApiException;
/**
* 退款查询
* @param outTradeNo 订单编号(唯一)
* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
*/
String refundQuery(String outTradeNo,String outRequestNo) throws AlipayApiException;
}
serviceImpl书写,支付宝返回的From文件,直接返回到前端就行,这是一个直接打开的from文件
/**
* 支付实现类
* @author lcc
* @data :2018年6月4日 上午10:18:07
*/
@Service("alipayService")
public class AlipayServiceImpl implements AlipayService {
/** 调取支付宝接口 web端支付*/
DefaultAlipayClient alipayClient = new DefaultAlipayClient(
AlipayConfig.GATEWAYURL, AlipayConfig.APP_ID, AlipayConfig.MERCHANT_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);
/** 调取支付宝接口app端支付*/
AlipayClient alipayClients = new DefaultAlipayClient(
AlipayConfig.GATEWAYURL, AlipayConfig.APP_ID, AlipayConfig.MERCHANT_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);
@Override
public String webPagePay(String outTradeNo, Integer totalAmount, String subject) throws Exception {
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
/** 同步通知,支付完成后,支付成功页面*/
alipayRequest.setReturnUrl(AlipayConfig.return_url);
/** 异步通知,支付完成后,需要进行的异步处理*/
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
+ "\"total_amount\":\""+ totalAmount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\"商品名称\","
+ "\"timeout_express\":\"90m\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
/**转换格式*/
String result = alipayClient.pageExecute(alipayRequest).getBody().replace('\"','\'').replace('\n',' ');
return result;
}
@Override
public String refund(String outTradeNo,String refundReason,Integer refundAmount,String outRequestNo) throws AlipayApiException {
AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
/** 调取接口*/
alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
+ "\"refund_amount\":\""+ refundAmount +"\","
+ "\"refund_reason\":\""+ refundReason +"\","
+ "\"out_request_no\":\""+ outRequestNo +"\"}");
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
@Override
public String query(String outTradeNo) throws AlipayApiException {
AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();
/**请求接口*/
alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","+"\"trade_no\":\""+ "" +"\"}");
/**转换格式*/
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
@Override
public String close(String outTradeNo) throws AlipayApiException {
AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\"," +"\"trade_no\":\""+ "" +"\"}");
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
@Override
public String refundQuery(String outTradeNo , String outRequestNo) throws AlipayApiException {
AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
/** 请求接口*/
alipayRequest.setBizContent("{\"out_trade_no\":\""+ outTradeNo +"\","
+"\"out_request_no\":\""+ outRequestNo +"\"}");
/** 格式转换*/
String result = alipayClient.execute(alipayRequest).getBody();
return result;
}
@Override
public String appPagePay(String outTradeNo, Integer totalAmount, String subject) throws Exception {
AlipayTradeWapPayRequest alipayRequest=new AlipayTradeWapPayRequest();
/** 同步通知,支付完成后,支付成功页面*/
alipayRequest.setReturnUrl(AlipayConfig.return_url);
/** 异步通知,支付完成后,需要进行的异步处理*/
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
/**销售产品码(固定)*/
String productCode="QUICK_WAP_WAY";
/** 进行赋值 */
AlipayTradeWapPayModel wapPayModel=new AlipayTradeWapPayModel();
wapPayModel.setOutTradeNo(outTradeNo);
wapPayModel.setSubject(subject);
wapPayModel.setTotalAmount(totalAmount.toString());
wapPayModel.setBody("商品名称");
wapPayModel.setTimeoutExpress("2m");
wapPayModel.setProductCode(productCode);
alipayRequest.setBizModel(wapPayModel);
/** 格式转换*/
String result = alipayClients.pageExecute(alipayRequest).getBody().replace('\"','\'').replace('\n',' ');
return result;
}
}
controller书写
/**
* 支付宝
* @author lcc
* @data :2018年6月4日 上午10:55:46
*/
@RestController
public class AlipayController {
@Autowired
@Qualifier("alipayService")
private AlipayService alipayService;
/**
* web 订单支付
*/
@GetMapping("getPagePay")
public Map<Object, Object> getPagePay() throws Exception{
/** 模仿数据库,从后台调数据*/
String outTradeNo = "19960310621211";
Integer totalAmount = 1;
String subject = "苹果28";
String pay = alipayService.webPagePay(outTradeNo, totalAmount, subject);
System.out.println(pay);
Map<Object, Object> pays = new HashMap<>();
pays.put("pay", pay);
return pays;
}
/**
* app 订单支付
*/
@GetMapping("getAppPagePay")
public ResultBO<?> getAppPagePay() throws Exception{
/** 模仿数据库,从后台调数据*/
String outTradeNo = "131233";
Integer totalAmount = 1000;
String subject = "天猫超市012";
String pay = alipayService.appPagePay(outTradeNo, totalAmount, subject);
Object json = JSONObject.toJSON(pay);
System.out.println(json);
return ResultTool.success(json);
}
/**
* 交易查询
*/
@PostMapping("aipayQuery")
public ResultBO<?> alipayQuery() throws Exception{
/**调取支付订单号*/
String outTradeNo = "13123";
String query = alipayService.query(outTradeNo);
Object json = JSONObject.toJSON(query);
/*JSONObject jObject = new JSONObject();
jObject.get(query);*/
return ResultTool.success(json);
}
/**
* 退款
* @throws AlipayApiException
*/
@GetMapping("alipayRefund")
public ResultBO<?> alipayRefund(
@RequestParam("outTradeNo")String outTradeNo,
@RequestParam(value = "outRequestNo", required = false)String outRequestNo,
@RequestParam(value = "refundAmount", required = false)Integer refundAmount
) throws AlipayApiException{
/** 调取数据*/
//String outTradeNo = "15382028806591197";
String refundReason = "用户不想购买";
//refundAmount = 1;
//outRequestNo = "22";
String refund = alipayService.refund(outTradeNo, refundReason, refundAmount, outRequestNo);
System.out.println(refund);
return ResultTool.success(refund);
}
/**
* 退款查询
* @throws AlipayApiException
*/
@PostMapping("refundQuery")
public ResultBO<?> refundQuery() throws AlipayApiException{
/** 调取数据*/
String outTradeNo = "13123";
String outRequestNo = "2";
String refund = alipayService.refundQuery(outTradeNo, outRequestNo);
return ResultTool.success(refund);
}
/**
* 交易关闭
* @throws AlipayApiException
*/
@PostMapping("alipayclose")
public ResultBO<?> alipaycolse() throws AlipayApiException{
/** 调取数据*/
String outTradeNo = "13123";
String close = alipayService.close(outTradeNo);
return ResultTool.success(close);
}
}
为了方便测试这里使用GetMapping请求的,这里订单号可以写个工具类,只能有一个,要是订单号重复,支付失败
http://localhost:8080/aipayQuery
有啥问题,可以交流