微信公众平台H5支付

值得注意的是openid值的获取, 直接贴代码这里输入代码`

    /**
     * 微信统一下单
     * 
     * @param fenpay
     * @param orderStr
     * @return
     */
    private String placOrder(int fenpay, String orderStr, String subject) {
        Object openid = WebUtils.getSessionAttribute("openid");
        if (openid == null) {
            throw new ServiceException("没有获得微信授权,不能使用微信支付");
        }
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        SortedMap<String, String> sm = new TreeMap<String, String>();
        // 添加三个固定的参数
        sm.put("appid", WeiXinUtil.APPID);
        sm.put("mch_id", WeiXinUtil.MCH_ID);
        sm.put("notify_url", WeiXinUtil.NOTIFY_URL);
        sm.put("trade_type", WeiXinUtil.TRADE_TYPE);
        sm.put("nonce_str", RandomStringGenerator.getRandomStringByLength(8));
        sm.put("body", subject);
        sm.put("out_trade_no", orderStr);
        sm.put("total_fee", String.valueOf(fenpay));
        sm.put("spbill_create_ip", "127.0.0.1");
        // 现在写死的
        // sm.put("openid", "oMEZLt3zK-GrAnkHRsHxKOaDONpM");
        //
        String openidStr = openid.toString();
        sm.put("openid", openidStr);
        getLogger().debug("opendid:" + openid);
        String sign = WeiXinUtil.createSign(sm);
        getLogger().debug("sign:" + sign);
        String xml = XmlUtil.createXml(sm, sign);
        getLogger().debug("post:" + xml);
        String result = HttpClientUtil.postXML(url, xml);
        getLogger().debug("result:" + result);
        Map<String, String> xmlmap = XmlUtil.parseXml(result);
        // 返回预支付标识
        String prepay_id = xmlmap.get("prepay_id");
        // 凡是拿不到prepay_id都统统归结为下单失败
        if (StringUtils.isEmpty(prepay_id)) {
            throw new ServiceException("微信下单失败");
        }
        return "prepay_id=" + prepay_id;
    }

我是通过授权跳转的方式获取openid,即在点击“去支付”按钮的时候跳转到微信平台进行自动授权然后跳转会指定页面,也可在系统登录的时候就进行授权跳转。贴代码注意加粗代码即可。还是推荐看文档 授权跳转 页面跳转授权

<a href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${payUrl2}&response_type=code&state=${user.uid}&scope=snsapi_base" class="paymentbtn">

redirect_uri为你要授权之后跳转回来的url

    /**
     * 
     * 活动报名
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    public String payApply() {
        Map<String, Object> user = (Map<String, Object>) WebUtils.getSessionAttribute("user");
**        // 获得微信支付返回来的state,用来存储登录用户的uid这个时候重新从接口中
        String state = WebUtils.getParameter("state");**
        getLogger().info("获取授权之后的state" + state);
        if (user == null && StringUtils.isNotEmpty(state)) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("uid", state);
            String userStr = HttpClientUtil.doGet("http://120.24.240.104/bikeapi/?m=user&a=get_user", map);
            user = (Map<String, Object>) JSON.parse(userStr);
            ActionContext.getContext().getSession().put("user", user);
        }

        if (getActivityId() == null) {
            return "activityerror";
        }
        Activity av = activityService.findById(getActivityId());
        setActivity(av);
**        // 获得用户的openid,支付的时候需要用到
        String code = WebUtils.getParameter("code");**
        // String code = "021ed6c6c2f9b4689e166d7d0ea9caaD";
        if (StringUtils.isEmpty(code)) {
            // 不能获得支付授权
            setMsg("获得微信支付授权失败,不能使用微信支付");
        } else {
**            // ------------一下为获取openid的代码
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("appid", WeiXinUtil.APPID);
            map.put("secret", WeiXinUtil.APPSECRET);
            map.put("code", code);
            map.put("grant_type", "authorization_code");
            try {
                // 授权字符串
                String authStr = HttpClientUtil.doPost(url, map);
                JSONObject json = new JSONObject(authStr);
                String openid = json.getString("openid");
                // 把他set到session中,这应该是最简单的了吧
                WebUtils.getSession().setAttribute("openid", openid);**
            } catch (Exception e) {
                e.printStackTrace();
                setMsg("获得微信支付授权失败,不能使用微信支付");
            }
        }
        // 没有登录不能报名
        if (user != null) {
            // 查询当前用户的余额,如果查不到那么就是0元咯
            BigDecimal balance = userService.findBalanceByUid(Long.valueOf(user.get("uid").toString()));
            this.setUserBalance(balance);
            return "payapply";
        } else {
            fromUrl = "/index/index!login.action?from_url=/activity/activity!apply.action?id="
                    + String.valueOf(getActivityId());
            return "login";
        }
    }

好的,完成了统一下单之后你应该获取到一个package格式为prepay_id=123456789这样子的订单信息,那么接下来就可以在页面发起支付请求了。 刚开始的时候我按照文档的发起H5支付,结果怎么调试都不成功,相信很多朋友也是在这个地方遇到问题 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7 这个应该是官方文档没更新的原因,新版的微信中已经支持这种发起支付调用,而应该采用JSSDK发起支付请求。直接看到支付的api 输入链接说明 输入图片说明 遇到不懂的地方或者缺少的参数请往上看文档。 主要具体步骤有 输入图片说明

最后贴一下我的发起支付的页面代码,我只能帮你们到这里了,剩下的就是调试了。

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ include file="/common/header.jsp" %>
<title>微信支付</title>
<link rel="stylesheet" type="text/css" href="css/activity.css">
<script type="text/javascript" charset="UTF-8" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">

function pay(){
    var appId = $('#appId').val();
    var timeStamp = $('#timeStamp').val();
    var nonceStr = $('#nonceStr').val();
    var pk = $('#package').val();
    var signType = $('#signType').val();
    var paySign = $('#paySign').val();
    //config
    var timeStamp2 = $('#timeStamp2').val();
    var nonceStr2 = $('#nonceStr2').val();
    var signature = $('#signature').val();
    //
    var activityId = $('#activityId').val();

    wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: appId, // 必填,公众号的唯一标识
        timestamp:timeStamp2 , // 必填,生成签名的时间戳
        nonceStr: nonceStr2, // 必填,生成签名的随机串
        signature: signature,// 必填,签名,见附录1
        jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
    });
    wx.ready(function(){
        // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
        wx.chooseWXPay({
            timestamp: timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
            nonceStr: nonceStr, // 支付签名随机串,不长于 32 位
            package: pk, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
            signType: signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
            paySign: paySign, // 支付签名
            complete: function (res) {
                // 支付成功后的回调函数
                location.href=basePath+'/activityorder/activity-order!list.action?activityId='+activityId;
            }
        });
    });
}
</script>
</head>
<body onload="pay()">
    <input id="activityId" type="hidden" value="${activityId}" />

    <input id="appId" type="hidden" value="${payparam.appId}" />
    <input id="timeStamp" type="hidden" value="${payparam.timeStamp}" />
    <input id="nonceStr" type="hidden" value="${payparam.nonceStr}" />
    <input id="package" type="hidden" value="${payparam.package1}" />
    <input id="signType" type="hidden" value="${payparam.signType}" />
    <input id="paySign" type="hidden" value="${payparam.paySign}" />

    <input id="timeStamp2" type="hidden" value="${apijsmap.timestamp}" />
    <input id="nonceStr2" type="hidden" value="${apijsmap.noncestr}" />
    <input id="signature" type="hidden" value="${apijsmap.signature}" />
</body>
</html>

最后记得在公众平台的公众权限配置,你发起支付的页面一定要是在公众平台设置了授权的页面,调用jsjdk的页面也要授权了的。至于具体要哪些授权,地方太多了慢慢找吧。

Visual Studio 2017 ASP.NET Core开发

Visual Studio 2017 ASP.NET Core开发,Visual Studio 2017 已经内置ASP.NET Core 开发工具.

在选择.NET Core 功能安装以后就可以进行ASP.NET Core开发。

新的ASP.NET Core项目为csproj ,打开之前的xproj项目,会提示单向升级,确认以后,会自动帮你升级至csproj。

 

新建项目

VS 2017新建ASP.NET Core 项目:

 

确定以后

可选择ASP.NET Core 1.0 和ASP.NET Core 1.1 ,以及启用Docker支持。

以下是ASP.NET Core 1.1 启用Docker支持 项目结构。

项目就可以运行在Docker 上,如果想在Docker调试等须在本地安装Docker。

ASP.NET Core 1.1  增加了一些新的特性。比如: WebSockets 支持。

安装 Microsoft.AspNetCore.WebSockets 包,然后在Startup 类Configure 方法中添加:

app.UseWebSockets();

具体可以看官方文档:

https://docs.microsoft.com/en-us/aspnet/core/aspnetcore-1.1#choosing-between-versions-10-and-11-of-aspnet-core

.NET Core csproj 支持

在项目的csproj文件中,你可以注意到项目的引用极大简化。

右键编辑csproj 文件:

复制代码
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <PropertyGroup>
    <PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
    <DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.0" />
  </ItemGroup>

</Project>
复制代码

 

PackageReference 为NuGet 包

DotNetCliToolReference 为增强 dotnet 命令行工具

 

发布应用程序

在项目上右键选择 发布 ,接着选择文件夹

点击发布如下:

目标位置后面的设置中可以进行具体的一些设置。

 

推荐Visual Studio 2017 扩展

开发ASP.NET Core ,下面两个扩展推荐安装:

 编辑的csproj文件推荐NuGet 安装包: Project File Tools

https://marketplace.visualstudio.com/items?itemName=ms-madsk.ProjectFileTools

ASP.NET Core Tag Helpers 智能提示:Razor Language Services

https://marketplace.visualstudio.com/items?itemName=ms-madsk.RazorLanguageServices

可以根据上面地址下载下来安装,也可以在 工具->扩展和更新 中搜索安装:

 

以下再推荐两款VS 2017 扩展:

Web Essentials Web开发利器:

https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebExtensionPack2017

Productivity Power Tools 2017 效率开发:

https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.ProductivityPowerPack2017

 

由于VS2017 刚出正式版,问题还是存在一些。

具体可以去 https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes#a-idknownissues-aknown-issues 查看。

你如果遇到问题,可以点击右上方发送反馈报告问题。

 

参考文档:https://blogs.msdn.microsoft.com/webdev/2017/03/07/announcing-visual-studio-2017/

 

如果你觉得本文对你有帮助,请点击“推荐”,谢谢。

ASP.NET Core实践交流群: 133144964

.NET Core 跨平台交流群: 550897034
博客示例代码GitHub:https://github.com/linezero/Blog
分类: ASP.NET Core