串接第三方支付
SpringBoot微服務項目筆記-22

商城支付

非對稱加密 RSA

image-20220131093614541

  • 加密跟解密是不同的鑰匙
    • 我用私鑰加密,發給給你,你用公鑰解密,你不知道我的私鑰
  • 加簽: 根據明文(例如: “我給小明100元”)用MD5生成一個簽名,如果明文任意字符修改,簽名就會天差地別(MD5特性)
  • 驗簽: 確定 明文與簽名是否對應(明文是否被篡改)

NAT穿透

Network Address Translation Traversal

  • 內部IP就是192.168.X.X開頭的那些,穿透技術就是讓外部可以透過公有IP訪問到你的內部IP
  • 原理就是透過各種網路服務供應商幫你搭橋
  • 使用場景:
    • 開發測試,取得暫時的對外域名讓外部可以訪問本機
    • 智慧家電連網,例如出門在外用手機網路可以看家裡監控那種
    • 遠程控制,遠端桌面
  • 以前玩Minecraft架server有用過類似的東西

支付沙盒

支付串接流程

  • PayWebController.java
    • 這邊接收前端來的訂單號@RequestParam("orderSn"),用訂單號去查詢訂單內容,然後帶著訂單內容往支付的API
@GetMapping(value = "/payOrder", produces = "text/html")
public String payOrder(@RequestParam("orderSn") String orderSn) throws AlipayApiException {

	PayVo payVo = orderService.getOrderPay(orderSn);
	String pay = alipayTemplate.pay(payVo);
	System.out.println(pay);
	return pay;
}
  • AlipayTemplate.java
    • 這個是由第三方提供的,台灣的我查了一下接近的有綠界的站內付2.0,但是他屬於高級會員才有的服務,API也沒有對外公開。只能說台灣在支付這塊真的落後很多,大部分是要自己寫一個前端頁面給顧客填付款資訊,把資訊串進第三方金流提供的SDK,生成付款的訂單訊息,就沒那麼方便
    • 他這個Template都已經做好付款、退款、查詢等功能,只要填入自己支付的私鑰、公鑰、支付完要跳轉到的成功頁面,串上訂單號、金額、商品描述等等就能使用
    • 用戶點支付,就從訂單跳轉到專屬生成的支付頁面(SDK直接生成的一個html頁面),付完就回到成功頁面,串接真的是超簡單
    • 並且只要支付成功,會發一個異步通知給商戶(一樣提前設定好notify_url),收到通知驗證一下簽名(用商戶的key),就能從裡面取出支付的詳細內容,根據這個內容,在後台修改訂單狀態、保存交易的流水號等訊息,自此完成一個完整的支付

會員查詢訂單

他把會員的訂單歸到會員模組了

  • 整理新建模組要幹的事:

    • 引入thymeleaf、放頁面、放靜態檔案
    • 設定網域與網關轉發
    • 由於會員需要登入,設定登入攔截器、註冊WebMvcConfigurer
    • 登入狀態存在session,所以還要導入spring-session與data-redis
    • 其實應該用Spring Security的OA2做登入權限的統一管理會更好,否則這有些還要給feign調用放行特別寫規則還挺麻煩的
  • MemberWebController.java

@GetMapping(value = "/memberOrder.html")
public String memberOrderPage(@RequestParam(value = "pageNum", required = false, defaultValue = "0") Integer pageNum,
                              Model model) {

    //查出當前登錄用戶的所有訂單列表數據
    Map<String, Object> page = new HashMap<>();
    page.put("page", pageNum.toString());

    //遠程查詢訂單服務訂單數據
    R orderInfo = orderFeignService.listWithItem(page);
    System.out.println(JSON.toJSONString(orderInfo));
    model.addAttribute("orders", orderInfo);

    return "orderList";
}
  • 因為請求是從member.mall.com發出去的,由於也需要帶著會員登入的cookie所以也用FeignConfig做了請求頭複製
  • 查詢返回裡面包的是OrderEntity,因為member的thymeleaf渲染也要能訪問到這個bean,所以又要從order模組複製一份到member模組
  • 老師這樣用其實很坑,一是貪方便要顯示訂單中的商品項,把OrderEntity魔改多了一個List<OrderItemEntity>
// OrderEntity
@TableField(exist = false)
private List<OrderItemEntity> orderItemEntityList;
  • 與其改Entity,反正都要跨模組傳,還不如抽出一個TO更規範
    • 結果又會想把TO當成VO傳給前端,唉前後端不分離就是這樣討人厭,還不如都轉成JSON最統一

記踩坑

  • 當遠程調用傳入的參數不是單純的String或Int,而是有一個map或list,此時必然是帶有RequestBody請求體的@PostMapping

  • 所以被遠程調用的也必須是@PostMapping,也可以用@RequestMapping

  • thymeleaf返回字串而不是頁面的時候,看一下方法是不是@ResponseBody,當用了@ResponseBody@RestController就不會解析成html


上次修改於 2022-02-08