呼叫微信公眾號現金紅包介面給使用者傳送紅包

NO IMAGE

紅包功能簡單介紹:

1、商戶呼叫介面時,通過指定傳送物件以及傳送金額的方式發放紅包,這樣的方式,允許商戶靈活的應用於各種各樣豐富的活動場景

2、領取到紅包後,使用者的資金直接進入微信零錢,避免繁複的領獎流程,帶給使用者微信支付原生的流暢體驗

現金紅包官網文件地址:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_1

呼叫現金紅包介面需要使用到證書,請前往商戶平臺下載證書

官網有關詳細證書的介紹:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=4_3

 

因為傳送現金紅包是從商戶平臺餘額扣款,所以商戶平臺的賬戶餘額必須有充足的餘額

 

下面是呼叫紅包介面詳細程式碼: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必須有許可權對該資料夾操作的許可權。