银联分账c#demo-商户资金自主管理系统报文接口
using HRB.ECommerce.AppService.BLL;
using HRB.ECommerce.DAL.Sales;
using HRB.ECommerce.DAL.Merchants;
using HRB.ECommerce.Framework;
using HRB.ECommerce.Pay;
using HRB.ECommerce.Utils;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Web;
using System.Reflection;
using System.Net.Http;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace zyzy.team
{
class PayAllocation
{
const string preURL = "https://mobl-test.chinaums.com/channel/Business/UnifyMulti/";
const string SYS_VAR_RAW_DATA = "rawData";
//const string ALGORITHM_SHA256WITHRSA = "SHA256withRSA";
static string ALGORITHM_SHA256WITHRSA = ConfigurationManager.AppSettings["SHA256WITHRSA"];
const String TRANSFORMATION_RSA = "RSA";
static string verNo = "100";
static string channelId = "043";
static string groupId = ConfigurationManager.AppSettings["GroupId"];
static string merNo= ConfigurationManager.AppSettings["MerNo"];
private static SafeUtil su = new SafeUtil();
const string privateKey = "pem\\rsa_private_dev.pfx";
const string publicKey = "pem\\rsa_public_dev.cer";
/**
* 获取Json格式报文加签;发送;并对返回值进行处理后验签
*
* @param superDto
* @return
*/
public static bool PostPayAllocation(SuperDto superDto)
{
superDto.setTransCode("202004");
superDto.setMerNo(merNo);
superDto.setPayType("0");
Dictionary<String, String> srcMap = sign(superDto);
String result = JsonSerializer.Serialize<Dictionary<String, String>>(srcMap);
Console.WriteLine(result);
try
{
string url = preURL + superDto.getTransCode();
string data = result.Substring(0, result.Length);
string resposeStr = Post(url, data, Encoding.UTF8);
Console.WriteLine(resposeStr);
if (null == resposeStr)
{
FileLog.WriteLog("数据返回超时");
}
SuperDto returnDto = new SuperDto();
returnDto = JsonSerializer.Deserialize<SuperDto>(resposeStr);
Boolean flag = validate(returnDto);
if (!flag)
{
FileLog.WriteLog("返回报文验签失败:"+resposeStr);
}
return flag;
}
catch (Exception e)
{
FileLog.WriteLog("分账异常:" + e.Message);
throw e;
}
}
public static bool validate(SuperDto superDto)
{
Console.WriteLine("========开始验签===========");
Console.WriteLine("result:" + superDto);
try
{
String signature = superDto.getSignature();
Console.WriteLine("========生成rawData===========");
String rawDataStr = getReturnRawData(superDto);
Console.WriteLine("========生成验签结果===========");
Boolean flag = false;
try
{
flag = su.VerifySign(rawDataStr, signature, getRsaFileFullPath(publicKey), "utf-8");
}
catch (Exception e)
{
flag = su.VerifySign(Sha256(superDto.getCardNo()), signature, TRANSFORMATION_RSA, "utf-8");
}
return flag;
}
catch (Exception e)
{
return false;
}
}
/**
* 获取签名裸数据
*
* @param superDto
*/
public static String getReturnRawData(SuperDto superDto)
{
Dictionary<String, String> srcMap = beanToMap(superDto);
List<String> sortKeys = srcMap.Keys.ToList<String>();
sortKeys.Sort();
StringBuilder sb = new StringBuilder();
foreach (String key in sortKeys)
{
string value;
srcMap.TryGetValue(key, out value);
if (key.Equals("signature") || isEmpty(value))
{
continue;
}
sb.Append(key);
sb.Append("=");
sb.Append(value);
sb.Append("&");
}
String rawData = sb.ToString();
return rawData.Substring(0, rawData.Length - 1);
}
/**
* 将对象转换成map
*
* @param bean
* @return
*/
public static Dictionary<String, String> beanToMap<T>(T bean)
{
if (bean == null)
throw new ArgumentNullException(nameof(bean));
var dictionary = new Dictionary<string, String>();
foreach (var property in bean.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
if (property.CanRead && property.GetValue(bean, null) != null)
{
dictionary[property.Name] = property.GetValue(bean, null).ToString();
}
}
return dictionary;
}
/**
* 签名
*
* @param superDto
*/
public static Dictionary<String, String> sign(SuperDto superDto)
{
Dictionary<String, String> srcMap = getRawData(superDto);
String rawData;
srcMap.TryGetValue(SYS_VAR_RAW_DATA, out rawData);
srcMap.Remove(SYS_VAR_RAW_DATA);
try
{
string strSignedData = su.Sign(rawData, getRsaFileFullPath(privateKey), ALGORITHM_SHA256WITHRSA, "utf-8");
srcMap.Add("signature", strSignedData);
Console.WriteLine(strSignedData);
return srcMap;
}
catch (Exception e)
{
throw e;
}
}
private static string getRsaFileFullPath(string relativeBinPath)
{
string path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
return Path.Combine(path, relativeBinPath);
}
/**
* 获取报文签名裸数据
*
* @param superDto
*/
public static Dictionary<String, String> getRawData(SuperDto superDto)
{
Dictionary<String, String> srcMap = getSrcMap(superDto);
List<String> sortKeys = srcMap.Keys.ToList<String>();
sortKeys.Sort();
StringBuilder sb = new StringBuilder();
foreach (String key in sortKeys)
{
sb.Append(key);
sb.Append("=");
string value = "";
srcMap.TryGetValue(key, out value);
sb.Append(value);
sb.Append("&");
}
String rawData = sb.ToString();
Console.WriteLine(rawData.Substring(0, rawData.Length - 1));
srcMap.Add(SYS_VAR_RAW_DATA, rawData.Substring(0, rawData.Length - 1));
return srcMap;
}
/**
* 获取map类型报文
*
* @param superDto
* @return
*/
public static Dictionary<String, String> getSrcMap(SuperDto superDto)
{
String dateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
Dictionary<String, String> srcMap = new Dictionary<string, string>();
/*----------------------报文头start------------------------*/
if (String.IsNullOrEmpty(superDto.getTransCode()))
{
Console.WriteLine("未定义交易码");
}
srcMap.Add("transCode", superDto.getTransCode());
srcMap.Add("verNo", verNo);
srcMap.Add("channelId", channelId);
srcMap.Add("groupId", groupId);
//请求系统日期
srcMap.Add("srcReqDate", dateTime.Substring(0, 8));
//请求系统时间
srcMap.Add("srcReqTime", dateTime.Substring(8));
//请求系统流水号,须唯一,该处取时间戳以表示不重复序列,生产环境不建议使用
srcMap.Add("srcReqId", superDto.getSrcReqId());
/*----------------------报文头end--------------------------*/
/*----------------------报文体start------------------------*/
if (!"202014".Equals(superDto.getTransCode()) && !"202015".Equals(superDto.getTransCode()))
{
if (isEmpty(superDto.getMerNo()))
{
FileLog.WriteError("未定义企业用户号");
}
srcMap.Add("merNo", superDto.getMerNo());
}
try
{
switch (Int32.Parse(superDto.getTransCode()))
{
case 202004:
if (isEmpty(superDto.getPayAmt()) || isEmpty(superDto.getPayType()) || isEmpty(superDto.getCardNo()) ||
isEmpty(superDto.getPs()))
{
Console.WriteLine("未定义划付金额或者分账类型或者卡号或者附言");
break;
}
srcMap.Add("payAmt", superDto.getPayAmt());
srcMap.Add("cardNo", Sha256(superDto.getCardNo()));
srcMap.Add("payType", superDto.getPayType());
srcMap.Add("ps", superDto.getPs());
break;
case 202006:
break;
case 202011://商户余额查询
if (isEmpty(superDto.getAcctType()))
{
Console.WriteLine("未定义账户类型");
break;
}
srcMap.Add("merNo", superDto.getMerNo());
srcMap.Add("acctType", superDto.getAcctType());
break;
default:
break;
}
}
catch (Exception e)
{
throw e;
}
/*----------------------报文体end-------------------------*/
return srcMap;
}
public static Boolean isEmpty(String str)
{
if (String.IsNullOrEmpty(str) || String.IsNullOrWhiteSpace(str))
{
return true;
}
return false;
}
private static string Post(string url, string pars,Encoding encode)
{
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
req.AllowAutoRedirect = false;
req.ContentType = "application/json; charset=utf-8";
req.Timeout = 60000;
req.ReadWriteTimeout = 20000;
byte[] data = encode.GetBytes(pars);
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(data, 0, data.Length);
reqStream.Close();
}
HttpWebResponse resp;
try
{
resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
}
catch (WebException ex)
{
resp = (HttpWebResponse)ex.Response;
}
using (StreamReader reader = new StreamReader(resp.GetResponseStream(), encode))
{
result = reader.ReadToEnd();
}
return result;
}
private static string Sha256(string strData)
{
byte[] bytValue = Encoding.UTF8.GetBytes(strData);
SHA256 sha256 = new SHA256CryptoServiceProvider();
byte[] retVal = sha256.ComputeHash(bytValue);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
}
}

浙公网安备 33010602011771号