public String getOpenId(){
String code = getPara( "code" );
String openid = "" ;
if (StringUtils.isEmpty(openid) && !StringUtils.isEmpty(code)) {
SnsAccessToken token = SnsAccessTokenApi.getSnsAccessToken( "你的APPID" , "你的appsecret密码" ,
code);
openid = token.getOpenid();
}
getSession().setAttribute( "openandid" ,openid);
return openid;
}
public void index() throws Exception{
String openid = getOpenId();
//得到金额
String money= getPara( "money" );
Map<String ,String > map= new HashMap<String,String>();
//获取随机串
String nonceStr=UUID.randomUUID().toString().substring( 0 , 32 );
//可以是支付物品的订单号。一个号码,看自己怎么给
String out_trade_no= "123456789" ;
//支付金额。微信默认支付是(1=0.01)的比例,下面是将金额换算成微信可识别的
BigDecimal re1= new BigDecimal(expressCharge);
BigDecimal re2= new BigDecimal(Float.toString( 100 .00f));
Float aa = re1.multiply(re2).floatValue();
String total_fee = String.valueOf(aa);
String[] smill = total_fee.split( "\\." );
total_fee = smill[ 0 ];
//微信的appid
String appid= "XXXXXXXXXXXXXXXXX" ;
String mch_id= "XXXXXXXXX" ; //商户号
String body= "xxxxxxx" ; //商品信息,可以自己起最好写英文
//密匙,商户平台的支付API密匙,注意是商户平台,不是微信平台
String key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" ;
long timestamp = System.currentTimeMillis() / 1000 ;
map.put( "appid" , appid );
map.put( "mch_id" , mch_id);
map.put( "nonce_str" ,nonceStr);
map.put( "body" , body);
map.put( "out_trade_no" , out_trade_no);
map.put( "total_fee" , total_fee);
map.put( "spbill_create_ip" ,getRequest().getRemoteAddr());
//这里是支付成功后返回的地址,微信会以XML形式放回数据,就是本篇文章的下一类(例:wxxml())方法名。
map.put( "notify_url" , "http://www.XXXX.com/XXXX/XXXX/xxxx/wxxml" );
map.put( "trade_type" , "JSAPI" );
map.put( "openid" , openid); //传入OpenId
//这里传入Map集合和key商户支付密匙
String paySign=getPayCustomSign(map,key);
map.put( "sign" ,paySign);
//将map转为XML格式
String xml= ArrayToXml(map);
//统一下单,这里不用改
String url = "https://api.mch.weixin.qq.com/pay/unifiedorder" ;
String xmlStr = HttpKit.post(url, xml);
//prepayid由微信返回的 。
String prepayid = "" ;
if (xmlStr.indexOf( "SUCCESS" ) != - 1 ) {
Map<String, String> map2 = doXMLParse(xmlStr);
prepayid = (String) map2.get( "prepay_id" );
}
String paySign2=getPayCustomSign(signMap,key);
setAttr( "model" , model);
setAttr( "appId" , appid);
setAttr( "paytimestamp" , String.valueOf(timestamp));
setAttr( "paynonceStr" , nonceStr);
setAttr( "paypackage" , "prepay_id=" +prepayid);
setAttr( "paysignType" , "MD5" );
setAttr( "paySign" , paySign2);
//去到确认支付页面,返回页面方式不同,(例:pay.html页面),下面
render( "/XXXX/pay.html" );
}
/**
* 获取支付所需签名
* @param ticket
* @param timeStamp
* @param card_id
* @param code
* @return
* @throws Exception
*/
public static String getPayCustomSign(Map<String, String> bizObj,String key) throws Exception {
String bizString = FormatBizQueryParaMap(bizObj, false );
return sign(bizString, key);
}
/**
* 字典排序
* @param paraMap
* @param urlencode
* @return
* @throws Exception
*/
public static String FormatBizQueryParaMap(Map<String, String> paraMap,
boolean urlencode) throws Exception {
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 + "=" + val + "&" ;
}
}
if (buff.isEmpty() == false ) {
buff = buff.substring( 0 , buff.length() - 1 );
}
} catch (Exception e) {
throw new Exception(e.getMessage());
}
return buff;
}
//支付所需签名处调用此方法
public static String sign(String content, String key)
throws Exception{
String signStr = "" ;
signStr = content + "&key=" + key;
return MD5(signStr).toUpperCase();
}
//上一方法,MD5加密处理
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();
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 ;
}
}
//转为XML格式
public static String ArrayToXml(Map<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>" ;
return xml;
}
public static boolean IsNumeric(String str) {
if (str.matches( "\\d *" )) {
return true ;
} else {
return false ;
}
}
//解析XML
private Map<String, String> doXMLParse(String xml)
throws XmlPullParserException, IOException {
InputStream inputStream = new ByteArrayInputStream(xml.getBytes());
Map<String, String> map = null ;
XmlPullParser pullParser = XmlPullParserFactory.newInstance()
.newPullParser();
pullParser.setInput(inputStream, "UTF-8" ); // 为xml设置要解析的xml数据
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
map = new HashMap<String, String>();
break ;
case XmlPullParser.START_TAG:
String key = pullParser.getName();
if (key.equals( "xml" ))
break ;
String value = pullParser.nextText();
map.put(key, value);
break ;
case XmlPullParser.END_TAG:
break ;
}
eventType = pullParser.next();
}
return map;
}
|