SoFunction
Updated on 2025-03-01

C# official account development to send red packets to users

A brief introduction to the red envelope function:

1. When a merchant calls the interface, red envelopes are distributed by specifying the sending object and sending amount. This method allows merchants to flexibly apply to various rich activity scenarios.

2. After receiving the red envelope, the user's funds will go directly to WeChat change to avoid the complicated reward process and bring users a smooth experience of WeChat payment natively.

Cash red envelope official websiteDocument address

You need to use the certificate when calling the cash red envelope interface. Please go to the merchant platform to download the certificate.

The official website provides detailed certificate introduction,Click to view

Because sending cash red envelopes is deducted from the merchant platform's balance, the account balance of the merchant platform must have sufficient balance.

Below is the detailed code of calling the red envelope interface:

1. Signed MD5 encryption class:

/// <summary>
/// Summary description of MD5UtilHelper./// </summary>
public class MD5UtilHelper
{
 public MD5UtilHelper()
 {
  //
  // TODO: Add constructor logic here  //
 }

 /// <summary>
   /// Get the capitalized MD5 signature result /// </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();

  //Create md5 object  byte[] inputBye;
  byte[] outputBye;

  //Use GB2312 encoding to convert strings into byte arrays.  try
  {
   inputBye = (charset).GetBytes(encypStr);
  }
  catch (Exception ex)
  {
   inputBye = ("GB2312").GetBytes(encypStr);
  }
  outputBye = (inputBye);

  retStr = (outputBye);
  retStr = ("-", "").ToUpper();
  return retStr;
 }
}

2. Classes that process parameters:

public class RequestHandler
 {

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

    = httpContext ?? ;

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

  protected HttpContext HttpContext;

  /// <summary>
  /// Requested parameters  /// </summary>
  protected Hashtable Parameters;

  /// <summary>
  /// debug information  /// </summary>
  private string DebugInfo;

  /// <summary>
  /// Initialize the function  /// </summary>
  public virtual void Init()
  {
  }
  /// <summary>
  /// Get debug information  /// </summary>
  /// <returns></returns>
  public String GetDebugInfo()
  {
   return DebugInfo;
  }
  /// <summary>
  /// Get the key  /// </summary>
  /// <returns></returns>
  public string GetKey()
  {
   return Key;
  }
  /// <summary>
  /// Set the key  /// </summary>
  /// <param name="key"></param>
  public void SetKey(string key)
  {
    = key;
  }

  /// <summary>
  /// Set parameter values  /// </summary>
  /// <param name="parameter"></param>
  /// <param name="parameterValue"></param>
  public void SetParameter(string parameter, string parameterValue)
  {
   if (parameter != null && parameter != "")
   {
    if ((parameter))
    {
     (parameter);
    }

    (parameter, parameterValue);
   }
  }


  /// <summary>
  /// Create md5 summary, the rule is: sort by parameter name a-z, and the parameters that encounter empty values ​​do not participate in the signature  /// </summary>
  /// <param name="key">param name</param>  /// <param name="value">parameter value</param>  /// key and value are usually used to fill the last set of parameters  /// &lt;returns&gt;&lt;/returns&gt;
  public virtual string CreateMd5Sign(string key, string value)
  {
   StringBuilder sb = new StringBuilder();

   ArrayList akeys = new ArrayList();
   ();

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

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

   return sign;
  }

  /// &lt;summary&gt;
  /// Output XML  /// &lt;/summary&gt;
  /// &lt;returns&gt;&lt;/returns&gt;
  public string ParseXML()
  {
   StringBuilder sb = new StringBuilder();
   ("&lt;xml&gt;");
   foreach (string k in )
   {
    string v = (string)Parameters[k];
    if ((v, @"^[0-9.]$"))
    {

     ("&lt;" + k + "&gt;" + v + "&lt;/" + k + "&gt;");
    }
    else
    {
     ("&lt;" + k + "&gt;&lt;![CDATA[" + v + "]]&gt;&lt;/" + k + "&gt;");
    }

   }
   ("&lt;/xml&gt;");
   return ();
  }


  /// &lt;summary&gt;
  /// Set debug information  /// &lt;/summary&gt;
  /// &lt;param name="debugInfo"&gt;&lt;/param&gt;
  public void SetDebugInfo(String debugInfo)
  {
    = debugInfo;
  }

  public Hashtable GetAllParameters()
  {
   return ;
  }

  protected virtual string GetCharset()
  {
   return ;
  }
 }

3. Call cash red envelope processing class:

 /// &lt;summary&gt;
 /// Enterprise number WeChat payment interface /// &lt;/summary&gt;
 public static class TenPay
 {

  #region Enterprises send red packets to users  /// &lt;summary&gt;
  /// Used to send red packets to WeChat users in person  /// Currently, it supports sending red packets to openid individuals of designated WeChat users  /// &lt;/summary&gt;
  /// <param name="certPassword">apiclient_cert.p12 certificate password is the merchant number</param>  /// <param name="data">WeChat payment requires post xml data</param>  /// <param name="certPath">apiclient_cert.p12's certificate physical location (for example: E:\projects\Document\WeChat Merchant Platform Certificate\Merchant Platform API Certificate</param>  /// &lt;param name="timeOut"&gt;&lt;/param&gt;
  /// &lt;returns&gt;&lt;/returns&gt;
  public static string Sendredpack(string data, string certPassword,string certPath, int timeOut = Config.TIME_OUT)
  {
   var urlFormat = "/mmpaymkttransfers/sendredpack";
   string cert = certPath;

    = new RemoteCertificateValidationCallback(CheckValidationResult);
   X509Certificate2 cer = new X509Certificate2(cert, certPassword,  | );

   var formDataBytes = data == null ? new byte[0] : Encoding.(data);
   MemoryStream ms = new MemoryStream();
   (formDataBytes, 0, );
   (0, );//Set the pointer reading position
   HttpWebRequest request = (HttpWebRequest)(urlFormat);
   (cer);
    = "POST";
    = timeOut;

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

   #region Enter binary stream   if (ms != null)
   {
     = 0;
    //Write to stream directly    Stream requestStream = ();
    byte[] buffer = new byte[1024];
    int bytesRead = 0;
    while ((bytesRead = (buffer, 0, )) != 0)
    {
     (buffer, 0, bytesRead);
    }
    ();//Close file access   }
   #endregion

   HttpWebResponse response = (HttpWebResponse)();

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

 }

4. Call the cash red envelope interface

#region Send red packetsbool fals = false; //Record whether the red envelope was sent successfullystring xmlResult = null; //The xml returned by the cash red envelope interfacestring certPath = null; //The certificate is in the physical location of the serverstring data = null; //The data required to call the cash red envelope interfacetry
{
 //Create a payment reply object RequestHandler packageReqHandler = new RequestHandler(null);
 //initialization ();
 string nonceStr = (); //Time stamp //Set package order parameters ("nonce_str", nonceStr); //Random string, no longer than 32 bits ("mch_billno", ["TenPayV3_MchId"] + );// Merchant order number (each order number must be unique) consists of: mch_id+yyyymmdd+10 digits that cannot be repeated within one day.  The interface supports reentry according to the merchant order number, and can be called again if the timeout occurs. ("mch_id", ["TenPayV3_MchId"]); //The merchant number assigned by WeChat Pay ("wxappid", ["TenPayV3_AppId"]);//The public account ID assigned by WeChat (the corporate number corpid is this appId).  All appids passed in the interface should be the appid of the official account (in the application) and cannot be the appid of the app (in the application). ("send_name", "test");//Business name ("re_openid", ); //User openid The user who accepts red envelopes is openid under wxappid ("total_amount", Convert.ToInt32((decimal)( * 100M)).ToString()); //Payment amount Unit points ("total_num", "1"); //Total number of red envelopes issued ("wishing", "Test Red Envelope"); //Red envelope blessings ("client_ip", );//Ip address ("act_name", "Test Red Envelope");//Activity name ("remark", "Test Red Envelope");  //Remark string sign = packageReqHandler.CreateMd5Sign("key", ["TenPayV3_Key"]);
 ("sign", sign);      //sign data = ();
 certPath = ("~/") + ["certPath"];
 xmlResult = Sendredpack(data, ["TenPayV3_MchId"],certPath);
 var res = (xmlResult);
 string return_code = ("xml").Element("return_code").Value;
 if ("SUCCESS".Equals(return_code))
 {
  string result_code = ("xml").Element("result_code").Value;
  if ("SUCCESS".Equals(result_code))
  {
   fals = true;
  }
 }
}
catch (Exception exception)
{
}
#endregion

Note: The folder where the certificate is located must have permissions to operate on this folder.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.