搜尋
首頁Javajava教程小程式後端用什麼寫
小程式後端用什麼寫May 14, 2019 pm 02:00 PM
java

這裡本篇文章使用Java進行小程式後端編寫,由於公司前段時間要做小程式支付,所以這裡把自己寫的小程式後端支付controller記錄下來,文檔參考微信支付官方文檔,地址: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1

推薦課程:Java教學

小程式後端用什麼寫

廢話不多說,直接上程式碼:

#PayController

@Api(tags = "支付模块")
@RestController
@RequestMapping("")
public class PayController {

    @ApiOperation(value = "请求支付接口")
    @RequestMapping(value = "/wxPay", method = RequestMethod.POST)
    public JSONObject wxPay(HttpServletRequest request) {        try {            //生成的随机字符串
            String nonce_str = getRandomStringByLength(32);            //商品名称
            String body = "测试商品名称";            //获取客户端的ip地址
            String spbill_create_ip = getIpAddr(request);            //组装参数,用户生成统一下单接口的签名
            Map<string> packageParams = new HashMap();
            packageParams.put("appid", WechatConfig.appid);
            packageParams.put("mch_id", WechatConfig.mch_id);
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", payOrderId + "");//商户订单号,自己的订单ID
            packageParams.put("total_fee", 100 + "");//支付金额,这边需要转成字符串类型,否则后面的签名会失败
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("notify_url", WechatConfig.notify_url);//支付成功后的回调地址
            packageParams.put("trade_type", WechatConfig.TRADETYPE);//支付方式
            packageParams.put("openid", openId + "");//用户的openID,自己获取

            String prestr = PayUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串

            //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
            String mysign = PayUtil.sign(prestr, WechatConfig.key, "utf-8").toUpperCase();            //拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
            String xml = "<xml>" + "<appid>" + WechatConfig.appid + "</appid>"
                    + ""
                    + "<mch_id>" + WechatConfig.mch_id + "</mch_id>"
                    + "<nonce_str>" + nonce_str + "</nonce_str>"
                    + "<notify_url>" + WechatConfig.notify_url + "</notify_url>"
                    + "<openid>" + openid + "</openid>"
                    + "<out_trade_no>" + payOrderId + "</out_trade_no>"
                    + "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
                    + "<total_fee>" + 100 + "</total_fee>"//支付的金额,单位:分
                    + "<trade_type>" + WechatConfig.TRADETYPE + "</trade_type>"
                    + "<sign>" + mysign + "</sign>"
                    + "</xml>";            //调用统一下单接口,并接受返回的结果
            String result = PayUtil.httpRequest(WechatConfig.pay_url, "POST", xml);            // 将解析结果存储在HashMap中
            Map map = PayUtil.doXMLParse(result);            String return_code = (String) map.get("return_code");//返回状态码
            String result_code = (String) map.get("result_code");//返回状态码

            Map<string> response = new HashMap<string>();//返回给小程序端需要的参数
            if (return_code == "SUCCESS" && return_code.equals(result_code)) {                String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
                response.put("nonceStr", nonce_str);
                response.put("package", "prepay_id=" + prepay_id);
                Long timeStamp = System.currentTimeMillis() / 1000;
                response.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
                //拼接签名需要的参数
                String stringSignTemp = "appId=" + WechatConfig.appid + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp;                //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                String paySign = PayUtil.sign(stringSignTemp, WechatConfig.key, "utf-8").toUpperCase();

                response.put("paySign", paySign);
            }

            response.put("appid", WechatConfig.appid);            return Response.succ(response);
        } catch (Exception e) {
            e.printStackTrace();
        }        return null;
    }    //这里是支付回调接口,微信支付成功后会自动调用
    @RequestMapping(value = "/wxNotify", method = RequestMethod.POST)
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));        String line = null;
        StringBuilder sb = new StringBuilder();        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();        //sb为微信返回的xml
        String notityXml = sb.toString();        String resXml = "";        Map map = PayUtil.doXMLParse(notityXml);        String returnCode = (String) map.get("return_code");        if ("SUCCESS".equals(returnCode)) {            //验证签名是否正确
            Map<string> validParams = PayUtil.paraFilter(map);  //回调验签时需要去除sign和空值参数
            String prestr = PayUtil.createLinkString(validParams); 
            //根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等
            if (PayUtil.verify(prestr, (String) map.get("sign"), WechatConfig.key, "utf-8")) {                /**此处添加自己的业务逻辑代码start**/
                
                //注意要判断微信支付重复回调,支付成功后微信会重复的进行回调
                
                /**此处添加自己的业务逻辑代码end**/
                //通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code></return_code>"
                        + "<return_msg></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code></return_code>"
                    + "<return_msg></return_msg>" + "</xml> ";
        }

        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }    //获取随机字符串
    private String getRandomStringByLength(int length) {        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();        for (int i = 0; i <p>上面程式碼用到了PayUtil和WechatConfig這兩個類,一個是配置類,一個是工具類,代碼如下:</p>
<p><strong>#PayUtil</strong></p>
<pre class="brush:php;toolbar:false">public class PayUtil {    /**
     * 签名字符串
     *
     * @param text          需要签名的字符串
     * @param key           密钥
     * @param input_charset 编码格式
     * @return 签名结果
     */
    public static String sign(String text, String key, String input_charset) {
        text = text + "&key=" + key;        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
    }    /**
     * 签名字符串
     *
     * @param text          需要签名的字符串
     * @param sign          签名结果
     * @param key           密钥
     * @param input_charset 编码格式
     * @return 签名结果
     */
    public static boolean verify(String text, String sign, String key, String input_charset) {
        text = text + key;        String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));        if (mysign.equals(sign)) {            return true;
        } else {            return false;
        }
    }    /**
     * @param content
     * @param charset
     * @return
     * @throws java.security.SignatureException
     * @throws UnsupportedEncodingException
     */
    public static byte[] getContentBytes(String content, String charset) {        if (charset == null || "".equals(charset)) {            return content.getBytes();
        }        try {            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }

    private static boolean isValidChar(char ch) {        if ((ch >= '0' && ch = 'A' && ch = 'a' && ch = 0x4e00 && ch = 0x8000 && ch  paraFilter(Map<string> sArray) {        Map<string> result = new HashMap<string>();        if (sArray == null || sArray.size()  params) {
        List<string> keys = new ArrayList(params.keySet());
        Collections.sort(keys);        String prestr = "";        for (int i = 0; i ");                if (!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("" + name + ">");
            }
        }        return sb.toString();
    }

    public static InputStream String2Inputstream(String str) {        return new ByteArrayInputStream(str.getBytes());
    }
}</string></string></string></string>

WechatConfig

public class WechatConfig {    //小程序appid
    public static final String appid = "";    //微信支付的商户id
    public static final String mch_id = "";    //微信支付的商户密钥
    public static final String key = "";    //支付成功后的服务器回调url,这里填PayController里的回调函数地址
    public static final String notify_url = "";    //签名方式,固定值
    public static final String SIGNTYPE = "MD5";    //交易类型,小程序支付的固定值为JSAPI
    public static final String TRADETYPE = "JSAPI";    //微信统一下单接口地址
    public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
}

在剛開始接觸小程式付款的時候,也覺得比較的棘手,因為自己並沒有寫過支付相關的程式碼。後來透過百度查找資料和閱讀官方文檔,最後把這個支付的controller完成了。最後,一定要多讀幾遍官方文檔,然後結合PayController的程式碼去看,就會發現其實付款也不是很難。

以上是小程式後端用什麼寫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java数据结构之AVL树详解Java数据结构之AVL树详解Jun 01, 2022 am 11:39 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

一文掌握Java8新特性Stream流的概念和使用一文掌握Java8新特性Stream流的概念和使用Jun 23, 2022 pm 12:03 PM

本篇文章给大家带来了关于Java的相关知识,其中主要整理了Stream流的概念和使用的相关问题,包括了Stream流的概念、Stream流的获取、Stream流的常用方法等等内容,下面一起来看一下,希望对大家有帮助。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能