C#公众号开发之给用户发红包
程序员文章站
2023-12-17 15:11:40
红包功能简单介绍:
1、商户调用接口时,通过指定发送对象以及发送金额的方式发放红包,这样的方式,允许商户灵活的应用于各种各样丰富的活动场景
2、领取到红包后,用户的资金...
红包功能简单介绍:
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必须有权限对该文件夹操作的权限。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。