最近研究了一下支付宝的支付流程,其它的倒没感觉出来,唯一的感受就是微信支付和支付宝支付这两个官方文档写的真是无法描述,不好好研究还真看不明白.所以将自己理解的支付宝支付流程描述出来.一来将自己学的东西记录下来,另一方面避免做这方面的朋友们浪费过多的时间.

支付宝调用流程

java的支付宝接口(支付宝支付Java代码)(1)

开发前的准备工作

java的支付宝接口(支付宝支付Java代码)(2)

支付宝支付流程:

开发需要准备的物料

pom.xml添加支付宝依赖

[java] view plain copy

  1. <dependency>
  2. <groupId>commons-logging</groupId>
  3. <artifactId>commons-logging</artifactId>
  4. <version>1.1.1</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>com.alipay</groupId>
  8. <artifactId>alipay-sdk</artifactId>
  9. <version>java20170307171631</version>
  10. </dependency>

支付宝方面的参数

java的支付宝接口(支付宝支付Java代码)(3)

代码展示

商户后台支付接口

[java] view plain copy

  1. /**
  2. * 支付宝支付
  3. * @param req
  4. * @param response
  5. * @throws OperationFailedException
  6. */
  7. @RequestMapping("alipay/Prepay")
  8. @ResponseBody
  9. public void aliPrepay(@RequestBody AliPrepayReq req, HttpServletResponse response) throws OperationFailedException {
  10. Set<ConstraintViolation<AliPrepayReq>> constraintViolationSet = validator.validate(req);
  11. if (constraintViolationSet.size() > 0) {
  12. throw new OperationFailedException(constraintViolationSet.iterator().next().getMessage());
  13. }
  14. LibraOrder libraOrder = libraService.findLibraOrderByHashCode(req.getOutTradeNo());
  15. Product product = productRepository.findOne(Long.valueOf(libraOrder.getProduct().getId()));
  16. if(product == null) { throw new OperationFailedException("该商品不存在"); }
  17. try{
  18. String form = aliPayService.generateAliPay(req);
  19. if(!"err".equals(form)){
  20. response.setContentType("text/html;charset=utf-8");
  21. response.getWriter().write(form);// 直接将完整的表单html输出到页面
  22. response.getWriter().flush();
  23. }
  24. }catch (Exception e){
  25. throw new OperationFailedException("支付失败");
  26. }
  27. }

[java] view plain copy

  1. /**
  2. * 支付宝方面订单号获取
  3. * @param aliPrepayReq
  4. * @return
  5. * @throws OperationFailedException
  6. */
  7. public String generateAliPay(AliPrepayReq aliPrepayReq) throws OperationFailedException {
  8. AlipayClient alipayClient = new DefaultAlipayClient(aliPayUrl,
  9. appId, rsaPrivateKey, "json", "UTF-8", rsaPublicKey, "RSA2"); //获得初始化的AlipayClient
  10. Map<String, String> param = new HashMap<>();
  11. AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
  12. // 封装请求支付信息
  13. AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
  14. model.setOutTradeNo(aliPrepayReq.getOutTradeNo());
  15. model.setSubject(aliPrepayReq.getSubject());
  16. Integer totalAmount = aliPrepayReq.getTotalAmount();
  17. model.setTotalAmount(String.valueOf(totalAmount / 100.0));
  18. model.setBody(aliPrepayReq.getBody());
  19. model.setProductCode(aliPrepayReq.getProductCode());
  20. alipay_request.setBizModel(model);
  21. // 设置异步通知地址
  22. alipay_request.setNotifyUrl(notifyUrl);
  23. // 设置同步地址
  24. alipay_request.setReturnUrl(returnUrl);
  25. String form = "";
  26. try {
  27. LOGGER.info("alipay_request = " jsonService.toJson(alipay_request));
  28. // 调用SDK生成表单
  29. form = alipayClient.pageExecute(alipay_request).getBody();
  30. LOGGER.info("form = " form);
  31. } catch (Exception e) {
  32. throw new OperationFailedException("支付出错");
  33. }
  34. return form;
  35. }

异步回调接口

[java] view plain copy

  1. /**
  2. * 支付宝方面异步回调
  3. * @param request
  4. * @return
  5. * @throws OperationFailedException
  6. */
  7. @RequestMapping("alipay/notifyCallback")
  8. public String AlipayCallBack(HttpServletRequest request) throws OperationFailedException {
  9. //获取支付宝POST过来反馈信息
  10. Map<String,String> params = new HashMap<String,String>();
  11. Map requestParams = request.getParameterMap();
  12. for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
  13. String name = (String) iter.next();
  14. String[] values = (String[]) requestParams.get(name);
  15. String valueStr = "";
  16. for (int i = 0; i < values.length; i ) {
  17. valueStr = (i == values.length - 1) ? valueStr values[i]
  18. : valueStr values[i] ",";
  19. }
  20. //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
  21. //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
  22. params.put(name, valueStr);
  23. }
  24. LOGGER.info("params = " jsonService.toJson(params));
  25. boolean verify_result = aliPayService.rsaCheck(params);
  26. if(verify_result && aliPayService.dealWithAliPayChargeOrder(params)){
  27. return "success";
  28. }
  29. return "false";
  30. }

[java] view plain copy

  1. /**
  2. * 订单验证
  3. * @param params
  4. * @return
  5. */
  6. @Transactional
  7. public boolean dealWithAliPayChargeOrder(Map<String, String> params) {
  8. String outTradeNo = params.get("out_trade_no");
  9. LibraOrder libraOrder = libraOrderRepository.findByHashCode(outTradeNo);
  10. if (libraOrder == null) {
  11. LOGGER.info("订单" outTradeNo "不存在");
  12. return false;
  13. }
  14. boolean locked = distributeLocker.lock(USER_ALIPAY_DEAL_LOCK_KEY);
  15. try {
  16. if (locked) {
  17. String totalAmount = params.get("total_amount");
  18. double totalPrice = Double.parseDouble(totalAmount) * 100;
  19. if(libraOrder.getTotalPrice() != Math.round(totalPrice)){
  20. LOGGER.info("alipay和订单金额不一致");
  21. return false;
  22. }
  23. if(totalPrice < 0 || libraOrder.getTotalPrice() < 0){
  24. LOGGER.info("alipay或订单金额为负");
  25. return false;
  26. }
  27. //set done
  28. libraOrder.setPayAt(new Date());
  29. libraOrder.setUpdateAt(new Date());
  30. libraOrder.setStatus(ClientOrderStatus.PAYED);
  31. //后台订单状态初始化为 等待接待
  32. libraOrder.setServiceStatus(ServiceStatus.SERVICE_WAIT);
  33. libraOrderRepository.save(libraOrder);
  34. }
  35. } finally {
  36. if (locked) {
  37. //TODO order.getUserId()
  38. distributeLocker.unlock(USER_ALIPAY_DEAL_LOCK_KEY);
  39. }
  40. }
  41. return false;
  42. }

[java] view plain copy

  1. /**
  2. * 验证RSA签名
  3. * @param params
  4. * @return
  5. * @throws OperationFailedException
  6. */
  7. public boolean rsaCheck(Map<String, String> params) throws OperationFailedException {
  8. try {
  9. boolean verify_result = AlipaySignature.rsaCheckV1(params, rsaPublicKey, charset, signType);
  10. LOGGER.info("verify_result = " verify_result);
  11. return verify_result;
  12. } catch (AlipayApiException e) {
  13. throw new OperationFailedException("验证签名失败");
  14. }
  15. }

java的支付宝接口(支付宝支付Java代码)(4)

,