| @ -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> | |||