Files
g.hnyhua.cn/Mtxfw.Utility/WXPay.Interface_WxPay.cs
2026-02-07 15:48:27 +08:00

884 lines
41 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;
namespace Mtxfw.Utility
{
public class Interface_WxPay
{
public static string APPID = "wx8874b820fc84430c";
public static string TENPAY = "qbccandgengliu";
public static string PARTNER = "1239351402";//商户号
public static string APPSECRET = "fb2ceb817c30b371f172336b7e1da929";
public static string PARTNER_KEY = "qbpxltgocom8848vipxltgocom885888";
public const string OAUTH2 = "https://open.weixin.qq.com/connect/oauth2/authorize";
public const string OAUTH2_ACCESS_TOKEN = "https://api.weixin.qq.com/sns/oauth2/access_token";
//支付密钥Key(原来的Paysignkey )
public static string PAY_SIGNKEY = "qbpxltgocom8848vipxltgocom885888";//paysignkey(非appkey)
//服务器异步通知页面路径(流量卡)
public static string NOTIFY_URL_Card_Store = "/pay/weixinnotify_url.aspx";// ConfigurationManager.AppSettings["WXPayNotify_URL_CardStore"].ToString();
public static string NOTIFY_URL_Card_User = "/pay/weixinnotify_url.aspx"; //ConfigurationManager.AppSettings["WXPayNotify_URL_CardUser"].ToString();
public static string NOTIFY_URL_HB_Store = "/pay/weixinnotify_url.aspx";// ConfigurationManager.AppSettings["WXPayNotify_URL_CardStore"].ToString();
public static string Get_RequestHtml(Mtxfw.Utility.Config config, HttpContext Context, string openid, string Bill_No, decimal Charge_Amt, string Body = "测试充值", string PayType = "card_store")
{
if (openid.Length == 0)
{
return "";
}
APPID = config.webappKey;
APPSECRET = config.webappSecret;
TENPAY = config.webToken;
PARTNER = config.webPARTNER;
PARTNER_KEY = config.webPARTNER_KEY;
PAY_SIGNKEY = config.webPARTNER_KEY;
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_Store;
if (PayType == "card_user")
{
//用户购买支付
TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
}
else if (PayType == "hb_store")
{
//店铺红包充值
TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_HB_Store;
}
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string total_fee = (Charge_Amt*100).ToString("f0");
string wx_timeStamp = "";
string wx_nonceStr = Interface_WxPay.getNoncestr();
dic.Add("appid", APPID);
dic.Add("mch_id", PARTNER);//财付通帐号商家
dic.Add("device_info", "WEB");//可为空
dic.Add("nonce_str", wx_nonceStr);
dic.Add("trade_type", "JSAPI");
dic.Add("attach", "att1");
dic.Add("openid", openid);
dic.Add("out_trade_no", Bill_No); //商家订单号
dic.Add("total_fee", total_fee); //商品金额,以分为单位(money * 100).ToString()
dic.Add("notify_url", TENPAY_NOTIFY.ToLower());//接收财付通通知的URL
dic.Add("body", Body);//商品描述
dic.Add("spbill_create_ip", Context.Request.UserHostAddress); //用户的公网ip不是商户服务器IP
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
string _req_data = "<xml>";
_req_data += "<appid>" + APPID + "</appid>";
_req_data += "<attach><![CDATA[att1]]></attach>";
_req_data += "<body><![CDATA[" + Body + "]]></body> ";
_req_data += "<device_info><![CDATA[WEB]]></device_info> ";
_req_data += "<mch_id><![CDATA[" + PARTNER + "]]></mch_id> ";
_req_data += "<openid><![CDATA[" + openid + "]]></openid> ";
_req_data += "<nonce_str><![CDATA[" + wx_nonceStr + "]]></nonce_str> ";
_req_data += "<notify_url><![CDATA[" + TENPAY_NOTIFY.ToLower() + "]]></notify_url> ";
_req_data += "<out_trade_no><![CDATA[" + Bill_No + "]]></out_trade_no> ";
_req_data += "<spbill_create_ip><![CDATA[" + Context.Request.UserHostAddress + "]]></spbill_create_ip> ";
_req_data += "<total_fee><![CDATA[" + total_fee + "]]></total_fee> ";
_req_data += "<trade_type><![CDATA[JSAPI]]></trade_type> ";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, false, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/prepay_id");
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/return_msg");
string return_json = "";
Mtxfw.Utility.Common.WriteHtml("/weixin/weixin1.txt", retValue.Message + get_sign);
if (Event != null)
{
string _prepay_id = Event.InnerText;
Mtxfw.Utility.Common.WriteHtml("/weixin/weixin2.txt", _prepay_id);
SortedDictionary<string, string> pay_dic = new SortedDictionary<string, string>();
wx_timeStamp = Interface_WxPay.getTimestamp();
wx_nonceStr = Interface_WxPay.getNoncestr();
string _package = "prepay_id=" + _prepay_id;
pay_dic.Add("appId", APPID);
pay_dic.Add("timeStamp", wx_timeStamp);
pay_dic.Add("nonceStr", wx_nonceStr);
pay_dic.Add("package", _package);
pay_dic.Add("signType", "MD5");
string get_PaySign = BuildRequest(pay_dic, PARTNER_KEY);
return_json = JsonUtils.SerializeToJson(new
{
appId = APPID,
timeStamp = wx_timeStamp,
nonceStr = wx_nonceStr,
package = _package,
paySign = get_PaySign,
signType = "MD5"
});
}
return return_json;
}
public static string Get_RequestHtml5(Mtxfw.Utility.Config config, HttpContext Context, string Bill_No, decimal Charge_Amt, string Body = "测试充值", string PayType = "card_store")
{
APPID = config.webappKey;
APPSECRET = config.webappSecret;
TENPAY = config.webToken;
PARTNER = config.webPARTNER;
PARTNER_KEY = config.webPARTNER_KEY;
PAY_SIGNKEY = config.webPARTNER_KEY;
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_Store;
if (PayType == "card_user")
{
//用户购买支付
TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
}
else if (PayType == "hb_store")
{
//店铺红包充值
TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_HB_Store;
}
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string attach = "购买商品";
string total_fee = (Charge_Amt * 100).ToString("f0");
string wx_nonceStr = Interface_WxPay.getNoncestr();
string scene_info = "{\"h5_info\":{\"type\":\"Wap\",\"wap_url\": \"" + config.webUrl + "\",\"wap_name\": \"礼名公司\"}}";
string uIP = Context.Request.UserHostAddress;
dic.Add("appid", APPID);
dic.Add("mch_id", PARTNER);//财付通帐号商家
dic.Add("nonce_str", wx_nonceStr);
dic.Add("trade_type", "MWEB");
dic.Add("attach", attach);
dic.Add("out_trade_no", Bill_No); //商家订单号
dic.Add("total_fee", total_fee); //商品金额,以分为单位(money * 100).ToString()
dic.Add("notify_url", TENPAY_NOTIFY.ToLower());//接收财付通通知的URL
dic.Add("body", Body);//商品描述
dic.Add("scene_info", scene_info);
dic.Add("spbill_create_ip", uIP); //用户的公网ip不是商户服务器IP
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
string _req_data = "<xml>";
_req_data += "<appid><![CDATA[" + APPID + "]]></appid>";
_req_data += "<mch_id><![CDATA[" + PARTNER + "]]></mch_id>";
_req_data += "<nonce_str><![CDATA[" + wx_nonceStr + "]]></nonce_str>";
_req_data += "<trade_type><![CDATA[MWEB]]></trade_type>";
_req_data += "<attach><![CDATA[" + attach + "]]></attach>";
_req_data += "<out_trade_no><![CDATA[" + Bill_No + "]]></out_trade_no> ";
_req_data += "<total_fee><![CDATA[" + total_fee + "]]></total_fee>";
_req_data += "<notify_url><![CDATA[" + TENPAY_NOTIFY.ToLower() + "]]></notify_url>";
_req_data += "<body><![CDATA[" + Body + "]]></body> ";
_req_data += "<scene_info><![CDATA[" + scene_info + "]]></scene_info>";
_req_data += "<spbill_create_ip><![CDATA[" + uIP + "]]></spbill_create_ip>";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, false, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/prepay_id");
XmlNode Event0 = xmldoc.SelectSingleNode("/xml/mweb_url");
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/return_msg");
string return_json = "";
Mtxfw.Utility.Common.WriteHtml("/weixin/weixin1.txt", retValue.Message + get_sign);
if (Event != null && Event0 != null)
{
string _prepay_id = Event.InnerText;
string mweb_url = Event0.InnerText;
return_json = mweb_url + "&redirect_url=" + HttpUtility.UrlEncode(config.webUrl + "/mobile/my.aspx");
}
return return_json;
}
//小程序支付
public static void Get_RequestHtml0(Mtxfw.Utility.Config config, HttpContext Context, string openid, string Bill_No, decimal Charge_Amt, ref string timeStamp, ref string nonceStr, ref string package, ref string paySign, string Body = "测试充值", string PayType = "card_store")
{
APPID = config.webXAppID;
APPSECRET = config.webXAppSecret;
TENPAY = config.webToken;
PARTNER = config.webPARTNER;
PARTNER_KEY = config.webPARTNER_KEY;
PAY_SIGNKEY = config.webPARTNER_KEY;
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string total_fee = (Charge_Amt * 100).ToString("f0");
string wx_timeStamp = Interface_WxPay.getTimestamp();
string wx_nonceStr = Interface_WxPay.getNoncestr();
dic.Add("appid", APPID);
dic.Add("mch_id", PARTNER);//财付通帐号商家
dic.Add("device_info", "WEB");//可为空
dic.Add("nonce_str", wx_nonceStr);
dic.Add("trade_type", "JSAPI");
dic.Add("attach", "att1");
dic.Add("openid", openid);
dic.Add("out_trade_no", Bill_No); //商家订单号
dic.Add("total_fee", total_fee); //商品金额,以分为单位(money * 100).ToString()
dic.Add("notify_url", TENPAY_NOTIFY.ToLower());//接收财付通通知的URL
dic.Add("body", Body);//商品描述
dic.Add("spbill_create_ip", Context.Request.UserHostAddress); //用户的公网ip不是商户服务器IP
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
string _req_data = "<xml>";
_req_data += "<appid>" + APPID + "</appid>";
_req_data += "<attach><![CDATA[att1]]></attach>";
_req_data += "<body><![CDATA[" + Body + "]]></body> ";
_req_data += "<device_info><![CDATA[WEB]]></device_info> ";
_req_data += "<mch_id><![CDATA[" + PARTNER + "]]></mch_id> ";
_req_data += "<openid><![CDATA[" + openid + "]]></openid> ";
_req_data += "<nonce_str><![CDATA[" + wx_nonceStr + "]]></nonce_str> ";
_req_data += "<notify_url><![CDATA[" + TENPAY_NOTIFY.ToLower() + "]]></notify_url> ";
_req_data += "<out_trade_no><![CDATA[" + Bill_No + "]]></out_trade_no> ";
_req_data += "<spbill_create_ip><![CDATA[" + Context.Request.UserHostAddress + "]]></spbill_create_ip> ";
_req_data += "<total_fee><![CDATA[" + total_fee + "]]></total_fee> ";
_req_data += "<trade_type><![CDATA[JSAPI]]></trade_type> ";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, false, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/prepay_id");
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/return_msg");
Mtxfw.Utility.Common.WriteHtml("/weixin/weixin1.txt", _req_data + "|" + retValue.Message + "|" + get_sign);
if (Event != null)
{
string _prepay_id = Event.InnerText;
Mtxfw.Utility.Common.WriteHtml("/weixin/weixin2.txt", _prepay_id);
SortedDictionary<string, string> pay_dic = new SortedDictionary<string, string>();
string _package = "prepay_id=" + _prepay_id;
pay_dic.Add("appId", APPID);
pay_dic.Add("timeStamp", wx_timeStamp);
pay_dic.Add("nonceStr", wx_nonceStr);
pay_dic.Add("package", _package);
pay_dic.Add("signType", "MD5");
string get_PaySign = BuildRequest(pay_dic, PARTNER_KEY);
timeStamp = wx_timeStamp;
nonceStr = wx_nonceStr;
package = _package;
paySign = get_PaySign;
}
}
//付款到微信零钱
public static void Get_Requestchange(int ifweb, Mtxfw.Utility.Config config, HttpContext Context, string openid, string Bill_No, decimal Charge_Amt, string re_user_name,ref bool IFSUCCESS, ref string payment_no, ref string ErrMsg, string Body = "付款到零钱")
{
APPID = config.weixinAPP_ID;
APPSECRET = config.weixinAPP_Secret;
if (ifweb == 1)
{
APPID = config.webappKey;
APPSECRET = config.webappSecret;
}
TENPAY = config.webToken;
PARTNER = config.webPARTNER;
PARTNER_KEY = config.webPARTNER_KEY;
PAY_SIGNKEY = config.webPARTNER_KEY;
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string total_fee = (Charge_Amt * 100).ToString("f0");
string wx_timeStamp = Interface_WxPay.getTimestamp();
string wx_nonceStr = Interface_WxPay.getNoncestr();
string uIP = Context.Request.UserHostAddress;
dic.Add("mch_appid", APPID);
dic.Add("mchid", PARTNER);//财付通帐号商家
dic.Add("device_info", "");//可为空
dic.Add("nonce_str", wx_nonceStr);
dic.Add("partner_trade_no", Bill_No); //商家订单号
dic.Add("openid", openid);
dic.Add("check_name", "FORCE_CHECK");
dic.Add("re_user_name", re_user_name);
dic.Add("amount", total_fee); //商品金额,以分为单位(money * 100).ToString()
dic.Add("desc", Body);//商品描述
dic.Add("spbill_create_ip", uIP); //用户的公网ip不是商户服务器IP//Context.Request.UserHostAddress
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
string _req_data = "<xml>";
_req_data += "<mch_appid>" + APPID + "</mch_appid>";
_req_data += "<mchid>" + PARTNER + "</mchid>";
_req_data += "<device_info></device_info>";
_req_data += "<nonce_str><![CDATA[" + wx_nonceStr + "]]></nonce_str> ";
_req_data += "<partner_trade_no><![CDATA[" + Bill_No + "]]></partner_trade_no> ";
_req_data += "<openid><![CDATA[" + openid + "]]></openid> ";
_req_data += "<check_name><![CDATA[FORCE_CHECK]]></check_name> ";
_req_data += "<re_user_name><![CDATA[" + re_user_name + "]]></re_user_name> ";
_req_data += "<amount><![CDATA[" + total_fee + "]]></amount> ";
_req_data += "<desc><![CDATA[" + Body + "]]></desc>";
_req_data += "<spbill_create_ip><![CDATA[" + uIP + "]]></spbill_create_ip> ";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, true, false, config.webPARTNER);
Mtxfw.Utility.Common.WriteHtml("/weixin/changeweixin0.txt", retValue.Message);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/return_code");
XmlNode Event0 = xmldoc.SelectSingleNode("/xml/return_msg");
Mtxfw.Utility.Common.WriteHtml("/weixin/changeweixin1.txt", _req_data + "|" + retValue.Message + "|" + get_sign);
if (Event != null)
{
string return_code = Event.InnerText;
if(return_code== "SUCCESS")
{
XmlNode Event1 = xmldoc.SelectSingleNode("/xml/result_code");
string result_code = Event1.InnerText;
if (result_code== "SUCCESS")
{
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/partner_trade_no");
string partner_trade_no = Event2.InnerText;
XmlNode Event3 = xmldoc.SelectSingleNode("/xml/payment_no");
payment_no = Event3.InnerText;
IFSUCCESS = true;
}
else
{
XmlNode Event4 = xmldoc.SelectSingleNode("/xml/err_code");
XmlNode Event5 = xmldoc.SelectSingleNode("/xml/err_code_des");
if (Event4.InnerText == "SYSTEMERROR")
{
ErrMsg = "系统繁忙,请稍后再试。";
}
else if (Event4.InnerText == "NAME_MISMATCH")
{
ErrMsg = "您的姓名与微信收款人姓名不一致";
}
else
{
ErrMsg = Event5.InnerText;
}
}
}
else
{
ErrMsg= Event0.InnerText;
}
}
}
//查询付款到零钱记录
public static void Get_Requestchange0(int ifweb, Mtxfw.Utility.Config config, string partner_trade_no, ref bool IFSUCCESS, ref string ErrMsg)
{
APPID = config.weixinAPP_ID;
APPSECRET = config.weixinAPP_Secret;
if (ifweb == 1)
{
APPID = config.webappKey;
APPSECRET = config.webappSecret;
}
TENPAY = config.webToken;
PARTNER = config.webPARTNER;
PARTNER_KEY = config.webPARTNER_KEY;
PAY_SIGNKEY = config.webPARTNER_KEY;
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string wx_timeStamp = Interface_WxPay.getTimestamp();
string wx_nonceStr = Interface_WxPay.getNoncestr();
dic.Add("nonce_str", wx_nonceStr);
dic.Add("partner_trade_no", partner_trade_no);//商家订单号
dic.Add("mch_id", PARTNER);
dic.Add("appid ", APPID);//财付通帐号商家
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";
string _req_data = "<xml>";
_req_data += "<nonce_str><![CDATA[" + wx_nonceStr + "]]></nonce_str> ";
_req_data += "<partner_trade_no><![CDATA[" + partner_trade_no + "]]></partner_trade_no> ";
_req_data += "<mch_id>" + PARTNER + "</mch_id>";
_req_data += "<appid>" + APPID + "</appid>";
_req_data += "<sign><![CDATA[" + get_sign + "]]></sign> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, true, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/return_code");
XmlNode Event0 = xmldoc.SelectSingleNode("/xml/return_msg");
Mtxfw.Utility.Common.WriteHtml("/weixin/change0weixin1.txt", _req_data + "|" + retValue.Message + "|" + get_sign);
if (Event != null)
{
string return_code = Event.InnerText;
if (return_code == "SUCCESS")
{
XmlNode Event1 = xmldoc.SelectSingleNode("/xml/result_code");
string result_code = Event1.InnerText;
if (result_code == "SUCCESS")
{
XmlNode Event3 = xmldoc.SelectSingleNode("/xml/status");
string status = Event3.InnerText;
if (status == "SUCCESS")
{
IFSUCCESS = true;
}
}
else
{
XmlNode Event4 = xmldoc.SelectSingleNode("/xml/err_code");
XmlNode Event5 = xmldoc.SelectSingleNode("/xml/err_code_des");
ErrMsg = Event5.InnerText;
}
}
else
{
ErrMsg = Event0.InnerText;
}
}
}
//退款
public static void Get_Requestrefund(Mtxfw.Utility.Config config, string transaction_id, string out_trade_no, string out_refund_no, decimal refund, decimal total, ref int refundstatus, ref string ErrMsg, ref string refund_id, ref string refund_channel, ref string user_received_account,ref string success_time, string reason = "退款")
{
//支付完成后的回调处理页面,*替换成notify_url.asp所在路径
string TENPAY_NOTIFY = config.webUrl + NOTIFY_URL_Card_User;
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
dic.Add("transaction_id", transaction_id);
dic.Add("out_trade_no", out_trade_no);
dic.Add("out_refund_no", out_refund_no);
dic.Add("reason", reason);
dic.Add("notify_url", TENPAY_NOTIFY);
dic.Add("amount", "{\"refund\":"+ refund + ",\"total\":"+ total + ",\"currency\": \"CNY\"}");
string get_sign = BuildRequest(dic, PARTNER_KEY);
string url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
string _req_data = "<xml>";
_req_data += "<transaction_id>" + transaction_id + "</transaction_id>";
_req_data += "<out_trade_no>" + PARTNER + "</out_trade_no>";
_req_data += "<out_refund_no>"+ out_refund_no + "</out_refund_no>";
_req_data += "<reason><![CDATA[" + reason + "]]></reason> ";
_req_data += "<notify_url><![CDATA[" + TENPAY_NOTIFY + "]]></notify_url> ";
_req_data += "</xml>";
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, Encoding.UTF8.GetBytes(_req_data), System.Text.Encoding.UTF8, true, false, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/status");
Mtxfw.Utility.Common.WriteHtml("/weixin/Requestrefund.txt", _req_data + "|" + retValue.Message);
if (Event != null)
{
string return_code = Event.InnerText;
if (return_code == "SUCCESS")
{
XmlNode Event1 = xmldoc.SelectSingleNode("/xml/refund_id");
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/channel");
XmlNode Event3 = xmldoc.SelectSingleNode("/xml/user_received_account");
XmlNode Event4 = xmldoc.SelectSingleNode("/xml/success_time");
refund_id = Event1.InnerText;
string channel = Event2.InnerText;
if (channel == "ORIGINAL")
{
refund_channel = "原路退款";
}
else if (channel == "BALANCE")
{
refund_channel = "退回到余额";
}
else if (channel == "OTHER_BALANCE")
{
refund_channel = "原账户异常退到其他余额账户";
}
else if (channel == "OTHER_BANKCARD")
{
refund_channel = "原银行卡异常退到其他银行卡 ";
}
user_received_account = Event3.InnerText;
success_time = Event4.InnerText;
refundstatus = 1;
}
else if (return_code == "CLOSED")
{
ErrMsg = "退款关闭";
refundstatus = 2;
}
else if (return_code == "PROCESSING")
{
ErrMsg = "退款处理中";
refundstatus = 3;
}
else if (return_code == "ABNORMAL")
{
ErrMsg = "退款异常";
refundstatus = 4;
}
}
}
//查询退款记录
public static void Get_Requestrefund0(Mtxfw.Utility.Config config, string out_refund_no, ref bool IFSUCCESS, ref string ErrMsg, ref string refund_id, ref string refund_channel, ref string user_received_account, ref string success_time)
{
//设置package订单参数
SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
string url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/" + out_refund_no;
//通知支付接口拿到prepay_id
ReturnValue retValue = StreamReaderUtils.StreamReader(url, null, System.Text.Encoding.UTF8, false, false, false, config.webPARTNER);
//设置支付参数
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(retValue.Message);
XmlNode Event = xmldoc.SelectSingleNode("/xml/status");
Mtxfw.Utility.Common.WriteHtml("/weixin/Requestrefund0.txt", retValue.Message);
if (Event != null)
{
string return_code = Event.InnerText;
if (return_code == "SUCCESS")
{
XmlNode Event1 = xmldoc.SelectSingleNode("/xml/refund_id");
XmlNode Event2 = xmldoc.SelectSingleNode("/xml/channel");
XmlNode Event3 = xmldoc.SelectSingleNode("/xml/user_received_account");
XmlNode Event4 = xmldoc.SelectSingleNode("/xml/success_time");
refund_id = Event1.InnerText;
string channel = Event2.InnerText;
if (channel == "ORIGINAL")
{
refund_channel = "原路退款";
}
else if (channel == "BALANCE")
{
refund_channel = "退回到余额";
}
else if (channel == "OTHER_BALANCE")
{
refund_channel = "原账户异常退到其他余额账户";
}
else if (channel == "OTHER_BANKCARD")
{
refund_channel = "原银行卡异常退到其他银行卡 ";
}
user_received_account = Event3.InnerText;
success_time = Event4.InnerText;
}
else if (return_code == "CLOSED")
{
ErrMsg = "退款关闭";
}
else if (return_code == "PROCESSING")
{
ErrMsg = "退款处理中";
}
else if (return_code == "ABNORMAL")
{
ErrMsg = "退款异常";
}
else
{
ErrMsg = "其它原因";
}
}
}
#region OAuth2 URL地址
public static string OAuth2_GetUrl_Pay(string URL, int Scope, string state = "STATE")
{
StringBuilder sbCode = new StringBuilder(OAUTH2);
sbCode.Append("?appid=" + APPID);
sbCode.Append("&scope=" + (Scope == 1 ? "snsapi_userinfo" : "snsapi_base"));
sbCode.Append("&state=" + state);
sbCode.Append("&redirect_uri=" + Uri.EscapeDataString(URL));
sbCode.Append("&response_type=code#wechat_redirect");
return sbCode.ToString();
}
#endregion
#region OAuth2 Access_Token
public static ReturnValue OAuth2_Access_Token(string Code)
{
StringBuilder sbCode = new StringBuilder(OAUTH2_ACCESS_TOKEN);
sbCode.Append("?appid=" + APPID);
sbCode.Append("&secret=" + APPSECRET);
sbCode.Append("&code=" + Code);
sbCode.Append("&grant_type=authorization_code");
ReturnValue retValue = StreamReaderUtils.StreamReader(sbCode.ToString(), Encoding.UTF8);
if (retValue.HasError)
{
return retValue;
}
try
{
int intWeixin_ExpiresIn = Convert.ToInt32(StringUtils.GetJsonValue(retValue.Message, "expires_in").ToString());
retValue.PutValue("Weixin_OpenID", StringUtils.GetJsonValue(retValue.Message, "openid").ToString());
retValue.PutValue("Weixin_Token", StringUtils.GetJsonValue(retValue.Message, "access_token").ToString());
//retValue.PutValue("Weixin_ExpiresIn", intWeixin_ExpiresIn);
//retValue.PutValue("Weixin_ExpiresDate", DateTime.Now.AddSeconds(intWeixin_ExpiresIn));
//retValue.PutValue("refresh_token", StringUtils.GetJsonValue(retValue.Message, "refresh_token").ToString());
//retValue.PutValue("scope", StringUtils.GetJsonValue(retValue.Message, "scope").ToString());
}
catch
{
retValue.HasError = true;
retValue.Message = retValue.Message;
retValue.ErrorCode = "";
}
return retValue;
}
#endregion
public static string getNoncestr()
{
Random random = new Random();
return GetMD5(random.Next(1000).ToString(), "utf-8");
}
public static string getTimestamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
public static string BuildRequest(SortedDictionary<string, string> sParaTemp, string key)
{
//获取过滤后的数组
Dictionary<string, string> dicPara = new Dictionary<string, string>();
dicPara = FilterPara(sParaTemp);
//组合参数数组
string prestr = CreateLinkString(dicPara);
//拼接支付密钥
string stringSignTemp = prestr + "&key=" + key;
//获得加密结果
string myMd5Str = GetMD5(stringSignTemp);
//返回转换为大写的加密串
return myMd5Str.ToUpper();
}
public static string BuildRequest0(SortedDictionary<string, string> sParaTemp, string key)
{
//获取过滤后的数组
Dictionary<string, string> dicPara = new Dictionary<string, string>();
dicPara = FilterPara(sParaTemp);
//组合参数数组
string prestr = CreateLinkString0(dicPara);
//获得加密结果
return sign(key, prestr);
}
/// <summary>
/// 除去数组中的空值和签名参数并以字母a到z的顺序排序
/// </summary>
/// <param name="dicArrayPre">过滤前的参数组</param>
/// <returns>过滤后的参数组</returns>
public static Dictionary<string, string> FilterPara(SortedDictionary<string, string> dicArrayPre)
{
Dictionary<string, string> dicArray = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> temp in dicArrayPre)
{
if (temp.Key != "sign" && !string.IsNullOrEmpty(temp.Value))
{
dicArray.Add(temp.Key, temp.Value);
}
}
return dicArray;
}
//组合参数数组
public static string CreateLinkString(Dictionary<string, string> dicArray)
{
StringBuilder prestr = new StringBuilder();
foreach (KeyValuePair<string, string> temp in dicArray)
{
prestr.Append(temp.Key + "=" + temp.Value + "&");
}
int nLen = prestr.Length;
prestr.Remove(nLen - 1, 1);
return prestr.ToString();
}
//组合参数数组
public static string CreateLinkString0(Dictionary<string, string> dicArray)
{
StringBuilder prestr = new StringBuilder();
foreach (KeyValuePair<string, string> temp in dicArray)
{
prestr.Append("\""+temp.Key + "\":\"" + temp.Value + "\",");
}
int nLen = prestr.Length;
prestr.Remove(nLen - 1, 1);
return "{" + prestr.ToString() + "}";
}
public static string sign(string signaturePrivateKey, string signatureData, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
FromPrivateKeyJavaString(rsa,signaturePrivateKey);
byte[] signatureBytes = rsa.SignData(Encoding.GetEncoding(encoding).GetBytes(signatureData), hashAlgorithm);
return Convert.ToBase64String(signatureBytes);
}
// <summary>
/// RSA加载JAVA PrivateKey
/// </summary>
/// <param name="privateJavaKey">java提供的第三方私钥</param>
/// <returns></returns>
public static void FromPrivateKeyJavaString(RSA rsa, string privateJavaKey)
{
string xmlPrivateKey = ConvertToXmlPrivateKey(rsa, privateJavaKey);
rsa.FromXmlString(xmlPrivateKey);
}
/// <summary>
/// 把java的私钥转换成.net的xml格式
/// </summary>
/// <param name="rsa"></param>
/// <param name="privateJavaKey"></param>
/// <returns></returns>
public static string ConvertToXmlPrivateKey(RSA rsa, string privateJavaKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateJavaKey));
string xmlPrivateKey = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
return xmlPrivateKey;
}
public static bool verfySign(string publicKey, string signature, string content, string hashAlgorithm = "SHA256", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string xmlPublicKey = ConvertToXmlPublicJavaKey(rsa, publicKey);
rsa.FromXmlString(xmlPublicKey);
//返回数据验证结果
byte[] Data = Encoding.GetEncoding(encoding).GetBytes(content);
byte[] rgbSignature = Convert.FromBase64String(signature);
return rsa.VerifyData(Data, hashAlgorithm, rgbSignature);
}
/// <summary>
/// 把java的公钥转换成.net的xml格式
/// </summary>
/// <param name="publicJavaKey">java提供的第三方公钥</param>
/// <returns></returns>
public static string ConvertToXmlPublicJavaKey(RSA rsa, string publicJavaKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicJavaKey));
string xmlpublicKey = string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
return xmlpublicKey;
}
//加密
public static string GetMD5(string pwd)
{
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.UTF8.GetBytes(pwd));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
return sBuilder.ToString();
}
/** 获取大写的MD5签名结果 */
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;
}
}
}