标签:
一、系统A(官网)与系统B(第三方支付平台)数据交换的方式
1.1 页面浏览器方式:系统A以构造Form表单的方式,通过系统A客户的浏览器重定向到系统B(向系统B发送请求),B系统完成交易后,将交易结果送给A系统。eg:A系统用户完成注册后在B系统开户
1.2 后台数据流方式:后台数据流方式分为表单和Json格式返回两种数据格式,开户和交易接口都是使用表单,查询类接口使用JSON;A系统服务器,构造Http协议报文,直接访问B系统,将Http报文发送到B系统,并获取返回的满足Http报文协议的字符流。在数据流的方式下,A系统以表单的方式将数据发送到B系统,B系统收到后进行相应的处理。
现已第三方提供的Pos机自动代扣的接口为例,分别讲解前台和回台数据交换:
二、页面浏览器方式
2.1 以Form表单的形式提交
A、 transfer.aspx页面,body内容如下,其中注意body标签的onload事件,form的Action在后台指定;transfer只是中转页面,以供在系统中其他页面只需抛数据到transfer页面,而不关注与第三方的交互,与第三方交互主要由transfer页面完成
<body onload="sub();">
<form id="formMain" runat="server">
<input type="hidden" name="Version" value="<%=Version%>" />
<input type="hidden" name="CmdId" value="<%=CmdId%>" />
<input type="hidden" name="MerCustId" value="<%=MerCustId%>" />
<input type="hidden" name="UsrCustId" value="<%=UsrCustId%>" />
<input type="hidden" name="OpenAcctId" value="<%=OpenAcctId%>" />
<input type="hidden" name="TransAmt" value="<%=TransAmt%>" />
<input type="hidden" name="OrdId" value="<%=OrdId%>" />
<input type="hidden" name="OrdDate" value="<%=OrdDate%>" />
<input type="hidden" name="CheckDate" value="<%=CheckDate%>" />
<input type="hidden" name="RetUrl" value="<%=RetUrl%>" />
<input type="hidden" name="BgRetUrl" value="<%=BgRetUrl%>" />
<input type="hidden" name="MerPriv" value="<%=MerPriv%>" />
<input type="hidden" name="ChkValue" value="<%=ChkValue%>" />
</form>
<script type="text/javascript">
function sub() {
document.getElementById("formMain").submit();
}
</script>
</body>
B、 transfer.aspx.cs内容如下:
public partial class Interface_POSWithoutCard_Transfer
{
public readonly string PnrUrl = ChinaPnrInterfaces.GetConfigValue("pnrurl");
public readonly string Version = ChinaPnrInterfaces.GetConfigValue("pnrversion");
public readonly string CmdId = "PosWhSave"; //函数名称
public string MerCustId = string.Empty; //商户ID
public string UsrCustId = string.Empty; //用户ID(PNRID)
public string OpenAcctId = string.Empty; //开户银行账号
public string TransAmt = string.Empty; //交易金额
public string OrdId = string.Empty; //订单号
public string OrdDate = string.Empty; //订单日期
public string CheckDate = string.Empty; //校验日期
public string RetUrl = string.Empty; //页面返回
public string BgRetUrl = string.Empty; //商户后台应答地址
public string MerPriv = string.Empty; //商户私有域
public string ChkValue = string.Empty;protected void Page_Load(object sender, EventArgs e)
{
MerCustId = CurMerCustId;
UsrCustId = DESEncrypt.Decrypt(Request["UsrCustId"]);
OpenAcctId = DESEncrypt.Decrypt(Request["OpenAcctId"]);
TransAmt = DESEncrypt.Decrypt(Request["TransAmt"]);
CheckDate = DESEncrypt.Decrypt(Request["CheckDate"]);OrdId = bll.GetNextOrdId();
OrdDate = DateTime.Now.ToString("yyyyMMdd");//CurWebUrl
RetUrl = string.Format("{0}/Interface/POSWithoutCard_Return.aspx?action=frontend&ordid={1}&transamt={2}", CurWebUrl, DESEncrypt.Encrypt(OrdId), DESEncrypt.Encrypt(TransAmt));//第三方支付平台根据此字段获取前后回应地址,注意,由第三方处理完后回传的这部分数据其他内容需要通过Request.Form["Name"]获取,但对于地址后面的action,ordid和transamt需要使用get方式获取; 公路养护车,双排座自卸车,散装饲料运输车厂家价格(http://www.glyhche.com/)
BgRetUrl = string.Format("{0}/Interface/POSWithoutCard_Return.aspx?action=backend&ordid={1}&transamt={2}", CurWebUrl, DESEncrypt.Encrypt(OrdId), DESEncrypt.Encrypt(TransAmt));//后台预防返回地址
formMain.Action = PnrUrl;//地址为第三方提供的接收页面if (bll.CreateLog(new dw_poswksave_log_model()
{
OrdId = OrdId,
PnrId = UsrCustId,
BankId = OpenAcctId,
TransAmt = float.Parse(TransAmt),
OrdDate = OrdDate,
CheckDate = CheckDate
}))
{
ChkValue = ChinaPnrInterfaces.SignChkValue(Version + CmdId + MerCustId + UsrCustId
+ OpenAcctId + TransAmt + OrdId + OrdDate + CheckDate + RetUrl + BgRetUrl + MerPriv);
}Response.ContentEncoding = Encoding.GetEncoding("gb2312");
}protected string DateToString(string strDate)
{
DateTime date;
if (!DateTime.TryParse(strDate, out date))
date = DateTime.Now;return date.ToString("yyyyMMdd");
}protected string MoneyToString(string strMoney)
{
if (string.IsNullOrEmpty(strMoney))
strMoney = "0";return float.Parse(strMoney).ToString("F2");
}
}C、Return.aspx 页面用于接收第三方支付平台回传的结果
<body>
<% if (ShowUserTip) { %>
<div class="err">
<div class="info">
<div>
响应信息
</div>
<div>
<div>代码:<%=RespHFCode%></div>
<div>描述:<%=RespHFDesc%></div>
</div>
<div><%=RespHFCode.Equals(HFOK) ? "" : "请重新提交!"%></div>
</div>
<div class="bot">
<input type="button" value="关闭此窗口" onclick="window.close();" />
</div>
</div>
<% } %>
</body>
D、Return.aspx.cs文件如下:
public readonly string HFOK = "000";
public string RespHFString = string.Empty;
public string RespHFCode = string.Empty;
public string RespHFDesc = string.Empty;
public string OrdId = string.Empty;
public string TransAmt = string.Empty;
public bool ShowUserTip = false;protected void Page_Load(object sender, EventArgs e)
{
string action = Request["action"];//对应transfer传递参数时放在地址后的参数
if (!string.IsNullOrEmpty(action))
{
RespHFString = "RECV_ORD_ID_" + Request.Form["TrxId"];//在页面显示
RespHFCode = Request.Form["RespCode"];
RespHFDesc = Request.Form["RespDesc"];
OrdId = DESEncrypt.Decrypt(Request["ordid"]);
TransAmt = DESEncrypt.Decrypt(Request["transamt"]);switch (action)
{
case "frontend":
ShowUserTip = true;//前台回复,将结果显示在页面上
UpdatePosLog();
break;
case "backend"://后台响应直接存储就可以了,但需要判断前台是否已经处理,否则会造成数据重复处理
string checkValue = Request.Form["CmdId"].Trim()
+ Request.Form["RespCode"].Trim()
+ Request.Form["MerCustId"].Trim()
+ Request.Form["UsrCustId"].Trim()
+ Request.Form["OpenAcctId"].Trim()
+ Request.Form["TransAmt"].Trim()
+ Request.Form["OrdId"].Trim()
+ Request.Form["OrdDate"].Trim()
+ Request.Form["CheckDate"].Trim()
+ Request.Form["TrxId"].Trim()
+ Request.Form["RetUrl"].Trim()
+ Request.Form["BgRetUrl"].Trim()
+ Request.Form["MerPriv"].Trim();if (ChinaPnrInterfaces.DecChkValue(checkValue, Request.Form["ChkValue"]).Equals("0"))
{
UpdatePosLog();
}
break;
}
}
}
三、后台数据流方式
3.1、使用HttpWebRequest对象,Post数据:
string TransferUrl = string.Empty;
string postData = string.Empty;
string userPnrID = dr["pnrid"].ToString();
string bankID = dr["BankId"].ToString();
string checkDate = dr["CheckDate"].ToString();
string repayment_account = Decimal.Round(Convert.ToDecimal(TransNullOrEmpty(dr["repayment_account"].ToString())), 2).ToString();
TransferUrl = string.Format("{0}/Interface/POSWithoutCard_Transfer.aspx", strWebSiteUrl);//需要请求的页面
postData = string.Format("UsrCustId={0}&OpenAcctId={1}&TransAmt={2}&CheckDate={3}",
DESEncrypt.Encrypt(userPnrID), DESEncrypt.Encrypt(bankID), DESEncrypt.Encrypt(repayment_account), DESEncrypt.Encrypt(checkDate));//传递的参数
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(TransferUrl);//后台请求页面
string s = postData;
Encoding encoding = Encoding.GetEncoding("GB2312");//GB2312,注意页面的编码,否则会出现乱码
byte[] requestBytes = encoding.GetBytes(postData);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = requestBytes.Length;
Stream requestStream = req.GetRequestStream();
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.GetEncoding("GB2312"));
string backstr = sr.ReadToEnd();//可以读取到从页面返回的结果,以数据流的形式。
// Response.Write(backstr);
sr.Close();
res.Close();
3.2、使用WebClient对象:
string postData = string.Format("UsrCustId={0}&OpenAcctId={1}&TransAmt={2}&CheckDate={3}",
DESEncrypt.Encrypt(userPnrID), DESEncrypt.Encrypt(bankID), DESEncrypt.Encrypt(repayment_account), DESEncrypt.Encrypt(checkDate));//这里即为传递的参数,可以用工具抓包分析,也可以自己分析,主要是form里面每一个name都要加进来byte[] postData = Encoding.UTF8.GetBytes(postString);//编码,尤其是汉字,事先要看下抓取网页的编码方式
string TransferUrl= string.Format("{0}/Interface/POSWithoutCard_Transfer.aspx", strWebSiteUrl);//需要请求的页面
WebClient webClient = new WebClient();
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");//采取POST方式必须加的header,如果改为GET方式的话就去掉这句话即可
byte[] responseData = webClient.UploadData(TransferUrlurl, "POST", postData);//得到返回字符流
string srcString = Encoding.UTF8.GetString(responseData);//解码
3.3、WebBrowser对象(没用过,暂时不讨论,具体可参考http://www.cnblogs.com/peterzb/archive/2009/07/12/1521787.html)
转自:http://blog.itpub.net/28699126/viewspace-1127499/
标签:
原文地址:http://www.cnblogs.com/bingle/p/4494809.html