欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實(shí)現(xiàn)微信小程序支付功能

 更新時(shí)間:2025年04月11日 11:04:05   作者:全干程序員demo  
小程序支付功能已成為眾多應(yīng)用的核心需求之一,本文主要介紹了SpringBoot實(shí)現(xiàn)微信小程序支付功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、引言

在當(dāng)今數(shù)字化時(shí)代,小程序支付功能已成為眾多應(yīng)用的核心需求之一。通過小程序支付,用戶可以便捷地完成購物、充值等操作,極大地提升了用戶體驗(yàn)和業(yè)務(wù)效率。Spring Boot作為一款流行的Java開發(fā)框架,以其簡潔、高效的特點(diǎn),為實(shí)現(xiàn)小程序支付功能提供了強(qiáng)大的支持。本文將詳細(xì)介紹如何在Spring Boot項(xiàng)目中實(shí)現(xiàn)微信小程序支付功能,包括環(huán)境搭建、接口開發(fā)、支付流程實(shí)現(xiàn)以及支付結(jié)果通知處理等關(guān)鍵環(huán)節(jié)。

二、準(zhǔn)備工作

(一)微信支付商戶平臺配置

注冊微信支付商戶號:在微信支付商戶平臺(pay.weixin.qq.com/)注冊一個(gè)商戶號,獲取商戶號(mch_id)、API密鑰(key)等基本信息。
申請微信支付證書:在商戶平臺下載支付證書,用于簽名驗(yàn)證和數(shù)據(jù)加密。
配置支付參數(shù):在商戶平臺配置支付參數(shù),包括回調(diào)地址(notify_url)等。

(二)Spring Boot項(xiàng)目搭建

創(chuàng)建Spring Boot項(xiàng)目:通過Spring Initializr(start.spring.io/)快速創(chuàng)建一個(gè)Spring Boot項(xiàng)目,選擇所需的依賴,如Spring Web、Spring Boot DevTools等。

添加微信支付依賴:在pom.xml文件中添加微信支付相關(guān)依賴:

<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>1.0.0</version>
</dependency>

(三)配置文件設(shè)置

在application.properties或application.yml文件中配置微信支付相關(guān)參數(shù):

wx.pay.appId: your_app_id
wx.pay.mchId: your_mch_id
wx.pay.key: your_api_key
wx.pay.notifyUrl: your_notify_url

三、支付功能實(shí)現(xiàn)

(一)統(tǒng)一下單接口開發(fā)

創(chuàng)建支付服務(wù)類:創(chuàng)建WxPayService類,用于處理支付相關(guān)邏輯:

@Service
public class WxPayService {
    @Value("${wx.pay.appId}")
    private String appId;
    @Value("${wx.pay.mchId}")
    private String mchId;
    @Value("${wx.pay.key}")
    private String key;
    @Value("${wx.pay.notifyUrl}")
    private String notifyUrl;

    public Map<String, String> unifiedOrder(Map<String, String> params) {
        // 構(gòu)建統(tǒng)一下單請求參數(shù)
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("appid", appId);
        requestParams.put("mch_id", mchId);
        requestParams.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
        requestParams.put("body", params.get("body"));
        requestParams.put("out_trade_no", params.get("out_trade_no"));
        requestParams.put("total_fee", params.get("total_fee"));
        requestParams.put("spbill_create_ip", params.get("spbill_create_ip"));
        requestParams.put("notify_url", notifyUrl);
        requestParams.put("trade_type", "JSAPI");
        requestParams.put("openid", params.get("openid"));

        // 簽名
        String sign = WxPayUtil.createSign(requestParams, key);
        requestParams.put("sign", sign);

        // 發(fā)起統(tǒng)一下單請求
        String xml = WxPayUtil.mapToXml(requestParams);
        String result = HttpClientUtil.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
        Map<String, String> resultMap = WxPayUtil.xmlToMap(result);

        // 返回前端需要的支付參數(shù)
        Map<String, String> payParams = new HashMap<>();
        payParams.put("appId", appId);
        payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
        payParams.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
        payParams.put("package", "prepay_id=" + resultMap.get("prepay_id"));
        payParams.put("signType", "MD5");
        payParams.put("paySign", WxPayUtil.createSign(payParams, key));

        return payParams;
    }
}

創(chuàng)建支付控制器:創(chuàng)建WxPayController類,用于接收小程序的支付請求并調(diào)用統(tǒng)一下單接口:

@RestController
@RequestMapping("/wxpay")
public class WxPayController {
    @Autowired
    private WxPayService wxPayService;

    @PostMapping("/unifiedOrder")
    public Map<String, String> unifiedOrder(@RequestBody Map<String, String> params) {
        return wxPayService.unifiedOrder(params);
    }
}

(二)支付結(jié)果通知處理

創(chuàng)建支付結(jié)果通知處理接口:創(chuàng)建WxPayNotifyController類,用于接收微信支付結(jié)果通知:

@RestController
@RequestMapping("/wxpay")
public class WxPayNotifyController {
    @Autowired
    private WxPayService wxPayService;

    @PostMapping("/notify")
    public String notify(@RequestBody String notifyData) {
        return wxPayService.notify(notifyData);
    }
}

實(shí)現(xiàn)支付結(jié)果處理邏輯:在WxPayService中實(shí)現(xiàn)支付結(jié)果處理邏輯:

public String notify(String notifyData) {
    try {
        // 解析通知數(shù)據(jù)
        Map<String, String> notifyMap = WxPayUtil.xmlToMap(notifyData);
        // 驗(yàn)證簽名
        if (!WxPayUtil.verifySignature(notifyMap, key)) {
            return "FAIL";
        }

        // 處理支付結(jié)果
        if ("SUCCESS".equals(notifyMap.get("result_code"))) {
            // 更新訂單狀態(tài)等業(yè)務(wù)邏輯
            return "SUCCESS";
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "FAIL";
}

(三)前端調(diào)用支付接口

在小程序前端頁面中,調(diào)用后端接口獲取支付參數(shù),并調(diào)用微信支付API完成支付:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WeChat Pay Example</title>
</head>
<body>
    <h1>WeChat Pay Example</h1>
    <button id="payButton">Pay Now</button>
    <script>
        document.getElementById("payButton").addEventListener("click", function() {
            // 調(diào)用后端接口獲取支付參數(shù)
            fetch('/wxpay/unifiedOrder', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    body: 'Test Payment',
                    out_trade_no: '123456789',
                    total_fee: '1',
                    spbill_create_ip: '127.0.0.1',
                    openid: 'your_openid'
                })
            })
            .then(response => response.json())
            .then(payParams => {
                // 調(diào)用微信支付API
                WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        "appId": payParams.appId,
                        "timeStamp": payParams.timeStamp,
                        "nonceStr": payParams.nonceStr,
                        "package": payParams.package,
                        "signType": payParams.signType,
                        "paySign": payParams.paySign
                    },
                    function(res) {
                        if (res.err_msg == "get_brand_wcpay_request:ok") {
                            alert("支付成功");
                        } else {
                            alert("支付失敗");
                        }
                    }
                );
            });
        });
    </script>
</body>
</html>

四、測試與優(yōu)化

(一)測試支付流程

  • 模擬支付請求:在小程序中發(fā)起支付請求,檢查是否能夠正確調(diào)用后端接口并返回支付參數(shù)。
  • 驗(yàn)證支付結(jié)果通知:模擬微信支付結(jié)果通知,檢查后端是否能夠正確處理支付結(jié)果并更新訂單狀態(tài)。

(二)優(yōu)化與安全

  • 簽名驗(yàn)證:確保在支付結(jié)果通知處理中嚴(yán)格驗(yàn)證簽名,防止偽造通知。
  • 日志記錄:記錄支付請求和通知處理的日志,便于排查問題。
  • 異常處理:在支付流程中添加異常處理邏輯,確保系統(tǒng)在遇到錯(cuò)誤時(shí)能夠正常運(yùn)行。

五、總結(jié)

通過以上步驟,我們成功在Spring Boot項(xiàng)目中實(shí)現(xiàn)了微信小程序支付功能。從環(huán)境搭建到接口開發(fā),再到支付流程實(shí)現(xiàn)和支付結(jié)果通知處理,每一步都至關(guān)重要。在實(shí)際開發(fā)中,還需要根據(jù)具體業(yè)務(wù)需求進(jìn)行進(jìn)一步的優(yōu)化和調(diào)整 。希望本文能夠?yàn)殚_發(fā)者提供一個(gè)清晰的實(shí)現(xiàn)思路和參考代碼,幫助大家快速實(shí)現(xiàn)小程序支付功能。

六、參考代碼

以下是完整的參考代碼:

(一)WxPayService.java

@Service
public class WxPayService {
    @Value("${wx.pay.appId}")
    private String appId;
    @Value("${wx.pay.mchId}")
    private String mchId;
    @Value("${wx.pay.key}")
    private String key;
    @Value("${wx.pay.notifyUrl}")
    private String notifyUrl;

    public Map<String, String> unifiedOrder(Map<String, String> params) {
        Map<String, String> requestParams = new HashMap<>();
        requestParams.put("appid", appId);
        requestParams.put("mch_id", mchId);
        requestParams.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));
        requestParams.put("body", params.get("body"));
        requestParams.put("out_trade_no", params.get("out_trade_no"));
        requestParams.put("total_fee", params.get("total_fee"));
        requestParams.put("spbill_create_ip", params.get("spbill_create_ip"));
        requestParams.put("notify_url", notifyUrl);
        requestParams.put("trade_type", "JSAPI");
        requestParams.put("openid", params.get("openid"));

        String sign = WxPayUtil.createSign(requestParams, key);
        requestParams.put("sign", sign);

        String xml = WxPayUtil.mapToXml(requestParams);
        String result = HttpClientUtil.doPost("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
        Map<String, String> resultMap = WxPayUtil.xmlToMap(result);

        Map<String, String> payParams = new HashMap<>();
        payParams.put("appId", appId);
        payParams.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
        payParams.put("nonceStr", UUID.randomUUID().toString().replace("-", ""));
        payParams.put("package", "prepay_id=" + resultMap.get("prepay_id"));
        payParams.put("signType", "MD5");
        payParams.put("paySign", WxPayUtil.createSign(payParams, key));

        return payParams;
    }

    public String notify(String notifyData) {
        try {
            Map<String, String> notifyMap = WxPayUtil.xmlToMap(notifyData);
            if (!WxPayUtil.verifySignature(notifyMap, key)) {
                return "FAIL";
            }

            if ("SUCCESS".equals(notifyMap.get("result_code"))) {
                // Update order status and other business logic
                return "SUCCESS";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "FAIL";
    }
}

(二)WxPayController.java

@RestController
@RequestMapping("/wxpay")
public class WxPayController {
    @Autowired
    private WxPayService wxPayService;

    @PostMapping("/unifiedOrder")
    public Map<String, String> unifiedOrder(@RequestBody Map<String, String> params) {
        return wxPayService.unifiedOrder(params);
    }
}

(三)WxPayNotifyController.java

@RestController
@RequestMapping("/wxpay")
public class WxPayNotifyController {
    @Autowired
    private WxPayService wxPayService;

    @PostMapping("/notify")
    public String notify(@RequestBody String notifyData) {
        return wxPayService.notify(notifyData);
    }
}

通過以上代碼示例和詳細(xì)步驟,可以快速實(shí)現(xiàn)微信小程序支付功能。希望能夠幫助大家更好地理解和應(yīng)用Spring Boot實(shí)現(xiàn)小程序支付功能。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)微信小程序支付功能的文章就介紹到這了,更多相關(guān)SpringBoot小程序支付內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    Java實(shí)現(xiàn)基于token認(rèn)證的方法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)基于token認(rèn)證的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • SpringCloud Nacos集群搭建過程詳解

    SpringCloud Nacos集群搭建過程詳解

    Nacos集群不僅僅是服務(wù)注冊中心,還在微服務(wù)架構(gòu)中發(fā)揮著關(guān)鍵的角色,支持多種場景下的服務(wù)治理和協(xié)調(diào),本文介紹了如何在SpringCloud環(huán)境中搭建Nacos集群,為讀者提供了一份清晰而詳盡的指南,通過逐步演示每個(gè)關(guān)鍵步驟,讀者能夠輕松理解并操作整個(gè)搭建過程
    2024-02-02
  • Java全面解析XML格式串(JDOM解析)

    Java全面解析XML格式串(JDOM解析)

    下面小編就為大家?guī)硪黄狫ava全面解析XML格式串(JDOM解析)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • 詳解Java如何判斷ResultSet結(jié)果集是否為空

    詳解Java如何判斷ResultSet結(jié)果集是否為空

    ResultSet 表示 select 語句的查詢結(jié)果集。這篇文章主要為大家詳細(xì)介紹了Java如何判斷ResultSet結(jié)果集是否為空,感興趣的可以了解一下
    2023-02-02
  • Java多線程案例實(shí)戰(zhàn)之定時(shí)器的實(shí)現(xiàn)

    Java多線程案例實(shí)戰(zhàn)之定時(shí)器的實(shí)現(xiàn)

    在Java中可以使用多線程和定時(shí)器來實(shí)現(xiàn)定時(shí)任務(wù),下面這篇文章主要給大家介紹了關(guān)于Java多線程案例之定時(shí)器實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • java String類功能、原理與應(yīng)用案例【統(tǒng)計(jì)、判斷、轉(zhuǎn)換等】

    java String類功能、原理與應(yīng)用案例【統(tǒng)計(jì)、判斷、轉(zhuǎn)換等】

    這篇文章主要介紹了java String類功能、原理與應(yīng)用案例,結(jié)合實(shí)例形式詳細(xì)分析了java String類的基本功能、構(gòu)造方法,以及使用String類實(shí)現(xiàn)統(tǒng)計(jì)、判斷、轉(zhuǎn)換等功能相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • SpringBoot+Netty+WebSocket實(shí)現(xiàn)消息發(fā)送的示例代碼

    SpringBoot+Netty+WebSocket實(shí)現(xiàn)消息發(fā)送的示例代碼

    這篇文章主要介紹了SpringBoot+Netty+WebSocket實(shí)現(xiàn)消息發(fā)送的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java實(shí)現(xiàn)簡單局域網(wǎng)聊天室

    Java實(shí)現(xiàn)簡單局域網(wǎng)聊天室

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡單局域網(wǎng)聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • spring bean標(biāo)簽的primary屬性用法講解

    spring bean標(biāo)簽的primary屬性用法講解

    這篇文章主要介紹了spring bean標(biāo)簽的primary屬性用法講解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java的設(shè)計(jì)模式之代理模式使用詳解

    Java的設(shè)計(jì)模式之代理模式使用詳解

    這篇文章主要介紹了Java的設(shè)計(jì)模式之代理模式使用詳解,代理模式是23種設(shè)計(jì)模式之一,它關(guān)心的主要是過程,而不是結(jié)果,代理模式主要提供了對目標(biāo)對象的間接訪問方式,即通過代理對象來訪問目標(biāo)對象,需要的朋友可以參考下
    2024-01-01

最新評論