| @ -0,0 +1,26 @@ | |||||
| | |||||
| Microsoft Visual Studio Solution File, Format Version 11.00 | |||||
| # Visual Studio 2010 | |||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BWP.ABCClient", "BWP.ABCClient\BWP.ABCClient.csproj", "{22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}" | |||||
| EndProject | |||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}" | |||||
| EndProject | |||||
| Global | |||||
| GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||||
| Debug|Any CPU = Debug|Any CPU | |||||
| Release|Any CPU = Release|Any CPU | |||||
| EndGlobalSection | |||||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||||
| {22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| {9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
| {9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
| {9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
| {9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
| EndGlobalSection | |||||
| GlobalSection(SolutionProperties) = preSolution | |||||
| HideSolutionNode = FALSE | |||||
| EndGlobalSection | |||||
| EndGlobal | |||||
| @ -0,0 +1,90 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class FundTransferRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static FundTransferRequest New() | |||||
| { | |||||
| return new FundTransferRequest { | |||||
| Message = new MessageContent { | |||||
| Merchant = new MerchantContent { | |||||
| ECMerchantType = "B2B", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| TrxRequest = new TrxRequestContent { | |||||
| TrxType = TrxType.FundTransfer, | |||||
| MerchantTrnxNo = string.Empty, | |||||
| TrnxAmount = "0", | |||||
| TrnxDate = string.Empty, | |||||
| TrnxTime = string.Empty, | |||||
| AccountDB = new AccountDBContent { | |||||
| AccountDBNo = string.Empty, | |||||
| AccountDBName = string.Empty, | |||||
| AccountDBBank = string.Empty | |||||
| }, | |||||
| TrnxInfo = new TrnxInfoContent { | |||||
| TrnxOpr = string.Empty | |||||
| }, | |||||
| ResultNotifyURL = string.Empty, | |||||
| MerchantRemarks = string.Empty | |||||
| } | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxRequestContent TrxRequest { get; set; } | |||||
| } | |||||
| public class TrxRequestContent | |||||
| { | |||||
| public string TrxType { get; set; } | |||||
| public string MerchantTrnxNo { get; set; } | |||||
| public string TrnxAmount { get; set; } | |||||
| public string TrnxDate { get; set; } | |||||
| public string TrnxTime { get; set; } | |||||
| public AccountDBContent AccountDB { get; set; } | |||||
| public TrnxInfoContent TrnxInfo { get; set; } | |||||
| public string ResultNotifyURL { get; set; } | |||||
| public string MerchantRemarks { get; set; } | |||||
| } | |||||
| public class TrnxInfoContent | |||||
| { | |||||
| public string TrnxOpr { get; set; } | |||||
| [XmlArrayItem(ElementName = "Remark")] | |||||
| public TrnxRemark[] TrnxRemarks { get; set; } | |||||
| public TrnxItem[] TrnxItems { get; set; } | |||||
| } | |||||
| public class TrnxRemark | |||||
| { | |||||
| public string Key { get; set; } | |||||
| public string Value { get; set; } | |||||
| } | |||||
| public class TrnxItem | |||||
| { | |||||
| public string ProductID { get; set; } | |||||
| public string ProductName { get; set; } | |||||
| public string UnitPrice { get; set; } | |||||
| public string Qty { get; set; } | |||||
| } | |||||
| public class AccountDBContent | |||||
| { | |||||
| public string AccountDBNo { get; set; } | |||||
| public string AccountDBName { get; set; } | |||||
| public string AccountDBBank { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,32 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class FundTransferResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public string TrnxType { get; set; } | |||||
| public string TrnxAMT { get; set; } | |||||
| public string MerchantTrnxNo { get; set; } | |||||
| public string PaymentURL { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class QueryTrnxRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static QueryTrnxRequest New() | |||||
| { | |||||
| return new QueryTrnxRequest { | |||||
| Message = new MessageContent { | |||||
| Merchant = new MerchantContent { | |||||
| ECMerchantType = "B2B", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| TrxRequest = new TrxRequestContent { | |||||
| TrxType = TrxType.QueryTrnx, | |||||
| MerchantTrnxNo = string.Empty, | |||||
| MerchantRemarks = string.Empty | |||||
| } | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxRequestContent TrxRequest { get; set; } | |||||
| } | |||||
| public class TrxRequestContent | |||||
| { | |||||
| public string TrxType { get; set; } | |||||
| public string MerchantTrnxNo { get; set; } | |||||
| public string MerchantRemarks { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,34 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class QueryTrnxResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public string TrnxType { get; set; } | |||||
| public string TrnxAMT { get; set; } | |||||
| public string MerchantTrnxNo { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| public string TrnxStatus { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,13 @@ | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| public static class TrxStatus | |||||
| { | |||||
| public const string CANCEL = "5"; | |||||
| public const string CHECK = "1"; | |||||
| public const string FAILURE = "3"; | |||||
| public const string NO_RESPONSE = "9"; | |||||
| public const string ORIGINAL = "0"; | |||||
| public const string REJECT = "4"; | |||||
| public const string SUCCESS = "2"; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,17 @@ | |||||
| namespace BWP.ABCClient.B2B | |||||
| { | |||||
| public static class TrxType | |||||
| { | |||||
| public static string DownloadTrnx = "DownloadTrnx"; | |||||
| public static string Freeze = "Freeze"; | |||||
| public static string FreezeResult = "FreezeResult"; | |||||
| public static string FreezeTransfer = "FreezeTransfer"; | |||||
| public static string FundTransfer = "FundTransfer"; | |||||
| public static string PartFreezeTransfer = "PartFreezeTransfer"; | |||||
| public static string PartUnFreeze = "PartUnFreeze"; | |||||
| public static string PayFee = "PayFee"; | |||||
| public static string QueryTrnx = "QueryTrnx"; | |||||
| public static string UnFreeze = "UnFreeze"; | |||||
| public static string UnFreezeResult = "UnFreezeResult"; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,232 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using System.Security.Cryptography; | |||||
| using System.Net; | |||||
| using System.IO; | |||||
| using System.Security; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public abstract class OnlineRemitBaseRequest | |||||
| { | |||||
| protected abstract void checkRequest(); | |||||
| protected abstract XmlDocument createMessage(); | |||||
| XmlDocument verifySign(XmlDocument aMessage) | |||||
| { | |||||
| XmlDocument document = aMessage.GetValue("Message"); | |||||
| if (document == null) | |||||
| { | |||||
| throw new OnlineRemitException("1301", "网上支付平台的响应报文不完整", "无[Message]段!"); | |||||
| } | |||||
| if (aMessage.GetValueNoNull("Signature-Algorithm") == null) | |||||
| { | |||||
| throw new OnlineRemitException("1301", "网上支付平台的响应报文不完整", "无[Signature-Algorithm]段!"); | |||||
| } | |||||
| string data = aMessage.GetValueNoNull("Signature"); | |||||
| if (data == null) | |||||
| { | |||||
| throw new OnlineRemitException("1301", "网上支付平台的响应报文不完整", "无[Signature]段!"); | |||||
| } | |||||
| byte[] rgbSignature = Convert.FromBase64String(data); | |||||
| try | |||||
| { | |||||
| SHA1Managed managed = new SHA1Managed(); | |||||
| byte[] rgbHash = managed.ComputeHash(Encoding.GetEncoding("gb2312").GetBytes(document.ToString())); | |||||
| RSACryptoServiceProvider provider = new RSACryptoServiceProvider(new CspParameters { Flags = CspProviderFlags.UseMachineKeyStore }); | |||||
| //RSAParameters parameters = TrustpayCertificate.GetPublicKey().ExportParameters(); | |||||
| RSAParameters parameters = new RSAParameters() { Exponent = OnlineRemitConfig.GetCertificate().GetPublicKey() }; | |||||
| provider.ImportParameters(parameters); | |||||
| bool flag = provider.VerifyHash(rgbHash, CryptoConfig.MapNameToOID("SHA1"), rgbSignature); | |||||
| managed.Clear(); | |||||
| provider.Clear(); | |||||
| if (!flag) | |||||
| { | |||||
| throw new OnlineRemitException("1302", "网上支付平台的响应报文签名验证失败"); | |||||
| } | |||||
| } | |||||
| catch (OnlineRemitException exception) | |||||
| { | |||||
| throw exception; | |||||
| } | |||||
| catch (Exception exception2) | |||||
| { | |||||
| throw new OnlineRemitException("1302", "网上支付平台的响应报文签名验证失败 - " + exception2.Message); | |||||
| } | |||||
| return document; | |||||
| } | |||||
| string ECMerchantType = "B2C"; | |||||
| /// <summary> | |||||
| /// 商户编号 | |||||
| /// </summary> | |||||
| public string MerchantID { get; set; } | |||||
| XmlDocument sendMessage(XmlDocument aMessage) | |||||
| { | |||||
| Exception exception; | |||||
| string s = "<MSG>" + aMessage.ToString() + "</MSG>"; | |||||
| int length = 0; | |||||
| try | |||||
| { | |||||
| length = Encoding.UTF8.GetBytes(s).Length; | |||||
| } | |||||
| catch (Exception exception1) | |||||
| { | |||||
| exception = exception1; | |||||
| throw new OnlineRemitException("1999", "系统发生无法预期的错误", exception.Message); | |||||
| } | |||||
| HttpWebRequest request = null; | |||||
| BufferedStream stream = null; | |||||
| HttpWebResponse response = null; | |||||
| string aXMLString = ""; | |||||
| XmlDocument document = null; | |||||
| string str3 = OnlineRemitConfig.TrustPayConnectMethod + "://" + OnlineRemitConfig.TrustPayServerName; | |||||
| if ((OnlineRemitConfig.TrustPayConnectMethod.Equals("https") && (OnlineRemitConfig.TrustPayServerPort != 0x1bb)) || (OnlineRemitConfig.TrustPayConnectMethod.Equals("http") && (OnlineRemitConfig.TrustPayServerPort != 80))) | |||||
| { | |||||
| str3 = str3 + ":" + OnlineRemitConfig.TrustPayServerPort; | |||||
| } | |||||
| try | |||||
| { | |||||
| request = (HttpWebRequest)WebRequest.Create(str3 + OnlineRemitConfig.TrustPayTrxURL); | |||||
| request.Method = "POST"; | |||||
| request.ProtocolVersion = HttpVersion.Version10; | |||||
| request.ContentType = "application/x-www-form-urlencoded"; | |||||
| //this.iLogWriter.log("成功"); | |||||
| //this.iLogWriter.logNewLine("提交交易报文:"); | |||||
| byte[] bytes = Encoding.UTF8.GetBytes(s); | |||||
| request.ContentLength = bytes.Length; | |||||
| stream = new BufferedStream(request.GetRequestStream()); | |||||
| if (!stream.CanWrite) | |||||
| { | |||||
| throw new OnlineRemitException("1201", "无法连线网上支付平台", "无法连线到[" + str3 + "]"); | |||||
| } | |||||
| stream.Write(bytes, 0, bytes.Length); | |||||
| stream.Flush(); | |||||
| stream.Close(); | |||||
| //this.iLogWriter.log("成功"); | |||||
| //this.iLogWriter.logNewLine("等待网上支付平台返回交易结果:"); | |||||
| response = (HttpWebResponse)request.GetResponse(); | |||||
| Stream responseStream = response.GetResponseStream(); | |||||
| Encoding encoding = Encoding.GetEncoding("gb2312"); | |||||
| StreamReader reader = new StreamReader(responseStream, encoding); | |||||
| string str4 = null; | |||||
| while ((str4 = reader.ReadLine()) != null) | |||||
| { | |||||
| aXMLString = aXMLString + str4; | |||||
| if (str4.IndexOf("</MSG>") != -1) | |||||
| { | |||||
| break; | |||||
| } | |||||
| } | |||||
| response.Close(); | |||||
| //this.iLogWriter.log("成功"); | |||||
| //this.iLogWriter.logNewLine("返回报文:"); | |||||
| //this.iLogWriter.log("\n" + aXMLString.ToString()); | |||||
| if (response.StatusCode != HttpStatusCode.OK) | |||||
| { | |||||
| throw new OnlineRemitException("1206", "网上支付平台服务暂时停止"); | |||||
| } | |||||
| document = new XmlDocument(aXMLString).GetValue("MSG"); | |||||
| if (document == null) | |||||
| { | |||||
| throw new OnlineRemitException("1205", "无法辨识网上支付平台的响应报文", "无[MSG]段!"); | |||||
| } | |||||
| } | |||||
| catch (WebException exception2) | |||||
| { | |||||
| //this.iLogWriter.logNewLine(exception2.ToString()); | |||||
| throw new OnlineRemitException("1201", "无法连线网上支付平台", "无法连线到[" + str3 + "], " + exception2.Message); | |||||
| } | |||||
| catch (IOException exception3) | |||||
| { | |||||
| //this.iLogWriter.logNewLine(exception3.ToString()); | |||||
| throw new OnlineRemitException("1202", "提交交易时发生网络错误", "连线中断!"); | |||||
| } | |||||
| catch (SecurityException exception4) | |||||
| { | |||||
| //this.iLogWriter.logNewLine(exception4.ToString()); | |||||
| throw new OnlineRemitException("1201", "无法连线网上支付平台", "进程权限太低!"); | |||||
| } | |||||
| catch (OnlineRemitException exception5) | |||||
| { | |||||
| throw exception5; | |||||
| } | |||||
| catch (Exception exception10) | |||||
| { | |||||
| exception = exception10; | |||||
| //this.iLogWriter.logNewLine(exception.StackTrace); | |||||
| throw new OnlineRemitException("1201", "无法连线网上支付平台", exception.StackTrace); | |||||
| } | |||||
| finally | |||||
| { | |||||
| if (stream != null) | |||||
| { | |||||
| try | |||||
| { | |||||
| stream.Close(); | |||||
| } | |||||
| catch (Exception) | |||||
| { | |||||
| } | |||||
| } | |||||
| if (response != null) | |||||
| { | |||||
| try | |||||
| { | |||||
| response.Close(); | |||||
| } | |||||
| catch (Exception) | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| return document; | |||||
| } | |||||
| /// <summary> | |||||
| /// 在消息头部加上商户信息 | |||||
| /// </summary> | |||||
| /// <param name="aMessage"></param> | |||||
| /// <returns></returns> | |||||
| XmlDocument composeRequestMessage(XmlDocument aMessage) | |||||
| { | |||||
| return new XmlDocument("<Merchant><ECMerchantType>" + ECMerchantType + "</ECMerchantType><MerchantID>" + MerchantID + "</MerchantID></Merchant>" + aMessage.ToString()); | |||||
| } | |||||
| /// <summary> | |||||
| /// 加入签名信息 | |||||
| /// </summary> | |||||
| /// <param name="aMessage"></param> | |||||
| /// <returns></returns> | |||||
| XmlDocument fileSignMessage(XmlDocument aMessage) | |||||
| { | |||||
| RSACryptoServiceProvider provider = OnlineRemitConfig.GetMerchantKey(MerchantID); | |||||
| byte[] rgbHash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(aMessage.ToString())); | |||||
| byte[] data = provider.SignHash(rgbHash, CryptoConfig.MapNameToOID("SHA1")); | |||||
| string str = Convert.ToBase64String(data); | |||||
| return new XmlDocument("<Message>" + aMessage.ToString() + "</Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>" + str + "</Signature>"); | |||||
| } | |||||
| protected XmlDocument Send() | |||||
| { | |||||
| checkRequest(); | |||||
| var message = createMessage(); | |||||
| message = composeRequestMessage(message); | |||||
| message = fileSignMessage(message); | |||||
| message = sendMessage(message); | |||||
| message = verifySign(message); | |||||
| return message; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,72 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using System.Security.Cryptography; | |||||
| using System.Security.Cryptography.X509Certificates; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public class OnlineRemitConfig | |||||
| { | |||||
| /// <summary> | |||||
| /// 网上支付平台通讯方式(http / https) | |||||
| /// </summary> | |||||
| public static string TrustPayConnectMethod | |||||
| { | |||||
| get | |||||
| { | |||||
| return "https"; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// 网上支付平台服务器名 | |||||
| /// </summary> | |||||
| public static string TrustPayServerName | |||||
| { | |||||
| get | |||||
| { | |||||
| return "www.95599.cn"; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// 网上支付平台交易端口 | |||||
| /// </summary> | |||||
| public static int TrustPayServerPort | |||||
| { | |||||
| get | |||||
| { | |||||
| return 443; | |||||
| } | |||||
| } | |||||
| public static string TrustPayTrxURL | |||||
| { | |||||
| get | |||||
| { | |||||
| return "/b2c/trustpay/ReceiveMerchantTrxReqServlet"; | |||||
| } | |||||
| } | |||||
| /// <summary> | |||||
| /// 得到商户的签名 | |||||
| /// </summary> | |||||
| /// <param name="MerchantID"></param> | |||||
| /// <returns></returns> | |||||
| internal static RSACryptoServiceProvider GetMerchantKey(string MerchantID) | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| /// <summary> | |||||
| /// 得到农行公钥 | |||||
| /// </summary> | |||||
| /// <returns></returns> | |||||
| internal static X509Certificate2 GetCertificate() | |||||
| { | |||||
| throw new NotImplementedException(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,25 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public class OnlineRemitException : Exception | |||||
| { | |||||
| public string Code { get; set; } | |||||
| public string DetailMessage { get; set; } | |||||
| public OnlineRemitException(string code, string message, string detailMessage):base(string.Format("{0}:{1}",message,detailMessage)) | |||||
| { | |||||
| Code = code; | |||||
| DetailMessage = detailMessage; | |||||
| } | |||||
| public OnlineRemitException(string code, string message):this(code,message,"") | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,63 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using System.Globalization; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public class OnlineRemitQueryResultRequest:OnlineRemitBaseRequest | |||||
| { | |||||
| public string SerialNumber { get; set; } | |||||
| public string ReceiveAccount { get; set; } | |||||
| public DateTime? StartDate { get; set; } | |||||
| public DateTime? EndDate { get; set; } | |||||
| protected override void checkRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SerialNumber) && string.IsNullOrEmpty(ReceiveAccount)) | |||||
| { | |||||
| throw new OnlineRemitException("1100", "商户提交的交易资料不合法", "付款流水号和收款方账号同时为空"); | |||||
| } | |||||
| if (StartDate == null) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "起始日期格式不正确"); | |||||
| } | |||||
| if (EndDate == null) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "截止日期格式不正确"); | |||||
| } | |||||
| } | |||||
| protected override XmlDocument createMessage() | |||||
| { | |||||
| return new XmlDocument(new StringBuilder("") | |||||
| .Append("<TrxRequest>") | |||||
| .Append("<TrxType>OnlineRmtQueryResult</TrxType>") | |||||
| .AppendFormat("<SerialNumber>{0}</SerialNumber>",SerialNumber) | |||||
| .AppendFormat("<ReceiveAccount>{0}</ReceiveAccount>",ReceiveAccount) | |||||
| .AppendFormat("<StartTime>{0}</StartTime>",FormatDate(StartDate.Value)) | |||||
| .AppendFormat("<EndTime>{0}</EndTime>",FormatDate(EndDate.Value)) | |||||
| .Append("</TrxRequest>").ToString()); | |||||
| } | |||||
| private string FormatDate(DateTime date) | |||||
| { | |||||
| return date.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture); | |||||
| } | |||||
| public OnlineRemitQueryResultResponse GetResponse() | |||||
| { | |||||
| var message = base.Send(); | |||||
| return new OnlineRemitQueryResultResponse(message); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public class OnlineRemitQueryResultResponse | |||||
| { | |||||
| private XmlDocument mMessage; | |||||
| public OnlineRemitQueryResultResponse(XmlDocument message) | |||||
| { | |||||
| mMessage = message; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,169 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using System.Security.Cryptography; | |||||
| using System.Net; | |||||
| using System.IO; | |||||
| using System.Security; | |||||
| using System.Security.Cryptography.X509Certificates; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| /// <summary> | |||||
| /// 网付通,在线付款 | |||||
| /// </summary> | |||||
| public class OnlineRemitRequest:OnlineRemitBaseRequest | |||||
| { | |||||
| /// <summary> | |||||
| /// 总笔数 | |||||
| /// </summary> | |||||
| public int TotalCount { get; set; } | |||||
| /// <summary> | |||||
| /// 总金额 | |||||
| /// </summary> | |||||
| public double TotalAmount { get; set; } | |||||
| /// <summary> | |||||
| /// 序号 | |||||
| /// </summary> | |||||
| public string SerialNumber { get; set; } | |||||
| /// <summary> | |||||
| /// 备注 | |||||
| /// </summary> | |||||
| public string Remark { get; set; } | |||||
| /// <summary> | |||||
| /// 0:无需操作员确认直接付款;1:需要操作员在商户服务系统确认后付款 | |||||
| /// </summary> | |||||
| public int CheckType { get; set; } | |||||
| List<OnlineRemitRequest_Detail> mDetails = new List<OnlineRemitRequest_Detail>(); | |||||
| public List<OnlineRemitRequest_Detail> Details | |||||
| { | |||||
| get | |||||
| { | |||||
| return mDetails; | |||||
| } | |||||
| } | |||||
| public OnlineRemitResponse GetResponse() | |||||
| { | |||||
| var message = base.Send(); | |||||
| OnlineRemitResponse response = new OnlineRemitResponse(message); | |||||
| return response; | |||||
| } | |||||
| protected override XmlDocument createMessage() | |||||
| { | |||||
| StringBuilder builder = new StringBuilder("").Append("<TrxRequest>").Append("<TrxType>").Append("OnlineRemit").Append("</TrxType>") | |||||
| .Append("<CheckType>").Append(CheckType).Append("</CheckType>") | |||||
| .Append("<SerialNumber>").Append(SerialNumber).Append("</SerialNumber>") | |||||
| .Append("<TotalCount>").Append(TotalCount).Append("</TotalCount>") | |||||
| .Append("<TotalAmount>").Append(TotalAmount).Append("</TotalAmount>") | |||||
| .Append("<Remark>").Append(Remark).Append("</Remark>"); | |||||
| builder.Append("<RemitData>"); | |||||
| foreach (var detail in this.Details) | |||||
| { | |||||
| builder.Append("<RemitDetail>") | |||||
| .Append("<NO>").Append(detail.NO).Append("</NO>") | |||||
| .Append("<CardNo>").Append(detail.CardNo).Append("</CardNo>") | |||||
| .Append("<CardName>").Append(detail.CardName).Append("</CardName>") | |||||
| .Append("<RemitAmount>").Append(detail.Amount).Append("</RemitAmount>") | |||||
| .Append("<Purpose>").Append(detail.Purpose).Append("</Purpose>") | |||||
| .Append("</RemitDetail>"); | |||||
| } | |||||
| builder.Append("</RemitData>").Append("</TrxRequest>"); | |||||
| return new XmlDocument(builder.ToString()); | |||||
| } | |||||
| public static bool isValidAmount(double aAmount, int aExp) | |||||
| { | |||||
| bool flag = false; | |||||
| if (aExp >= 0) | |||||
| { | |||||
| string str = aAmount.ToString(); | |||||
| int index = str.IndexOf('.'); | |||||
| if (index == -1) | |||||
| { | |||||
| return true; | |||||
| } | |||||
| if (index >= ((str.Length - aExp) - 1)) | |||||
| { | |||||
| flag = true; | |||||
| } | |||||
| } | |||||
| return flag; | |||||
| } | |||||
| protected override void checkRequest() | |||||
| { | |||||
| if (TotalCount != Details.Count) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款总笔数与明细笔数不一致!"); | |||||
| } | |||||
| if (SerialNumber.Trim().Equals("")) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款流水号不能为空!"); | |||||
| } | |||||
| if (TotalCount <= 0) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款交易总笔数不能小于1笔"); | |||||
| } | |||||
| if (TotalCount > 100) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款交易总笔数不能大于100笔"); | |||||
| } | |||||
| if (TotalAmount <= 0.0) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款交易总金额不合法!"); | |||||
| } | |||||
| if (!(isValidAmount(TotalAmount, 2) && (TotalAmount > 0.0))) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款交易总金额不合法!"); | |||||
| } | |||||
| var noDic = new Dictionary<int, int>(); | |||||
| foreach (var detail in this.Details) | |||||
| { | |||||
| if (noDic.ContainsKey(detail.NO)) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "批次内序号重复"); | |||||
| } | |||||
| else | |||||
| { | |||||
| noDic.Add(detail.NO, detail.NO); | |||||
| } | |||||
| if (detail.NO < 0 || detail.NO > 99999) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "批次内序号需要在1至5位之间:" + detail.NO); | |||||
| } | |||||
| if (string.IsNullOrEmpty(detail.CardNo)) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款明细卡号不能为空!"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(detail.CardName)) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款明细收款人信息不能为空!"); | |||||
| } | |||||
| if (!(isValidAmount(detail.Amount, 2) && (detail.Amount > 0.0))) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "付款交易明细金额不合法:" + detail.Amount.ToString()); | |||||
| } | |||||
| if (detail.Purpose.Length > 30) | |||||
| { | |||||
| throw new OnlineRemitException("1101", "商户提交的交易资料不合法", "明细内容不能超过30个字:" + detail.Purpose); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,38 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| public class OnlineRemitRequest_Detail | |||||
| { | |||||
| /// <summary> | |||||
| /// 序号 | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// 格式化为3位 | |||||
| /// </remarks> | |||||
| public int NO { get; set; } | |||||
| /// <summary> | |||||
| /// 收款方账号 | |||||
| /// </summary> | |||||
| public string CardNo { get; set; } | |||||
| /// <summary> | |||||
| /// 收款方户名 | |||||
| /// </summary> | |||||
| public string CardName { get; set; } | |||||
| /// <summary> | |||||
| /// 金额 | |||||
| /// </summary> | |||||
| public double Amount { get; set; } | |||||
| /// <summary> | |||||
| /// 用途 | |||||
| /// </summary> | |||||
| public string Purpose { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,74 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| namespace BWP.ABCClient.B2C.OnlineRemits | |||||
| { | |||||
| /// <summary> | |||||
| /// 网付通返回 | |||||
| /// </summary> | |||||
| public class OnlineRemitResponse | |||||
| { | |||||
| public string ErrorMessage | |||||
| { | |||||
| get; | |||||
| private set; | |||||
| } | |||||
| public string ReturnCode | |||||
| { | |||||
| get; | |||||
| private set; | |||||
| } | |||||
| XmlDocument mMessage = new XmlDocument(""); | |||||
| public const string RC_SUCCESS = "0000"; | |||||
| public OnlineRemitResponse(XmlDocument message) | |||||
| { | |||||
| mMessage = message; | |||||
| } | |||||
| protected internal OnlineRemitResponse() | |||||
| { | |||||
| } | |||||
| public OnlineRemitResponse(string aReturnCode, string aErrorMessage) | |||||
| { | |||||
| ReturnCode = aReturnCode; | |||||
| ErrorMessage = aErrorMessage; | |||||
| } | |||||
| void init(XmlDocument aXMLDocument) | |||||
| { | |||||
| XmlDocument returnCode = aXMLDocument.GetValue("ReturnCode"); | |||||
| if (returnCode == null) | |||||
| { | |||||
| throw new OnlineRemitException("1303", "无法辨识网上支付平台的交易结果", "无法取得[ReturnCode]!"); | |||||
| } | |||||
| ReturnCode = returnCode.ToString(); | |||||
| if (!Success) | |||||
| { | |||||
| XmlDocument errorMessage = aXMLDocument.GetValue("ErrorMessage"); | |||||
| if (errorMessage != null) | |||||
| { | |||||
| ErrorMessage = errorMessage.ToString(); | |||||
| } | |||||
| else | |||||
| { | |||||
| ErrorMessage = "未能返回错误信息"; | |||||
| } | |||||
| } | |||||
| } | |||||
| public bool Success | |||||
| { | |||||
| get | |||||
| { | |||||
| return RC_SUCCESS.Equals(ReturnCode); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| public class OrderContent | |||||
| { | |||||
| public string OrderNo { get; set; } | |||||
| public string OrderAmount { get; set; } | |||||
| public string OrderDesc { get; set; } | |||||
| public string OrderDate { get; set; } | |||||
| public string OrderTime { get; set; } | |||||
| public string OrderURL { get; set; } | |||||
| public string PayAmount { get; set; } | |||||
| public string RefundAmount { get; set; } | |||||
| public string OrderStatus { get; set; } | |||||
| public OrderItem[] OrderItems { get; set; } | |||||
| } | |||||
| public class OrderItem { } | |||||
| } | |||||
| @ -0,0 +1,64 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class PaymentRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static PaymentRequest New() | |||||
| { | |||||
| return new PaymentRequest { | |||||
| Message = new MessageContent { | |||||
| Merchant = new MerchantContent { | |||||
| ECMerchantType = "B2C", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| TrxRequest = new TrxRequestContent { | |||||
| TrxType = TrxType.PayReq, | |||||
| Order = new OrderContent { | |||||
| OrderNo = string.Empty, | |||||
| OrderAmount = string.Empty, | |||||
| OrderDesc = string.Empty, | |||||
| OrderDate = string.Empty, | |||||
| OrderTime = string.Empty, | |||||
| OrderURL = string.Empty, | |||||
| PayAmount = null, | |||||
| RefundAmount = null, | |||||
| OrderStatus = null, | |||||
| OrderItems = new OrderItem[]{} | |||||
| }, | |||||
| ProductType = "2", | |||||
| PaymentType = "1", | |||||
| NotifyType = "1", | |||||
| ResultNotifyURL = string.Empty, | |||||
| MerchantRemarks = string.Empty, | |||||
| PaymentLinkType = "1" | |||||
| } | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxRequestContent TrxRequest { get; set; } | |||||
| } | |||||
| public class TrxRequestContent | |||||
| { | |||||
| public string TrxType { get; set; } | |||||
| public OrderContent Order { get; set; } | |||||
| public string ProductType { get; set; } | |||||
| public string PaymentType { get; set; } | |||||
| public string NotifyType { get; set; } | |||||
| public string ResultNotifyURL { get; set; } | |||||
| public string MerchantRemarks { get; set; } | |||||
| public string PaymentLinkType { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,32 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class PaymentResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public string TrxType { get; set; } | |||||
| public string OrderNo { get; set; } | |||||
| public string PaymentURL { get; set; } | |||||
| public string OrderAmount { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class QueryOrderRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static QueryOrderRequest New() | |||||
| { | |||||
| return new QueryOrderRequest { | |||||
| Message = new MessageContent { | |||||
| Merchant = new MerchantContent { | |||||
| ECMerchantType = "B2C", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| TrxRequest = new TrxRequestContent { | |||||
| TrxType = TrxType.Query, | |||||
| OrderNo = string.Empty, | |||||
| QueryDetail = "false" | |||||
| } | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxRequestContent TrxRequest { get; set; } | |||||
| } | |||||
| public class TrxRequestContent | |||||
| { | |||||
| public string TrxType { get; set; } | |||||
| public string OrderNo { get; set; } | |||||
| public string QueryDetail { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,26 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class QueryOrderResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public OrderContent Order { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,50 @@ | |||||
| using System; | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class SettleRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static SettleRequest New() | |||||
| { | |||||
| return new SettleRequest { | |||||
| Message = new MessageContent { | |||||
| Merchant = new MerchantContent { | |||||
| ECMerchantType = "B2C", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| TrxRequest = new TrxRequestContent { | |||||
| TrxType = TrxType.Settle, | |||||
| SettleDate = string.Empty, | |||||
| SettleStartHour = "false", | |||||
| SettleEndHour = string.Empty, | |||||
| SettleType = string.Empty, | |||||
| ZIP = "YES" | |||||
| } | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxRequestContent TrxRequest { get; set; } | |||||
| } | |||||
| public class TrxRequestContent | |||||
| { | |||||
| public string TrxType { get; set; } | |||||
| public string SettleDate { get; set; } | |||||
| public string SettleStartHour { get; set; } | |||||
| public string SettleEndHour { get; set; } | |||||
| public string SettleType { get; set; } | |||||
| public string ZIP { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,71 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class SettleResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| private string _zipDetailRecords; | |||||
| public string ZIPDetailRecords | |||||
| { | |||||
| get { return _zipDetailRecords; } | |||||
| set | |||||
| { | |||||
| _zipDetailRecords = value; | |||||
| SetDetailRecords(value); | |||||
| } | |||||
| } | |||||
| private void SetDetailRecords(string value) | |||||
| { | |||||
| if (string.IsNullOrEmpty(value)) { | |||||
| return; | |||||
| } | |||||
| string innerXml = MsgUtil.DeCompress(value); | |||||
| string xml = "<Records>" + innerXml + "</Records>"; | |||||
| var records = MsgUtil.GetMultiInnerXml(xml, "//Record"); | |||||
| var recordList = new List<Record>(records.Length); | |||||
| foreach (var record in records) { | |||||
| var recordCols = record.Split(new[] {','}, StringSplitOptions.None); | |||||
| recordList.Add(new Record { | |||||
| Sign = recordCols[0], | |||||
| OrderNumber = recordCols[1], | |||||
| Amount = recordCols[2], | |||||
| DaySeqNo = recordCols[3], | |||||
| Date = recordCols[4] | |||||
| }); | |||||
| } | |||||
| DetailRecords = recordList.ToArray(); | |||||
| } | |||||
| public Record[] DetailRecords { get; set; } | |||||
| } | |||||
| } | |||||
| public class Record | |||||
| { | |||||
| public string Sign { get; set; } | |||||
| public string OrderNumber { get; set; } | |||||
| public string Amount { get; set; } | |||||
| public string DaySeqNo { get; set; } | |||||
| public string Date { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,16 @@ | |||||
| namespace BWP.ABCClient.B2C | |||||
| { | |||||
| public class TrxType | |||||
| { | |||||
| public const string FundPayReq = "FundPayReq"; | |||||
| public const string MobilePayReq = "MobilePayReq"; | |||||
| public const string MobilePayReg = "MobilePayReg"; | |||||
| public const string PayReq = "PayReq"; | |||||
| public const string PayResult = "PayResult"; | |||||
| public const string Query = "Query"; | |||||
| public const string Refund = "Refund"; | |||||
| public const string Settle = "Settle"; | |||||
| public const string VoidPay = "VoidPay"; | |||||
| public const string VoidRefund = "VoidRefund"; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,151 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
| <PropertyGroup> | |||||
| <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
| <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
| <ProductVersion>8.0.30703</ProductVersion> | |||||
| <SchemaVersion>2.0</SchemaVersion> | |||||
| <ProjectGuid>{22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}</ProjectGuid> | |||||
| <OutputType>Library</OutputType> | |||||
| <AppDesignerFolder>Properties</AppDesignerFolder> | |||||
| <RootNamespace>BWP.ABCClient</RootNamespace> | |||||
| <AssemblyName>BWP.ABCClient</AssemblyName> | |||||
| <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||||
| <FileAlignment>512</FileAlignment> | |||||
| <KeyContainerName>BwpApp</KeyContainerName> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||||
| <DebugSymbols>true</DebugSymbols> | |||||
| <DebugType>full</DebugType> | |||||
| <Optimize>false</Optimize> | |||||
| <OutputPath>bin\Debug\</OutputPath> | |||||
| <DefineConstants>DEBUG;TRACE</DefineConstants> | |||||
| <ErrorReport>prompt</ErrorReport> | |||||
| <WarningLevel>4</WarningLevel> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||||
| <DebugType>pdbonly</DebugType> | |||||
| <Optimize>true</Optimize> | |||||
| <OutputPath>bin\Release\</OutputPath> | |||||
| <DefineConstants>TRACE</DefineConstants> | |||||
| <ErrorReport>prompt</ErrorReport> | |||||
| <WarningLevel>4</WarningLevel> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <Reference Include="Forks.Utils, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7254430f49d10aae, processorArchitecture=MSIL"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| <HintPath>..\..\..\tsref\Debug\Forks.Utils.dll</HintPath> | |||||
| <Private>False</Private> | |||||
| </Reference> | |||||
| <Reference Include="System"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Core"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Security"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Xml.Linq"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Data.DataSetExtensions"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="Microsoft.CSharp"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Data"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Xml"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="Wpf, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a04fa581c0f74d43, processorArchitecture=MSIL"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| <HintPath>..\..\..\tsref\Debug\Wpf.dll</HintPath> | |||||
| <Private>False</Private> | |||||
| </Reference> | |||||
| <Reference Include="Wpf.System, Version=1.3.0.0, Culture=neutral, PublicKeyToken=a04fa581c0f74d43, processorArchitecture=MSIL"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| <HintPath>..\..\..\tsref\Debug\Wpf.System.dll</HintPath> | |||||
| <Private>False</Private> | |||||
| </Reference> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <Compile Include="..\..\..\version\tslib_version.cs"> | |||||
| <Link>tslib_version.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitBaseRequest.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitConfig.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitQueryResultRequest.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitQueryResultResponse.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitRequest.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitRequest_Detail.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitResponse.cs" /> | |||||
| <Compile Include="B2C\OnlineRemits\OnlineRemitException.cs" /> | |||||
| <Compile Include="Businesses\MarketOrderPay.cs" /> | |||||
| <Compile Include="Businesses\XMLDocument.cs" /> | |||||
| <Compile Include="Businesses\MarketOrderApply.cs" /> | |||||
| <Compile Include="Businesses\IReturnedResult.cs" /> | |||||
| <Compile Include="Businesses\ResultB2CReturned.cs" /> | |||||
| <Compile Include="Businesses\ResultB2BReturned.cs" /> | |||||
| <Compile Include="B2B\QueryTrnxResponse.cs" /> | |||||
| <Compile Include="B2B\QueryTrnxRequest.cs" /> | |||||
| <Compile Include="B2B\TrxStatus.cs" /> | |||||
| <Compile Include="B2B\TrxType.cs" /> | |||||
| <Compile Include="B2C\SettleResponse.cs" /> | |||||
| <Compile Include="B2C\OrderContent.cs" /> | |||||
| <Compile Include="B2C\QueryOrderResponse.cs" /> | |||||
| <Compile Include="B2C\SettleRequest.cs" /> | |||||
| <Compile Include="B2C\QueryOrderRequest.cs" /> | |||||
| <Compile Include="B2C\TrxType.cs" /> | |||||
| <Compile Include="Businesses\B2BReceivingPayment.cs" /> | |||||
| <Compile Include="Businesses\B2BDealQuery.cs" /> | |||||
| <Compile Include="Businesses\B2CReceivingPayment.cs" /> | |||||
| <Compile Include="Businesses\B2COrderQuery.cs" /> | |||||
| <Compile Include="Businesses\B2CSettleByDate.cs" /> | |||||
| <Compile Include="Businesses\MarketReceivingPayment.cs" /> | |||||
| <Compile Include="Businesses\MarketSignOff.cs" /> | |||||
| <Compile Include="Businesses\MarketSignUp.cs" /> | |||||
| <Compile Include="Exceptions\ResponseException.cs" /> | |||||
| <Compile Include="Log\AbcLog.cs" /> | |||||
| <Compile Include="Market\OrderPayResponse.cs" /> | |||||
| <Compile Include="Market\OrderApplyResponse.cs" /> | |||||
| <Compile Include="Market\OrderApplyRequest.cs" /> | |||||
| <Compile Include="Market\MarketResponse.cs" /> | |||||
| <Compile Include="Businesses\Type\B2B.cs" /> | |||||
| <Compile Include="Businesses\BusinessBase.cs" /> | |||||
| <Compile Include="Businesses\Type\BusinessTypes.cs" /> | |||||
| <Compile Include="Businesses\Type\Market.cs" /> | |||||
| <Compile Include="Businesses\Type\B2C.cs" /> | |||||
| <Compile Include="Businesses\Type\IBusinessType.cs" /> | |||||
| <Compile Include="Exceptions\HttpException.cs" /> | |||||
| <Compile Include="Market\OrderPayRequest.cs" /> | |||||
| <Compile Include="Market\PayRequest.cs" /> | |||||
| <Compile Include="Market\SignOffRequest.cs" /> | |||||
| <Compile Include="Market\SignUpRequest.cs" /> | |||||
| <Compile Include="Request.cs" /> | |||||
| <Compile Include="B2B\FundTransferRequest.cs" /> | |||||
| <Compile Include="B2B\FundTransferResponse.cs" /> | |||||
| <Compile Include="B2C\PaymentRequest.cs" /> | |||||
| <Compile Include="B2C\PaymentResponse.cs" /> | |||||
| <Compile Include="Exceptions\CertException.cs" /> | |||||
| <Compile Include="CertManager.cs" /> | |||||
| <Compile Include="Common\MerchantContent.cs" /> | |||||
| <Compile Include="Common\MessageBase.cs" /> | |||||
| <Compile Include="MsgUtil.cs" /> | |||||
| <Compile Include="Common\PaymentURLResponse.cs" /> | |||||
| <Compile Include="Properties\AssemblyInfo.cs" /> | |||||
| <Compile Include="RSAService.cs" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup /> | |||||
| <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||||
| <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
| Other similar extension points exist, see Microsoft.Common.targets. | |||||
| <Target Name="BeforeBuild"> | |||||
| </Target> | |||||
| <Target Name="AfterBuild"> | |||||
| </Target> | |||||
| --> | |||||
| </Project> | |||||
| @ -0,0 +1,58 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.B2B; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class B2BDealQuery : BusinessBase<QueryTrnxRequest, QueryTrnxResponse> | |||||
| { | |||||
| public B2BDealQuery() : base(BusinessTypes.B2B) | |||||
| { | |||||
| RequestObj = QueryTrnxRequest.New(); | |||||
| } | |||||
| public string MerchantTrnxNo { get; set; } | |||||
| public DealStatusEnum DealStatus { get; set; } | |||||
| public bool DealIsSuccess { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.TrxResponse.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", ResponseObj.Message.TrxResponse.ErrorMessage)); | |||||
| if (ResponseObj.Message.TrxResponse.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.TrxResponse.ReturnCode, ResponseObj.Message.TrxResponse.ErrorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| DealIsSuccess = ResponseObj.Message.TrxResponse.TrnxStatus == ((int)DealStatusEnum.交易成功).ToString(); | |||||
| DealStatusEnum dealStatus; | |||||
| if (DealStatusEnum.TryParse(ResponseObj.Message.TrxResponse.TrnxStatus, out dealStatus)) { | |||||
| DealStatus = dealStatus; | |||||
| } | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(MerchantTrnxNo)) { | |||||
| throw new Exception("查询的交易号不能为空,B2BGathering.MerchantTrnxNo"); | |||||
| } | |||||
| RequestObj.Message.Merchant.MerchantID = MerchantID; | |||||
| RequestObj.Message.TrxRequest.MerchantTrnxNo = MerchantTrnxNo; | |||||
| RequestObj.Message.TrxRequest.MerchantRemarks = Remarks; | |||||
| } | |||||
| } | |||||
| public enum DealStatusEnum | |||||
| { | |||||
| 交易作废 = 5, | |||||
| 复核中 = 1, | |||||
| 交易失败 = 3, | |||||
| 交易无响应 = 9, | |||||
| 原始请求 = 0, | |||||
| 交易被驳回 = 4, | |||||
| 交易成功 = 2 | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,62 @@ | |||||
| using System; | |||||
| using System.Globalization; | |||||
| using BWP.ABCClient.B2B; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class B2BReceivingPayment : BusinessBase<FundTransferRequest, FundTransferResponse> | |||||
| { | |||||
| public B2BReceivingPayment() : base(BusinessTypes.B2B) | |||||
| { | |||||
| RequestObj = FundTransferRequest.New(); | |||||
| } | |||||
| public string AccountNo { get; set; } | |||||
| public string AccountName { get; set; } | |||||
| public string AccountBank { get; set; } | |||||
| public string Operator { get; set; } | |||||
| public string PaymentUrl { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.TrxResponse.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", ResponseObj.Message.TrxResponse.ErrorMessage)); | |||||
| if (ResponseObj.Message.TrxResponse.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.TrxResponse.ReturnCode, ResponseObj.Message.TrxResponse.ErrorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| PaymentUrl = ResponseObj.Message.TrxResponse.PaymentURL; | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(ResultNotifyURL)) { | |||||
| throw new Exception("接受交易结果信息Url不能为空,ResultNotifyURL"); | |||||
| } | |||||
| if (AccountNo == null) { | |||||
| throw new Exception("收款方帐号不能为空,AccountNo"); | |||||
| } | |||||
| if (Date == null) { | |||||
| throw new Exception("交易日期不能为空,Date"); | |||||
| } | |||||
| RequestObj.Message.Merchant.MerchantID = MerchantID; | |||||
| RequestObj.Message.TrxRequest.AccountDB.AccountDBNo = AccountNo; | |||||
| RequestObj.Message.TrxRequest.AccountDB.AccountDBName = AccountName; | |||||
| RequestObj.Message.TrxRequest.AccountDB.AccountDBBank = AccountBank; | |||||
| RequestObj.Message.TrxRequest.TrnxDate = Date.Value.ToString("yyyy/MM/dd", DateTimeFormatInfo.InvariantInfo); | |||||
| RequestObj.Message.TrxRequest.TrnxTime = Date.Value.ToString("HH:MM:ss", DateTimeFormatInfo.InvariantInfo); | |||||
| RequestObj.Message.TrxRequest.TrnxAmount = Amount.ToString("f2"); | |||||
| RequestObj.Message.TrxRequest.MerchantTrnxNo = SequenceNo; | |||||
| RequestObj.Message.TrxRequest.TrnxInfo.TrnxOpr = Operator; | |||||
| RequestObj.Message.TrxRequest.ResultNotifyURL = ResultNotifyURL; | |||||
| RequestObj.Message.TrxRequest.MerchantRemarks = Remarks; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,53 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.B2C; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class B2COrderQuery : BusinessBase<QueryOrderRequest, QueryOrderResponse> | |||||
| { | |||||
| public B2COrderQuery() | |||||
| : base(BusinessTypes.B2C) | |||||
| { | |||||
| RequestObj = QueryOrderRequest.New(); | |||||
| } | |||||
| public string OrderStatus { get; set; } | |||||
| public bool OrderIsFinished { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.TrxResponse.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", ResponseObj.Message.TrxResponse.ErrorMessage)); | |||||
| if (ResponseObj.Message.TrxResponse.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.TrxResponse.ReturnCode, ResponseObj.Message.TrxResponse.ErrorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| OrderStatus = ResponseObj.Message.TrxResponse.Order.OrderStatus; | |||||
| OrderIsFinished = OrderStatus == OrderStatusEnum.PAY || OrderStatus == OrderStatusEnum.SETTLED; | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("查询的交易号不能为空,SequenceNo"); | |||||
| } | |||||
| RequestObj.Message.Merchant.MerchantID = MerchantID; | |||||
| RequestObj.Message.TrxRequest.OrderNo = SequenceNo; | |||||
| } | |||||
| } | |||||
| public class OrderStatusEnum | |||||
| { | |||||
| public const string CANCEL = "00"; | |||||
| public const string ISSUE = "99"; | |||||
| public const string NEW = "01"; | |||||
| public const string PAY = "03"; | |||||
| public const string REFUND = "05"; | |||||
| public const string SETTLED = "04"; | |||||
| public const string WAIT = "02"; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,56 @@ | |||||
| using System; | |||||
| using System.Globalization; | |||||
| using BWP.ABCClient.B2C; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class B2CReceivingPayment : BusinessBase<PaymentRequest, PaymentResponse> | |||||
| { | |||||
| public B2CReceivingPayment() : base(BusinessTypes.B2C) | |||||
| { | |||||
| RequestObj = PaymentRequest.New(); | |||||
| } | |||||
| public string OrderUrl { get; set; } | |||||
| public string OrderRemarks { get; set; } | |||||
| public string PaymentUrl { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.TrxResponse.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", ResponseObj.Message.TrxResponse.ErrorMessage)); | |||||
| if (ResponseObj.Message.TrxResponse.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.TrxResponse.ReturnCode, ResponseObj.Message.TrxResponse.ErrorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| PaymentUrl = ResponseObj.Message.TrxResponse.PaymentURL; | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(ResultNotifyURL)) { | |||||
| throw new Exception("接受交易结果信息Url不能为空,ResultNotifyURL"); | |||||
| } | |||||
| if (Date == null) { | |||||
| throw new Exception("交易日期不能为空,Date"); | |||||
| } | |||||
| RequestObj.Message.Merchant.MerchantID = MerchantID; | |||||
| RequestObj.Message.TrxRequest.Order.OrderNo = SequenceNo; | |||||
| RequestObj.Message.TrxRequest.Order.OrderAmount = Amount.ToString("f2"); | |||||
| RequestObj.Message.TrxRequest.Order.OrderDesc = OrderRemarks; | |||||
| RequestObj.Message.TrxRequest.Order.OrderDate = Date.Value.ToString("yyyy/MM/dd", DateTimeFormatInfo.InvariantInfo); | |||||
| RequestObj.Message.TrxRequest.Order.OrderTime = Date.Value.ToString("HH:MM:ss", DateTimeFormatInfo.InvariantInfo); | |||||
| RequestObj.Message.TrxRequest.Order.OrderURL = OrderUrl; | |||||
| RequestObj.Message.TrxRequest.ResultNotifyURL = ResultNotifyURL; | |||||
| RequestObj.Message.TrxRequest.MerchantRemarks = Remarks; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,50 @@ | |||||
| using System; | |||||
| using System.Globalization; | |||||
| using BWP.ABCClient.B2C; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class B2CSettleByDate : BusinessBase<SettleRequest, SettleResponse> | |||||
| { | |||||
| public B2CSettleByDate() | |||||
| : base(BusinessTypes.B2C) | |||||
| { | |||||
| RequestObj = SettleRequest.New(); | |||||
| } | |||||
| public Record[] Records { get; set; } | |||||
| public string RecordsHexString { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.TrxResponse.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", ResponseObj.Message.TrxResponse.ErrorMessage)); | |||||
| if (ResponseObj.Message.TrxResponse.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.TrxResponse.ReturnCode, ResponseObj.Message.TrxResponse.ErrorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| Records = ResponseObj.Message.TrxResponse.DetailRecords; | |||||
| RecordsHexString = ResponseObj.Message.TrxResponse.ZIPDetailRecords; | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (Date == null) { | |||||
| throw new Exception("查询的日期不能为空,Date"); | |||||
| } | |||||
| RequestObj.Message.Merchant.MerchantID = MerchantID; | |||||
| RequestObj.Message.TrxRequest.SettleDate = Date.Value.ToString("yyyy/MM/dd", CultureInfo.InvariantCulture); | |||||
| RequestObj.Message.TrxRequest.SettleType = SettleType.TRX; | |||||
| } | |||||
| } | |||||
| public class SettleType | |||||
| { | |||||
| public const string SETTLE = "SETTLE"; | |||||
| public const string TRX = "TRX"; | |||||
| public const string TRX_BYHOUR = "TRXBYHOUR"; | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,111 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Common; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class BusinessBase<T, T1> | |||||
| where T : MessageBase | |||||
| where T1 : MessageBase | |||||
| { | |||||
| private readonly IBusinessType _businessType; | |||||
| public string MerchantID { get; set; } | |||||
| public string RequestUrl { get; set; } | |||||
| public bool IsTestState { get; set; } | |||||
| public T RequestObj { get; set; } | |||||
| public T1 ResponseObj { get; set; } | |||||
| public DateTime? Date { get; set; } | |||||
| public string SequenceNo { get; set; } | |||||
| public decimal Amount { get; set; } | |||||
| public string Remarks { get; set; } | |||||
| public string ResultNotifyURL { get; set; } | |||||
| protected AbcLog Log; | |||||
| public BusinessBase(IBusinessType businessInfo) | |||||
| { | |||||
| _businessType = businessInfo; | |||||
| Log = new AbcLog(businessInfo.Name); | |||||
| } | |||||
| public virtual void Request() | |||||
| { | |||||
| if (RequestObj == null) { | |||||
| throw new Exception("RequestObj不能为空"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(RequestUrl)) { | |||||
| throw new Exception("RequestUrl不能为空"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(MerchantID)) { | |||||
| throw new Exception("MerchantID不能为空"); | |||||
| } | |||||
| BeforeRequest(); | |||||
| RSAService.Sign(RequestObj, MerchantID, _businessType.SignEncoding, _businessType.IsMarket); | |||||
| var request = new Request { | |||||
| RequestEncoding = _businessType.RequestEncoding, | |||||
| ResponseEncoding = _businessType.ResponseEncoding, | |||||
| Url = RequestUrl, | |||||
| Message = SendXml | |||||
| }; | |||||
| Log.AddNewLine(string.Format("{0}交易开始:==========================", string.IsNullOrEmpty(SequenceNo) ? string.Empty : "流水号[" + SequenceNo + "]")); | |||||
| if (_businessType.CompressEnabled) { | |||||
| Log.AddNewLine("压缩前的报文"); | |||||
| Log.AddNewLine(MsgUtil.MsgToBareXml(RequestObj)); | |||||
| } | |||||
| Log.AddNewLine("提交的报文:"); | |||||
| Log.AddNewLine(request.Message); | |||||
| Log.AddNewLine(string.Format("连线网上支付平台:[{0}]", RequestUrl)); | |||||
| string result = request.Run(); | |||||
| string receivedXml = GetReceivedXml(result); | |||||
| Log.AddNewLine("返回报文:"); | |||||
| Log.AddNewLine(receivedXml); | |||||
| Verify(receivedXml); | |||||
| ResponseObj = MsgUtil.ParseXmlToMsg<T1>(receivedXml); | |||||
| AfterRequest(); | |||||
| } | |||||
| protected void Verify(string receivedXml) | |||||
| { | |||||
| if (!RSAService.Verify(receivedXml, _businessType.VerifyEncoding, _businessType.IsMarket, IsTestState)) { | |||||
| Log.AddNewLine("网上支付平台的响应报文签名验证失败"); | |||||
| Log.Commit(); | |||||
| throw new RSAException("网上支付平台的响应报文签名验证失败"); | |||||
| } | |||||
| } | |||||
| protected virtual void BeforeRequest() { } | |||||
| protected virtual void AfterRequest() { } | |||||
| private string GetReceivedXml(string result) | |||||
| { | |||||
| if (_businessType.CompressEnabled) { | |||||
| result = MsgUtil.DeCompress(result); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| public string SendXml | |||||
| { | |||||
| get | |||||
| { | |||||
| var result = MsgUtil.MsgToBareXml(RequestObj); | |||||
| if (_businessType.CompressEnabled) { | |||||
| result = MsgUtil.Compress(result); | |||||
| } | |||||
| return result; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,15 @@ | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public interface IReturnedResult | |||||
| { | |||||
| bool IsValid { get; set; } | |||||
| string ReturnCode { get; set; } | |||||
| string ErrorMessage { get; set; } | |||||
| bool IsSuccess { get; set; } | |||||
| string SequenceNo { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,65 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using BWP.ABCClient.Market; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class MarketOrderApply : BusinessBase<OrderApplyRequest, OrderApplyResponse> | |||||
| { | |||||
| public MarketOrderApply() | |||||
| : base(BusinessTypes.Market) | |||||
| { | |||||
| RequestObj = OrderApplyRequest.New(); | |||||
| } | |||||
| public string BuyerCustomer { get; set; } | |||||
| public string BuyerCustName { get; set; } | |||||
| public string SalerCustomer { get; set; } | |||||
| public string SalerCustName { get; set; } | |||||
| public string PaymentUrl { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| var errorMessage = ResponseObj.Message.Control.ReturnMessage ?? string.Empty ; | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.Control.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", errorMessage)); | |||||
| Log.Commit(); | |||||
| if (ResponseObj.Message.Control.ReturnCode != "0000") { | |||||
| throw new ResponseException(ResponseObj.Message.Control.ReturnCode, errorMessage); | |||||
| } | |||||
| PaymentUrl=ResponseObj.Message.Parameters.ReturnURL; | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(BuyerCustomer)) { | |||||
| throw new Exception("付款帐户不能为空,BuyerCustomer"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(BuyerCustName)) { | |||||
| throw new Exception("付款人不能为空,BuyerCustName"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(SalerCustomer)) { | |||||
| throw new Exception("收款帐户不能为空,SalerCustomer"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(SalerCustName)) { | |||||
| throw new Exception("收款人不能为空,SalerCustName"); | |||||
| } | |||||
| RequestObj.Message.Control.MerchantID = MerchantID; | |||||
| RequestObj.Message.Control.MerchantTrxNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.OrderNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.BuyerCustName = BuyerCustName; | |||||
| RequestObj.Message.Parameters.BuyerCustomer = BuyerCustomer; | |||||
| RequestObj.Message.Parameters.SalerCustName = SalerCustName; | |||||
| RequestObj.Message.Parameters.SalerCustomer = SalerCustomer; | |||||
| RequestObj.Message.Parameters.PayAmount = Amount.ToString("f2"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,49 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using BWP.ABCClient.Market; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class MarketOrderPay : BusinessBase<OrderPayRequest, OrderPayResponse> | |||||
| { | |||||
| public MarketOrderPay() | |||||
| : base(BusinessTypes.Market) | |||||
| { | |||||
| RequestObj = OrderPayRequest.New(); | |||||
| } | |||||
| public string OrderNo { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| public string CustSignInfo2 { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| var errorMessage = ResponseObj.Message.Control.ReturnMessage ?? string.Empty; | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.Control.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", errorMessage)); | |||||
| Log.Commit(); | |||||
| if (ResponseObj.Message.Control.ReturnCode != "0000") { | |||||
| throw new ResponseException(ResponseObj.Message.Control.ReturnCode, errorMessage); | |||||
| } | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(OrderNo)) { | |||||
| throw new Exception("订单号不能为空,OrderNo"); | |||||
| } | |||||
| RequestObj.Message.Control.MerchantID = MerchantID; | |||||
| RequestObj.Message.Control.MerchantTrxNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.OrderNo = OrderNo; | |||||
| RequestObj.Message.Parameters.PayAmount = Amount.ToString("f2"); | |||||
| RequestObj.Message.Parameters.CustSignInfo = CustSignInfo; | |||||
| RequestObj.Message.Parameters.CustSignInfo2 = CustSignInfo2; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,54 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using BWP.ABCClient.Market; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class MarketReceivingPayment : BusinessBase<PayRequest, MarketResponse> | |||||
| { | |||||
| public MarketReceivingPayment() | |||||
| : base(BusinessTypes.Market) | |||||
| { | |||||
| RequestObj = PayRequest.New(); | |||||
| } | |||||
| public string CustomerSignInfo { get; set; } | |||||
| public string CustomerNo { get; set; } | |||||
| public string OrderMessage { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| var errorMessage = (ResponseObj.Message.Control.ReturnMessage ?? string.Empty) + (ResponseObj.Message.Control.ErrorMessage ?? string.Empty); | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.Control.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", errorMessage)); | |||||
| if (ResponseObj.Message.Control.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.Control.ReturnCode, errorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(CustomerSignInfo)) { | |||||
| throw new Exception("客户签名不能为空,CustomerSignInfo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(CustomerNo)) { | |||||
| throw new Exception("客户号不能为空,CustomerSignInfo"); | |||||
| } | |||||
| RequestObj.Message.Control.MerchantID = MerchantID; | |||||
| RequestObj.Message.Control.MerchantTrxNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.CustomerNo = CustomerNo; | |||||
| RequestObj.Message.Parameters.CustSignInfo = CustomerSignInfo; | |||||
| RequestObj.Message.Parameters.CustSignInfo2 = CustomerSignInfo; | |||||
| RequestObj.Message.Parameters.PayAmount = Amount.ToString("f2"); | |||||
| RequestObj.Message.Parameters.OrderMg = OrderMessage; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,51 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using BWP.ABCClient.Market; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class MarketSignOff : BusinessBase<SignOffRequest, MarketResponse> | |||||
| { | |||||
| public MarketSignOff() : base(BusinessTypes.Market) | |||||
| { | |||||
| RequestObj = SignOffRequest.New(); | |||||
| } | |||||
| public string MerchantName { get; set; } | |||||
| public string CustomerSignInfo { get; set; } | |||||
| public string CustomerName { get; set; } | |||||
| public string CustomerNo { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| var errorMessage = ResponseObj.Message.Control.ReturnMessage ?? string.Empty + ResponseObj.Message.Control.ErrorMessage ?? string.Empty; | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.Control.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", errorMessage)); | |||||
| if (ResponseObj.Message.Control.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.Control.ReturnCode, errorMessage); | |||||
| } | |||||
| Log.Commit(); | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(CustomerSignInfo)) { | |||||
| throw new Exception("客户签名不能为空,CustmerSignInfo"); | |||||
| } | |||||
| RequestObj.Message.Control.MerchantID = MerchantID; | |||||
| RequestObj.Message.Control.MerchantTrxNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.CustName = CustomerName; | |||||
| RequestObj.Message.Parameters.CustSignInfo = CustomerSignInfo; | |||||
| RequestObj.Message.Parameters.MerchantName = MerchantName; | |||||
| RequestObj.Message.Parameters.CustomerNo = CustomerNo; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,56 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using BWP.ABCClient.Market; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class MarketSignUp : BusinessBase<SignUpRequest, MarketResponse> | |||||
| { | |||||
| public MarketSignUp() | |||||
| : base(BusinessTypes.Market) | |||||
| { | |||||
| RequestObj = SignUpRequest.New(); | |||||
| NeedTwoCheck = null; | |||||
| } | |||||
| public string MerchantName { get; set; } | |||||
| public string CustomerSignInfo { get; set; } | |||||
| public string CustomerName { get; set; } | |||||
| public string NeedTwoCheck { get; set; } | |||||
| protected override void AfterRequest() | |||||
| { | |||||
| var errorMessage = ResponseObj.Message.Control.ReturnMessage ?? string.Empty + ResponseObj.Message.Control.ErrorMessage ?? string.Empty; | |||||
| Log.AddNewLine(string.Format("交易结果:[{0}]", ResponseObj.Message.Control.ReturnCode)); | |||||
| Log.AddNewLine(string.Format("返回信息:[{0}]", errorMessage)); | |||||
| if (ResponseObj.Message.Control.ReturnCode != "0000") { | |||||
| Log.Commit(); | |||||
| throw new ResponseException(ResponseObj.Message.Control.ReturnCode, errorMessage + MsgUtil.MsgToBareXml(RequestObj)); | |||||
| } | |||||
| Log.Commit(); | |||||
| } | |||||
| protected override void BeforeRequest() | |||||
| { | |||||
| if (string.IsNullOrEmpty(SequenceNo)) { | |||||
| throw new Exception("交易流水号不能为空,SequenceNo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(CustomerSignInfo)) { | |||||
| throw new Exception("客户签名不能为空,CustmerSignInfo"); | |||||
| } | |||||
| if (string.IsNullOrEmpty(MerchantName)) { | |||||
| throw new Exception("商户名不能为空,MerchantName"); | |||||
| } | |||||
| RequestObj.Message.Control.MerchantID = MerchantID; | |||||
| RequestObj.Message.Control.MerchantTrxNo = SequenceNo; | |||||
| RequestObj.Message.Parameters.CustName = CustomerName; | |||||
| RequestObj.Message.Parameters.CustSignInfo = CustomerSignInfo; | |||||
| RequestObj.Message.Parameters.NeedTwoCheck = NeedTwoCheck; | |||||
| RequestObj.Message.Parameters.MerchantName = MerchantName; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,46 @@ | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class ResultB2BReturned : IReturnedResult | |||||
| { | |||||
| private readonly string _xml; | |||||
| public ResultB2BReturned(string base64string) | |||||
| { | |||||
| var log = new AbcLog("b2bReturn"); | |||||
| log.AddNewLine("TrustPayClient ASP V2.0.1 交易开始=========================="); | |||||
| log.AddNewLine("接收到的支付结果通知:\n[" + base64string + "]"); | |||||
| _xml = MsgUtil.FromBase64StringToXml(base64string); | |||||
| log.AddNewLine("经过Base64解码后的支付结果通知:\n[" + _xml + "]"); | |||||
| log.AddNewLine("验证支付结果通知的签名:"); | |||||
| IsValid = RSAService.Verify(_xml, BusinessTypes.B2B.VerifyEncoding, false, false); | |||||
| if (IsValid) | |||||
| log.AddNewLine("验证通过!\n 经过验证的支付结果通知:\n[" + _xml + "]"); | |||||
| else | |||||
| log.AddNewLine("验证失败!"); | |||||
| log.Commit(); | |||||
| ReturnCode = MsgUtil.GetInnerXml(_xml, "ReturnCode"); | |||||
| ErrorMessage = MsgUtil.GetInnerXml(_xml, "ErrorMessage"); | |||||
| IsSuccess = ReturnCode == "0000" ; | |||||
| SequenceNo = MsgUtil.GetInnerXml(_xml, "MerchantTrnxNo"); | |||||
| } | |||||
| public string Xml | |||||
| { | |||||
| get { return _xml; } | |||||
| } | |||||
| public bool IsValid { get; set; } | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public bool IsSuccess { get; set; } | |||||
| public string SequenceNo { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,46 @@ | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class ResultB2CReturned : IReturnedResult | |||||
| { | |||||
| private readonly string _xml; | |||||
| public ResultB2CReturned(string base64string) | |||||
| { | |||||
| var log = new AbcLog("b2cReturn"); | |||||
| log.AddNewLine("TrustPayClient ASP V2.0.1 交易开始=========================="); | |||||
| log.AddNewLine("接收到的支付结果通知:\n[" + base64string + "]"); | |||||
| _xml = MsgUtil.FromBase64StringToXml(base64string); | |||||
| log.AddNewLine("经过Base64解码后的支付结果通知:\n[" + _xml + "]"); | |||||
| log.AddNewLine("验证支付结果通知的签名:"); | |||||
| IsValid = RSAService.Verify(_xml, BusinessTypes.B2C.VerifyEncoding, false, false); | |||||
| if (IsValid) | |||||
| log.AddNewLine("验证通过!\n 经过验证的支付结果通知:\n[" + _xml + "]"); | |||||
| else | |||||
| log.AddNewLine("验证失败!"); | |||||
| log.Commit(); | |||||
| ReturnCode = MsgUtil.GetInnerXml(_xml, "ReturnCode"); | |||||
| ErrorMessage = MsgUtil.GetInnerXml(_xml, "ErrorMessage"); | |||||
| IsSuccess = ReturnCode == "0000"; | |||||
| SequenceNo = MsgUtil.GetInnerXml(_xml, "OrderNo"); | |||||
| } | |||||
| public string Xml | |||||
| { | |||||
| get { return _xml; } | |||||
| } | |||||
| public bool IsValid { get; set; } | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public bool IsSuccess { get; set; } | |||||
| public string SequenceNo { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.Businesses.Type | |||||
| { | |||||
| public class B2B : IBusinessType | |||||
| { | |||||
| public Encoding RequestEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public Encoding ResponseEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public Encoding SignEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public Encoding VerifyEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public bool CompressEnabled | |||||
| { | |||||
| get { return false; } | |||||
| } | |||||
| public bool IsMarket | |||||
| { | |||||
| get { return false; } | |||||
| } | |||||
| public string Name | |||||
| { | |||||
| get { return "b2b"; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.Businesses.Type | |||||
| { | |||||
| public class B2C : IBusinessType | |||||
| { | |||||
| public Encoding RequestEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public Encoding ResponseEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public Encoding SignEncoding | |||||
| { | |||||
| get { return Encoding.UTF8; } | |||||
| } | |||||
| public Encoding VerifyEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public bool CompressEnabled | |||||
| { | |||||
| get { return false; } | |||||
| } | |||||
| public bool IsMarket | |||||
| { | |||||
| get { return false; } | |||||
| } | |||||
| public string Name | |||||
| { | |||||
| get { return "b2c"; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,24 @@ | |||||
| namespace BWP.ABCClient.Businesses.Type | |||||
| { | |||||
| public static class BusinessTypes | |||||
| { | |||||
| private static IBusinessType _b2bInfo; | |||||
| private static IBusinessType _b2cInfo; | |||||
| private static IBusinessType _marketInfo; | |||||
| public static IBusinessType B2B | |||||
| { | |||||
| get { return _b2bInfo ?? (_b2bInfo = new Type.B2B() ); } | |||||
| } | |||||
| public static IBusinessType B2C | |||||
| { | |||||
| get { return _b2cInfo ?? (_b2cInfo = new Type.B2C()); } | |||||
| } | |||||
| public static IBusinessType Market | |||||
| { | |||||
| get { return _marketInfo ?? (_marketInfo = new Market()); } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,15 @@ | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.Businesses.Type | |||||
| { | |||||
| public interface IBusinessType | |||||
| { | |||||
| Encoding RequestEncoding { get; } | |||||
| Encoding ResponseEncoding { get; } | |||||
| Encoding SignEncoding { get; } | |||||
| Encoding VerifyEncoding { get; } | |||||
| bool CompressEnabled { get; } | |||||
| bool IsMarket { get; } | |||||
| string Name { get; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,43 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| namespace BWP.ABCClient.Businesses.Type | |||||
| { | |||||
| public class Market : IBusinessType | |||||
| { | |||||
| public Encoding RequestEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public Encoding ResponseEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public Encoding SignEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public Encoding VerifyEncoding | |||||
| { | |||||
| get { return Encoding.GetEncoding("GB2312"); } | |||||
| } | |||||
| public bool CompressEnabled | |||||
| { | |||||
| get { return true; } | |||||
| } | |||||
| public bool IsMarket | |||||
| { | |||||
| get { return true; } | |||||
| } | |||||
| public string Name | |||||
| { | |||||
| get { return "market"; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,118 @@ | |||||
| using System.Collections; | |||||
| namespace BWP.ABCClient.Businesses | |||||
| { | |||||
| public class XmlDocument | |||||
| { | |||||
| private string _xmlString; | |||||
| public XmlDocument() | |||||
| { | |||||
| _xmlString = ""; | |||||
| } | |||||
| public XmlDocument(string xmlString) | |||||
| { | |||||
| _xmlString = ""; | |||||
| Init(xmlString); | |||||
| } | |||||
| public XmlDocument DeleteFirstTagDocument() | |||||
| { | |||||
| string str = GetFirstTagName(); | |||||
| int index = _xmlString.IndexOf("<" + str + ">"); | |||||
| int num2 = _xmlString.IndexOf("</" + str + ">"); | |||||
| if (num2 > index) { | |||||
| _xmlString = _xmlString.Substring((num2 + str.Length) + 3); | |||||
| } | |||||
| return this; | |||||
| } | |||||
| public ArrayList GetDocuments(string aTag) | |||||
| { | |||||
| string xmlString = _xmlString; | |||||
| var list = new ArrayList(); | |||||
| while (true) { | |||||
| int index = xmlString.IndexOf("<" + aTag.Trim() + ">"); | |||||
| int num2 = xmlString.IndexOf("</" + aTag.Trim() + ">"); | |||||
| if (((index == -1) || (num2 == -1)) || (index > num2)) { | |||||
| return list; | |||||
| } | |||||
| var document = new XmlDocument(xmlString.Substring(index, ((num2 + aTag.Length) + 3) - index)); | |||||
| list.Add(document); | |||||
| xmlString = xmlString.Substring(num2 + 1); | |||||
| } | |||||
| } | |||||
| public string GetFirstTagName() | |||||
| { | |||||
| string str = null; | |||||
| int index = _xmlString.IndexOf('<'); | |||||
| int num2 = _xmlString.IndexOf('>'); | |||||
| if (num2 > index) { | |||||
| str = _xmlString.Substring(index + 1, num2 - (index + 1)); | |||||
| } | |||||
| return str; | |||||
| } | |||||
| public XmlDocument GetFormatDocument(string aSpace) | |||||
| { | |||||
| return GetFormatDocument(0, aSpace); | |||||
| } | |||||
| private XmlDocument GetFormatDocument(int aLevel, string aSpace) | |||||
| { | |||||
| string str2; | |||||
| string str = aSpace; | |||||
| for (int i = 0; i < aLevel; i++) { | |||||
| str = str + aSpace; | |||||
| } | |||||
| if (GetFirstTagName() == null) { | |||||
| return this; | |||||
| } | |||||
| string xmlString = "\n"; | |||||
| for (var document = new XmlDocument(_xmlString); (str2 = document.GetFirstTagName()) != null; document = document.DeleteFirstTagDocument()) { | |||||
| var document2 = document.GetValue(str2); | |||||
| var str4 = ""; | |||||
| if (document2.GetFirstTagName() != null) { | |||||
| str4 = str; | |||||
| } | |||||
| xmlString = string.Concat(new object[] { xmlString, str, "<", str2, ">", document2.GetFormatDocument(aLevel + 1, aSpace), str4, "</", str2, ">\n" }); | |||||
| } | |||||
| return new XmlDocument(xmlString); | |||||
| } | |||||
| public XmlDocument GetValue(string aTag) | |||||
| { | |||||
| XmlDocument document = null; | |||||
| int index = _xmlString.IndexOf("<" + aTag.Trim() + ">"); | |||||
| int num2 = _xmlString.IndexOf("</" + aTag.Trim() + ">"); | |||||
| if (((index >= 0) && (num2 >= 0)) && (index < num2)) { | |||||
| document = new XmlDocument(_xmlString.Substring((index + aTag.Length) + 2, num2 - ((index + aTag.Length) + 2))); | |||||
| } | |||||
| return document; | |||||
| } | |||||
| public virtual string GetValueNoNull(string aTag) | |||||
| { | |||||
| var str = ""; | |||||
| var document = GetValue(aTag); | |||||
| if (document != null) { | |||||
| str = document.ToString(); | |||||
| } | |||||
| return str; | |||||
| } | |||||
| public XmlDocument Init(string xmlString) | |||||
| { | |||||
| _xmlString = xmlString; | |||||
| return this; | |||||
| } | |||||
| public override string ToString() | |||||
| { | |||||
| return _xmlString; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,165 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.Security.Cryptography.X509Certificates; | |||||
| using System.Security.Permissions; | |||||
| using System.Threading; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| using TSingSoft.WebPluginFramework.TimerTasks; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public class CertManager | |||||
| { | |||||
| public static CertManager MainSystemCertManager | |||||
| { | |||||
| get | |||||
| { | |||||
| return new CertManager("MainSystemABCCerts"); | |||||
| } | |||||
| } | |||||
| CertManager(string storeName) | |||||
| { | |||||
| _store = new X509Store(storeName, StoreLocation.LocalMachine); | |||||
| new StorePermission(StorePermissionFlags.AllFlags).Assert(); | |||||
| } | |||||
| private readonly X509Store _store; | |||||
| public CertManager():this("ABCCerts") | |||||
| { | |||||
| } | |||||
| volatile static object _lockObj = new object(); | |||||
| public void SetupPfx(Stream stream, string password) | |||||
| { | |||||
| if (!Monitor.TryEnter(_lockObj)) | |||||
| { | |||||
| throw new ApplicationException("另一名操作员正在导入证书,请稍后再试"); | |||||
| } | |||||
| try | |||||
| { | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| using (var binaryReader = new BinaryReader(stream)) | |||||
| { | |||||
| var bytes = binaryReader.ReadBytes((int)stream.Length); | |||||
| var cert = new X509Certificate2(bytes, password); | |||||
| if (_store.Certificates.Find(X509FindType.FindBySerialNumber, cert.SerialNumber, false).Count == 0) | |||||
| { | |||||
| _store.Add(new X509Certificate2(bytes, password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet)); | |||||
| } | |||||
| } | |||||
| _store.Close(); | |||||
| } | |||||
| finally | |||||
| { | |||||
| Monitor.Exit(_lockObj); | |||||
| } | |||||
| } | |||||
| public void SetupPfx(string fileName, string password) | |||||
| { | |||||
| using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) | |||||
| { | |||||
| SetupPfx(stream, password); | |||||
| } | |||||
| } | |||||
| public X509Certificate2 Fetch(string merchantID) | |||||
| { | |||||
| return Fetch(X509FindType.FindBySubjectName, merchantID); | |||||
| } | |||||
| public X509Certificate2 Fetch(X509FindType findType, string findValue) | |||||
| { | |||||
| _store.Open(OpenFlags.ReadOnly); | |||||
| var certs = _store.Certificates.Find(findType, findValue, false); | |||||
| _store.Close(); | |||||
| if (certs.Count == 0) { | |||||
| throw new RSAException("找不到商户号对应的证书"); | |||||
| } | |||||
| if (certs.Count > 1) { | |||||
| throw new RSAException("同一个商户号有多张证书"); | |||||
| } | |||||
| return certs[0]; | |||||
| } | |||||
| public bool TryFetch(string merchantID, out X509Certificate2 cert) | |||||
| { | |||||
| cert = null; | |||||
| _store.Open(OpenFlags.ReadOnly); | |||||
| var certs = _store.Certificates.Find(X509FindType.FindBySubjectName, merchantID, false); | |||||
| _store.Close(); | |||||
| if (certs.Count == 0) { | |||||
| return false; | |||||
| } | |||||
| cert = certs[0]; | |||||
| return true; | |||||
| } | |||||
| public void Remove(string merchantID) | |||||
| { | |||||
| var cert = Fetch(merchantID); | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| _store.Remove(cert); | |||||
| _store.Close(); | |||||
| } | |||||
| public void Remove(X509Certificate2 cert) | |||||
| { | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| _store.Remove(cert); | |||||
| _store.Close(); | |||||
| } | |||||
| public void ClearAll() | |||||
| { | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| _store.RemoveRange(_store.Certificates); | |||||
| _store.Close(); | |||||
| } | |||||
| public X509Certificate2Collection FetchAll() | |||||
| { | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| var certs = _store.Certificates; | |||||
| _store.Close(); | |||||
| return certs; | |||||
| } | |||||
| public void Export(string merchantID, string password, Stream stream) | |||||
| { | |||||
| var cert = Fetch(merchantID); | |||||
| var bytes = cert.Export(X509ContentType.Pfx, password); | |||||
| stream.Write(bytes, 0, bytes.Length); | |||||
| } | |||||
| public void SetupABCPubKey(string fileName) | |||||
| { | |||||
| _store.Open(OpenFlags.ReadWrite); | |||||
| _store.Add(new X509Certificate2(fileName)); | |||||
| _store.Close(); | |||||
| } | |||||
| public X509Certificate2 GetABCPubKey() | |||||
| { | |||||
| _store.Open(OpenFlags.ReadOnly); | |||||
| var certs = _store.Certificates.Find(X509FindType.FindBySerialNumber, "7b97ca10275a0000d99d", false); | |||||
| if (certs.Count == 0) { | |||||
| throw new RSAException("找不到农行公钥"); | |||||
| } | |||||
| return certs[0]; | |||||
| } | |||||
| public X509Certificate2 GetABCTestPubKey() | |||||
| { | |||||
| _store.Open(OpenFlags.ReadOnly); | |||||
| var certs = _store.Certificates.Find(X509FindType.FindBySerialNumber, "50 3a ca 10 53 5b 00 00 02 7f", false); | |||||
| if (certs.Count == 0) { | |||||
| throw new RSAException("找不到农行公钥"); | |||||
| } | |||||
| return certs[0]; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,8 @@ | |||||
| namespace BWP.ABCClient.Common | |||||
| { | |||||
| public class MerchantContent | |||||
| { | |||||
| public string ECMerchantType { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,18 @@ | |||||
| using System.Xml.Serialization; | |||||
| namespace BWP.ABCClient.Common | |||||
| { | |||||
| public class MessageBase | |||||
| { | |||||
| [XmlElement(ElementName = "Signature-Algorithm")] | |||||
| public string SignatureAlgorithm { get; set; } | |||||
| /// <summary> | |||||
| /// 签名 | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// 使用私钥加密消息后得到的一个签名 | |||||
| /// </remarks> | |||||
| public string Signature { get; set; } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,27 @@ | |||||
| using System.Xml.Serialization; | |||||
| namespace BWP.ABCClient.Common | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class PaymentURLResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public MerchantContent Merchant { get; set; } | |||||
| public TrxResponseContent TrxResponse { get; set; } | |||||
| } | |||||
| public class TrxResponseContent | |||||
| { | |||||
| public string ReturnCode { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public string TrnxType { get; set; } | |||||
| public string PaymentURL { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,11 @@ | |||||
| using System; | |||||
| namespace BWP.ABCClient.Exceptions | |||||
| { | |||||
| public class RSAException : Exception | |||||
| { | |||||
| public RSAException(string message) : base(message) | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,12 @@ | |||||
| using System; | |||||
| namespace BWP.ABCClient.Exceptions | |||||
| { | |||||
| public class HttpException : Exception | |||||
| { | |||||
| public HttpException(string message) : base(message) | |||||
| { | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,20 @@ | |||||
| using System; | |||||
| namespace BWP.ABCClient.Exceptions | |||||
| { | |||||
| public class ResponseException : Exception | |||||
| { | |||||
| private readonly string _errorCode; | |||||
| public ResponseException(string errorCode, string message) | |||||
| : base(errorCode + ":" + message) | |||||
| { | |||||
| _errorCode = errorCode; | |||||
| } | |||||
| public string ErrorCode | |||||
| { | |||||
| get { return _errorCode; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,61 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.Text; | |||||
| using Forks.Utils.IO; | |||||
| using TSingSoft.WebPluginFramework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public class AbcLog | |||||
| { | |||||
| private readonly string _filePath; | |||||
| private readonly StringBuilder _msg = new StringBuilder(); | |||||
| public AbcLog(string type) | |||||
| { | |||||
| #if DEBUG | |||||
| _filePath = Path.Combine("../../abclog/", DateTime.Today.ToString("yyyyMMdd") + type + "log.txt"); | |||||
| #else | |||||
| _filePath = Path.Combine(Wpf.Settings.ConfigFolder + "../../abclog/", DateTime.Today.ToString("yyyyMMdd") + type + "log.txt"); | |||||
| #endif | |||||
| if (!FS.FileExists(_filePath)) | |||||
| FS.CreateDirectory(Path.GetDirectoryName(_filePath)); | |||||
| } | |||||
| public void Add(string msg) | |||||
| { | |||||
| _msg.Append(msg); | |||||
| } | |||||
| public void AddNewLine(string msg) | |||||
| { | |||||
| _msg.AppendLine(); | |||||
| _msg.Append(string.Format("{0} {1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), msg)); | |||||
| } | |||||
| public void Commit() | |||||
| { | |||||
| try { | |||||
| File.AppendAllText(_filePath, _msg.ToString(), Encoding.UTF8); | |||||
| _msg.Clear(); | |||||
| } catch (Exception) | |||||
| { } | |||||
| } | |||||
| public string Load() | |||||
| { | |||||
| return File.ReadAllText(_filePath, Encoding.UTF8); | |||||
| } | |||||
| public void Clear() | |||||
| { | |||||
| FS.WriteAllText(_filePath, string.Empty); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,49 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class MarketResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| public string ReturnCode { get; set; } | |||||
| public string ReturnMessage { get; set; } | |||||
| public string ErrorMessage { get; set; } | |||||
| public string ClientIP { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string OrderMg { get; set; } | |||||
| public string CustomerNo { get; set; } | |||||
| public string CustSignInfo2 { get; set; } | |||||
| public string PayAmount { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,72 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class OrderApplyRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static OrderApplyRequest New() | |||||
| { | |||||
| return new OrderApplyRequest { | |||||
| Message = new MessageContent { | |||||
| Control = new ControlContent { | |||||
| MerchantTrxNo = string.Empty, | |||||
| Version = "Java_V1.0", | |||||
| ChannelType = "01", | |||||
| BusinessID = "MARKET", | |||||
| FunctionID = "0025", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| Parameters = new ParametersContent { | |||||
| OrderMg = "http://127.0.0.1:18080/marketclientCS/MerchantResult.jsp", | |||||
| FeeFlag = "0", | |||||
| OrderType = "C", | |||||
| PayAmount = string.Empty, | |||||
| OrderNo = string.Empty, | |||||
| BuyerCustName = string.Empty, | |||||
| BuyerCustomer = string.Empty, | |||||
| SalerCustName = string.Empty, | |||||
| SalerCustomer = string.Empty | |||||
| }, | |||||
| Resultsets = string.Empty | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string FeeFlag { get; set; } | |||||
| public string BuyerCustomer { get; set; } | |||||
| public string OrderMg { get; set; } | |||||
| public string PayAmount { get; set; } | |||||
| public string OrderType { get; set; } | |||||
| public string OrderNo { get; set; } | |||||
| public string SalerCustomer { get; set; } | |||||
| public string SalerCustName { get; set; } | |||||
| public string BuyerCustName { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,44 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class OrderApplyResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| public string ReturnCode { get; set; } | |||||
| public string ReturnMessage { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string OrderDate { get; set; } | |||||
| public string ReturnURL { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,61 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class OrderPayRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static OrderPayRequest New() | |||||
| { | |||||
| return new OrderPayRequest { | |||||
| Message = new MessageContent { | |||||
| Control = new ControlContent { | |||||
| MerchantTrxNo = string.Empty, | |||||
| Version = "Java_V1.0", | |||||
| ChannelType = "01", | |||||
| BusinessID = "MARKET", | |||||
| FunctionID = "0026", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| Parameters = new ParametersContent { | |||||
| PayAmount = string.Empty, | |||||
| OrderNo = string.Empty, | |||||
| CustSignInfo = string.Empty, | |||||
| CustSignInfo2 = string.Empty, | |||||
| }, | |||||
| Resultsets = string.Empty | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string CustSignInfo2 { get; set; } | |||||
| public string PayAmount { get; set; } | |||||
| public string OrderNo { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,41 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class OrderPayResponse : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public string Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string ReturnMessage { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ClientIP { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string ReturnCode { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,68 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class PayRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static PayRequest New() | |||||
| { | |||||
| return new PayRequest { | |||||
| Message = new MessageContent { | |||||
| Control = new ControlContent { | |||||
| MerchantTrxNo = string.Empty, | |||||
| Version = "Java_V1.0", | |||||
| ChannelType = "01", | |||||
| BusinessID = "MARKET", | |||||
| FunctionID = "0009", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| Parameters = new ParametersContent { | |||||
| OrderMg = "实时支付", | |||||
| CustomerNo = string.Empty, | |||||
| CustSignInfo2 = null, | |||||
| PayAmount = string.Empty, | |||||
| CustSignInfo = string.Empty | |||||
| }, | |||||
| Resultsets = string.Empty | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string OrderMg { get; set; } | |||||
| public string CustomerNo { get; set; } | |||||
| public string CustSignInfo2 { get; set; } | |||||
| public string PayAmount { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,69 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class SignOffRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static SignOffRequest New() | |||||
| { | |||||
| return new SignOffRequest { | |||||
| Message = new MessageContent { | |||||
| Control = new ControlContent { | |||||
| MerchantTrxNo = string.Empty, | |||||
| Version = "Java_V1.0", | |||||
| ChannelType = "01", | |||||
| BusinessID = "MARKET", | |||||
| FunctionID = "0001", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| Parameters = new ParametersContent { | |||||
| CustName = string.Empty, | |||||
| MerchantName = string.Empty, | |||||
| CustomerNo = string.Empty, | |||||
| CustSignInfo = string.Empty | |||||
| }, | |||||
| Resultsets = string.Empty | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string CustName { get; set; } | |||||
| public string MerchantName { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| public string CustomerNo { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,69 @@ | |||||
| using System.Xml.Serialization; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient.Market | |||||
| { | |||||
| [XmlRoot(ElementName = "MSG")] | |||||
| public class SignUpRequest : MessageBase | |||||
| { | |||||
| public MessageContent Message { get; set; } | |||||
| public static SignUpRequest New() | |||||
| { | |||||
| return new SignUpRequest { | |||||
| Message = new MessageContent { | |||||
| Control = new ControlContent { | |||||
| MerchantTrxNo = string.Empty, | |||||
| Version = "Java_V1.0", | |||||
| ChannelType = "01", | |||||
| BusinessID = "MARKET", | |||||
| FunctionID = "0000", | |||||
| MerchantID = string.Empty | |||||
| }, | |||||
| Parameters = new ParametersContent { | |||||
| CustName = string.Empty, | |||||
| MerchantName = string.Empty, | |||||
| CustSignInfo = string.Empty, | |||||
| NeedTwoCheck = null | |||||
| }, | |||||
| Resultsets = string.Empty | |||||
| }, | |||||
| SignatureAlgorithm = "SHA1withRSA", | |||||
| Signature = string.Empty | |||||
| }; | |||||
| } | |||||
| public class MessageContent | |||||
| { | |||||
| public ControlContent Control { get; set; } | |||||
| public ParametersContent Parameters { get; set; } | |||||
| public string Resultsets { get; set; } | |||||
| } | |||||
| public class ControlContent | |||||
| { | |||||
| public string MerchantTrxNo { get; set; } | |||||
| public string Version { get; set; } | |||||
| public string ChannelType { get; set; } | |||||
| public string BusinessID { get; set; } | |||||
| public string FunctionID { get; set; } | |||||
| public string MerchantID { get; set; } | |||||
| } | |||||
| public class ParametersContent | |||||
| { | |||||
| public string CustName { get; set; } | |||||
| public string MerchantName { get; set; } | |||||
| public string CustSignInfo { get; set; } | |||||
| public string NeedTwoCheck { get; set; } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,108 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.IO.Compression; | |||||
| using System.Text; | |||||
| using System.Xml; | |||||
| using System.Xml.Serialization; | |||||
| using XmlDocument = BWP.ABCClient.Businesses.XmlDocument; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public class MsgUtil | |||||
| { | |||||
| public class BareXmlTextWriter : XmlTextWriter | |||||
| { | |||||
| public BareXmlTextWriter(TextWriter writer) : base(writer) {} | |||||
| public override void WriteStartDocument() {} | |||||
| public override void WriteStartDocument(bool bare) {} | |||||
| public override void WriteEndElement() | |||||
| { | |||||
| WriteFullEndElement(); | |||||
| } | |||||
| } | |||||
| public static string MsgToBareXml(object obj) | |||||
| { | |||||
| return MsgToBareXml(obj, Formatting.None, char.MinValue); | |||||
| } | |||||
| public static string MsgToBareXml(object obj, Formatting formatting, char indentChar) | |||||
| { | |||||
| StringBuilder sb = new StringBuilder(); | |||||
| using (var stringWriter = new StringWriter(sb)) { | |||||
| using (BareXmlTextWriter writer = new BareXmlTextWriter(stringWriter)) { | |||||
| writer.Formatting = formatting; | |||||
| writer.IndentChar = indentChar; | |||||
| var ns = new XmlSerializerNamespaces(); | |||||
| ns.Add(string.Empty, string.Empty); | |||||
| new XmlSerializer(obj.GetType()).Serialize(writer, obj, ns); | |||||
| } | |||||
| } | |||||
| return sb.ToString(); | |||||
| } | |||||
| public static T ParseXmlToMsg<T>(string xml) | |||||
| { | |||||
| using (TextReader reader = new StringReader(xml)) { | |||||
| return (T)new XmlSerializer(typeof(T)).Deserialize(reader); | |||||
| } | |||||
| } | |||||
| public static string GetInnerXml(string xml, string xpath) | |||||
| { | |||||
| var aMessage = new XmlDocument(xml); | |||||
| return aMessage.GetValueNoNull(xpath); | |||||
| } | |||||
| public static string Compress(string uncompressedString) | |||||
| { | |||||
| byte[] byteData = Encoding.GetEncoding("GB18030").GetBytes(uncompressedString); | |||||
| using (MemoryStream srcStream = new MemoryStream(byteData)) { | |||||
| using (var destStream = new MemoryStream()) { | |||||
| using (GZipStream compress = new GZipStream(destStream, CompressionMode.Compress)) { | |||||
| srcStream.CopyTo(compress); | |||||
| } | |||||
| return Convert.ToBase64String(destStream.ToArray()); | |||||
| } | |||||
| } | |||||
| } | |||||
| public static string DeCompress(string comppressedString) | |||||
| { | |||||
| byte[] byteInput = Convert.FromBase64String(comppressedString); | |||||
| using (var srcStream = new MemoryStream(byteInput)) { | |||||
| using (var destStream = new MemoryStream()) { | |||||
| using (GZipStream decompress = new GZipStream(srcStream, CompressionMode.Decompress)) { | |||||
| decompress.CopyTo(destStream); | |||||
| var resultBytes = destStream.ToArray(); | |||||
| return Encoding.GetEncoding("GB18030").GetString(resultBytes, 0, resultBytes.Length); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| public static string[] GetMultiInnerXml(string xml, string xpath) | |||||
| { | |||||
| var xmlDoc = new System.Xml.XmlDocument(); | |||||
| xmlDoc.LoadXml(xml); | |||||
| var nodes = xmlDoc.SelectNodes(xpath); | |||||
| if (nodes == null) { | |||||
| return null; | |||||
| } | |||||
| var result = new string[nodes.Count]; | |||||
| for (int i = 0; i < result.Length; i++) { | |||||
| result[i] = nodes[i].InnerXml; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| public static string FromBase64StringToXml(string msg) | |||||
| { | |||||
| byte[] bytes = Convert.FromBase64String(msg); | |||||
| return Encoding.GetEncoding("gb2312").GetString(bytes, 0, bytes.Length); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,35 @@ | |||||
| using System.Reflection; | |||||
| using System.Runtime.CompilerServices; | |||||
| using System.Runtime.InteropServices; | |||||
| // General Information about an assembly is controlled through the following | |||||
| // set of attributes. Change these attribute values to modify the information | |||||
| // associated with an assembly. | |||||
| [assembly: AssemblyTitle("BWP.ABCClient")] | |||||
| [assembly: AssemblyDescription("")] | |||||
| [assembly: AssemblyConfiguration("")] | |||||
| [assembly: AssemblyCompany("")] | |||||
| [assembly: AssemblyProduct("BWP.ABCClient")] | |||||
| [assembly: AssemblyCopyright("Copyright © BWP 2011")] | |||||
| [assembly: AssemblyTrademark("")] | |||||
| [assembly: AssemblyCulture("")] | |||||
| // Setting ComVisible to false makes the types in this assembly not visible | |||||
| // to COM components. If you need to access a type in this assembly from | |||||
| // COM, set the ComVisible attribute to true on that type. | |||||
| [assembly: ComVisible(false)] | |||||
| // The following GUID is for the ID of the typelib if this project is exposed to COM | |||||
| [assembly: Guid("49a33933-5a6f-4d22-98aa-b462f5a974d0")] | |||||
| // Version information for an assembly consists of the following four values: | |||||
| // | |||||
| // Major Version | |||||
| // Minor Version | |||||
| // Build Number | |||||
| // Revision | |||||
| // | |||||
| // You can specify all the values or you can default the Build and Revision Numbers | |||||
| // by using the '*' as shown below: | |||||
| // [assembly: AssemblyVersion("1.0.*")] | |||||
| [assembly: AssemblyVersion("1.0.0.0")] | |||||
| @ -0,0 +1,74 @@ | |||||
| using System; | |||||
| using System.Security.Cryptography; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Common; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public static class RSAService | |||||
| { | |||||
| public static void Sign(MessageBase msgObj, string merchantID, Encoding msgEncoding, bool isMarket) | |||||
| { | |||||
| string xml = MsgUtil.MsgToBareXml(msgObj); | |||||
| var message = MsgUtil.GetInnerXml(xml, "Message"); | |||||
| message = isMarket ? string.Format("<Message>{0}</Message>", message) : message; | |||||
| msgObj.Signature = Sign(message, merchantID, msgEncoding); | |||||
| } | |||||
| public static string Sign(string msg, string merchantID) | |||||
| { | |||||
| return Sign(msg, merchantID, Encoding.Default); | |||||
| } | |||||
| public static string Sign(string msg, string merchantID, Encoding msgEncoding) | |||||
| { | |||||
| var cert = new CertManager().Fetch(merchantID); | |||||
| var privateKey = (RSACryptoServiceProvider)cert.PrivateKey; | |||||
| if (privateKey == null) | |||||
| { | |||||
| throw new Exception("商户的证书中没有私钥,请上传有效的证书"); | |||||
| } | |||||
| byte[] rgbHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(msg)); | |||||
| byte[] data = privateKey.SignHash(rgbHash, cert.SignatureAlgorithm.Value); | |||||
| return Convert.ToBase64String(data); | |||||
| } | |||||
| public static bool Verify(string returnMsg, string abcSign) | |||||
| { | |||||
| return Verify(returnMsg, abcSign, Encoding.Default, false); | |||||
| } | |||||
| public static bool Verify(string returnMsg, string abcSign, Encoding msgEncoding, bool isTest) | |||||
| { | |||||
| var certMgr = new CertManager(); | |||||
| var cert = isTest ? certMgr.GetABCTestPubKey() : certMgr.GetABCPubKey(); | |||||
| var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; | |||||
| var singature = Convert.FromBase64String(abcSign); | |||||
| var msgHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(returnMsg)); | |||||
| return publicKey.VerifyHash(msgHash, cert.SignatureAlgorithm.Value, singature); | |||||
| } | |||||
| public static bool Verify(string receivedXml, Encoding msgEncoding, bool isMarket, bool isTest) | |||||
| { | |||||
| string message = MsgUtil.GetInnerXml(receivedXml, "Message"); | |||||
| message = isMarket ? string.Format("<Message>{0}</Message>", message) : message; | |||||
| string signature = MsgUtil.GetInnerXml(receivedXml, "Signature"); | |||||
| return Verify(message, signature, msgEncoding, isTest); | |||||
| } | |||||
| public static bool TestVerify(string returnMsg, string abcSign) | |||||
| { | |||||
| return TestVerify(returnMsg, abcSign, Encoding.Default); | |||||
| } | |||||
| public static bool TestVerify(string returnMsg, string abcSign, Encoding msgEncoding) | |||||
| { | |||||
| var cert = new CertManager().GetABCTestPubKey(); | |||||
| var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; | |||||
| var singature = Convert.FromBase64String(abcSign); | |||||
| var msgHash = new SHA1Managed().ComputeHash(msgEncoding.GetBytes(returnMsg)); | |||||
| return publicKey.VerifyHash(msgHash, cert.SignatureAlgorithm.Value, singature); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,50 @@ | |||||
| using System.IO; | |||||
| using System.Net; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Exceptions; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public class Request | |||||
| { | |||||
| public string Message { get; set; } | |||||
| public string Url { get; set; } | |||||
| public Encoding RequestEncoding { get; set; } | |||||
| public Encoding ResponseEncoding { get; set; } | |||||
| public string ProxyIP { get; set; } | |||||
| public int ProxyPort { get; set; } | |||||
| public string Run() | |||||
| { | |||||
| ServicePointManager.ServerCertificateValidationCallback = delegate { | |||||
| return true; | |||||
| }; | |||||
| var request = (HttpWebRequest)WebRequest.Create(Url); | |||||
| if (!string.IsNullOrEmpty(ProxyIP) && ProxyPort != 0) { | |||||
| request.Proxy = new WebProxy(ProxyIP, ProxyPort); | |||||
| } | |||||
| request.Method = "POST"; | |||||
| request.ProtocolVersion = HttpVersion.Version10; | |||||
| request.ContentType = "application/x-www-form-urlencoded"; | |||||
| byte[] bytes = RequestEncoding.GetBytes(Message); | |||||
| request.ContentLength = bytes.Length; | |||||
| using (var stream = request.GetRequestStream()) { | |||||
| stream.Write(bytes, 0, bytes.Length); | |||||
| } | |||||
| var response = (HttpWebResponse)request.GetResponse(); | |||||
| if (response.StatusCode != HttpStatusCode.OK) { | |||||
| throw new HttpException("网上支付平台服务暂时停止 " + response.StatusCode); | |||||
| } | |||||
| using (var responseStream = response.GetResponseStream()) { | |||||
| using (var reader = new StreamReader(responseStream, ResponseEncoding)) { | |||||
| return reader.ReadToEnd(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,57 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class B2BReceivingPaymentTest | |||||
| { | |||||
| [Test] | |||||
| public void AssignValue() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| B2BReceivingPayment collections = new B2BReceivingPayment(); | |||||
| collections.MerchantID = "337100000000066"; | |||||
| collections.Date = DateTime.Now; | |||||
| collections.Amount = 234.5m; | |||||
| collections.AccountNo = "622587263489712639846"; | |||||
| collections.AccountName = string.Empty; | |||||
| collections.AccountBank = string.Empty; | |||||
| collections.ResultNotifyURL = "http://a.b.c.d"; | |||||
| collections.Remarks = string.Empty; | |||||
| collections.Operator = string.Empty; | |||||
| collections.SequenceNo = "209329384902834"; | |||||
| collections.RequestUrl = "http://localhost:5000/B2B/"; | |||||
| using (new MockWebServer("http://localhost:5000/B2B/", Encoding.UTF8, Encoding.UTF8, false)) { | |||||
| collections.Request(); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void ReturnValue() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| B2BReceivingPayment collections = new B2BReceivingPayment(); | |||||
| collections.MerchantID = "337100000000066"; | |||||
| collections.Date = DateTime.Now; | |||||
| collections.Amount = 234.5m; | |||||
| collections.AccountNo = "622587263489712639846"; | |||||
| collections.ResultNotifyURL = "http://a.b.c.d"; | |||||
| collections.SequenceNo = "209329384902834"; | |||||
| collections.RequestUrl = "http://localhost:5000/B2B/"; | |||||
| using (new MockWebServer("http://localhost:5000/B2B/", Encoding.UTF8, Encoding.UTF8, false)) { | |||||
| collections.Request(); | |||||
| } | |||||
| Assert.AreEqual("https://easyabc.95599.cn/b2b/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12975716546177309876", collections.PaymentUrl); | |||||
| } | |||||
| public static void EnsureCertsExists() | |||||
| { | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupPfx("Certs/asB.pfx", "14814622"); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,97 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.B2B; | |||||
| using BWP.ABCClient.B2C; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using BWP.ABCClient.Common; | |||||
| using BWP.ABCClient.Market; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class BusinessTest | |||||
| { | |||||
| [Test] | |||||
| public void B2CRequest() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| using (new MockWebServer("http://localhost:5000/B2C/", Encoding.UTF8, Encoding.GetEncoding("GB2312"), false)) { | |||||
| var business = new BusinessBase<PaymentRequest, PaymentURLResponse>(BusinessTypes.B2C); | |||||
| business.MerchantID = "103452083980419"; | |||||
| business.RequestUrl = "http://localhost:5000/B2C/"; | |||||
| business.RequestObj = PaymentRequest.New(); | |||||
| business.Request(); | |||||
| var responseObj = business.ResponseObj; | |||||
| Assert.AreEqual("https://easyabc.95599.cn/b2c/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12977496798933397376", responseObj.Message.TrxResponse.PaymentURL); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void B2BRequest() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| using (new MockWebServer("http://localhost:5000/B2B/", Encoding.UTF8, Encoding.UTF8, false)) { | |||||
| var business = new BusinessBase<FundTransferRequest, PaymentURLResponse>(BusinessTypes.B2B); | |||||
| business.MerchantID = "337100000000066"; | |||||
| business.RequestUrl = "http://localhost:5000/B2B/"; | |||||
| business.RequestObj = FundTransferRequest.New(); | |||||
| business.Request(); | |||||
| var responseObj = business.ResponseObj; | |||||
| Assert.AreEqual("https://easyabc.95599.cn/b2b/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12975716546177309876", responseObj.Message.TrxResponse.PaymentURL); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void MarketRequest() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| Encoding gb2312Encoding = Encoding.GetEncoding("GB2312"); | |||||
| using (new MockWebServer("http://localhost:5000/Market/", gb2312Encoding, gb2312Encoding, true)) { | |||||
| var business = new BusinessBase<PayRequest, MarketResponse>(BusinessTypes.Market); | |||||
| business.MerchantID = "337100000000066"; | |||||
| business.RequestUrl = "http://localhost:5000/Market/"; | |||||
| business.RequestObj = PayRequest.New(); | |||||
| business.Request(); | |||||
| var responseObj = business.ResponseObj; | |||||
| Assert.AreEqual("337199901033E01", responseObj.Message.Control.MerchantID); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void MarketOrderApplyRequest() | |||||
| { | |||||
| EnsureCertsExists(); | |||||
| Encoding gb2312Encoding = Encoding.GetEncoding("GB2312"); | |||||
| var orderApplyRequest=OrderApplyRequest.New(); | |||||
| orderApplyRequest.Message.Control.MerchantTrxNo = "Req110607008"; | |||||
| orderApplyRequest.Message.Control.MerchantID = "337199901033E01"; | |||||
| orderApplyRequest.Message.Parameters.BuyerCustomer = "84000471247"; | |||||
| orderApplyRequest.Message.Parameters.PayAmount = "0.01"; | |||||
| orderApplyRequest.Message.Parameters.OrderNo = "00000000011"; | |||||
| orderApplyRequest.Message.Parameters.SalerCustomer = "84003761702"; | |||||
| orderApplyRequest.Message.Parameters.SalerCustName = "张冠群"; | |||||
| orderApplyRequest.Message.Parameters.BuyerCustName = "宋元华"; | |||||
| using (new MockWebServer("http://localhost:5000/MarketOrderApply/", gb2312Encoding, gb2312Encoding, true)) { | |||||
| var business = new BusinessBase<OrderApplyRequest, OrderApplyResponse>(BusinessTypes.Market); | |||||
| business.MerchantID = "337199901033E01"; | |||||
| business.RequestUrl = "http://localhost:5000/MarketOrderApply/"; | |||||
| business.RequestObj = orderApplyRequest; | |||||
| business.Request(); | |||||
| var responseObj = business.ResponseObj; | |||||
| Console.WriteLine(MsgUtil.MsgToBareXml(orderApplyRequest)); | |||||
| Assert.AreEqual("337199901033E01", responseObj.Message.Control.MerchantID); | |||||
| } | |||||
| } | |||||
| private void EnsureCertsExists() { | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupPfx("Certs/asC.pfx", "14814622"); | |||||
| certManager.SetupPfx("Certs/asB.pfx", "14814622"); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| certManager.SetupABCPubKey("Certs/TrustPayTest.cer"); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,93 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.Security.Cryptography; | |||||
| using System.Xml.Serialization; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class CertManagerTest | |||||
| { | |||||
| [SetUp] | |||||
| public void Setup() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| manager.ClearAll(); | |||||
| } | |||||
| [Test] | |||||
| public void SetupLocation() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| const string fileName = "Certs/asB.pfx"; | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(fileName, password); | |||||
| var cert = manager.Fetch("337100000000066"); | |||||
| var rsa = cert.PrivateKey as RSACryptoServiceProvider; | |||||
| } | |||||
| [Test] | |||||
| public void ClearAll() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| const string fileName = "Certs/asB.pfx"; | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(fileName, password); | |||||
| manager.ClearAll(); | |||||
| var certs = manager.FetchAll(); | |||||
| Assert.IsTrue(certs.Count == 0); | |||||
| } | |||||
| [Test] | |||||
| public void SetupPfxFile() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| const string fileName = "Certs/asB.pfx"; | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(fileName, password); | |||||
| var cert = manager.Fetch("337100000000066"); | |||||
| Assert.AreEqual("7B97CA10275A0121D1B9", cert.SerialNumber); | |||||
| } | |||||
| [Test] | |||||
| public void Remove() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| const string fileName = "Certs/asB.pfx"; | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(fileName, password); | |||||
| manager.Remove("337100000000066"); | |||||
| try { | |||||
| manager.Fetch("337100000000066"); | |||||
| Assert.Fail("error"); | |||||
| } catch (Exception e) { | |||||
| Assert.AreEqual("找不到商户号对应的证书", e.Message); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void SetupPfxStream() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| using (var stream = File.OpenRead("Certs/asB.pfx")) { | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(stream, password); | |||||
| } | |||||
| var cert = manager.Fetch("337100000000066"); | |||||
| Assert.AreEqual("7B97CA10275A0121D1B9", cert.SerialNumber); | |||||
| } | |||||
| [Test] | |||||
| public void ExportCert() | |||||
| { | |||||
| var manager = new CertManager(); | |||||
| const string fileName = "Certs/asB.pfx"; | |||||
| const string password = "14814622"; | |||||
| manager.SetupPfx(fileName, password); | |||||
| using (var stream = File.OpenWrite("Certs/asBclone.pfx")) { | |||||
| manager.Export("337100000000066", password, stream); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,78 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using System.Threading; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class LogTest | |||||
| { | |||||
| [Test] | |||||
| public void CommitAndLoadTest() | |||||
| { | |||||
| var log = new AbcLog("test"); | |||||
| log.Clear(); | |||||
| log.AddNewLine("开始交易:"); | |||||
| log.AddNewLine("检查配置:"); | |||||
| log.Add("正确"); | |||||
| log.Commit(); | |||||
| Assert.AreEqual(string.Format("\r\n{0} 开始交易:\r\n{0} 检查配置:正确", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), log.Load()); | |||||
| } | |||||
| [Test] | |||||
| public void ThreadTest() | |||||
| { | |||||
| new AbcLog("test").Clear(); | |||||
| var t = new Thread(ThreadProc); | |||||
| t.Start(); | |||||
| for (int i = 0; i < 9; i++) { | |||||
| var log = new AbcLog("test"); | |||||
| log.AddNewLine("接受农行回馈:" + i); | |||||
| log.Add("正确"); | |||||
| log.Commit(); | |||||
| Thread.Sleep(1); | |||||
| } | |||||
| t.Join(); | |||||
| Console.WriteLine(new AbcLog("test").Load()); | |||||
| } | |||||
| static void ThreadProc() | |||||
| { | |||||
| for (var i = 0; i < 10; i++) { | |||||
| var log = new AbcLog("test"); | |||||
| log.AddNewLine("开始交易:" + i); | |||||
| log.AddNewLine("检查配置:"); | |||||
| log.Add("正确"); | |||||
| log.Commit(); | |||||
| Thread.Sleep(1); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void B2BLogTest() | |||||
| { | |||||
| var log = new AbcLog(BusinessTypes.B2B.Name); | |||||
| log.Clear(); | |||||
| B2BReceivingPaymentTest.EnsureCertsExists(); | |||||
| var collections = new B2BReceivingPayment(); | |||||
| collections.MerchantID = "337100000000066"; | |||||
| collections.Date = DateTime.Now; | |||||
| collections.Amount = 234.5m; | |||||
| collections.AccountNo = "622587263489712639846"; | |||||
| collections.ResultNotifyURL = "http://a.b.c.d"; | |||||
| collections.SequenceNo = "209329384902834"; | |||||
| collections.RequestUrl = "http://localhost:5000/B2B/"; | |||||
| using (new MockWebServer("http://localhost:5000/B2B/", Encoding.UTF8, Encoding.UTF8, false)) { | |||||
| collections.Request(); | |||||
| ; | |||||
| } | |||||
| Console.WriteLine(log.Load()); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,86 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.Text; | |||||
| using System.Net; | |||||
| using System.Threading; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| public sealed class MockWebServer : IDisposable | |||||
| { | |||||
| private readonly HttpListener _listener; | |||||
| private readonly Thread _thread; | |||||
| private readonly Encoding _reqEncoding; | |||||
| private Encoding _respEncoding; | |||||
| private readonly bool _compressResp; | |||||
| public MockWebServer() : this("http://localhost:5000/", Encoding.UTF8, Encoding.UTF8, false) | |||||
| { | |||||
| } | |||||
| public MockWebServer(string prefix, Encoding reqEncoding, Encoding respEncoding, bool compressResp) | |||||
| { | |||||
| try { | |||||
| _listener = new HttpListener(); | |||||
| _listener.Prefixes.Add(prefix); | |||||
| _listener.Start(); | |||||
| Console.WriteLine("MockWebServer Listening... "); | |||||
| _thread = new Thread(Listen); | |||||
| _thread.Start(); | |||||
| } catch (Exception e) { | |||||
| Console.WriteLine(e); | |||||
| } | |||||
| _reqEncoding = reqEncoding; | |||||
| _respEncoding = respEncoding; | |||||
| _compressResp = compressResp; | |||||
| } | |||||
| private void Listen() | |||||
| { | |||||
| while (true) { | |||||
| HttpListenerContext context = _listener.GetContext(); | |||||
| HttpListenerRequest request = context.Request; | |||||
| string receivedData; | |||||
| using (var inputStream = request.InputStream) { | |||||
| using (var inputReader = new StreamReader(inputStream, _reqEncoding)) { | |||||
| receivedData = inputReader.ReadToEnd(); | |||||
| } | |||||
| } | |||||
| Console.WriteLine("ReceivedData:"); | |||||
| Console.WriteLine(receivedData); | |||||
| string responseStr = string.Empty; | |||||
| if (request.RawUrl.Contains("B2C")) { | |||||
| responseStr = "<MSG><Message><Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980410</MerchantID></Merchant><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage>交易成功</ErrorMessage><TrxType>PayReq</TrxType><OrderNo>634333749713468745</OrderNo><PaymentURL>https://easyabc.95599.cn/b2c/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12977496798933397376</PaymentURL><OrderAmount>170940.8</OrderAmount></TrxResponse></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>eAy2xu/VmFnkHEY5sAxwmV/NfbXUDRzLH3IJa7oXOMuGGHHkXfYlwFfe2HesKq6gQgfFcfIsNs0bEc8r6EDkzZVETuiVviQxahqnqr0+GRnfly5OwNELtFCbtJ5PdzuWjme6SbNPSTqMUN6bRWzgr/UXrkuo3uyJOIIyCFGsFbs=</Signature></MSG>"; | |||||
| _respEncoding = Encoding.GetEncoding("gb2312"); | |||||
| } | |||||
| if (request.RawUrl.Contains("B2B")) { | |||||
| responseStr = "<MSG><Message><Merchant><ECMerchantType>B2B</ECMerchantType><MerchantID>337100000000066</MerchantID></Merchant><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage>交易成功</ErrorMessage><TrnxType>FundTransfer</TrnxType><TrnxAMT>.1</TrnxAMT><MerchantTrnxNo>634331972002042500</MerchantTrnxNo><PaymentURL>https://easyabc.95599.cn/b2b/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12975716546177309876</PaymentURL></TrxResponse></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>977AkRZUxtHflGP4fyvfNFpcmjuD0goKvRWD+w5g/bx45ZiCkGIki3wDwtgSNBA+QDBs/cyYAsR6AxuIs9CC0obMeSMrMBbixKJgJkNKO0UPlIU4seJ5rSlYKT1HX7tNE1SI7/VEmsv9i0r110hQjkSjzFhVrv9jRlMhNxSopbg=</Signature></MSG>"; | |||||
| } | |||||
| if (request.RawUrl.Contains("Market")) { | |||||
| responseStr = "<MSG><Message><Control><MerchantTrxNo>RSU110406001</MerchantTrxNo><ChannelType>01</ChannelType><Version>Java_V1.0</Version><ClientIP>187.61.1.1</ClientIP><BusinessID>MARKET</BusinessID><FunctionID>0000</FunctionID><ReturnCode>0000</ReturnCode><MerchantID>337199901033E01</MerchantID></Control><Parameters></Parameters><Resultsets></Resultsets></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>evJk/wQM5BjR72vHSCd1wgXSK8ZSRCVHbKv15faI1dY5kr4oz7ThBftaqcKqV7548QoDrMT0M3nITOffUU2CkLqb4TJcLAFZm+UVX2p/+1J2VPR0pBOnVLde8F6ADtnSV4IvqOCSkRi1Zoymr6UQ1gVw9p1Mh+TgOd6K85Zhitk=</Signature></MSG>"; | |||||
| } | |||||
| if (request.RawUrl.Contains("MarketOrderApply")) { | |||||
| responseStr = "<MSG><Message><Control><MerchantTrxNo>Req110607008</MerchantTrxNo><ReturnMessage>交易成功</ReturnMessage><ChannelType>01</ChannelType><Version>Java_V1.0</Version><BusinessID>MARKET</BusinessID><FunctionID>0025</FunctionID><ReturnCode>0000</ReturnCode><MerchantID>337199901033E01</MerchantID></Control><Parameters><OrderDate>2011-06-07 11:13:18</OrderDate><ReturnURL>https://www.95599.cn/market/MarketOrderPay.ebf?token=13074163984216493171</ReturnURL></Parameters><Resultsets></Resultsets></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>MI99KF8wCoZR9DDBVEZWPFPJqJJFHV4Eci7/LJKP46fmaK3N4y9nWXPhJ+STnAZ5xwvjpRrgZqzcwVEY4acI0EqaUfADvzVV5jIgXatFG8gO1UhL3YpfK7HJX5lXdBcSN72QNuJA1M9ZbaH6KDhs3V/fWYrlLfTrdHnfjKssxMY=</Signature></MSG>"; | |||||
| } | |||||
| if (_compressResp) { | |||||
| responseStr = MsgUtil.Compress(responseStr); | |||||
| } | |||||
| HttpListenerResponse response = context.Response; | |||||
| byte[] buffer = _respEncoding.GetBytes(responseStr); | |||||
| response.ContentLength64 = buffer.Length; | |||||
| using (Stream output = response.OutputStream) { | |||||
| output.Write(buffer, 0, buffer.Length); | |||||
| } | |||||
| } | |||||
| } | |||||
| public void Dispose() | |||||
| { | |||||
| _thread.Abort(); | |||||
| _listener.Stop(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,67 @@ | |||||
| using System; | |||||
| using BWP.ABCClient.B2B; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class MsgUtilTest | |||||
| { | |||||
| [Test] | |||||
| public void ParseReturnMsg() | |||||
| { | |||||
| string msg = "PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PFJldHVybkNvZGU+MDAwMDwvUmV0dXJuQ29kZT48RXJyb3JNZXNzYWdlPjwvRXJyb3JNZXNzYWdlPjxFQ01lcmNoYW50VHlwZT5CMkM8L0VDTWVyY2hhbnRUeXBlPjxNZXJjaGFudElEPjEwMzQ1MjA4Mzk4MDQwNDwvTWVyY2hhbnRJRD48VHJ4VHlwZT5QYXlSZXN1bHQ8L1RyeFR5cGU+PE9yZGVyTm8+VGVzdE9yZGVyPC9PcmRlck5vPjxBbW91bnQ+MTAwLjA8L0Ftb3VudD48QmF0Y2hObz4wMDAwMDE8L0JhdGNoTm8+PFZvdWNoZXJObz4xMjM0NTY8L1ZvdWNoZXJObz48SG9zdERhdGU+MjAwOS8wOS8wODwvSG9zdERhdGU+PEhvc3RUaW1lPjEwOjU1OjUwPC9Ib3N0VGltZT48TWVyY2hhbnRSZW1hcmtzPlRoaXMgaXMgdGVzdCE8L01lcmNoYW50UmVtYXJrcz48UGF5VHlwZT5QQVkwMTwvUGF5VHlwZT48Tm90aWZ5VHlwZT4wPC9Ob3RpZnlUeXBlPjwvVHJ4UmVzcG9uc2U+PC9NZXNzYWdlPjxTaWduYXR1cmUtQWxnb3JpdGhtPlNIQTF3aXRoUlNBPC9TaWduYXR1cmUtQWxnb3JpdGhtPjxTaWduYXR1cmU+SVE4Z2pFSlRvK0FXQWxqWGVhcVVwdW43Z1JCNnNWdEhRSS9pNFdqUTNISExqZmphMTF3RE5VRVUyVzBVRUNsQnp5RFZuc0tRUHE2MmliM21YRjgrSnJZTWdpYW53WDNBNlRJbkxXMXJQTldVV1AwNGl5UVIvTUxuMHNaTjJ1S2JFbU5SWXRURjNPQ0lsTHFEblppYk1tSEZPTzhnektneVBxeEtaUkRRaHRZPTwvU2lnbmF0dXJlPjwvTVNHPg=="; | |||||
| Console.WriteLine(MsgUtil.FromBase64StringToXml(msg)); | |||||
| } | |||||
| [Test] | |||||
| public void SelectMultiNode() | |||||
| { | |||||
| string str = "<Records><Record>123</Record><Record>134</Record><Record>456</Record></Records>"; | |||||
| string[] values = MsgUtil.GetMultiInnerXml(str, "//Record"); | |||||
| Assert.AreEqual("123", values[0]); | |||||
| Assert.AreEqual("134", values[1]); | |||||
| Assert.AreEqual("456", values[2]); | |||||
| } | |||||
| [Test] | |||||
| public void MsgToXml() | |||||
| { | |||||
| var msg = FundTransferRequest.New(); | |||||
| var xml = MsgUtil.MsgToBareXml(msg); | |||||
| Console.WriteLine(xml); | |||||
| msg = MsgUtil.ParseXmlToMsg<FundTransferRequest>(xml); | |||||
| Console.WriteLine(msg.Message.Merchant.ECMerchantType); | |||||
| var response = new FundTransferResponse(); | |||||
| response.Message = new FundTransferResponse.MessageContent(); | |||||
| response.Message.TrxResponse = new FundTransferResponse.TrxResponseContent(); | |||||
| response.Message.TrxResponse.ReturnCode = "0000"; | |||||
| xml = MsgUtil.MsgToBareXml(response); | |||||
| Console.WriteLine(xml); | |||||
| var obj = MsgUtil.ParseXmlToMsg<FundTransferResponse>(xml); | |||||
| Assert.AreEqual("0000", obj.Message.TrxResponse.ReturnCode); | |||||
| } | |||||
| [Test] | |||||
| public void GetInnerXml() | |||||
| { | |||||
| var msg = "<MSG><Message><Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>634333823922218745</OrderNo><OrderAmount>254011</OrderAmount><OrderDesc></OrderDesc><OrderDate>2011/02/15</OrderDate><OrderTime>16:02:29</OrderTime><OrderURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx?id=10821</OrderURL><OrderItems></OrderItems></Order><ProductType>2</ProductType><PaymentType>1</PaymentType><NotifyType>1</NotifyType><ResultNotifyURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx</ResultNotifyURL><MerchantRemarks></MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>Nj7TTt4jyHTH93TekdWXr98tFKbjz/aRx3PBaE0SA6ns4bwqLbpI/27ljN90tElzqVnZWyHIKjDjo25SpPkgXlCsQGHtQcLbA6ZVXVqH18SjLxc4baUyEokMlnpbPYHAiOufOG3Ss8bI3/QlCbESV+7aeOwBfkQESAYvzsZWSWE=</Signature></MSG>"; | |||||
| var expectmsg = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>634333823922218745</OrderNo><OrderAmount>254011</OrderAmount><OrderDesc></OrderDesc><OrderDate>2011/02/15</OrderDate><OrderTime>16:02:29</OrderTime><OrderURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx?id=10821</OrderURL><OrderItems></OrderItems></Order><ProductType>2</ProductType><PaymentType>1</PaymentType><NotifyType>1</NotifyType><ResultNotifyURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx</ResultNotifyURL><MerchantRemarks></MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest>"; | |||||
| Assert.AreEqual(expectmsg, MsgUtil.GetInnerXml(msg, "Message")); | |||||
| expectmsg = "Nj7TTt4jyHTH93TekdWXr98tFKbjz/aRx3PBaE0SA6ns4bwqLbpI/27ljN90tElzqVnZWyHIKjDjo25SpPkgXlCsQGHtQcLbA6ZVXVqH18SjLxc4baUyEokMlnpbPYHAiOufOG3Ss8bI3/QlCbESV+7aeOwBfkQESAYvzsZWSWE="; | |||||
| Assert.AreEqual(expectmsg, MsgUtil.GetInnerXml(msg, "Signature")); | |||||
| } | |||||
| [Test] | |||||
| public void CompressDeCompress() | |||||
| { | |||||
| string str = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage>交易成功</ErrorMessage><TrxType>PayReq</TrxType><OrderNo>634333823922218745</OrderNo><PaymentURL>https://easyabc.95599.cn/b2c/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12977568750460430844</PaymentURL><OrderAmount>254011</OrderAmount></TrxResponse>"; | |||||
| Assert.AreEqual(str, MsgUtil.DeCompress(MsgUtil.Compress(str))); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,35 @@ | |||||
| using System.Reflection; | |||||
| using System.Runtime.CompilerServices; | |||||
| using System.Runtime.InteropServices; | |||||
| // General Information about an assembly is controlled through the following | |||||
| // set of attributes. Change these attribute values to modify the information | |||||
| // associated with an assembly. | |||||
| [assembly: AssemblyTitle("test")] | |||||
| [assembly: AssemblyDescription("")] | |||||
| [assembly: AssemblyConfiguration("")] | |||||
| [assembly: AssemblyCompany("")] | |||||
| [assembly: AssemblyProduct("test")] | |||||
| [assembly: AssemblyCopyright("Copyright © 2011")] | |||||
| [assembly: AssemblyTrademark("")] | |||||
| [assembly: AssemblyCulture("")] | |||||
| // Setting ComVisible to false makes the types in this assembly not visible | |||||
| // to COM components. If you need to access a type in this assembly from | |||||
| // COM, set the ComVisible attribute to true on that type. | |||||
| [assembly: ComVisible(false)] | |||||
| // The following GUID is for the ID of the typelib if this project is exposed to COM | |||||
| [assembly: Guid("38052bef-0132-48b6-a766-0e3b52f90baf")] | |||||
| // Version information for an assembly consists of the following four values: | |||||
| // | |||||
| // Major Version | |||||
| // Minor Version | |||||
| // Build Number | |||||
| // Revision | |||||
| // | |||||
| // You can specify all the values or you can default the Build and Revision Numbers | |||||
| // by using the '*' as shown below: | |||||
| // [assembly: AssemblyVersion("1.0.*")] | |||||
| [assembly: AssemblyVersion("1.0.0.0")] | |||||
| @ -0,0 +1,54 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses.Type; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class RSAServiceTest | |||||
| { | |||||
| [SetUp] | |||||
| public void Setup() | |||||
| { | |||||
| new CertManager().ClearAll(); | |||||
| } | |||||
| [Test] | |||||
| public void Sign() | |||||
| { | |||||
| string msg = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxRequest><TrxType>PayReq</TrxType><Order><OrderNo>634333823922218745</OrderNo><OrderAmount>254011</OrderAmount><OrderDesc></OrderDesc><OrderDate>2011/02/15</OrderDate><OrderTime>16:02:29</OrderTime><OrderURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx?id=10821</OrderURL><OrderItems></OrderItems></Order><ProductType>2</ProductType><PaymentType>1</PaymentType><NotifyType>1</NotifyType><ResultNotifyURL>http://119.167.225.52/B2/InternetSale/Pub/B2CReceive.aspx</ResultNotifyURL><MerchantRemarks></MerchantRemarks><PaymentLinkType>1</PaymentLinkType></TrxRequest>"; | |||||
| string sign = "yGt5aaDrHmWBFb5Lk5WZlLmpuJXe4B25/t4FJzvQlAeKA+cqegiddcpfjGbv3AmspoRqZYNTEfnyLSOjZ8iz9L1U5nl415CzNml2uTLx1aiX4SpHSQASlu6fGqgO2yl2PrABslo+/njsy1tkzwFGm+y1gpjPNykkOWpaYyUjnfw="; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupPfx("Certs/asC.pfx", "14814622"); | |||||
| var signedMsg = RSAService.Sign(msg, "103452083980419"); | |||||
| Console.WriteLine(signedMsg); | |||||
| Assert.AreEqual(sign, signedMsg); | |||||
| } | |||||
| [Test] | |||||
| public void Verify() | |||||
| { | |||||
| string returnMsg = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage>交易成功</ErrorMessage><TrxType>PayReq</TrxType><OrderNo>634333823922218745</OrderNo><PaymentURL>https://easyabc.95599.cn/b2c/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12977568750460430844</PaymentURL><OrderAmount>254011</OrderAmount></TrxResponse>"; | |||||
| string abcSign = "3+0sE/7PTfYfHYqHUwWoFzUVvr0h2HUaXpq5pr+r3+DhyvufhVUPq1We9a0E+DzqzwnW3ZD5EYLhA204o4oRiLauEzM1cj8ddXZJGAtk5ftv1OGVCV+bvts/Ei9FQp8ws5b7pNqAvIyoSbIToartR7AJ42RJsT5DxXBtFy0Y2oQ="; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| var pass = RSAService.Verify(returnMsg, abcSign); | |||||
| Assert.IsTrue(pass); | |||||
| } | |||||
| [Test] | |||||
| public void MarketVerify() | |||||
| { | |||||
| string returnMsg = "<Message><Control><MerchantTrxNo>1301643918078</MerchantTrxNo><ReturnMessage>商户状态不允许交易!</ReturnMessage><ChannelType>01</ChannelType><Version>Java_V1.0</Version><ClientIP>187.61.1.1</ClientIP><BusinessID>MARKET</BusinessID><FunctionID>0000</FunctionID><ReturnCode>500105</ReturnCode><MerchantID>337199901033E01</MerchantID></Control><Parameters></Parameters><Resultsets></Resultsets></Message>"; | |||||
| string abcSign = "0m9ZR3zXZPKNa7z7Tr3DqHSoDx8NzgHeI0UCmlnpCqBGZS/YcGNZ+UThdVgfBacC27ELhtnRQaAzduQ0zzROs/Cpqm6h8BXfbhaU6Qr+Pp7Qfsu13XuBGr0iCfesFY5yoUlBnedUxCz6GOt9hGhVpPGsROvXU1cKIyafEGtpn9k="; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| var pass = RSAService.Verify(returnMsg, abcSign ); | |||||
| Assert.IsTrue(pass); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,27 @@ | |||||
| using System; | |||||
| using System.Text; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class RequestTest | |||||
| { | |||||
| private const string MSG = "<MSG><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature></Signature><Message><Merchant><ECMerchantType>B2B</ECMerchantType><MerchantID></MerchantID></Merchant><TrxRequest><TrxType>FundTransfer</TrxType><MerchantTrnxNo></MerchantTrnxNo><TrnxAmount>0</TrnxAmount><TrnxDate></TrnxDate><TrnxTime></TrnxTime><AccountDB><AccountDBNo></AccountDBNo><AccountDBName></AccountDBName><AccountDBBank></AccountDBBank></AccountDB><TrnxInfo><TrnxOpr></TrnxOpr><TrnxRemarks><Remark><Key>充值时间</Key><Value></Value></Remark></TrnxRemarks><TrnxItems><TrnxItem><ProductID></ProductID><ProductName>人民币</ProductName><UnitPrice>0</UnitPrice><Qty>1</Qty></TrnxItem></TrnxItems></TrnxInfo><ResultNotifyURL></ResultNotifyURL><MerchantRemarks></MerchantRemarks></TrxRequest></Message></MSG>"; | |||||
| [Test] | |||||
| public void Request() | |||||
| { | |||||
| using (new MockWebServer()) { | |||||
| var request = new Request { | |||||
| Url = "http://localhost:5000/", | |||||
| RequestEncoding = Encoding.UTF8, | |||||
| ResponseEncoding = Encoding.UTF8, | |||||
| Message = MSG | |||||
| }; | |||||
| string receivedMsg = request.Run(); | |||||
| Console.WriteLine("client received:" + receivedMsg); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,57 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Linq; | |||||
| using System.Text; | |||||
| using BWP.ABCClient.Businesses; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class ResultReturnedTest | |||||
| { | |||||
| [Test] | |||||
| public void B2BTest() | |||||
| { | |||||
| const string msg = "PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PE1lcmNoYW50SUQ+MzM3MTAwMDAwMDAwMDU2PC9NZXJjaGFudElEPjxDb3Jwb3JhdGlvbkN1c3RvbWVyTm8+Mzc5OTk2NzE5NjU8L0NvcnBvcmF0aW9uQ3VzdG9tZXJObz48TWVyY2hhbnRUcm54Tm8+NjM0Mzc0MTU0NDI5MzE3NTAwPC9NZXJjaGFudFRybnhObz48VHJueFNOPjwvVHJueFNOPjxUcm54VHlwZT5GVU5EX1RSQU5TRkVSPC9Ucm54VHlwZT48VHJueEFNVD4xODU3MTIxLjAwPC9Ucm54QU1UPjxPcmdpbmFsRnJlZXplTm8+PC9PcmdpbmFsRnJlZXplTm8+PEZyZWV6ZU5vPjwvRnJlZXplTm8+PEFjY291bnRObz48L0FjY291bnRObz48QWNjb3VudE5hbWU+PC9BY2NvdW50TmFtZT48QWNjb3VudEJhbms+PC9BY2NvdW50QmFuaz48QWNjb3VudERCTm8+MTUtNDkxMTAxMDQwMDIwNTIzPC9BY2NvdW50REJObz48QWNjb3VudERCTmFtZT7Busm9wfm6zb7FwPvKs8a309DP3rmry748L0FjY291bnREQk5hbWU+PEFjY291bnREQkJhbms+MzQyNzc8L0FjY291bnREQkJhbms+PFRybnhUaW1lPjIwMTEtMDQtMDMgMDg6MTg6NTI8L1RybnhUaW1lPjxUcm54U3RhdHVzPjA8L1RybnhTdGF0dXM+PFJldHVybkNvZGU+PC9SZXR1cm5Db2RlPjwvVHJ4UmVzcG9uc2U+PC9NZXNzYWdlPjxTaWduYXR1cmUtQWxnb3JpdGhtPlNIQTF3aXRoUlNBPC9TaWduYXR1cmUtQWxnb3JpdGhtPjxTaWduYXR1cmU+Y2sra3V6Mk9KRVpwTWlhLzBva3JPOTAvZWdVTnZDeUN2cjdZRXN0SXA3aGtYeGEzbDJDWVNMd1NpczlHU0p3OVYrQitlVHkrRGRZUDF0cWZlaHRRZmEyZWQxMENRR2Z0eTViL3F4R2VRL3ZrR1NTOUNOTWxDNjdOV1VMTnhCaVdxNkFVQkwybndUbkVmRzV3VXZjZ3BrTHE2VWF6MklUekhBTWZselBmU1ZJPTwvU2lnbmF0dXJlPjwvTVNHPg=="; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| var result = new ResultB2BReturned(msg); | |||||
| Console.WriteLine(result.Xml); | |||||
| Assert.IsTrue(result.IsValid); | |||||
| Assert.AreEqual(@"<MSG><Message><TrxResponse><MerchantID>337100000000056</MerchantID><CorporationCustomerNo>37999671965</CorporationCustomerNo><MerchantTrnxNo>634374154429317500</MerchantTrnxNo><TrnxSN></TrnxSN><TrnxType>FUND_TRANSFER</TrnxType><TrnxAMT>1857121.00</TrnxAMT><OrginalFreezeNo></OrginalFreezeNo><FreezeNo></FreezeNo><AccountNo></AccountNo><AccountName></AccountName><AccountBank></AccountBank><AccountDBNo>15-491101040020523</AccountDBNo><AccountDBName>梁山六和九利食品有限公司</AccountDBName><AccountDBBank>34277</AccountDBBank><TrnxTime>2011-04-03 08:18:52</TrnxTime><TrnxStatus>0</TrnxStatus><ReturnCode></ReturnCode></TrxResponse></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>ck+kuz2OJEZpMia/0okrO90/egUNvCyCvr7YEstIp7hkXxa3l2CYSLwSis9GSJw9V+B+eTy+DdYP1tqfehtQfa2ed10CQGfty5b/qxGeQ/vkGSS9CNMlC67NWULNxBiWq6AUBL2nwTnEfG5wUvcgpkLq6Uaz2ITzHAMflzPfSVI=</Signature></MSG>", result.Xml); | |||||
| } | |||||
| [Test] | |||||
| public void B2BTest2() | |||||
| { | |||||
| const string msg = "PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PE1lcmNoYW50SUQ+MzM3MTAwMDAwMDAwMDc1PC9NZXJjaGFudElEPjxDb3Jwb3JhdGlvbkN1c3RvbWVyTm8+MzM5OTkwODc1NDA8L0NvcnBvcmF0aW9uQ3VzdG9tZXJObz48TWVyY2hhbnRUcm54Tm8+NjM0NDUzNzMwNTA3NDI3NTAwPC9NZXJjaGFudFRybnhObz48VHJueFNOPjkwMTEwNzA0MTA0OTQ5NDA1NzE8L1RybnhTTj48VHJueFR5cGU+RlVORF9UUkFOU0ZFUjwvVHJueFR5cGU+PFRybnhBTVQ+MTUwMDAwMDwvVHJueEFNVD48T3JnaW5hbEZyZWV6ZU5vPiA8L09yZ2luYWxGcmVlemVObz48RnJlZXplTm8+IDwvRnJlZXplTm8+PEFjY291bnRObz4xOS0wODAyMDEwNDAwNTc5MzQ8L0FjY291bnRObz48QWNjb3VudE5hbWU+urzW3c/owPvT8Mje1sbGt9PQz965q8u+PC9BY2NvdW50TmFtZT48QWNjb3VudEJhbms+1eO9rbfW0NA8L0FjY291bnRCYW5rPjxBY2NvdW50REJObz4xNS03NDA4MDEwNDAwMDE3MzM8L0FjY291bnREQk5vPjxBY2NvdW50REJOYW1lPrH11t3B+brNwqG078WpxMHT0M/euavLvjwvQWNjb3VudERCTmFtZT48QWNjb3VudERCQmFuaz7Jvbart9bQ0DwvQWNjb3VudERCQmFuaz48VHJueFRpbWU+MjAxMS03LTQgMTA6NDk6NDk8L1RybnhUaW1lPjxUcm54U3RhdHVzPjI8L1RybnhTdGF0dXM+PFJldHVybkNvZGU+MDAwMDwvUmV0dXJuQ29kZT48L1RyeFJlc3BvbnNlPjwvTWVzc2FnZT48U2lnbmF0dXJlLUFsZ29yaXRobT5TSEExd2l0aFJTQTwvU2lnbmF0dXJlLUFsZ29yaXRobT48U2lnbmF0dXJlPndBdHJYWFVMYkkvZDdvSWhma25KNm1sb1YzL2tEdFBFWWROd2h6R0swL2VtTUZxTGlTckgvbS93d3FiakNKZnNLajUxdW1NazI0TUY1QXY0Ui94YUZnYVJlQUNwYStET0x6SE9RTjlCV3ByWUF0SDJ6VjBub1BablJQU1hIQkVpSXowYTYwTFptZkc0emVNbE82Z045bWJGYXA2dzh3VWFnOGFNR3VBYmRGOD08L1NpZ25hdHVyZT48L01TRz4="; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| var result = new ResultB2BReturned(msg); | |||||
| Console.WriteLine(result.Xml); | |||||
| Assert.IsTrue(result.IsValid); | |||||
| Assert.AreEqual(@"<MSG><Message><TrxResponse><MerchantID>337100000000075</MerchantID><CorporationCustomerNo>33999087540</CorporationCustomerNo><MerchantTrnxNo>634453730507427500</MerchantTrnxNo><TrnxSN>9011070410494940571</TrnxSN><TrnxType>FUND_TRANSFER</TrnxType><TrnxAMT>1500000</TrnxAMT><OrginalFreezeNo> </OrginalFreezeNo><FreezeNo> </FreezeNo><AccountNo>19-080201040057934</AccountNo><AccountName>杭州翔利羽绒制品有限公司</AccountName><AccountBank>浙江分行</AccountBank><AccountDBNo>15-740801040001733</AccountDBNo><AccountDBName>滨州六和隆达农牧有限公司</AccountDBName><AccountDBBank>山东分行</AccountDBBank><TrnxTime>2011-7-4 10:49:49</TrnxTime><TrnxStatus>2</TrnxStatus><ReturnCode>0000</ReturnCode></TrxResponse></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>wAtrXXULbI/d7oIhfknJ6mloV3/kDtPEYdNwhzGK0/emMFqLiSrH/m/wwqbjCJfsKj51umMk24MF5Av4R/xaFgaReACpa+DOLzHOQN9BWprYAtH2zV0noPZnRPSXHBEiIz0a60LZmfG4zeMlO6gN9mbFap6w8wUag8aMGuAbdF8=</Signature></MSG>", result.Xml); | |||||
| } | |||||
| [Test] | |||||
| public void B2CTest() | |||||
| { | |||||
| const string msg = "PE1TRz48TWVzc2FnZT48VHJ4UmVzcG9uc2U+PFJldHVybkNvZGU+MDAwMDwvUmV0dXJuQ29kZT48RXJyb3JNZXNzYWdlPjwvRXJyb3JNZXNzYWdlPj" + "xFQ01lcmNoYW50VHlwZT5CMkM8L0VDTWVyY2hhbnRUeXBlPjxNZXJjaGFudElEPjEwMzQ1MjA4Mzk4MDQwNDwvTWVyY2hhbnRJRD48VHJ4VHlwZT5QYXlSZXN1bHQ8L1RyeFR5" + "cGU+PE9yZGVyTm8+VGVzdE9yZGVyPC9PcmRlck5vPjxBbW91bnQ+MTAwLjA8L0Ftb3VudD48QmF0Y2hObz4wMDAwMDE8L0JhdGNoTm8+PFZvdWNoZXJObz4xMjM0NTY8L1ZvdW" + "NoZXJObz48SG9zdERhdGU+MjAwOS8wOS8wODwvSG9zdERhdGU+PEhvc3RUaW1lPjEwOjU1OjUwPC9Ib3N0VGltZT48TWVyY2hhbnRSZW1hcmtzPlRoaXMgaXMgdGVzdCE8L01l" + "cmNoYW50UmVtYXJrcz48UGF5VHlwZT5QQVkwMTwvUGF5VHlwZT48Tm90aWZ5VHlwZT4wPC9Ob3RpZnlUeXBlPjwvVHJ4UmVzcG9uc2U+PC9NZXNzYWdlPjxTaWduYXR1cmUtQWx" + "nb3JpdGhtPlNIQTF3aXRoUlNBPC9TaWduYXR1cmUtQWxnb3JpdGhtPjxTaWduYXR1cmU+SVE4Z2pFSlRvK0FXQWxqWGVhcVVwdW43Z1JCNnNWdEhRSS9pNFdqUTNISExqZmphMT" + "F3RE5VRVUyVzBVRUNsQnp5RFZuc0tRUHE2MmliM21YRjgrSnJZTWdpYW53WDNBNlRJbkxXMXJQTldVV1AwNGl5UVIvTUxuMHNaTjJ1S2JFbU5SWXRURjNPQ0lsTHFEblppYk1tS" + "EZPTzhnektneVBxeEtaUkRRaHRZPTwvU2lnbmF0dXJlPjwvTVNHPg=="; | |||||
| ; | |||||
| var certManager = new CertManager(); | |||||
| certManager.SetupABCPubKey("Certs/TrustPay.cer"); | |||||
| var result = new ResultB2CReturned(msg); | |||||
| Assert.IsTrue(result.IsValid); | |||||
| Console.WriteLine(result.Xml); | |||||
| Assert.AreEqual(@"<MSG><Message><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage></ErrorMessage><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980404</MerchantID><TrxType>PayResult</TrxType><OrderNo>TestOrder</OrderNo><Amount>100.0</Amount><BatchNo>000001</BatchNo><VoucherNo>123456</VoucherNo><HostDate>2009/09/08</HostDate><HostTime>10:55:50</HostTime><MerchantRemarks>This is test!</MerchantRemarks><PayType>PAY01</PayType><NotifyType>0</NotifyType></TrxResponse></Message><Signature-Algorithm>SHA1withRSA</Signature-Algorithm><Signature>IQ8gjEJTo+AWAljXeaqUpun7gRB6sVtHQI/i4WjQ3HHLjfja11wDNUEU2W0UEClBzyDVnsKQPq62ib3mXF8+JrYMgianwX3A6TInLW1rPNWUWP04iyQR/MLn0sZN2uKbEmNRYtTF3OCIlLqDnZibMmHFOO8gzKgyPqxKZRDQhtY=</Signature></MSG>", result.Xml); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,153 @@ | |||||
| using System; | |||||
| using System.IO; | |||||
| using System.IO.Compression; | |||||
| using System.Security.Cryptography; | |||||
| using System.Security.Cryptography.X509Certificates; | |||||
| using System.Text; | |||||
| using System.Threading; | |||||
| using NUnit.Framework; | |||||
| namespace BWP.ABCClient | |||||
| { | |||||
| [TestFixture] | |||||
| public class Test | |||||
| { | |||||
| [Test] | |||||
| public void B2BMockWebServer() | |||||
| { | |||||
| new MockWebServer("http://localhost:5000/", Encoding.UTF8, Encoding.UTF8, false); | |||||
| Thread.Sleep(300000); | |||||
| } | |||||
| [Test] | |||||
| public void RSASendReveive() | |||||
| { | |||||
| const string original = "message that will be sent"; | |||||
| Sender mySender = new Sender(); | |||||
| Receiver myReceiver = new Receiver(); | |||||
| byte[] toEncrypt = Encoding.Default.GetBytes(original); | |||||
| byte[] encrypted = mySender.EncryptData(myReceiver.PublicKey, toEncrypt); | |||||
| byte[] signature = mySender.HashAndSign(encrypted); | |||||
| Console.WriteLine("Original: {0}", original); | |||||
| if (myReceiver.VerifyHash(mySender.PublicKey, encrypted, signature)) { | |||||
| myReceiver.DecryptData(encrypted); | |||||
| } else { | |||||
| Console.WriteLine("Invalid signature"); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void TryReadPfx() | |||||
| { | |||||
| try { | |||||
| X509Store store = new X509Store("MY", StoreLocation.CurrentUser); | |||||
| store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); | |||||
| X509Certificate2Collection collection = store.Certificates; | |||||
| X509Certificate2Collection fcollection = collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); | |||||
| X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select", "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.MultiSelection); | |||||
| Console.WriteLine("Number of certificates: {0}{1}", scollection.Count, Environment.NewLine); | |||||
| foreach (X509Certificate2 x509 in scollection) { | |||||
| byte[] rawdata = x509.RawData; | |||||
| Console.WriteLine("Content Type: {0}{1}", X509Certificate2.GetCertContentType(rawdata), Environment.NewLine); | |||||
| Console.WriteLine("Friendly Name: {0}{1}", x509.FriendlyName, Environment.NewLine); | |||||
| Console.WriteLine("Certificate Verified?: {0}{1}", x509.Verify(), Environment.NewLine); | |||||
| Console.WriteLine("颁发给: {0}{1}", x509.Subject, Environment.NewLine); | |||||
| Console.WriteLine("Simple Name: {0}{1}", x509.GetNameInfo(X509NameType.SimpleName, true), Environment.NewLine); | |||||
| Console.WriteLine("Signature Algorithm: {0}{1}", x509.SignatureAlgorithm.FriendlyName, Environment.NewLine); | |||||
| Console.WriteLine("Private Key: {0}{1}", x509.PrivateKey.ToXmlString(false), Environment.NewLine); | |||||
| Console.WriteLine("Public Key: {0}{1}", x509.PublicKey.Key.ToXmlString(false), Environment.NewLine); | |||||
| Console.WriteLine("Certificate Archived?: {0}{1}", x509.Archived, Environment.NewLine); | |||||
| Console.WriteLine("Length of Raw Data: {0}{1}", x509.RawData.Length, Environment.NewLine); | |||||
| X509Certificate2UI.DisplayCertificate(x509); | |||||
| x509.Reset(); | |||||
| } | |||||
| store.Close(); | |||||
| } catch (CryptographicException) { | |||||
| Console.WriteLine("Information could not be written out for this certificate."); | |||||
| } | |||||
| } | |||||
| [Test] | |||||
| public void VerifySignedByABC() | |||||
| { | |||||
| string returnMsg = "<Merchant><ECMerchantType>B2C</ECMerchantType><MerchantID>103452083980409</MerchantID></Merchant><TrxResponse><ReturnCode>0000</ReturnCode><ErrorMessage>交易成功</ErrorMessage><TrxType>PayReq</TrxType><OrderNo>634333823922218745</OrderNo><PaymentURL>https://easyabc.95599.cn/b2c/NotCheckStatus/PaymentModeAct.ebf?TOKEN=12977568750460430844</PaymentURL><OrderAmount>254011</OrderAmount></TrxResponse>"; | |||||
| string ABCSignature = "3+0sE/7PTfYfHYqHUwWoFzUVvr0h2HUaXpq5pr+r3+DhyvufhVUPq1We9a0E+DzqzwnW3ZD5EYLhA204o4oRiLauEzM1cj8ddXZJGAtk5ftv1OGVCV+bvts/Ei9FQp8ws5b7pNqAvIyoSbIToartR7AJ42RJsT5DxXBtFy0Y2oQ="; | |||||
| var cert = new X509Certificate2("Certs/TrustPay.cer"); | |||||
| var publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; | |||||
| var singature = Convert.FromBase64String(ABCSignature); | |||||
| var msgHash = new SHA1Managed().ComputeHash(Encoding.Default.GetBytes(returnMsg)); | |||||
| Assert.IsTrue(publicKey.VerifyHash(msgHash, cert.SignatureAlgorithm.Value, singature)); | |||||
| } | |||||
| } | |||||
| internal class Sender | |||||
| { | |||||
| private readonly RSACryptoServiceProvider _privateKey; | |||||
| private readonly RSACryptoServiceProvider _publicKey; | |||||
| public RSACryptoServiceProvider PublicKey | |||||
| { | |||||
| get { return _publicKey; } | |||||
| } | |||||
| public Sender() | |||||
| { | |||||
| var cert = new X509Certificate2("Certs/asB.pfx", "14814622"); | |||||
| _privateKey = (RSACryptoServiceProvider)cert.PrivateKey; | |||||
| _publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; | |||||
| } | |||||
| public byte[] HashAndSign(byte[] encryptedData) | |||||
| { | |||||
| byte[] hashedData = new SHA1Managed().ComputeHash(encryptedData); | |||||
| return _privateKey.SignHash(hashedData, CryptoConfig.MapNameToOID("SHA1")); | |||||
| } | |||||
| public byte[] EncryptData(RSACryptoServiceProvider receiverPublicKey, byte[] toEncrypt) | |||||
| { | |||||
| return receiverPublicKey.Encrypt(toEncrypt, false); | |||||
| } | |||||
| } | |||||
| internal class Receiver | |||||
| { | |||||
| private readonly RSACryptoServiceProvider _privateKey; | |||||
| private readonly RSACryptoServiceProvider _publicKey; | |||||
| public RSACryptoServiceProvider PublicKey | |||||
| { | |||||
| get { return _publicKey; } | |||||
| } | |||||
| public Receiver() | |||||
| { | |||||
| var cert = new X509Certificate2("Certs/asC.pfx", "14814622"); | |||||
| _privateKey = (RSACryptoServiceProvider)cert.PrivateKey; | |||||
| _publicKey = (RSACryptoServiceProvider)cert.PublicKey.Key; | |||||
| } | |||||
| //Manually performs hash and then verifies hashed value. | |||||
| public bool VerifyHash(RSACryptoServiceProvider senderPublicKey, byte[] encryptedData, byte[] signature) | |||||
| { | |||||
| byte[] hashedData = new SHA1Managed().ComputeHash(encryptedData); | |||||
| return senderPublicKey.VerifyHash(hashedData, CryptoConfig.MapNameToOID("SHA1"), signature); | |||||
| } | |||||
| //Decrypt using the private key data. | |||||
| public void DecryptData(byte[] encryptedData) | |||||
| { | |||||
| byte[] fromEncrypt = _privateKey.Decrypt(encryptedData, false); | |||||
| string roundTrip = Encoding.Default.GetString(fromEncrypt); | |||||
| Console.WriteLine("RoundTrip: {0}", roundTrip); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -0,0 +1,110 @@ | |||||
| <?xml version="1.0" encoding="utf-8"?> | |||||
| <Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
| <PropertyGroup> | |||||
| <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
| <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
| <ProductVersion>8.0.30703</ProductVersion> | |||||
| <SchemaVersion>2.0</SchemaVersion> | |||||
| <ProjectGuid>{9299FD15-70F9-4E71-9AB8-DC0C081FB7B5}</ProjectGuid> | |||||
| <OutputType>Library</OutputType> | |||||
| <AppDesignerFolder>Properties</AppDesignerFolder> | |||||
| <RootNamespace>BWP.ABCClient</RootNamespace> | |||||
| <AssemblyName>test</AssemblyName> | |||||
| <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||||
| <FileAlignment>512</FileAlignment> | |||||
| <KeyContainerName>BwpApp</KeyContainerName> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||||
| <DebugSymbols>true</DebugSymbols> | |||||
| <DebugType>full</DebugType> | |||||
| <Optimize>false</Optimize> | |||||
| <OutputPath>bin\Debug\</OutputPath> | |||||
| <DefineConstants>DEBUG;TRACE</DefineConstants> | |||||
| <ErrorReport>prompt</ErrorReport> | |||||
| <WarningLevel>4</WarningLevel> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||||
| <DebugType>pdbonly</DebugType> | |||||
| <Optimize>true</Optimize> | |||||
| <OutputPath>bin\Release\</OutputPath> | |||||
| <DefineConstants>TRACE</DefineConstants> | |||||
| <ErrorReport>prompt</ErrorReport> | |||||
| <WarningLevel>4</WarningLevel> | |||||
| </PropertyGroup> | |||||
| <ItemGroup> | |||||
| <Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Core"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Security"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Xml.Linq"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Data.DataSetExtensions"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="Microsoft.CSharp"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Data"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| <Reference Include="System.Xml"> | |||||
| <SpecificVersion>False</SpecificVersion> | |||||
| </Reference> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <Compile Include="..\..\..\version\tslib_version.cs"> | |||||
| <Link>tslib_version.cs</Link> | |||||
| </Compile> | |||||
| <Compile Include="B2BReceivingPaymentTest.cs" /> | |||||
| <Compile Include="BusinessTest.cs" /> | |||||
| <Compile Include="LogTest.cs" /> | |||||
| <Compile Include="ResultReturnedTest.cs" /> | |||||
| <Compile Include="RequestTest.cs" /> | |||||
| <Compile Include="CertManagerTest.cs" /> | |||||
| <Compile Include="MockWebServer.cs" /> | |||||
| <Compile Include="MsgUtilTest.cs" /> | |||||
| <Compile Include="Properties\AssemblyInfo.cs" /> | |||||
| <Compile Include="RSAServiceTest.cs" /> | |||||
| <Compile Include="Test.cs" /> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <ProjectReference Include="..\BWP.ABCClient\BWP.ABCClient.csproj"> | |||||
| <Project>{22FEFA9B-1D58-4E8A-A1FF-49CEED62C355}</Project> | |||||
| <Name>BWP.ABCClient</Name> | |||||
| </ProjectReference> | |||||
| </ItemGroup> | |||||
| <ItemGroup> | |||||
| <None Include="Certs\asB.pfx"> | |||||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
| </None> | |||||
| <None Include="Certs\asC.pfx"> | |||||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
| </None> | |||||
| <None Include="Certs\PDM.pfx"> | |||||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
| </None> | |||||
| <None Include="Certs\TrustPay.cer"> | |||||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
| </None> | |||||
| <None Include="Certs\TrustPayTest.cer"> | |||||
| <CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
| </None> | |||||
| </ItemGroup> | |||||
| <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||||
| <!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
| Other similar extension points exist, see Microsoft.Common.targets. | |||||
| <Target Name="BeforeBuild"> | |||||
| </Target> | |||||
| <Target Name="AfterBuild"> | |||||
| </Target> | |||||
| --> | |||||
| </Project> | |||||