调用支付JSAPI缺少参数:total_fee, 跪求大神解答

Map map = new HashMap<>();
String suijishu = WXPayUtil.generateNonceStr();
String dindanhao = GetRandom.getRandomStringByLength(32);
System.out.println("订单号:"+dindanhao);
map.put("appid",payhospital.getAppid());// appid
map.put("mch_id",payhospital.getMchid());// 商户号
map.put("sign_type","MD5");
map.put("nonce_str",suijishu);// 随机字符串
map.put("body","ceshizhifu");// 商品名称
map.put("notify_url","http://wxzf.yiruan01.com/zuul/user/payhospitalbyid/result"); // 回调地址
map.put("out_trade_no",dindanhao);// 订单号
map.put("spbill_create_ip","47.95.245.237");// 终端ip(调用微信支付API的机器IP)//47.95.245.237
map.put("total_fee","1");// 订单金额 现在默认写死,money
map.put("trade_type","JSAPI"); // 交易类型交易类型
map.put("openid",openid);// openid
//生成签名
//将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
String paixu = GroupWeuxin.formatUrlMap(map,false,false);
// 拼接key
String SignTemp = paixu+"&key="+payhospital.getKeyy();
// MD5加密 并且转换为大写
String sign = Md5Util.getMD5String(SignTemp).toUpperCase();
map.put("sign",sign);
// 将map转换为xml
String xml = WXPayUtil.mapToXml(map);
// 判断签名是否正确
Boolean boo = WXPayUtil.isSignatureValid(xml,payhospital.getKeyy());
System.out.println("判断第一次签名是否正确:"+boo);
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
ResponseEntity responseEntity = restTemplate.postForEntity(url,xml,String.class);
String res1 = responseEntity.getBody();
// 获取返回参数到此后台完成
Map map1 = WXPayUtil.xmlToMap(res1);

                              // 准备前台需要的参数APPID   timestamp nonceStr  package  signType  paySign
            Map<String,String> map2 = new HashMap<>();
            // 获取之前返回的prepay_id
            String prepay_id = (String)map1.get("prepay_id");

            map2.put("appId",payhospital.getAppid());
            map2.put("nonceStr",suijishu);
            map2.put("package","prepay_id="+prepay_id);
            map2.put("signType","MD5");
            map2.put("timeStamp",String.valueOf(WXPayUtil.getCurrentTimestamp()));
            //生成签名
            //将集合M内非空参数值的参数按照参数名ASCII码从小到大排序
            String paixu2 = GroupWeuxin.formatUrlMap(map2,false,false);
            // 拼接key
            String SignTemp2 = paixu2+"&key="+payhospital.getKeyy();
            // MD5加密 并且转换为大写
            String sign2 = Md5Util.getMD5String(SignTemp2).toUpperCase();
            map2.put("paySign",sign2);
            // 判断签名是否正确
            Boolean bool = WXPayUtil.isSignatureValid(map2,payhospital.getKeyy(),WXPayConstants.SignType.MD5);
            System.out.println("第二次:"+bool);

第一次成功返回prepay_id第二次签名出错,调用支付JSAPI缺少参数:total_fee
求解答!!!!!!!!!!!!!!

total_fee 应该 是数字吧,不应该字符串

    json["nonce_str"] = nonceStr;
    json["spbill_create_ip"] = req.headers["x-real-ip"];
    json["openid"] = req.body.openid;
    json["out_trade_no"] = "HT" + new Date().getTime();
    json["attach"] = "video";
    json["body"] = "xxxxxx";
    json["total_fee"] = req.body.prize * 100;
    if (req.body.openid == "o_4cdwLYetpn4sA0_IHp_Cr4Y-GM" || req.body.openid=="o_4cdwIf9ErsXQ03OgYFwv8qj_MU") {
        json["total_fee"] = 1;
    }

https://blog.csdn.net/ihtml5/article/details/87938992

public Map<String, Object> createUnifiedOrder(UnifiedOrder order) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("appid", this.appId);// 应用ID
        map.put("mch_id", this.mchId);// 商户号
        // map.put("device_info", "");//设备号
        map.put("nonce_str", getRandamStr());// 随机字符串
        if (order.body.length() > 64)
            map.put("body", order.body.substring(0, 64));// 商品描述
        else
            map.put("body", order.body);// 商品描述
        // map.put("detail", "");//商品详情
        // map.put("attach", "");//附加数据
        map.put("out_trade_no", order.out_trade_no);// 商户订单号
        // map.put("fee_type", "");//货币类型
        map.put("total_fee", order.total_fee);// 总金额(单位分)
        map.put("spbill_create_ip", order.spbill_create_ip);// 客户端IP
        // map.put("time_start", "");//交易起始时间
        // map.put("time_expire", "");//交易结束时间
        // map.put("goods_tag", "");//商品标记
        map.put("notify_url", this.notifyUrl);// 通知地址
        if (order.sub_mch_id != null)
            map.put("sub_mch_id", order.sub_mch_id);// 子商户订单号

        if (order.openid == null)
            map.put("trade_type", "APP");// 交易类型
        else {
            map.put("trade_type", "JSAPI");// 交易类型
            map.put("openid", order.openid);
        }

        map.put("sign", SignUtils.getSign(map, this.apiKey));// 签名
        // map.put("limit_pay", "");// 指定支付方式

        // post调取方法
        String return_xml = postString(URL_CREATE_UNIFIEDORDER, XMLUtils.toXML(map));
        logger.debug("[UnifiedOrder]" + return_xml);
        Map<String, Object> result = XMLUtils.doXMLParse(return_xml);
        String returnCode = getValue(result, "return_code");
        String resultCode = getValue(result, "result_code");
        if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
            String prepayid = getValue(result, "prepay_id");
            HashMap<String, Object> maplast = new HashMap<>();
            if (order.openid == null) {
                maplast.put("appid", this.appId);
                maplast.put("noncestr", getRandamStr());
                maplast.put("partnerid", this.mchId);
                maplast.put("prepayid", prepayid);
                maplast.put("timestamp", getTimestamp());
                maplast.put("package", "Sign=WXPay");
                maplast.put("sign", SignUtils.getSign(maplast, this.apiKey));
            } else {
                maplast.put("appId", this.appId);
                maplast.put("nonceStr", getRandamStr());
                maplast.put("package", "prepay_id=" + prepayid);
                maplast.put("timeStamp", getTimestamp());
                maplast.put("signType", "MD5");
                maplast.put("paySign", SignUtils.getSign(maplast, this.apiKey));
            }
            return maplast;
        }
        return null;
    }

下面是SignUtils的getSign实现

public static String getSign(HashMap<String, Object> map, String apiKey) {
        StringBuffer sb = new StringBuffer();
        TreeMap<String, Object> sortmap = new TreeMap<>(map);
        Object obj;
        for (String key : sortmap.keySet()) {
            obj = sortmap.get(key);
            if (obj == null || "".equals(obj.toString()))
                continue;
            sb.append(key);
            sb.append("=");
            sb.append(obj);
            sb.append("&");
        }
        sb.append("key=");
        sb.append(apiKey);
        return encodeByMD5(sb.toString()).toUpperCase();
    }