Beispiel #1
0
        /// <summary>
        /// 公共API => 测速上报
        /// 不需要证书
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_8
        ///应用场景
        ///商户在调用微信支付提供的相关接口时,会得到微信支付返回的相关信息以及获得整个接口的响应时间。为提高整体的服务水平,
        ///协助商户一起提高服务质量,微信支付提供了相关接口调用耗时和返回信息的主动上报接口,微信支付可以根据商户侧上报的数据进一步优化网络部署,完善服务监控,和商户更好的协作为用户提供更好的业务体验。
        /// </summary>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="device_info"> String(32) 微信支付分配的终端设备号,商户自定义</param>
        /// <param name="nonce_str">(必填) 随机字符串 随机字符串,不长于32位。</param>
        /// <param name="interface_url">String(127) 接口URL  上报对应的接口的完整URL,类似:
        ///https://api.mch.weixin.qq.com/pay/unifiedorder
        ///对于被扫支付,为更好的和商户共同分析一次业务行为的整体耗时情况,对于两种接入模式,请都在门店侧对一次被扫行为进行一次单独的整体上报,上报URL指定为:
        ///https://api.mch.weixin.qq.com/pay/micropay/total
        ///关于两种接入模式具体可参考本文档章节:被扫支付商户接入模式
        ///其它接口调用仍然按照调用一次,上报一次来进行。
        /// </param>
        /// <param name="execute_time_">Int  接口耗时   接口耗时情况,单位为毫秒 </param>
        /// <param name="return_code">String(16)  返回状态码   接口耗时情况,单位为毫秒 </param>
        /// <param name="return_msg">String(128)  返回信息    返回信息,如非空,为错误原因 :签名失败; 参数格式校验错误 </param>
        /// <param name="result_code">String(16)  业务结果    SUCCESS/FAIL </param>
        /// <param name="err_code">String(32)  错误代码   </param>
        /// <param name="err_code_des">String(128)  错误代码描述</param>
        /// <param name="out_trade_no">String(32)  商户订单号 商户系统内部的订单号,商户可以在上报时提供相关商户订单号方便微信支付更好的提高服务质量。 </param>
        /// <param name="user_ip">String(16)  访问接口IP   发起接口调用时的机器IP  </param>
        /// <param name="time">String(14)  商户上报时间 系统时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。 其他详见第4.2节时间规则:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_2  </param>
        /// <param name="partnerKey">API密钥</param>
        /// <returns> 参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_8 </returns>
        public static dynamic Report(string appid, string mch_id, string device_info, string nonce_str,
                                     string interface_url, string execute_time_,
                                     string return_code, string return_msg, string result_code, string err_code,
                                     string err_code_des, string out_trade_no, string user_ip, string time,
                                     string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("device_info", device_info);
            stringADict.Add("nonce_str", nonce_str);
            stringADict.Add("interface_url", interface_url);
            stringADict.Add("execute_time_", execute_time_);
            stringADict.Add("return_code", return_code);
            stringADict.Add("return_msg", return_msg);
            stringADict.Add("result_code", result_code);
            stringADict.Add("err_code", err_code);
            stringADict.Add("err_code_des", err_code_des);
            stringADict.Add("out_trade_no", out_trade_no);
            stringADict.Add("user_ip", user_ip);
            stringADict.Add("time", time);

            var sign     = Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/pay/refundquery";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #2
0
        /// <summary>
        /// 公共API => 下载对账单
        /// 不需要证书
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_6
        ///应用场景
        ///商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。
        ///注意:
        ///1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致,bill_type为REVOKED;
        ///2.微信在次日9点启动生成前一天的对账单,建议商户10点后再获取;
        ///3.对账单中涉及金额的字段单位为“元”。
        /// </summary>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="device_info"> String(32) 微信支付分配的终端设备号,商户自定义</param>
        /// <param name="nonce_str">(必填) 随机字符串 随机字符串,不长于32位。</param>
        /// <param name="bill_date">String(8) 对账单日起 下载对账单的日期,格式:20140603 </param>
        /// <param name="bill_type">String(8) 账单类型  ALL,返回当日所有订单信息,默认值 SUCCESS,返回当日成功支付的订单; REFUND,返回当日退款订单; REVOKED,已撤销的订单 </param>
        /// <param name="partnerKey">API密钥</param>
        /// <returns>
        /// 成功时,数据以文本表格的方式返回,第一行为表头,后面各行为对应的字段内容,字段内容跟查询订单或退款结果一致,具体字段说明可查阅相应接口。
        /// 参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_6 </returns>
        public static dynamic Downloadbill(string appid, string mch_id, string device_info, string nonce_str,
                                           string bill_date, string bill_type,
                                           string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("device_info", device_info);
            stringADict.Add("nonce_str", nonce_str);
            stringADict.Add("bill_date", bill_date);
            stringADict.Add("bill_type", bill_type);

            var sign     = Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/pay/refundquery";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #3
0
        /// <summary>
        /// 公共API => 申请退款
        /// 需要双向证书
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_4
        ///应用场景
        ///当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
        ///注意:
        ///1.交易时间超过半年的订单无法提交退款;
        ///2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
        ///3.接口提交成功后,还需要在微信商户后台由商户管理员审核退款
        /// </summary>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="device_info"> String(32) 微信支付分配的终端设备号,商户自定义</param>
        /// <param name="nonce_str">(必填) 随机字符串 随机字符串,不长于32位。</param>
        /// <param name="transaction_id">String(32) 微信订单号 微信的订单号,优先使用 </param>
        /// <param name="out_trade_no">(transaction_id为空时必填) String(32) 商户订单号 transaction_id、out_trade_no二选一,如果同时存在优先级:transaction_id> out_trade_no </param>
        /// <param name="out_refund_no">(必填) String(32) 商户退款单号 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔 </param>
        /// <param name="total_fee">(必填) int 总金额 订单总金额,单位为分,只能为整数。 </param>
        /// <param name="refund_fee">(必填) int  退款金额 退款总金额,订单总金额,单位为分,只能为整数</param>
        /// <param name="refund_fee_type">String(8) 货币种类 符合ISO 4217标准的三位字母代码,默认人民币:CNY</param>
        /// <param name="op_user_id">(必填) String(32) 操作员 操作员帐号, 默认为商户号mch_id </param>
        /// <param name="partnerKey">API密钥</param>
        /// <returns> 参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_4 </returns>
        public static dynamic Refund(string appid, string mch_id, string device_info, string nonce_str,
                                     string transaction_id, string out_trade_no, string out_refund_no,
                                     int total_fee, int refund_fee, string refund_fee_type, string op_user_id,
                                     string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("device_info", device_info);
            stringADict.Add("nonce_str", nonce_str);
            stringADict.Add("transaction_id", transaction_id);
            stringADict.Add("out_trade_no", out_trade_no);
            stringADict.Add("out_refund_no", out_refund_no);
            stringADict.Add("total_fee", total_fee.ToString());
            stringADict.Add("refund_fee", refund_fee.ToString());
            stringADict.Add("refund_fee_type", refund_fee_type);
            stringADict.Add("op_user_id", op_user_id);

            var sign     = Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/secapi/pay/refund";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #4
0
        /// <summary>
        /// 提交被扫支付API
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=5_5
        /// 1.应用场景:收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。
        ///是否需要证书:不需要。
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="device_info"> String(32) 微信支付分配的终端设备号,商户自定义</param>
        /// <param name="nonce_str">(必填) String(32) 随机字符串,不长于32位</param>
        /// <param name="body">(必填) String(32) 商品描述 商品或支付单简要描</param>
        /// <param name="detail"> String(8192) 商品详情  商品名称明细列表</param>
        /// <param name="attach"> String(127) 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据</param>
        /// <param name="out_trade_no">(必填) String(32) 商家订单ID,32个字符内、可包含字母, 其他说明见第4.2节商户订单号:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_2 </param>
        /// <param name="fee_type">符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见第4.2节货币类型: http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_2 </param>
        /// <param name="total_fee">(必填) Int 订单总金额,只能为整数,详见第4.2节支付金额:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_2 </param>
        /// <param name="spbill_create_ip">(必填) String(32)终端IP APP和网页支付提交用户端IP,Native支付填调用微信支付API的机器IP。</param>
        /// <param name="time_start">String(14) 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。</param>
        /// <param name="time_expire">String(14) 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。</param>
        /// <param name="goods_tag">String(32) 商品标记,代金券或立减优惠功能的参数,说明详见第10节代金券或立减优惠:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=10_1 </param>
        /// <param name="auth_code">String(128) 授权码 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 </param>
        /// <param name="partnerKey">API密钥</param>
        /// <returns>返回json字符串,格式参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=5_5 </returns>
        public static dynamic Submit(string appid, string mch_id, string device_info,
                                     string nonce_str, string body, string detail, string attach,
                                     string out_trade_no, string fee_type, int total_fee, string spbill_create_ip,
                                     string time_start, string time_expire, string goods_tag,
                                     string auth_code,
                                     string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("device_info", device_info);
            stringADict.Add("nonce_str", nonce_str);
            stringADict.Add("body", body);
            stringADict.Add("attach", attach);
            stringADict.Add("out_trade_no", out_trade_no);
            stringADict.Add("fee_type", fee_type);
            stringADict.Add("total_fee", total_fee.ToString());
            stringADict.Add("spbill_create_ip", spbill_create_ip);
            stringADict.Add("time_start", time_start);
            stringADict.Add("time_expire", time_expire);
            stringADict.Add("goods_tag", goods_tag);
            stringADict.Add("auth_code", auth_code);
            var sign     = WxPayAPI.Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/pay/micropay";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(new DynamicXml(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #5
0
        /// <summary>
        /// 公共API => 查询订单
        /// 不需要证书
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_2
        /// 该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。
        /// 需要调用查询接口的情况:
        ///◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;
        ///◆ 调用支付接口后,返回系统错误或未知交易状态情况;
        ///◆ 调用被扫支付API,返回USERPAYING的状态;
        ///◆ 调用关单或撤销接口API之前,需确认支付状态;
        /// </summary>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="transaction_id">String(32) 微信订单号 微信的订单号,优先使用 </param>
        /// <param name="out_trade_no">(transaction_id为空时必填) String(32) 商户订单号 商户系统内部的订单号,当没提供transaction_id时需要传这个。 </param>
        /// <param name="nonce_str">随机字符串 随机字符串,不长于32位。</param>
        /// <param name="partnerKey">API密钥</param>
        /// <returns> 参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_2 </returns>
        public static dynamic OrderQuery(string appid, string mch_id, string transaction_id, string out_trade_no, string nonce_str, string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("transaction_id", transaction_id);
            stringADict.Add("out_trade_no", out_trade_no);
            stringADict.Add("nonce_str", nonce_str);
            var sign     = Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/pay/orderquery";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #6
0
        /// <summary>
        /// 公共API => 转换短链接
        /// 不需要证书
        /// http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_9
        ///应用场景
        ///该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。
        /// </summary>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="long_url">(必填) String(512) URL链接 需要转换的URL,签名用原串,传输需URL encode  </param>
        /// <param name="nonce_str">(必填) 随机字符串 随机字符串,不长于32位。</param>
        /// <param name="partnerKey">(必填)API密钥</param>
        /// <returns> 参见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=9_9 </returns>
        public static dynamic ShortUrl(string appid, string mch_id, string long_url, string nonce_str,
                                       string partnerKey)
        {
            var stringADict = new Dictionary <string, string>();

            stringADict.Add("appid", appid);
            stringADict.Add("mch_id", mch_id);
            stringADict.Add("nonce_str", nonce_str);
            stringADict.Add("long_url", long_url);

            var sign     = Sign(stringADict, partnerKey);//生成签名字符串
            var postdata = PayUtil.GeneralPostdata(stringADict, sign);
            var url      = "https://api.mch.weixin.qq.com/tools/shorturl";
            var client   = new HttpClient();
            var result   = client.PostAsync(url, new StringContent(postdata)).Result;

            if (!result.IsSuccessStatusCode)
            {
                return(string.Empty);
            }
            return(DynamicJson.Parse(result.Content.ReadAsStringAsync().Result));
        }
Beispiel #7
0
        /// <summary>
        /// 获取微信现金红包信息接口
        /// 是否需要证书:需要。
        /// http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6
        /// 使用说明
        /// 用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
        /// </summary>
        /// <param name="nonce_str">(必填) String(32) 随机字符串,不长于32位</param>
        /// <param name="mch_billno">(必填) String(28) 商户发放红包的商户订单号</param>
        /// <param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        /// <param name="appid">(必填) String(32) 微信分配的公众账号ID</param>
        /// <param name="bill_type">(必填) String(32) 订单类型  例子:MCHT ,通过商户订单号获取红包信息。</param>
        /// <param name="partnerKey">API密钥</param>
        /// <param name="cert_path">秘钥路径</param>
        /// <param name="cert_password">秘钥密码</param>
        /// <returns>返回xml字符串,格式参见:http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_6 </returns>
        public static string GetHbInfo(string nonce_str, string mch_billno, string mch_id, string appid,
                                       string bill_type, string partnerKey, string cert_path, string cert_password)
        {
            try
            {
                var stringADict = new Dictionary <string, string>();
                stringADict.Add("nonce_str", nonce_str);
                stringADict.Add("mch_billno", mch_billno);
                stringADict.Add("mch_id", mch_id);
                stringADict.Add("appid", appid);
                stringADict.Add("bill_type", bill_type);

                var sign     = WxPayAPI.Sign(stringADict, partnerKey);//生成签名字符串
                var postdata = PayUtil.GeneralPostdata(stringADict, sign);
                var url      = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo";

                // 要注意的这是这个编码方式,还有内容的Xml内容的编码方式
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                byte[]   data     = encoding.GetBytes(postdata);

                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);

                //X509Certificate cer = new X509Certificate(cert_path, cert_password);
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                X509Certificate cer = new X509Certificate(cert_path, cert_password);

                #region 该部分是关键,若没有该部分则在IIS下会报 CA证书出错
                X509Certificate2 certificate = new X509Certificate2(cert_path, cert_password);
                X509Store        store       = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadWrite);
                store.Remove(certificate);   //可省略
                store.Add(certificate);
                store.Close();

                #endregion

                HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
                webrequest.ClientCertificates.Add(cer);
                webrequest.Method        = "post";
                webrequest.ContentLength = data.Length;


                Stream outstream = webrequest.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Flush();
                outstream.Close();


                HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
                Stream          instream   = webreponse.GetResponseStream();
                string          resp       = string.Empty;
                using (StreamReader reader = new StreamReader(instream))
                {
                    resp = reader.ReadToEnd();
                }
                return(resp);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Beispiel #8
0
        /// <summary>
        /// http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5
        /// 1.应用场景:向指定微信用户的openid发放指定金额红包
        ///是否需要证书:需要。
        ///<param name="nonce_str">(必填) String(32) 随机字符串,不长于32位</param>
        ///<param name="mch_billno">(必填) String(32) 商户订单号(每个订单号必须唯一)组成: mch_id+yyyymmdd+10位一天内不能重复的数字。</param>
        ///<param name="mch_id">(必填) String(32) 微信支付分配的商户号</param>
        ///<param name="sub_mch_id"> String(32) 微信支付分配的子商户号,受理模式下必填</param>
        /// <param name="wxappid">(必填) String(32) 商户appid</param>
        /// <param name="nick_name">(必填) String(32) 提供方名称</param>
        /// <param name="send_name">(必填) String(32) 红包发送者名称</param>
        /// <param name="re_openid">(必填) String(32) 接受收红包的用户 用户在wxappid下的openid</param>
        /// <param name="total_amount">(必填) int 付款金额,单位分</param>
        /// <param name="min_value">(必填) int 最小红包金额,单位分</param>
        /// <param name="max_value">(必填) int 最大红包金额,单位分</param>
        /// <param name="total_num">(必填) int 红包发放总人数</param>
        /// <param name="wishing">(必填) String(128) 红包祝福语</param>
        /// <param name="client_ip">(必填) String(15) 调用接口的机器Ip地址</param>
        /// <param name="act_name">(必填) String(32) 活动名称</param>
        /// <param name="remark">(必填) String(256) 备注信息</param>
        /// <param name="logo_imgurl"> String(128) 商户logo的url</param>
        /// <param name="share_content"> String(256) 分享文案</param>
        /// <param name="share_url"> String(128) 分享链接</param>
        /// <param name="share_imgurl"> String(128) 分享的图片url</param>
        /// <param name="partnerKey">API密钥</param>
        /// <param name="cert_path">秘钥路径</param>
        /// <param name="cert_password">秘钥密码</param>
        /// <returns>返回xml字符串,格式参见:http://pay.weixin.qq.com/wiki/doc/api/cash_coupon.php?chapter=13_5 </returns>
        public static string SendRedPack(string nonce_str, string mch_billno, string mch_id,
                                         string sub_mch_id, string wxappid, string nick_name, string send_name,
                                         string re_openid, int total_amount, int min_value, int max_value,
                                         int total_num, string wishing, string client_ip, string act_name,
                                         string remark, string logo_imgurl, string share_content, string share_url,
                                         string share_imgurl, string partnerKey, string cert_path, string cert_password)
        {
            try
            {
                var stringADict = new Dictionary <string, string>();
                stringADict.Add("nonce_str", nonce_str);
                stringADict.Add("mch_billno", mch_billno);
                stringADict.Add("mch_id", mch_id);
                stringADict.Add("sub_mch_id", sub_mch_id);
                stringADict.Add("wxappid", wxappid);
                stringADict.Add("nick_name", nick_name);
                stringADict.Add("send_name", send_name);
                stringADict.Add("re_openid", re_openid);
                stringADict.Add("total_amount", total_amount.ToString());
                stringADict.Add("min_value", min_value.ToString());
                stringADict.Add("max_value", max_value.ToString());
                stringADict.Add("total_num", total_num.ToString());
                stringADict.Add("wishing", wishing.ToString());
                stringADict.Add("client_ip", client_ip);
                stringADict.Add("act_name", act_name);
                stringADict.Add("remark", remark);
                stringADict.Add("logo_imgurl", logo_imgurl);
                stringADict.Add("share_content", share_content);
                stringADict.Add("share_url", share_url);
                stringADict.Add("share_imgurl", share_imgurl);

                var sign     = WxPayAPI.Sign(stringADict, partnerKey);//生成签名字符串
                var postdata = PayUtil.GeneralPostdata(stringADict, sign);
                var url      = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";

                // 要注意的这是这个编码方式,还有内容的Xml内容的编码方式
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                byte[]   data     = encoding.GetBytes(postdata);

                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                //X509Certificate cer = new X509Certificate(cert_path, cert_password);
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                X509Certificate cer = new X509Certificate(cert_path, cert_password);

                #region 该部分是关键,若没有该部分则在IIS下会报 CA证书出错
                X509Certificate2 certificate = new X509Certificate2(cert_path, cert_password);
                X509Store        store       = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadWrite);
                store.Remove(certificate);   //可省略
                store.Add(certificate);
                store.Close();

                #endregion

                HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
                webrequest.ClientCertificates.Add(cer);
                webrequest.Method        = "post";
                webrequest.ContentLength = data.Length;


                Stream outstream = webrequest.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Flush();
                outstream.Close();

                HttpWebResponse webreponse = (HttpWebResponse)webrequest.GetResponse();
                Stream          instream   = webreponse.GetResponseStream();
                string          resp       = string.Empty;
                using (StreamReader reader = new StreamReader(instream))
                {
                    resp = reader.ReadToEnd();
                }
                return(resp);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }