首页新闻找找看学习计划

微信扫码开发模式二统一下单接口调用

0
悬赏园豆:20 [已解决问题] 解决于 2015-11-06 10:54

我封装了,下单接口怎么调用?https://api.mch.weixin.qq.com/pay/unifiedorder,谁有源码可以参考?

泡沫_之夏的主页 泡沫_之夏 | 初学一级 | 园豆:110
提问于:2015-11-03 12:42
< >
分享
最佳答案
1
public UnifiedOrderResponseModel UnifiedOrder(UnifiedOrderReqeustModel model)
        {
            return Client.PostAsync(ApiUrl.UnifiedOrder, new StringContent(model.ToXml(), System.Text.Encoding.UTF8, "application/xml"))
                .Result
                .Content
                .ReadAsStringAsync()
                .Result
                .XmlDeserialize<UnifiedOrderResponseModel>();
        }
    /// <summary>
    /// APP支付统一下单接口实体
    /// </summary>
    [DataContract(Name = "xml", Namespace = "", IsReference = true)]
    [XmlRoot(ElementName = "xml", Namespace = "", IsNullable = false)]
    [XmlType(AnonymousType = true)]
    public class UnifiedOrderReqeustModel
    {
        /// <summary> 公众账号 ID 
        /// 微信分配的公众账号 ID
        /// </summary>
        [XmlElement(ElementName = "appid")]
        [DataMember(Name = "appid", IsRequired = false)]
        public string AppId { get; set; }

        /// <summary> 商户号
        /// 微信分配的公众账号 ID
        /// </summary>
        [XmlElement(ElementName = "mch_id", IsNullable = false)]
        [DataMember(Name = "mch_id", IsRequired = false)]
        public string MchId { get; set; }


        /// <summary> 附加信息 
        /// 终端设备号(商户自定义)
        /// </summary>
        [XmlElement(ElementName = "device_info", IsNullable = false)]
        [DataMember(Name = "device_info", IsRequired = false)]
        public string DeviceInfo { get; set; }

        /// <summary> 随机字符串
        /// 不长于32位
        /// </summary>
        [XmlElement(ElementName = "nonce_str", IsNullable = false)]
        [DataMember(Name = "nonce_str", IsRequired = false)]
        public string NonceStr { get; set; }

        /// <summary> 商品描述 </summary>
        [XmlElement(ElementName = "body", IsNullable = false)]
        [DataMember(Name = "body", IsRequired = false)]
        public string Body { get; set; }

        /// <summary> 商品描述 </summary>
        [XmlElement(ElementName = "detail", IsNullable = false)]
        [DataMember(Name = "detail", IsRequired = false)]
        public string Detail { get; set; }

        /// <summary> 附加数据 
        /// 附加数据,原样返回
        /// </summary>
        [XmlElement(ElementName = "attach", IsNullable = false)]
        [DataMember(Name = "attach", IsRequired = false)]
        public string Attach { get; set; }

        /// <summary> 商户订单号
        /// 商户系统内部的订单号,32 个字符内、可包含字母, 确保在商户系统唯一
        /// 商户支付的订单号由商户自定义生成,微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。
        /// 重新发起一笔支付要使用原订单号,避免重复支付;已支付过或已调用关单、撤销(请见后文的API列表)的订单号不能重新发起支付。
        /// </summary>
        [XmlElement(ElementName = "out_trade_no", IsNullable = false)]
        [DataMember(Name = "out_trade_no", IsRequired = false)]
        public string OutTradeNo { get; set; }

        /// <summary>
        /// 符合ISO 4217标准的三位字母代码,默认人民币:CNY
        /// </summary>
        [XmlElement(ElementName = "fee_type", IsNullable = false)]
        [DataMember(Name = "fee_type", IsRequired = false)]
        public FeeType FeeType { get; set; }

        /// <summary> 订单总额
        /// 订单总金额,单位为分,只能 整数
        /// </summary>
        [XmlElement(ElementName = "total_fee", IsNullable = false)]
        [DataMember(Name = "total_fee", IsRequired = false)]
        public int TotalFee { get; set; }

        /// <summary> 终端IP
        /// 订单生成的机器IP
        /// </summary>
        [XmlElement(ElementName = "spbill_create_ip", IsNullable = false)]
        [DataMember(Name = "spbill_create_ip", IsRequired = false)]
        public string SpbillCreateIp { get; set; }

        [XmlElement(ElementName = "time_start", IsNullable = false)]
        [DataMember(Name = "time_start", IsRequired = false)]
        public string time_start { get; set; }

        /// <summary> 订单生成时间
        /// 格式为 yyyyMMddHHmmss,如 2009 年 12月 25日 9 点 10 分 10 秒 
        /// 表示为 20091225091010。时 区为 GMT+8beijing。该时间取 自商户服务器
        /// </summary>
        [IgnoreDataMember]
        public DateTime TimeStart
        {
            set { time_start = value.ToString("yyyyMMddHHmmss"); }
        }

        [XmlElement(ElementName = "time_expire", IsNullable = false)]
        [DataMember(Name = "time_expire", IsRequired = false)]
        public string time_expire { get; set; }

        /// <summary>订单失效时间
        /// 格式为 yyyyMMddHHmmss,如 2009 年 12月 27日 9 点 10 分 10 秒 表示为 20091227091010。
        /// 时 区为 GMT+8beijing。该时间取 自商户服务器
        /// </summary>
        [XmlIgnore]
        [IgnoreDataMember]
        public DateTime TimeExpire
        {
            set { time_expire = value.ToString("yyyyMMddHHmmss"); }
        }

        /// <summary> 商品标记
        /// 商品标记,微信平台配置的商 品标记,用于优惠券或者满减 使用,使用说明详见第 3 节 
        /// </summary>
        [XmlElement(ElementName = "goods_tag", IsNullable = false)]
        [DataMember(Name = "goods_tag", IsRequired = false)]
        public string GoodsTag { get; set; }

        /// <summary> 商品标记
        /// 商品标记,微信平台配置的商 品标记,用于优惠券或者满减 使用,使用说明详见第 3 节 
        /// </summary>
        [XmlElement(ElementName = "notify_url", IsNullable = false)]
        [DataMember(Name = "notify_url", IsRequired = false)]
        public string NotifyUrl { get; set; }


        /// <summary>
        /// 订单类型,取值如下:JSAPI,NATIVE,APP,详细说明见
        /// </summary>
        [XmlElement(ElementName = "trade_type", IsNullable = false)]
        [DataMember(Name = "trade_type", IsRequired = false)]
        public TradeType TradeType { set; get; }

        /// <summary>
        /// trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义。
        /// </summary>
        [XmlElement(ElementName = "product_id", IsNullable = false)]
        [DataMember(Name = "product_id", IsRequired = false)]
        public string ProductId { get; set; }


        /// <summary>
        /// trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。
        /// 下单前需要调用【网页授权获取用户信息】接口获取到用户的Openid。
        /// </summary>
        [XmlElement(ElementName = "openid", IsNullable = false)]
        [DataMember(Name = "openid", IsRequired = false)]
        public string OpenId { get; set; }

        /// <summary>
        /// 商户Key
        /// </summary>
        [IgnoreDataMember]
        [XmlIgnore]
        public string Key { get; set; }

        /// <summary> 签名
        /// 由于数据中携带了生成订单的详细信息,因此在微信将对数据里面的内容进行鉴权,
        /// 确定携带的信息是真实、有效、合理的。因此,这里将定义生成sign字符串的方法。
        /// a.对所有传入参数按照字段名的ASCII码从小到大排序(字典序)后,
        /// 使用URL键 值对的格式(即key1=value1&key2=value2…)拼接成字符串string1,
        /// 注意:值为空的 参数不参与签名; 
        /// b.在string1最后拼接上key=paternerKey 得到stringSignTemp字符串,
        /// 并对 stringSignTemp进行md5运算,再将得到的字符串所有字符转换为大写,得到sign值 signValue。 
        /// </summary>
        [XmlElement(ElementName = "sign", IsNullable = false)]
        [DataMember(Name = "sign", IsRequired = false)]

        public string Sign
        {
            get
            {
                var list = new[]
                {
                    new NameValue<string> {Name="appid",Value=AppId},
                    new NameValue<string> {Name="mch_id",Value=MchId},
                    new NameValue<string> {Name="device_info",Value=DeviceInfo},
                    new NameValue<string> {Name="nonce_str",Value=NonceStr},
                    new NameValue<string> {Name="body",Value=Body},
                    new NameValue<string> {Name="detail",Value=Detail},
                    new NameValue<string> {Name="attach",Value=Attach},
                    new NameValue<string> {Name="out_trade_no",Value=OutTradeNo},
                    new NameValue<string> {Name="fee_type",Value=this.FeeType.ToString()},
                    new NameValue<string> {Name="total_fee",Value=TotalFee.ToString()},
                    new NameValue<string> {Name="spbill_create_ip",Value=SpbillCreateIp},
                    new NameValue<string> {Name="time_start",Value=time_start},
                    new NameValue<string> {Name="time_expire",Value=time_expire},
                    new NameValue<string> {Name="goods_tag",Value=GoodsTag},
                    new NameValue<string> {Name="notify_url",Value=NotifyUrl},
                    new NameValue<string> {Name="trade_type",Value=this.TradeType.ToString().ToUpper()},
                    new NameValue<string> {Name="product_id",Value=this.ProductId},
                    new NameValue<string> {Name="openid",Value=OpenId},
                };
                var str = list
                    .Where(m => !m.Value.IsNullOrWhiteSpace())
                    .OrderBy(m => m.Name)
                    .Select(m => "{0}={1}".FormatExt(m.Name, m.Value))
                    .Concat(new[] { "key=" + Key })
                    .JoinStr("&");
                return str
                    .MD5Default()
                    .ToUpper();
            }
            set { }
        }
    }


    [XmlRoot(ElementName = "xml", Namespace = "", IsNullable = false)]
    [XmlType(AnonymousType = true)]
    public class UnifiedOrderResponseModel
    {
        /// <summary>
        /// SUCCESS/FAIL
        /// 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
        /// </summary>
        [XmlElement("return_code")]
        public ReturnCode ReturnCode { get; set; }

        [XmlElement("return_msg")]
        public string ReturnMsg { get; set; }

        /// <summary> 公众账号 ID 
        /// 微信分配的公众账号 ID
        /// </summary>
        [XmlElement("appid")]
        public string AppId { get; set; }

        [XmlElement("mch_id")]
        public string MchId { get; set; }

        [XmlElement("device_info")]
        public string DeviceInfo { get; set; }

        [XmlElement("nonce_str")]
        public string NonceStr { get; set; }

        [XmlElement("sign")]
        public string Sign { get; set; }

        [XmlElement("result_code")]
        public ReturnCode ResultCode { get; set; }

        [XmlElement("err_code")]
        public ErrorCode ErrCode { get; set; }

        /// <summary>
        /// 错误返回的信息描述
        /// </summary>
        [XmlElement("err_code_des")]
        public string ErrCodeDes { get; set; }

        /// <summary>
        /// 订单类型,取值如下:JSAPI,NATIVE,APP,详细说明见
        /// </summary>
        [XmlElement("trade_type")]
        public TradeType TradeType { get; set; }

        /// <summary>
        /// 微信生成的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时
        /// </summary>
        [XmlElement("prepay_id")]
        public string PrepayId { get; set; }

        /// <summary>
        /// trade_type为NATIVE是有返回,可将该参数值生成二维码展示出来进行扫码支付
        /// </summary>
        [XmlElement("code_url")]
        public string CodeUrl { get; set; }


        /// <summary>
        /// 校验签名是否正确
        /// </summary>
        /// <param name="key">商家密钥</param>
        /// <returns></returns>
        public bool CheckSign(string key)
        {
            var list = new[]
                {
                    new NameValue<string> {Name="return_code",Value=ReturnCode.ToString().ToUpper()},
                    new NameValue<string> {Name="return_msg",Value=ReturnMsg},
                    new NameValue<string> {Name="appid",Value=AppId},
                    new NameValue<string> {Name="mch_id",Value=MchId},
                    new NameValue<string> {Name="device_info",Value=DeviceInfo},
                    new NameValue<string> {Name="nonce_str",Value=NonceStr},
                    new NameValue<string> {Name="result_code",Value=ResultCode.ToString().ToUpper()},
                    new NameValue<string> {Name="err_code",Value=ErrCode.ToString().ToUpper()},
                    new NameValue<string> {Name="err_code_des",Value=ErrCodeDes},
                    new NameValue<string> {Name="trade_type",Value=TradeType.ToString().ToUpper()},
                    new NameValue<string> {Name="prepay_id",Value=PrepayId},
                    new NameValue<string> {Name="code_url",Value=CodeUrl}
                };
            var str = list
                .Where(m => !m.Value.IsNullOrWhiteSpace())
                .OrderBy(m => m.Name)
                .Select(m => "{0}={1}".FormatExt(m.Name, m.Value))
                .Concat(new[] { "key=" + key })
                .JoinStr("&");
            return str
                .MD5Default()
                .ToUpper() == Sign;
        }

    }

 


收获园豆:20
吴瑞祥 | 高人七级 |园豆:28736 | 2015-11-03 21:56

   request = (HttpWebRequest)WebRequest.Create(url);

                request.Method = "POST";
                request.Timeout = timeout * 1000;

              //设置POST的数据类型和长度
                request.ContentType = "text/xml";
                byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
                request.ContentLength = data.Length;

               //往服务器写入数据
                reqStream = request.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();

                //获取服务端返回
                response = (HttpWebResponse)request.GetResponse();

                //获取服务端返回数据
                StreamReader sr = new StreamReader(response.GetResponseStream(),Encoding.GetEncoding("gb2312"));
                result = sr.ReadToEnd().Trim();
                sr.Close();  我这样post数据怎么返回的是乱码是怎么回事?

泡沫_之夏 | 园豆:110 (初学一级) | 2015-11-04 10:54

@泡沫_之夏: 乱码都是因为编码格式原因.一个不行就换一个.

吴瑞祥 | 园豆:28736 (高人七级) | 2015-11-04 11:02

@吴瑞祥: 恩,改过来了,现在是签名错误。

泡沫_之夏 | 园豆:110 (初学一级) | 2015-11-04 11:02

@泡沫_之夏: 我用官网生成的xml发送,怎么也是返回签名错误,这个商户key,是商户平台登录的密码没错吧?

泡沫_之夏 | 园豆:110 (初学一级) | 2015-11-04 16:00

@泡沫_之夏: 签名封装错了。已解决。还是谢谢啊。

泡沫_之夏 | 园豆:110 (初学一级) | 2015-11-06 10:53

我调用接口的时候报错:

远程服务器返回错误: (404) 未找到。

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

 

这是什么原因啊?代码:

public static string HttpPost(string url, string data)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "text/xml";
//request.ContentType = "application/x-www-form-urlencoded";
//request.ContentLength = Encoding.UTF8.GetByteCount(data);

byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data); // 编码形式按照个人需求来设置
request.ContentLength = bytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(bytes, 0, bytes.Length);
requestStream.Close();

HttpWebResponse response = (HttpWebResponse)request.GetResponse();

Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();

return retString;
}

lsboke | 园豆:200 (初学一级) | 2016-03-18 06:18

@lsboke: 别用这个东西,用webapiclient吧.那个方便.

吴瑞祥 | 园豆:28736 (高人七级) | 2016-03-18 09:46
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册