C#公众号开发之给用户发红包

红包功能简单介绍:

1、商户调用接口时,通过指定发送对象以及发送金额的方式发放红包,这样的方式,允许商户灵活的应用于各种各样丰富的活动场景

2、领取到红包后,用户的资金直接进入微信零钱,避免繁复的领奖流程,带给用户微信支付原生的流畅体验

现金红包官网文档地址

调用现金红包接口需要使用到证书,请前往商户平台下载证书

官网有关详细证书的介绍,点击查看

因为发送现金红包是从商户平台余额扣款,所以商户平台的账户余额必须有充足的余额

下面是调用红包接口详细代码:

1、签名的MD5加密类:

/// <summary>
/// MD5UtilHelper 的摘要说明。
/// </summary>
public class MD5UtilHelper
{
  public MD5UtilHelper()
  {
    //
    // TODO: 在此处添加构造函数逻辑
    //
  }

  /// <summary>
      /// 获取大写的MD5签名结果
  /// </summary>
  /// <param name="encypStr"></param>
  /// <param name="charset"></param>
  /// <returns></returns>
  public static string GetMD5(string encypStr, string charset)
  {
    string retStr;
    MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();

    //创建md5对象
    byte[] inputBye;
    byte[] outputBye;

    //使用GB2312编码方式把字符串转化为字节数组.
    try
    {
      inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
    }
    catch (Exception ex)
    {
      inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
    }
    outputBye = m5.ComputeHash(inputBye);

    retStr = System.BitConverter.ToString(outputBye);
    retStr = retStr.Replace("-", "").ToUpper();
    return retStr;
  }
}

2、处理参数的类:

public class RequestHandler
  {

    public RequestHandler(HttpContext httpContext)
    {
      Parameters = new Hashtable();

      this.HttpContext = httpContext ?? HttpContext.Current;

    }
    /// <summary>
    /// 密钥
    /// </summary>
    private string Key;

    protected HttpContext HttpContext;

    /// <summary>
    /// 请求的参数
    /// </summary>
    protected Hashtable Parameters;

    /// <summary>
    /// debug信息
    /// </summary>
    private string DebugInfo;

    /// <summary>
    /// 初始化函数
    /// </summary>
    public virtual void Init()
    {
    }
    /// <summary>
    /// 获取debug信息
    /// </summary>
    /// <returns></returns>
    public String GetDebugInfo()
    {
      return DebugInfo;
    }
    /// <summary>
    /// 获取密钥
    /// </summary>
    /// <returns></returns>
    public string GetKey()
    {
      return Key;
    }
    /// <summary>
    /// 设置密钥
    /// </summary>
    /// <param name="key"></param>
    public void SetKey(string key)
    {
      this.Key = key;
    }

    /// <summary>
    /// 设置参数值
    /// </summary>
    /// <param name="parameter"></param>
    /// <param name="parameterValue"></param>
    public void SetParameter(string parameter, string parameterValue)
    {
      if (parameter != null && parameter != "")
      {
        if (Parameters.Contains(parameter))
        {
          Parameters.Remove(parameter);
        }

        Parameters.Add(parameter, parameterValue);
      }
    }

    /// <summary>
    /// 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名
    /// </summary>
    /// <param name="key">参数名</param>
    /// <param name="value">参数值</param>
    /// key和value通常用于填充最后一组参数
    /// <returns></returns>
    public virtual string CreateMd5Sign(string key, string value)
    {
      StringBuilder sb = new StringBuilder();

      ArrayList akeys = new ArrayList(Parameters.Keys);
      akeys.Sort();

      foreach (string k in akeys)
      {
        string v = (string)Parameters[k];
        if (null != v && "".CompareTo(v) != 0
          && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
        {
          sb.Append(k + "=" + v + "&");
        }
      }

      sb.Append(key + "=" + value);
      string sign = MD5UtilHelper.GetMD5(sb.ToString(), GetCharset()).ToUpper();

      return sign;
    }

    /// <summary>
    /// 输出XML
    /// </summary>
    /// <returns></returns>
    public string ParseXML()
    {
      StringBuilder sb = new StringBuilder();
      sb.Append("<xml>");
      foreach (string k in Parameters.Keys)
      {
        string v = (string)Parameters[k];
        if (Regex.IsMatch(v, @"^[0-9.]$"))
        {

          sb.Append("<" + k + ">" + v + "</" + k + ">");
        }
        else
        {
          sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
        }

      }
      sb.Append("</xml>");
      return sb.ToString();
    }

    /// <summary>
    /// 设置debug信息
    /// </summary>
    /// <param name="debugInfo"></param>
    public void SetDebugInfo(String debugInfo)
    {
      this.DebugInfo = debugInfo;
    }

    public Hashtable GetAllParameters()
    {
      return this.Parameters;
    }

    protected virtual string GetCharset()
    {
      return this.HttpContext.Request.ContentEncoding.BodyName;
    }
  }

3、调用现金红包处理类:

 /// <summary>
 /// 企业号微信支付接口
 /// </summary>
 public static class TenPay
 {

   #region 企业向用户发红包
   /// <summary>
   /// 用于企业向微信用户个人发红包
   /// 目前支持向指定微信用户的openid个人发红包
   /// </summary>
   /// <param name="certPassword">apiclient_cert.p12证书密码即商户号</param>
   /// <param name="data">微信支付需要post的xml数据</param>
   /// <param name="certPath">apiclient_cert.p12的证书物理位置(例如:E:\projects\文档\微信商户平台证书\商户平台API证书</param>
   /// <param name="timeOut"></param>
   /// <returns></returns>
   public static string Sendredpack(string data, string certPassword,string certPath, int timeOut = Config.TIME_OUT)
   {
     var urlFormat = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
     string cert = certPath;

     ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
     X509Certificate2 cer = new X509Certificate2(cert, certPassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

     var formDataBytes = data == null ? new byte[0] : Encoding.UTF8.GetBytes(data);
     MemoryStream ms = new MemoryStream();
     ms.Write(formDataBytes, 0, formDataBytes.Length);
     ms.Seek(0, SeekOrigin.Begin);//设置指针读取位置

     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlFormat);
     request.ClientCertificates.Add(cer);
     request.Method = "POST";
     request.Timeout = timeOut;

     request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";

     #region 输入二进制流
     if (ms != null)
     {
       ms.Position = 0;
       //直接写入流
       Stream requestStream = request.GetRequestStream();
       byte[] buffer = new byte[1024];
       int bytesRead = 0;
       while ((bytesRead = ms.Read(buffer, 0, buffer.Length)) != 0)
       {
         requestStream.Write(buffer, 0, bytesRead);
       }
       ms.Close();//关闭文件访问
     }
     #endregion

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

     using (Stream responseStream = response.GetResponseStream())
     {
       using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.GetEncoding("utf-8")))
       {
         string retString = myStreamReader.ReadToEnd();
         return retString;
       }
     }
   }
   private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
   {
     if (errors == SslPolicyErrors.None)
       return true;
     return false;
   }
   #endregion

 }

4、调用现金红包接口

#region 发送红包
bool fals = false;  //记录发送红包是否成功
string xmlResult = null; //现金红包接口返回的xml
string certPath = null; //证书在服务器的物理位置
string data = null; //调用现金红包接口需要的数据
try
{
  //创建支付应答对象
  RequestHandler packageReqHandler = new RequestHandler(null);
  //初始化
  packageReqHandler.Init();
  string nonceStr = TenPayV3Util.GetNoncestr(); //时间戳
  //设置package订单参数
  packageReqHandler.SetParameter("nonce_str", nonceStr);  //随机字符串,不长于32位
  packageReqHandler.SetParameter("mch_billno", System.Configuration.ConfigurationManager.AppSettings["TenPayV3_MchId"] + model.JournalNumber);//商户订单号(每个订单号必须唯一)组成:mch_id+yyyymmdd+10位一天内不能重复的数字。接口根据商户订单号支持重入,如出现超时可再调用。
  packageReqHandler.SetParameter("mch_id", System.Configuration.ConfigurationManager.AppSettings["TenPayV3_MchId"]); //微信支付分配的商户号
  packageReqHandler.SetParameter("wxappid", System.Configuration.ConfigurationManager.AppSettings["TenPayV3_AppId"]);//微信分配的公众账号ID(企业号corpid即为此appId)。接口传入的所有appid应该为公众号的appid(在mp.weixin.qq.com申请的),不能为APP的appid(在open.weixin.qq.com申请的)。
  packageReqHandler.SetParameter("send_name", "测试");//商户名称
  packageReqHandler.SetParameter("re_openid", model.BankCard); //用户openid 接受红包的用户用户在wxappid下的openid
  packageReqHandler.SetParameter("total_amount", Convert.ToInt32((decimal)(model.Amount * 100M)).ToString(CultureInfo.InvariantCulture)); //付款金额 单位分
  packageReqHandler.SetParameter("total_num", "1"); //红包发放总人数
  packageReqHandler.SetParameter("wishing", "测试红包"); //红包祝福语
  packageReqHandler.SetParameter("client_ip", HttpContext.Current.Request.UserHostAddress);//Ip地址
  packageReqHandler.SetParameter("act_name", "测试红包");//活动名称
  packageReqHandler.SetParameter("remark", "测试红包");   //备注
  string sign = packageReqHandler.CreateMd5Sign("key", System.Configuration.ConfigurationManager.AppSettings["TenPayV3_Key"]);
  packageReqHandler.SetParameter("sign", sign);            //签名
  data = packageReqHandler.ParseXML();
  certPath = Server.MapPath("~/") + System.Configuration.ConfigurationManager.AppSettings["certPath"];
  xmlResult = Sendredpack(data, System.Configuration.ConfigurationManager.AppSettings["TenPayV3_MchId"],certPath);
  var res = XDocument.Parse(xmlResult);
  string return_code = res.Element("xml").Element("return_code").Value;
  if ("SUCCESS".Equals(return_code))
  {
    string result_code = res.Element("xml").Element("result_code").Value;
    if ("SUCCESS".Equals(result_code))
    {
      fals = true;
    }
  }
}
catch (Exception exception)
{
}
#endregion

注意:证书所在文件夹权限,IIS必须有权限对该文件夹操作的权限。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#实现微信红包功能

    本文实例为大家分享了C#仿微信红包功能的具体代码,供大家参考,具体内容如下 Program.cs代码: class Program { static void Main(string[] args) { //初始化要发起的红包基础数据 double total = 100; int num = 50; double min = 0.01; string temp; bool flag = false; Console.WriteLine(string.Format("是否需要自定义红包金额和数量

  • C#公众号开发之给用户发红包

    红包功能简单介绍: 1.商户调用接口时,通过指定发送对象以及发送金额的方式发放红包,这样的方式,允许商户灵活的应用于各种各样丰富的活动场景 2.领取到红包后,用户的资金直接进入微信零钱,避免繁复的领奖流程,带给用户微信支付原生的流畅体验 现金红包官网文档地址 调用现金红包接口需要使用到证书,请前往商户平台下载证书 官网有关详细证书的介绍,点击查看 因为发送现金红包是从商户平台余额扣款,所以商户平台的账户余额必须有充足的余额 下面是调用红包接口详细代码: 1.签名的MD5加密类: /// <sum

  • 微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解

    微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读"网页授权获取用户基本信息"的接口说明 在微信公众账号开发中,往往有定义一个菜单,然后用户点击该菜单就进入用户个人中心的功能,通常应用于各个公众账号中的会员服务. 如何在微信自定义菜单中将用户导航到个人中心页面呢? 首选需要通过用户点击获取用户openid,而通过用户的点击跳转获取用户openid就必须在菜单中动态绑定用户的openid,或者在菜单的跳转URL中填写微信提供的链接,官方给了两个链接类型

  • Java微信公众号开发之通过微信公众号获取用户信息

    最近由于公司业务,就开始研究微信开发的流程,说实话,这东西刚开始看到时候和看天书的一样,总算,看了一天的文档,测试代码终于出来了. 1.首先需要到微信网站去设置一下,我是直接用的微信测试号. 接口配置信息必须要填写的,所以说必须能将自己的服务发布出去 到此微信配置完毕,接下来就是直接上代码了 2.获取用户信息的方式一共是两种,前提都是用户关注微信公众号,一种是静默获取(snsapi_base,这种方式只能获取openid),另一种是授权获取(snsapi_userinfo,可以获取用户的详细信息

  • C#微信公众号开发之用户上下文WeixinContext和MessageContext

    概述 由于微信公众平台的特殊机制,所有的信息都由微信服务器转发而来,因此服务器是无法使用Session对用户会话的上下文进行管理的. 为此Senparc.WeiXin.MP SDK增加了上下文的模块,并集成到了MessageHandler中. WeixinContext WeixinContext是所有单个用户上下文(MessageContext)实体的容器(暂且称为全局上下文).WeixinContext本身不是静态类,意味着您可以在同一个应用中创建多个上下文实体. 同时,一个静态的Weixi

  • C#微信公众号开发之用户管理

    前言: 微信公众号提供了用户和用户组的管理,我们可以在微信公众号官方里面进行操作,添加备注和标签,以及移动用户组别,同时,微信公众号提供了相应的接口方便我们调用,可方便的把用户同步到本地,这样我们可以自己为用户定义更多的信息,以及与本地的业务更好的对接起来.以方便做各种应用分析.所以本节内容主要是用户和用户组的管理. 开始: 一.用户关注与退订事件: 在之前的消息处理中,我们在UserMessageHandler.cs,需要继承Senparc.Weixin.MP.MessageHandlers<

  • C#微信公众号开发之接收事件推送与消息排重的方法

    本文实例讲述了C#微信公众号开发之接收事件推送与消息排重的方法.分享给大家供大家参考.具体分析如下: 微信服务器在5秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次.这样的话,问题就来了.有这样一个场景:当用户关注微信账号时,获取当前用户信息,然后将信息写到数据库中.类似于pc端网站的注册.可能由于这个关注事件中,我们需要处理的业务逻辑比较复杂.如送积分啊,写用户日志啊,分配用户组啊.等等--一系列的逻辑需要执行,或者网络环境比较复杂,无法保证5秒内响应当前用户的操作,那如果当操作尚未完

  • PHP微信公众号开发之微信红包实现方法分析

    本文实例讲述了PHP微信公众号开发之微信红包实现方法.分享给大家供大家参考,具体如下: 这几天遇到了一个客户 要给他们的微信公众平台上添加微信现金红包功能,是个二次开发的功能,顺手百度一下,原来不复杂.就着手开发功能了.现将开发的过程和需求贴出来分享一下: 一.需求: 粉丝通过在客户的公众平台点击他们公司的订单,然后给这个订单返现五元,发到订单的这个微信号上. 二.开发想法: 1:先拿到关注这个粉丝的openid,openid是关注某个公众号的微信标识,这样就可以定位到这个人是订单的操作者了.

  • 详解nodejs微信公众号开发——4.自动回复各种消息

    上一篇文章:nodejs微信公众号开发--3.封装消息响应模块,实现了对消息接口的模块化处理,方便后期的使用,本篇文章将介绍微信公众号回复各种消息的功能实现,包括文本.图片.语音.视频.音乐.图文等. 注:感觉最近localtunnel很不稳定,测试起来比较麻烦,有条件的自己搞个云服务器吧,我比较偷懒,几继续使用localtunnel了. 1. 被动回复用户消息 当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML

  • java微信公众号开发案例

    微信公众号开发一般是针对企业和组织的,个人一般只能申请订阅号,并且调用的接口有限,下面我们就来简单的描述下接入公众号的步骤: 1.首先你需要一个邮箱在微信公众号平台进行注册:      注册的方式有订阅号.公众号.小程序和企业号,个人我们这里只能选择订阅号 2.注册完后,我们登录到公众号平台--->开发--->基本配置,这里需要填写URL和token,URL就是我们使用服务器的接口: 3.Java Web服务器程序编译好且在服务器上部署可以运行的话,可在微信公众号进行在线接口调试: 1).选择

  • Python微信公众号开发平台

    上大学的时候,对微信公众号开发浅尝辄止的玩了一下,感觉还是挺有意思的. http://www.jb51.net/article/133677.htm后来服务器到期了,也就搁置了.由于发布web程序,使用PHP很顺手,就使用了PHP作为开发语言.但是其实微信公众号的开发和语言关联并不大,流程,原理上都是一致的. 快要做毕设了,想着到时候应该会部署一些代码到服务器上,进行长期的系统构建.所以趁着还是学生,就买了阿里云的学生机.买了之后,就想着玩点什么,于是微信公众号的开发,就又提上了日程.但是这次,

随机推荐