using System;
using Newtonsoft.Json;
using System.Net;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Newtonsoft.Json.Linq;
namespace BasePaySdk
{
///
/// 网络通信类
///
public class NetUtils
{
public const string POST = "post";
public const string GET = "get";
///
/// 发送报文请求
///
///
/// 报文参数集合
/// 上传文件路径
/// 上传文件参数名
/// 接口功能编码
/// http请求方法
/// 商户配置信息
///
/// 返回报文
///
public static Dictionary requestBasePayWithFuncCode(Dictionary postParams, string filePath, string fileParam, string funcCode, string method, MerConfig merConfig)
{
if (null == merConfig || merConfig.RsaPrivateKey == null)
{
throw new Exception("privateKey 不能为空");
}
string requireUrl = fetchRequestUrl(funcCode);
HttpWebRequest request = null;
if (method.Equals(GET))
{
request = CreateGetRequest(postParams, requireUrl, merConfig);
}
else if (null != filePath)
{
request = CreateUploadRequest(postParams, filePath,fileParam, requireUrl, merConfig);
}
else
{
request = CreatePostRequest(postParams, requireUrl, merConfig);
}
Dictionary responseJson = null;
string responseText = null;
object responseSign = null;
String rsaPublicKey = merConfig.RsaPublicKey;
if(string.IsNullOrEmpty( rsaPublicKey )) {
rsaPublicKey = BasePay.HUIFU_DEFAULT_PUBLIC_KEY;
}
try
{
HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream(), Encoding.UTF8))
{
responseText = streamReader.ReadToEnd();
CoreUtils.Log("response:" + responseText);
if (responseText != null && responseText.Contains("html")) {
// 页面版本支付,需要将页面直接返回给
responseJson = new Dictionary();
responseJson.Add("data", responseText);
return responseJson;
}
Dictionary response = (Dictionary)JsonConvert.DeserializeObject>(responseText);
Dictionary data = (Dictionary)JsonConvert.DeserializeObject>(response["data"].ToString());
object respCode = null;
data.TryGetValue("resp_code", out respCode);
object respDesc = null;
data.TryGetValue("resp_desc", out respDesc);
string strRespCode = (string) respCode;
string strRespDesc = (string) respDesc;
// 判断接口调用是否成功
//if (!"10000".Equals(strRespCode)) {
// CoreUtils.Log("接口调用失败,失败原因:" + strRespDesc);
// throw new Exception("接口调用失败,失败原因:" + strRespDesc);
//}
CoreUtils.Log("response data....." + data);
responseSign = null;
response.TryGetValue("sign", out responseSign);
string strData = JsonConvert.SerializeObject(response["data"]);
string strSign = (string) responseSign;
if (!string.IsNullOrEmpty(strSign))
{
if (!RsaUtils.verfySign(rsaPublicKey, strSign, strData))
{
throw new Exception("public key veryfy singnature failed");
}
}
responseJson = data;
}
}
catch (WebException e)
{
responseJson = new Dictionary();
responseJson.Add("resp_code","99999999");
responseJson.Add("resp_desc", e.Message);
}
return responseJson;
}
///
/// 发送上传文件请求
///
///
/// 报文参数集合
/// 上传文件路径
/// 上传文件参数名
/// 接口功能编码
/// http请求方法
/// 商户配置信息
///
/// 返回报文
///
public static Dictionary requestBasePayForFileUpload(Dictionary postParams, string filePath, string fileParam, string funcCode, string method, MerConfig merConfig)
{
return requestBasePayWithFuncCode(postParams, filePath, fileParam, funcCode, method, merConfig);
}
///
/// 发送报文请求
///
///
/// 报文参数集合
/// 接口功能编码
/// http请求方法
/// 商户配置信息
///
/// 返回报文
///
public static Dictionary requestBasePay(Dictionary postParams, string funcCode, string method, MerConfig merConfig)
{
return requestBasePayWithFuncCode(postParams, null, null, funcCode, method, merConfig);
}
///
/// 跟据功能编码获取实际请求地址
///
///
/// 接口功能编码
///
/// 返回接口实际请求地址
///
private static String fetchRequestUrl(String funcCode) {
String baseUrl = BasePay.BASE_URL;
if (!BasePay.prodMode) {
baseUrl = BasePay.BASE_URL_MOCK;
}
if (!baseUrl.EndsWith("/")) {
baseUrl = baseUrl + "/";
}
String interfaceUrl = funcCode.Replace(".", "/");
String requestUrl = baseUrl + interfaceUrl;
return requestUrl;
}
//设置get请求参数
// get post 以及post 上传文件的接口,url地址以及签名方式有差别
private static HttpWebRequest CreateGetRequest(Dictionary postParams, string requireUrl, MerConfig merConfig)
{
string json_params = CoreUtils.getOrignalString(postParams);
string json_string = requireUrl + json_params;
//参数中会有中文,签名前需url encode
json_string = Uri.UnescapeDataString(json_string);
string signStr = RsaUtils.sign(merConfig.RsaPrivateKey, json_string);
requireUrl = requireUrl + "?" + json_params;
CoreUtils.Log("requireUrl:" + requireUrl);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requireUrl);
ServicePoint currentServicePoint = request.ServicePoint;
currentServicePoint.ConnectionLimit = 1000;
WebHeaderCollection header = request.Headers;
header.Set("sdk_version", "C#SDK_"+BasePay.sdk_version);
header.Set("format", "JSON");
header.Set("charset", "UTF-8");
header.Set("version", "1.0.0");
header.Set("product_id", merConfig.ProductId);
request.Method = "get";
request.ContentType = "text/html;charset=UTF-8";
return request;
}
//设置不带文件的post请求参数
private static HttpWebRequest CreatePostRequest(Dictionary postParams, string requireUrl, MerConfig merConfig)
{
string json_params = JsonConvert.SerializeObject(postParams, Formatting.None);
JObject jo = (JObject)JsonConvert.DeserializeObject(json_params);
Dictionary body = new Dictionary();
body.Add("sys_id", merConfig.SysId);
//body.Add("sign_type", "RSA2");
body.Add("data", jo);
body.Add("product_id",merConfig.ProductId);
String sortedData = JsonUtils.sort4JsonString(json_params);
string signStr = RsaUtils.sign(merConfig.RsaPrivateKey, sortedData);
body.Add("sign", signStr);
String jsonBody = JsonConvert.SerializeObject(body, Formatting.None);
CoreUtils.Log("request data:" + json_params);
CoreUtils.Log("request sign:" + signStr);
CoreUtils.Log("request body:" + jsonBody);
//参数中会有中文,签名前需url encode
// json_string = Uri.UnescapeDataString(json_string);
HttpWebRequest request = request = (HttpWebRequest)WebRequest.Create(requireUrl);
ServicePoint currentServicePoint = request.ServicePoint;
currentServicePoint.ConnectionLimit = 1000;
WebHeaderCollection header = request.Headers;
header.Set("sdk_version", "C#SDK_" + BasePay.sdk_version);
header.Set("format", "JSON");
header.Set("charset", "UTF-8");
header.Set("version", "1.0.0");
// header.Set("product_id", merConfig.ProductId);
request.Method = "post";
request.ContentType = "application/json";
byte[] byteData = Encoding.UTF8.GetBytes(jsonBody);
int length = byteData.Length;
request.ContentLength = length;
Stream writer = request.GetRequestStream();
writer.Write(byteData, 0, length);
writer.Close();
return request;
}
//设置文件上传request
private static HttpWebRequest CreateUploadRequest(Dictionary postParams, string filePath, string fileParam, string requireUrl, MerConfig merConfig)
{
HttpWebRequest request = request = (HttpWebRequest)WebRequest.Create(requireUrl);
ServicePoint currentServicePoint = request.ServicePoint;
currentServicePoint.ConnectionLimit = 1000;
string json_params = JsonConvert.SerializeObject(postParams, Formatting.None);
string signStr = RsaUtils.sign(merConfig.RsaPrivateKey, json_params);
Dictionary body = new Dictionary();
body.Add("sys_id", merConfig.SysId);
body.Add("sign_type", "RSA2");
body.Add("data", json_params);
body.Add("sign", signStr);
WebHeaderCollection header = request.Headers;
header.Set("sdk_version", "C#SDK_" + BasePay.sdk_version);
header.Set("format", "JSON");
header.Set("charset", "UTF-8");
header.Set("version", "1.0.0");
header.Set("product_id", merConfig.ProductId);
request.Method = "post";
//文件信息
byte[] UpdateFile = CoreUtils.File2Bytes(filePath);//转换为二进制
if (UpdateFile.Length == 0)
{
throw new Exception("file content cannot be null");
}
string Boundary = "--WebKitFormBoundary39B5a5e2FWoGbphs";
//构造POST请求体
StringBuilder PostContent = new StringBuilder("");
//组成普通参数信息
foreach (KeyValuePair item in body)
{
PostContent.Append("--" + Boundary + "\r\n")
.Append("Content-Disposition: form-data; name=\"" + item.Key + "\"" + "\r\n\r\n" + (string)item.Value + "\r\n");
}
byte[] PostContentByte = Encoding.UTF8.GetBytes(PostContent.ToString());
//文件信息
StringBuilder FileContent = new StringBuilder();
FileContent.Append("--" + Boundary + "\r\n")
.Append("Content-Disposition:form-data; name=\""+ fileParam + "\";filename=\""+ Path.GetFileName(filePath) +"\"" + "\r\n\r\n");
byte[] FileContentByte = Encoding.UTF8.GetBytes(FileContent.ToString());
request.ContentType = "multipart/form-data;boundary=" + Boundary;
byte[] ContentEnd = Encoding.UTF8.GetBytes("\r\n--" + Boundary + "--\r\n");//请求体末尾,后面会用到
//定义请求流
Stream myRequestStream = request.GetRequestStream();
myRequestStream.Write(PostContentByte, 0, PostContentByte.Length);//写入参数
myRequestStream.Write(FileContentByte, 0, FileContentByte.Length);//写入文件信息
myRequestStream.Write(UpdateFile, 0, UpdateFile.Length);//文件写入请求流中
myRequestStream.Write(ContentEnd, 0, ContentEnd.Length);//写入结尾
myRequestStream.Close();
return request;
}
}
}