zoukankan      html  css  js  c++  java
  • 微信扫码支付(基于java ssm)

    //微信扫码支付主要为返回预生成交易链接,所以需要生成二维码,前端可使用jquery.QRcode.js进行生成
    //主要的Controller
    package Controllers;

    import Entity.UnifiedOrderRequest;
    import Entity.UnifiedOrderRespose;
    import com.alibaba.fastjson.JSONObject;
    import com.thoughtworks.xstream.XStream;
    import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
    import com.thoughtworks.xstream.io.xml.XppDriver;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.servlet.ModelAndView;
    import utils.MD5Util;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.text.SimpleDateFormat;
    import java.util.*;

    @Controller
    @RequestMapping("/createQRCode")
    public class createQRCode {

    @RequestMapping(method = RequestMethod.GET, value = "/pay", produces = "text/plain;charset=GBK")
    public ModelAndView createCheck(){
    ModelAndView view = new ModelAndView();
    view.setViewName("forward:/jsp/wxPay.jsp");
    return view ;
    }

    /***
    * 查询订单
    * @param map
    * @param response
    * @param request
    * @return
    */
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/payCheck", produces = "text/plain;charset=GBK")
    public String payCheck(@RequestBody Map<String,String> map, HttpServletResponse response, HttpServletRequest request){
    try {
    String tradeNo = map.get("tradeNo");

    //生成订单
    String orderInfo = createSearchOrderInfo(tradeNo);
    //调统一下单API
    UnifiedOrderRespose code_return = httpSearchOrder(orderInfo);
    JSONObject return_flag = new JSONObject();
    if (code_return == null) {
    return_flag.put("msg", 0);
    } else {
    return_flag.put("msg", code_return.getTrade_state_desc());

    }

    return return_flag.toString();
    }catch (Exception e) {
    e.printStackTrace();
    JSONObject return_flag = new JSONObject();
    return_flag.put("msg", 0);
    return return_flag.toString();
    }

    }

    /***
    * 返回订单交易链接
    * @param map
    * @param response
    * @param request
    * @return
    */
    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, value = "/check", produces = "text/plain;charset=GBK")
    public String createCheck(@RequestBody Map<String,String> map, HttpServletResponse response, HttpServletRequest request){
    try {
    String Ip = null;
    if (request.getHeader("x-forwarded-for") == null) {
    Ip = request.getRemoteAddr();
    } else {
    Ip = request.getHeader("x-forwarded-for");
    }
    String money = map.get("money");
    String tradeNo = map.get("tradeNo");
    String name = map.get("name");

    String realMoney = String.valueOf((int) (Float.parseFloat(money) * 100));
    //生成订单
    String orderInfo = createOrderInfo(Ip, realMoney, tradeNo, name);
    //调统一下单API
    String code_url = httpOrder(orderInfo);
    JSONObject return_flag = new JSONObject();
    if (code_url.equals("0")) {
    return_flag.put("msg", 0);
    } else {
    return_flag.put("msg", code_url);

    }

    return return_flag.toString();
    }catch (Exception e) {
    e.printStackTrace();
    JSONObject return_flag = new JSONObject();
    return_flag.put("msg", 0);
    return return_flag.toString();
    }

    }
    /**
    * 生成订单
    * @param
    * @return
    */
    private String createOrderInfo(String IP, String money, String tradeNo, String name){
    //生成订单对象
    UnifiedOrderRequest unifiedOrderRequest = new UnifiedOrderRequest();
    unifiedOrderRequest.setAppid("");//公众账号ID
    unifiedOrderRequest.setMch_id("");//商户号
    unifiedOrderRequest.setNonce_str(makeUUID());//随机字符串
    unifiedOrderRequest.setBody(name);//商品描述
    unifiedOrderRequest.setOut_trade_no(tradeNo);//商户订单号
    unifiedOrderRequest.setTotal_fee(money); //金额需要扩大100倍:1代表支付时是0.01
    unifiedOrderRequest.setSpbill_create_ip(IP);//终端IP
    unifiedOrderRequest.setNotify_url("");//通知地址,虽然有,但仍需通过查询订单的方式进行确认状态
    unifiedOrderRequest.setTrade_type("NATIVE");//JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
    unifiedOrderRequest.setSign(createSign(unifiedOrderRequest));//签名说明5(见文末,签名方法一并给出)
    //将订单对象转为xml格式
    XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));

    xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xml
    return xStream.toXML(unifiedOrderRequest);
    }


    /***
    *生成查询订单序列化
    * @param tradeNo
    * @return
    */
    private String createSearchOrderInfo(String tradeNo){
    //生成订单对象
    UnifiedOrderRequest unifiedOrderRequest = new UnifiedOrderRequest();
    unifiedOrderRequest.setAppid("");//公众账号ID
    unifiedOrderRequest.setMch_id("");//商户号
    unifiedOrderRequest.setNonce_str(makeUUID());//随机字符串
    unifiedOrderRequest.setOut_trade_no(tradeNo);//商户订单号
    unifiedOrderRequest.setSign(createSearchSign(unifiedOrderRequest));//签名说明5(见文末,签名方法一并给出)
    //将订单对象转为xml格式
    XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));

    xStream.alias("xml", UnifiedOrderRequest.class);//根元素名需要是xml
    return xStream.toXML(unifiedOrderRequest);
    }




    /**
    * 调统一下单API
    * @param orderInfo
    * @return
    */
    private String httpOrder(String orderInfo) {
    String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    try {
    HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
    //加入数据
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);

    BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());
    buffOutStr.write(orderInfo.getBytes("UTF-8"));
    buffOutStr.flush();
    buffOutStr.close();

    //获取输入流
    InputStream is = null;
    BufferedReader reader = null;
    is = conn.getInputStream();
    reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    // BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

    String line = null;
    StringBuffer sb = new StringBuffer();
    while((line = reader.readLine())!= null){
    sb.append(line);
    }

    XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//说明3(见文末)
    //将请求返回的内容通过xStream转换为UnifiedOrderRespose对象
    xStream.alias("xml", UnifiedOrderRespose.class);
    UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString());

    //根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url
    if(null!=unifiedOrderRespose
    && "SUCCESS".equals(unifiedOrderRespose.getReturn_code())
    && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){
    return unifiedOrderRespose.getCode_url();
    }else{
    return "0";
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

    /**
    * 调统一下单API
    * @param orderInfo
    * @return
    */
    private UnifiedOrderRespose httpSearchOrder(String orderInfo) {
    String url = "https://api.mch.weixin.qq.com/pay/orderquery";
    try {
    HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
    //加入数据
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);

    BufferedOutputStream buffOutStr = new BufferedOutputStream(conn.getOutputStream());
    buffOutStr.write(orderInfo.getBytes("UTF-8"));
    buffOutStr.flush();
    buffOutStr.close();

    //获取输入流
    InputStream is = null;
    BufferedReader reader = null;
    is = conn.getInputStream();
    reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
    // BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

    String line = null;
    StringBuffer sb = new StringBuffer();
    while((line = reader.readLine())!= null){
    sb.append(line);
    }

    XStream xStream = new XStream(new XppDriver(new XmlFriendlyNameCoder("_-", "_")));//说明3(见文末)
    //将请求返回的内容通过xStream转换为UnifiedOrderRespose对象
    xStream.alias("xml", UnifiedOrderRespose.class);
    UnifiedOrderRespose unifiedOrderRespose = (UnifiedOrderRespose) xStream.fromXML(sb.toString());

    //根据微信文档return_code 和result_code都为SUCCESS的时候
    if(null!=unifiedOrderRespose
    && "SUCCESS".equals(unifiedOrderRespose.getReturn_code())
    && "SUCCESS".equals(unifiedOrderRespose.getResult_code())){
    return unifiedOrderRespose;
    }else{
    return null;
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }

    /**
    * 创建UUID
    * @return
    */
    public static synchronized String makeUUID() {
    Date date = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    StringBuffer s = new StringBuffer(dateFormat.format(date));
    return s.append((new Random().nextInt(900) + 100)).toString();
    }

    /**
    * 生成签名
    * @return
    */
    private String createSign(UnifiedOrderRequest unifiedOrderRequest) {
    //根据规则创建可排序的map集合
    SortedMap<String, String> packageParams = new TreeMap<String, String>();
    packageParams.put("appid", unifiedOrderRequest.getAppid());
    packageParams.put("body", unifiedOrderRequest.getBody());
    packageParams.put("mch_id", unifiedOrderRequest.getMch_id());
    packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str());
    packageParams.put("notify_url", unifiedOrderRequest.getNotify_url());
    packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no());
    packageParams.put("spbill_create_ip", unifiedOrderRequest.getSpbill_create_ip());
    packageParams.put("trade_type", unifiedOrderRequest.getTrade_type());
    packageParams.put("total_fee", unifiedOrderRequest.getTotal_fee());

    StringBuffer sb = new StringBuffer();
    Set es = packageParams.entrySet();//字典序
    Iterator it = es.iterator();
    while (it.hasNext()) {
    Map.Entry entry = (Map.Entry) it.next();
    String k = (String) entry.getKey();
    String v = (String) entry.getValue();
    //为空不参与签名、参数名区分大小写
    if (null != v && !"".equals(v) && !"sign".equals(k)
    && !"key".equals(k)) {
    sb.append(k + "=" + v + "&");
    }
    }
    //第二步拼接key,key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
    sb.append("key=" +"");
    String sign = MD5Util.MD5Encode(sb.toString(), "utf-8")
    .toUpperCase();//MD5加密
    return sign;
    }

    /***
    * 生成查询订单签名
    * @param unifiedOrderRequest
    * @return
    */
    private String createSearchSign(UnifiedOrderRequest unifiedOrderRequest) {
    //根据规则创建可排序的map集合
    SortedMap<String, String> packageParams = new TreeMap<String, String>();
    packageParams.put("appid", unifiedOrderRequest.getAppid());
    packageParams.put("mch_id", unifiedOrderRequest.getMch_id());
    packageParams.put("nonce_str", unifiedOrderRequest.getNonce_str());
    packageParams.put("out_trade_no", unifiedOrderRequest.getOut_trade_no());

    StringBuffer sb = new StringBuffer();
    Set es = packageParams.entrySet();//字典序
    Iterator it = es.iterator();
    while (it.hasNext()) {
    Map.Entry entry = (Map.Entry) it.next();
    String k = (String) entry.getKey();
    String v = (String) entry.getValue();
    //为空不参与签名、参数名区分大小写
    if (null != v && !"".equals(v) && !"sign".equals(k)
    && !"key".equals(k)) {
    sb.append(k + "=" + v + "&");
    }
    }
    //第二步拼接key,key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
    sb.append("key=" +"");
    String sign = MD5Util.MD5Encode(sb.toString(), "utf-8")
    .toUpperCase();//MD5加密
    return sign;
    }
    }
    //定义请求的实体类
    package Entity;
    /**
    * 统一下单请求参数(必填)
    * @author moucong
    *
    */
    public class UnifiedOrderRequest {

    public String getAppid() {
    return appid;
    }

    public void setAppid(String appid) {
    this.appid = appid;
    }

    public String getMch_id() {
    return mch_id;
    }

    public void setMch_id(String mch_id) {
    this.mch_id = mch_id;
    }

    public String getNonce_str() {
    return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
    this.nonce_str = nonce_str;
    }

    public String getSign() {
    return sign;
    }

    public void setSign(String sign) {
    this.sign = sign;
    }

    public String getBody() {
    return body;
    }

    public void setBody(String body) {
    this.body = body;
    }

    public String getOut_trade_no() {
    return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
    this.out_trade_no = out_trade_no;
    }

    public String getTotal_fee() {
    return total_fee;
    }

    public void setTotal_fee(String total_fee) {
    this.total_fee = total_fee;
    }

    public String getSpbill_create_ip() {
    return spbill_create_ip;
    }

    public void setSpbill_create_ip(String spbill_create_ip) {
    this.spbill_create_ip = spbill_create_ip;
    }

    public String getNotify_url() {
    return notify_url;
    }

    public void setNotify_url(String notify_url) {
    this.notify_url = notify_url;
    }

    public String getTrade_type() {
    return trade_type;
    }

    public void setTrade_type(String trade_type) {
    this.trade_type = trade_type;
    }


    private String appid; //公众账号ID
    private String mch_id; //商户号
    private String nonce_str; //随机字符串
    private String sign; //签名
    private String body; //商品描述
    private String out_trade_no; //商户订单号
    private String total_fee; //总金额
    private String spbill_create_ip; //终端IP
    private String notify_url; //通知地址
    private String trade_type; //交易类型

    }
    //返回接收数据的实体类
    package Entity;
    /**
    * 统一下单返回参数
    * @author moucong
    *
    */
    public class UnifiedOrderRespose {


    private String return_code; //返回状态码
    private String return_msg; //返回信息
    private String appid; //公众账号ID
    private String mch_id; //商户号
    private String device_info; //设备号
    private String nonce_str; //随机字符串
    private String sign; //签名
    private String result_code; //业务结果
    private String err_code; //错误代码
    private String err_code_des; //错误代码描述
    private String trade_type; //交易类型
    private String prepay_id; //预支付交易会话标识
    private String code_url; //二维码链接
    private String total_fee; //总金额
    private String out_trade_no; //商户订单号
    private String trade_state; //交易状态
    private String trade_state_desc; //交易状态描述
    private String openid; //用户标识
    private String is_subscribe; //是否关注公众账号
    private String bank_type; //付款银行
    private String cash_fee; //现金支付金额
    private String transaction_id; //微信支付订单号
    private String time_end; //支付完成时间
    private String fee_type; //标价币种
    private String attach; //附加数据
    private String cash_fee_type; //现金支付币种
    private String coupon_fee; //代金券金额
    private String coupon_count; //代金券使用数量
    private String coupon_type_$n; //代金券类型
    private String coupon_id_$n; //代金券ID
    private String coupon_fee_$n; //单个代金券支付金额

    public String getCash_fee_type() {
    return cash_fee_type;
    }

    public void setCash_fee_type(String cash_fee_type) {
    this.cash_fee_type = cash_fee_type;
    }

    public String getCoupon_fee() {
    return coupon_fee;
    }

    public void setCoupon_fee(String coupon_fee) {
    this.coupon_fee = coupon_fee;
    }

    public String getCoupon_count() {
    return coupon_count;
    }

    public void setCoupon_count(String coupon_count) {
    this.coupon_count = coupon_count;
    }

    public String getCoupon_type_$n() {
    return coupon_type_$n;
    }

    public void setCoupon_type_$n(String coupon_type_$n) {
    this.coupon_type_$n = coupon_type_$n;
    }

    public String getCoupon_id_$n() {
    return coupon_id_$n;
    }

    public void setCoupon_id_$n(String coupon_id_$n) {
    this.coupon_id_$n = coupon_id_$n;
    }

    public String getCoupon_fee_$n() {
    return coupon_fee_$n;
    }

    public void setCoupon_fee_$n(String coupon_fee_$n) {
    this.coupon_fee_$n = coupon_fee_$n;
    }




    public String getAttach() {
    return attach;
    }

    public void setAttach(String attach) {
    this.attach = attach;
    }




    public String getFee_type() {
    return fee_type;
    }

    public void setFee_type(String fee_type) {
    this.fee_type = fee_type;
    }




    public String getReturn_code() {
    return return_code;
    }

    public void setReturn_code(String return_code) {
    this.return_code = return_code;
    }

    public String getReturn_msg() {
    return return_msg;
    }

    public void setReturn_msg(String return_msg) {
    this.return_msg = return_msg;
    }

    public String getAppid() {
    return appid;
    }

    public void setAppid(String appid) {
    this.appid = appid;
    }

    public String getMch_id() {
    return mch_id;
    }

    public void setMch_id(String mch_id) {
    this.mch_id = mch_id;
    }

    public String getDevice_info() {
    return device_info;
    }

    public void setDevice_info(String device_info) {
    this.device_info = device_info;
    }

    public String getNonce_str() {
    return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
    this.nonce_str = nonce_str;
    }

    public String getSign() {
    return sign;
    }

    public void setSign(String sign) {
    this.sign = sign;
    }

    public String getResult_code() {
    return result_code;
    }

    public void setResult_code(String result_code) {
    this.result_code = result_code;
    }

    public String getErr_code() {
    return err_code;
    }

    public void setErr_code(String err_code) {
    this.err_code = err_code;
    }

    public String getErr_code_des() {
    return err_code_des;
    }

    public void setErr_code_des(String err_code_des) {
    this.err_code_des = err_code_des;
    }

    public String getTrade_type() {
    return trade_type;
    }

    public void setTrade_type(String trade_type) {
    this.trade_type = trade_type;
    }

    public String getPrepay_id() {
    return prepay_id;
    }

    public void setPrepay_id(String prepay_id) {
    this.prepay_id = prepay_id;
    }

    public String getCode_url() {
    return code_url;
    }

    public void setCode_url(String code_url) {
    this.code_url = code_url;
    }


    public String getIs_subscribe() {
    return is_subscribe;
    }

    public void setIs_subscribe(String is_subscribe) {
    this.is_subscribe = is_subscribe;
    }

    public String getBank_type() {
    return bank_type;
    }

    public void setBank_type(String bank_type) {
    this.bank_type = bank_type;
    }

    public String getCash_fee() {
    return cash_fee;
    }

    public void setCash_fee(String cash_fee) {
    this.cash_fee = cash_fee;
    }

    public String getTransaction_id() {
    return transaction_id;
    }

    public void setTransaction_id(String transaction_id) {
    this.transaction_id = transaction_id;
    }

    public String getTime_end() {
    return time_end;
    }

    public void setTime_end(String time_end) {
    this.time_end = time_end;
    }




    public String getOpenid() {
    return openid;
    }

    public void setOpenid(String openid) {
    this.openid = openid;
    }



    public String getTrade_state_desc() {
    return trade_state_desc;
    }

    public void setTrade_state_desc(String trade_state_desc) {
    this.trade_state_desc = trade_state_desc;
    }





    public String getOut_trade_no() {
    return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
    this.out_trade_no = out_trade_no;
    }



    public String getTotal_fee() {
    return total_fee;
    }

    public void setTotal_fee(String total_fee) {
    this.total_fee = total_fee;
    }


    public String getTrade_state() {
    return trade_state;
    }

    public void setTrade_state(String trade_state) {
    this.trade_state = trade_state;
    }
    }
    //MD5算法
    package utils;



    import java.security.MessageDigest;

    /**
    * ***************************************************
    *
    * @Auther: zianY -.-- .- -. --. --.. .. .- -.
    * @Descipion: MD5
    * @CreateDate: 2019-12-19
    * ****************************************************
    */
    public class MD5Util {


    public static void main(String[] args) {

    // 99B26BE5F5F7AF4A576DFB6DF0DD38FF
    System.out.println(MD5EncodeUtf8("123456"));
    }

    private static String byteArrayToHexString(byte b[]) {
    StringBuffer resultSb = new StringBuffer();
    for (int i = 0; i < b.length; i++)
    resultSb.append(byteToHexString(b[i]));

    return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
    int n = b;
    if (n < 0)
    n += 256;
    int d1 = n / 16;
    int d2 = n % 16;
    return hexDigits[d1] + hexDigits[d2];
    }

    /**
    * 返回大写MD5
    *
    * @param origin
    * @param charsetname
    * @return
    */
    public static String MD5Encode(String origin, String charsetname) {
    String resultString = null;
    try {
    resultString = origin;
    MessageDigest md = MessageDigest.getInstance("MD5");
    if (charsetname == null || "".equals(charsetname))
    resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
    else
    resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
    } catch (Exception exception) {
    }
    return resultString.toUpperCase();
    }


    /**
    * @param origin
    * @return
    */
    public static String MD5EncodeUtf8(String origin) {
    origin = origin + "323@#@$1234da";
    return MD5Encode(origin.trim(), "utf-8");
    }


    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
    "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};




    }


  • 相关阅读:
    Sublime Text 2 实用快捷键[Mac OS X]
    SublimeText2 快捷键一览表
    sublime text 3 快捷键大全以及配置编译环境
    解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in
    PHP中include和require的区别详解
    Call to undefined function imagettftext()解决方法
    mysql单引号和双引号的用法
    php.ini 配置文件的深入解析
    《JavaScript设计模式与开发实践》—— 代理模式
    《JavaScript高级程序设计》—— DOM
  • 原文地址:https://www.cnblogs.com/setname/p/12199892.html
Copyright © 2011-2022 走看看