首页 文章 精选 留言 我的

精选列表

搜索[Java实现],共10022篇文章
优秀的个人博客,低调大师

关于微信支付和支付宝支付java实现

目前支付宝支付和微信支付是算是目前app的标配了 支付宝支付在更新过后有了官方专门的sdk和demo,所以相对而言比较简单,而微信支付稍微复杂一点,下面的文章会附实例代码,微信支付也是参考的github上的某位大神级人物的代码。 首先是微信支付 先准备各种数据,我一般都是放到配置类中,当然也可以放到数据库或者配置文件中 `public final class WxpayConfig { /** *商家可以考虑读取配置文件 */ //微信开发平台应用id public static final String APP_ID = "wx8888888888888888"; //财付通商户号 public static final String PARTNER = "1900000109";//app请求的商户号 public static final String MCHID = "1900000109";//预支付请求的商户号 //商户号对应的密钥 public static final String PARTNER_KEY = ""; //预支付接口 public static final String PREPAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //查询订单接口 public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; //签名算法常量值 public static final String SIGN_METHOD = "sha1"; //异步通知地址 public static final String NOTIFY_URL = “”; //交易类型 public static final String TRADE_TYPE = "APP"; //暂定包值 public static final String PACKAGE = "Sign=WXPay"; //返回状态成功 public static final String SUCCESS = "SUCCESS"; //返回状态失败 public static final String FAIL = "FAIL"; }` 这是关于微信支付的封装的工具类,其中httpclient和md5加密的需要自己去封装工具类 `public class WxpayUtil { /** *随机串 * @return */ public static String getNonceStr() { Random random = new Random(); return MD5Util.getMD5String(String.valueOf(random.nextInt(10000))); } /** *时间戳 * @return */ public static String getTimeStamp() { return String.valueOf(System.currentTimeMillis() / 1000); } /** *解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。 * @param strxml * @return * @throws JDOMException * @throws IOException */ @SuppressWarnings("unchecked") public static Map parseToMap(String strXml) throws JDOMException, IOException { strXml = strXml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\""); if(null == strXml || "".equals(strXml)) { return null; } Map m = new HashMap<>(); 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 = 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; } /** *获取子结点的xml * @param children * @return String */ @SuppressWarnings("unchecked") private static String getChildrenText(List children) { StringBuffer sb = new StringBuffer(); if(!children.isEmpty()) { Iterator it = children.iterator(); while(it.hasNext()) { Element e = it.next(); String name = e.getName(); String value = e.getTextNormalize(); List list = e.getChildren(); sb.append("<" + name + ">"); if(!list.isEmpty()) { sb.append(getChildrenText(list)); } sb.append(value); sb.append(""); } } return sb.toString(); } /** *只支持String,并且value非空 * @param map * @return */ public static String parseToXml(Map map){ StringBuffer sb = new StringBuffer(""); for(Map.Entry entry : map.entrySet()){ sb.append("<"+entry.getKey()+">"); sb.append(""); sb.append(""); } sb.append(""); return sb.toString(); } /** * POST提交XML对象 * @param document */ public static String postXmlClient(String url,String xmlParams) throws Exception { // return HttpUtils.postXmlEntity(url, xmlParams).getContent(); return HttpClient.postRequest(url, xmlParams); } } 这是关于微信支付一些参数处理的方法 public class WxpayHelper { /** *除去数组中的空值和签名参数 * @param sArray签名参数组 * @return去掉空值与签名参数后的新签名参数组 */ public static Map paraFilter(Map sArray) { Map result = new HashMap(); if (sArray == null || sArray.size() <= 0) { return result; } for (String key : sArray.keySet()) { String value = sArray.get(key); if (value == null || value.equals("") || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("key")) { continue; } result.put(key, value); } return result; } /** *把数组所有元素,并按照“参数=参数值”的模式用“&”字符拼接成字符串 * @param params需要参与字符拼接的参数组 * @param sorts 是否需要排序 true 或者false * @return拼接后字符串 */ public static String createLinkString(Map params) { List keys = new ArrayList(params.keySet()); Collections.sort(keys); String prestr = ""; for (int i = 0; i < keys.size(); i++) { String key = keys.get(i); String value = params.get(key); if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符 prestr = prestr + key + "=" + value; } else { prestr = prestr + key + "=" + value + "&"; } } return prestr; } /** *验签响应签名 * @param paras * @return */ public static boolean verify(Map paras){ String sign = paras.get("sign"); if(StringUtils.isBlank(sign)) return false; return sign.equals(WxpayBuilder.buildRequestMysign(paraFilter(paras))); } /** *响应成功 * @param loggerAgent -日志代理 * @return String */ /*public static String yes(ILoggerAgent loggerAgent){ Map return_wx = new HashMap<>(); return_wx.put("return_code", WxpayConfig.SUCCESS); loggerAgent.payParamsLogger(null , "WX-NOTIFY", false, return_wx); return WxpayUtil.parseToXml(return_wx); }*/ } public class WxpayBuilder { /** *生成签名结果 * @param sPara要签名的数组 * @return签名结果字符串 */ public static String buildRequestMysign(Map sPara) { String prestr = WxpayHelper.createLinkString(sPara)+"&key="+WxpayConfig.PARTNER_KEY; LogFactory.getInstance().getLogger().debug("微信支付签名的字符串:"+prestr); return MD5Util.getMD5String(prestr).toUpperCase(); } public static Map buildRequestPara(Map sParaTemp) { //除去数组中的空值和签名参数 Map sPara = WxpayHelper.paraFilter(sParaTemp); //生成签名结果 String mysign = buildRequestMysign(sPara); LogFactory.getInstance().getLogger().debug("微信支付签名数据:"+mysign); //签名结果与签名方式加入请求提交参数组中 sPara.put("sign", mysign); return sPara; } }` 使用例程 其中业务接口信息,参考https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3 ` /** *微信订单逻辑 * * @throws Exception */ public Map wxPayLogic() throws Exception { //微信业务代码 Map xmlData = new HashMap(); xmlData.put("appid", WxpayConfig.APP_ID); xmlData.put("mch_id", WxpayConfig.MCHID); xmlData.put("nonce_str", WxpayUtil.getNonceStr()); xmlData.put("out_trade_no",); xmlData.put("total_fee",); xmlData.put("spbill_create_ip",“”); //从数据字典里面去主机地址 DataDictionary dataDictionary = dataDictionaryService.getDicByKey("PAY_CALLBACK"); xmlData.put("notify_url", dataDictionary.getValue() + WxpayConfig.NOTIFY_URL); xmlData.put("trade_type", WxpayConfig.TRADE_TYPE); xmlData.put("body", ""); //少写签名 Map result = WxpayBuilder.buildRequestPara(xmlData); // Map result = WxpayHelper.paraFilter(xmlData); String xmlParams = WxpayUtil.parseToXml(result); LogFactory.getInstance().getLogger().debug("微信支付请求报文:" + xmlParams); String xmlResult = WxpayUtil.postXmlClient(WxpayConfig.PREPAY_URL, xmlParams); Map map = WxpayUtil.parseToMap(xmlResult); LogFactory.getInstance().getLogger().debug("微信支付返回报文:" + JsonHelper.toJson(map)); //返回时SUCCESS if (WxpayConfig.SUCCESS.equals(map.get("return_code"))) { //验证返回是否成功 if (WxpayConfig.SUCCESS.equals(map.get("result_code"))) { //除去签名和空值 Map paraFilter = WxpayHelper.paraFilter(map); //获得签名 String mysign = WxpayBuilder.buildRequestMysign(paraFilter); //验证签名 if (mysign.equals(map.get("sign"))) { String prepay_id = map.get("prepay_id"); //验证签名成功 //进行操作 } else { //签名验证失败 LogFactory.getInstance().getLogger().debug("微信支付验证签名失败"); } } else { // result_code返回失败 String err_code = map.get("err_code"); String err_code_des = map.get("err_code_des"); chargeRecord.setCauses(err_code+err_code_des); LogFactory.getInstance().getLogger().debug("微信支付结果失败:失败码为"+err_code+",失败原因是"+err_code_des); chargeRecord.setState(2); } } else { // return_code返回失败 String return_msg = map.get("return_msg"); LogFactory.getInstance().getLogger().debug("微信支付返回失败:返回消息为:" + return_msg); return null; } //微信支付 Map mapBack = new HashMap<>(); mapBack.put("appid", WxpayConfig.APP_ID); mapBack.put("partnerid", WxpayConfig.PARTNER); mapBack.put("prepayid", chargeRecord.getOpenId()); mapBack.put("package", WxpayConfig.PACKAGE); mapBack.put("noncestr", WxpayUtil.getNonceStr()); mapBack.put("timestamp", WxpayUtil.getTimeStamp()); return WxpayBuilder.buildRequestPara(mapBack); }` 支付异步回传 接收到异步通知之后,才算是付款成功 `@Controller @RequestMapping(value = "/api") public class WxPayCallbackController extends BaseController { @Autowired OrderLogic orderLogic; @Autowired RedisFactory redisFactory; @Autowired ApplicationContext applicationContext; @RequestMapping(value = "/wxPayCallback", method = RequestMethod.POST) @ResponseBody public String wxPayCallback(@RequestBody String body) { MDC.put("seqID", SeqIdGenerator.generate());//日志序列 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付结果通知信息data=" + body); Map resultMap = new HashMap<>(); if (StringUtils.isNotBlank(body)) { try { Map map = WxpayUtil.parseToMap(body); //返回代码 if (WxpayConfig.SUCCESS.equals(map.get("return_code"))) { //验证签名 if (WxpayHelper.verify(map)) { //验证业务结果是否成功 String outTradeNo = map.get("out_trade_no"); if (WxpayConfig.SUCCESS.equals(map.get("result_code"))) { //设置支付类型,1为支付宝,2为微信 map.put("payType","2"); //通过所有验证,启动事件,通过spring的监听器进行监听,并执行付款成功后的业务 applicationContext.publishEvent(new OrderFinishEvent(map)); } else { //业务结果失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付业务结果失败"); orderLogic.updateState(outTradeNo,2); resultMap.put("return_code", WxpayConfig.SUCCESS); } } else { //签名失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付签名失败"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "签名失败"); } } else { //返回结果失败 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付返回结果失败"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "参数格式校验错误"); } } catch (Exception e) { e.printStackTrace(); } } else { //返回结果为空 LogFactory.getInstance().getPayCallbackLogger().info("参数格式校验错误"); resultMap.put("return_code", WxpayConfig.FAIL); resultMap.put("return_msg", "参数格式校验错误"); } return WxpayUtil.parseToXml(resultMap); } }` 付款成功统一处理事件监听 `@Component public class OrderFinishLister { @EventListener public void onApplicationEvent(OrderFinishEvent event){//这里不能抛出异常,外层无法处理,会造成中断 try { Map params = (HashMap) event.getSource(); String payType = params.get("payType"); String outTradeNo = params.get("out_trade_no"); String trade_no = null; String buyerLogonId = null; String buyerId = null; String transactionId = null; UserOrder order = null; if("1".equals(payType)){ //支付宝 trade_no = params.get("trade_no"); buyerLogonId = params.get("buyer_logon_id"); buyerId = params.get("buyer_id"); //执行付款成功后的业务逻辑 LogFactory.getInstance().getLogger().debug("支付宝获取支付更新状态:" + outTradeNo); }else if("2".equals(payType)){ //微信 transactionId = params.get("transaction_id"); //执行微信付款成功后的业务逻辑 LogFactory.getInstance().getLogger().debug("微信获取支付更新状态:" + outTradeNo); } }catch (Exception e){ e.printStackTrace(); } } }` 这就是单独的微信支付业务流程

优秀的个人博客,低调大师

JAVA实现调用微信js-sdk扫一扫

喜欢的朋友可以关注下。 已经很久没有给大家分享一片技术文章了,今天抽了点时间来,给大家说一说如何调用微信提供的扫一扫接口。 前提: 需要申请一个公众号:申请公众号需要的资料我就不说了,去申请微信会提示需要哪些。 准备appid(公众号的id) AppSecret (公众号的密钥) 正文: 首先,我们先来简单了解一下流程,详细的微信文档有说明。 获取Token→根据token获取Ticket→根据ticket签名→反会参数给前端→前端调起扫一扫接口 下面直接上代码 1.获取token /** * Description: 获取微信公众号token<BR> * * @author dsn * @date 2018年9月21日 上午9:53:26 * @param appid * @param secret * @return * @version 1.0 */ public static String getAccessToken(String appid, String secret) { String token = ""; String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret; JSONObject result = PayCommonUtil.httpsRequest(token_url, "POST"); if (result.get("access_token") != null) { token = result.get("access_token").toString(); } return token; } 2.获取ticket /** * Description: 获取微信ticket<BR> * * @author dsn * @date 2018年9月21日 上午9:54:03 * @param token * @return * @version 1.0 */ public static String getTicket(String token) { if ("".equalsIgnoreCase(token) || null == token) { return ""; } String ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + token + "&type=jsapi"; JSONObject result = PayCommonUtil.httpsRequest(ticket_url, "POST"); return result.get("ticket").toString(); } 3.签名 public static String getSign(String jsapi_ticket, String noncestr, Long timestamp, String url) throws NoSuchAlgorithmException { String shaStr = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "×tamp=" + timestamp + "&url=" + url; MessageDigest mDigest = MessageDigest.getInstance("SHA1"); byte[] result = mDigest.digest(shaStr.getBytes()); StringBuffer signature = new StringBuffer(); for (int i = 0; i < result.length; i++) { signature.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1)); } return signature.toString(); } 4.action中调用 /** * Description:微信扫一扫接口 <BR> * * @author ran.chunlin * @date 2017年4月11日 上午10:07:35 * @param request * @return * @throws Exception * @version 1.0 */ @RequestMapping(params = "method=getWechatSign", method = RequestMethod.GET) public @ResponseBody Map<String, Object> getWechatSign(HttpServletRequest request) throws Exception { /* 返回的json数据 */ Map<String, Object> jsonMap = new HashMap<>(); // 构成子数据map Map<String, Object> subJsonMap = new HashMap<>(); // 1.获取参数 String url = showNull(request.getParameter("url")); String t = showNull(request.getParameter("t")); String appId = showNull(request.getParameter("appId")); String appSecret = showNull(request.getParameter("appSecret")); if (url == null || t == null || appId == null || appSecret == null) { return json4Map(jsonMap, subJsonMap, "参数为空", STATUSCODE_FAILED_BADINPUT_PARAM); } else { String accessToken = WeiXinUtils.getAccessToken(appId, appSecret); String ticket = WeiXinUtils.getTicket(accessToken); Long timestamp = System.currentTimeMillis() / 1000; String nonceStr = RandomStringUtils.randomAlphanumeric(16); String sign = getSign(ticket, nonceStr, timestamp, url); subJsonMap.put("result", "1"); subJsonMap.put("timestamp", timestamp); subJsonMap.put("nonceStr", nonceStr); subJsonMap.put("appId", appId); subJsonMap.put("sign", sign); } return json4Map(jsonMap, subJsonMap, "获取sign成功", STATUSCODE_SUCCESS); } 5.前端代码 // 扫一扫 进入页面时去调用 $.ajax({ type : 'GET', url : "你action的url", data : { appId : "", appSecret : "", url : location.href, t : Math.random() }, success : function(json) { if (json.data.result == "1") { wxConfig(json.data.timestamp, json.data.nonceStr, json.data.sign, json.data.appId); } } }); function wxConfig(_timestamp, _nonceStr, _signature, _appId) { wx.config({ // debug : false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId : _appId, // 必填,公众号的唯一标识 timestamp : _timestamp, // 必填,生成签名的时间戳 nonceStr : _nonceStr, // 必填,生成签名的随机串 signature : _signature,// 必填,签名,见附录1 jsApiList : [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'scanQRCode' ] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); } //扫码调用 function scanCode() { wx.scanQRCode({ needResult : 1, scanType : [ "qrCode", "barCode" ], success : function(res) { console.log(res) //扫描返回的数据 var result = res.resultStr; }, fail : function(res) { layer.open({ content : '请稍后再试', skin : 'msg', time : 2 //2秒后自动关闭 }); } }); } 其实就是这么的简单 这里需要提醒大家 页面一定要引入 <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> 不然会调用不了微信的函数 如有需要可以加我Q群【308742428】大家一起讨论技术。 后面会不定时为大家更新文章,敬请期待。 喜欢的朋友可以关注下。

优秀的个人博客,低调大师

使用Java实现度分秒坐标转十进制度的实践

在地理信息系统(GIS)、导航、测绘等领域,精确地表示和转换地理位置坐标是一项基本而重要的任务。地理坐标通常以经度和纬度的形式表示,它们可以采用度分秒(DMS)或十进制度(DD)两种格式。度分秒是一种传统的表示方式,它将角度分为度、分和秒,而十进制度则以小数形式直接表示角度,更便于计算机处理。随着技术的发展,十进制度因其精确性和便捷性在现代应用中越来越受到青睐。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册