電商中的訂單支付(內網穿透)

支付頁面

在這里插入圖片描述

接口文檔

在這里插入圖片描述
在這里插入圖片描述

@Operation(summary="獲取訂單信息")
@GetMapping("auth/{orderId}")
public Reuslt<OrderInfo> getOrderInfo(@Parameter(name="orderId",description="訂單id",required=true) @PathVaariable Long orderId){OrderInfo orderInfo = orderInfoService.getOrderInfo(orderId);return Reuslt.build(orderInfo,ResultCode.SUCCESS);
}
@Override
public OrderInfo getOrderInfo(Long orderId){return orderInfoMapper.getById(orderId);
}
//mapper
OrderInfo getById(Long orderId);
<select id="getById"resultType="com.xxx.OrderInfo" >select *from order_infowhere id=#{orderId}</select>

不經過購物車,直接購買

@Operation(summary="立即購買")
@GetMapping("auth/buy/{skuId}")
public Result buy(@PathVariable Long skuId){TradeVo tradeVo = orderInfoService.buy(skuId);return Result.build(tredeVo,ResultCodeEnum.SUCCESS);
}
@Override
public TradeVo buy(Long skuId){List<OrderItem> orderItemList = new ArrayList<>();ProductSku productSku = productFeignClient.getBySkuId(skuId);OrderIntem orderItem = new OrderItem();orderItem.setSkuId(skuId);orderItem.setSkuName(productSku.getSkuName());orderItem.setSkuNum(1);orderItem.setSkuPrice(productSku.getSalePrice());orderItem.setThumbImg(productSku.getThumbImg());orderItemList.add(orderItem);TradeVo tradeVo = new TradeVo();trade.setOrderItemList(orderItemList);trade.setTotalAmount(productSku.getSalePrice());return tradeVo;
}

查詢訂單
在這里插入圖片描述

@Operation(summary="獲取訂單分頁列表")
@GetMapping("auth/{page}/{limit}")
public Result<PageInfo<OrderInfo>> list(@Parameter(name="page",description="當前頁碼",required=true)@PathVariable Integer page,@Parameter(name="limit",description="每頁記錄數",required=true)@PathVariable Integer limit,@Parameter(name="orderStatus",description="訂單狀態",required=false)@RequestParam(required=false,defaultValue="") Integer orderStatus){PageInfo<OrderInfo> pageInfo = orderInfoService.findUserPage(page,limit,orderStatus);return Result.build(pageInfo,ResultCodeEnum.SUCCESS);
}
@Override
public PageInfo<OrderInfo> findOrderPage(Integer page,Integer limit,Integer orderStatus){PageHelper.startPage(page,limit);//查詢訂單信息Long userId = AuthContextUtil.getUserInfo().getId();List<OrderItem> orderInfoList = orderInfoMapper.findUserPage(userId,orderStatus);//查詢訂單里所有的訂單項orderInfoList.forEach(orderInfo -> {//訂單id查詢訂單里面的訂單項List<OrderItem> orderItemList = orderItemMapper.findByOrderId(orderInfo.getId());orderInfo.setOrderItemList(orderItemList);});return new PageInfo<>(orderInfoList);
}

在這里插入圖片描述

在這里插入圖片描述

===================================================================================

支付寶支付

在這里插入圖片描述

在這里插入圖片描述
通過營業執照進行開通

獲取的參數
在這里插入圖片描述

在這里插入圖片描述

①、創建模塊service-pay

配置文件、啟動類……

spring:profiles:active: devserver:port:
spring:application:name:cloud:nacos:discovery:server-addr: localhost:8848datasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl:username:password:data:redis:host: localhostport: 6379
mybatis:config-localtion: classpath:mybatis-config.xmlmapper-location: classpath:mapper/*/*.xml

②、保存支付記錄

public interface PaymetInfoService{PaymentInfo savePaymentInfo(String orderNo);
}
@Service
public class PaymentInfoService implements PaymentInfoService{@Autowiredprivate PaymentInfoMapper paymentInfoMapper; @Overridepublic PaymentInfo savePaymentInfo(String orderNo){PaymentInfo paymentInfo = paymentInfoMapper.getByOrderNo(orderNo);if(paymentInfo==null){//如果支付記錄不存在,則遠程調用訂單信息OrderInfo orderInfo = orderFeignClient.getOrderInfoByOrderNo(orderNo).getData();paymentInfo = new PaymentInfo();paymentInfo.setUserId(orderInfo.getUserId());paymentInfo.setPayType(orderInfo.getPayType());String content = "";for(OrderItem item:orderInfo.getOrderItemList()){content += item.getSkuName() + "";}paymentInfo.setContent(content);paymentInfo.setAmount(orderInfo.getTotalAmount());paymentInfo.setOrderNo(orderNo);paymentInfoMapper.save(paymentInfo);}return paymentInfo;}
}
@Mapper
public interface PaymentInfoMapper{PaymentInfo getByOrderNo(String orderNo);void save(PaymentInfo paymentInfo);
}
<sql id="columns">id,user_id,order_no,pay_type,out_trade_no,amount,content,payment_status,callback_time,callback_content
</sql><select id="getByOrderNo" resultMap="paymentInfoMap">select <include refid="colums"></include>from payment_infowhere order_no = #{orderNo}
</select><insert id="save" useGeneratedKeys="true" keyProperty="id">insert into payment_info(id,user_id,order_no,pay_type,out_tread_no,amount,coutent,payment_status,)
</insert>

在這里插入圖片描述

在這里插入圖片描述

③、支付接口

Ⅰ、service-pay模塊中添加alipay-sdk依賴

Ⅱ、application-alipay.yml文件,添加配置
在這里插入圖片描述
Ⅲ、application-dev.yml配置文件需要引入application-alipay.yml

spring:config:import: application-alipay.yml

Ⅳ、讀取配置文件

@Data
@Configuration(prefix="spzx.alipay")
public class AlipayProperties{//屬性名必需和配置文件中的保持一致private String alipayUrl;private String appPrivateKey;public String alipayPublicKey;private String appId;public String returnPaymetUrl;public String notifyPaymentUrl;public final static String format="json";public final static String charset="utf-8";public final static String sign_type="RAS2";
}

Ⅴ、啟動類添加注解@EnableConfigurationProperties(value={AlipayProperties.class})

④、配置發送請求的核心對象AlipayClient

@Configuration
public class AlipayConfiguration{@Autowiredprivate AlipayProperties alipayProperties;@Beanpublic AlipayClient alipayClient(){AlipayClient alipayClient = new DefaultAlipayClient(alipayProperties.getAlipayUrl(),alipayProperties.getAppPrivateKey(),alipayProperties.format,alipayProperties.charset,alipayProperties.getAlipayPublicKey(),alipayProperties.sign_type);return alipayClient;}
}

⑤、返回支付寶支付頁面

@Controller
@RequestMapping()
public class AlipayController{@Autowiredprivate AlipayService alipayService;@Operation(summary="支付寶下單")@GetMapping("submitAlipay/{orderNo}")public Result<String> submitAliPay(@Parameter(name="orderNo",description="訂單號",required=true),@PathVariable(value="orderNo") String orderNo){String form = aliapyService.submitAlipay(orderNo);//返回表單頁面return Result.build(form,ResultCodeEnum.SUCCESS);}
}
@Override
public String submitAlipay(String orderNo){//保存支付記錄PaymentInfo payementInfo = paymentInfoService.savePaymentInfo(orderNo);//調用支付寶服務接口封裝參數AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//同步回調alipayRequest.setReturnUrl(alipayProperties.getReturnPaymentUrl());//異步回調alipayRequest.setNotifyUrl(alipayProperties.getNotifyPaymentUrl());//準備請求參數HashMap<String,Object> map = new HashMap<>();map.put("out_trade_no",paymentInfo.getOrderNo());map.put("product_code","QUICK_WAP_WAY");map.put("total_amount",paymentInfo.getAmount());//map.put("total_amount",new BigDecimal("0.01")); 為了便于測試map.put("subject",paymentInfo.getContent());alipayRequest.setBizContent(JSON.toJSONString(map));try{//發送請求AlipayTradeWapPayResponse response = alipayClient.pageExecute(alipayRequest);if(response.isSuccess()){log.info("調用成功");String form = response.getBody();//返回支付頁面return form;}else{log.info("調用失敗");throw new GuiguException(ResultCodeEnum.DATA_ERROR);}}catch(AlipayApiException e){throw new RuntimeException(e);}}

在這里插入圖片描述

⑥、完成支付

  • 內網穿透,方便用來開發測試

在這里插入圖片描述

  • 支付成功之后到達的頁面:修改自定義的頁面
  • 本地的接口路徑:修改為內網穿透綁定到后端網關接口贈送的域名地址
    在這里插入圖片描述

在這里插入圖片描述

@Operation(summary="支付寶異步回調")
@ReqeustMapping("callback/notify")//該路徑和配置文件中的notify_payment_url
@ResponseBody
public String alipayNotify(@RequestParam Map<String,String> paramMap,HttpServletRequest request){log.info("AlipayController...alipayNotify方法執行了");boolean signVerified = false;//調用SDK驗證簽名(驗證是否是支付寶傳遞過來)try{signVerified = AlipaySignature.rsaCheckVl(paramMap,alipayProperties.getAlipayPublicKey(),AlipayProperties.charset,AlipayProperties.sign_type);}catch(AlipayApiException e){e.printStackTrace();}//交易狀態String trade_status = paramMap.get("trade_status");if(signVerified){//進行二次校驗if("TRADE_SUCCESS".equals(trade_status)||"TRADE_FINISHED".equals(trade_status)){//正常的支付成功,更新交易記錄狀態paymentInfoService.updatePaymentStatus(paraMap,2);return "success";}}else{//驗簽失敗,記錄異常日志return "failture";}
}
//支付狀態的更新
@Override
public void updatePaymentStatus(Map<String,String> map){//根據訂單編號查詢支付記錄信息PaymentInfo paymentInfo = paymentInfoMapper.getByOrderNo(map.get("out_trade_no"));//如果支付記錄已經完成,不需要更新if(paymentInfo.getPaymentStatus()==1){return;}//沒有完成才更新paymentInfo.setPaymentStatus(1);paymentInfo.setOutTradeNo(map.get("trade_no"));paymentInfo.setCallbackTime(new Date());paymentInfo.set.CallbackContent(JSON.toJSONString(map));paymentInfoMapper.updatePaymentInfo(paymentInfo);//遠程調用,更新訂單模塊(根據訂單編號修改)orderFeignClient.updateOorderStatus(paymentInfo.getOrderNo());//更新sku商品銷售
}

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

配置內網穿透

  • 本質上就是因為無法直接調用本地服務,所以通過內網穿透便于第三方服務通過域名來調用本地服務
  • ngrok工具:https://ngrok.cc/login/register 注冊用戶
  • 完成實名認證
  • 開通隧道管理
  • 綁定本地服務開發者的service-gateway網關模塊,獲取贈送的域名
  • 復制隧道id,下載客戶端工具windows_amd64zip

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901426.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901426.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901426.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL表的使用(4)

首先回顧一下之前所學的增刪查改&#xff0c;這些覆蓋了平時使用的80% 我們上節課中學習到了MySQL的約束 其中Primary key 是主鍵約束&#xff0c;我們今天要學習的是外鍵約束 插入一個表 外鍵約束 父表 子表 這條記錄中classid為5時候&#xff0c;不能插入&#xff1b; 刪除…

Kotlin作用域函數

在 Kotlin 中&#xff0c;.apply 是一個 作用域函數&#xff08;Scope Function&#xff09;&#xff0c;它允許你在一個對象的上下文中執行代碼塊&#xff0c;并返回該對象本身。它的設計目的是為了 對象初始化 或 鏈式調用 時保持代碼的簡潔性和可讀性。 // 不使用 apply va…

C#集合List<T>與HashSet<T>的區別

在C#中&#xff0c;List和HashSet都是用于存儲元素的集合&#xff0c;但它們在內部實現、用途、性能特性以及使用場景上存在一些關鍵區別。 內部實現 List&#xff1a;基于數組實現的&#xff0c;可以包含重復的元素&#xff0c;并且元素是按照添加的順序存儲的。 HashSet&…

Python 實現的運籌優化系統數學建模詳解(最大最小化模型)

一、引言 在數學建模的實際應用里&#xff0c;最大最小化模型是一種極為關鍵的優化模型。它的核心目標是找出一組決策變量&#xff0c;讓多個目標函數值里的最大值盡可能小。該模型在諸多領域&#xff0c;如資源分配、選址規劃等&#xff0c;都有廣泛的應用。本文將深入剖析最大…

數據庫的種類及常見類型

一&#xff0c;數據庫的種類 最常見的數據庫類型分為兩種&#xff0c;關系型數據庫和非關系型數據庫。 二&#xff0c;關系型數據庫介紹 生產環境主流的關系型數據庫有 Oracle、SQL Server、MySQL/MariaDB等。 關系型數據庫在存儲數據時實際就是采用的一張二維表&#xff0…

PE文件(十五)綁定導入表

我們在分析Windows自帶的一些程序時&#xff0c;常常發現有的程序&#xff0c;如notepad&#xff0c;他的IAT表在文件加載內存前已經完成綁定&#xff0c;存儲了函數的地址。這樣做可以使得程序是無需修改IAT表而直接啟動&#xff0c;這時程序啟動速度變快。但這種方式只適用于…

計算機網絡分層模型:架構與原理

前言 計算機網絡通過不同的層次結構來實現通信和數據傳輸&#xff0c;這種分層設計不僅使得網絡更加模塊化和靈活&#xff0c;也使得不同類型的通信能夠順利進行。在網絡協議和通信體系中&#xff0c;最廣為人知的分層模型有 OSI模型 和 TCP/IP模型。這兩種模型分別定義了計算…

Ollama模型顯存管理機制解析與Flask部署方案對比

一、Ollama顯存釋放機制 Ollama部署模型后&#xff0c;顯存占用分為兩種情況&#xff1a; 首次調用后短暫閑置&#xff08;約5分鐘內&#xff09;&#xff1a; ? 釋放KV Cache等中間計算數據&#xff08;約回收30%-50%顯存&#xff09;。 ? 模型權重仍保留在顯存中&#xf…

KWDB創作者計劃—KWDB技術重構:重新定義數據與知識的神經符號革命

引言&#xff1a;數據洪流中的范式危機 在AI算力突破千卡集群、大模型參數量級邁向萬億的時代&#xff0c;傳統數據庫系統正面臨前所未有的范式危機。當GPT-4展現出跨領域推理能力&#xff0c;AlphaFold3突破蛋白質預測精度時&#xff0c;數據存儲系統卻仍在沿用基于關系代數的…

Unified Modeling Language,統一建模語言

UML&#xff08;Unified Modeling Language&#xff0c;統一建模語言&#xff09;是一種標準化的圖形化建模語言&#xff0c;用于可視化、規范和文檔化軟件系統的設計。UML 提供了一套通用的符號和規則&#xff0c;幫助開發者、架構師和團隊成員更好地理解和溝通軟件系統的結構…

IO模式精講總結

一、IO模型概述 Java中的IO模型主要分為BIO&#xff08;同步阻塞IO&#xff09;、NIO&#xff08;同步非阻塞IO&#xff09;和AIO&#xff08;異步非阻塞IO&#xff09;三種。它們分別適用于不同的業務場景&#xff0c;理解其核心機制對高性能網絡編程至關重要。 二、BIO&…

使用pybind11開發c++擴展模塊輸出到控制臺的中文信息顯示亂碼的問題

使用pybind11開發供Python項目使用的C++擴展模塊時,如果在擴展模塊的C++代碼中向控制臺輸出的信息中包含中文,python程序的控制臺很容易出現亂碼。以如下C++擴展框架代碼為例(這是對上一篇文章簡明使用pybind11開發pythonc+擴展模塊教程-CSDN博客中的C++擴展框架代碼進行少量…

通過jstack分析線程死鎖場景

死鎖的四個必要條件&#xff1a;互斥、持有并等待、不可搶占、循環等待。 死鎖場景是兩個線程各自持有某個鎖&#xff0c;并試圖獲取對方持有的鎖&#xff0c;導致互相等待。 創建死鎖示例代碼 package io.renren.controller;import org.springframework.web.bind.annotation…

PyTorch梯度:深度學習的引擎與實戰解析

一、梯度&#xff1a;深度學習中的指南針 1.1 什么是梯度&#xff1f; 梯度是函數在某一點變化率最大的方向及其大小&#xff0c;就像爬山時最陡峭的上坡方向。在深度學習中&#xff0c;梯度告訴我們如何調整神經網絡參數&#xff0c;使損失函數最小化。 1.2 梯度的重要性 …

【Python爬蟲】詳細入門指南

目錄 一、簡單介紹 二、詳細工作流程以及組成部分 三、 簡單案例實現 一、簡單介紹 在當今數字化信息飛速發展的時代&#xff0c;數據的獲取與分析變得愈發重要&#xff0c;而網絡爬蟲技術作為一種能夠從互聯網海量信息中自動抓取所需數據的有效手段&#xff0c;正逐漸走入…

Golang|Channel 相關用法理解

文章目錄 用 channel 作為并發小容器channel 的遍歷channel 導致的死鎖問題用 channel 傳遞信號用 channel 并行處理文件用channel 限制接口的并發請求量用 channel 限制協程的總數量 用 channel 作為并發小容器 注意這里的 ok 如果為 false&#xff0c;表示此時不僅channel為空…

Windows單機模擬MySQL主從復制

這里寫自定義目錄標題 下載MySQL ZIP壓縮包安裝主庫1、創建配置文件2、安裝服務3、初始化數據庫4、啟動服務5、配置主庫 安裝從庫1、配置ini文件2、安裝服務3、初始化數據庫4、啟動服務5、配置從庫6、驗證從庫狀態 操作主庫驗證 下載MySQL ZIP壓縮包 https://dev.mysql.com/do…

OSPF路由引入

一、基本概念與作用 1.OSPF路由引入指通過自治系統邊界路由器&#xff08;ASBR&#xff09;將外部路由&#xff08;如BGP、RIP、靜態路由或其他OSPF進程的路由&#xff09;注入當前OSPF域&#xff0c;實現跨協議或跨區域的網絡互通?。 其核心作用包括&#xff1a; ?擴展網…

弱口令爆破

1.簡單介紹 弱口令是指一些簡單易猜的密碼&#xff0c;可通過社工方式和一些爆破工具進行破解&#xff0c;以下介紹一款爆破工具的用法。burpsuite簡稱BP&#xff0c;一款可以利用字典破解賬戶密碼的工具。 2.部署網站 可以使用PHPstudy的Apache服務&#xff0c;也可以使用I…

Vue3+Vite前端項目部署后部分圖片資源無法獲取、動態路徑圖片資源報404錯誤的原因及解決方案

目錄 Vue3vite前端項目部署后部分圖片資源無法獲取、動態路徑圖片資源報404錯誤的原因及解決方案 一、情景介紹 1、問題出現的場景 2、無法加載的圖片寫法 二、反向代理原理簡介 三、造成該現象的原因 四、解決方案 1、放棄動態渲染 2、在頁面掛載的時候引入圖片資源 …