整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          微軟:Win 11 商店將 HTML 替換為 XAML,性能得到顯著提升

          T之家 7 月 4 日消息 隨著首個 Win11 預覽版的發布,全新的微軟商店現已上線,并將在今年晚些時候開始向主流用戶推出。

          在 6 月 24 日的發布會上,微軟表示 Windows 11 商店已經經過了“從頭到腳重新設計”。整個界面都進行了更新,滾動速度更快,還為更多內容增加了空間。據微軟官方稱,用戶操作更簡單,HTML 組件也已經被砍掉了。

          在 Windows 10 上,微軟商店的前端部分構建于 HTML/CSS (web 組件) 中。例如產品頁面完全基于 html,雖然兼容性高一點但這大大降低了用戶體驗,尤其是當用戶點擊“獲取”或“安裝”按鈕時還會崩潰。

          例如,之前有網友反饋稱下載大文件時大概率會失敗,而且錯誤代碼還沒有給出任何解釋。

          在 Windows 11 中,微軟將用 XAML/c# 語言編寫的全新商店取代現有的商店,據微軟官方員稱,它是完全“UWP”的。

          據稱,新版應用商店的性能得到了顯著改善,例如下載不再出現之前出現的中、大型應用和游戲的下載失敗問題。一些不愿透露姓名的消息人士也證實,用戶在新版商店中下載大型游戲的速度也變得更快。

          Microsoft Store 店商業模式的巨大改變

          通過 Windows 11,微軟也在嘗試改變其 Microsoft Store 的商業模式。

          該公司希望所有開發者都去盡可能為 Microsoft Store 開發應用程序和游戲,而開發者現可使用自己的第三方商業支付系統,相對來說更加寬容和自由。

          IT之家了解到,微軟還支持通過添加更多使用不同框架創建的應用和游戲來擴展 Store 目錄。微軟 Teams 和 Visual Studio 預計將在今年年底上線全新商店。

          值得一提的是,Adobe, Zoom, OBS Studio 和 Canva 等著名應用現已上架微軟新版 Microsoft Store。

          此外,Windows Insider 體驗者可以通過使用舊版商店手動更新來下載新設計的 Microsoft Store。當然,雖然商店已經經過重新設計,但一些功能,如通過亞馬遜應用商店 整合 Android 應用的功能仍未上線。

          微軟還表示,Windows 10 用戶將在今年晚些時候獲得相同的商店體驗,其商店的質量將在未來幾個月得到顯著提高,例如搜索結果將不再包括低質量的指南/教程等內容。

          :簡介

          電腦支付常用于電商和后臺管理系統的賬戶充值等場景。

          電腦網站支付 文檔

          電腦網站支付流程圖

          二:集成步驟

          0. 創建應用、配置密鑰

          集成前需要先創建應用、配置密鑰、回調地址等以及alipay-sdk-java.jar和alipay-trade-sdk.jar請查看Spring Boot入門教程(三十五):支付寶集成-準備工作

          1. dependency

          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
          
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <scope>test</scope>
              </dependency>
          
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-thymeleaf</artifactId>
              </dependency>
              <!-- alipay begin -->
              <dependency>
                  <groupId>com.alipay</groupId>
                  <artifactId>alipay-sdk-java</artifactId>
                  <version>20170725114550</version>
              </dependency>
              <dependency>
                  <groupId>com.alipay</groupId>
                  <artifactId>alipay-trade-sdk</artifactId>
                  <version>20161215</version>
              </dependency>
              <dependency>
                  <groupId>com.google.code.gson</groupId>
                  <artifactId>gson</artifactId>
              </dependency>
              <dependency>
                  <groupId>commons-configuration</groupId>
                  <artifactId>commons-configuration</artifactId>
                  <version>1.10</version>
              </dependency>
              <dependency>
                  <groupId>com.google.zxing</groupId>
                  <artifactId>core</artifactId>
                  <version>3.2.1</version>
              </dependency>
              <!-- alipay end -->
              <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
              </dependency>
          </dependencies>
          

          2. application.yml

          # 沙箱賬號
          pay:
            alipay:
              gatewayUrl: https://openapi.alipaydev.com/gateway.do
              appid: 2016091400508498
              appPrivateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtXKWs+trRSuCxEUvlsEeSAuLWs3B/Dh74R8223BnfzoA29aGeoycAqfKlBMcbzU2G1KayESvZKGpwBLeejSbecRYjgZsQDyEaDimQQJtGFvZVV6u4XNnvIJ72eQzEaEIQfuiorjBTLm6DQuds4R0GxftqON6QFoIZkWB9ZrZKd02cuy16dW+UqtLVGGAHcCIAkB63zUiKSNfweMddneZ7MVs3lvu3xhMnD+5us/+n2Vp4qhfmpYLcdqIW6InU4GypeoOpyUTrfUGpgdR0l924vHy/GQJZEKFaRcK3cYK+ECyKpSIoqaJJFLHbkqsliuPpMUG+rM3jiqeIAH4psAznAgMBAAECggEBAJ5jyEbbxrJzrAh7GhHX1fwUQPYSadTbrPYAfHX2cHlnrQMJtsk+nTLhEv0r+VJwZ8WpYkfMong8kcqYtL7ajcmsHqMAFhE9EWxBxj2ymWsXLabZe93sj30IG9Rq0nxcGQgDO0RqKWLGSFgK93Al2KRInKT3InkY53K+vR61ihVLmGf7+GwPtIZteBy+tuAyvcj2RlkYvjiFi3ySyZ1wA3sJIlgrGiixd6fj20XFGNE3CnAwu0BJgXXbP/S9J4C0RRa3ZXj8fX7oONhVxz2xKxn7AT4e8OWjt7J41H2LRct8Fgl9pqgz2FJYv/WfbkG8x9fGiKYYvPXoxjjrk/tkewkCgYEA8f9Lcu5JPrE9rpw9zlwhm5cOO81xLxdwL5R5/1bRP48BZGIYuqlCbVvjJVqtO8eTnLhUwH7fG8B7cmoeO9bGr9GQrtfyCqz6FtVymTBieJlfgZDVhtzyv2qKOBMIFE8jsbSBK/NHHMvykJ+XdQ1riwCeQDdXICRuYTTFwGk2OsUCgYEAt2SoN95tVmVrvKG6ATLNEtge/ozeVywA4GjltrSw/G9vqp+DkkT2pY19uROuzMazoTzKWpPho2q/qzNlv/ANbOFM2GEmKamQ7CO88JgRxMsPTvc/HxCLU/ClMJU8LcOf9LfP2KYZpPwuheKJoF4vDGj8NsbFmccJyYSdpkNEk7sCgYBJlL2FMaz1sgC2Ue19DIhvfaunRV1P20mSPgwmNmijccETm7w3LXX0OIdFeV/JGHLqqSWj7i+6iXk/ncKZoUGCfi8G6sQ+uL/GJ5qTt6GJV+ExTS+PtSjeSO/EAw1m13Vb+C16hpstx1l23f+4aJ81gbecgPct38XsKpaiXZtOnQKBgQCMsN7QRYYxwoq9YoDUzIlAzKYyeBVWYL6najHYUZR5hG/xQIBqZRem9/4cTvpJxKInrwA6LrrqaEl0aHDFp75U6h7O3PCvA5PXZK9dD/yJsZIj7U/yX/nTQokn1UUegrYiwiTkusBvrrtuINWePsLvTVc4GpObHnPmsiNTWsWwYwKBgENaeTNOCHV2km/ysXQSEIhKbtlAMQPsgWHCt/bzHlF9m18izb1LrJyjzcSsd+Zy78R+pv4G50Q27c3e/DFPz/wYxN/yHWRbyLBA8ipJbCtMtPEdS9krpmN6cChIdLGbz4CVUqOPSRzNb9lhhgPCcCNRq6DG3HBceb1Se9VnO3zk
              alipayPublicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApFQKccMq+wPoWh93DcX3XYrnT7FJ3gntJA/jEwgk6Jd3iEVS2CyUCCgFVcQn8xjXT81YbZHYvoC50IBuu+A+Ey+J8VIgsBm5g9uwbOLRf66GrZjuKOlalHm5gHXjcL2gZRMBJEStOxstcO2YQriqhQzdL3EKp+HQc9u14IOVFpZdR8qq1l7CzKHn1vQo/1fUPfUrTLQqSuQTU9Ospv/QHFqOJA7DPetUQ+jnaZ082f3clr4ITw4EE8A6IWqTXcETTx5j/udCGP84g2Y4j+8i9DqYGyD5ePVgt4G0ICBX1bi1qNlylfxRg8Y3c1DFrRGyr0NpKQxSVXkYaVNvrCoudQIDAQAB
              returnUrl: http://s9v2cw.natappfree.cc/alipay/return
              notifyUrl: http://s9v2cw.natappfree.cc/alipay/notify
          
          spring:
            thymeleaf:
              prefix: classpath:/templates/
              suffix: .html
              mode: HTML5
              encoding: UTF-8
          

          3. AlipayProperties

          /**
           * 支付寶支付的參數配置
           *
           * @author mengday zhang
           */
          @Data
          @Slf4j
          @ConfigurationProperties(prefix = "pay.alipay")
          public class AlipayProperties {
          
              /** 支付寶gatewayUrl */
              private String gatewayUrl;
              /** 商戶應用id */
              private String appid;
              /** RSA私鑰,用于對商戶請求報文加簽 */
              private String appPrivateKey;
              /** 支付寶RSA公鑰,用于驗簽支付寶應答 */
              private String alipayPublicKey;
              /** 簽名類型 */
              private String signType = "RSA2";
          
              /** 格式 */
              private String formate = "json";
              /** 編碼 */
              private String charset = "UTF-8";
          
              /** 同步地址 */
              private String returnUrl;
          
              /** 異步地址 */
              private String notifyUrl;
          
              /** 最大查詢次數 */
              private static int maxQueryRetry = 5;
              /** 查詢間隔(毫秒) */
              private static long queryDuration = 5000;
              /** 最大撤銷次數 */
              private static int maxCancelRetry = 3;
              /** 撤銷間隔(毫秒) */
              private static long cancelDuration = 3000;
          
              private AlipayProperties() {}
          
              /**
               * PostContruct是spring框架的注解,在方法上加該注解會在項目啟動的時候執行該方法,也可以理解為在spring容器初始化的時候執行該方法。
               */
              @PostConstruct
              public void init() {
                  log.info(description());
              }
          
              public String description() {
                  StringBuilder sb = new StringBuilder("\nConfigs{");
                  sb.append("支付寶網關: ").append(gatewayUrl).append("\n");
                  sb.append(", appid: ").append(appid).append("\n");
                  sb.append(", 商戶RSA私鑰: ").append(getKeyDescription(appPrivateKey)).append("\n");
                  sb.append(", 支付寶RSA公鑰: ").append(getKeyDescription(alipayPublicKey)).append("\n");
                  sb.append(", 簽名類型: ").append(signType).append("\n");
          
                  sb.append(", 查詢重試次數: ").append(maxQueryRetry).append("\n");
                  sb.append(", 查詢間隔(毫秒): ").append(queryDuration).append("\n");
                  sb.append(", 撤銷嘗試次數: ").append(maxCancelRetry).append("\n");
                  sb.append(", 撤銷重試間隔(毫秒): ").append(cancelDuration).append("\n");
                  sb.append("}");
                  return sb.toString();
              }
          
              private String getKeyDescription(String key) {
                  int showLength = 6;
                  if (StringUtils.isNotEmpty(key) && key.length() > showLength) {
                      return new StringBuilder(key.substring(0, showLength)).append("******")
                              .append(key.substring(key.length() - showLength)).toString();
                  }
                  return null;
              }
          }
          

          4. AlipayConfiguration

          /**
           * 兩個支付寶客戶端,用戶可以使用任意一個.
           *
           * alipay-trade-sdk 是對alipay-sdk-java的封裝,建議使用alipay-trade-sdk.
           *
           * @author mengday zhang
           */
          @Configuration
          @EnableConfigurationProperties(AlipayProperties.class)
          public class AlipayConfiguration {
          
              @Autowired
              private AlipayProperties properties;
          
              /**
               * alipay-trade-sdk
               * @return
               */
              @Bean
              public AlipayTradeService alipayTradeService() {
                  return new AlipayTradeServiceImpl.ClientBuilder()
                          .setGatewayUrl(properties.getGatewayUrl())
                          .setAppid(properties.getAppid())
                          .setPrivateKey(properties.getAppPrivateKey())
                          .setAlipayPublicKey(properties.getAlipayPublicKey())
                          .setSignType(properties.getSignType())
                          .build();
              }
          
              /**
               * alipay-sdk-java
               * @return
               */
              @Bean
              public AlipayClient alipayClient(){
                  return new DefaultAlipayClient(properties.getGatewayUrl(),
                          properties.getAppid(),
                          properties.getAppPrivateKey(),
                          properties.getFormate(),
                          properties.getCharset(),
                          properties.getAlipayPublicKey(),
                          properties.getSignType());
              }
          }
          

          5. AlipayPagePayController

          /**
           * 支付寶-電腦網站支付.
           * <p>
           * 電腦網站支付 https://docs.open.alipay.com/270/105898/
           *
           * @author Mengday Zhang
           * @version 1.0
           * @since 2018/6/14
           */
          @Controller
          @RequestMapping("/alipay/page")
          public class AlipayPagePayController {
          
              @Autowired
              private AlipayProperties alipayProperties;
          
              @Autowired
              private AlipayClient alipayClient;
          
              @Autowired
              private AlipayController alipayController;
          
          
              @PostMapping("/gotoPayPage")
              public void gotoPayPage(HttpServletResponse response) throws AlipayApiException, IOException {
                  // 訂單模型
                  String productCode = "FAST_INSTANT_TRADE_PAY";
                  AlipayTradePagePayModel model = new AlipayTradePagePayModel();
                  model.setOutTradeNo(UUID.randomUUID().toString());
                  model.setSubject("支付測試");
                  model.setTotalAmount("0.01");
                  model.setBody("支付測試,共0.01元");
                  model.setProductCode(productCode);
          
                  AlipayTradePagePayRequest pagePayRequest =new AlipayTradePagePayRequest();
                  pagePayRequest.setReturnUrl("http://s9v2cw.natappfree.cc/alipay/page/returnUrl");
                  pagePayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
                  pagePayRequest.setBizModel(model);
          
                  // 調用SDK生成表單, 并直接將完整的表單html輸出到頁面
                  String form = alipayClient.pageExecute(pagePayRequest).getBody();
                  response.setContentType("text/html;charset=" + alipayProperties.getCharset());
                  response.getWriter().write(form);
                  response.getWriter().flush();
                  response.getWriter().close();
              }
          
              @RequestMapping("/returnUrl")
              public String returnUrl(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException, AlipayApiException {
                  response.setContentType("text/html;charset=" + alipayProperties.getCharset());
          
                  boolean verifyResult = alipayController.rsaCheckV1(request);
                  if(verifyResult){
                      //驗證成功
                      //請在這里加上商戶的業務邏輯程序代碼,如保存支付寶交易號
                      //商戶訂單號
                      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");
          
                      return "pagePaySuccess";
          
                  }else{
                      return "pagePayFail";
          
                  }
              }
          }
          

          6. AlipayController

          /**
           * 支付寶通用接口.
           * <p>
           * detailed description
           *
           * @author Mengday Zhang
           * @version 1.0
           * @since 2018/6/13
           */
          @Slf4j
          @RestController
          @RequestMapping("/alipay")
          public class AlipayController {
          
              @Autowired
              private AlipayProperties aliPayProperties;
          
              @Autowired
              private AlipayClient alipayClient;
          
              @Autowired
              private AlipayTradeService alipayTradeService;
          
              /**
               * 支付異步通知
               *
               * 接收到異步通知并驗簽通過后,一定要檢查通知內容,包括通知中的app_id、out_trade_no、total_amount是否與請求中的一致,并根據trade_status進行后續業務處理。
               *
               * https://docs.open.alipay.com/194/103296
               */
              @RequestMapping("/notify")
              public String notify(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
                  // 一定要驗簽,防止黑客篡改參數
                  Map<String, String[]> parameterMap = request.getParameterMap();
                  StringBuilder notifyBuild = new StringBuilder("/****************************** alipay notify ******************************/\n");
                  parameterMap.forEach((key, value) -> notifyBuild.append(key + "=" + value[0] + "\n") );
                  log.info(notifyBuild.toString());
          
          
                  boolean flag = this.rsaCheckV1(request);
                  if (flag) {
                      /**
                       * TODO 需要嚴格按照如下描述校驗通知數據的正確性
                       *
                       * 商戶需要驗證該通知數據中的out_trade_no是否為商戶系統中創建的訂單號,
                       * 并判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額),
                       * 同時需要校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email),
                       *
                       * 上述有任何一個驗證不通過,則表明本次通知是異常通知,務必忽略。
                       * 在上述驗證通過后商戶必須根據支付寶不同類型的業務通知,正確的進行不同的業務處理,并且過濾重復的通知結果數據。
                       * 在支付寶的業務通知中,只有交易通知狀態為TRADE_SUCCESS或TRADE_FINISHED時,支付寶才會認定為買家付款成功。
                       */
          
                      //交易狀態
                      String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
                      // 商戶訂單號
                      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 total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
                      // TRADE_FINISHED(表示交易已經成功結束,并不能再對該交易做后續操作);
                      // TRADE_SUCCESS(表示交易已經成功結束,可以對該交易做后續操作,如:分潤、退款等);
                      if(tradeStatus.equals("TRADE_FINISHED")){
                          //判斷該筆訂單是否在商戶網站中已經做過處理
                          //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,
                          // 并判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額),并執行商戶的業務程序
                          //請務必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的
                          //如果有做過處理,不執行商戶的業務程序
          
                          //注意:
                          //如果簽約的是可退款協議,退款日期超過可退款期限后(如三個月可退款),支付寶系統發送該交易狀態通知
                          //如果沒有簽約可退款協議,那么付款完成后,支付寶系統發送該交易狀態通知。
                      } else if (tradeStatus.equals("TRADE_SUCCESS")){
                          //判斷該筆訂單是否在商戶網站中已經做過處理
                          //如果沒有做過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,
                          // 并判斷total_amount是否確實為該訂單的實際金額(即商戶訂單創建時的金額),并執行商戶的業務程序
                          //請務必判斷請求時的total_fee、seller_id與通知時獲取的total_fee、seller_id為一致的
                          //如果有做過處理,不執行商戶的業務程序
          
                          //注意:
                          //如果簽約的是可退款協議,那么付款完成后,支付寶系統發送該交易狀態通知。
          
                      }
          
                      return "success";
                  }
          
                  return "fail";
              }
          
              /**
               * 訂單查詢(最主要用于查詢訂單的支付狀態)
               * @param orderNo 商戶訂單號
               * @return
               */
              @GetMapping("/query")
              public String query(String orderNo){
          
                  AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                          .setOutTradeNo(orderNo);
                  AlipayF2FQueryResult result = alipayTradeService.queryTradeResult(builder);
                  switch (result.getTradeStatus()) {
                      case SUCCESS:
                          log.info("查詢返回該訂單支付成功: )");
          
                          AlipayTradeQueryResponse resp = result.getResponse();
                          log.info(resp.getTradeStatus());
          //                log.info(resp.getFundBillList());
                          break;
          
                      case FAILED:
                          log.error("查詢返回該訂單支付失敗!!!");
                          break;
          
                      case UNKNOWN:
                          log.error("系統異常,訂單支付狀態未知!!!");
                          break;
          
                      default:
                          log.error("不支持的交易狀態,交易返回異常!!!");
                          break;
                  }
                  return result.getResponse().getBody();
              }
          
              /**
               * 退款
               * @param orderNo 商戶訂單號
               * @return
               */
              @PostMapping("/refund")
              @ResponseBody
              public String refund(String orderNo) throws AlipayApiException {
                  AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
          
                  AlipayTradeRefundModel model=new AlipayTradeRefundModel();
                  // 商戶訂單號
                  model.setOutTradeNo(orderNo);
                  // 退款金額
                  model.setRefundAmount("0.01");
                  // 退款原因
                  model.setRefundReason("無理由退貨");
                  // 退款訂單號(同一個訂單可以分多次部分退款,當分多次時必傳)
          //        model.setOutRequestNo(UUID.randomUUID().toString());
                  alipayRequest.setBizModel(model);
          
                  AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest);
                  System.out.println(alipayResponse.getBody());
          
                  return alipayResponse.getBody();
              }
          
              /**
               * 退款查詢
               * @param orderNo 商戶訂單號
               * @param refundOrderNo 請求退款接口時,傳入的退款請求號,如果在退款請求時未傳入,則該值為創建交易時的外部訂單號
               * @return
               * @throws AlipayApiException
               */
              @GetMapping("/refundQuery")
              @ResponseBody
              public String refundQuery(String orderNo, String refundOrderNo) throws AlipayApiException {
                  AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();
          
                  AlipayTradeFastpayRefundQueryModel model=new AlipayTradeFastpayRefundQueryModel();
                  model.setOutTradeNo(orderNo);
                  model.setOutRequestNo(refundOrderNo);
                  alipayRequest.setBizModel(model);
          
                  AlipayTradeFastpayRefundQueryResponse alipayResponse = alipayClient.execute(alipayRequest);
                  System.out.println(alipayResponse.getBody());
          
                  return alipayResponse.getBody();
              }
          
              /**
               * 關閉交易
               * @param orderNo
               * @return
               * @throws AlipayApiException
               */
              @PostMapping("/close")
              @ResponseBody
              public String close(String orderNo) throws AlipayApiException {
                  AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();
                  AlipayTradeCloseModel model =new AlipayTradeCloseModel();
                  model.setOutTradeNo(orderNo);
                  alipayRequest.setBizModel(model);
          
                  AlipayTradeCloseResponse alipayResponse = alipayClient.execute(alipayRequest);
                  System.out.println(alipayResponse.getBody());
          
                  return alipayResponse.getBody();
              }
          
              /**
               * 校驗簽名
               * @param request
               * @return
               */
              public boolean rsaCheckV1(HttpServletRequest request){
                  // https://docs.open.alipay.com/54/106370
                  // 獲取支付寶POST過來反饋信息
                  Map<String,String> params = new HashMap<>();
                  Map requestParams = request.getParameterMap();
                  for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
                      String name = (String) iter.next();
                      String[] values = (String[]) requestParams.get(name);
                      String valueStr = "";
                      for (int i = 0; i < values.length; i++) {
                          valueStr = (i == values.length - 1) ? valueStr + values[i]
                                  : valueStr + values[i] + ",";
                      }
                      params.put(name, valueStr);
                  }
          
                  try {
                      boolean verifyResult = AlipaySignature.rsaCheckV1(params,
                              aliPayProperties.getAlipayPublicKey(),
                              aliPayProperties.getCharset(),
                              aliPayProperties.getSignType());
          
                      return verifyResult;
                  } catch (AlipayApiException e) {
                      log.debug("verify sigin error, exception is:{}", e);
                      return false;
                  }
              }
          }
          

          7. WebMvcConfiguration

          /**
           * WebMVC 配置.
           * <p>
           * 添加路徑和頁面的映射關系
           *
           * @author Mengday Zhang
           * @version 1.0
           * @since 2018/6/13
           */
          @Configuration
          public class WebMvcConfiguration extends WebMvcConfigurationSupport {
              @Override
              protected void addViewControllers(ViewControllerRegistry registry) {
                  registry.addViewController("/gotoWapPage").setViewName("gotoWapPay");
                  registry.addViewController("/gotoPagePage").setViewName("gotoPagePay");
                  super.addViewControllers(registry);
              }
          }
          

          8. templates

          gotoPagePay.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body style="font-size: 30px">
          
          <form method="post" action="/alipay/page/gotoPayPage">
              <h3>購買商品:越南新娘</h3>
              <h3>價格:20000</h3>
              <h3>數量:10個</h3>
          
              <button style="width: 100%; height: 60px; alignment: center; background: #b49e8f" type="submit">立即支付</button>
          </form>
          
          </body>
          </html>
          

          pagePaySuccess.html

          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
          
          <h1>電腦網站支付 成功,我們將盡快從越南偷渡過來,收貨后請請及時驗貨!歡迎下次再來</h1>
          
          </body>
          </html>
          

          三:Demo圖

          三:查詢對賬單下載地址

          本教程詳細介紹了如何使用ssm框架實現支付寶支付功能。本文章分為兩大部分,分別是「支付寶測試環境代碼測試」和「將支付寶支付整合到ssm框架」,詳細的代碼和圖文解釋,自己實踐的時候一定仔細閱讀相關文檔,話不多說我們開始。

          一、支付寶測試環境代碼測試


          源代碼

          https://github.com/OUYANGSIHAI/sihai-maven-ssm-alipay

          1、下載電腦網站的官方demo:

          下載:https://docs.open.alipay.com/270/106291/

          2.下載解壓導入eclipse

          readme.txt請好好看一下。

          只有一個Java配置類,其余都是JSP。

          3、配置AlipayConfig

          (1) 注冊螞蟻金服開發者賬號(免費,不像蘋果會收取費用)

          注冊地址:https://open.alipay.com ,用你的支付寶賬號掃碼登錄,完善個人信息,選擇服務類型(我選的是自研)。

          (2) 設置app_id和gatewayUrl

          其中密鑰需要自己生成,appID和支付寶網關是已經給好的,網關有dev字樣,表明是用于開發測試。

          (3) 設置密鑰

          點擊“生成方法”,打開界面如下:

          下周密鑰生成工具,解壓打開后,選擇2048位生成密鑰:

          如果沒有設置過,此時顯示文本是"設置應用公鑰",我這里是已經設置過得。

          設置方法,"打開密鑰文件路徑":

          復制應用公鑰2048.txt中的內容到點擊"設置應用公鑰"的彈出框中,保存:

          • 商戶私鑰(merchant_private_key)復制 應用私鑰2048.txt 中的內容到merchant_private_key中。
          • 支付寶公鑰(alipay_public_key)

          點擊如上圖鏈接,復制彈出框里面的內容到alipay_public_key。

          如果這個設置不對,結果是:支付成功,但是驗簽失敗。

          如果是正式環境,需要上傳到對應的應用中:

          (4) 服務器異步通知頁面路徑(notify_url)

          如果沒有改名,修改IP和端口號就可以了,我自己的如下:

          http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp

          (5) 頁面跳轉同步通知頁面的路徑(return_url)

          http://localhost:8080/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp

          4、測試運行

          測試用的支付寶買家賬戶可以在"沙箱賬"這個頁面可以找到:

          支付成功后,驗簽結果:

          問題解決

          由于我們使用的是沙箱測試環境,測試環境和正式上線的環境的網關是不一樣的,如果配置錯誤,會出現,appid錯誤的問題。配置如下:

          源代碼下載

          鏈接: https://pan.baidu.com/s/1n6GbEJiMzoGWJrSw0bb2Cg 密碼: zd9e

          二、將支付寶支付整合到ssm框架

          1、項目架構

          • 項目架構:spring+springmvc+mybatis
          • 數據庫:mysql
          • 部署環境:tomcat9.0
          • 開發環境:jdk9、idea
          • 支付:支付寶、微信

          整合到ssm一樣,我們需要像沙箱測試環境一樣,需要修改支付的配置信息

          2、數據庫代碼

          主要包括以下的數據庫表:

          • user:用戶表
          • order:支付產生的訂單
          • flow:流水賬
          • product:商品表:用于模擬購買商品。
          drop table if exists user;
          
          /*==============================================================*/
          /* Table: user */
          /*==============================================================*/
          create table user
          (
           id varchar(20) not null,
           username varchar(128),
           sex varchar(20),
           primary key (id)
          );
          
          alter table user comment '用戶表';
          
          
          CREATE TABLE `flow` (
           `id` varchar(20) NOT NULL,
           `flow_num` varchar(20) DEFAULT NULL COMMENT '流水號',
           `order_num` varchar(20) DEFAULT NULL COMMENT '訂單號',
           `product_id` varchar(20) DEFAULT NULL COMMENT '產品主鍵ID',
           `paid_amount` varchar(11) DEFAULT NULL COMMENT '支付金額',
           `paid_method` int(11) DEFAULT NULL COMMENT '支付方式
           1:支付寶
           2:微信',
           `buy_counts` int(11) DEFAULT NULL COMMENT '購買個數',
           `create_time` datetime DEFAULT NULL COMMENT '創建時間',
           PRIMARY KEY (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='流水表';
          
          
          CREATE TABLE `orders` (
           `id` varchar(20) NOT NULL,
           `order_num` varchar(20) DEFAULT NULL COMMENT '訂單號',
           `order_status` varchar(20) DEFAULT NULL COMMENT '訂單狀態
           10:待付款
           20:已付款',
           `order_amount` varchar(11) DEFAULT NULL COMMENT '訂單金額',
           `paid_amount` varchar(11) DEFAULT NULL COMMENT '實際支付金額',
           `product_id` varchar(20) DEFAULT NULL COMMENT '產品表外鍵ID',
           `buy_counts` int(11) DEFAULT NULL COMMENT '產品購買的個數',
           `create_time` datetime DEFAULT NULL COMMENT '訂單創建時間',
           `paid_time` datetime DEFAULT NULL COMMENT '支付時間',
           PRIMARY KEY (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='訂單表';
          
          
          CREATE TABLE `product` (
           `id` varchar(20) NOT NULL,
           `name` varchar(20) DEFAULT NULL COMMENT '產品名稱',
           `price` varchar(11) DEFAULT NULL COMMENT '價格',
           PRIMARY KEY (`id`)
          ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='產品表 ';
          

          3、dao數據接口層

          這里就不介紹了,這個只包括簡單的curd,可以使用`通用mapper`,或者`逆向工程`就行。以訂單order為例給出:

          public interface OrdersMapper {
           int countByExample(OrdersExample example);
          
           int deleteByExample(OrdersExample example);
          
           int deleteByPrimaryKey(String id);
          
           int insert(Orders record);
          
           int insertSelective(Orders record);
          
           List<Orders> selectByExample(OrdersExample example);
          
           Orders selectByPrimaryKey(String id);
          
           int updateByExampleSelective(@Param("record") Orders record, @Param("example") OrdersExample example);
          
           int updateByExample(@Param("record") Orders record, @Param("example") OrdersExample example);
          
           int updateByPrimaryKeySelective(Orders record);
          
           int updateByPrimaryKey(Orders record);
          }

          注意:源代碼最后給出

          4、service層

          同上,最后在項目源代碼里可見。以訂單order為例給出:

          /**
           * 訂單操作 service
           * @author ibm
           *
           */
          public interface OrdersService {
          
           /**
           * 新增訂單
           * @param order
           */
           public void saveOrder(Orders order);
          
           /**
           * 
           * @Title: OrdersService.java
           * @Package com.sihai.service
           * @Description: 修改叮當狀態,改為 支付成功,已付款; 同時新增支付流水
           * Copyright: Copyright (c) 2017
           * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY
           * 
           * @author sihai
           * @date 2017年8月23日 下午9:04:35
           * @version V1.0
           */
           public void updateOrderStatus(String orderId, String alpayFlowNum, String paidAmount);
          
           /**
           * 獲取訂單
           * @param orderId
           * @return
           */
           public Orders getOrderById(String orderId);
          
          }

          三、支付寶支付controller(支付流程)

          支付流程圖

          首先,啟動項目后,輸入http://localhost:8080/,會進入到商品頁面,如下:

          下面是頁面代碼

          商品頁面(products.jsp)

          代碼實現:

          <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
          <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
          <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> 
          <script src="<%=request.getContextPath() %>/static/js/jquery.min.js" type="text/javascript"></script>
          
          <html>
          
           <head>
          
           </head>
          
           <body>
          
           <table>
           <tr>
           <td>
           產品編號
           </td>
           <td>
           產品名稱
           </td>
           <td>
           產品價格
           </td>
           <td>
           操作
           </td>
           </tr>
           <c:forEach items="${pList }" var="p">
           <tr>
           <td>
           ${p.id }
           </td>
           <td>
           ${p.name }
           </td>
           <td>
           ${p.price }
           </td>
           <td>
           <a href="<%=request.getContextPath() %>/alipay/goConfirm.action?productId=${p.id }">購買</a>
           </td>
           </tr>
          
           </c:forEach>
           </table>
          
           <input type="hidden" id="hdnContextPath" name="hdnContextPath" value="<%=request.getContextPath() %>"/>
           </body>
          
          </html>
          
          
          <script type="text/javascript">
          
           $(document).ready(function() {
          
           var hdnContextPath = $("#hdnContextPath").val();
          
          
           });
          
          
          </script>
          

          點擊上面的購買,進入到訂單頁面

          填寫個數,然后點擊生成訂單,調用如下代碼

          根據SID(生成id的工具)等信息生成訂單,保存到數據庫。

          進入到選擇支付頁面

          調用了如下代碼:

          然后,我們選擇支付寶支付,進入到了我們支付的頁面了,大功告成!

          調用了如下代碼:

          /**
           *
           * @Title: AlipayController.java
           * @Package com.sihai.controller
           * @Description: 前往支付寶第三方網關進行支付
           * Copyright: Copyright (c) 2017
           * Company:FURUIBOKE.SCIENCE.AND.TECHNOLOGY
           *
           * @author sihai
           * @date 2017年8月23日 下午8:50:43
           * @version V1.0
           */
           @RequestMapping(value = "/goAlipay", produces = "text/html; charset=UTF-8")
           @ResponseBody
           public String goAlipay(String orderId, HttpServletRequest request, HttpServletRequest response) throws Exception {
          
           Orders order = orderService.getOrderById(orderId);
          
           Product product = productService.getProductById(order.getProductId());
          
           //獲得初始化的AlipayClient
           AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
          
           //設置請求參數
           AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
           alipayRequest.setReturnUrl(AlipayConfig.return_url);
           alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
          
           //商戶訂單號,商戶網站訂單系統中唯一訂單號,必填
           String out_trade_no = orderId;
           //付款金額,必填
           String total_amount = order.getOrderAmount();
           //訂單名稱,必填
           String subject = product.getName();
           //商品描述,可空
           String body = "用戶訂購商品個數:" + order.getBuyCounts();
          
           // 該筆訂單允許的最晚付款時間,逾期將關閉交易。取值范圍:1m~15d。m-分鐘,h-小時,d-天,1c-當天(1c-當天的情況下,無論交易何時創建,都在0點關閉)。該參數數值不接受小數點, 如 1.5h,可轉換為 90m。
           String timeout_express = "1c";
          
           alipayRequest.setBizContent("{"out_trade_no":""+ out_trade_no +"","
           + ""total_amount":""+ total_amount +"","
           + ""subject":""+ subject +"","
           + ""body":""+ body +"","
           + ""timeout_express":""+ timeout_express +"","
           + ""product_code":"FAST_INSTANT_TRADE_PAY"}");
          
           //請求
           String result = alipayClient.pageExecute(alipayRequest).getBody();
          
           return result;
           }
          

          這段代碼都可以在阿里支付的demo里面找到的,只需要復制過來,然后改改,整合到ssm環境即可。

          上面就是將阿里支付寶支付整合到ssm的全過程了。


          主站蜘蛛池模板: 极品少妇一区二区三区四区| 亚洲视频一区网站| 无码人妻精品一区二区蜜桃| 午夜一区二区在线观看| 人妻无码第一区二区三区 | 国产午夜精品一区二区三区嫩草| tom影院亚洲国产一区二区| 国产A∨国片精品一区二区| 国产精品视频免费一区二区| 日韩精品无码中文字幕一区二区| 中文人妻无码一区二区三区| 亚洲第一区精品观看| 美女视频黄a视频全免费网站一区| AV天堂午夜精品一区| 无码一区18禁3D| 夜精品a一区二区三区| 日韩视频在线一区| 大屁股熟女一区二区三区| 丰满岳妇乱一区二区三区| 无码AV动漫精品一区二区免费| 视频一区二区三区免费观看| 麻豆视频一区二区三区| 国产一区二区三区高清视频 | 国产一区精品视频| 中文字幕一区二区三区精华液| 中文字幕乱码一区二区免费| 国产suv精品一区二区33| 无码精品尤物一区二区三区| 久久精品人妻一区二区三区 | 精品国产乱码一区二区三区| 国产成人久久精品区一区二区| 成人精品视频一区二区三区尤物 | 精品一区精品二区制服| 亚洲av永久无码一区二区三区| 日本一区二区三区不卡视频| 偷拍精品视频一区二区三区| 亚洲AV无码一区二区三区系列| 一本一道波多野结衣一区| 人妻在线无码一区二区三区| 国产在线一区视频| 午夜福利av无码一区二区 |