微信h5支付

首先需要查看文档 知道h5支付的步骤

这里注意测试的时候需要用手机打开浏览器测试,如果用电脑的浏览器测试跳不出支付页面(可能是电脑检测不到微信)

h5支付很简单 h5支付不需授权直接调用统一下单微信支付结果通知-废话不多说直接上代码

1.前台页面

<!DOCTYPE HTML>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv=content-type>
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1">
<meta name="renderer" content="webkit">
<title>支付</title>
</head>
<body>
<a href="javascript:f_authcode();" style="color:#000;">公众号支付</a>
 <a href="javascript:f_test();" style="color:#000;">H5充值</a>
</body>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>

<script type=text/javascript>


function f_test(){
    $.ajax({
        url:"http://wx.hsjsns.com/v1/api/pay/MWEB/unifiedorder",
        contentType: "application/json",
        type:"post",
        //data:"{'id': " + openid +",'id': " + openid +",'id': " + openid +"}"
        data:JSON.stringify({money:"0.01",goods:"testH5充值",appid:"H5WG",account:"18068794602"}),//注释这些参数根据自己业务传
        dataType: "json",
        success: function(v_res){
        alert(JSON.stringify(v_res.data.mweb_url));
            console.log(v_res);
            if(v_res.code==0){
                //onBridgeReady(v_res.data);
                document.location.href=v_res.data.mweb_url;
            }
        }
    });
}
</script>

</html>

2.后台接口直接调用统一下单

@RestController
@RequestMapping(value = "v1/api")
public class WXApiController {

/**
* 微信支付统一下单
* @param order
* @return sn
*/
@RequestMapping(value = "/pay/{tradetype}/unifiedorder", method = RequestMethod.POST)
public ResponseEntity<JsonResult> unifiedorder (@PathVariable(value = "tradetype") String tradetype,@RequestBody(required=false) Map<String, String> order, HttpServletRequest request){
JsonResult r = null;
try {

if(!"JSAPI".equals(tradetype) && !"APP".equals(tradetype) && !"MWEB".equals(tradetype)) throw new ServiceException("微信支付交易类型有误!");
//请求验证
String ver_str = VerifyUtilsEx.verifyData(order, new String[] {"account","money","goods","appid"});

if(StringUtils.isNotBlank(ver_str)){
throw new ServiceException(ver_str);
}
String passback = order.containsKey("passback") ? order.get("passback") : "";

if("JSAPI".equals(tradetype) && !order.containsKey("openid")){
throw new ServiceException("公众号支付缺少openid");
}
String openid = order.containsKey("openid") ? order.get("openid") : "";
String ip = "";
//设定IP
if(order.containsKey("ip") && StringUtilsEx.IsIp(order.get("ip"))){
ip = order.get("ip");
}else{
ip = CommonUtilsEx.getIpAddr(request);
}

String moneystr = order.get("money");

Float money = Float.parseFloat(moneystr);

/**
* 首先创建订单
*/
String sn = wxApiService.createOrder(order.get("account"), money, order.get("goods"), order.get("appid"), ip, tradetype);//注释这个需要根据自己的业务区创建临时订单插入数据库,然后返回订单号

if(StringUtils.isBlank(sn)) throw new ServiceException("创建临时订单失败!");

Map<String, String> resData = null;

String callback = callback_domain+"pay/paycomplate";//微信支付结果通知


resData = wxApiService.unifiedorder_H5(openid, sn, money, order.get("goods"), passback, ip, callback);


r= new JsonResult("0", "", resData);
} catch(ServiceException se){
r= new JsonResult("-1", se.getMessage());

} catch (Exception e) {
r= new JsonResult("-2", "系统错误");
logger.error(e.getMessage());
e.printStackTrace();
}
return ResponseEntity.ok(r);
}

/**
* 微信支付结果通知
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/pay/paycomplate", method = RequestMethod.POST)
public ResponseEntity<String> paycomplate(HttpServletRequest request, HttpServletResponse response){
String inputLine;
String notityXml = "";
String resXml = WXCommonUtil.setXML("FAIL", "");


try {
while ((inputLine = request.getReader().readLine()) != null) {
notityXml += inputLine;
}
request.getReader().close();

logger.info("接收到的报文:" + notityXml);
SortedMap<String, String> res = WXCommonUtil.doXMLParse(notityXml);

//校验是否接收成功
if(res != null && !res.isEmpty() && "SUCCESS".equals(res.get("result_code"))){

//校验参数格式是否正确
if(!res.containsKey("sign") || !res.containsKey("out_trade_no") || !res.containsKey("openid") || !res.containsKey("transaction_id") || !res.containsKey("total_fee")){
resXml = WXCommonUtil.setXML("FAIL", "参数格式校验错误");
logger.error("wx/paycomplate:WARN: ---------------------参数格式校验错误");
}else{
String sign = WXCommonUtil.createSign(res);

String v_signString = res.get("sign");

//校验签名
if(sign.equals(v_signString)){
resXml = WXCommonUtil.setXML("SUCCESS", "OK");

String sn = res.get("out_trade_no");

String transaction_id = res.get("transaction_id");

Double money = Double.parseDouble(res.get("total_fee"));

String passback = res.get("attach");

//微信传递金额为分 故需要转为元 /100 
wxApiService.payComplate(sn, transaction_id, String.valueOf(money/100), passback);
}else{
resXml = WXCommonUtil.setXML("FAIL", "签名校验失败");
logger.error("wx/paycomplate:WARN: ---------------------签名校验失败");
//sysErrLogService.addErrInfo("WX_PAY", "签名校验失败", notityXml);
}
}

}else{
resXml = WXCommonUtil.setXML("FAIL", "报文为空");
logger.error("wx/paycomplate:WARN: ---------------------报文为空");
//sysErrLogService.addErrInfo("WX_PAY", "报文为空", "");
}

} catch (ServiceException se) {
logger.warn("wx/paycomplate:WARN:"+se.getMessage());
}catch (Exception e) {
//e.printStackTrace();
logger.error(e.getMessage());
e.printStackTrace();
}

return ResponseEntity.ok(resXml);

}

}

3.涉及到的工具类

public class WXCommonUtil {

public static String setXML(String return_code, String return_msg) {
    return "<xml><return_code><![CDATA[" + return_code
            + "]]></return_code><return_msg><![CDATA[" + return_msg
            + "]]></return_msg></xml>";

}



/**
* 解析接收到的xml报文
* @param strxml
* @return SortedMap
* @throws JDOMException
* @throws IOException
*/
public static SortedMap<String, String> doXMLParse(String strxml) throws JDOMException, IOException {  
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");  


        if(null == strxml || "".equals(strxml)) {  
            return null;  
        }  
          
        SortedMap m = new TreeMap();  
          
        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));  
        SAXBuilder builder = new SAXBuilder();  
        Document doc = builder.build(in);  
        Element root = doc.getRootElement();  
        List list = root.getChildren();  
        Iterator it = list.iterator();  
        while(it.hasNext()) {  
            Element e = (Element) it.next();  
            String k = e.getName();  
            String v = "";  
            List children = e.getChildren();  
            if(children.isEmpty()) {  
                v = e.getTextNormalize();  
            } else {  
                v = getChildrenText(children);  
            }  
              
            m.put(k, v);  
        }  
          
        //关闭流  
        in.close();  
          
        return m;  

}

/**
* @author Mark
* @Description:sign签名
* @param characterEncoding 编码格式
* @param parameters 请求参数
* @return
*/
public static String createSign(SortedMap<String,String> parameters){
    StringBuffer sb = new StringBuffer();
    Set es = parameters.entrySet();
    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 + "&");
        }
    }
    
    String key= "";
    
    if(parameters.containsKey("key") && StringUtils.isNotBlank(parameters.get("key"))){
    key = parameters.get("key");
    }else{//通过商户ID获取秘钥KEY
    WXConfigService service = SpringUtil.getBean(WXConfigService.class);
    key = service.getKeyByMchid(parameters.get("mch_id")); 
    }
    //System.out.println("WXCommUtile:------>> key:"+key);
    sb.append("key=" + key);
    System.out.println(sb);
    String sign = Md5UtilsEx.getMD5Str(sb.toString()).toUpperCase();
    return sign;
}

}

public class VerifyUtilsEx {

static String KEY = "RVqq0cifgVJCfeCSxnWU6LoyGIpwYOa6";
static long TIMESTAMP = 5*60; //时间戳5分钟 5*60

/**
* 接口必要参数签名验证
* @return String
* @throws UnsupportedEncodingException 
*/
public static String verifyParam(HttpServletRequest request,String[] args) throws UnsupportedEncodingException{
Map params = transToMAP(request.getParameterMap());
return verifyData(params,args);
}

public static String verifyData(Map<String, String> data,String[] args) throws UnsupportedEncodingException{

String sign = "";
String arg_cnt = "";
String msg = "";

if(data == null || data.isEmpty()) return "没有检索到参数!";

for(String arg : args){

if(data.keySet().contains(arg)){
if(data.get(arg)==null || !StringUtils.hasText(String.valueOf(data.get(arg)))){
msg = "参数【"+arg+"】未明确,请确认!";
break;
}

if("sign".equals(arg)){
sign = String.valueOf(data.get(arg));
}

if("ts".equals(arg)){
long systime = System.currentTimeMillis()/1000;

long v_ts = Long.parseLong(data.get(arg));
//时间戳校验
if(Math.abs(systime-v_ts) > TIMESTAMP){
msg = "请求超出有效期!";
break;
}
}
}else{
msg = "参数【"+arg+"】未明确,请确认!";
break;
}
}

//参数都已明确并需要签名验证
if(StringUtils.hasText(sign) && !StringUtils.hasText(msg)){
for(String arg1 : args){
if(!"sign".equals(arg1)){
arg_cnt += String.valueOf(data.get(arg1));
}
}


//System.out.println(URLEncoder.encode(arg_cnt+KEY,"utf-8"));
String v_sign = Md5UtilsEx.getMD5Str(URLEncoder.encode(arg_cnt+KEY,"utf-8").toLowerCase());
//System.out.println(v_sign);
if(!sign.toLowerCase().equals(v_sign.toLowerCase())){
msg = "校验码错误!";
}
}

return msg;
}

private static Map transToMAP(Map parameterMap) throws UnsupportedEncodingException{
      // 返回值Map
      Map returnMap = new HashMap();
      Iterator entries = parameterMap.entrySet().iterator();
      Map.Entry entry;
      String name = "";
      String value = "";
      while (entries.hasNext()) {
          entry = (Map.Entry) entries.next();
          name = (String) entry.getKey();
          Object valueObj = entry.getValue();
          if(null == valueObj){
              value = "";
          }else if(valueObj instanceof String[]){
              String[] values = (String[])valueObj;
              for(int i=0;i<values.length;i++){
                  value = values[i] + ",";
              }
              value = value.substring(0, value.length()-1);
          }else{
              value = valueObj.toString();
          }
          System.out.println(value);
          returnMap.put(name, value);
      }
      return  returnMap;
  }


}



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值