APP微信支付后台内容小结
来源:互联网 发布:华罗庚的优化法时间 编辑:程序博客网 时间:2024/05/18 00:52
第一次做微信支付,在网上找了很多的demo,但我觉得没有一个可以拿来现成就可以用的,我东拼西凑下才“拼接”成功,终于和我们的手机前段打通脉络,经过测试还算好用。话不多说,在此作为我一个记忆节点,也希望能帮助到有和我相同困惑的朋友们!
此处使用spring MVC Controller注入方式,调用方法。
@Controller
@RequestMapping("/AsynAlipayNotifyController")
public class AsynAlipayNotifyController {
/**
* App端调用微信支付
* @param body
* @param out_trade_no
* @param total_fee
* @param spbill_create_ip
* @return
* @author superma
*/
@Author(type=CheckType.NO_CHECK)
@RequestMapping("/getWxPayInfo.json")
public @ResponseBody JSONMap<String,Object> getWxPayInfo(String body,String out_trade_no,int total_fee,
String spbill_create_ip){
JSONMap<String,Object> model = new JSONMap<String,Object>();
try{
//获取支付参数
String appid =WXSignUtils.APPID; //在工具类中定义申请的ID号
System.out.println("appid:"+appid);
String mch_id =WXSignUtils.MCH_ID;
System.out.println("mch_id:"+mch_id);
String nonce_str =RandCharsUtils.getRandomString(16);
String time_start =RandCharsUtils.timeStart();
System.out.println(time_start);
String time_expire =RandCharsUtils.timeExpire();
System.out.println(time_expire);
String notify_url =WXSignUtils.NOTIFY_URL;
System.out.println("notify_url:"+notify_url);
String trade_type = WXSignUtils.TRADE_TYPE;
//开始生成签名
SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
parameters.put("appid", appid);
parameters.put("mch_id", mch_id); //商户id
parameters.put("nonce_str", nonce_str); //随机字符串
parameters.put("body", body); //商品描述
parameters.put("out_trade_no", out_trade_no); //订单编号
parameters.put("total_fee", total_fee); //总价,‘分’为单位
parameters.put("time_start", time_start); //支付生成时间
parameters.put("time_expire", time_expire); //支付失效时间
parameters.put("notify_url", notify_url); //返回地址
parameters.put("trade_type", trade_type); //交易类型
parameters.put("spbill_create_ip", spbill_create_ip); //手机ip
String sign = WXSignUtils.createSign("UTF-8", parameters);
System.out.println("签名:"+sign);
Unifiedorder unifiedorder = new Unifiedorder();
unifiedorder.setAppid(appid);
unifiedorder.setMch_id(mch_id);
unifiedorder.setNonce_str(nonce_str);
unifiedorder.setSign(sign);
unifiedorder.setBody(body);
unifiedorder.setOut_trade_no(out_trade_no);
unifiedorder.setTotal_fee(total_fee);
unifiedorder.setSpbill_create_ip(spbill_create_ip);
unifiedorder.setTime_start(time_start);
unifiedorder.setTime_expire(time_expire);
unifiedorder.setNotify_url(notify_url);
unifiedorder.setTrade_type(trade_type);
//unifiedorder.setTimeStamp(timeStamp);
//xml解析
String xmlInfo = HttpXmlUtils.xmlInfo(unifiedorder);
String wxUrl = WXSignUtils.WXURL;
String method =WXSignUtils.METHOD;
String weixinPost = HttpXmlUtils.httpsRequest(wxUrl, method, xmlInfo).toString();
System.out.println("weixinPost:"+weixinPost);
ParseXMLUtils.jdomParseXml(weixinPost);
model.put("weixinPost", weixinPost);
model.put(SysConstant.OP_FLAG, true);
model.put(SysConstant.OP_MESSAGE, SysConstant.SUCCESS);
}catch(Exception e){
e.printStackTrace();
model.put(SysConstant.OP_FLAG, false);
model.put(SysConstant.OP_MESSAGE, SysConstant.Exception);
}
return model;
}
}
上面方法所调用的工具类
/**
* 签名算法sign
*/
public class WXSignUtils {
private static String Key = "W7IvC8FYCmUlsigWks48P********"; //此处为在微信公众平台上申请的各个参数,按顺序要求填写在下方即可
public static final String APPID="wx06440c98****";
public static final String MCH_ID="14223*****";
public static final String NOTIFY_URL=CommonUtil.WEBSITE+"GetWxNotifyUrlController/payNotifyUrl.json"; //调用微信支付传递参数的路径
public static final String TRADE_TYPE="APP";
public static final String WXURL="https://api.mch.weixin.qq.com/pay/unifiedorder";
public static final String METHOD="POST";
/**
* 微信支付签名算法sign
* @param characterEncoding
* @param parameters
* @return
*/
@SuppressWarnings("rawtypes")
public static String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
StringBuffer sb = new StringBuffer();
Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序(升序)
Iterator it = es.iterator();
while(it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
String k = (String)entry.getKey();
Object v = entry.getValue();
if(null != v && !"".equals(v)
&& !"sign".equals(k) && !"key".equals(k)) {
sb.append(k + "=" + v + "&");
}
}
sb.append("key=" + Key);
System.out.println("字符串拼接后是:"+sb.toString());
String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
return sign;
}
//生成时间的工具类
public class RandCharsUtils {
private static SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
public static String getRandomString(int length) {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
Random random = new Random();
StringBuffer sb = new StringBuffer();
int number = 0;
for (int i = 0; i < length; i++) {
number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
/*
* 当前时间
*/
public static String timeStart(){
return df.format(new Date());
}
/*
* 30分钟有效期
*/
public static String timeExpire(){
Calendar now=Calendar.getInstance();
now.add(Calendar.MINUTE,30);
return df.format(now.getTimeInMillis());
}
}
以上类和方法就是需要APP端按参数要求请求数据,通过以上方法就可以想微信发起支付请求了。
下面要接受微信发送回来的回调参数,服务器要接受参数,并更新因支付而产生各个参数的变化
@Controller
@RequestMapping("/GetWxNotifyUrlController")
public class GetWxNotifyUrlController {
protected static final Logger LOG = LoggerFactory
.getLogger(GetWxNotifyUrlController.class);
@Resource
private ZlGoodCartService zlGoodCartService;
@Resource(name="ZlGoodAccountService")
private ZlGoodAccountService zlGoodAccountService;
@RequestMapping("/payNotifyUrl.json")
@ResponseBody
public String payNotifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
BufferedReader reader = null;
reader = request.getReader();
String line = "";
String xmlString = null;
StringBuffer inputString = new StringBuffer();
while ((line = reader.readLine()) != null) {
inputString.append(line);
}
xmlString = inputString.toString();
request.getReader().close();
System.out.println("----接收到的数据如下:---" + xmlString);
Map<String, String> map = new HashMap<String, String>();
String result_code = "";
String return_code = "";
String out_trade_no = "";
map = XMLUtil.doXMLParse(xmlString);
result_code = map.get("result_code");
out_trade_no = map.get("out_trade_no");
return_code = map.get("return_code");
//此处为接收微信回调后的参数进行“验签”,如果通过后进行状态的更新
if (checkSign(xmlString)) {
//此处方法省略,可根据"out_trade_no"订单流水号,更新订单信息,比如销售量的增加,库存量的减少等等……
return returnXML(result_code);
} else {
return returnXML("FAIL");
}
}
//验签方法
private boolean checkSign(String xmlString) {
Map<Object, Object> map = null;
try {
map = XMLUtil.doXMLParse(xmlString);
} catch (Exception e) {
e.printStackTrace();
}
String signFromAPIResponse = map.get("sign").toString();
if (signFromAPIResponse == "" || signFromAPIResponse == null) {
System.out.println("API返回的数据签名数据不存在,有可能被第三方篡改!!!");
return false;
}
System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
//清掉返回数据对象里面的Sign数据(不能把这个数据也加进去进行签名),然后用签名算法进行签名
map.put("sign", "");
//将API返回的数据根据用签名算法进行计算新的签名,用来跟API返回的签名进行比较
String signForAPIResponse = getSign(map);
if (!signForAPIResponse.equals(signFromAPIResponse)) {
//签名验不过,表示这个API返回的数据有可能已经被篡改了
System.out.println("API返回的数据签名验证不通过,有可能被第三方篡改!!! signForAPIResponse生成的签名为" + signForAPIResponse);
return false;
}
System.out.println("恭喜,API返回的数据签名验证通过!!!");
return true;
}
//返回xml格式串
private String returnXML(String return_code) {
return "<xml><return_code><![CDATA["
+ return_code
+ "]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
}
//获取签名
public String getSign(Map<Object, Object> map) {
SortedMap<Object, Object> signParams = new TreeMap<Object, Object>();
for (Map.Entry<Object, Object> stringStringEntry : map.entrySet()) {
signParams.put(stringStringEntry.getKey(), stringStringEntry.getValue());
}
signParams.remove("sign");
String sign = WXSignUtils.createSign("UTF-8", signParams);
return sign;
}
}
通过以上两部分应该就可以完成微信支付的后台操作,还有些细节我并没有完全记录,也怪我能力一般,水平有限,希望能为您提供一点点帮助也算好的,千万别误导了朋友们,这是我第一次记录的内容,我还会继续努力,相信会越来越好!
- APP微信支付后台内容小结
- 微信APP支付-Java后台实现
- APP微信支付的后台实现
- 微信APP支付,后台回调
- App微信支付 php后台接口
- 微信APP支付-Java后台实现
- 微信APP支付-Java后台实现
- 微信支付小结
- 支付--微信APP支付
- 微信支付app
- 微信支付app
- 微信APP支付
- app微信支付
- APP微信支付
- app微信支付
- 微信APP支付
- 支付--微信APP
- 微信APP支付
- USACO——双重回文数
- basetsd.h(72): error C2371: “INT32”: 重定义;不同的基类型
- apply和call要点总结
- 用 AsyncDisplayKit 開發響應式 iOS App
- 【maven】---初识
- APP微信支付后台内容小结
- 关于编码与乱码问题
- USACO——混合牛奶
- java字符编码问题
- 使用net.sf.json库进行json反序列化时存在的问题
- gulp+webpack工具整合简介
- 寒假篇36
- Spring+JDBC编程
- Apache与Tomcat 区别联系