最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot實現(xiàn)微信支付接口調(diào)用及回調(diào)函數(shù)(商戶參數(shù)獲取)

 更新時間:2024年11月21日 11:39:50   作者:guicai_guojia  
本文詳細介紹了使用SpringBoot實現(xiàn)微信支付接口調(diào)用及回調(diào)函數(shù)的步驟,提供了代碼實現(xiàn)的具體步驟和工具類的創(chuàng)建,感興趣的朋友跟隨小編一起看看吧

 一、具體業(yè)務流程

1. 用戶下單

- 前端操作:
  - 用戶在應用中選擇商品、填寫訂單信息(如地址、聯(lián)系方式等),并點擊“下單”按鈕。
  - 前端將訂單信息(商品ID、數(shù)量、價格等)發(fā)送到后端。

- 后端處理:
  - 接收到訂單請求后,生成唯一的訂單號(`out_trade_no`)。
  - 將訂單信息存儲到數(shù)據(jù)庫中,設置訂單狀態(tài)為“待支付”。

 2. 后端創(chuàng)建訂單

- 構(gòu)建請求參數(shù):
  - 使用商戶號、應用ID、隨機字符串、訂單描述、商戶訂單號、金額(單位:分)、IP 地址等構(gòu)建 XML 格式的請求數(shù)據(jù)。

- 發(fā)送請求:
  - 使用 HTTP POST 方法將請求數(shù)據(jù)發(fā)送到微信的統(tǒng)一下單 API(`https://api.mch.weixin.qq.com/pay/unifiedorder`)。
- 處理響應:
  - 接收微信返回的響應數(shù)據(jù)(XML 格式),解析響應內(nèi)容。
  - 檢查返回的 `return_code` 和 `result_code`,確保請求成功。
  - 獲取 `prepay_id`,并根據(jù)它生成支付簽名等信息。

 3. 返回支付信息

- 返回給前端:
  - 將 `prepay_id` 和其他必要參數(shù)(如時間戳、隨機字符串、簽名等)封裝成 JSON 響應返回給前端。
- 前端支付:
  - 前端使用微信支付 SDK,調(diào)用支付接口啟動支付流程。
  - 用戶確認支付后,微信客戶端處理支付。

 4. 用戶確認支付

- 用戶行為:
  - 用戶在微信中查看支付信息,確認后進行支付。

- 支付結(jié)果:
  - 微信處理支付請求,完成后將結(jié)果異步通知你的服務器。

 5. 微信支付回調(diào)

- 回調(diào) URL 配置:
  - 在微信商戶平臺配置你的回調(diào) URL(如 `https://yourdomain.com/wechat/notify`)。

- 處理回調(diào)請求:
  - 接收到來自微信的 POST 請求,讀取請求體中的 XML 數(shù)據(jù)。

- 驗證簽名:
  - 提取回調(diào)數(shù)據(jù)中的簽名字段,使用相同的參數(shù)生成新的簽名,與返回的簽名進行比較,確保數(shù)據(jù)的完整性和有效性。

- 更新訂單狀態(tài):
  - 根據(jù)回調(diào)數(shù)據(jù)中的 `result_code` 更新數(shù)據(jù)庫中的訂單狀態(tài)。如果支付成功,修改訂單狀態(tài)為“已支付”,并進行相應的業(yè)務處理(如發(fā)貨)。
- 返回處理結(jié)果:
  - 向微信返回處理結(jié)果,通常是 `<xml><return_code>SUCCESS</return_code></xml>`。

 6. 返回處理結(jié)果

- 響應微信:
  - 確保響應格式正確,避免微信因無法解析而重發(fā)通知。

7. 訂單狀態(tài)查詢(可選)

- 查詢訂單狀態(tài):
  - 在用戶支付后的一段時間內(nèi),可以調(diào)用微信的訂單查詢 API(`https://api.mch.weixin.qq.com/pay/orderquery`)來確認訂單的狀態(tài)。
  
- 處理結(jié)果:
  - 根據(jù)查詢結(jié)果更新本地訂單狀態(tài),確保數(shù)據(jù)一致性。

 8. 訂單完成

- 后續(xù)處理:
  - 一旦訂單支付成功并發(fā)貨,可以根據(jù)業(yè)務需求進行后續(xù)操作,例如發(fā)送確認郵件、更新庫存等。

二、代碼具體實現(xiàn)

1. 商戶參數(shù)配置

application.properties 中配置微信支付的相關參數(shù):

# 微信支付配置
wechat.pay.appId=your_app_id
wechat.pay.mchId=your_mch_id
wechat.pay.apiKey=your_api_key
wechat.pay.notifyUrl=https://yourdomain.com/wechat/notify

2. 創(chuàng)建 Spring Boot 項目

確保你的項目引入了必要的依賴。在 pom.xml 中添加以下內(nèi)容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>
<dependency>
    <groupId>com.thoughtworks.xstream</groupId>
    <artifactId>xstream</artifactId>
    <version>1.4.18</version>
</dependency>

3. 創(chuàng)建微信支付服務類

創(chuàng)建一個服務類 WeChatPayService,用于處理訂單的創(chuàng)建和簽名等操作。

import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class WeChatPayService {
    @Value("${wechat.pay.appId}")
    private String appId;
    @Value("${wechat.pay.mchId}")
    private String mchId;
    @Value("${wechat.pay.apiKey}")
    private String apiKey;
    @Value("${wechat.pay.notifyUrl}")
    private String notifyUrl;
    private static final String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    public String createOrder(String orderNo, double amount) throws Exception {
        String nonceStr = String.valueOf(System.currentTimeMillis());
        String xmlData = "<xml>"
                + "<appid>" + appId + "</appid>"
                + "<mch_id>" + mchId + "</mch_id>"
                + "<nonce_str>" + nonceStr + "</nonce_str>"
                + "<body>Product Description</body>"
                + "<out_trade_no>" + orderNo + "</out_trade_no>"
                + "<total_fee>" + (int) (amount * 100) + "</total_fee>"
                + "<spbill_create_ip>127.0.0.1</spbill_create_ip>"
                + "<notify_url>" + notifyUrl + "</notify_url>"
                + "<trade_type>APP</trade_type>"
                + "</xml>";
        // 生成簽名并添加到請求數(shù)據(jù)
        String sign = WeChatPayUtil.generateSign(xmlData, apiKey);
        xmlData = xmlData.replace("</xml>", "<sign>" + sign + "</sign></xml>");
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost post = new HttpPost(UNIFIED_ORDER_URL);
            post.setEntity(new StringEntity(xmlData, "UTF-8"));
            post.setHeader("Content-Type", "text/xml");
            String response = EntityUtils.toString(client.execute(post).getEntity(), "UTF-8");
            return response; // 解析并返回需要的信息
        }
    }
}

4. 創(chuàng)建微信支付控制器

創(chuàng)建一個控制器 WeChatPayController,處理用戶的下單請求(@PostMapping("/createOrder"))和回調(diào)@PostMapping("/notify")。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/wechat")
public class WeChatPayController {
    @Autowired
    private WeChatPayService weChatPayService;
    @PostMapping("/createOrder")
    public String createOrder(@RequestParam String orderNo, @RequestParam double amount) {
        try {
            return weChatPayService.createOrder(orderNo, amount);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error creating order";
        }
    }
    @PostMapping("/notify")
    public String handleCallback(HttpServletRequest request) {
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        String xmlData = sb.toString();
        Map<String, String> data = WeChatPayUtil.parseXml(xmlData); // 解析 XML 數(shù)據(jù)
        // 驗證簽名
        String sign = data.get("sign");
        if (WeChatPayUtil.generateSign(xmlData, apiKey).equals(sign)) {
            // 處理業(yè)務邏輯,例如更新訂單狀態(tài)
            String resultCode = data.get("result_code");
            if ("SUCCESS".equals(resultCode)) {
                String orderNo = data.get("out_trade_no");
                // 更新訂單狀態(tài)為已支付
                // updateOrderStatus(orderNo, "PAID");
            }
            return "<xml><return_code>SUCCESS</return_code></xml>";
        } else {
            return "<xml><return_code>FAIL</return_code></xml>";
        }
    }
}

5. 簽名和 XML 處理工具類

創(chuàng)建一個工具類 WeChatPayUtil,負責簽名和 XML 解析。

import com.thoughtworks.xstream.XStream;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class WeChatPayUtil {
    public static String generateSign(String xmlData, String apiKey) {
        // 將 XML 轉(zhuǎn)換為 Map
        Map<String, String> data = parseXml(xmlData);
        TreeMap<String, String> sortedMap = new TreeMap<>(data);
        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
            if (!entry.getKey().equals("sign") && entry.getValue() != null) {
                stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
            }
        }
        stringBuilder.append("key=").append(apiKey);
        return md5(stringBuilder.toString()).toUpperCase();
    }
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes());
            StringBuilder hexString = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) hexString.append('0');
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static Map<String, String> parseXml(String xml) {
        // 使用 XStream 解析 XML
        XStream xStream = new XStream();
        xStream.alias("xml", HashMap.class);
        return (Map<String, String>) xStream.fromXML(xml);
    }
}

三、參數(shù)配置及獲取

一、回調(diào)函數(shù)的配置步驟

  • 在微信商戶平臺配置回調(diào)地址

    • 登錄微信商戶平臺。
    • 找到“賬戶設置”或“API安全”選項。
    • 在“支付結(jié)果通知 URL”中填寫你的回調(diào)地址(如 https://yourdomain.com/wechat/notify)。

二、商戶參數(shù)獲取

商戶參數(shù)主要包括微信支付的相關信息,這些信息可以在微信商戶平臺上獲取。

商戶參數(shù)

  • appId: 公眾賬號ID,由微信開放平臺或微信支付商戶平臺提供。
  • mchId: 商戶號,由微信支付商戶平臺提供。
  • apiKey: API 密鑰,在微信支付商戶平臺設置,用于簽名請求。
  • notifyUrl: 支付結(jié)果通知地址,即微信支付成功后,微信服務器將異步通知該地址。

到此這篇關于SpringBoot實現(xiàn)微信支付接口調(diào)用及回調(diào)函數(shù)(商戶參數(shù)獲取)的文章就介紹到這了,更多相關SpringBoot微信支付接口調(diào)用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JAVA判斷兩個時間之間的差

    JAVA判斷兩個時間之間的差

    經(jīng)常會遇到需要判斷兩個時間之間的差異的情況,本文主要介紹了JAVA計算兩個時間之間的差,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Java遞歸以及根據(jù)節(jié)點取子集合方式

    Java遞歸以及根據(jù)節(jié)點取子集合方式

    文章介紹了Java中遞歸的使用方法,包括如何根據(jù)節(jié)點構(gòu)建樹形結(jié)構(gòu)以及如何反向遞歸獲取所有子節(jié)點,提供了遞歸方法的參數(shù)解釋和示例代碼,希望對大家有所幫助
    2024-12-12
  • 兩種實現(xiàn)Java類隔離加載的方法

    兩種實現(xiàn)Java類隔離加載的方法

    這篇文章主要介紹了兩種實現(xiàn)Java類隔離加載的方法,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-02-02
  • 使用Java操作TensorFlow的方法

    使用Java操作TensorFlow的方法

    TensorFlow是一個功能強大且廣泛使用的框架,它不斷得到改進,并最近被引入新語言包括Java和JavaScript,這篇文章主要介紹了如何使用Java操作TensorFlow,需要的朋友可以參考下
    2023-05-05
  • idea web項目沒有小藍點的的兩種解決方法

    idea web項目沒有小藍點的的兩種解決方法

    本文主要介紹了idea web項目沒有小藍點的的兩種解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 關于SpringBoot的自動裝配原理詳解

    關于SpringBoot的自動裝配原理詳解

    這篇文章主要介紹了關于SpringBoot的自動裝配原理詳解,Spring?Boot自動裝配原理是指Spring?Boot在啟動時自動掃描項目中的依賴關系,根據(jù)依賴關系自動配置相應的Bean,從而簡化了Spring應用的配置過程,需要的朋友可以參考下
    2023-07-07
  • Spring事務管理@Transactional注解最佳實踐

    Spring事務管理@Transactional注解最佳實踐

    本文詳細介紹了Spring框架的核心特性,包括IOC容器、AOP面向切面編程和事務管理,重點解析了Spring事務的傳播行為和隔離級別,以及SpringBoot的自動配置原理,本文給大家講解的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • 在SpringBoot中更改默認端口的方法總結(jié)

    在SpringBoot中更改默認端口的方法總結(jié)

    在本文中,小編將帶大家學習如何在 Spring Boot 中更改默認端口,默認情況下,嵌入式 Web 服務器使用 8080端口來啟動 Spring 引導應用程序,有幾種方法可以更改該端口,文中介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Java實現(xiàn)短信發(fā)送驗證碼功能

    Java實現(xiàn)短信發(fā)送驗證碼功能

    這篇文章主要介紹了Java實現(xiàn)短信發(fā)送驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2018-10-10
  • 一文搞懂Spring中的注解與反射

    一文搞懂Spring中的注解與反射

    這篇文章主要為大家介紹了Spring中的注解與反射的原理與實現(xiàn),文中的示例代碼講解詳細,對我們了解Spring有一定的幫助,需要的可以參考一下
    2022-06-06

最新評論

湟中县| 沂水县| 昌吉市| 正安县| 原阳县| 达州市| 宽城| 新源县| 泗水县| 琼海市| 香港 | 酉阳| 怀安县| 清水河县| 台北县| 长乐市| 保康县| 吉安市| 离岛区| 东宁县| 五台县| 鹤庆县| 峡江县| 黑河市| 南雄市| 乌兰浩特市| 丹凤县| 洞头县| 鲁甸县| 南雄市| 陆良县| 阳城县| 宜阳县| 尼玛县| 宁晋县| 南华县| 罗城| 宝山区| 当涂县| 汝南县| 汉源县|