springboot接入沙箱支付宝的支付流程
首先梳理一下支付流程:
- 用户点击下单按钮
- 商户系统生成订单,并构造支付请求,将请求发送给支付宝
- 在支付宝APP上,支付宝为用户展示相关信息,用户输入密码完成支付
- 支付完毕后将支付结果返回给商户系统(或者商户系统主动查询结果)
- 商户系统侧将订单支付结果展示给用户
粗略使用说明

1.下载支付宝SDK https://opendocs.alipay.com/common/02kkv2?pathHash=358ff034
2.生成二维码使用说明
通过zxing的jar包为一个链接生成专用二维码 使用说明
在生成二维码的时候我们会生成对应的订单,扫描的时候只需要传id参数即可
3.扫码请求的使用示例
@RequestMapping("/alipay")
public void doPost(HttpServletRequest httpRequest,
HttpServletResponse httpResponse) throws IOException, AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);
//获得初始化的AlipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request
alipayRequest.setNotifyUrl(public_network+"/orders/paynotify");//在公共参数中设置回跳和通知地址
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\"202410100010101001\"," +
" \"total_amount\":0.1," +
" \"subject\":\"Iphone6 16G\"," +
" \"product_code\":\"QUICK_WAP_WAY\"" +
" }");//填充业务参数
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面
httpResponse.getWriter().flush();
}
out_trade_no:要求商户系统内唯一
product_code:文档没写,默认是不可改的固定值
4.主动查询支付结果示例(此外包括上述扫码请求时的通知地址,)AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2"); AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); JSONObject bizContent = new JSONObject(); bizContent.put("out_trade_no", "20150320010101001"); //bizContent.put("trade_no", "2014112611001004680073956707"); request.setBizContent(bizContent.toString()); AlipayTradeQueryResponse response = alipayClient.execute(request); if(response.isSuccess()){ System.out.println("调用成功"); } else { System.out.println("调用失败"); }
out_trade_no与trade_no二选一即可查询
回调接口:alipayRequest.setNotifyUrl()中设置回调地址
@PostMapping("/paynotify")
public void paynotify(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, 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);
}
boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");
if (verify_result) {//验证成功
//商户订单号
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 trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
if (trade_status.equals("TRADE_SUCCESS")) {//交易成功
}
response.getWriter().write("success");
} else {
response.getWriter().write("fail");
}
}
实际设计方案:


表结构设计说明:
为什么要设计一个订单明细表:一个订单可能包含多个产品,是一对多的关系
为什么要设计一个支付记录表:在支付宝的使用中,如果我们把orders的id作为out_trade_no,那么如果我们在支付出现异常后,由于同一个out_trade_no不能重复使用而无法继续。因此我们引入记录表:记录表的pay_no作为out_trade_no,这样可以防止支付失败的异常问题。简单来说,out_trade_no在这个设计结构中不论使用结果如何都永远只会使用一次,并且在使用完成后会修改主表order的status
后端支付宝接口使用流程
1.点击支付按钮时,将商品记录填入记录表中,再将商品填入商品订单,根据用户id和商品信息生成二维码,二维码最少提供支付宝支付需要的唯一单号、总价格、商品信息。将二维码的base64返回给前端展示
2.用户扫码后,在支付宝同意支付并由支付宝返回支付信息
3.支付完成后按理来说,我们的表信息应该已经修改。这里就需要我们主动向支付宝发起请求,如果支付已经完成,则修改订单表与支付记录表的状态。
此外我们也可以在扫码下单处增加回调,支付完成并且成功后同样修改订单表和支付记录表的状态

浙公网安备 33010602011771号