lyhzzz 3 years ago
parent
commit
bbf8b7f3e3
100 changed files with 6522 additions and 20 deletions
  1. 17 0
      pom.xml
  2. 87 0
      src/main/java/com/fdkankan/ucenter/common/BaseController.java
  3. 17 0
      src/main/java/com/fdkankan/ucenter/common/SkuEnum.java
  4. 9 0
      src/main/java/com/fdkankan/ucenter/constant/OrderStatus.java
  5. 8 0
      src/main/java/com/fdkankan/ucenter/constant/PaymentStatus.java
  6. 9 0
      src/main/java/com/fdkankan/ucenter/constant/ShippingStatus.java
  7. 1 1
      src/main/java/com/fdkankan/ucenter/controller/CartController.java
  8. 100 0
      src/main/java/com/fdkankan/ucenter/controller/OrderAlipayController.java
  9. 46 0
      src/main/java/com/fdkankan/ucenter/controller/OrderController.java
  10. 252 0
      src/main/java/com/fdkankan/ucenter/controller/OrderPaypalController.java
  11. 260 0
      src/main/java/com/fdkankan/ucenter/controller/OrderWechatPayController.java
  12. 57 0
      src/main/java/com/fdkankan/ucenter/controller/SceneApplyController.java
  13. 43 0
      src/main/java/com/fdkankan/ucenter/controller/VirtualOrderController.java
  14. 118 0
      src/main/java/com/fdkankan/ucenter/entity/CommerceOrder.java
  15. 142 0
      src/main/java/com/fdkankan/ucenter/entity/ExpansionOrder.java
  16. 106 0
      src/main/java/com/fdkankan/ucenter/entity/GoodsSku.java
  17. 90 0
      src/main/java/com/fdkankan/ucenter/entity/SceneApply.java
  18. 1 1
      src/main/java/com/fdkankan/ucenter/generate/AutoGenerate.java
  19. 18 0
      src/main/java/com/fdkankan/ucenter/mapper/ICommerceOrderMapper.java
  20. 22 0
      src/main/java/com/fdkankan/ucenter/mapper/IExpansionOrderMapper.java
  21. 18 0
      src/main/java/com/fdkankan/ucenter/mapper/IGoodsSkuMapper.java
  22. 18 0
      src/main/java/com/fdkankan/ucenter/mapper/ISceneApplyMapper.java
  23. 5 0
      src/main/java/com/fdkankan/ucenter/mapper/IVirtualOrderMapper.java
  24. 91 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/AlipayDefaultConfig.java
  25. 81 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayConfig.java
  26. 60 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayGoodsDetail.java
  27. 160 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayService.java
  28. 38 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayUtil.java
  29. 113 0
      src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipaymentEx.java
  30. 14 0
      src/main/java/com/fdkankan/ucenter/pay/factory/PayEntity.java
  31. 39 0
      src/main/java/com/fdkankan/ucenter/pay/factory/PayFactory.java
  32. 264 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/PayOrderService.java
  33. 58 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/AlipayCommerce.java
  34. 57 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/PaypalCommerce.java
  35. 55 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/WechatCommerce.java
  36. 73 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/AlipayDownload.java
  37. 58 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/PaypalDownload.java
  38. 65 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/WechatDownload.java
  39. 82 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/AlipayExpansion.java
  40. 65 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/PaypalExpansion.java
  41. 81 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/WechatExpansion.java
  42. 77 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/AlipayGoods.java
  43. 72 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/PaypalGoods.java
  44. 73 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/WechatGoods.java
  45. 72 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/AlipayIncrement.java
  46. 58 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/PaypalIncrement.java
  47. 65 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/WechatIncrement.java
  48. 59 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/AlipayRecharge.java
  49. 60 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/PaypalRecharge.java
  50. 55 0
      src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/WechatRecharge.java
  51. 56 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/PayPalDefaultConfig.java
  52. 43 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PayPalConfig.java
  53. 130 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PayPalmentEx.java
  54. 88 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalOrderAddressEx.java
  55. 59 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalOrderItemEx.java
  56. 5 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalPaymentIntent.java
  57. 5 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalPaymentMethod.java
  58. 267 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalService.java
  59. 66 0
      src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/UrlUtils.java
  60. 11 0
      src/main/java/com/fdkankan/ucenter/pay/strategy/OrderItemStrategy.java
  61. 9 0
      src/main/java/com/fdkankan/ucenter/pay/strategy/OrderStrategy.java
  62. 68 0
      src/main/java/com/fdkankan/ucenter/pay/strategy/OrderStrategyFactory.java
  63. 44 0
      src/main/java/com/fdkankan/ucenter/pay/strategy/impl/DownloadOrderImpl.java
  64. 673 0
      src/main/java/com/fdkankan/ucenter/pay/wx/WXPay.java
  65. 53 0
      src/main/java/com/fdkankan/ucenter/pay/wx/WXPayConfig.java
  66. 45 0
      src/main/java/com/fdkankan/ucenter/pay/wx/WXPayConstants.java
  67. 62 0
      src/main/java/com/fdkankan/ucenter/pay/wx/WXPayDefaultConfig.java
  68. 307 0
      src/main/java/com/fdkankan/ucenter/pay/wx/WXPayUtil.java
  69. 2 0
      src/main/java/com/fdkankan/ucenter/service/ICartService.java
  70. 16 0
      src/main/java/com/fdkankan/ucenter/service/ICommerceOrderService.java
  71. 210 0
      src/main/java/com/fdkankan/ucenter/service/IDownloadOrderService.java
  72. 19 0
      src/main/java/com/fdkankan/ucenter/service/IExpansionOrderService.java
  73. 17 0
      src/main/java/com/fdkankan/ucenter/service/IGoodsSkuService.java
  74. 4 0
      src/main/java/com/fdkankan/ucenter/service/IIncrementOrderService.java
  75. 5 0
      src/main/java/com/fdkankan/ucenter/service/IInvoiceService.java
  76. 14 0
      src/main/java/com/fdkankan/ucenter/service/IOrderService.java
  77. 16 0
      src/main/java/com/fdkankan/ucenter/service/ISceneApplyService.java
  78. 4 0
      src/main/java/com/fdkankan/ucenter/service/IVirtualOrderService.java
  79. 5 0
      src/main/java/com/fdkankan/ucenter/service/impl/CartServiceImpl.java
  80. 20 0
      src/main/java/com/fdkankan/ucenter/service/impl/CommerceOrderServiceImpl.java
  81. 68 0
      src/main/java/com/fdkankan/ucenter/service/impl/DownloadOrderServiceImpl.java
  82. 38 0
      src/main/java/com/fdkankan/ucenter/service/impl/ExpansionOrderServiceImpl.java
  83. 32 0
      src/main/java/com/fdkankan/ucenter/service/impl/GoodsSkuServiceImpl.java
  84. 50 6
      src/main/java/com/fdkankan/ucenter/service/impl/IncrementOrderServiceImpl.java
  85. 44 1
      src/main/java/com/fdkankan/ucenter/service/impl/InvoiceServiceImpl.java
  86. 209 10
      src/main/java/com/fdkankan/ucenter/service/impl/OrderServiceImpl.java
  87. 20 0
      src/main/java/com/fdkankan/ucenter/service/impl/SceneApplyServiceImpl.java
  88. 18 0
      src/main/java/com/fdkankan/ucenter/service/impl/VirtualOrderServiceImpl.java
  89. 63 0
      src/main/java/com/fdkankan/ucenter/vo/request/InvoiceParam.java
  90. 14 1
      src/main/java/com/fdkankan/ucenter/vo/request/OrderParam.java
  91. 31 0
      src/main/java/com/fdkankan/ucenter/vo/request/PlaceOrderParam.java
  92. 18 0
      src/main/java/com/fdkankan/ucenter/vo/request/ShipUserParam.java
  93. 13 0
      src/main/java/com/fdkankan/ucenter/vo/request/VirtualOrderParam.java
  94. 10 0
      src/main/java/com/fdkankan/ucenter/vo/response/DownloadVo.java
  95. 12 0
      src/main/java/com/fdkankan/ucenter/vo/response/ExpansionOrderVo.java
  96. 34 0
      src/main/java/com/fdkankan/ucenter/vo/response/GoodsSkuVo.java
  97. 9 0
      src/main/java/com/fdkankan/ucenter/vo/response/VirtualOrderVo.java
  98. 5 0
      src/main/resources/mapper/ucenter/CommerceOrderMapper.xml
  99. 22 0
      src/main/resources/mapper/ucenter/ExpansionOrderMapper.xml
  100. 0 0
      src/main/resources/mapper/ucenter/GoodsSkuMapper.xml

+ 17 - 0
pom.xml

@@ -104,6 +104,23 @@
             <artifactId>easyexcel</artifactId>
             <version>3.1.0</version>
         </dependency>
+        <!-- Alipay  -->
+        <dependency>
+            <groupId>com.alipay</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>20170324180803</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alipay</groupId>
+            <artifactId>alipay-trade-sdk</artifactId>
+            <version>20161215</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.paypal.sdk</groupId>
+            <artifactId>rest-api-sdk</artifactId>
+            <version>1.14.0</version>
+        </dependency>
 
 
     </dependencies>

+ 87 - 0
src/main/java/com/fdkankan/ucenter/common/BaseController.java

@@ -0,0 +1,87 @@
+package com.fdkankan.ucenter.common;
+
+import com.fdkankan.common.util.DateEditor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.Date;
+
+public class BaseController {
+
+    @Autowired
+    protected HttpServletRequest request;
+
+    @Autowired
+    protected HttpServletResponse response;
+
+    @InitBinder
+    protected void initBinder(WebDataBinder webDataBinder) {
+        webDataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
+        webDataBinder.registerCustomEditor(Date.class, new DateEditor(true));
+    }
+
+    /**
+     * 带参重定向
+     *
+     * @param path
+     * @return
+     */
+    protected String redirect(String path) {
+        return "redirect:" + path;
+    }
+
+    /**
+     * 不带参重定向
+     *
+     * @param response
+     * @param path
+     * @return
+     */
+    protected String redirect(HttpServletResponse response, String path) {
+        try {
+            response.sendRedirect(path);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+
+    public static void output(HttpServletResponse resp, File file) {
+        OutputStream os = null;
+        BufferedInputStream bis = null;
+        byte[] buff = new byte[1024];
+        try {
+            os = resp.getOutputStream();
+            bis = new BufferedInputStream(new FileInputStream(file));
+            int i = 0;
+            while ((i = bis.read(buff)) != -1) {
+                os.write(buff, 0, i);
+                os.flush();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                bis.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    protected String getToken(){
+        return request.getHeader("token");
+    }
+
+}

+ 17 - 0
src/main/java/com/fdkankan/ucenter/common/SkuEnum.java

@@ -0,0 +1,17 @@
+package com.fdkankan.ucenter.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class SkuEnum {
+    public static Map<String, String> skusMap = new HashMap<>();
+
+    static {
+        skusMap.put("1", "U15604126369780003,U15604126369840004,U15609161655710002,U15604132404280073");
+        skusMap.put("2", "U15604126369780013,U15604126369840014,U15609161655710012,U15604132404280083");
+        skusMap.put("3", "U15604126369780023,U15604126369840024,U15609161655710022,U15604132404280093");
+        skusMap.put("4", "U15604126369780033,U15604126369840034,U15609161655710032,U15604132404280103");
+        skusMap.put("5", "U15604132404280203");
+        skusMap.put("6", "U15604132404280303");
+    }
+}

+ 9 - 0
src/main/java/com/fdkankan/ucenter/constant/OrderStatus.java

@@ -0,0 +1,9 @@
+package com.fdkankan.ucenter.constant;
+
+
+/**
+ * 订单状态(未处理、已确认、已完成、已取消)
+ */
+public enum OrderStatus {
+    unprocessed, processed, completed, invalid, expire
+}

+ 8 - 0
src/main/java/com/fdkankan/ucenter/constant/PaymentStatus.java

@@ -0,0 +1,8 @@
+package com.fdkankan.ucenter.constant;
+
+/**
+ * 付款状态(未付款、已付款、已取消, 部分支付, 部分退款, 全额退款)
+ */
+public enum PaymentStatus {
+    unpaid, paid, cancel, partPayment, partRefund, refunded
+}

+ 9 - 0
src/main/java/com/fdkankan/ucenter/constant/ShippingStatus.java

@@ -0,0 +1,9 @@
+package com.fdkankan.ucenter.constant;
+
+/**
+ * 配送状态(未发货、部分发货、已发货、部分退货、已退货、已收货)
+ */
+public enum ShippingStatus {
+    unshipped, partShipped, shipped, partReshiped, reshiped, received
+
+}

+ 1 - 1
src/main/java/com/fdkankan/ucenter/controller/CartController.java

@@ -64,7 +64,7 @@ public class CartController {
         }
         String[] split = param.getIds().split(",");
         List<String> ids = Arrays.asList(split);
-        cartService.removeByIds(ids);
+        cartService.deleteIds(ids);
         return Result.success();
     }
 

+ 100 - 0
src/main/java/com/fdkankan/ucenter/controller/OrderAlipayController.java

@@ -0,0 +1,100 @@
+package com.fdkankan.ucenter.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.fdkankan.ucenter.common.BaseController;
+import com.fdkankan.ucenter.common.Result;
+import com.fdkankan.ucenter.pay.alipay.AlipayDefaultConfig;
+import com.fdkankan.ucenter.pay.factory.PayFactory;
+import com.fdkankan.ucenter.pay.strategy.OrderStrategyFactory;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+@Log4j2
+/**支付中心-支付宝支付模块*/
+@RestController
+@RequestMapping("/api/order/pay")
+public class OrderAlipayController extends BaseController {
+    @Autowired
+    private AlipayDefaultConfig alipayDefaultConfig;
+    @Autowired
+    private OrderStrategyFactory orderStrategyFactory;
+    @Autowired
+    private PayFactory payFactory;
+
+    @RequestMapping(value = "/alipay", method = RequestMethod.POST)
+    public Result alipay(@RequestBody PlaceOrderParam order) throws Exception {
+        return Result.success(payFactory.scanPay("alipay", order));
+    }
+
+    @RequestMapping(value = "/aliMobilePay", method = RequestMethod.POST)
+    public Result aliMobilePay(@RequestBody PlaceOrderParam order) throws Exception {
+        return  Result.success(payFactory.h5Pay("alipay", order, null));
+    }
+
+    @RequestMapping(value = "/alipay/async_notify", method = RequestMethod.POST)
+    public String async_notify() {
+        //获取支付宝POST过来反馈信息
+        Map<String, String> params = new HashMap<String, String>();
+        Map<String, String[]> requestParams = request.getParameterMap();
+        for (Iterator<String> 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] + ",";
+            }
+            //乱码解决,这段代码在出现乱码时使用
+            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
+            params.put(name, valueStr);
+        }
+        //调用SDK验证签名
+        try {
+            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayDefaultConfig.getAlipayPublicKey(), alipayDefaultConfig.getCharset(), alipayDefaultConfig.getSignType());
+            if (signVerified) {
+                log.info("支付宝回调签名认证成功");
+                //商户订单号
+                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");
+                //交易body
+                String body = new String(request.getParameter("body").getBytes("ISO-8859-1"), "UTF-8");
+                log.info("支付宝回调返回body:" + body);
+                //付款金额
+//                String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"), "UTF-8");
+                String openid = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"),"UTF-8");
+                String orderSn = out_trade_no.split("_")[0];
+                if(body.split("_").length == 2){
+                    orderSn += "_" + body.split("_")[1];
+                }
+                if ("TRADE_FINISHED".equals(trade_status)){
+                    log.warn("支付宝——交易结束了!" + out_trade_no);
+                }else if ("TRADE_SUCCESS".equals(trade_status)){
+                    orderStrategyFactory.doHandler(orderSn, trade_no, openid, out_trade_no.split("_")[1], 1);
+                }else {
+                    log.error("订单号:" + orderSn + "支付宝回调交易状态异常:" + trade_status);
+                }
+                return "success";
+            }else{
+                log.warn("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", JSON.toJSONString(params));
+                return "failure";
+            }
+        } catch (Exception e) {
+            log.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", JSON.toJSONString(params), e.getMessage());
+            return "failure";
+        }
+    }
+
+}

+ 46 - 0
src/main/java/com/fdkankan/ucenter/controller/OrderController.java

@@ -5,6 +5,7 @@ import com.fdkankan.common.util.JwtUtil;
 import com.fdkankan.ucenter.common.Result;
 import com.fdkankan.ucenter.service.IOrderService;
 import com.fdkankan.ucenter.vo.request.OrderParam;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -28,5 +29,50 @@ public class OrderController {
         param.setUserName(username);
         return Result.success(orderService.pageList(param));
     }
+
+    /**
+     * 取消订单
+     */
+    @PostMapping("/cancel")
+    public Result cancel(@RequestBody OrderParam param){
+        orderService.cancel(param.getOrderId());
+        return Result.success();
+    }
+    /**
+     * 确认收货
+     */
+    @PostMapping("/receipt")
+    public Result receipt(@RequestBody OrderParam param){
+        orderService.receipt(param.getOrderId());
+        return Result.success();
+    }
+    /**
+     * 确认订单
+     */
+    @PostMapping("/placeOrder")
+    public Result placeOrder(@RequestBody PlaceOrderParam param, @RequestHeader String token){
+        String username = JwtUtil.getUsername(token);
+        param.setUserName(username);
+        return Result.success(orderService.placeOrder(param));
+    }
+
+    /**
+     * 交易查询 (轮询)
+     */
+    @PostMapping("/queryOrderStatus")
+    public Result queryOrderStatus(@RequestBody OrderParam param) throws Exception {
+        return Result.success(orderService.queryOrderStatus(param));
+    }
+
+    /**
+     * 获取增值权益或场景下载价格
+     */
+    @PostMapping("/getIncrementOrDownloadPrice")
+    public Result getIncrementOrDownloadPrice(@RequestBody OrderParam param, @RequestHeader String token){
+        String username = JwtUtil.getUsername(token);
+        param.setUserName(username);
+        return Result.success(orderService.getIncrementOrDownloadPrice(param));
+    }
+
 }
 

+ 252 - 0
src/main/java/com/fdkankan/ucenter/controller/OrderPaypalController.java

@@ -0,0 +1,252 @@
+package com.fdkankan.ucenter.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.ucenter.common.BaseController;
+import com.fdkankan.ucenter.common.Result;
+import com.fdkankan.ucenter.pay.factory.PayFactory;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.pay.paypal.sdk.PaypalService;
+import com.fdkankan.ucenter.pay.strategy.OrderStrategyFactory;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import com.paypal.api.payments.Payment;
+import com.paypal.base.rest.PayPalRESTException;
+import lombok.extern.log4j.Log4j2;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+
+@Log4j2
+/**支付中心-paypal支付模块*/
+@Controller
+@RequestMapping("/api/order/pay")
+public class OrderPaypalController extends BaseController {
+
+    @Autowired
+    private OrderStrategyFactory orderStrategyFactory;
+    @Autowired
+    private PayFactory payFactory;
+    @Autowired
+    private PaypalService paypalService;
+    @Autowired
+    private PayPalDefaultConfig config;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    /**
+     * Paypal付款
+     * orderId      订单id
+     * orderType    订单类型,0购买相机,1点数重置,2扩容,3商业版,4增值服务,5场景下载
+     * spaceId      0表示国内订单,1表示国外订单
+     */
+    @RequestMapping(value = "/paypal", method = RequestMethod.POST)
+    public String paypal(@RequestBody PlaceOrderParam order) throws Exception {
+        JSONObject jsonObject = payFactory.scanPay("paypal", order);
+        if (jsonObject != null && jsonObject.get("redirect") != null){
+            return "redirect:" + jsonObject.getString("redirect");
+        }
+        return  "redirect:" + mainUrl + config.getFailUrl();
+    }
+
+    @RequestMapping(value = "/paypalH5", method = RequestMethod.POST)
+    public String paypalH5(PlaceOrderParam order) throws Exception {
+        JSONObject jsonObject = payFactory.h5Pay("paypal", order, null);
+        if (jsonObject != null && jsonObject.get("redirect") != null){
+            return "redirect:" + jsonObject.getString("redirect");
+        }
+        return  "redirect:" + mainUrl + config.getH5FailUrl();
+    }
+
+    /**
+     * 支付成功
+     */
+    @RequestMapping(value = "/paypal/callback", method = RequestMethod.GET)
+    public String successPay(@RequestParam("paymentId") String paymentId,
+                             @RequestParam("PayerID") String payerId) {
+        try {
+            log.warn("=====paypal支付回调=====\npaymentId:"+paymentId+"\npayerId:"+payerId);
+            Payment payment = paypalService.executePayment(paymentId, payerId);
+            if (payment.getState().equals("approved")) {
+                log.info("paypal支付成功回调");
+                String custom = payment.getTransactions().get(0).getCustom();
+                String txnId = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getId();
+                String payerEmail  = payment.getTransactions().get(0).getPayee().getEmail();
+                log.warn("=====custom:"+custom+"\ntxnId:"+txnId+"\npayerEmail:"+payerEmail);
+
+                String orderSn = custom.split("_")[0];
+                if(custom.split("_").length > 2 && custom.split("_")[2].matches("^-?[0-9]+")){
+                    orderSn += "_" + custom.split("_")[2];
+                }
+                orderStrategyFactory.doHandler(orderSn, txnId, payerEmail, custom.split("_")[1], 2);
+                return "redirect:" + mainUrl + config.getSuccessUrl();
+            }
+        } catch (PayPalRESTException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
+        }
+        return "redirect:" + mainUrl + config.getFailUrl();
+    }
+
+    /**
+     * 支付成功
+     * @param paymentId
+     * @param payerId
+     * @return
+     */
+    @RequestMapping(value = "/paypal/callbackH5", method = RequestMethod.GET)
+    public String successPayH5(@RequestParam("paymentId") String paymentId,
+                             @RequestParam("PayerID") String payerId) {
+        try {
+            log.warn("=====paypal支付回调=====\npaymentId:"+paymentId+"\npayerId:"+payerId);
+            Payment payment = paypalService.executePayment(paymentId, payerId);
+            if (payment.getState().equals("approved")) {
+                log.info("paypal支付成功回调");
+                String custom = payment.getTransactions().get(0).getCustom();
+                String txnId = payment.getTransactions().get(0).getRelatedResources().get(0).getSale().getId();
+                String payerEmail  = payment.getTransactions().get(0).getPayee().getEmail();
+                log.warn("=====custom:"+custom+"\ntxnId:"+txnId+"\npayerEmail:"+payerEmail);
+                String orderSn = custom.split("_")[0];
+                if(custom.split("_").length > 2 && custom.split("_")[2].matches("^-?[0-9]+")){
+                    orderSn += "_" + custom.split("_")[2];
+                }
+                orderStrategyFactory.doHandler(orderSn, txnId, payerEmail, custom.split("_")[1], 2);
+                return "redirect:" + mainUrl + config.getH5SuccessUrl();
+            }
+        } catch (PayPalRESTException e) {
+            log.error(e.getMessage());
+        } catch (Exception e) {
+            log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
+        }
+        return "redirect:" + mainUrl + config.getH5FailUrl();
+    }
+
+    /**
+     * 取消支付
+     * @return
+     */
+    @RequestMapping(value = "/paypal/cancel", method = RequestMethod.GET)
+    public String cancelPay(){
+        return "redirect:" + mainUrl + config.getFailUrl();
+    }
+
+    /**
+     * 取消支付
+     * @return
+     */
+    @RequestMapping(value = "/paypal/cancelH5", method = RequestMethod.GET)
+    public String cancelPayH5(){
+        return "redirect:" + mainUrl + config.getH5FailUrl();
+    }
+
+    /**
+     *  Paypal的INP异步通知服务器, 需要修改Paypal官网即时付款通知IPN通告URL
+     */
+    @RequestMapping(value = "/paypal/notify", method = RequestMethod.POST)
+    public void callback() {
+        Enumeration en = request.getParameterNames();
+        String str = "cmd=_notify-validate";
+        while (en.hasMoreElements()) {
+            String paramName = (String) en.nextElement();
+            String paramValue = request.getParameter(paramName);
+            try {
+                str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, "utf-8");
+            } catch (UnsupportedEncodingException e) {
+                StringWriter trace=new StringWriter();
+                e.printStackTrace(new PrintWriter(trace));
+                log.error(trace.toString());
+            }
+            //此处的编码一定要和自己的网站编码一致,不然会出现乱码,paypal回复的通知为‘INVALID’
+        }
+        final String itemName = request.getParameter("item_name");//商品名
+        final String itemNumber = request.getParameter("item_number");//购买数量
+        final String paymentDate = request.getParameter("payment_date");//交易时间
+        final String receiverEmail = request.getParameter("receiver_email");//收款人email
+        final String payerEmail = request.getParameter("payer_email");//付款人email
+        final String paymentAmount = request.getParameter("mc_gross");//交易钱数
+        final String paymentCurrency = request.getParameter("mc_currency");//货币种类
+        final String paymentStatus = request.getParameter("payment_status");//交易状态
+        final String txnId = request.getParameter("txn_id");//交易id
+        String custom = request.getParameter("custom");//发送payment请求时候自定义的业务服务器订单号
+
+        log.info("itemName:"+itemName);
+        log.info("itemNumber:"+itemNumber);
+        log.info("paymentDate:"+paymentDate);
+        log.info("receiverEmail:"+receiverEmail);
+        log.info("payerEmail:"+payerEmail);
+        log.info("paymentAmount:"+paymentAmount);
+        log.info("paymentCurrency:"+paymentCurrency);
+        log.info("paymentStatus:"+paymentStatus);
+        log.info("txnId:"+txnId);
+        log.info("custom:"+custom);
+        String orderSn = custom.split("_")[0];
+        try {
+            //构建post请求给paypal,将信息 POST 回给 PayPal 进行验证
+            //String url = "https://www.sandbox.paypal.com/cgi-bin/webscr";//沙箱环境
+            //String url = new URL("https://www.paypal.com/cgi-bin/webscr");//正式环境
+            String url = "https://www.paypal.com/cgi-bin/webscr";//正式环境
+            //http框架用的是okhttp,okhttp也依赖okio的jar包
+            OkHttpClient client = new OkHttpClient();
+            okhttp3.RequestBody body = okhttp3.RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), str);
+            Request req = new Request.Builder().post(body).url(url).build();
+            client.newCall(req).enqueue(new Callback() {
+                @Override
+                public void onFailure(Call arg0, IOException arg1) {
+                    log.error("构建post请求给paypal时候发生了错误:" + custom);
+                }
+                @Override
+                public void onResponse(Call arg0, Response arg1) throws IOException {
+                    String str = arg1.body().string();
+                    //验证通过
+                    if ("VERIFIED".equals(str)) {
+//	                    StringBuilder sb = new StringBuilder();
+//	                    sb.append("付款成功参数:itemName=").append(itemName).append(",itemNumber=").append(itemNumber).
+//	                    append("付款成功参数:paymentStatus=").append(paymentStatus).append(",paymentDate=").append(paymentDate).
+//	                    append("付款成功参数:paymentAmount=").append(paymentAmount).append(",paymentCurrency=").append(paymentCurrency).
+//	                    append("付款成功参数:txnId=").append(txnId).append(",receiverEmail=").append(receiverEmail).
+//	                    append("付款成功参数:payerEmail=").append(payerEmail);
+//	                    log.info(sb.toString());
+
+                        //1.确认“payment_status”为“Completed”,因为系统也会为其他结果(如“Pending”或“Failed”)发送 IPN。
+                        //2.检查“txn_id”是否未重复,以防止欺诈者重复使用旧的已完成的交易
+                        //3.验证“receiver_email”是已在您的PayPal账户中注册的电子邮件地址,以防止将付款发送到欺诈者的账户
+                        if ("Completed".equals(paymentStatus)) {
+                            //根据自己业务进行处理(修改订单状态,支付时间等等操作)
+                            try {
+                                log.info("paypal支付成功回调");
+                                //表示续费,有消费记录id
+                                if(custom.split("_").length > 2 && custom.split("_")[2].matches("^-?[0-9]+")){
+                                    orderStrategyFactory.doHandler(custom.split("_")[0] + "_" + custom.split("_")[2], txnId, payerEmail, custom.split("_")[1], 2);
+                                }else {
+                                    orderStrategyFactory.doHandler(orderSn, txnId, payerEmail, custom.split("_")[1], 2);
+                                }
+                            } catch (Exception e) {
+                                log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
+                            }
+                        }
+                    } else if ("VERIFIED".equals(str)) {
+                        log.error("付款失败回调VERIFIED,订单号=" + orderSn);
+                    } else {
+                        log.error("付款无效回调VERIFIED,订单号=" + orderSn);
+                    }
+                }
+            });
+        } catch (Exception e) {
+            log.error("paypal支付回调异常,errorMsg:{}", e.getMessage());
+        }
+    }
+
+
+}

+ 260 - 0
src/main/java/com/fdkankan/ucenter/controller/OrderWechatPayController.java

@@ -0,0 +1,260 @@
+package com.fdkankan.ucenter.controller;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ConstantUrl;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.ucenter.common.BaseController;
+import com.fdkankan.ucenter.common.Result;
+import com.fdkankan.ucenter.entity.*;
+import com.fdkankan.ucenter.pay.factory.PayFactory;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.sdk.UrlUtils;
+import com.fdkankan.ucenter.pay.strategy.OrderStrategyFactory;
+import com.fdkankan.ucenter.pay.wx.WXPayConstants;
+import com.fdkankan.ucenter.pay.wx.WXPayDefaultConfig;
+import com.fdkankan.ucenter.pay.wx.WXPayUtil;
+import com.fdkankan.ucenter.service.*;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.io.BufferedOutputStream;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+@Log4j2
+/**支付中心-微信支付模块"*/
+@Controller
+@RequestMapping("/api/order/pay")
+public class OrderWechatPayController extends BaseController {
+    @Autowired
+    private OrderStrategyFactory orderStrategyFactory;
+    @Autowired
+    private PayFactory payFactory;
+    @Autowired
+    private IOrderService orderService;
+    @Autowired
+    private IVirtualOrderService virtualOrderService;
+    @Autowired
+    private IExpansionOrderService expansionOrderService;
+
+    @Autowired
+    private IIncrementOrderService incrementOrderService;
+    @Autowired
+    IOrderItemService orderItemService;
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    PayOrderService payOrderService;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @ResponseBody
+    @RequestMapping(value = "/wechatPay", method = RequestMethod.POST)
+    public Result wechatPay(@RequestBody PlaceOrderParam order) throws Exception {
+        return Result.success(payFactory.scanPay("wechat", order));
+    }
+
+    @ResponseBody
+    @RequestMapping(value = "/wechatMobilePay", method = RequestMethod.POST)
+    public Result wechatMobilePay(@RequestBody PlaceOrderParam order) throws Exception {
+        return Result.success(payFactory.h5Pay("wechat", order, UrlUtils.getIpAddr(request)));
+    }
+
+    @RequestMapping(value = "/wechatPreJsPay")
+    public String wechatPreJsPay(Long orderId, int orderType, String code, Long spaceId) throws Exception {
+        InputStream is = null;
+        WXPayDefaultConfig config = new WXPayDefaultConfig();
+        // 这个url链接地址和参数皆不能变
+        String url = ConstantUrl.WEIXIN_TOKEN_URL1 + config.getAppID() + "&secret=" + config.getSecret() + "&grant_type=authorization_code" + "&code=" + code;
+        try {
+            URL urlGet = new URL(url);
+            HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
+            http.setRequestMethod("GET"); // 必须是get方式请求
+            http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            http.setDoOutput(true);
+            http.setDoInput(true);
+            System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
+            System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
+            http.connect();
+            is = http.getInputStream();
+            int size = is.available();
+            byte[] jsonBytes = new byte[size];
+            is.read(jsonBytes);
+            String message = new String(jsonBytes, "UTF-8");
+            log.debug("获取access_token返回的message:"+message);
+            JSONObject oppidObj = JSONObject.parseObject(message);
+            String access_token = (String) oppidObj.get("access_token");
+            String openid = (String) oppidObj.get("openid");
+
+            String orderSn = null;
+            StringBuilder sb = new StringBuilder();
+            BigDecimal totalFee = null;
+            switch (orderType){
+                case 0:
+                    Order responseOrder = orderService.getById(orderId);
+                    if (responseOrder.getId() == null) return "redirect:" + mainUrl + "mobile.html#/payresult/fail";
+
+                    List<OrderItem> items = orderItemService.getByOrderId(orderId);
+                    for (int i = 0; i < items.size(); i++){
+                        sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+                        if (i != items.size() - 1){
+                            sb.append(",");
+                        }
+                    }
+                    totalFee = responseOrder.getTotalAmount().multiply(new BigDecimal(100));
+                    orderSn = responseOrder.getOrderSn();
+                    orderSn += "_entity";
+                    break;
+                case 1:
+                    VirtualOrder virtualOrderEntity = virtualOrderService.getById(orderId);
+                    if (virtualOrderEntity == null){
+                        return "redirect:" + mainUrl + "mobile.html#/payresult/fail";
+                    }
+                    sb.append(Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints());
+                    totalFee = new BigDecimal(virtualOrderEntity.getPoints()).multiply(new BigDecimal(100));
+                    orderSn = virtualOrderEntity.getOrderSn();
+                    orderSn += "_recharge";
+                    break;
+                case 2:
+                    ExpansionOrder expansion = expansionOrderService.getById(orderId);
+                    if (expansion == null){
+                        return "redirect:" + mainUrl + "mobile.html#/payresult/fail";
+                    }
+                    //订单金额为国外金额就报错
+                    if(expansion.getAbroad() == 1){
+                        throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+                    }
+                    String date = "1年";
+                    if(expansion.getMonth() < 12){
+                        date = expansion.getMonth() + "个月";
+                    }
+                    String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+                    sb.append(subject);
+                    totalFee = expansion.getAmount().multiply(new BigDecimal(100));
+                    orderSn = expansion.getOrderSn();
+                    orderSn += "_expansion";
+                    break;
+                case 3:
+                    break;
+                case 4:
+                    IncrementOrder incrementOrderEntity = incrementOrderService.getById(orderId);
+                    if (incrementOrderEntity == null){
+                        return "redirect:" + mainUrl + "mobile.html#/payresult/fail";
+                    }
+                    //订单金额为国外金额就报错
+                    if(incrementOrderEntity.getAbroad() == 1){
+                        throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+                    }
+                    sb.append(Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年");
+                    totalFee = incrementOrderEntity.getAmount().multiply(new BigDecimal(100));
+                    orderSn = incrementOrderEntity.getOrderSn();
+                    orderSn += "_increment";
+                    break;
+                case 5:
+                    break;
+            }
+            String body = sb.toString();
+            if(spaceId != null){
+                orderSn = orderSn.replace("expansion", String.valueOf(spaceId));
+            }
+            Map<String, String> resp = payOrderService.wechatPay(orderSn, sb.toString(), body, totalFee, UrlUtils.getIpAddr(request), openid);
+            String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
+            return "redirect:" + mainUrl + ConstantUrl.WEIXIN_MOBILE_PAY_URL + timeStamp + "&signType=MD5&appId=" + resp.get("appid")
+                    + "&nonceStr=" + resp.get("nonce_str") + "&prepay_id=" + resp.get("prepay_id") + "&paySign=" + resp.get("paySign");
+        }catch (Exception e){
+            log.debug("获取access_token发生异常",e);
+        }finally {
+            if (is != null){
+                is.close();
+            }
+        }
+        return "redirect:" + mainUrl + "mobile.html#/payresult/fail";
+    }
+
+    @RequestMapping(value = {"/wechatPay/notify"}, method = RequestMethod.POST)
+    public void callback() {
+        log.warn("微信回调接口方法 start");
+        String inputLine = "";
+        String notifyXml = "";
+        try {
+            while((inputLine = request.getReader().readLine()) != null){
+                notifyXml += inputLine;
+            }
+            //关闭流
+            request.getReader().close();
+            log.warn("微信回调内容信息:"+notifyXml);
+            //解析成Map
+            Map<String,String> map = WXPayUtil.xmlToMap(notifyXml);
+
+            WXPayDefaultConfig config = new WXPayDefaultConfig();
+            if (WXPayUtil.isSignatureValid(map, config.getKey(), WXPayConstants.SignType.MD5) || WXPayUtil.isSignatureValid(map, config.getKey(), WXPayConstants.SignType.HMACSHA256)) {
+                //判断 支付是否成功
+                if("SUCCESS".equals(map.get("result_code"))){
+                    log.warn("微信回调返回是否支付成功:是");
+                    //获得 返回的商户订单号
+                    String out_trade_no = map.get("out_trade_no");
+                    String trade_no = map.get("transaction_id");
+                    String openid = map.get("openid");
+                    log.warn("微信回调返回商户订单号:" + out_trade_no);
+                    //修改订单状态
+                    String orderSnE = out_trade_no.substring(0, out_trade_no.lastIndexOf("_"));
+
+                    String orderSn = out_trade_no.split("_")[0];
+                    if(!out_trade_no.contains("recharge") && !out_trade_no.contains("commerce") &&
+                            !out_trade_no.contains("entity") && !out_trade_no.contains("expansion") &&
+                            !out_trade_no.contains("increment") && !out_trade_no.contains("download")){
+//                        orderSn += "_" + out_trade_no.split("_")[1];
+
+                        log.warn("orderSnE:" + orderSn + "_expansion");
+                        if (redisUtil.hasKey(orderSn + "_expansion")){
+                            redisUtil.del(orderSn + "_expansion");
+                        }
+                        redisUtil.set(orderSn + "_expansion", out_trade_no);
+                    }else {
+                        log.warn("orderSnE:" + orderSnE);
+                        if (redisUtil.hasKey(orderSnE)){
+                            redisUtil.del(orderSnE);
+                        }
+                        redisUtil.set(orderSnE, out_trade_no);
+                    }
+                    orderStrategyFactory.doHandler(orderSn, trade_no, openid, out_trade_no.split("_")[1], 0);
+                    log.warn("微信支付成功,订单号:"  + orderSn);
+                    //通知微信服务器已经支付成功
+                    notifyXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code>"
+                            + "<return_msg><![CDATA[OK]]></return_msg></xml> ";
+                }else{
+                    notifyXml = "<xml><return_code><![CDATA[FAIL]]></return_code>"
+                            + "<return_msg><![CDATA[报文为空]]></return_msg></xml> ";
+                }
+            } else{
+                log.error("签名验证错误");
+                notifyXml = "<xml><return_code><![CDATA[FAIL]]></return_code>"
+                        + "<return_msg><![CDATA[签名验证错误]]></return_msg></xml>";
+            }
+            BufferedOutputStream out = new BufferedOutputStream(
+                    response.getOutputStream());
+            out.write(notifyXml.getBytes());
+            out.flush();
+            out.close();
+
+        } catch (Exception e) {
+            log.error("微信支付回调数据异常, errorMsg:{}", e.getMessage());
+        }
+    }
+
+
+}

+ 57 - 0
src/main/java/com/fdkankan/ucenter/controller/SceneApplyController.java

@@ -0,0 +1,57 @@
+package com.fdkankan.ucenter.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.ucenter.entity.SceneApply;
+import com.fdkankan.ucenter.service.ISceneApplyService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@RestController
+@RequestMapping("/api/demo/scen")
+public class SceneApplyController {
+    @Autowired
+    private ISceneApplyService sceneApplyService;
+
+    /**
+     * 新增演示场景申请
+     */
+    @PostMapping("/save")
+    public ResultData save(@RequestBody SceneApply sceneApplyEntity){
+        sceneApplyService.save(sceneApplyEntity);
+        return ResultData.ok();
+    }
+
+    @PostMapping("/pageList")
+    public ResultData pageList(@RequestBody JSONObject param){
+        Integer page =param.get("pageNum") == null ? 1 : param.getInteger("pageNum");
+        Integer pageSize =param.get("pageSize") == null ? 10 : param.getInteger("pageSize");
+        return ResultData.ok(sceneApplyService.page(new Page<>(page,pageSize)));
+    }
+
+    @PostMapping("/delete")
+    public ResultData delete(@RequestBody JSONObject param){
+        if(param.get("id") == null){
+            throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
+        }
+        sceneApplyService.removeById(param.getInteger("id"));
+        return ResultData.ok();
+    }
+}
+

+ 43 - 0
src/main/java/com/fdkankan/ucenter/controller/VirtualOrderController.java

@@ -4,8 +4,12 @@ package com.fdkankan.ucenter.controller;
 import com.dtflys.forest.annotation.Post;
 import com.fdkankan.common.util.JwtUtil;
 import com.fdkankan.ucenter.common.Result;
+import com.fdkankan.ucenter.service.IDownloadOrderService;
+import com.fdkankan.ucenter.service.IExpansionOrderService;
 import com.fdkankan.ucenter.service.IIncrementOrderService;
+import com.fdkankan.ucenter.service.IVirtualOrderService;
 import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -23,11 +27,50 @@ public class VirtualOrderController {
 
     @Autowired
     IIncrementOrderService incrementOrderService;
+    @Autowired
+    IDownloadOrderService downloadOrderService;
+    @Autowired
+    IVirtualOrderService virtualOrderService;
+    @Autowired
+    IExpansionOrderService expansionOrderService;
+
 
+    /**
+     * 获取会员权益记录
+     */
     @PostMapping("/incrementOrderList")
     public Result incrementOrderList(@RequestBody IncrementOrderParam param, @RequestHeader String token){
         param.setUserName(JwtUtil.getUsername(token));
         return Result.success(incrementOrderService.pageList(param));
     }
+
+    /**
+     * 获取用户下载订单
+     */
+    @PostMapping("/downloadOrderList")
+    public Result downloadOrderList(@RequestBody IncrementOrderParam param, @RequestHeader String token){
+        param.setUserName(JwtUtil.getUsername(token));
+        return Result.success(downloadOrderService.pageList(param));
+    }
+
+    /**
+     * 获取用户充值记录
+     */
+    @PostMapping("/chargeList")
+    public Result chargeList(@RequestBody VirtualOrderParam param, @RequestHeader String token){
+        param.setUserName(JwtUtil.getUsername(token));
+        return Result.success(virtualOrderService.pageList(param));
+    }
+
+    /**
+     * 获取用户扩容记录
+     */
+    @PostMapping("/expansionList")
+    public Result expansionList(@RequestBody VirtualOrderParam param, @RequestHeader String token){
+        param.setUserName(JwtUtil.getUsername(token));
+        return Result.success(expansionOrderService.pageList(param));
+    }
+
+
 }
 

+ 118 - 0
src/main/java/com/fdkankan/ucenter/entity/CommerceOrder.java

@@ -0,0 +1,118 @@
+package com.fdkankan.ucenter.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 商业订单表(八目相机)
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Getter
+@Setter
+@TableName("t_commerce_order")
+public class CommerceOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 订单号
+     */
+    @TableField("order_sn")
+    private String orderSn;
+
+    /**
+     * 金额
+     */
+    @TableField("amount")
+    private BigDecimal amount;
+
+    /**
+     * 支付宝的交易号或者微信支付订单号
+     */
+    @TableField("number")
+    private String number;
+
+    /**
+     * 付款方式,0表示微信,1表示支付宝,2表示paypal,3表示其他
+     */
+    @TableField("pay_type")
+    private Integer payType;
+
+    /**
+     * 状态,0或-1表示未付款,1表示已付款
+     */
+    @TableField("pay_status")
+    private Integer payStatus;
+
+    /**
+     * 交易时间
+     */
+    @TableField("trade_time")
+    private Date tradeTime;
+
+    /**
+     * 用户表t_user的id
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 相机主表t_camera的id
+     */
+    @TableField("camera_id")
+    private Long cameraId;
+
+    /**
+     * 0表示年,1表示月
+     */
+    @TableField("commerce_type")
+    private Integer commerceType;
+
+    /**
+     * 数量
+     */
+    @TableField("count")
+    private Integer count;
+
+    /**
+     * 0表示国内订单,1表示国外订单
+     */
+    @TableField("abroad")
+    private Integer abroad;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private String createTime;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private String updateTime;
+
+
+}

+ 142 - 0
src/main/java/com/fdkankan/ucenter/entity/ExpansionOrder.java

@@ -0,0 +1,142 @@
+package com.fdkankan.ucenter.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 扩容订单表(八目相机)
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Getter
+@Setter
+@TableName("t_expansion_order")
+public class ExpansionOrder implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 订单号
+     */
+    @TableField("order_sn")
+    private String orderSn;
+
+    /**
+     * 金额
+     */
+    @TableField("amount")
+    private BigDecimal amount;
+
+    /**
+     * 支付宝的交易号或者微信支付订单号
+     */
+    @TableField("number")
+    private String number;
+
+    /**
+     * 付款方式,0表示微信,1表示支付宝,2表示paypal,3表示其他
+     */
+    @TableField("pay_type")
+    private Integer payType;
+
+    /**
+     * 状态,0或-1表示未付款,-2表示已退款,1表示已付款
+     */
+    @TableField("pay_status")
+    private Integer payStatus;
+
+    /**
+     * 状态,1表示充值,0表示系统赠送,2表示升级套餐
+     */
+    @TableField("status")
+    private Integer status;
+
+    /**
+     * 交易时间
+     */
+    @TableField("trade_time")
+    private Date tradeTime;
+
+    /**
+     * 用户表t_user的id
+     */
+    @TableField("user_id")
+    private Long userId;
+
+    /**
+     * 期限,月为单位
+     */
+    @TableField("month")
+    private Integer month;
+
+    /**
+     * 期限,年为单位
+     */
+    @TableField("years")
+    private Integer years;
+
+    /**
+     * 延期,天为单位
+     */
+    @TableField("delay")
+    private Integer delay;
+
+    /**
+     * 容量大小
+     */
+    @TableField("unit_size")
+    private Integer unitSize;
+
+    /**
+     * 容量单位,"GB", "TB", "PB"
+     */
+    @TableField("unit")
+    private String unit;
+
+    /**
+     * 相机主表t_camera的id
+     */
+    @TableField("camera_id")
+    private Long cameraId;
+
+    /**
+     * 0表示国内订单,1表示国外订单
+     */
+    @TableField("abroad")
+    private Integer abroad;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private String createTime;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private String updateTime;
+
+
+}

+ 106 - 0
src/main/java/com/fdkankan/ucenter/entity/GoodsSku.java

@@ -0,0 +1,106 @@
+package com.fdkankan.ucenter.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 商品sku表
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Getter
+@Setter
+@TableName("t_goods_sku")
+public class GoodsSku implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 商品表t_goods的id
+     */
+    @TableField("goods_id")
+    private Long goodsId;
+
+    /**
+     * sku编号,唯一
+     */
+    @TableField("sku_sn")
+    private String skuSn;
+
+    /**
+     * 规格描述
+     */
+    @TableField("description")
+    private String description;
+
+    /**
+     * 库存,-1指充足
+     */
+    @TableField("stock")
+    private Integer stock;
+
+    /**
+     * 价格(RMB)
+     */
+    @TableField("price")
+    private BigDecimal price;
+
+    /**
+     * 价格(美元)
+     */
+    @TableField("dollar_price")
+    private BigDecimal dollarPrice;
+
+    /**
+     * 容量大小
+     */
+    @TableField("unit_size")
+    private Integer unitSize;
+
+    /**
+     * 容量单位,"GB", "TB", "PB"
+     */
+    @TableField("unit")
+    private String unit;
+
+    /**
+     * 容量时长
+     */
+    @TableField("month")
+    private Integer month;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private String createTime;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private String updateTime;
+
+
+}

+ 90 - 0
src/main/java/com/fdkankan/ucenter/entity/SceneApply.java

@@ -0,0 +1,90 @@
+package com.fdkankan.ucenter.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Getter
+@Setter
+@TableName("t_scene_apply")
+public class SceneApply implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 姓名
+     */
+    @TableField("name")
+    private String name;
+
+    /**
+     * 手机号码
+     */
+    @TableField("phone")
+    private String phone;
+
+    /**
+     * 邮箱地址
+     */
+    @TableField("email")
+    private String email;
+
+    /**
+     * 公司
+     */
+    @TableField("company")
+    private String company;
+
+    /**
+     * 行业
+     */
+    @TableField("job")
+    private String job;
+
+    /**
+     * 大洲
+     */
+    @TableField("continent")
+    private String continent;
+
+    /**
+     * 国家
+     */
+    @TableField("country")
+    private String country;
+
+    /**
+     * 备注
+     */
+    @TableField("remark")
+    private String remark;
+
+    @TableField("create_time")
+    private String createTime;
+
+    @TableField("update_time")
+    private String updateTime;
+
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+
+}

+ 1 - 1
src/main/java/com/fdkankan/ucenter/generate/AutoGenerate.java

@@ -18,7 +18,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir") ;
 
         generate(path,"ucenter", getTables(new String[]{
-                "t_virtual_order","t_increment_order","t_download_order"
+                "t_scene_apply",
         }));
 
 //        generate(path,"goods", getTables(new String[]{

+ 18 - 0
src/main/java/com/fdkankan/ucenter/mapper/ICommerceOrderMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.ucenter.mapper;
+
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 商业订单表(八目相机) Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Mapper
+public interface ICommerceOrderMapper extends BaseMapper<CommerceOrder> {
+
+}

+ 22 - 0
src/main/java/com/fdkankan/ucenter/mapper/IExpansionOrderMapper.java

@@ -0,0 +1,22 @@
+package com.fdkankan.ucenter.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
+import com.fdkankan.ucenter.vo.response.ExpansionOrderVo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 扩容订单表(八目相机) Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Mapper
+public interface IExpansionOrderMapper extends BaseMapper<ExpansionOrder> {
+
+    Page<ExpansionOrderVo> pageList(Page<ExpansionOrderVo> page, VirtualOrderParam param);
+}

+ 18 - 0
src/main/java/com/fdkankan/ucenter/mapper/IGoodsSkuMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.ucenter.mapper;
+
+import com.fdkankan.ucenter.entity.GoodsSku;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 商品sku表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Mapper
+public interface IGoodsSkuMapper extends BaseMapper<GoodsSku> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/ucenter/mapper/ISceneApplyMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.ucenter.mapper;
+
+import com.fdkankan.ucenter.entity.SceneApply;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Mapper
+public interface ISceneApplyMapper extends BaseMapper<SceneApply> {
+
+}

+ 5 - 0
src/main/java/com/fdkankan/ucenter/mapper/IVirtualOrderMapper.java

@@ -1,7 +1,11 @@
 package com.fdkankan.ucenter.mapper;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fdkankan.ucenter.entity.VirtualOrder;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
+import com.fdkankan.ucenter.vo.response.VirtualOrderVo;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
@@ -15,4 +19,5 @@ import org.apache.ibatis.annotations.Mapper;
 @Mapper
 public interface IVirtualOrderMapper extends BaseMapper<VirtualOrder> {
 
+    Page<VirtualOrderVo> pageList(Page<VirtualOrderVo> page, VirtualOrderParam param);
 }

File diff suppressed because it is too large
+ 91 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/AlipayDefaultConfig.java


+ 81 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayConfig.java

@@ -0,0 +1,81 @@
+package com.fdkankan.ucenter.pay.alipay.sdk;
+
+import com.alipay.demo.trade.service.AlipayTradeService;
+import com.alipay.demo.trade.service.impl.AlipayTradeServiceImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+@Component
+public abstract class AlipayConfig {
+
+    /** 签名类型 */
+    private String signType = "RSA2";
+    /** 格式 */
+    private String formate = "json";
+    /** 编码 */
+    private String charset = "UTF-8";
+    /** 最大查询次数 */
+    private int maxQueryRetry = 5;
+    /** 查询间隔(毫秒) */
+    private long queryDuration = 5000;
+    /** 最大撤销次数 */
+    private int maxCancelRetry = 3;
+    /** 撤销间隔(毫秒) */
+    private long cancelDuration = 3000;
+
+    /** 支付宝gatewayUrl */
+    abstract public String getGatewayUrl();
+
+    /** 商户应用id */
+    abstract public String getAppid();
+
+    /** RSA私钥,用于对商户请求报文加签 */
+    abstract public String getAppPrivateKey();
+
+    /** 支付宝RSA公钥,用于验签支付宝应答 */
+    abstract public String getAlipayPublicKey();
+
+    /** 同步地址 */
+    abstract public String getReturnUrl();
+    /** 异步地址 */
+    abstract public String getNotifyUrl();
+
+    public String getSignType(){
+        return signType;
+    }
+
+    public String getFormate(){
+        return formate;
+    }
+
+    public String getCharset(){
+        return charset;
+    }
+
+    public int getMaxQueryRetry() {
+        return maxQueryRetry;
+    }
+
+    public long getQueryDuration() {
+        return queryDuration;
+    }
+
+    public int getMaxCancelRetry() {
+        return maxCancelRetry;
+    }
+
+    public long getCancelDuration() {
+        return cancelDuration;
+    }
+
+    @Bean
+    public AlipayTradeService alipayTradeService() {
+        return new AlipayTradeServiceImpl.ClientBuilder()
+                .setGatewayUrl(getGatewayUrl())
+                .setAppid(getAppid())
+                .setPrivateKey(getAppPrivateKey())
+                .setAlipayPublicKey(getAlipayPublicKey())
+                .setSignType(getSignType())
+                .build();
+    }
+}

+ 60 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayGoodsDetail.java

@@ -0,0 +1,60 @@
+package com.fdkankan.ucenter.pay.alipay.sdk;
+
+import java.io.Serializable;
+
+public class AlipayGoodsDetail implements Serializable {
+
+    private static final long serialVersionUID = -8875896136641533825L;
+
+    public AlipayGoodsDetail() {
+    }
+
+    public static AlipayGoodsDetail newInstance(String goodsId, String goodsName, long price, int quantity) {
+        AlipayGoodsDetail info = new AlipayGoodsDetail();
+        info.setGoodsId(goodsId);
+        info.setGoodsName(goodsName);
+        info.setPrice(price);
+        info.setQuantity(quantity);
+        return info;
+    }
+    // 必填,商品的编号,length=32
+    private String goodsId;
+    // 必填,商品的名称,length=256
+    private String goodsName;
+    // 必填,商品数量
+    private int quantity;
+    // 必填,商品单价,单位为元
+    private long price;
+
+    public String getGoodsId() {
+        return goodsId;
+    }
+
+    public void setGoodsId(String goodsId) {
+        this.goodsId = goodsId;
+    }
+
+    public String getGoodsName() {
+        return goodsName;
+    }
+
+    public void setGoodsName(String goodsName) {
+        this.goodsName = goodsName;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+    public long getPrice() {
+        return price;
+    }
+
+    public void setPrice(long price) {
+        this.price = price;
+    }
+}

+ 160 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayService.java

@@ -0,0 +1,160 @@
+package com.fdkankan.ucenter.pay.alipay.sdk;
+
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayResponse;
+import com.alipay.api.domain.TradeFundBill;
+import com.alipay.api.response.AlipayTradePrecreateResponse;
+import com.alipay.api.response.AlipayTradeQueryResponse;
+import com.alipay.demo.trade.model.GoodsDetail;
+import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
+import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
+import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
+import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
+import com.alipay.demo.trade.service.AlipayTradeService;
+import com.alipay.demo.trade.utils.Utils;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Log4j2
+@Service
+public class AlipayService {
+
+    @Autowired
+    private AlipayTradeService alipayTradeService;
+
+    /**
+     * 当面付-扫码付
+     *
+     * 扫码支付,指用户打开支付宝钱包中的“扫一扫”功能,扫描商户针对每个订单实时生成的订单二维码,并在手机端确认支付。
+     *
+     * 发起预下单请求,同步返回订单二维码
+     *
+     * 适用场景:商家获取二维码展示在屏幕上,然后用户去扫描屏幕上的二维码
+     * @return
+     * @throws AlipayApiException
+     */
+    public Map<String, String> tradePrecreate(AlipaymentEx alipaymentEx, String notifyUrl) throws AlipayApiException {
+        if (StringUtils.isEmpty(alipaymentEx.getOutTradeNo())){
+            throw new AlipayApiException("outTradeNo should not be null");
+        }else if (StringUtils.isEmpty(alipaymentEx.getSubject())){
+            throw new AlipayApiException("subject should not be null");
+        }else if (StringUtils.isEmpty(alipaymentEx.getBody())){
+            throw new AlipayApiException("body should not be null");
+        }else if (alipaymentEx.getTotalAmount() == null){
+            throw new AlipayApiException("totalAmout should not be null");
+        }else if (StringUtils.isEmpty(alipaymentEx.getStoreId())){
+            throw new AlipayApiException("storeid should not be null");
+        }else if (alipaymentEx.getGoodsDetailList() == null || alipaymentEx.getGoodsDetailList().size() == 0){
+            throw new AlipayApiException("goodsDetailList should not be null");
+        }else if (StringUtils.isEmpty(notifyUrl)){
+            throw new AlipayApiException("notifyUrl should not be null");
+        }
+
+        List<AlipayGoodsDetail> alipayGoodsDetails = alipaymentEx.getGoodsDetailList();
+        List<GoodsDetail> goodsDetailList = new ArrayList<>();
+        for (AlipayGoodsDetail alipayGoodsDetail : alipayGoodsDetails){
+            GoodsDetail goods1 = GoodsDetail.newInstance(alipayGoodsDetail.getGoodsId(),
+                    alipayGoodsDetail.getGoodsName(), alipayGoodsDetail.getPrice(), alipayGoodsDetail.getQuantity());
+            goodsDetailList.add(goods1);
+        }
+
+        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
+                .setSubject(alipaymentEx.getSubject())
+                .setTotalAmount(alipaymentEx.getTotalAmount().toString())
+                .setOutTradeNo(alipaymentEx.getOutTradeNo())
+                .setUndiscountableAmount(alipaymentEx.getUndiscountableAmount() == null ? "" : alipaymentEx.getUndiscountableAmount().toString())
+                .setSellerId(alipaymentEx.getSellerId() == null ? "" : alipaymentEx.getSellerId())
+                .setBody(alipaymentEx.getBody())
+                .setOperatorId(alipaymentEx.getOperatorId() == null ? "" : alipaymentEx.getOperatorId())
+                .setStoreId(alipaymentEx.getStoreId())
+                .setTimeoutExpress(alipaymentEx.getTimeoutExpress())
+                //支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
+                .setNotifyUrl(notifyUrl)
+                .setGoodsDetailList(goodsDetailList);
+
+        Map<String, String> resp = new HashMap<>();
+        AlipayF2FPrecreateResult result = alipayTradeService.tradePrecreate(builder);
+        AlipayTradePrecreateResponse res = result.getResponse();
+        switch (result.getTradeStatus()) {
+            case SUCCESS:
+                dumpResponse(res);
+                log.info("支付宝预下单成功。");
+                resp.put("code", "0");
+                resp.put("out_trade_no", res.getOutTradeNo());
+                resp.put("qr_code", res.getQrCode());
+                break;
+
+            case FAILED:
+                log.error("支付宝预下单失败,code:" + res.getCode() + ",msg:" + res.getMsg());
+                resp.put("code", "-1");
+                break;
+
+            case UNKNOWN:
+                log.error("系统异常,预下单状态未知,code:" + res.getCode() + ",msg:" + res.getMsg());
+                resp.put("code", "-2");
+                break;
+
+            default:
+                log.error("不支持的交易状态,交易返回异常,code:" + res.getCode() + ",msg:" + res.getMsg());
+                resp.put("code", "-3");
+                break;
+        }
+        return resp;
+    }
+
+    public String tradeQuery(String outTradeNo) {
+        // (必填) 商户订单号,通过此商户订单号查询当面付的交易状态
+        String Type;
+        // 创建查询请求builder,设置请求参数
+        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
+                .setOutTradeNo(outTradeNo);
+        System.out.println("请求参数:" + builder);
+        AlipayF2FQueryResult result = alipayTradeService.queryTradeResult(builder);
+        switch (result.getTradeStatus()) {
+            case SUCCESS:
+                log.info("查询返回该订单支付成功: )");
+                Type = "SUCCESS";
+                AlipayTradeQueryResponse response = result.getResponse();
+                dumpResponse(response);
+                log.info(response.getTradeStatus());
+                if (Utils.isListNotEmpty(response.getFundBillList())) {
+                    for (TradeFundBill bill : response.getFundBillList()) {
+                        log.info(bill.getFundChannel() + ":" + bill.getAmount());
+                    }
+                }
+                break;
+            case FAILED:
+                log.error("查询返回该订单支付失败或被关闭!!!");
+                Type = "FAILED";
+                break;
+            case UNKNOWN:
+                log.error("系统异常,订单支付状态未知!!!");
+                Type = "UNKNOWN";
+                break;
+            default:
+                log.error("不支持的交易状态,交易返回异常!!!");
+                Type = "default";
+                break;
+        }
+        return Type;
+    }
+
+    // 简单打印应答
+    private void dumpResponse(AlipayResponse response) {
+        if (response != null) {
+            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
+            if (StringUtils.isNotEmpty(response.getSubCode())) {
+                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
+                        response.getSubMsg()));
+            }
+            log.info("body:" + response.getBody());
+        }
+    }
+}

+ 38 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipayUtil.java

@@ -0,0 +1,38 @@
+package com.fdkankan.ucenter.pay.alipay.sdk;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+import java.awt.image.BufferedImage;
+import java.util.Hashtable;
+import java.util.Map;
+
+public class AlipayUtil {
+
+    /**
+     * 根据url生成二位图片对象
+     *
+     * @param codeUrl
+     * @return
+     * @throws WriterException
+     */
+    public static BufferedImage getQRCodeImge(String codeUrl) throws WriterException {
+        Map<EncodeHintType, Object> hints = new Hashtable();
+        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
+        hints.put(EncodeHintType.CHARACTER_SET, "UTF8");
+        int width = 300;
+        BitMatrix bitMatrix = (new MultiFormatWriter()).encode(codeUrl, BarcodeFormat.QR_CODE, width, width, hints);
+        BufferedImage image = new BufferedImage(width, width, 1);
+        for(int x = 0; x < width; ++x) {
+            for(int y = 0; y < width; ++y) {
+                image.setRGB(x, y, bitMatrix.get(x, y) ? -16777216 : -1);
+            }
+        }
+
+        return image;
+    }
+}

+ 113 - 0
src/main/java/com/fdkankan/ucenter/pay/alipay/sdk/AlipaymentEx.java

@@ -0,0 +1,113 @@
+package com.fdkankan.ucenter.pay.alipay.sdk;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+public class AlipaymentEx implements Serializable {
+
+    private static final long serialVersionUID = 8082279987959002563L;
+    // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线,
+    private String outTradeNo;
+    // (必填) 订单标题,粗略描述用户的支付目的。如“喜士多(浦东店)消费”
+    private String subject;
+    // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元"
+    private String body;
+    // (必填) 订单总金额,单位为元,不能超过1亿元
+    // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
+    private BigDecimal totalAmount;
+    // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段
+    // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
+    private BigDecimal undiscountableAmount;
+    // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号)
+    // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID
+    private String sellerId;
+    // (必填) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持
+    private String storeId;
+    // 商户操作员编号,添加此参数可以为商户操作员做销售统计
+    private String operatorId;
+    // 支付超时,线下扫码交易定义为5分钟
+    private String timeoutExpress = "5m";
+    // 商品明细列表,需填写购买商品详细信息
+    private List<AlipayGoodsDetail> goodsDetailList;
+
+    public String getOutTradeNo() {
+        return outTradeNo;
+    }
+
+    public void setOutTradeNo(String outTradeNo) {
+        this.outTradeNo = outTradeNo;
+    }
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getBody() {
+        return body;
+    }
+
+    public void setBody(String body) {
+        this.body = body;
+    }
+
+    public BigDecimal getTotalAmount() {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(BigDecimal totalAmount) {
+        this.totalAmount = totalAmount;
+    }
+
+    public BigDecimal getUndiscountableAmount() {
+        return undiscountableAmount;
+    }
+
+    public void setUndiscountableAmount(BigDecimal undiscountableAmount) {
+        this.undiscountableAmount = undiscountableAmount;
+    }
+
+    public String getSellerId() {
+        return sellerId;
+    }
+
+    public void setSellerId(String sellerId) {
+        this.sellerId = sellerId;
+    }
+
+    public String getStoreId() {
+        return storeId;
+    }
+
+    public void setStoreId(String storeId) {
+        this.storeId = storeId;
+    }
+
+    public String getOperatorId() {
+        return operatorId;
+    }
+
+    public void setOperatorId(String operatorId) {
+        this.operatorId = operatorId;
+    }
+
+    public String getTimeoutExpress() {
+        return timeoutExpress;
+    }
+
+    public void setTimeoutExpress(String timeoutExpress) {
+        this.timeoutExpress = timeoutExpress;
+    }
+
+    public List<AlipayGoodsDetail> getGoodsDetailList() {
+        return goodsDetailList;
+    }
+
+    public void setGoodsDetailList(List<AlipayGoodsDetail> goodsDetailList) {
+        this.goodsDetailList = goodsDetailList;
+    }
+}

+ 14 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/PayEntity.java

@@ -0,0 +1,14 @@
+package com.fdkankan.ucenter.pay.factory;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+
+public interface PayEntity {
+
+    JSONObject scanPay(PlaceOrderParam order) throws Exception;
+
+    JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception;
+
+    String getType();
+
+}

+ 39 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/PayFactory.java

@@ -0,0 +1,39 @@
+package com.fdkankan.ucenter.pay.factory;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.util.SpringUtil;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+@Slf4j
+public class PayFactory implements InitializingBean {
+
+    @Autowired
+    private SpringUtil applicationContextHelper;
+
+    private Map<String, PayEntity> payMap = new ConcurrentHashMap<>();
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        Map<String, PayEntity> payHandles = applicationContextHelper.getBeansOfType(PayEntity.class);
+        for (Map.Entry<String, PayEntity> payHandle : payHandles.entrySet()) {
+            payMap.put(payHandle.getValue().getType(), payHandle.getValue());
+        }
+    }
+
+    public JSONObject scanPay(String type, PlaceOrderParam order) throws Exception {
+        log.warn("scanPay:" + type + "_" + order.getOrderType() + "----------payMap:" + payMap.get(type + "_" + order.getOrderType()));
+        return payMap.get(type + "_" + order.getOrderType()).scanPay(order);
+    }
+
+    public JSONObject h5Pay(String type, PlaceOrderParam order, String ipAddr) throws Exception {
+        return payMap.get(type + "_" + order.getOrderType()).h5Pay(order, ipAddr);
+    }
+}

+ 264 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/PayOrderService.java

@@ -0,0 +1,264 @@
+package com.fdkankan.ucenter.pay.factory.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.AlipayTradeWapPayModel;
+import com.alipay.api.request.AlipayTradeWapPayRequest;
+import com.fdkankan.common.constant.ConstantFilePath;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.MD5;
+import com.fdkankan.ucenter.pay.alipay.AlipayDefaultConfig;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayService;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayUtil;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipaymentEx;
+import com.fdkankan.ucenter.pay.paypal.sdk.PayPalmentEx;
+import com.fdkankan.ucenter.pay.paypal.sdk.PaypalService;
+import com.fdkankan.ucenter.pay.wx.WXPay;
+import com.fdkankan.ucenter.pay.wx.WXPayDefaultConfig;
+import com.fdkankan.ucenter.pay.wx.WXPayUtil;
+import com.paypal.api.payments.Links;
+import com.paypal.api.payments.Payment;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+@Service
+@Slf4j
+public class PayOrderService {
+
+    @Autowired
+    private AlipayService alipayService;
+    @Autowired
+    private AlipayDefaultConfig alipayDefaultConfig;
+    @Autowired
+    private PaypalService paypalService;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    public JSONObject aliPayScanPay(String orderSn, String subject, String body, BigDecimal totalFee, List<AlipayGoodsDetail> goodsDetailList) throws Exception{
+        AlipaymentEx alipaymentEx = new AlipaymentEx();
+        alipaymentEx.setOutTradeNo(orderSn);
+        alipaymentEx.setSubject(subject);
+        alipaymentEx.setBody(body);
+        alipaymentEx.setTotalAmount(totalFee);
+        alipaymentEx.setStoreId("test_store_id");
+        alipaymentEx.setOperatorId("test_operator_id");
+        alipaymentEx.setTimeoutExpress("120m");
+        alipaymentEx.setGoodsDetailList(goodsDetailList);
+        String pngPath = ConstantFilePath.ALI_QRCODE_FOLDER + orderSn + ".png";
+        try {
+            Map<String, String> alipayMap = alipayService.tradePrecreate(alipaymentEx, mainUrl + alipayDefaultConfig.getNotifyUrl());
+            if ("0".equals(alipayMap.get("code"))){
+                BufferedImage image = AlipayUtil.getQRCodeImge(alipayMap.get("qr_code"));
+                File file = new File(pngPath);
+                if (file.exists()){
+                    file.delete();
+                }
+                ImageIO.write(image, "png", file);
+            }else{
+                throw new BusinessException(ErrorCode.ERROR_MSG);
+            }
+        } catch (AlipayApiException e) {
+           log.error(e.getMessage());
+            throw new BusinessException(ErrorCode.ERROR_MSG);
+        }
+
+        JSONObject j = new JSONObject();
+        j.put("src", pngPath.replace(ConstantFilePath.BASE_PATH, ""));
+        j.put("price", totalFee);
+        return j;
+    }
+
+    public JSONObject aliPayH5Pay(String orderSn, String subject, String body, BigDecimal totalFee) {
+        // 超时时间 可空
+        String timeoutExpress = "2m";
+        // 销售产品码 必填
+        String productCode = "QUICK_WAP_WAY";
+        /**********************/
+        // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
+        //调用RSA签名方式,这个不用你管,只要你配置文件是正确的
+        AlipayClient client = new DefaultAlipayClient(alipayDefaultConfig.getGatewayUrl(),
+                alipayDefaultConfig.getAppid(), alipayDefaultConfig.getAppPrivateKey(), alipayDefaultConfig.getFormate(),
+                alipayDefaultConfig.getCharset(), alipayDefaultConfig.getAlipayPublicKey(), alipayDefaultConfig.getSignType());
+        AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();
+        // 封装请求支付信息
+        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
+        //带!的都是你需要传递的参数 其他的是支付宝必须的
+        //!本地生成的订单编号
+        model.setOutTradeNo(orderSn);
+        //!商品名称
+        model.setSubject(subject);
+        //!商品价格
+        model.setTotalAmount(String.valueOf(totalFee));
+        //!商品介绍
+        model.setBody(body);
+        //超时时间
+        model.setTimeoutExpress(timeoutExpress);
+        //产品销售码
+        model.setProductCode(productCode);
+        //将参数传入到 BizModel中
+        alipayRequest.setBizModel(model);
+        //异步回调地址
+        alipayRequest.setNotifyUrl(mainUrl + alipayDefaultConfig.getNotifyUrl());
+        //同步回调地址
+        alipayRequest.setReturnUrl(mainUrl + alipayDefaultConfig.getReturnUrl());
+
+        String result = "";
+        try {
+            // 调用SDK生成表单
+            //get方式生成表单 主要解决在微信中对支付宝屏蔽问题,如果不是在微信中可post提交,将form的注释解开,result注释掉即可
+            result = client.pageExecute(alipayRequest, "get").getBody();
+            log.warn("支付宝调用SDK生成表单:" + result);
+            //form = client.pageExecute(alipay_request).getBody();
+//                System.out.println(form);
+        } catch (AlipayApiException e) {
+            e.printStackTrace();
+            log.error("生成表单失败!");
+        }
+        JSONObject j = new JSONObject();
+        j.put("form", result);
+        return j;
+    }
+
+    public JSONObject payPalPay(String orderSn, String subject, String body, BigDecimal totalFee, BigDecimal goodsFee, String successUrl, String cancelUrl) throws Exception {
+        PayPalmentEx payPalmentEx = new PayPalmentEx();
+        payPalmentEx.setOrderSn(orderSn);
+        payPalmentEx.setOrderTotal(totalFee);
+        payPalmentEx.setSubTotal(goodsFee);
+        payPalmentEx.setDescription(body);
+
+        Payment payment = paypalService.createPayment(payPalmentEx, successUrl, cancelUrl);
+        for(Links links : payment.getLinks()){
+            if(links.getRel().equals("approval_url")){
+                // 客户付款登陆地址
+                JSONObject j = new JSONObject();
+                j.put("redirect", links.getHref());
+                j.put("price", totalFee);
+                return j;
+            }
+        }
+        throw new BusinessException(ErrorCode.FAILURE_CODE_8002);
+    }
+
+    public JSONObject wechatScanPay(String orderSn, String subject, String body, BigDecimal totalFee) throws Exception {
+        WXPayDefaultConfig config = new WXPayDefaultConfig();
+        WXPay wxPay = new WXPay(config);
+
+        Map<String, String> data = new HashMap<String, String>();
+        data.put("body", body);
+        data.put("detail", subject);
+        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
+        data.put("device_info", "WEB");
+        data.put("fee_type", "CNY");
+        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
+        data.put("spbill_create_ip", config.getCreateIP());
+        data.put("notify_url", mainUrl + config.getNotifyURL());
+        data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
+        data.put("product_id", orderSn); //多个商品,使用订单号
+
+        String pngPath = ConstantFilePath.WEIXIN_QRCODE_FOLDER + orderSn + ".png";
+        try {
+            //发起支付
+            Map<String, String> resp = wxPay.unifiedOrder(data);
+            BufferedImage image = AlipayUtil.getQRCodeImge(resp.get("code_url"));
+            File file = new File(pngPath);
+            if (file.exists()){
+                file.delete();
+            }
+            ImageIO.write(image, "png", file);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            throw new BusinessException(ErrorCode.ERROR_MSG);
+        }
+        JSONObject j = new JSONObject();
+        j.put("src", pngPath.replace(ConstantFilePath.BASE_PATH, ""));
+        j.put("price", totalFee.divide(new BigDecimal("100"), 2));
+        return j;
+    }
+
+    public JSONObject wechatH5Pay(String orderSn, String subject, String body, BigDecimal totalFee, String ipAddress) throws Exception {
+        log.warn("ipAddress:"+ipAddress);
+        WXPayDefaultConfig config = new WXPayDefaultConfig();
+        WXPay wxPay = new WXPay(config);
+
+        Map<String, String> data = new HashMap<String, String>();
+        data.put("body", subject);
+        data.put("detail", body);
+        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
+        data.put("device_info", "H5");
+        data.put("fee_type", "CNY");
+        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
+        data.put("spbill_create_ip", ipAddress);
+        data.put("notify_url", mainUrl + config.getNotifyURL());
+        data.put("trade_type", "MWEB");  // 此处指定为扫码支付
+        data.put("product_id", orderSn); //多个商品,使用订单号
+        data.put("nonce_str", MD5.getMessageDigest(String.valueOf(new Random().nextInt(10000)).getBytes()));
+
+        String mweb_url = "";
+        Map<String, String> resp = wxPay.unifiedOrder(data);
+        log.warn("wechatH5Pay" + resp);
+        String return_code = resp.get("return_code");
+        String return_msg = resp.get("return_msg");
+        if ("SUCCESS".equals(return_code) && "OK".equals(return_msg)) {
+            mweb_url = resp.get("mweb_url");//调微信支付接口地址
+            mweb_url += "&redirect_url=" + URLEncoder.encode(mainUrl + config.getH5RedirectURL(), "UTF-8");
+            log.warn("mweb_url=" + mweb_url);
+        } else {
+            log.error("微信统一支付接口获取预支付订单出错");
+        }
+        JSONObject j = new JSONObject();
+        j.put("mweb_url", mweb_url);
+        return j;
+    }
+
+    public Map<String, String> wechatPay(String orderSn, String subject, String body, BigDecimal totalFee, String ipAddress, String openid) throws Exception {
+        WXPayDefaultConfig config = new WXPayDefaultConfig();
+        WXPay wxPay = new WXPay(config);
+
+        Map<String, String> data = new HashMap<String, String>();
+        data.put("body", subject);
+        data.put("detail", body);
+        data.put("out_trade_no", orderSn + "_" + new Random().nextInt(100));
+        data.put("device_info", "wechat");
+        data.put("fee_type", "CNY");
+        data.put("total_fee", totalFee.stripTrailingZeros().toPlainString());
+        data.put("spbill_create_ip", ipAddress);
+        data.put("notify_url", mainUrl + config.getNotifyURL());
+        data.put("trade_type", "JSAPI");
+        data.put("product_id", orderSn);
+        data.put("openid", openid);
+
+        Map<String, String> resp = wxPay.unifiedOrder(data);
+        log.warn("wechatPay" + resp);
+
+        Map<String, String> sign = new HashMap<>();
+        sign.put("package", "prepay_id="+resp.get("prepay_id"));
+        sign.put("appId", config.getAppID());
+        sign.put("timeStamp",String.valueOf(System.currentTimeMillis() / 1000));
+        sign.put("nonceStr", resp.get("nonce_str"));
+        sign.put("signType", "MD5");
+        String paySign = WXPayUtil.generateSignature(sign, config.getKey());
+
+        resp.put("signType", "MD5");
+        resp.put("paySign", paySign);
+        log.warn("wechatPay" + resp);
+        return resp;
+    }
+
+}

+ 58 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/AlipayCommerce.java

@@ -0,0 +1,58 @@
+package com.fdkankan.ucenter.pay.factory.impl.commerce;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.ICommerceOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class AlipayCommerce implements PayEntity {
+
+    @Autowired
+    private ICommerceOrderService commerceOrderService;
+    @Autowired
+    private PayOrderService payOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        CommerceOrder commerce = commerceOrderService.getById(order.getOrderId());
+        if (commerce == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.COMMERCE_SUBJECT;
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        AlipayGoodsDetail goodsDetail = AlipayGoodsDetail.newInstance(commerce.getOrderSn(), subject, commerce.getAmount().intValue(), 1);
+        goodsDetailList.add(goodsDetail);
+        String orderSn = commerce.getOrderSn();
+        orderSn += "_commerce";
+        return payOrderService.aliPayScanPay(orderSn, subject, subject, commerce.getAmount(), goodsDetailList);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        CommerceOrder commerce = commerceOrderService.getById(order.getOrderId());
+        if (commerce == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.COMMERCE_SUBJECT;
+        String orderSn = commerce.getOrderSn();
+        orderSn += "_commerce";
+        return payOrderService.aliPayH5Pay(orderSn, subject, subject, commerce.getAmount());
+    }
+
+    @Override
+    public String getType() {
+        return "alipay_3";
+    }
+}

+ 57 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/PaypalCommerce.java

@@ -0,0 +1,57 @@
+package com.fdkankan.ucenter.pay.factory.impl.commerce;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.ICommerceOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PaypalCommerce implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private ICommerceOrderService commerceOrderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        CommerceOrder commerce = commerceOrderService.getById(order.getOrderId());
+        if (commerce == null) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.COMMERCE_SUBJECT;
+        String orderSn = commerce.getOrderSn();
+        orderSn += "_commerce";
+        return payOrderService.payPalPay(orderSn, subject, subject, commerce.getAmount(), commerce.getAmount(),
+                successUrl,
+                cancelUrl);
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_3";
+    }
+}

+ 55 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/commerce/WechatCommerce.java

@@ -0,0 +1,55 @@
+package com.fdkankan.ucenter.pay.factory.impl.commerce;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.ICommerceOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class WechatCommerce implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private ICommerceOrderService commerceOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        CommerceOrder commerce = commerceOrderService.getById(order.getOrderId());
+        if (commerce == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.COMMERCE_SUBJECT;
+        BigDecimal totalFee = commerce.getAmount().multiply(new BigDecimal(100));
+        String orderSn = commerce.getOrderSn();
+        orderSn += "_commerce";
+        return payOrderService.wechatScanPay(orderSn, subject, subject, totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        CommerceOrder commerce = commerceOrderService.getById(order.getOrderId());
+        if (commerce == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.COMMERCE_SUBJECT;
+        BigDecimal totalFee = commerce.getAmount().multiply(new BigDecimal(100));
+        String orderSn = commerce.getOrderSn();
+        orderSn += "_commerce";
+        return payOrderService.wechatH5Pay(orderSn, subject, subject, totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_3";
+    }
+}

+ 73 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/AlipayDownload.java

@@ -0,0 +1,73 @@
+package com.fdkankan.ucenter.pay.factory.impl.down;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IDownloadOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * 增值权益
+ */
+@Component
+public class AlipayDownload implements PayEntity {
+
+    @Autowired
+    private IDownloadOrderService downloadOrderService;
+    @Autowired
+    private PayOrderService payOrderService;
+
+
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        DownloadOrder downloadOrderEntity = downloadOrderService.getById(order.getOrderId());
+        if (downloadOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(downloadOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.DOWNLOAD_SUBJECT + ":" + downloadOrderEntity.getCount() + "次";
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        AlipayGoodsDetail goodsDetail = AlipayGoodsDetail.newInstance(downloadOrderEntity.getOrderSn(), subject, downloadOrderEntity.getAmount().intValue(), 1);
+        goodsDetailList.add(goodsDetail);
+        String orderSn = downloadOrderEntity.getOrderSn();
+        orderSn += "_download";
+        String body = subject;
+        return payOrderService.aliPayScanPay(orderSn, subject, body, downloadOrderEntity.getAmount(), goodsDetailList);    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        DownloadOrder downloadOrderEntity = downloadOrderService.getById(order.getOrderId());
+        if (downloadOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(downloadOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.DOWNLOAD_SUBJECT + ":" + downloadOrderEntity.getCount() + "次";
+        String orderSn = downloadOrderEntity.getOrderSn();
+        orderSn += "_increment";
+        String body = subject;
+        return payOrderService.aliPayH5Pay(orderSn, subject, body, downloadOrderEntity.getAmount());    }
+
+
+    @Override
+    public String getType() {
+        return "alipay_5";
+    }
+}

+ 58 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/PaypalDownload.java

@@ -0,0 +1,58 @@
+package com.fdkankan.ucenter.pay.factory.impl.down;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.IDownloadOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PaypalDownload implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IDownloadOrderService downloadOrderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        DownloadOrder downloadOrderEntity = downloadOrderService.getById(order.getOrderId());
+        if (downloadOrderEntity == null) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + downloadOrderEntity.getCount() + "次";
+        String orderSn = downloadOrderEntity.getOrderSn();
+        orderSn += "_download";
+        String body = subject;
+        return payOrderService.payPalPay(orderSn, subject, body, downloadOrderEntity.getAmount(), downloadOrderEntity.getAmount(),
+                successUrl,
+                cancelUrl);
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_5";
+    }
+}

+ 65 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/down/WechatDownload.java

@@ -0,0 +1,65 @@
+package com.fdkankan.ucenter.pay.factory.impl.down;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IDownloadOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class WechatDownload implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IDownloadOrderService downloadOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        DownloadOrder downloadOrderEntity = downloadOrderService.getById(order.getOrderId());
+        if (downloadOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(downloadOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.DOWNLOAD_SUBJECT + ":" + downloadOrderEntity.getCount() + "次";
+        BigDecimal totalFee = downloadOrderEntity.getAmount().multiply(new BigDecimal(100));
+        String orderSn = downloadOrderEntity.getOrderSn();
+        String body = subject;
+        orderSn += "_download";
+        return payOrderService.wechatScanPay(orderSn, subject, body, totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        DownloadOrder downloadOrderEntity = downloadOrderService.getById(order.getOrderId());
+        if (downloadOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(downloadOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.DOWNLOAD_SUBJECT + ":" + downloadOrderEntity.getCount() + "次";
+        BigDecimal totalFee = downloadOrderEntity.getAmount().multiply(new BigDecimal(100));
+        String orderSn = downloadOrderEntity.getOrderSn();
+        String body = subject;
+        orderSn += "_download";
+        return payOrderService.wechatH5Pay(orderSn, subject, body, totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_5";
+    }
+}

+ 82 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/AlipayExpansion.java

@@ -0,0 +1,82 @@
+package com.fdkankan.ucenter.pay.factory.impl.expansion;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IExpansionOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class AlipayExpansion implements PayEntity {
+
+    @Autowired
+    private IExpansionOrderService expansionOrderService;
+    @Autowired
+    private PayOrderService payOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        ExpansionOrder expansion = expansionOrderService.getById(order.getOrderId());
+        if (expansion == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(expansion.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String date = "1年";
+        if(expansion.getMonth() < 12){
+            date = expansion.getMonth() + "个月";
+        }
+        String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        AlipayGoodsDetail goodsDetail = AlipayGoodsDetail.newInstance(expansion.getOrderSn(), subject, expansion.getAmount().intValue(), 1);
+        goodsDetailList.add(goodsDetail);
+        String orderSn = expansion.getOrderSn();
+        orderSn += "_expansion";
+        String body = subject;
+        if(order.getSpaceId() != null){
+            body += "_" + order.getSpaceId();
+        }
+        return payOrderService.aliPayScanPay(orderSn, subject, body, expansion.getAmount(), goodsDetailList);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        ExpansionOrder expansion = expansionOrderService.getById(order.getOrderId());
+        if (expansion == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(expansion.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String date = "1年";
+        if(expansion.getMonth() < 12){
+            date = expansion.getMonth() + "个月";
+        }
+        String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+        String orderSn = expansion.getOrderSn();
+        orderSn += "_expansion";
+        String body = subject;
+        if(order.getSpaceId() != null){
+            body += "_" + order.getSpaceId();
+        }
+        return payOrderService.aliPayH5Pay(orderSn, subject, body, expansion.getAmount());
+    }
+
+    @Override
+    public String getType() {
+        return "alipay_2";
+    }
+}

+ 65 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/PaypalExpansion.java

@@ -0,0 +1,65 @@
+package com.fdkankan.ucenter.pay.factory.impl.expansion;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.IExpansionOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PaypalExpansion implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IExpansionOrderService expansionOrderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        ExpansionOrder expansion = expansionOrderService.getById(order.getOrderId());
+        if (expansion == null) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String date = "1年";
+        if(expansion.getMonth() < 12){
+            date = expansion.getMonth() + "个月";
+        }
+        String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+        String orderSn = expansion.getOrderSn();
+        orderSn += "_expansion";
+        String body = subject;
+        if(order.getSpaceId() != null){
+            orderSn += "_" + order.getSpaceId();
+        }
+        return payOrderService.payPalPay(orderSn, subject, body, expansion.getAmount(), expansion.getAmount(),
+                successUrl,
+                cancelUrl);
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_2";
+    }
+}

+ 81 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/expansion/WechatExpansion.java

@@ -0,0 +1,81 @@
+package com.fdkankan.ucenter.pay.factory.impl.expansion;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IExpansionOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class WechatExpansion implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IExpansionOrderService expansionOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        ExpansionOrder expansion = expansionOrderService.getById(order.getOrderId());
+        if (expansion == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(expansion.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String date = "1年";
+        if(expansion.getMonth() < 12){
+            date = expansion.getMonth() + "个月";
+        }
+        String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+        BigDecimal totalFee = expansion.getAmount().multiply(new BigDecimal(100));
+        String orderSn = expansion.getOrderSn();
+        String body = subject;
+        if(order.getSpaceId() != null){
+            orderSn += "_" + order.getSpaceId();
+        }else {
+            orderSn += "_expansion";
+        }
+        return payOrderService.wechatScanPay(orderSn, subject, body, totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        ExpansionOrder expansion = expansionOrderService.getById(order.getOrderId());
+        if (expansion == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(expansion.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String date = "1年";
+        if(expansion.getMonth() < 12){
+            date = expansion.getMonth() + "个月";
+        }
+        String subject = Constant.EXPANSION_SUBJECT + ":" + expansion.getUnitSize() + expansion.getUnit() + "/" + date;
+        BigDecimal totalFee = expansion.getAmount().multiply(new BigDecimal(100));
+        String orderSn = expansion.getOrderSn();
+        String body = subject;
+        if(order.getSpaceId() != null){
+            orderSn += "_" + order.getSpaceId();
+        }else {
+            orderSn += "_expansion";
+        }
+        return payOrderService.wechatH5Pay(orderSn, subject, body, totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_2";
+    }
+}

+ 77 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/AlipayGoods.java

@@ -0,0 +1,77 @@
+package com.fdkankan.ucenter.pay.factory.impl.goods;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.Order;
+import com.fdkankan.ucenter.entity.OrderItem;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IOrderItemService;
+import com.fdkankan.ucenter.service.IOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class AlipayGoods implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IOrderService orderService;
+    @Autowired
+    private IOrderItemService orderItemService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        Order responseOrder = orderService.getById(order.getOrderId());
+        if (responseOrder.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        List<OrderItem> items = orderItemService.getByOrderId(order.getOrderId());
+        StringBuilder sb = new StringBuilder();
+        AlipayGoodsDetail goodsDetail = null;
+        for (int i = 0; i < items.size(); i++){
+            sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+            if (i != items.size() - 1){
+                sb.append(",");
+            }
+
+            goodsDetail = AlipayGoodsDetail.newInstance(items.get(i).getGoodsSn(), items.get(i).getGoodsName(), items.get(i).getGoodsPrice().intValue(), items.get(i).getGoodsCount());
+            goodsDetailList.add(goodsDetail);
+        }
+        String orderSn = responseOrder.getOrderSn();
+        orderSn += "_entity";
+        return payOrderService.aliPayScanPay(orderSn, "四维看看官网-商品", sb.toString(), responseOrder.getTotalAmount(), goodsDetailList);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        Order responseOrder = orderService.getById(order.getOrderId());
+        if (responseOrder.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        List<OrderItem> items = orderItemService.getByOrderId(order.getOrderId());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < items.size(); i++) {
+            sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+            if (i != items.size() - 1) {
+                sb.append(",");
+            }
+        }
+        String orderSn = responseOrder.getOrderSn();
+        orderSn += "_entity";
+        return payOrderService.aliPayH5Pay(orderSn, "四维看看官网-商品", sb.toString(),  responseOrder.getTotalAmount());
+    }
+
+    @Override
+    public String getType() {
+        return "alipay_0";
+    }
+}

+ 72 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/PaypalGoods.java

@@ -0,0 +1,72 @@
+package com.fdkankan.ucenter.pay.factory.impl.goods;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.Order;
+import com.fdkankan.ucenter.entity.OrderItem;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.IOrderItemService;
+import com.fdkankan.ucenter.service.IOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class PaypalGoods implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IOrderService orderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+    @Autowired
+    private IOrderItemService orderItemService;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_0";
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        Order responseOrder = orderService.getById(order.getOrderId());
+        if (responseOrder.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        List<OrderItem> items = orderItemService.getByOrderId(order.getOrderId());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < items.size(); i++) {
+            sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+            if (i != items.size() - 1) {
+                sb.append(",");
+            }
+        }
+        String orderSn = responseOrder.getOrderSn();
+        orderSn += "_entity";
+        return payOrderService.payPalPay(orderSn, sb.toString(), sb.toString(),
+                responseOrder.getTotalAmount(), responseOrder.getGoodsAmount(),
+                successUrl,
+                cancelUrl);
+    }
+}

+ 73 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/goods/WechatGoods.java

@@ -0,0 +1,73 @@
+package com.fdkankan.ucenter.pay.factory.impl.goods;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.Order;
+import com.fdkankan.ucenter.entity.OrderItem;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IOrderItemService;
+import com.fdkankan.ucenter.service.IOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Component
+public class WechatGoods implements PayEntity {
+
+    @Autowired
+    private IOrderService orderService;
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IOrderItemService orderItemService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        Order responseOrder = orderService.getById(order.getOrderId());
+        if (responseOrder.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        List<OrderItem> items = orderItemService.getByOrderId(order.getOrderId());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < items.size(); i++){
+            sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+            if (i != items.size() - 1){
+                sb.append(",");
+            }
+        }
+        BigDecimal totalFee = responseOrder.getTotalAmount().multiply(new BigDecimal(100));
+        String orderSn = responseOrder.getOrderSn();
+        orderSn += "_entity";
+        return payOrderService.wechatScanPay(orderSn, "四维看看官网-商品", sb.toString(), totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        Order responseOrder = orderService.getById(order.getOrderId());
+        if (responseOrder.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        List<OrderItem> items = orderItemService.getByOrderId(order.getOrderId());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < items.size(); i++){
+            sb.append(items.get(i).getGoodsCount()).append("*").append(items.get(i).getGoodsName());
+            if (i != items.size() - 1){
+                sb.append(",");
+            }
+        }
+        BigDecimal totalFee = responseOrder.getTotalAmount().multiply(new BigDecimal(100));
+        String orderSn = responseOrder.getOrderSn();
+        orderSn += "_entity";
+        return payOrderService.wechatH5Pay(orderSn, "四维看看官网-商品", sb.toString(), totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_0";
+    }
+}

+ 72 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/AlipayIncrement.java

@@ -0,0 +1,72 @@
+package com.fdkankan.ucenter.pay.factory.impl.increment;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.IncrementOrder;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IIncrementOrderService;
+import com.fdkankan.ucenter.service.IOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 增值权益
+ */
+@Component
+public class AlipayIncrement implements PayEntity {
+
+    @Autowired
+    private IIncrementOrderService iIncrementOrderService;
+    @Autowired
+    private PayOrderService payOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        IncrementOrder incrementOrderEntity = iIncrementOrderService.getById(order.getOrderId());
+        if (incrementOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(incrementOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年";
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        AlipayGoodsDetail goodsDetail = AlipayGoodsDetail.newInstance(incrementOrderEntity.getOrderSn(), subject, incrementOrderEntity.getAmount().intValue(), 1);
+        goodsDetailList.add(goodsDetail);
+        String orderSn = incrementOrderEntity.getOrderSn();
+        orderSn += "_increment";
+        String body = subject;
+        return payOrderService.aliPayScanPay(orderSn, subject, body, incrementOrderEntity.getAmount(), goodsDetailList);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        IncrementOrder incrementOrderEntity = iIncrementOrderService.getById(order.getOrderId());
+        if (incrementOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(incrementOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年";
+        String orderSn = incrementOrderEntity.getOrderSn();
+        orderSn += "_increment";
+        String body = subject;
+        return payOrderService.aliPayH5Pay(orderSn, subject, body, incrementOrderEntity.getAmount());
+    }
+
+    @Override
+    public String getType() {
+        return "alipay_4";
+    }
+}

+ 58 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/PaypalIncrement.java

@@ -0,0 +1,58 @@
+package com.fdkankan.ucenter.pay.factory.impl.increment;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.IncrementOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.IIncrementOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PaypalIncrement implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IIncrementOrderService incrementOrderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        IncrementOrder incrementOrderEntity = incrementOrderService.getById(order.getOrderId());
+        if (incrementOrderEntity == null) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年";
+        String orderSn = incrementOrderEntity.getOrderSn();
+        orderSn += "_increment";
+        String body = subject;
+        return payOrderService.payPalPay(orderSn, subject, body, incrementOrderEntity.getAmount(), incrementOrderEntity.getAmount(),
+                successUrl,
+                cancelUrl);
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_4";
+    }
+}

+ 65 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/increment/WechatIncrement.java

@@ -0,0 +1,65 @@
+package com.fdkankan.ucenter.pay.factory.impl.increment;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.IncrementOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IIncrementOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class WechatIncrement implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IIncrementOrderService incrementOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        IncrementOrder incrementOrderEntity = incrementOrderService.getById(order.getOrderId());
+        if (incrementOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(incrementOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年";
+        BigDecimal totalFee = incrementOrderEntity.getAmount().multiply(new BigDecimal(100));
+        String orderSn = incrementOrderEntity.getOrderSn();
+        String body = subject;
+        orderSn += "_increment";
+        return payOrderService.wechatScanPay(orderSn, subject, body, totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        IncrementOrder incrementOrderEntity = incrementOrderService.getById(order.getOrderId());
+        if (incrementOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        //订单金额为国外金额就报错
+        if(incrementOrderEntity.getAbroad() == 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8004);
+        }
+        String subject = Constant.INCREMENT_SUBJECT + ":" + incrementOrderEntity.getCount() + "个/年";
+        BigDecimal totalFee = incrementOrderEntity.getAmount().multiply(new BigDecimal(100));
+        String orderSn = incrementOrderEntity.getOrderSn();
+        String body = subject;
+        orderSn += "_increment";
+        return payOrderService.wechatH5Pay(orderSn, subject, body, totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_4";
+    }
+}

+ 59 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/AlipayRecharge.java

@@ -0,0 +1,59 @@
+package com.fdkankan.ucenter.pay.factory.impl.recharge;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.VirtualOrder;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayGoodsDetail;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IVirtualOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class AlipayRecharge implements PayEntity {
+
+    @Autowired
+    private IVirtualOrderService virtualOrderService;
+    @Autowired
+    private PayOrderService payOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        VirtualOrder virtualOrderEntity = virtualOrderService.getById(order.getOrderId());
+        if (virtualOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints();
+        List<AlipayGoodsDetail> goodsDetailList = new ArrayList<>();
+        AlipayGoodsDetail goodsDetail = AlipayGoodsDetail.newInstance(virtualOrderEntity.getOrderSn(), subject, new BigDecimal(virtualOrderEntity.getPoints()).intValue(), 1);
+        goodsDetailList.add(goodsDetail);
+        String orderSn = virtualOrderEntity.getOrderSn();
+        orderSn += "_recharge";
+        return payOrderService.aliPayScanPay(orderSn, subject, subject, new BigDecimal(virtualOrderEntity.getPoints()), goodsDetailList);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        VirtualOrder virtualOrderEntity = virtualOrderService.getById(order.getOrderId());
+        if (virtualOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints();
+        String orderSn = virtualOrderEntity.getOrderSn();
+        orderSn += "_recharge";
+        return payOrderService.aliPayH5Pay(orderSn, subject, subject, new BigDecimal(virtualOrderEntity.getPoints()));
+    }
+
+    @Override
+    public String getType() {
+        return "alipay_1";
+    }
+}

+ 60 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/PaypalRecharge.java

@@ -0,0 +1,60 @@
+package com.fdkankan.ucenter.pay.factory.impl.recharge;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.VirtualOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.fdkankan.ucenter.service.IVirtualOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class PaypalRecharge implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IVirtualOrderService virtualOrderService;
+    @Autowired
+    private PayPalDefaultConfig payPalDefaultConfig;
+
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getPaySuccessUrl(), mainUrl + payPalDefaultConfig.getCancelUrl());
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        return getResult(order, mainUrl + payPalDefaultConfig.getH5PaySuccessUrl(), mainUrl + payPalDefaultConfig.getH5CancelUrl());
+    }
+
+    private JSONObject getResult(PlaceOrderParam order, String successUrl, String cancelUrl) throws Exception {
+        VirtualOrder virtualOrderEntity = virtualOrderService.getById(order.getOrderId());
+        if (virtualOrderEntity == null) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints();
+        String orderSn = virtualOrderEntity.getOrderSn();
+        orderSn += "_recharge";
+        return payOrderService.payPalPay(orderSn, subject, subject,
+                new BigDecimal(virtualOrderEntity.getPoints()), new BigDecimal(virtualOrderEntity.getPoints()),
+                successUrl,
+                cancelUrl);
+    }
+
+    @Override
+    public String getType() {
+        return "paypal_1";
+    }
+}

+ 55 - 0
src/main/java/com/fdkankan/ucenter/pay/factory/impl/recharge/WechatRecharge.java

@@ -0,0 +1,55 @@
+package com.fdkankan.ucenter.pay.factory.impl.recharge;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.Constant;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.ucenter.entity.VirtualOrder;
+import com.fdkankan.ucenter.pay.factory.PayEntity;
+import com.fdkankan.ucenter.pay.factory.impl.PayOrderService;
+import com.fdkankan.ucenter.service.IVirtualOrderService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Component
+public class WechatRecharge implements PayEntity {
+
+    @Autowired
+    private PayOrderService payOrderService;
+    @Autowired
+    private IVirtualOrderService virtualOrderService;
+
+    @Override
+    public JSONObject scanPay(PlaceOrderParam order) throws Exception {
+        VirtualOrder virtualOrderEntity = virtualOrderService.getById(order.getOrderId());
+        if (virtualOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints();
+        BigDecimal totalFee = new BigDecimal(virtualOrderEntity.getPoints()).multiply(new BigDecimal(100));
+        String orderSn = virtualOrderEntity.getOrderSn();
+        orderSn += "_recharge";
+        return payOrderService.wechatScanPay(orderSn, subject, subject, totalFee);
+    }
+
+    @Override
+    public JSONObject h5Pay(PlaceOrderParam order, String ip) throws Exception {
+        VirtualOrder virtualOrderEntity = virtualOrderService.getById(order.getOrderId());
+        if (virtualOrderEntity == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_8001);
+        }
+        String subject = Constant.PAY_SUBJECT + ":" + virtualOrderEntity.getPoints();
+        BigDecimal totalFee = new BigDecimal(virtualOrderEntity.getPoints()).multiply(new BigDecimal(100));
+        String orderSn = virtualOrderEntity.getOrderSn();
+        orderSn += "_recharge";
+        return payOrderService.wechatH5Pay(orderSn, subject, subject, totalFee, ip);
+    }
+
+    @Override
+    public String getType() {
+        return "wechat_1";
+    }
+}

+ 56 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/PayPalDefaultConfig.java

@@ -0,0 +1,56 @@
+package com.fdkankan.ucenter.pay.paypal;
+
+import com.fdkankan.ucenter.pay.paypal.sdk.PayPalConfig;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PayPalDefaultConfig extends PayPalConfig {
+
+    @Override
+    public String getClientId() {
+        return "AZJEGWlvvI2q52bR4k_mC1ftW8tEnlaJj30huGQTBsdAjwmKlMDiEiMixVKbfrdw6fB55NSj_BAE8FPP";
+    }
+
+    @Override
+    public String getSecret() {
+        return "EL-RGNmsbFpcKT7QuIlxMxX7MQplp8rCyaGDZ5KOCMQ9BkOhY5OYZyVInAeHT8_4tXoPth8tOEZY_3s_";
+    }
+
+    @Override
+    public String getMode() {
+        return "live";
+    }
+
+    public String getPaySuccessUrl(){
+        return "api/order/pay/paypal/callback";
+    }
+
+    public String getH5PaySuccessUrl(){
+        return "api/order/pay/paypal/callbackH5";
+    }
+
+    public String getCancelUrl(){
+        return "api/order/pay/paypal/cancel";
+    }
+
+    public String getH5CancelUrl(){
+        return "api/order/pay/paypal/cancelH5";
+    }
+
+    public String getSuccessUrl(){
+        return "index.html#/payresult/success/recharge";
+    }
+
+    public String getFailUrl(){
+        return "#/payresult/fail/recharge";
+    }
+
+    public String getH5SuccessUrl(){
+        return "mobile.html#/payresult/success";
+    }
+
+    public String getH5FailUrl(){
+        return "mobile.html#/payresult/fail";
+    }
+
+}

+ 43 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PayPalConfig.java

@@ -0,0 +1,43 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import com.paypal.base.rest.APIContext;
+import com.paypal.base.rest.OAuthTokenCredential;
+import com.paypal.base.rest.PayPalRESTException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@Component
+public abstract class PayPalConfig {
+
+    abstract public String getClientId();
+
+    abstract public String getSecret();
+
+    abstract public String getMode();
+
+    @Bean
+    public Map<String, String> paypalSdkConfig(){
+        Map<String, String> sdkConfig = new HashMap<>();
+        sdkConfig.put("mode", getMode());
+        return sdkConfig;
+    }
+
+    @Bean
+    public OAuthTokenCredential authTokenCredential(){
+        return new OAuthTokenCredential(getClientId(), getSecret(), paypalSdkConfig());
+    }
+
+    @Bean
+    public APIContext apiContext() throws PayPalRESTException {
+        String accessToken = authTokenCredential().getAccessToken();
+        log.info("paypal新的accessToken:" + accessToken);
+        APIContext apiContext = new APIContext(accessToken);
+        apiContext.setConfigurationMap(paypalSdkConfig());
+        return apiContext;
+    }
+}

+ 130 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PayPalmentEx.java

@@ -0,0 +1,130 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+public class PayPalmentEx implements Serializable {
+
+    private static final long serialVersionUID = 5027458587257867876L;
+    /**
+     * 订单Id
+     */
+    private String orderSn;
+    /**
+     * 支付的总价
+     */
+    private BigDecimal orderTotal;
+    /**
+     * 商品总价
+     */
+    private BigDecimal subTotal;
+    /**
+     * 税费
+     */
+    private BigDecimal tax;
+    /**
+     * 描述
+     */
+    private String description;
+    /**
+     * 成功回调url
+     */
+    private String successUrl;
+    /**
+     * 支付失败url
+     */
+    private String failUrl;
+    /**
+     * 取消支付url
+     */
+    private String cancelUrl;
+    /**
+     * 收货地址
+     */
+    private PaypalOrderAddressEx paypayOrderAddressEx;
+    /**
+     * 订单商品明细
+     */
+    private List<PaypalOrderItemEx> paypalOrderItemExList;
+
+    public String getOrderSn() {
+        return orderSn;
+    }
+
+    public void setOrderSn(String orderSn) {
+        this.orderSn = orderSn;
+    }
+
+    public BigDecimal getOrderTotal() {
+        return orderTotal;
+    }
+
+    public void setOrderTotal(BigDecimal orderTotal) {
+        this.orderTotal = orderTotal;
+    }
+
+    public BigDecimal getSubTotal() {
+        return subTotal;
+    }
+
+    public void setSubTotal(BigDecimal subTotal) {
+        this.subTotal = subTotal;
+    }
+
+    public BigDecimal getTax() {
+        return tax;
+    }
+
+    public void setTax(BigDecimal tax) {
+        this.tax = tax;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getSuccessUrl() {
+        return successUrl;
+    }
+
+    public void setSuccessUrl(String successUrl) {
+        this.successUrl = successUrl;
+    }
+
+    public String getFailUrl() {
+        return failUrl;
+    }
+
+    public void setFailUrl(String failUrl) {
+        this.failUrl = failUrl;
+    }
+
+    public String getCancelUrl() {
+        return cancelUrl;
+    }
+
+    public void setCancelUrl(String cancelUrl) {
+        this.cancelUrl = cancelUrl;
+    }
+
+    public PaypalOrderAddressEx getPaypayOrderAddressEx() {
+        return paypayOrderAddressEx;
+    }
+
+    public void setPaypayOrderAddressEx(PaypalOrderAddressEx paypayOrderAddressEx) {
+        this.paypayOrderAddressEx = paypayOrderAddressEx;
+    }
+
+    public List<PaypalOrderItemEx> getPaypalOrderItemExList() {
+        return paypalOrderItemExList;
+    }
+
+    public void setPaypalOrderItemExList(List<PaypalOrderItemEx> paypalOrderItemExList) {
+        this.paypalOrderItemExList = paypalOrderItemExList;
+    }
+}

+ 88 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalOrderAddressEx.java

@@ -0,0 +1,88 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import java.io.Serializable;
+
+public class PaypalOrderAddressEx implements Serializable {
+
+    private static final long serialVersionUID = 5667747195118555705L;
+
+    private String firstName;
+
+    private String lastName;
+
+    private String countryCode;
+
+    private String state;
+
+    private String city;
+
+    private String address;
+
+    private String phone;
+
+    private String postalCode;
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    public String getCountryCode() {
+        return countryCode;
+    }
+
+    public void setCountryCode(String countryCode) {
+        this.countryCode = countryCode;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getAddress() {
+        return address;
+    }
+
+    public void setAddress(String address) {
+        this.address = address;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getPostalCode() {
+        return postalCode;
+    }
+
+    public void setPostalCode(String postalCode) {
+        this.postalCode = postalCode;
+    }
+}

+ 59 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalOrderItemEx.java

@@ -0,0 +1,59 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+public class PaypalOrderItemEx implements Serializable {
+
+    private static final long serialVersionUID = 7764234386178614511L;
+
+    private String sku;
+
+    private String name;
+
+    private BigDecimal price;
+
+    private int quantity;
+
+    private String currency;
+
+    public String getSku() {
+        return sku;
+    }
+
+    public void setSku(String sku) {
+        this.sku = sku;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public BigDecimal getPrice() {
+        return price;
+    }
+
+    public void setPrice(BigDecimal price) {
+        this.price = price;
+    }
+
+    public int getQuantity() {
+        return quantity;
+    }
+
+    public void setQuantity(int quantity) {
+        this.quantity = quantity;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+}

+ 5 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalPaymentIntent.java

@@ -0,0 +1,5 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+public enum PaypalPaymentIntent {
+	sale, authorize, order
+}

+ 5 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalPaymentMethod.java

@@ -0,0 +1,5 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+public enum PaypalPaymentMethod {
+	credit_card, paypal
+}

+ 267 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/PaypalService.java

@@ -0,0 +1,267 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.ucenter.pay.paypal.PayPalDefaultConfig;
+import com.paypal.api.payments.*;
+import com.paypal.base.codec.binary.Base64;
+import com.paypal.base.rest.APIContext;
+import com.paypal.base.rest.PayPalRESTException;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+@Log4j2
+@Service
+public class PaypalService {
+
+    @Autowired
+    private APIContext apiContext;
+    @Autowired
+    private PayPalDefaultConfig config;
+
+    private static final String CURRENCY = "USD";
+
+    /**
+     * 创建支付
+     *
+     * @param paymentEx
+     * @return
+     * @throws PayPalRESTException
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public Payment createPayment(PayPalmentEx paymentEx, String successUrl, String cancelUrl) throws PayPalRESTException {
+        if (StringUtils.isEmpty(successUrl) || StringUtils.isEmpty(cancelUrl)) {
+            throw new PayPalRESTException("缺少url");
+        }
+        Transaction transaction = new Transaction();
+        transaction.setDescription(paymentEx.getDescription());
+        // 将我们的订单ID保存到支付信息中,用于后面支付回传
+        if (null != paymentEx.getOrderSn()) {
+            transaction.setCustom(paymentEx.getOrderSn());
+        }
+        //订单价格
+        Amount amount = new Amount();
+        amount.setCurrency(CURRENCY);
+        // 支付的总价,paypal会校验 total = subTotal + tax + ...
+        amount.setTotal(paymentEx.getOrderTotal().toString());
+        // 设置各种费用
+        Details details = new Details();
+        // 商品总价
+        if (paymentEx.getSubTotal() != null) {
+            details.setSubtotal(paymentEx.getSubTotal().toString());
+        }
+        // 税费
+        if (paymentEx.getTax() != null) {
+            details.setTax(paymentEx.getTax().toString());
+        }
+
+        amount.setDetails(details);
+
+        transaction.setAmount(amount);
+
+        ItemList itemList = new ItemList();
+        // 收货地址
+        PaypalOrderAddressEx orderAddress = paymentEx.getPaypayOrderAddressEx();
+        if (orderAddress != null) {
+            ShippingAddress shippingAddress = new ShippingAddress();
+            if (StringUtils.isNotEmpty(orderAddress.getFirstName()) && StringUtils.isNotEmpty(orderAddress.getLastName())) {
+                shippingAddress.setRecipientName(orderAddress.getFirstName() + "." + orderAddress.getLastName());
+            }
+            shippingAddress.setCountryCode(orderAddress.getCountryCode());
+            shippingAddress.setState(orderAddress.getState());
+            shippingAddress.setCity(orderAddress.getCity());
+            shippingAddress.setLine1(orderAddress.getAddress());
+            shippingAddress.setPhone(orderAddress.getPhone());
+            shippingAddress.setPostalCode(orderAddress.getPostalCode());
+
+            itemList.setShippingAddress(shippingAddress);
+            itemList.setShippingPhoneNumber(orderAddress.getPhone());
+        }
+
+        // 商品明细
+        List<PaypalOrderItemEx> orderItemList = paymentEx.getPaypalOrderItemExList();
+        if (orderItemList != null && orderItemList.size() > 0) {
+            List<Item> items = new ArrayList<>();
+            for (PaypalOrderItemEx orderItemEx : orderItemList) {
+                Item item = new Item();
+                item.setSku(orderItemEx.getSku());
+                item.setName(orderItemEx.getName());
+                item.setPrice(orderItemEx.getPrice().toString());
+                item.setQuantity(String.valueOf(orderItemEx.getQuantity()));
+                item.setCurrency(CURRENCY);
+                items.add(item);
+            }
+            itemList.setItems(items);
+            transaction.setItemList(itemList);
+        }
+
+        List<Transaction> transactions = new ArrayList<>();
+        transactions.add(transaction);
+
+        // 支付信息
+        Payer payer = new Payer();
+        payer.setPaymentMethod(PaypalPaymentMethod.paypal.toString());
+
+        Payment payment = new Payment();
+        //刷新accessToken时间;
+        apiContext = new APIContext("Bearer " + getAccessToken());
+        apiContext.setConfigurationMap(config.paypalSdkConfig());
+
+        payment.setIntent(PaypalPaymentIntent.sale.toString());
+        payment.setPayer(payer);
+        payment.setTransactions(transactions);
+
+        //回调地址
+        RedirectUrls redirectUrls = new RedirectUrls();
+        redirectUrls.setReturnUrl(successUrl);
+        redirectUrls.setCancelUrl(cancelUrl);
+        payment.setRedirectUrls(redirectUrls);
+
+        return payment.create(apiContext);
+    }
+
+    /**
+     * 执行支付
+     *
+     * @param paymentId
+     * @param payerId
+     * @return
+     * @throws PayPalRESTException
+     */
+    public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
+        Payment payment = new Payment();
+        payment.setId(paymentId);
+        PaymentExecution paymentExecute = new PaymentExecution();
+        paymentExecute.setPayerId(payerId);
+        apiContext = new APIContext("Bearer " + getAccessToken());
+        apiContext.setConfigurationMap(config.paypalSdkConfig());
+        return payment.execute(apiContext, paymentExecute);
+    }
+
+    /**
+      * 获取token
+      * 了解更多:https://developer.paypal.com/webapps/developer/docs/integration/mobile/verify-mobile-payment/
+      * @return
+      */
+    private String getAccessToken() {
+        BufferedReader reader = null;
+        try {
+            URL url = new URL(UrlUtils.TOKEN_URL);
+            String authorization = config.getClientId() + ":" + config.getSecret();
+            authorization = Base64.encodeBase64String(authorization.getBytes());
+
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("POST");// 提交模式
+            //设置请求头header
+            conn.setRequestProperty("Accept", "application/json");
+            conn.setRequestProperty("Accept-Language", "en_US");
+            conn.setRequestProperty("Authorization", "Basic " + authorization);
+            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
+            // conn.setReadTimeout(2000);//读取超时 单位毫秒
+            conn.setDoOutput(true);// 是否输入参数
+            String params = "grant_type=client_credentials";
+            conn.getOutputStream().write(params.getBytes());// 输入参数
+
+            InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
+            reader = new BufferedReader(inStream);
+            StringBuilder result = new StringBuilder();
+            String lineTxt = null;
+            while ((lineTxt = reader.readLine()) != null) {
+                result.append(lineTxt);
+            }
+            reader.close();
+            String accessTokey = JSONObject.parseObject(result.toString()).getString("access_token");
+            log.info("getAccessToken:" + accessTokey);
+            return accessTokey;
+        } catch (Exception err) {
+            err.printStackTrace();
+        } finally {
+            if (reader != null){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    public String getPaymentDetails(String paymentId) {
+        BufferedReader reader = null;
+        try {
+            URL url = new URL(UrlUtils.PAYMENT_DETAIL + paymentId);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            conn.setRequestMethod("GET");// 提交模式
+            //设置请求头header
+            conn.setRequestProperty("Accept", "application/json");
+            conn.setRequestProperty("Authorization", "Bearer " + getAccessToken());
+            // conn.setConnectTimeout(10000);//连接超时 单位毫秒
+            // conn.setReadTimeout(2000);//读取超时 单位毫秒
+            InputStreamReader inStream = new InputStreamReader(conn.getInputStream());
+            reader = new BufferedReader(inStream);
+            StringBuilder result = new StringBuilder();
+            String lineTxt = null;
+            while ((lineTxt = reader.readLine()) != null) {
+                result.append(lineTxt);
+            }
+            reader.close();
+            return result.toString();
+        } catch (Exception err) {
+            err.printStackTrace();
+        }finally {
+            if (reader != null){
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return null;
+    }
+
+    public boolean verifyPayment(String paymentId){
+        //从PayPal获取付款详情
+        String str = getPaymentDetails(paymentId);
+        JSONObject detail = JSONObject.parseObject(str);
+        //校验订单是否完成
+        if("approved".equals(detail.getString("state"))){
+            JSONObject transactions = detail.getJSONArray("transactions").getJSONObject(0);
+            JSONObject amount = transactions.getJSONObject("amount");
+            JSONArray relatedResources = transactions.getJSONArray("related_resources");
+            //从数据库查询总金额与Paypal校验支付总金额
+            double total = 0;
+            if( total != amount.getDouble("total") ){
+                return false;
+            }
+            //校验交易货币类型
+            String currency = "USD";
+            if( !currency.equals(amount.getString("currency")) ){
+                return false;
+            }
+            //校验每个子订单是否完成
+            for (int i = 0,j = relatedResources.size(); i < j; i++) {
+                JSONObject sale = relatedResources.getJSONObject(i).getJSONObject("sale");
+                if( !"completed".equals(sale.getString("state")) ){
+                    System.out.println("子订单未完成,订单状态:"+sale.getString("state"));
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+
+}

+ 66 - 0
src/main/java/com/fdkankan/ucenter/pay/paypal/sdk/UrlUtils.java

@@ -0,0 +1,66 @@
+package com.fdkankan.ucenter.pay.paypal.sdk;
+
+import javax.servlet.http.HttpServletRequest;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+public class UrlUtils {
+
+    //沙箱链接
+//    public static final String TOKEN_URL = "https://api.sandbox.paypal.com/v1/oauth2/token";
+    public static final String TOKEN_URL = "https://api.paypal.com/v1/oauth2/token";
+    public static final String PAYMENT_DETAIL = "https://api.sandbox.paypal.com/v1/payments/payment/";
+
+    public static String getBaseURl(HttpServletRequest request) {
+        String scheme = request.getScheme();
+        String serverName = request.getServerName();
+        int serverPort = request.getServerPort();
+        String contextPath = request.getContextPath();
+        StringBuffer url =  new StringBuffer();
+        url.append(scheme).append("://").append(serverName);
+        if ((serverPort != 80) && (serverPort != 443)) {
+            url.append(":").append(serverPort);
+        }
+        url.append(contextPath);
+        if(url.toString().endsWith("/")){
+            url.append("/");
+        }
+        return url.toString();
+    }
+
+    /**
+     * 获取用户实际ip
+     * @param request
+     * @return
+     */
+    public static String getIpAddr(HttpServletRequest request){
+        String ipAddress = request.getHeader("x-forwarded-for");
+        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("Proxy-Client-IP");
+        }
+        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if(ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getRemoteAddr();
+            if(ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")){
+                //根据网卡取本机配置的IP
+                InetAddress inet=null;
+                try {
+                    inet = InetAddress.getLocalHost();
+                } catch (UnknownHostException e) {
+                    e.printStackTrace();
+                }
+                ipAddress= inet.getHostAddress();
+            }
+        }
+        //对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+        if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
+            if(ipAddress.indexOf(",")>0){
+                ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
+            }
+        }
+        return ipAddress;
+    }
+
+}

+ 11 - 0
src/main/java/com/fdkankan/ucenter/pay/strategy/OrderItemStrategy.java

@@ -0,0 +1,11 @@
+package com.fdkankan.ucenter.pay.strategy;
+
+
+import com.fdkankan.ucenter.entity.OrderItem;
+
+public interface OrderItemStrategy {
+
+    public void handleOrderItem(Long userId, OrderItem orderItem) throws Exception;
+
+    public String getType();
+}

+ 9 - 0
src/main/java/com/fdkankan/ucenter/pay/strategy/OrderStrategy.java

@@ -0,0 +1,9 @@
+package com.fdkankan.ucenter.pay.strategy;
+
+public interface OrderStrategy {
+
+    public void handleOrder(String orderSn, String tradeNo, String openId, int paymentTypeName, Long spaceId) throws Exception;
+
+    public String getType();
+
+}

+ 68 - 0
src/main/java/com/fdkankan/ucenter/pay/strategy/OrderStrategyFactory.java

@@ -0,0 +1,68 @@
+package com.fdkankan.ucenter.pay.strategy;
+
+import com.fdkankan.common.util.SpringUtil;
+import com.fdkankan.ucenter.entity.OrderItem;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Log4j2
+@Component
+public class OrderStrategyFactory implements InitializingBean {
+
+    @Autowired
+    private SpringUtil applicationContextHelper;
+
+    private Map<String, OrderStrategy> orderHandleMap = new ConcurrentHashMap<>();
+
+    private Map<String, OrderItemStrategy> orderItemHandleMap = new ConcurrentHashMap<>();
+
+    @Override
+    public void afterPropertiesSet() throws Exception {
+        Map<String, OrderItemStrategy> orderItemHandles = applicationContextHelper.getBeansOfType(OrderItemStrategy.class);
+        for (Map.Entry<String, OrderItemStrategy> orderHandle : orderItemHandles.entrySet()) {
+
+            String type = orderHandle.getValue().getType();
+            String[] types = type.split(",");
+            if (types.length > 1){
+                for (String str : types){
+                    orderItemHandleMap
+                            .put(str, orderHandle.getValue());
+                }
+            }
+            else{
+                orderItemHandleMap
+                        .put(orderHandle.getValue().getType(), orderHandle.getValue());
+            }
+        }
+
+
+        Map<String, OrderStrategy> orderHandles = applicationContextHelper.getBeansOfType(OrderStrategy.class);
+        for (Map.Entry<String, OrderStrategy> orderHandle : orderHandles.entrySet()) {
+            orderHandleMap.put(orderHandle.getValue().getType(), orderHandle.getValue());
+        }
+    }
+
+    public void doHandler(Long userId, OrderItem t) throws Exception{
+        log.warn("sku:"+t.getSkuSn());
+        orderItemHandleMap.get(t.getSkuSn()).handleOrderItem(userId, t);
+    }
+    public void doHandler(String orderSn, String tradeNo, String openId, String type, int paymentTypeName) throws Exception{
+        Long spaceId = null;
+        log.info("进入doHandler");
+        if(orderSn.split("_").length == 2){
+            spaceId = Long.valueOf(orderSn.split("_")[1]);
+            orderSn = orderSn.split("_")[0];
+        }
+        if(type.matches("^-?[0-9]+")){
+            type = "expansion";
+        }
+        log.info("type:" + type);
+        log.info("orderSn:" + orderSn);
+        orderHandleMap.get(type).handleOrder(orderSn, tradeNo, openId, paymentTypeName, spaceId);
+    }
+}

+ 44 - 0
src/main/java/com/fdkankan/ucenter/pay/strategy/impl/DownloadOrderImpl.java

@@ -0,0 +1,44 @@
+package com.fdkankan.ucenter.pay.strategy.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.entity.User;
+import com.fdkankan.ucenter.pay.strategy.OrderStrategy;
+import com.fdkankan.ucenter.service.IDownloadOrderService;
+import com.fdkankan.ucenter.service.IUserService;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Log4j2
+@Component
+public class DownloadOrderImpl implements OrderStrategy {
+    @Autowired
+    private IDownloadOrderService downloadOrderService;
+    @Autowired
+    private IUserService userService;
+
+    @Override
+    public void handleOrder(String orderSn, String tradeNo, String openId, int paymentTypeName, Long spaceId) throws Exception {
+        DownloadOrder downloadOrder = downloadOrderService.getByOrderSn(orderSn);
+        if (downloadOrder == null) {
+            log.error("找不到订单:" + orderSn);
+            throw new Exception("找不到订单,out_trade_no错误");
+        }
+        // 更新场景下载订单
+        boolean result = downloadOrderService.paySuccessDownloadOrder(orderSn, tradeNo, paymentTypeName);
+        if (!result){
+            log.error("更新增值权益订单失败");
+            throw new Exception("更新增值权益订单失败");
+        }
+        //更新用户下载次数
+        User userEntity = userService.getById(downloadOrder.getUserId());
+        userEntity.setDownloadNumTotal(userEntity.getDownloadNumTotal() + downloadOrder.getCount());
+        userService.updateById(userEntity);
+    }
+
+    @Override
+    public String getType() {
+        return "download";
+    }
+}

+ 673 - 0
src/main/java/com/fdkankan/ucenter/pay/wx/WXPay.java

@@ -0,0 +1,673 @@
+package com.fdkankan.ucenter.pay.wx;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WXPay {
+
+    private WXPayConfig config;
+    private WXPayConstants.SignType signType;
+    private boolean useSandbox;
+
+    public WXPay(final WXPayConfig config) {
+        this(config, WXPayConstants.SignType.MD5, false);
+    }
+
+    public WXPay(final WXPayConfig config, final WXPayConstants.SignType signType) {
+        this(config, signType, false);
+    }
+
+    public WXPay(final WXPayConfig config, final WXPayConstants.SignType signType, final boolean useSandbox) {
+        this.config = config;
+        this.signType = signType;
+        this.useSandbox = useSandbox;
+    }
+
+
+    /**
+     * 向 Map 中添加 appid、mch_id、nonce_str、sign_type、sign <br>
+     * 该函数适用于商户适用于统一下单等接口,不适用于红包、代金券接口
+     *
+     * @param reqData
+     * @return
+     * @throws Exception
+     */
+    public Map<String, String> fillRequestData(Map<String, String> reqData) throws Exception {
+        reqData.put("appid", config.getAppID());
+        reqData.put("mch_id", config.getMchID());
+        reqData.put("nonce_str", WXPayUtil.generateNonceStr());
+        if (WXPayConstants.SignType.MD5.equals(this.signType)) {
+            reqData.put("sign_type", WXPayConstants.MD5);
+        }
+        else if (WXPayConstants.SignType.HMACSHA256.equals(this.signType)) {
+            reqData.put("sign_type", WXPayConstants.HMACSHA256);
+        }
+        reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));
+        return reqData;
+    }
+
+    /**
+     * 判断xml数据的sign是否有效,必须包含sign字段,否则返回false。
+     *
+     * @param reqData 向wxpay post的请求数据
+     * @return 签名是否有效
+     * @throws Exception
+     */
+    public boolean isResponseSignatureValid(Map<String, String> reqData) throws Exception {
+        // 返回数据的签名方式和请求中给定的签名方式是一致的
+        return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), this.signType);
+    }
+
+    /**
+     * 判断支付结果通知中的sign是否有效
+     *
+     * @param reqData 向wxpay post的请求数据
+     * @return 签名是否有效
+     * @throws Exception
+     */
+    public boolean isPayResultNotifySignatureValid(Map<String, String> reqData) throws Exception {
+        String signTypeInData = reqData.get(WXPayConstants.FIELD_SIGN_TYPE);
+        WXPayConstants.SignType signType;
+        if (signTypeInData == null) {
+            signType = WXPayConstants.SignType.MD5;
+        }
+        else {
+            signTypeInData = signTypeInData.trim();
+            if (signTypeInData.length() == 0) {
+                signType = WXPayConstants.SignType.MD5;
+            }
+            else if (WXPayConstants.MD5.equals(signTypeInData)) {
+                signType = WXPayConstants.SignType.MD5;
+            }
+            else if (WXPayConstants.HMACSHA256.equals(signTypeInData)) {
+                signType = WXPayConstants.SignType.HMACSHA256;
+            }
+            else {
+                throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData));
+            }
+        }
+        return WXPayUtil.isSignatureValid(reqData, this.config.getKey(), signType);
+    }
+
+
+    /**
+     * 不需要证书的请求
+     * @param strUrl String
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 超时时间,单位是毫秒
+     * @param readTimeoutMs 超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public String requestWithoutCert(String strUrl, Map<String, String> reqData,
+                                     int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String UTF8 = "UTF-8";
+        String reqBody = WXPayUtil.mapToXml(reqData);
+        URL httpUrl = new URL(strUrl);
+        HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
+        httpURLConnection.setDoOutput(true);
+        httpURLConnection.setRequestMethod("POST");
+        httpURLConnection.setConnectTimeout(connectTimeoutMs);
+        httpURLConnection.setReadTimeout(readTimeoutMs);
+        httpURLConnection.connect();
+        OutputStream outputStream = httpURLConnection.getOutputStream();
+        outputStream.write(reqBody.getBytes(UTF8));
+
+        // if (httpURLConnection.getResponseCode()!= 200) {
+        //     throw new Exception(String.format("HTTP response code is %d, not 200", httpURLConnection.getResponseCode()));
+        // }
+
+        //获取内容
+        InputStream inputStream = httpURLConnection.getInputStream();
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
+        final StringBuffer stringBuffer = new StringBuffer();
+        String line = null;
+        while ((line = bufferedReader.readLine()) != null) {
+            stringBuffer.append(line).append("\n");
+        }
+        String resp = stringBuffer.toString();
+        if (stringBuffer!=null) {
+            try {
+                bufferedReader.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        if (inputStream!=null) {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        if (outputStream!=null) {
+            try {
+                outputStream.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        // if (httpURLConnection!=null) {
+        //     httpURLConnection.disconnect();
+        // }
+
+        return resp;
+    }
+
+
+    /**
+     * 需要证书的请求
+     * @param strUrl String
+     * @param reqData 向wxpay post的请求数据  Map
+     * @param connectTimeoutMs 超时时间,单位是毫秒
+     * @param readTimeoutMs 超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public String requestWithCert(String strUrl, Map<String, String> reqData,
+                                  int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String UTF8 = "UTF-8";
+        String reqBody = WXPayUtil.mapToXml(reqData);
+        URL httpUrl = new URL(strUrl);
+        char[] password = config.getMchID().toCharArray();
+        InputStream certStream = config.getCertStream();
+        KeyStore ks = KeyStore.getInstance("PKCS12");
+        ks.load(certStream, password);
+
+        // 实例化密钥库 & 初始化密钥工厂
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        kmf.init(ks, password);
+
+        // 创建SSLContext
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
+        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
+
+        HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
+
+        httpURLConnection.setDoOutput(true);
+        httpURLConnection.setRequestMethod("POST");
+        httpURLConnection.setConnectTimeout(connectTimeoutMs);
+        httpURLConnection.setReadTimeout(readTimeoutMs);
+        httpURLConnection.connect();
+        OutputStream outputStream = httpURLConnection.getOutputStream();
+        outputStream.write(reqBody.getBytes(UTF8));
+
+        // if (httpURLConnection.getResponseCode()!= 200) {
+        //     throw new Exception(String.format("HTTP response code is %d, not 200", httpURLConnection.getResponseCode()));
+        // }
+
+        //获取内容
+        InputStream inputStream = httpURLConnection.getInputStream();
+        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
+        final StringBuffer stringBuffer = new StringBuffer();
+        String line = null;
+        while ((line = bufferedReader.readLine()) != null) {
+            stringBuffer.append(line);
+        }
+        String resp = stringBuffer.toString();
+        if (stringBuffer!=null) {
+            try {
+                bufferedReader.close();
+            } catch (IOException e) {
+                // e.printStackTrace();
+            }
+        }
+        if (inputStream!=null) {
+            try {
+                inputStream.close();
+            } catch (IOException e) {
+                // e.printStackTrace();
+            }
+        }
+        if (outputStream!=null) {
+            try {
+                outputStream.close();
+            } catch (IOException e) {
+                // e.printStackTrace();
+            }
+        }
+        if (certStream!=null) {
+            try {
+                certStream.close();
+            } catch (IOException e) {
+                // e.printStackTrace();
+            }
+        }
+        // if (httpURLConnection!=null) {
+        //     httpURLConnection.disconnect();
+        // }
+
+        return resp;
+    }
+
+    /**
+     * 处理 HTTPS API返回数据,转换成Map对象。return_code为SUCCESS时,验证签名。
+     * @param xmlStr API返回的XML格式数据
+     * @return Map类型数据
+     * @throws Exception
+     */
+    public Map<String, String> processResponseXml(String xmlStr) throws Exception {
+        String RETURN_CODE = "return_code";
+        String return_code;
+        Map<String, String> respData = WXPayUtil.xmlToMap(xmlStr);
+        if (respData.containsKey(RETURN_CODE)) {
+            return_code = respData.get(RETURN_CODE);
+        }
+        else {
+            throw new Exception(String.format("No `return_code` in XML: %s", xmlStr));
+        }
+
+        if (return_code.equals(WXPayConstants.FAIL)) {
+            return respData;
+        }
+        else if (return_code.equals(WXPayConstants.SUCCESS)) {
+           if (this.isResponseSignatureValid(respData)) {
+               return respData;
+           }
+           else {
+               throw new Exception(String.format("Invalid sign value in XML: %s", xmlStr));
+           }
+        }
+        else {
+            throw new Exception(String.format("return_code value %s is invalid in XML: %s", return_code, xmlStr));
+        }
+    }
+
+    /**
+     * 作用:提交刷卡支付<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> microPay(Map<String, String> reqData) throws Exception {
+        return this.microPay(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:提交刷卡支付<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> microPay(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_MICROPAY_URL;
+        }
+        else {
+            url = WXPayConstants.MICROPAY_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:统一下单<br>
+     * 场景:公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> unifiedOrder(Map<String, String> reqData) throws Exception {
+        return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:统一下单<br>
+     * 场景:公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> unifiedOrder(Map<String, String> reqData,  int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_UNIFIEDORDER_URL;
+        }
+        else {
+            url = WXPayConstants.UNIFIEDORDER_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:查询订单<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> orderQuery(Map<String, String> reqData) throws Exception {
+        return this.orderQuery(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:查询订单<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据 int
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> orderQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_ORDERQUERY_URL;
+        }
+        else {
+            url = WXPayConstants.ORDERQUERY_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:撤销订单<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> reverse(Map<String, String> reqData) throws Exception {
+        return this.reverse(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:撤销订单<br>
+     * 场景:刷卡支付<br>
+     * 其他:需要证书
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> reverse(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_REVERSE_URL;
+        }
+        else {
+            url = WXPayConstants.REVERSE_URL;
+        }
+        String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:关闭订单<br>
+     * 场景:公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> closeOrder(Map<String, String> reqData) throws Exception {
+        return this.closeOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:关闭订单<br>
+     * 场景:公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> closeOrder(Map<String, String> reqData,  int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_CLOSEORDER_URL;
+        }
+        else {
+            url = WXPayConstants.CLOSEORDER_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:申请退款<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> refund(Map<String, String> reqData) throws Exception {
+        return this.refund(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:申请退款<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>
+     * 其他:需要证书
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> refund(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_REFUND_URL;
+        }
+        else {
+            url = WXPayConstants.REFUND_URL;
+        }
+        String respXml = this.requestWithCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:退款查询<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> refundQuery(Map<String, String> reqData) throws Exception {
+        return this.refundQuery(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:退款查询<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> refundQuery(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_REFUNDQUERY_URL;
+        }
+        else {
+            url = WXPayConstants.REFUNDQUERY_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:对账单下载(成功时返回对账单数据,失败时返回XML格式数据)<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> downloadBill(Map<String, String> reqData) throws Exception {
+        return this.downloadBill(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:对账单下载<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付<br>
+     * 其他:无论是否成功都返回Map。若成功,返回的Map中含有return_code、return_msg、data,
+     *      其中return_code为`SUCCESS`,data为对账单数据。
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return 经过封装的API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> downloadBill(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_DOWNLOADBILL_URL;
+        }
+        else {
+            url = WXPayConstants.DOWNLOADBILL_URL;
+        }
+        String respStr = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs).trim();
+        Map<String, String> ret;
+        // 出现错误,返回XML数据
+        if (respStr.indexOf("<") == 0) {
+            ret = WXPayUtil.xmlToMap(respStr);
+        }
+        else {
+            // 正常返回csv数据
+            ret = new HashMap<String, String>();
+            ret.put("return_code", WXPayConstants.SUCCESS);
+            ret.put("return_msg", "sdk");
+            ret.put("data", respStr);
+        }
+        return ret;
+    }
+
+
+    /**
+     * 作用:交易保障<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> report(Map<String, String> reqData) throws Exception {
+        return this.report(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:交易保障<br>
+     * 场景:刷卡支付、公共号支付、扫码支付、APP支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> report(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_REPORT_URL;
+        }
+        else {
+            url = WXPayConstants.REPORT_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return WXPayUtil.xmlToMap(respXml);
+    }
+
+
+    /**
+     * 作用:转换短链接<br>
+     * 场景:刷卡支付、扫码支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> shortUrl(Map<String, String> reqData) throws Exception {
+        return this.shortUrl(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:转换短链接<br>
+     * 场景:刷卡支付、扫码支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> shortUrl(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_SHORTURL_URL;
+        }
+        else {
+            url = WXPayConstants.SHORTURL_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+    /**
+     * 作用:授权码查询OPENID接口<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> authCodeToOpenid(Map<String, String> reqData) throws Exception {
+        return this.authCodeToOpenid(reqData, this.config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
+    }
+
+
+    /**
+     * 作用:授权码查询OPENID接口<br>
+     * 场景:刷卡支付
+     * @param reqData 向wxpay post的请求数据
+     * @param connectTimeoutMs 连接超时时间,单位是毫秒
+     * @param readTimeoutMs 读超时时间,单位是毫秒
+     * @return API返回数据
+     * @throws Exception
+     */
+    public Map<String, String> authCodeToOpenid(Map<String, String> reqData, int connectTimeoutMs, int readTimeoutMs) throws Exception {
+        String url;
+        if (this.useSandbox) {
+            url = WXPayConstants.SANDBOX_AUTHCODETOOPENID_URL;
+        }
+        else {
+            url = WXPayConstants.AUTHCODETOOPENID_URL;
+        }
+        String respXml = this.requestWithoutCert(url, this.fillRequestData(reqData), connectTimeoutMs, readTimeoutMs);
+        return this.processResponseXml(respXml);
+    }
+
+
+} // end class

+ 53 - 0
src/main/java/com/fdkankan/ucenter/pay/wx/WXPayConfig.java

@@ -0,0 +1,53 @@
+package com.fdkankan.ucenter.pay.wx;
+
+import java.io.InputStream;
+
+public interface WXPayConfig {
+
+
+    /**
+     * 获取 App ID
+     *
+     * @return App ID
+     */
+    public String getAppID();
+
+
+    /**
+     * 获取 Mch ID
+     *
+     * @return Mch ID
+     */
+    public String getMchID();
+
+
+    /**
+     * 获取 API 密钥
+     *
+     * @return API密钥
+     */
+    public String getKey();
+
+
+    /**
+     * 获取商户证书内容
+     *
+     * @return 商户证书内容
+     */
+    public InputStream getCertStream();
+
+    /**
+     * HTTP(S) 连接超时时间,单位毫秒
+     *
+     * @return
+     */
+    public int getHttpConnectTimeoutMs();
+
+    /**
+     * HTTP(S) 读数据超时时间,单位毫秒
+     *
+     * @return
+     */
+    public int getHttpReadTimeoutMs();
+
+}

+ 45 - 0
src/main/java/com/fdkankan/ucenter/pay/wx/WXPayConstants.java

@@ -0,0 +1,45 @@
+package com.fdkankan.ucenter.pay.wx;
+
+/**
+ * 常量
+ */
+public class WXPayConstants {
+
+    public enum SignType {
+        MD5, HMACSHA256
+    }
+
+    public static final String FAIL     = "FAIL";
+    public static final String SUCCESS  = "SUCCESS";
+    public static final String HMACSHA256 = "HMAC-SHA256";
+    public static final String MD5 = "MD5";
+
+    public static final String FIELD_SIGN = "sign";
+    public static final String FIELD_SIGN_TYPE = "sign_type";
+
+    public static final String MICROPAY_URL     = "https://api.mch.weixin.qq.com/pay/micropay";
+    public static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
+    public static final String ORDERQUERY_URL   = "https://api.mch.weixin.qq.com/pay/orderquery";
+    public static final String REVERSE_URL      = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
+    public static final String CLOSEORDER_URL   = "https://api.mch.weixin.qq.com/pay/closeorder";
+    public static final String REFUND_URL       = "https://api.mch.weixin.qq.com/secapi/pay/refund";
+    public static final String REFUNDQUERY_URL  = "https://api.mch.weixin.qq.com/pay/refundquery";
+    public static final String DOWNLOADBILL_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
+    public static final String REPORT_URL       = "https://api.mch.weixin.qq.com/payitil/report";
+    public static final String SHORTURL_URL     = "https://api.mch.weixin.qq.com/tools/shorturl";
+    public static final String AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
+
+    // sandbox
+    public static final String SANDBOX_MICROPAY_URL     = "https://api.mch.weixin.qq.com/sandboxnew/pay/micropay";
+    public static final String SANDBOX_UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder";
+    public static final String SANDBOX_ORDERQUERY_URL   = "https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery";
+    public static final String SANDBOX_REVERSE_URL      = "https://api.mch.weixin.qq.com/sandboxnew/secapi/pay/reverse";
+    public static final String SANDBOX_CLOSEORDER_URL   = "https://api.mch.weixin.qq.com/sandboxnew/pay/closeorder";
+    public static final String SANDBOX_REFUND_URL       = "https://api.mch.weixin.qq.com/sandboxnew/secapi/pay/refund";
+    public static final String SANDBOX_REFUNDQUERY_URL  = "https://api.mch.weixin.qq.com/sandboxnew/pay/refundquery";
+    public static final String SANDBOX_DOWNLOADBILL_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill";
+    public static final String SANDBOX_REPORT_URL       = "https://api.mch.weixin.qq.com/sandboxnew/payitil/report";
+    public static final String SANDBOX_SHORTURL_URL     = "https://api.mch.weixin.qq.com/sandboxnew/tools/shorturl";
+    public static final String SANDBOX_AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/sandboxnew/tools/authcodetoopenid";
+
+}

+ 62 - 0
src/main/java/com/fdkankan/ucenter/pay/wx/WXPayDefaultConfig.java

@@ -0,0 +1,62 @@
+package com.fdkankan.ucenter.pay.wx;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+public class WXPayDefaultConfig implements WXPayConfig {
+
+    private byte[] certData;
+
+    public WXPayDefaultConfig() throws Exception {
+        /*String certPath = CONSTANTFILEPATH.WEIXINCERT;
+        File file = new File(certPath);
+        InputStream certStream = new FileInputStream(file);
+        this.certData = new byte[(int) file.length()];
+        certStream.read(this.certData);
+        certStream.close();*/
+    }
+
+    public String getAppID() {
+        return "wx779dbafb46bab697";
+    }
+
+    public String getMchID() {
+        return "1505605401";
+    }
+
+    public String getKey() {
+        return "4DAGE1684DAGE1684DAGE1684DAGE168";
+    }
+
+    public String getSecret() {
+        return "306d0d03b372232e03dca1107525f4fc";
+    }
+
+    public String getCreateIP() {
+        return "47.104.99.106";
+    }
+
+    public String getH5RedirectURL() {
+        return "mobile.html#/check";
+    }
+
+    public String getNotifyURL() {
+        return "api/order/pay/wechatPay/notify";
+    }
+
+    public String getOrderURL() {
+        return "https://api.mch.weixin.qq.com/pay/unifiedorder";
+    }
+
+    public InputStream getCertStream() {
+        return new ByteArrayInputStream(this.certData);
+    }
+
+    public int getHttpConnectTimeoutMs() {
+        return 8000;
+    }
+
+    public int getHttpReadTimeoutMs() {
+        return 10000;
+    }
+}

+ 307 - 0
src/main/java/com/fdkankan/ucenter/pay/wx/WXPayUtil.java

@@ -0,0 +1,307 @@
+package com.fdkankan.ucenter.pay.wx;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.common.BitMatrix;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.security.MessageDigest;
+import java.util.*;
+
+
+public class WXPayUtil {
+
+    /**
+     * XML格式字符串转换为Map
+     *
+     * @param strXML XML字符串
+     * @return XML数据转换后的Map
+     * @throws Exception
+     */
+    public static Map<String, String> xmlToMap(String strXML) throws Exception {
+        Map<String, String> data = new HashMap<String, String>();
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
+        // 禁用XML外部实体注入
+        /**
+         * XXE
+         * XML 外部实体注入漏洞(XML External Entity Injection,简称 XXE),
+         * 是一种容易被忽视,但危害巨大的漏洞。它可以利用 XML 外部实体加载注入,
+         * 执行不可预控的代码,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
+         */
+
+        /**
+         * 原理:
+         * 通常,我们在使用微信支付时,商家会有一个通知的 URL 来接收异步支付结果。
+         * 然而,微信在 JAVA 版本的 SDK 存在一个 XXE 漏洞来处理这个结果。
+         * 由此攻击者可以向通知的 URL 中构建恶意的回调数据,以便根据需要窃取商家服务器上的任意信息。
+         * 一旦攻击者获得商家的关键安全密钥(md5-key 和merchant-Id),
+         * 那么他们可以通过发送伪造的信息来欺骗商家而无需付费购买任意商品。
+         */
+        documentBuilderFactory.setExpandEntityReferences(false);
+        documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
+        InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
+        org.w3c.dom.Document doc = documentBuilder.parse(stream);
+        doc.getDocumentElement().normalize();
+        NodeList nodeList = doc.getDocumentElement().getChildNodes();
+        for (int idx=0; idx<nodeList.getLength(); ++idx) {
+            Node node = nodeList.item(idx);
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                org.w3c.dom.Element element = (org.w3c.dom.Element) node;
+                data.put(element.getNodeName(), element.getTextContent());
+            }
+        }
+        try {
+            stream.close();
+        }
+        catch (Exception ex) {
+
+        }
+        return data;
+    }
+
+    /**
+     * 将Map转换为XML格式的字符串
+     *
+     * @param data Map类型数据
+     * @return XML格式的字符串
+     * @throws Exception
+     */
+    public static String mapToXml(Map<String, String> data) throws Exception {
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
+        org.w3c.dom.Document document = documentBuilder.newDocument();
+        org.w3c.dom.Element root = document.createElement("xml");
+        document.appendChild(root);
+        for (String key: data.keySet()) {
+            String value = data.get(key);
+            if (value == null) {
+                value = "";
+            }
+            value = value.trim();
+            org.w3c.dom.Element filed = document.createElement(key);
+            filed.appendChild(document.createTextNode(value));
+            root.appendChild(filed);
+        }
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Transformer transformer = tf.newTransformer();
+        DOMSource source = new DOMSource(document);
+        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        StringWriter writer = new StringWriter();
+        StreamResult result = new StreamResult(writer);
+        transformer.transform(source, result);
+        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
+        try {
+            writer.close();
+        }
+        catch (Exception ex) {
+        }
+        return output;
+    }
+
+
+    /**
+     * 生成带有 sign 的 XML 格式字符串
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @return 含有sign字段的XML
+     */
+    public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
+        return generateSignedXml(data, key, WXPayConstants.SignType.MD5);
+    }
+
+    /**
+     * 生成带有 sign 的 XML 格式字符串
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @param signType 签名类型
+     * @return 含有sign字段的XML
+     */
+    public static String generateSignedXml(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
+        String sign = generateSignature(data, key, signType);
+        data.put(WXPayConstants.FIELD_SIGN, sign);
+        return mapToXml(data);
+    }
+
+
+    /**
+     * 判断签名是否正确
+     *
+     * @param xmlStr XML格式数据
+     * @param key API密钥
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
+        Map<String, String> data = xmlToMap(xmlStr);
+        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
+            return false;
+        }
+        String sign = data.get(WXPayConstants.FIELD_SIGN);
+        return generateSignature(data, key).equals(sign);
+    }
+
+    /**
+     * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
+        return isSignatureValid(data, key, WXPayConstants.SignType.MD5);
+    }
+
+    /**
+     * 判断签名是否正确,必须包含sign字段,否则返回false。
+     *
+     * @param data Map类型数据
+     * @param key API密钥
+     * @param signType 签名方式
+     * @return 签名是否正确
+     * @throws Exception
+     */
+    public static boolean isSignatureValid(Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
+        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
+            return false;
+        }
+        String sign = data.get(WXPayConstants.FIELD_SIGN);
+        return generateSignature(data, key, signType).equals(sign);
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param data 待签名数据
+     * @param key API密钥
+     * @return 签名
+     */
+    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
+        return generateSignature(data, key, WXPayConstants.SignType.MD5);
+    }
+
+    /**
+     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
+     *
+     * @param data 待签名数据
+     * @param key API密钥
+     * @param signType 签名方式
+     * @return 签名
+     */
+    public static String generateSignature(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
+        Set<String> keySet = data.keySet();
+        String[] keyArray = keySet.toArray(new String[keySet.size()]);
+        Arrays.sort(keyArray);
+        StringBuilder sb = new StringBuilder();
+        for (String k : keyArray) {
+            if (k.equals(WXPayConstants.FIELD_SIGN)) {
+                continue;
+            }
+            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
+                sb.append(k).append("=").append(data.get(k).trim()).append("&");
+        }
+        sb.append("key=").append(key);
+        if (WXPayConstants.SignType.MD5.equals(signType)) {
+            return MD5(sb.toString()).toUpperCase();
+        }
+        else if (WXPayConstants.SignType.HMACSHA256.equals(signType)) {
+            return HMACSHA256(sb.toString(), key);
+        }
+        else {
+            throw new Exception(String.format("Invalid sign_type: %s", signType));
+        }
+    }
+
+
+    /**
+     * 获取随机字符串 Nonce Str
+     *
+     * @return String 随机字符串
+     */
+    public static String generateNonceStr() {
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+    }
+
+
+    /**
+     * 生成 MD5
+     *
+     * @param data 待处理数据
+     * @return MD5结果
+     */
+    public static String MD5(String data) throws Exception {
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        byte[] array = md.digest(data.getBytes("UTF-8"));
+        StringBuilder sb = new StringBuilder();
+        for (byte item : array) {
+            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+        }
+        return sb.toString().toUpperCase();
+    }
+
+    /**
+     * 生成 HMACSHA256
+     * @param data 待处理数据
+     * @param key 密钥
+     * @return 加密结果
+     * @throws Exception
+     */
+    public static String HMACSHA256(String data, String key) throws Exception {
+        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
+        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
+        sha256_HMAC.init(secret_key);
+        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
+        StringBuilder sb = new StringBuilder();
+        for (byte item : array) {
+            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
+        }
+        return sb.toString().toUpperCase();
+    }
+
+    /**
+     * 根据url生成二位图片对象
+     *
+     * @param codeUrl
+     * @return
+     * @throws WriterException
+     */
+    public static BufferedImage getQRCodeImge(String codeUrl) throws WriterException {
+        int width = 300;
+        //根据url生成二维码
+        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
+        // 设置二维码参数
+        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
+        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
+        BitMatrix bitMatrix = multiFormatWriter.encode(codeUrl, BarcodeFormat.QR_CODE, width, width, hints);
+        BufferedImage image = new BufferedImage(width, width, 1);
+        for(int x = 0; x < width; ++x) {
+            for(int y = 0; y < width; ++y) {
+                image.setRGB(x, y, bitMatrix.get(x, y) ? -16777216 : -1);
+            }
+        }
+        return image;
+
+    }
+}

+ 2 - 0
src/main/java/com/fdkankan/ucenter/service/ICartService.java

@@ -24,4 +24,6 @@ public interface ICartService extends IService<Cart> {
     void delete(CartParam param);
 
     List<CartVo> listByUser(String username);
+
+    void deleteIds(List<String> ids);
 }

+ 16 - 0
src/main/java/com/fdkankan/ucenter/service/ICommerceOrderService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.ucenter.service;
+
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 商业订单表(八目相机) 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+public interface ICommerceOrderService extends IService<CommerceOrder> {
+
+}

+ 210 - 0
src/main/java/com/fdkankan/ucenter/service/IDownloadOrderService.java

@@ -1,7 +1,9 @@
 package com.fdkankan.ucenter.service;
 
+import com.fdkankan.common.response.PageInfo;
 import com.fdkankan.ucenter.entity.DownloadOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
 
 /**
  * <p>
@@ -13,4 +15,212 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IDownloadOrderService extends IService<DownloadOrder> {
 
+
+     PageInfo pageList(IncrementOrderParam param);
+
+    DownloadOrder getByOrderSn(String orderSn);
+
+    boolean paySuccessDownloadOrder(String orderSn, String tradeNo, int paymentTypeName);
 }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 19 - 0
src/main/java/com/fdkankan/ucenter/service/IExpansionOrderService.java

@@ -0,0 +1,19 @@
+package com.fdkankan.ucenter.service;
+
+import com.fdkankan.common.response.PageInfo;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
+
+/**
+ * <p>
+ * 扩容订单表(八目相机) 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+public interface IExpansionOrderService extends IService<ExpansionOrder> {
+
+    PageInfo pageList(VirtualOrderParam param);
+}

+ 17 - 0
src/main/java/com/fdkankan/ucenter/service/IGoodsSkuService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.ucenter.service;
+
+import com.fdkankan.ucenter.entity.GoodsSku;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 商品sku表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+public interface IGoodsSkuService extends IService<GoodsSku> {
+
+    GoodsSku getBySku(String skuStr);
+}

+ 4 - 0
src/main/java/com/fdkankan/ucenter/service/IIncrementOrderService.java

@@ -4,6 +4,8 @@ import com.fdkankan.common.response.PageInfo;
 import com.fdkankan.ucenter.entity.IncrementOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.OrderParam;
+import com.fdkankan.ucenter.vo.response.GoodsSkuVo;
 
 /**
  * <p>
@@ -16,4 +18,6 @@ import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
 public interface IIncrementOrderService extends IService<IncrementOrder> {
 
     PageInfo pageList(IncrementOrderParam param);
+
+    GoodsSkuVo getDownloadPrice(OrderParam param);
 }

+ 5 - 0
src/main/java/com/fdkankan/ucenter/service/IInvoiceService.java

@@ -2,6 +2,7 @@ package com.fdkankan.ucenter.service;
 
 import com.fdkankan.ucenter.entity.Invoice;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
 
 /**
  * <p>
@@ -16,4 +17,8 @@ public interface IInvoiceService extends IService<Invoice> {
     Invoice getByOrderId(Long orderId);
 
     Invoice getByIncrementOrderId(Long incrementOrderId);
+
+    Invoice getByDownId(Long downId);
+
+    void saveByOrder(Long userId, PlaceOrderParam param);
 }

+ 14 - 0
src/main/java/com/fdkankan/ucenter/service/IOrderService.java

@@ -4,6 +4,8 @@ import com.fdkankan.common.response.PageInfo;
 import com.fdkankan.ucenter.entity.Order;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.ucenter.vo.request.OrderParam;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import com.fdkankan.ucenter.vo.response.GoodsSkuVo;
 
 /**
  * <p>
@@ -16,4 +18,16 @@ import com.fdkankan.ucenter.vo.request.OrderParam;
 public interface IOrderService extends IService<Order> {
 
     PageInfo pageList(OrderParam param);
+
+    GoodsSkuVo getIncrementOrDownloadPrice(OrderParam param);
+
+    void cancel(Long orderId);
+
+    void receipt(Long orderId);
+
+    Order placeOrder(PlaceOrderParam param);
+
+    boolean queryOrderStatus(OrderParam param) throws Exception;
+
+    Order getByOrderSn(String orderSn);
 }

+ 16 - 0
src/main/java/com/fdkankan/ucenter/service/ISceneApplyService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.ucenter.service;
+
+import com.fdkankan.ucenter.entity.SceneApply;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+public interface ISceneApplyService extends IService<SceneApply> {
+
+}

+ 4 - 0
src/main/java/com/fdkankan/ucenter/service/IVirtualOrderService.java

@@ -1,7 +1,10 @@
 package com.fdkankan.ucenter.service;
 
+import com.fdkankan.common.response.PageInfo;
 import com.fdkankan.ucenter.entity.VirtualOrder;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
 
 /**
  * <p>
@@ -13,4 +16,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IVirtualOrderService extends IService<VirtualOrder> {
 
+    PageInfo pageList(VirtualOrderParam param);
 }

+ 5 - 0
src/main/java/com/fdkankan/ucenter/service/impl/CartServiceImpl.java

@@ -116,4 +116,9 @@ public class CartServiceImpl extends ServiceImpl<ICartMapper, Cart> implements I
         }
         return voList;
     }
+
+    @Override
+    public void deleteIds(List<String> ids) {
+        this.removeByIds(ids);
+    }
 }

+ 20 - 0
src/main/java/com/fdkankan/ucenter/service/impl/CommerceOrderServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.ucenter.service.impl;
+
+import com.fdkankan.ucenter.entity.CommerceOrder;
+import com.fdkankan.ucenter.mapper.ICommerceOrderMapper;
+import com.fdkankan.ucenter.service.ICommerceOrderService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 商业订单表(八目相机) 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Service
+public class CommerceOrderServiceImpl extends ServiceImpl<ICommerceOrderMapper, CommerceOrder> implements ICommerceOrderService {
+
+}

+ 68 - 0
src/main/java/com/fdkankan/ucenter/service/impl/DownloadOrderServiceImpl.java

@@ -1,11 +1,29 @@
 package com.fdkankan.ucenter.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.constant.TbStatus;
+import com.fdkankan.common.response.PageInfo;
 import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.entity.Invoice;
+import com.fdkankan.ucenter.entity.User;
 import com.fdkankan.ucenter.mapper.IDownloadOrderMapper;
 import com.fdkankan.ucenter.service.IDownloadOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.ucenter.service.IInvoiceService;
+import com.fdkankan.ucenter.service.IUserService;
+import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.response.DownloadVo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
 /**
  * <p>
  * 下载次数订单表 服务实现类
@@ -17,4 +35,54 @@ import org.springframework.stereotype.Service;
 @Service
 public class DownloadOrderServiceImpl extends ServiceImpl<IDownloadOrderMapper, DownloadOrder> implements IDownloadOrderService {
 
+    @Autowired
+    IUserService userService;
+    @Autowired
+    IInvoiceService invoiceService;
+
+    @Override
+    public PageInfo pageList(IncrementOrderParam param) {
+        User user = userService.getByUserName(param.getUserName());
+        LambdaQueryWrapper<DownloadOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(DownloadOrder::getUserId,user.getId());
+        wrapper.orderByDesc(DownloadOrder::getTradeTime);
+        Page<DownloadOrder> page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
+
+        List<DownloadVo> listVo = new ArrayList<>();
+        for (DownloadOrder record : page.getRecords()) {
+            DownloadVo vo = new DownloadVo();
+            BeanUtils.copyProperties(record,vo);
+
+            Invoice invoice = invoiceService.getByDownId(record.getId());
+            vo.setInvoice(invoice);
+            listVo.add(vo);
+        }
+        Page<DownloadVo> pageVo = new Page<>(param.getPageNum(),param.getPageSize());
+        pageVo.setTotal(page.getTotal());
+        pageVo.setRecords(listVo);
+        return PageInfo.PageInfo(pageVo);
+    }
+
+    @Override
+    public DownloadOrder getByOrderSn(String orderSn) {
+        QueryWrapper<DownloadOrder> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(DownloadOrder::getOrderSn,orderSn);
+        List<DownloadOrder> list = this.list(queryWrapper);
+        if(list == null || list.size() <=0){
+            return null;
+        }
+        return list.get(0);
+    }
+
+    @Override
+    public boolean paySuccessDownloadOrder(String orderSn, String tradeNo, int paymentTypeName) {
+        LambdaUpdateWrapper<DownloadOrder> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.set(DownloadOrder::getPayType,paymentTypeName)
+                .set(DownloadOrder::getNumber,tradeNo)
+                .set(DownloadOrder::getPayStatus,1)
+                .set(DownloadOrder::getTradeTime,new Date())
+                .eq(DownloadOrder::getOrderSn,orderSn);
+        return this.update(updateWrapper);
+
+    }
 }

+ 38 - 0
src/main/java/com/fdkankan/ucenter/service/impl/ExpansionOrderServiceImpl.java

@@ -0,0 +1,38 @@
+package com.fdkankan.ucenter.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.response.PageInfo;
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import com.fdkankan.ucenter.entity.User;
+import com.fdkankan.ucenter.mapper.IExpansionOrderMapper;
+import com.fdkankan.ucenter.service.IExpansionOrderService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.ucenter.service.IUserService;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
+import com.fdkankan.ucenter.vo.response.ExpansionOrderVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 扩容订单表(八目相机) 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Service
+public class ExpansionOrderServiceImpl extends ServiceImpl<IExpansionOrderMapper, ExpansionOrder> implements IExpansionOrderService {
+
+    @Autowired
+    IUserService userService;
+
+
+    @Override
+    public PageInfo pageList(VirtualOrderParam param) {
+        User user = userService.getByUserName(param.getUserName());
+        param.setUserId(user.getId());
+        Page<ExpansionOrderVo> page = this.getBaseMapper().pageList(new Page<>(param.getPageNum(),param.getPageSize()),param);
+        return PageInfo.PageInfo(page);
+    }
+}

+ 32 - 0
src/main/java/com/fdkankan/ucenter/service/impl/GoodsSkuServiceImpl.java

@@ -0,0 +1,32 @@
+package com.fdkankan.ucenter.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.ucenter.entity.GoodsSku;
+import com.fdkankan.ucenter.mapper.IGoodsSkuMapper;
+import com.fdkankan.ucenter.service.IGoodsSkuService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 商品sku表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-14
+ */
+@Service
+public class GoodsSkuServiceImpl extends ServiceImpl<IGoodsSkuMapper, GoodsSku> implements IGoodsSkuService {
+    @Override
+    public GoodsSku getBySku(String skuStr) {
+        LambdaQueryWrapper<GoodsSku> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(GoodsSku::getSkuSn,skuStr);
+        List<GoodsSku> list = this.list(wrapper);
+        if(list !=null && list.size() >0){
+            return list.get(0);
+        }
+        return null;
+    }
+}

+ 50 - 6
src/main/java/com/fdkankan/ucenter/service/impl/IncrementOrderServiceImpl.java

@@ -2,22 +2,28 @@ package com.fdkankan.ucenter.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.constant.SceneConstant;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.response.PageInfo;
-import com.fdkankan.ucenter.entity.IncrementOrder;
-import com.fdkankan.ucenter.entity.Invoice;
-import com.fdkankan.ucenter.entity.User;
+import com.fdkankan.ucenter.common.SkuEnum;
+import com.fdkankan.ucenter.constant.LoginConstant;
+import com.fdkankan.ucenter.entity.*;
 import com.fdkankan.ucenter.mapper.IIncrementOrderMapper;
-import com.fdkankan.ucenter.service.IIncrementOrderService;
+import com.fdkankan.ucenter.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.ucenter.service.IInvoiceService;
-import com.fdkankan.ucenter.service.IUserService;
+import com.fdkankan.ucenter.util.DateUserUtil;
 import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.OrderParam;
+import com.fdkankan.ucenter.vo.response.GoodsSkuVo;
 import com.fdkankan.ucenter.vo.response.IncrementOrderVo;
+import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -35,6 +41,10 @@ public class IncrementOrderServiceImpl extends ServiceImpl<IIncrementOrderMapper
     IUserService userService;
     @Autowired
     IInvoiceService invoiceService;
+    @Autowired
+    IUserIncrementService userIncrementService;
+    @Autowired
+    IGoodsSkuService goodsSkuService;
 
     @Override
     public PageInfo pageList(IncrementOrderParam param) {
@@ -59,4 +69,38 @@ public class IncrementOrderServiceImpl extends ServiceImpl<IIncrementOrderMapper
         return PageInfo.PageInfo(pageVo);
     }
 
+    @Override
+    public GoodsSkuVo getDownloadPrice(OrderParam param) {
+        if(param.getDateType() == null){
+            throw new BusinessException(LoginConstant.FAILURE_CODE_3001, LoginConstant.FAILURE_MSG_3001);
+        }
+
+        if(param.getDateType() != 5 && param.getDateType() != 6){
+            throw new BusinessException(SceneConstant.FAILURE_CODE_5012, SceneConstant.FAILURE_MSG_5012);
+        }
+        DateTime dateTime = new DateTime();
+        if(param.getUserIncrementId() != null){
+            UserIncrement userIncrementEntity = userIncrementService.getById(param.getUserIncrementId());
+            if(userIncrementEntity != null && DateUserUtil.getDate(userIncrementEntity.getIncrementEndTime()).getTime()> new Date().getTime()){
+                dateTime = new DateTime(userIncrementEntity.getIncrementEndTime());
+            }
+        }
+        GoodsSkuVo vo = this.getIncrementOrDownloadPrice(param.getDateType());
+        dateTime = dateTime.plusYears(1);
+        vo.setDeadLine(dateTime.toDate().getTime());
+        return vo;
+    }
+
+    public GoodsSkuVo getIncrementOrDownloadPrice(Integer dateType)  {
+        String skuStr = SkuEnum.skusMap.get(String.valueOf(dateType));
+        if (StringUtils.isEmpty(skuStr)){
+            skuStr = SkuEnum.skusMap.get("5");
+        }
+
+        GoodsSkuVo responseGoodsSku = new GoodsSkuVo();
+        GoodsSku goodsSkuEntity = goodsSkuService.getBySku(skuStr);
+        BeanUtils.copyProperties(goodsSkuEntity, responseGoodsSku);
+
+        return responseGoodsSku;
+    }
 }

+ 44 - 1
src/main/java/com/fdkankan/ucenter/service/impl/InvoiceServiceImpl.java

@@ -5,8 +5,11 @@ import com.fdkankan.ucenter.entity.Invoice;
 import com.fdkankan.ucenter.mapper.IInvoiceMapper;
 import com.fdkankan.ucenter.service.IInvoiceService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.ucenter.vo.request.InvoiceParam;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -39,5 +42,45 @@ public class InvoiceServiceImpl extends ServiceImpl<IInvoiceMapper, Invoice> imp
         if(list != null && list.size() >0){
             return list.get(0);
         }
-        return null;    }
+        return null;
+    }
+
+    @Override
+    public Invoice getByDownId(Long downId) {
+        LambdaQueryWrapper<Invoice> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(Invoice::getDownloadOrderId,downId);
+        List<Invoice> list = this.list(wrapper);
+        if(list != null && list.size() >0){
+            return list.get(0);
+        }
+        return null;
+    }
+
+    @Override
+    public void saveByOrder(Long userId, PlaceOrderParam orderParam) {
+        InvoiceParam param = orderParam.getInvoice();
+        Invoice invoiceEntity = new Invoice();
+        invoiceEntity.setUserId(userId);
+        invoiceEntity.setType(Integer.valueOf(param.getInvoiceType()));
+        invoiceEntity.setTitle(param.getTitle());
+        invoiceEntity.setCode(param.getCode());
+        invoiceEntity.setEmailAddress(param.getEmailAddress());
+
+        if (3 == invoiceEntity.getType()){
+            invoiceEntity.setOrganizedAddress(param.getOrganizedAddress());
+            invoiceEntity.setRegisterPhone(param.getRegisterPhone());
+            invoiceEntity.setBankName(param.getBankName());
+            invoiceEntity.setBankAccount(param.getBankAccount());
+        }
+        invoiceEntity.setConsumeType(0);
+        invoiceEntity.setOrderId(orderParam.getOrderId());
+        invoiceEntity.setShipName(orderParam.getReceiver().getShipName());
+        invoiceEntity.setShipMobile(orderParam.getReceiver().getShipMobile());
+        invoiceEntity.setShipAddress(orderParam.getReceiver().getShipAddress());
+        invoiceEntity.setShipAreaPath(orderParam.getReceiver().getShipAreaPath());
+        invoiceEntity.setEmailAddress(param.getEmailAddress());
+
+        invoiceEntity.setMoney(new BigDecimal(param.getAmount()));
+        this.save(invoiceEntity);
+    }
 }

+ 209 - 10
src/main/java/com/fdkankan/ucenter/service/impl/OrderServiceImpl.java

@@ -1,26 +1,39 @@
 package com.fdkankan.ucenter.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.constant.ConstantFilePath;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.response.PageInfo;
-import com.fdkankan.ucenter.entity.Invoice;
-import com.fdkankan.ucenter.entity.Order;
-import com.fdkankan.ucenter.entity.OrderItem;
-import com.fdkankan.ucenter.entity.User;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.common.util.NumberUtils;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.ucenter.constant.LoginConstant;
+import com.fdkankan.ucenter.constant.OrderStatus;
+import com.fdkankan.ucenter.constant.PaymentStatus;
+import com.fdkankan.ucenter.constant.ShippingStatus;
+import com.fdkankan.ucenter.entity.*;
 import com.fdkankan.ucenter.mapper.IOrderMapper;
-import com.fdkankan.ucenter.service.IInvoiceService;
-import com.fdkankan.ucenter.service.IOrderItemService;
-import com.fdkankan.ucenter.service.IOrderService;
+import com.fdkankan.ucenter.pay.alipay.sdk.AlipayService;
+import com.fdkankan.ucenter.pay.wx.WXPay;
+import com.fdkankan.ucenter.pay.wx.WXPayConstants;
+import com.fdkankan.ucenter.pay.wx.WXPayDefaultConfig;
+import com.fdkankan.ucenter.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.ucenter.service.IUserService;
+import com.fdkankan.ucenter.vo.request.CartParam;
 import com.fdkankan.ucenter.vo.request.OrderParam;
+import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
+import com.fdkankan.ucenter.vo.response.GoodsSkuVo;
 import com.fdkankan.ucenter.vo.response.OrderVo;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -39,6 +52,18 @@ public class OrderServiceImpl extends ServiceImpl<IOrderMapper, Order> implement
     IOrderItemService orderItemService;
     @Autowired
     IInvoiceService invoiceService;
+    @Autowired
+    IIncrementOrderService incrementOrderService;
+    @Autowired
+    ICartService cartService;
+    @Autowired
+    IGoodsService goodsService;
+    @Autowired
+    IGoodsSkuService goodsSkuService;
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    AlipayService alipayService;
 
     @Override
     public PageInfo pageList(OrderParam param) {
@@ -65,4 +90,178 @@ public class OrderServiceImpl extends ServiceImpl<IOrderMapper, Order> implement
         pageVo.setTotal(page.getTotal());
         return PageInfo.PageInfo(pageVo);
     }
+
+    @Override
+    public GoodsSkuVo getIncrementOrDownloadPrice(OrderParam param) {
+        return incrementOrderService.getDownloadPrice(param);
+    }
+
+    @Override
+    public void cancel(Long orderId) {
+        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(Order::getOrderStatus, OrderStatus.invalid)
+                .eq(Order::getId,orderId);
+        this.update(wrapper);
+    }
+
+    @Override
+    public void receipt(Long orderId) {
+        LambdaUpdateWrapper<Order> wrapper = new LambdaUpdateWrapper<>();
+        wrapper.set(Order::getOrderStatus, OrderStatus.completed)
+                .set(Order::getShippingStatus, ShippingStatus.received)
+                .eq(Order::getId,orderId);
+        this.update(wrapper);
+    }
+
+    @Override
+    public Order placeOrder(PlaceOrderParam param) {
+        List<Long> id = param.getGoods().parallelStream().map(CartParam::getId).collect(Collectors.toList());
+        List<String> ids = new ArrayList<>();
+        for (Long aLong : id) {
+            ids.add(String.valueOf(aLong));
+        }
+        User user = userService.getByUserName(param.getUserName());
+        cartService.deleteIds(ids);
+        // 下单
+        List<OrderItem> orderItemEntities = new ArrayList<>();
+        OrderItem orderItemEntity = null;
+        int goodsTotalCount = 0;
+        BigDecimal goodsAmount = new BigDecimal(0);
+
+        for(CartParam requestCart : param.getGoods()){
+            goodsTotalCount += requestCart.getGoodsCount();
+
+            Goods responseGoods = goodsService.getById(requestCart.getGoodsId());
+            if (responseGoods == null){
+                continue;
+            }
+            GoodsSku sku = goodsSkuService.getBySku(requestCart.getSkuSn());
+            if (sku == null){
+                throw new BusinessException(500,LoginConstant.ERROR_MSG);
+            }
+            orderItemEntity = new OrderItem();
+            orderItemEntity.setExpressNum(null);
+            orderItemEntity.setGoodsPrice(param.getAbroad().intValue() == 0 ? sku.getPrice() : sku.getDollarPrice());
+            orderItemEntity.setGoodsId(requestCart.getGoodsId());
+            orderItemEntity.setShippingStatus(ShippingStatus.unshipped.name());
+            orderItemEntity.setExpressName("顺丰速运");
+            orderItemEntity.setGoodsCount(requestCart.getGoodsCount());
+            orderItemEntity.setGoodsName(responseGoods.getName());
+            orderItemEntity.setGoodsSn(responseGoods.getGoodsSn());
+            if (StringUtils.isNotEmpty(requestCart.getSkuSn())){
+                orderItemEntity.setSkuSn(requestCart.getSkuSn());
+            }
+            orderItemEntities.add(orderItemEntity);
+
+            goodsAmount = goodsAmount.add(orderItemEntity.getGoodsPrice().multiply(new BigDecimal(orderItemEntity.getGoodsCount())));
+        }
+
+        Order orderEntity = new Order();
+        orderEntity.setOrderSn(NumberUtils.getOrderSn());
+        orderEntity.setOrderTime(new Date());
+        orderEntity.setOrderStatus(OrderStatus.unprocessed.name());
+        orderEntity.setPaymentStatus(PaymentStatus.unpaid.name());
+        orderEntity.setShippingStatus(ShippingStatus.unshipped.name());
+        orderEntity.setPaymentTypeName(param.getPayType());
+        orderEntity.setUserId(user.getId());
+        orderEntity.setGoodsTotalCount(goodsTotalCount);
+        orderEntity.setGoodsAmount(goodsAmount);
+        orderEntity.setTotalAmount(goodsAmount);
+        orderEntity.setPaidAmount(BigDecimal.ZERO);
+        orderEntity.setExpressAmount(BigDecimal.ZERO);
+        orderEntity.setDeliveryTypeName("快递运输");
+
+        if (param.getReceiver() != null){
+            orderEntity.setShipAddress(param.getReceiver().getShipAddress());
+            orderEntity.setShipAreaPath(param.getReceiver().getShipAreaPath());
+            orderEntity.setShipMobile(param.getReceiver().getShipMobile());
+            orderEntity.setShipName(param.getReceiver().getShipName());
+        }
+        orderEntity.setAbroad(param.getAbroad());
+        this.save(orderEntity);
+
+        for (OrderItem entity : orderItemEntities){
+            entity.setOrderId(orderEntity.getId());
+        }
+        orderItemService.saveBatch(orderItemEntities);
+
+        if(param.getInvoice()!=null && StringUtils.isNotBlank(param.getInvoice().getInvoiceType())){
+            param.setOrderId(orderEntity.getId());
+            param.getInvoice().setAmount(orderEntity.getTotalAmount().toString());
+            invoiceService.saveByOrder(user.getId(),param);
+        }
+        return orderEntity;
+    }
+
+    @Override
+    public boolean queryOrderStatus(OrderParam param) throws Exception {
+        boolean success = false;
+        String orderSn = param.getOrderSn();
+        switch (param.getOrderType()){
+            case 0:
+                orderSn += "_entity";
+                break;
+            case 1:
+                orderSn += "_recharge";
+                break;
+            case 2:
+                orderSn += "_expansion";
+                break;
+            case 3:
+                orderSn += "_commerce";
+                break;
+            case 4:
+                orderSn += "_increment";
+                break;
+            case 5:
+                orderSn += "_download";
+                break;
+        }
+        switch (param.getPayType()){
+            // 微信
+            case 0:
+                String orderSnE = redisUtil.get(orderSn);
+                log.warn("out_trade_no:" + orderSnE);
+                if (StringUtils.isNotEmpty(orderSnE)){
+                    Map<String, String> data = new HashMap<String, String>();
+                    data.put("out_trade_no", orderSnE);
+                    WXPayDefaultConfig config = new WXPayDefaultConfig();
+                    WXPay wxPay = new WXPay(config);
+                    Map<String, String> resp = wxPay.orderQuery(data);
+                    if (resp.get("trade_state") != null && resp.get("trade_state").equals(WXPayConstants.SUCCESS)) {
+                        redisUtil.del(orderSnE);
+                        String pngPath = ConstantFilePath.BASE_PATH + ConstantFilePath.WEIXIN_QRCODE_FOLDER + orderSn + ".png";
+                        FileUtils.deleteFile(pngPath);
+                        success = true;
+                    }
+                }
+                break;
+            // 支付宝
+            case 1:
+                log.warn("alipay out_trade_no:" + orderSn);
+                String type = alipayService.tradeQuery(orderSn);
+                log.warn("alipay type:" + type);
+                if ("SUCCESS".equals(type)){
+                    success = true;
+                }
+                break;
+            // paypal
+            case 2:
+                orderSn = orderSn.split("_")[0];
+                log.warn("paypal out_trade_no:" + orderSn);
+                Order orderEntity = this.getByOrderSn(orderSn);
+                if (PaymentStatus.paid.name().equals(orderEntity.getPaymentStatus())){
+                    success = true;
+                }
+                break;
+        }
+        return success;
+    }
+
+    @Override
+    public Order getByOrderSn(String orderSn) {
+        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(Order::getOrderSn,orderSn);
+        return this.getOne(wrapper);
+    }
 }

+ 20 - 0
src/main/java/com/fdkankan/ucenter/service/impl/SceneApplyServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.ucenter.service.impl;
+
+import com.fdkankan.ucenter.entity.SceneApply;
+import com.fdkankan.ucenter.mapper.ISceneApplyMapper;
+import com.fdkankan.ucenter.service.ISceneApplyService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-07-15
+ */
+@Service
+public class SceneApplyServiceImpl extends ServiceImpl<ISceneApplyMapper, SceneApply> implements ISceneApplyService {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/ucenter/service/impl/VirtualOrderServiceImpl.java

@@ -1,9 +1,17 @@
 package com.fdkankan.ucenter.service.impl;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.response.PageInfo;
+import com.fdkankan.ucenter.entity.User;
 import com.fdkankan.ucenter.entity.VirtualOrder;
 import com.fdkankan.ucenter.mapper.IVirtualOrderMapper;
+import com.fdkankan.ucenter.service.IUserService;
 import com.fdkankan.ucenter.service.IVirtualOrderService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.ucenter.vo.request.IncrementOrderParam;
+import com.fdkankan.ucenter.vo.request.VirtualOrderParam;
+import com.fdkankan.ucenter.vo.response.VirtualOrderVo;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 /**
@@ -17,4 +25,14 @@ import org.springframework.stereotype.Service;
 @Service
 public class VirtualOrderServiceImpl extends ServiceImpl<IVirtualOrderMapper, VirtualOrder> implements IVirtualOrderService {
 
+    @Autowired
+    IUserService userService;
+
+    @Override
+    public PageInfo pageList(VirtualOrderParam param) {
+        User user = userService.getByUserName(param.getUserName());
+        param.setUserId(user.getId());
+        Page<VirtualOrderVo> page = this.getBaseMapper().pageList(new Page<>(param.getPageNum(),param.getPageSize()),param);
+        return PageInfo.PageInfo(page);
+    }
 }

+ 63 - 0
src/main/java/com/fdkankan/ucenter/vo/request/InvoiceParam.java

@@ -0,0 +1,63 @@
+package com.fdkankan.ucenter.vo.request;
+
+import com.fdkankan.common.request.RequestBase;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class InvoiceParam extends RequestBase implements Serializable {
+
+    private static final long serialVersionUID = -4551505946155392907L;
+
+    private Long invoiceId;
+
+    private Long cameraId;
+
+    private Long orderId;
+
+    private String invoiceType;
+
+    private String amount;
+
+    private String title;
+
+    private String code;
+
+    private String organizedAddress;
+
+    private String registerPhone;
+
+    private String bankName;
+
+    private String bankAccount;
+
+    private String shipName;
+
+    private String shipAreaPath;
+
+    private String shipAddress;
+
+    private String shipMobile;
+
+    private Integer type;
+
+    private Long userId;
+
+    private String emailAddress;
+
+    private Integer send;
+
+    private String expressCompany;
+
+    private String expressNumber;
+
+    private String eInvoice;
+
+    private String remarks;
+
+    private String filePath;
+
+    private Integer consumeType;
+
+}

+ 14 - 1
src/main/java/com/fdkankan/ucenter/vo/request/OrderParam.java

@@ -5,6 +5,19 @@ import lombok.Data;
 
 @Data
 public class OrderParam extends RequestBase {
-    private String type;
     private String userName;
+    private Integer dateType;
+    private Long userIncrementId;
+
+    private Long orderId;
+
+    //0-待支付,1-待发货,2-已发货,3-已完成,空-全部
+    private String type;
+
+    private String orderSn;
+    // 订单类型,0表示购物,1表示点数充值,2表示扩充容量
+    private Integer orderType;
+
+    private int payType;
+
 }

+ 31 - 0
src/main/java/com/fdkankan/ucenter/vo/request/PlaceOrderParam.java

@@ -0,0 +1,31 @@
+package com.fdkankan.ucenter.vo.request;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+// 下单
+@Data
+public class PlaceOrderParam implements Serializable {
+
+    private static final long serialVersionUID = -8648579354113017724L;
+    // 商品信息
+    private List<CartParam> goods;
+    // 收货人信息
+    private ShipUserParam receiver;
+    // 发票
+    private InvoiceParam invoice;
+    // 付款方式,0表示微信,1表示支付宝,2表示paypal,3表示其他,4表示货到付款
+    private Integer payType;
+    // 订单表id
+    private Long orderId;
+    // 订单类型,0表示购物,1表示点数充值,2表示扩充容量
+    private Integer orderType;
+    // 0表示国内订单,1表示国外订单
+    private Integer abroad;
+    // 续费时扩容信息id
+    private Long spaceId;
+
+    private String userName;
+}

+ 18 - 0
src/main/java/com/fdkankan/ucenter/vo/request/ShipUserParam.java

@@ -0,0 +1,18 @@
+package com.fdkankan.ucenter.vo.request;
+
+import lombok.Data;
+
+@Data
+public class ShipUserParam {
+    private Long id;
+    private String country;
+    private Integer setDefault;
+    private String shipAddress;
+    private String shipArea;
+    private String shipAreaPath;
+    private String shipMobile;
+    private String shipName;
+    private String shipPhone;
+    private String shipZipCode;
+    private Long userId;
+}

+ 13 - 0
src/main/java/com/fdkankan/ucenter/vo/request/VirtualOrderParam.java

@@ -0,0 +1,13 @@
+package com.fdkankan.ucenter.vo.request;
+
+import com.fdkankan.common.request.RequestBase;
+import lombok.Data;
+
+@Data
+public class VirtualOrderParam  extends RequestBase {
+    private Long userId;
+    private String userName;
+    private String childName;
+    private Long cameraId;
+    private Integer status;
+}

+ 10 - 0
src/main/java/com/fdkankan/ucenter/vo/response/DownloadVo.java

@@ -0,0 +1,10 @@
+package com.fdkankan.ucenter.vo.response;
+
+import com.fdkankan.ucenter.entity.DownloadOrder;
+import com.fdkankan.ucenter.entity.Invoice;
+import lombok.Data;
+
+@Data
+public class DownloadVo extends DownloadOrder {
+    private Invoice invoice;
+}

+ 12 - 0
src/main/java/com/fdkankan/ucenter/vo/response/ExpansionOrderVo.java

@@ -0,0 +1,12 @@
+package com.fdkankan.ucenter.vo.response;
+
+import com.fdkankan.ucenter.entity.ExpansionOrder;
+import lombok.Data;
+
+@Data
+public class ExpansionOrderVo extends ExpansionOrder {
+    private String childName;
+    private Long space;
+    private String spaceStartTime;
+    private String spaceEndTime;
+}

+ 34 - 0
src/main/java/com/fdkankan/ucenter/vo/response/GoodsSkuVo.java

@@ -0,0 +1,34 @@
+package com.fdkankan.ucenter.vo.response;
+
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class GoodsSkuVo {
+    private Long id;
+
+    private Long goodsId;
+
+    private String skuSn;
+
+    private String description;
+
+    private int stock;
+
+    private BigDecimal price;
+
+    private BigDecimal costPrice;
+
+    private BigDecimal dollarPrice;
+
+    private BigDecimal costDollarPrice;
+    //扩容专用
+    private String unit;
+    //扩容大小
+    private int unitSize;
+    //扩容期限,单位月
+    private int month;
+    //预计到期时间
+    private Long deadLine;
+}

+ 9 - 0
src/main/java/com/fdkankan/ucenter/vo/response/VirtualOrderVo.java

@@ -0,0 +1,9 @@
+package com.fdkankan.ucenter.vo.response;
+
+import com.fdkankan.ucenter.entity.VirtualOrder;
+import lombok.Data;
+
+@Data
+public class VirtualOrderVo extends VirtualOrder {
+    private String childName;
+}

+ 5 - 0
src/main/resources/mapper/ucenter/CommerceOrderMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.ucenter.mapper.ICommerceOrderMapper">
+
+</mapper>

+ 22 - 0
src/main/resources/mapper/ucenter/ExpansionOrderMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.ucenter.mapper.IExpansionOrderMapper">
+
+    <select id="pageList" resultType="com.fdkankan.ucenter.vo.response.ExpansionOrderVo">
+        select o.id, t.child_name, o.unit, o.unit_size, c.space, o.pay_type, c.space_start_time, c.space_end_time, o.trade_time, o.pay_status, o.amount, o.order_sn, o.status, o.month
+        from t_expansion_order o
+        LEFT JOIN t_camera_space c on o.order_sn = c.order_sn
+        LEFT JOIN t_camera t on o.camera_id = t.id
+        WHERE o.pay_status = 1 AND o.rec_status = 'A'
+        <if test="param.cameraId !=null">
+            and o.camera_id = #{param.cameraId}
+        </if>
+        <if test="param.userId !=null">
+            and o.user_id = #{param.userId}
+        </if>
+        <if test="param.childName !=null and param.childName !=''">
+            and o.t.child_name like concat('%', #{param.childName},'%')
+        </if>
+
+    </select>
+</mapper>

+ 0 - 0
src/main/resources/mapper/ucenter/GoodsSkuMapper.xml


Some files were not shown because too many files changed in this diff