当前位置: 移动技术网 > IT编程>开发语言>c# > C#公众号开发之给用户发红包

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

2019年07月18日  | 移动技术网IT编程  | 我要评论

红包功能简单介绍:

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必须有权限对该文件夹操作的权限。

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网