上周开始,公司要做支付系统,以前在的公司是已经写好的,直接调用,这个要从头写,因本人水平有限,以下代码可能存在错误,请多多指教.
先说流程,公司做的是app.就拿安卓来举例了.
⒈用户在客户机上点击购买XXX;
⒉安卓端拿着当前的商品信息,请求公司的服务器;
⒊后端收到购买请求,将订单存到数据库,并使用阿里的类库,将这些数据加密,生成一个字符串订单,返回给安卓;
⒋安卓拿到后端生成的加密信息,请求支付宝.等待用户付款;
⒌此时如果支付成功,支付宝会请求公司服务器的一个接口(这个接口在生成订单的时候写在加密的数据中);
⒍公司服务器收到支付宝的请求,将数据解密,验证,做各种判断,确定为真实信息之后,查询数据库里,和当前信息对应的订单,然后将其状态修改为已支付;
⒍安卓端接收到支付宝app交易成功的提示之后,去公司后端服务器查询;
此时不管是否付款成功,一次调用支付宝支付的流程就结束了,下面上代码;
// 这里为了方便理解,不接收请求数据,数据全部写死在了方法里.
@RequestMapping("/aliPay.do")
public void aliPayInfo(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
// 这里先生成一个单号,一个付款金额,我随便生成了;
String outTradeNo = TokenAndUUID.generateUUID();
// 付款单位 : 分
String money = "1";
// 将分,转化为0.01元,多此一举是因为 微信支付采用的是分的格式,需要将格式统一;
DecimalFormat decimalFormat = new DecimalFormat("0.00");
String moneyStr = decimalFormat.format(Double.valueOf(money) / 100) + "";
// 实例化客户端,里面的部分参数,在支付宝的开发者平台获取
AlipayClient alipayClient = new DefaultAlipayClient(URL, APPID, RSA_PRIVATE_KEY, FORMAT, CHARSET,
ALIPAY_PUBLIC_KEY, SIGN_TYPE);
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口为alipay.trade.app.pay
AlipayTradeAppPayRequest requestR = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("uuid购买XXX元服务" );// 这里是自定义的,ali会原样返回
model.setSubject("充值" + moneyStr + "元到XXXXX");//这一行,用户是能看到的;
model.setOutTradeNo(outTradeNo);// 单号
model.setTimeoutExpress("30m");// 30分钟过期
model.setTotalAmount("0.01"); //扣款的金额,支付宝会让用户付0.01元
model.setProductCode("QUICK_MSECURITY_PAY"); // 如果是app支付,这里不需要改,是ali定义的支付类型
requestR.setBizModel(model);
//如果支付成功了,支付宝会请求这个接口,这是我们公司的服务器外网地址,接口aliPayRet
requestR.setNotifyUrl("https://www.xxxxx.net/aliPayRet");// 下面有回调的接口详解
// 这里使用阿里提供的方法将订单生成并加密
AlipayTradeAppPayResponse response1 = alipayClient.sdkExecute(requestR);
String orderStr = response1.getBody(); // 拿到订单.返回给前端
response.getWriter().print(orderStr);
}
//--------------------------------以上就是订单的生成,下面是回调接口--------------------
2019.03.13
整个支付,微信+支付宝,大约用了一周多, 其实早就写好了,但是我们老板说暂时 实现功能就行,先把项目进度向前推进,所以我们的支付系统,相当于只能支付,以及支付的订单信息,其他的都 没做,到现在都没做…今天就把回调的功能代码 补一下吧
@RequestMapping("/aliPayRet") // 这个映射对应的是上文下订单的时候写入的,requestR.setNotifyUrl("https://www.xxxxx.net/aliPayRet");
public void aliPayRet(HttpServletRequest request, HttpServletResponse resp) throws AlipayApiException, IOException {
Map<String, String> params = new HashMap<String, String>();
Map requestParams = request.getParameterMap();
for (Iterator 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] + ",";
}
params.put(name, valueStr);
}
// 切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
boolean flag = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, "RSA2");
String ret = "failure"; // 给阿里返回这个值,就表示你接受到的数据是不正确的,他会继续给你发该条支付的状态;
if (flag) {
ret = "success"; //给阿里返回这个值,就表示你接受到的数据是正确的,表示支付已完成,阿里就不会重复给你发送该条支付的状态了
// 到了这里,其实已经确定了,回调的信息是真实的,储存就可以了
// 因为这里都是业务逻辑代码,就不拿上来了.
// System.out.println(request.getQueryString()); // 用这行代码看一下支付宝的回调参数,自己组合一下就可以了
}
resp.getWriter().print(ret);
}
maven 引入
<dependency>
<groupId>com.alipay.sdkgroupId>
<artifactId>alipay-sdk-javaartifactId>
<version>3.4.27.ALLversion>
dependency>