当前位置: 移动技术网 > IT编程>开发语言>Java > 微信支付java版本之Native付款

微信支付java版本之Native付款

2019年07月22日  | 移动技术网IT编程  | 我要评论

最近工作中接触到一些关于微信支付方面的东西,看到给的demo都是php版本的,再加上微信支付文档写的确实不敢恭维,趟过不少坑之后闲下来做个总结。

一、前期准备 

做微信开发首先要申请一个公共账号,申请成功后会以邮件形式发给你一些必要信息,公共账号中有开发文档以及开发中必要信息,以及测试的数据查询。

 

二、工具类
1.md5加密工具类 

package com.pay.utils.weixin;
import java.security.messagedigest;
public class md5util {
 public final static string md5(string s) {
    char hexdigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};    
    try {
      byte[] btinput = s.getbytes();
      // 获得md5摘要算法的 messagedigest 对象
      messagedigest mdinst = messagedigest.getinstance("md5");
      // 使用指定的字节更新摘要
      mdinst.update(btinput);
      // 获得密文
      byte[] md = mdinst.digest();
      // 把密文转换成十六进制的字符串形式
      int j = md.length;
      char str[] = new char[j * 2];
      int k = 0;
      for (int i = 0; i < j; i++) {
        byte byte0 = md[i];
        str[k++] = hexdigits[byte0 >>> 4 & 0xf];
        str[k++] = hexdigits[byte0 & 0xf];
      }
      return new string(str);
    } catch (exception e) {
      e.printstacktrace();
      return null;
    }
 }
}

2.commonutil工具类,用于装换成微信所需xml。以下return new string(xml.tostring().getbytes(),"iso8859-1");将工具类中的utf-8改成iso8859-1,否则微信订单中的中文会出现乱码,改后可以正确显示。 

package com.pay.utils.weixin;

import java.io.unsupportedencodingexception;
import java.net.urlencoder;
import java.util.*;
import java.util.map.entry;

public class commonutil {

 public static string createnoncestr(int length) {
 string chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789";
 string res = "";
 for (int i = 0; i < length; i++) {
  random rd = new random();
  res += chars.indexof(rd.nextint(chars.length() - 1));
 }
 return res;
 }

 public static string createnoncestr() {
 string chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789";
 string res = "";
 for (int i = 0; i < 16; i++) {
  random rd = new random();
  res += chars.charat(rd.nextint(chars.length() - 1));
 }
 return res;
 }

 public static string formatqueryparamap(hashmap<string, string> parameters)
  throws sdkruntimeexception {

 string buff = "";
 try {
  list<map.entry<string, string>> infoids = new arraylist<map.entry<string, string>>(
   parameters.entryset());

  collections.sort(infoids,
   new comparator<map.entry<string, string>>() {
   public int compare(map.entry<string, string> o1,
    map.entry<string, string> o2) {
    return (o1.getkey()).tostring().compareto(
     o2.getkey());
   }
   });

  for (int i = 0; i < infoids.size(); i++) {
  map.entry<string, string> item = infoids.get(i);
  if (item.getkey() != "") {
   buff += item.getkey() + "="
    + urlencoder.encode(item.getvalue(), "utf-8") + "&";
  }
  }
  if (buff.isempty() == false) {
  buff = buff.substring(0, buff.length() - 1);
  }
 } catch (exception e) {
  throw new sdkruntimeexception(e.getmessage());
 }

 return buff;
 }

 public static string formatbizqueryparamap(hashmap<string, string> paramap,
  boolean urlencode) throws sdkruntimeexception {

 string buff = "";
 try {
  list<map.entry<string, string>> infoids = new arraylist<map.entry<string, string>>(
   paramap.entryset());

  collections.sort(infoids,
   new comparator<map.entry<string, string>>() {
   public int compare(map.entry<string, string> o1,
    map.entry<string, string> o2) {
    return (o1.getkey()).tostring().compareto(
     o2.getkey());
   }
   });

  for (int i = 0; i < infoids.size(); i++) {
  map.entry<string, string> item = infoids.get(i);
  //system.out.println(item.getkey());
  if (item.getkey() != "") {
   
   string key = item.getkey();
   string val = item.getvalue();
   if (urlencode) {
   val = urlencoder.encode(val, "utf-8");

   }
   buff += key.tolowercase() + "=" + val + "&";

  }
  }

  if (buff.isempty() == false) {
  buff = buff.substring(0, buff.length() - 1);
  }
 } catch (exception e) {
  throw new sdkruntimeexception(e.getmessage());
 }
 return buff;
 }

 public static boolean isnumeric(string str) {
 if (str.matches("\\d *")) {
  return true;
 } else {
  return false;
 }
 }

 public static string arraytoxml(hashmap<string, string> arr) {
 string xml = "<xml>";
 
 iterator<entry<string, string>> iter = arr.entryset().iterator();
 while (iter.hasnext()) {
  entry<string, string> entry = iter.next();
  string key = entry.getkey();
  string val = entry.getvalue();
  if (isnumeric(val)) {
  xml += "<" + key + ">" + val + "</" + key + ">";

  } else
  xml += "<" + key + "><![cdata[" + val + "]]></" + key + ">";
 }

 xml += "</xml>";
  try {
  return new string(xml.tostring().getbytes(),"iso8859-1");
 } catch (unsupportedencodingexception e) {
  // todo auto-generated catch block
  e.printstacktrace();
 } 
  return "";
 }

}

3.clientcustomssl工具类,用于生成sign以及创建微信订单package com.pay.utils.weixin;

import java.util.arraylist;
import java.util.collections;
import java.util.comparator;
import java.util.hashmap;
import java.util.list;
import java.util.map;

import org.springframework.util.stringutils;


/**
 * this example demonstrates how to create secure connections with a custom ssl
 * context.
 */
public class clientcustomssl {

 public static string getbizsign(hashmap<string, string> bizobj)
  throws sdkruntimeexception {
 hashmap<string, string> bizparameters = new hashmap<string, string>();

 list<map.entry<string, string>> infoids = new arraylist<map.entry<string, string>>(
  bizobj.entryset());
 system.out.println(infoids);
 collections.sort(infoids, new comparator<map.entry<string, string>>() {
  public int compare(map.entry<string, string> o1,
   map.entry<string, string> o2) {
  return (o1.getkey()).tostring().compareto(o2.getkey());
  }
 });
system.out.println("--------------------");
 system.out.println(infoids);
 for (int i = 0; i < infoids.size(); i++) {
  map.entry<string, string> item = infoids.get(i);
  if (item.getkey() != "") {
  bizparameters.put(item.getkey().tolowercase(), item.getvalue());
  }
 }
 //bizparameters.put("key", "12345678123456781234567812345671");
 string bizstring = commonutil.formatbizqueryparamap(bizparameters,
  false);
 bizstring += "&key=12345678123456781234567812345671";
 system.out.println("***************");
 
 system.out.println(bizstring);

// return sha1util.sha1(bizstring);
 return md5util.md5(bizstring);

 }
 /**
 * 微信创建订单
 * @param noncestr
 * @param orderdescribe
 * @param orderno
 * @param price
 * @param timestart
 * @param timeexpire
 * @return
 * @throws sdkruntimeexception
 */
 public static string createnativepackage(string noncestr,string orderdescribe,string orderno,string price,string timestart,string timeexpire) throws sdkruntimeexception {
 hashmap<string, string> nativeobj = new hashmap<string, string>();
 nativeobj.put("appid", "见公众账号");          //公众账号id
 nativeobj.put("mch_id", "见邮件");    //商户号
 nativeobj.put("nonce_str", noncestr);       //随机字符串
 nativeobj.put("body", orderdescribe);    //商品描述
 nativeobj.put("attach", "tradeno");    //附加数据
 nativeobj.put("out_trade_no", orderno);          //商户订单号(全局唯一)
 nativeobj.put("total_fee", price);   //总金额(单位为分,不能带小数点)
 nativeobj.put("spbill_create_ip","192.168.0.144");     //终端ip
 nativeobj.put("time_start", timestart);          //交易起始时间
 nativeobj.put("time_expire", timeexpire);      //交易结束时间
 nativeobj.put("notify_url", customizedpropertyplaceholderconfigurer.getcontextproperty("wxurl")+"/weixin_callback/weixincallback/init.action");                   //回调通知地址
 nativeobj.put("trade_type", "native");   //交易类型
 
 string sign = getbizsign(nativeobj);
 
 nativeobj.put("sign", sign.touppercase());
 
 return commonutil.arraytoxml(nativeobj);

 }       /**
* 微信订单支付查询
* @param noncestr
* @param orderdescribe
* @param orderno
* @param price
* @param timestart
* @param timeexpire
* @return
* @throws sdkruntimeexception
*/
public static string searchnativepackage(string transactionid,string outtradeno,string noncestr) throws sdkruntimeexception {
hashmap<string, string> nativeobj = new hashmap<string, string>();
nativeobj.put("appid", "见公众共账号"); //公众账号id
nativeobj.put("mch_id", "见邮件");//商户号
nativeobj.put("nonce_str", noncestr);//随机字符串
if(!stringutils.isempty(transactionid)){
nativeobj.put("transaction_id", transactionid); 
}
if(!stringutils.isempty(outtradeno)){
nativeobj.put("out_trade_no", outtradeno);//随机字符串
}
string sign = getbizsign(nativeobj);
nativeobj.put("sign", sign.touppercase()); 
return commonutil.arraytoxml(nativeobj);
 /**
* 微信退款
* @param outtradeno
* @param outrefundno
 * @param totalfee
* @param refundfee
* @return
* @throws sdkruntimeexception
*/
public static string refundnativepackage(string outtradeno,string outrefundno,string totalfee,string refundfee,string noncestr) throws sdkruntimeexception {
hashmap<string, string> nativeobj = new hashmap<string, string>();
nativeobj.put("appid", "见公众账号");//公众账号id
nativeobj.put("mch_id", "见邮件");//商户号
nativeobj.put("nonce_str", noncestr);//随机字符串
nativeobj.put("out_trade_no", outtradeno);//商户订单号(全局唯一)
nativeobj.put("out_refund_no", outrefundno);//商户退款单号(全局唯一)
nativeobj.put("total_fee", totalfee);//总金额(单位为分,不能带小数点)
nativeobj.put("refund_fee", refundfee);//退款金额(单位为分,不能带小数点)
nativeobj.put("op_user_id", "邮件");
string sign = getbizsign(nativeobj);
nativeobj.put("sign", sign.touppercase());
return commonutil.arraytoxml(nativeobj);
}

/**
* 微信待支付
 * @param noncestr
* @param orderdescribe
* @param orderno
* @param price
* @param timestart
* @param timeexpire
* @return
* @throws sdkruntimeexception
*/
public static string createjsapipackage(string noncestr,string orderdescribe,string orderno,string price,string timestart,string timeexpire,string openid) throws sdkruntimeexception {
hashmap<string, string> nativeobj = new hashmap<string, string>();
nativeobj.put("appid", "见公众账号");//公众账号id
nativeobj.put("openid", openid);//公众账号id
nativeobj.put("mch_id", "见邮件")//商户号
nativeobj.put("nonce_str", noncestr);//随机字符串
nativeobj.put("body", orderdescribe);//商品描述
nativeobj.put("attach", "tradeno");//附加数据
nativeobj.put("out_trade_no", orderno);//商户订单号(全局唯一)
nativeobj.put("total_fee", price);//总金额(单位为分,不能带小数点)
nativeobj.put("spbill_create_ip","192.168.0.144");//终端ip
nativeobj.put("time_start", timestart);//交易起始时间
nativeobj.put("time_expire", timeexpire)//交易结束时间
nativeobj.put("notify_url",customizedpropertyplaceholderconfigurer.getcontextproperty("wxurl")+"/weixin_callback/weixincallback/init.action");//通知地址
nativeobj.put("trade_type", "jsapi");//交易类型
string sign = getbizsign(nativeobj);
nativeobj.put("sign", sign.touppercase());
return commonutil.arraytoxml(nativeobj);
}
/**
* 微信关闭订单
* @param noncestr
* @param orderdescribe
* @param orderno
* @param price
* @param timestart
* @param timeexpire
* @param openid
* @return
* @throws sdkruntimeexception
*/
public static string createcloseorder(string outtradeno,string noncestr) throws sdkruntimeexception {
hashmap<string, string> nativeobj = new hashmap<string, string>();
nativeobj.put("appid", "见公众账号");//公众账号id
nativeobj.put("mch_id", "见邮件");//商户号
nativeobj.put("out_trade_no", outtradeno);//商户订单号(全局唯一)
nativeobj.put("nonce_str", noncestr);//随机字符串
 string sign = getbizsign(nativeobj);
nativeobj.put("sign", sign.touppercase());
 return commonutil.arraytoxml(nativeobj);
}
}

4.调用微信支付接口 

package com.pay.controller.weixin;

import java.io.file;
import java.io.fileinputstream;
import java.security.keystore;
import java.text.simpledateformat;
import java.util.date;
import java.util.list;

import javax.net.ssl.sslcontext;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;

import net.sf.json.jsonarray;
import net.sf.json.jsonobject;

import org.apache.http.httpentity;
import org.apache.http.client.methods.closeablehttpresponse;
import org.apache.http.client.methods.httppost;
import org.apache.http.conn.ssl.sslconnectionsocketfactory;
import org.apache.http.conn.ssl.sslcontexts;
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.dom4j.document;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.saxreader;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.http.httpstatus;
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.responsestatus;
import org.springframework.web.bind.annotation.restcontroller;

import com.pay.bo.payhist;
import com.pay.constants.payhistorypaystatus;
import com.pay.constants.payhistorypaytype;
import com.pay.service.weixinpayservice;
import com.pay.utils.weixin.clientcustomssl;
import com.pay.utils.weixin.closeweixinorderutils;
import com.pay.utils.weixin.customizedpropertyplaceholderconfigurer;


@restcontroller
@requestmapping("/pay")
public class weixinpaycontroller {
 
 
 @autowired
 weixinpayservice weixinpayservice;
 private static long standardtime = 1662652800000l;
 
 /**
 * 返回生成二维码的url
 * @param request
 * @param response
 * @return
 */
 @requestmapping(value="/geturl",method=requestmethod.post)
 @responsestatus(httpstatus.ok)
 public object geturl(httpservletresponse response,@requestbody string body){
 try{
  jsonobject jsono = jsonobject.fromobject(body);
  payhist ph = null;
//  list<map<string,object>> td = weixinpayservice.gettrade(orderno);
  date dt = new date();
  simpledateformat sdf = new simpledateformat("yyyymmddhhmmss");
  string noncestr = sdf.format(dt).tostring();
  date now = new date();
  
  string tradepayno = jsono.get("orderno").tostring()+string.format("%10d",standardtime - now.gettime()).substring(0, 10);
  system.out.println("订单标号orderno======="+jsono.get("orderno").tostring());
  system.out.println("10位随机数======="+string.format("%10d",standardtime - now.gettime()).substring(0, 10));
  string price = math.round(float.valueof(jsono.get("price").tostring())*100)+"";
  long timeexpirestrold = dt.gettime();
  long timenew = long.parselong(customizedpropertyplaceholderconfigurer.getcontextproperty("weixin.send2finish.overtime").tostring());
  long timeexpirenew = timeexpirestrold+timenew;
  date dttimeexpire = new date(timeexpirenew);
  simpledateformat dtsdf = new simpledateformat("yyyymmddhhmmss");
  string timeexpire = dtsdf.format(dttimeexpire).tostring();
  system.out.println("noncestr=="+noncestr);
  system.out.println("orderno=="+jsono.get("orderno").tostring());
  system.out.println("price=="+price);
  system.out.println("timestart=="+noncestr);
  system.out.println("timeexpire=="+timeexpire);
  
  
  jsonobject result = (jsonobject) seturl(noncestr,"订单",tradepayno,price,noncestr,timeexpire);
  
  if(result.get("status").tostring().equals("success")){
  ph = new payhist();
  ph.settradepayurl(result.getstring("weixinpayurl"));//此字段为支付链接,可以此链接生成二维码扫码支付
  ph.setpaytradeno(jsono.get("orderno").tostring());
  ph.settradepayno(tradepayno);
  ph.setpaystatus(payhistorypaystatus.wechat_pay_status_wait);
  ph.setpaytype(payhistorypaytype.wechat);
  ph.setappkey(jsono.getstring("appkey").tostring());
  ph.setpayamount(price);
  
  result.put("paytradeno", ph.getpaytradeno());
  result.put("tradepayno", ph.gettradepayno());
  result.put("paystatus", ph.getpaystatus());
  result.put("paytype", ph.getpaytype());
  
  }  
  return result;
  
  
 }catch(exception e){
  e.printstacktrace();
  jsonobject result = new jsonobject();
  result.put("status","error");
  result.put("msg",e.getmessage());
//  return result.tostring();
 }
 return null;
 
 
 }

 public object seturl(string noncestr,string orderdescribe,string orderno,string price,string timestart,string timeexpire) {
 try{
  
  keystore keystore = keystore.getinstance("pkcs12");
  fileinputstream instream = new fileinputstream(new file(微信证书绝对路径));
  try {
  keystore.load(instream, "商户id".tochararray());
  }finally {
  instream.close();
  }

  // trust own ca and all self-signed certs
  sslcontext sslcontext = sslcontexts.custom().loadkeymaterial(keystore,<span style="font-family: arial, helvetica, sans-serif;">商户id</span>.tochararray()).build();
  // allow tlsv1 protocol only
  sslconnectionsocketfactory sslsf = new sslconnectionsocketfactory(
   sslcontext, new string[] { "tlsv1" }, null,
   sslconnectionsocketfactory.allow_all_hostname_verifier);
  closeablehttpclient httpclient = httpclients.custom()
   .setsslsocketfactory(sslsf).build();
  // httpget httpget = new
  // httpget("https://api.mch.weixin.qq.com/secapi/pay/refund");
  httppost httppost = new httppost(
   "https://api.mch.weixin.qq.com/pay/unifiedorder");
  
  string xml = clientcustomssl.createnativepackage(noncestr,orderdescribe,orderno,price,timestart,timeexpire);
  try {

  
  stringentity se = new stringentity(xml);
  
  httppost.setentity(se);

  system.out.println("executing request" + httppost.getrequestline());

  closeablehttpresponse responseentry = httpclient.execute(httppost);
  try {
   httpentity entity = responseentry.getentity();

   system.out.println("----------------------------------------");
   system.out.println(responseentry.getstatusline());
   if (entity != null) {
   system.out.println("response content length: "
    + entity.getcontentlength());
  /* bufferedreader bufferedreader = new bufferedreader(
    new inputstreamreader(entity.getcontent()));
   string text;
   while ((text = bufferedreader.readline()) != null) {
    system.out.println("======="+text);
   }*/ 
      
   saxreader saxreader = new saxreader();
   document document = saxreader.read(entity.getcontent());
   element rootelt = document.getrootelement();
   system.out.println("根节点:" + rootelt.getname());
   system.out.println("==="+rootelt.elementtext("result_code"));
   system.out.println("==="+rootelt.elementtext("return_msg"));
   string resultcode = rootelt.elementtext("result_code");
   jsonobject result = new jsonobject();  
   
   document documentxml =documenthelper.parsetext(xml);
   element rooteltxml = documentxml.getrootelement();
   
   if(resultcode.equals("success")){
    system.out.println("=================prepay_id===================="+ rootelt.elementtext("prepay_id"));
    system.out.println("=================sign===================="+ rooteltxml.elementtext("sign"));
    result.put("weixinpayurl", rootelt.elementtext("code_url"));
    result.put("prepayid", rootelt.elementtext("prepay_id"));
    result.put("status","success");
    result.put("msg","success");
   }else{
    result.put("status","false");
    result.put("msg",rootelt.elementtext("err_code_des"));
   }
   
   
   return result;

   }
   entityutils.consume(entity);
  }
  finally {
   responseentry.close();
  }
  }
  finally {
  httpclient.close();
  }
  return null;
  
  
 }catch(exception e){
  e.printstacktrace();
  jsonobject result = new jsonobject();
  result.put("status","error");
  result.put("msg",e.getmessage());
  return result;
 }
 }
 
}


httpclient  jar包和json jar包:。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网