C#+Hybrid App(Android)实现微信APP支付

原创 2016年02月18日 13:14:00

之前一直在做Hybrid App(也就是用Android或者IOS的WebView控件嵌入你的H5应用,看起来跟原生应用一样),支付这块有用到第三方的WAP支付,效果还行,就是微信这块收款不能直接跟客户的账户对接,因为WebView允许H5应用利用Javascript呼叫原生应用,所以决定开发Hybrid App下的微信APP支付。


开发微信APP支付,首先要看腾讯给的开发文档。由于新旧接口差异巨大,所以走了不少弯路(大家说微信开发就是一个巨坑也是有道理),但最重要看官方文档,照着他的文档走应该是没错的,只是有些细节不完整。


好,闲话有点多,开始转入正题。微信APP支付大概流程是:服务器端生成预支付ID,然后APP端取得预支付ID后丢给微信SDK去呼叫微信支付。要进行微信APP支付开发,首先得通过微信公众号认证,然后注册开放平台,最后注册商户平台。公众号是基础,开放平台是管理APP信息的,商户平台相当于支付宝,是管理钱的地方。


开发前的准备

微信公众平台:https://mp.weixin.qq.com/cgi-bin/loginpage?t=wxm2-login&lang=zh_CN

微信开放平台:https://open.weixin.qq.com/

微信商户平台:https://pay.weixin.qq.com/index.php/home/login

开发文档:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_1


公众平台应该是必备的,要申请服务号,每年300块钱。


开放平台是创建应用的地方,生成AppID后面会用到,如下图:



商户平台有两个东西会用到,一个是Partner ID,就是微信支付商户号;一个是Key,就是对商户平台的登录密码进行MD5加密后得到的字串,到API安全>>API密钥>>设置密钥,把这个MD5字串填进去保存就行了,如下图:



1.Android原生应用加入微信SDK

这一步很简单,只要把微信SDK引入你的项目,然后调用就可以了,如下图:



调用代码如下:

			@JavascriptInterface
			public void setWxPay(String appId,String partnerId,String prepayId,String nonceStr,String timeStamp,String packageValue,String sign) {

				api = WXAPIFactory.createWXAPI(this, appId);

				api.registerApp(appId);	//注册APP到微信
				
				Toast.makeText(MainActivity.this, "获取订单中,请稍等...", Toast.LENGTH_SHORT).show();
		        try{
					if(appId!="" && prepayId!=""){
						PayReq req = new PayReq();
						req.appId			= appId;
						req.partnerId		= partnerId;
						req.prepayId		= prepayId;
						req.nonceStr		= nonceStr;
						req.timeStamp		= timeStamp;
						req.packageValue	= packageValue;
						req.sign			= sign;
						req.extData			= "app data";
						Toast.makeText(MainActivity.this, "正常调起支付", Toast.LENGTH_SHORT).show();
						api.sendReq(req);
					}else{
			        	Log.d("PAY_GET", "服务器请求错误");
			        	Toast.makeText(MainActivity.this, "服务器请求错误", Toast.LENGTH_SHORT).show();
					}
		        }catch(Exception e){
		        	Log.e("PAY_GET", "异常:"+e.getMessage());
		        	Toast.makeText(MainActivity.this, "异常:"+e.getMessage(), Toast.LENGTH_SHORT).show();
		        }
			}


2.服务器端生成预支付ID(prepay_id),并调起支付接口

这一步是最重要也是最容易出问题的地方,错一个小小的地方也可能导致发起支付失败。


服务器端是用C#写的,因为我的H5应用也是C#写的(有点废话)。当我H5应用里一件商品下单后,先生成一条订单记录,状态还是未支付的,这时候已经有了商品的名称、价格等商品信息。我们用这个商品的信息发送给微信支付,让它先生成一个预支付的订单,这个叫“统一下单”。


这里用到了网上大神的一些代码,原文是:http://www.cnblogs.com/vinsonLu/p/4345041.html

主要代码如下:

 /// <summary>
    /// 支付方法
    /// </summary>
    private void WxPay()
    {
        string appId = "这里填AppID";
        string partnerId = "这里填微信支付商户号";
        string key = "这里填MD5加密的字串";
        string body = txtProductName.Text.Trim();
        string orderNumber = DateTime.Now.ToString("yyyyMMddHHmmss");
        int price = int.Parse(txtPrict.Text.Trim());

        UnifiedOrder order = new UnifiedOrder();
        order.appid = appId;
        order.mch_id = partnerId;
        order.nonce_str = TenpayUtil.getNoncestr();
        order.body = body;
        order.out_trade_no = orderNumber;
        order.total_fee = price;    //单位是分
        order.spbill_create_ip = Page.Request.UserHostAddress;
        order.notify_url = "http://www.yourdomain.com/notify.aspx";
        order.trade_type = "APP";

        TenpayUtil tu = new TenpayUtil();

        string prepayId = tu.getPrepay_id(order, key);
        string nonceStr = order.nonce_str;
        string timeStamp = TenpayUtil.getTimestamp();
        string packageValue = "Sign=WXPay";

        SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
        sParams.Add("appid", appId);
        sParams.Add("noncestr", nonceStr);
        sParams.Add("package", packageValue);
        sParams.Add("partnerid", partnerId);
        sParams.Add("prepayid", prepayId);
        sParams.Add("timestamp", timeStamp);
        string sign = tu.getsign(sParams, key);
        
        //调用前台JS
        RunScript(this, "", "SetWxPay('" + appId + "','" + partnerId + "','" + prepayId + "','" + nonceStr + "','" + timeStamp + "','" + packageValue + "','" + sign + "');");
    }

    /// <summary>
    /// 执行一条JavaScript函数
    /// </summary>
    /// <param name="page">WEB窗体页</param>
    /// <param name="key">标示脚本块的唯一键</param>
    /// <param name="script">脚本内容</param>
    public static void RunScript(System.Web.UI.Page page, string key, string script)
    {
        page.ClientScript.RegisterStartupScript(page.GetType(), key, "<script language = 'javascript'>" + script + "</script>");
    }

3.获取微信支付结果返回信息

当你支付后,微信会将支付结果以XML的方式返回给你指定的路径,上面写的是http://www.yourdomain.com/notify.aspx,这个地址必须是可以访问的,并且不能带参数。

特别提醒:商户系统对于支付结果通知的内容一定要做签名验证,防止数据泄漏导致出现“假通知”,造成资金损失。

主要代码如下:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string data = "";

            try
            {
                //接收并读取POST过来的XML文件流
                StreamReader reader = new StreamReader(Request.InputStream);
                String xmlData = reader.ReadToEnd();

                data = xmlData;
            }
            catch { }

            if (GetWxKeyValue(data, "return_code") == "SUCCESS")
            {
                //这里是支付成功的信息,下面你可以自由发挥了,比如写入数据库,更改状态等
                //其他信息请参考https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_7&index=3
            }
        }
    }

    private string GetWxKeyValue(string data, string key)
    {
        string value = "";
        SortedDictionary<string, string> requestXML = GetInfoFromXml(data);
        foreach (KeyValuePair<string, string> k in requestXML)
        {
            if (k.Key == key)
            {
                value = k.Value;
                break;
            }
        }
        return value;
    }

    /// <summary>
    /// 把XML数据转换为SortedDictionary<string, string>集合
    /// </summary>
    /// <param name="strxml"></param>
    /// <returns></returns>
    protected SortedDictionary<string, string> GetInfoFromXml(string xmlstring)
    {
        SortedDictionary<string, string> sParams = new SortedDictionary<string, string>();
        try
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xmlstring);
            XmlElement root = doc.DocumentElement;
            int len = root.ChildNodes.Count;
            for (int i = 0; i < len; i++)
            {
                string name = root.ChildNodes[i].Name;
                if (!sParams.ContainsKey(name))
                {
                    sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
                }
            }
        }
        catch { }
        return sParams;
    }

到此,微信支付就可以工作了,至于查询订单、退款的以后有时间再研究。


源码下载:http://pan.baidu.com/s/1mhtW7cG



c#/.net 微信app支付服务器端demo

  • 2018年01月08日 10:11
  • 691KB
  • 下载

微信APP支付 C#

public static string CreateXML(string key, params string[] strs) { string stri...
  • baidu_26219069
  • baidu_26219069
  • 2016-09-09 10:55:16
  • 1636

C#微信支付统一下单 APP支付接口

 的说微信支付是坑  官方demo 少不说 配置也恶心  的确 坑了我一个多星期 终于搞定了 给大家分享下我是怎么做出来的 让新手少走弯路, 和大家一样接到要做这个功能我就开始各种百度找demo  也...
  • hejianxiong520
  • hejianxiong520
  • 2018-01-05 10:05:12
  • 437

微信支付 APP 支付方式的服务器端处理程序

对于微信的APP的支付,客户服务说只能通过微信开放平台申请。后来在公众帐号确实发现了证据: 微信支付在申请的时候就比较严(麻烦),对服务类的一些支付,本来商品就是虚拟的,所以需要将商品描述的比较详细...
  • apensu
  • apensu
  • 2015-07-18 20:20:27
  • 21966

HBuilder webApp开发(八)微信/QQ/新浪登录

接着昨天的《HTML5 WebApp开发(七)微信/QQ/新浪分享》 继续写了一下第三方登录。 首先是去官方文档和Demo找,发现官方文档基本就是那些配置的说明,但是Demo就需要去github上...
  • zhuming3834
  • zhuming3834
  • 2016-06-19 10:54:54
  • 10914

浅析hybrid模式下地支付宝钱包和微信

开篇 近期一直在为插件式开发而不断探询,对于android端已经有一套插件式开发的框架,有通过java的反射机制实现的plugin,但目前我还没有找到一套完整的开源的框架,后期继续寻...
  • wenchao126
  • wenchao126
  • 2014-11-17 20:40:19
  • 4817

VS 2015跨平台移动开发简单感受

当听到微软开源了.net而且.net能支持安卓和IOS开发后,很是兴奋,不过今天安装测试了一下后,有点失落。基本上没什么创新,搞了一个嘘头而已。VS 2015支持C#开发IOS和安卓有两种方式:使用c...
  • aofengdaxia
  • aofengdaxia
  • 2014-12-12 10:45:15
  • 56243

c#/.net微信APP支付服务端开发Demo

  • 2016年08月29日 15:32
  • 417KB
  • 下载

微信支付——调用微信客户端支付之【服务端】开发详解

之前一篇提到微信支付的开发过程,写得有点乱,现在重新整理一下。 好了,说说到底该怎样一步一步分享处理。 解压从官网下载下来的开发说明文档(下载地址:https://mp.weixin.qq.com...
  • Seven_cm
  • Seven_cm
  • 2014-11-28 00:22:10
  • 206712

c#/.net支付宝支付和jsapi微信支付和app微信支付项目代码(源码和整个项目已上线)

  • 2017年08月29日 16:02
  • 2.45MB
  • 下载
收藏助手
不良信息举报
您举报文章:C#+Hybrid App(Android)实现微信APP支付
举报原因:
原因补充:

(最多只允许输入30个字)