1.前言
最近有在弄支付宝和微信的支付,现在我们来弄下支付宝的支付
首先注册蚂蚁金服开放平台账号这个就不多说了(个人用的是支付宝账号)
配置好沙箱环境(一般来说沙箱环境跑通,到时候换上线上应用的配置就可以了)
详细过程:https://openclub.alipay.com/read.php?tid=1513&fid=28
2.准备
下载相关的jar(sdk)
https://alipay.open.taobao.com/doc2/detail?treeId=54&articleId=103419&docType=1
maven导包
<dependency>
<groupId>com.alipay</groupId>
<artifactId>sdk-java</artifactId>
<version>20180309170622</version>
</dependency>
3.配置类
public class AlipayConfig {
//网关地址
//public static final String URL = "https://openapi.alipay.com/gateway.do"; //(正式环境)
public static final String URL = "https://openapi.alipaydev.com/gateway.do"; //沙箱(测试环境)
//APPID
public static final String ALIPAY_APPID = "";
//私钥
public static String APP_PRIVATE_KEY = "";
//支付宝公钥
public static String ALIPAY_PUBLIC_KEY = "";
//签名算法类型(根据生成私钥的算法,RSA2或RSA)
public static final String SIGNTYPE = "RSA2";
public static final String FORMAT = "json";//请求数据格式
public static final String CHARSET = "utf-8";//编码集
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static final String OWnotify_url = "";//网站扫码
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
public static final String OWreturn_url = "";//网站扫码
// 统一收单交易创建接口
private static AlipayClient alipayClient = null;
/**获得初始化的AlipayClient
* @return 支付宝客户端
*/
public static AlipayClient getAlipayClient() {
if (alipayClient == null) {
synchronized (AlipayConfig.class) {
if (null == alipayClient) {
alipayClient = new DefaultAlipayClient(URL, ALIPAY_APPID, APP_PRIVATE_KEY, FORMAT, CHARSET,ALIPAY_PUBLIC_KEY,SIGNTYPE);
}
}
}
return alipayClient;
}
}
4.支付宝电脑网站支付
4.1方法一:(返回的是from表单)
// 扫码支付
@ResponseBody
@RequestMapping(value = "/pagePay")
public static String pagePay() {
int money = 100 ;//充值金额
//逻辑
long timeStart = Calendar.getInstance().getTimeInMillis();
String out_trade_no = timeStart+"";// 订单号
// 获得初始化的AlipayClient
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
// 创建API对应的request
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
alipayRequest.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
Map<String, Object> map = new HashMap<String, Object>();
map.put("out_trade_no", out_trade_no );// 订单号
map.put("product_code", "FAST_INSTANT_TRADE_PAY");// 销售产品码
map.put("total_amount", money);// 交易金额,单位:元
map.put("subject", "测试商品");// 订单标题
alipayRequest.setBizContent(JSON.toJSONString(map));
try {
// 调用SDK生成表单
String form = alipayClient.pageExecute(alipayRequest).getBody();
// 就是orderString可以直接给客户端请求,无需再做处理。
System.out.println("---------支付宝扫码---------> " + form);
return form;
} catch (AlipayApiException e) {
e.printStackTrace();
}
}
4.2 方法二: 返回的二维码地址
可以前端生成二维码也可后端生成二维码传输前端,这里我就只生成二维码地址.
public static String alipay() throws AlipayApiException{
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
Map<String,Object> map=new HashMap<String,Object>();
//设置回调地址
request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
//根据订单号查询订单信息
Map<String,Object> maps=new HashMap<String,Object>();
long timeStart = Calendar.getInstance().getTimeInMillis();
String out_trade_no = timeStart ;
maps.put("out_trade_no",out_trade_no);
maps.put("total_amount","0.01");
maps.put("subject","测试商品");
maps.put("timeout_express","5m");
//把订单信息转换为json对象的字符串
String postdata = JSONObject.fromObject(maps).toString();
request.setBizContent(postdata);
AlipayTradePrecreateResponse response = alipayClient.execute(request);
String body = response.getBody();
JSONObject jsonObject = JSONObject.fromObject(body);
String qr_code = jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
map.put("qr_code", qr_code);
return qr_code;
}
5. 手机网站支付
返回一样的是from表单,这样前端直接掉起支付宝
/**
* 封装好参数,前台通过form表单来调起支付宝
* @throws AlipayApiException
* @throws IOException
*/
@RequestMapping("/getContext1")
public String alipayPayChongRequest() throws AlipayApiException{
AlipayClient alipayClient = AlipayConfig.getAlipayClient();
//创建API对应的request类(主要是这里变化了)
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl(AlipayConfig.OWreturn_url);// 回跳地址
request.setNotifyUrl(AlipayConfig.OWnotify_url);// 通知地址
AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
long timeStart = Calendar.getInstance().getTimeInMillis();
model.setOutTradeNo(timeStart +"");
model.setSubject("测试商品");
model.setTotalAmount("0.01");
model.setBody("测试商品");
model.setTimeoutExpress("30m");
model.setProductCode("QUICK_WAP_PAY");
request.setBizModel(model);
String form = alipayClient.pageExecute(request).getBody(); //调用SDK生成表单
System.out.println(form);
return form;
}
6. 回调
支付异步回调(支付成功后,支付宝会调用这个接口)
@RequestMapping(value = "/OWnotify", method = RequestMethod.POST)
public void OWnotify(HttpServletRequest request, HttpServletResponse httpResponse) {
// 获取支付宝POST过来反馈信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
Set<String> keySet = requestParams.keySet();
String out_trade_no = "";
String trade_status = "";
String total_amount = "";
for (String key : keySet) {
StringBuffer buffer = new StringBuffer();
for (String string : requestParams.get(key)) {
buffer.append(string);
}
params.put(key, buffer.toString());
if (key.equals("out_trade_no")) {
out_trade_no = buffer.toString();// 商户订单号
System.out.println(key + " : " + buffer.toString());
} else if (key.equals("trade_status")) {
trade_status = buffer.toString();// 交易状态
System.out.println(key + " : " + buffer.toString());
} else if (key.equals("total_amount")) {
total_amount = buffer.toString().substring(0,buffer.toString().length()-3) + "";// 充值金额
System.out.println(key + " : " + total_amount);
}
}
System.out.println("支付异步回调");
try {
// 计算得出通知验证结果
boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY,
AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
if (verify_result) {// 验证成功
if (trade_status.equals("TRADE_SUCCESS")) { // 交易支付成功
//逻辑
httpResponse.getWriter().println("success");
}
} else {// 验证失败
httpResponse.getWriter().println("fail");
}
} catch (Exception e) {
e.printStackTrace();
}
}
有异步当然就有同步啦(同步接口一般用于跳转网页,执行部分逻辑)
注意: 返回的是from表单的才会主动调用(当然需要在配置类中配置啦)
使用request.getParameter能够获取到值或者用实体类
@RequestMapping("/OWreturn")
public ModelAndView OWreturn(HttpServletRequest request) {
ModelAndView mav = new ModelAndView();
System.out.println("支付同步回调");
mav.setViewName("");
return mav;
}
from表单发到前端,前端ajax请求成功后用$('#payFrom').html(from); 就会执行该from表单
好了!大概就是这样吧!