http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 116778|回复: 30

[接口] 中国建设银行接口使用详细说明

[复制链接]
发表于 2012-9-12 19:28:16 | 显示全部楼层 |阅读模式
接口介绍
本文章只是技术交流,如有用于其它与我无关哦
      建行的接口相对于支付宝,Q业务充值和移动,联通,电信,缴费接口要复杂一些,接口分为两块,一块是商户到银行,另外一块是银行到商户
商户到银行
      交易流程如下:
网上支付业务流程步骤说明:

cbb1.jpg
1) 客户登录商户网站,选择商户网站商品。
2) 客户将选好的商品放入购物车,并下订单。商户提供商户代码、订单号、合计金额等信息;
3) 客户选择代理付款的银行-建行,确认后,商户代码、订单信息、合计金额通过浏览器URL传到建行网上银行站点;
网上银行自动显示支付页面,客户首先选择是否使用建行证书,然后输入龙卡号和密码,选择“确定”。支付信息经加密后传送到网银中心;
4) 网银中心接收客户支付信息,转发到银行后台业务处理系统;
5) 银行后台业务系统处理后,返回处理结果给网银;
6) 网银通知客户支付(扣帐)是否成功。如果扣帐成功,提示客户注意接收商户返回的送货信息;对于不需要立即响应的商户,
跳过步骤7、8;
7) 对于需要立即响应的商户,如果支付成功,网银将成功结果反馈给商户。若支付失败,不返回给商户信息
8) 对于需要立即响应的商户,收到银行扣帐成功的通知后,发给客户送货信息。如客户收到银行支付(扣帐)成功通知(步骤6),
但未收到商户送货信息,则需向商户查询。
日终时,商户与开设结算帐户的建设银行(网银成员行)进行流水核对,对已支付但未得到商户确认的交易进行退款处理。

商户到银行

    其实这一步是把自己卡里的钱转到商户的帐上,就是转账,
代码实现其实很简单,我们先来分析一上要传的参考吧

个人客户在商户网站选择商品后,商户网站生成以下信息,传送到建行网站:
域名
名称
类型
备注
MERCHANTID
商户代码
CHAR(9)
由建行统一分配
POSID
商户柜台代码
CHAR(9)
由建行统一分配,缺省为000000000
BRANCHID
分行代码
CHAR(9)
由建行统一指定
ORDERID
定单号
CHAR(30)
由商户提供,最长30,按实际长度给出
PAYMENT
付款金额
NUMBER(16,2)
由商户提供,按实际金额给出
CURCODE
币种
CHAR(2)
缺省为01-人民币
REMARK1
备注1
CHAR(30)
网银不处理,直接传到城综网
REMARK2
备注2
CHAR(30)
网银不处理,直接传到城综网
TXCODE
交易码
CHAR(6)
由建行统一分配为520100
MAC
MAC校验域
CHAR(32)
采用标准MD5算法,由商户实现
注:商户要保证定单号的唯一性
为了加快站点间接口开发,站点间接口的参数传送采用普通的URL方式,商户将以上信息包含在FORM中,在SUBMIT后将生成URL,如下所示:
&TXCODE=520100&REMARK1=&REMARK2=&MAC=qwertyuioplkjhgfdsazxcvbnm901234
参与MAC运算的字符及其顺序如下:
MERCHANTID=123456789&POSID=000000000&BRANCHID=110000000&ORDERID=19991101234&PAYMENT=500.00&CURCODE=01&
TXCODE=520100&REMARK1=&REMARK2=
注:字符串中变量名必须是大写字母。
           这是建行文档说的说明,很明显这是使用Http的方式来实现的
下面我们动手来实现 一下吧,
我是把所有的参数生成了一个实体类这样方便,而且规范化,
来看看这个Model吧
[C#] 纯文本查看 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClientSystem.AliPay
{
    /// <summary>
    /// 建行传入参数
    /// </summary>
    public class CBBTextModel
    {

        private string _MERCHANTID = "";
        /// <summary>
        /// 商户代码 由建行统一分配
        /// </summary>
        public string MERCHANTID
        {
            get { return _MERCHANTID; }
            set { _MERCHANTID = value; }
        }


        private string _POSID = "";
        /// <summary>
        /// 商户柜台代码  由建行统一分配,缺省为000000000
        /// </summary>
        public string POSID
        {
            get { return _POSID; }
            set { _POSID = value; }
        }


        private string _BRANCHID = "";
        /// <summary>
        /// 分行代码  由建行统一指定
        /// </summary>
        public string BRANCHID
        {
            get { return _BRANCHID; }
            set { _BRANCHID = value; }
        }


        private string _ORDERID = "";
        /// <summary>
        /// 定单号 由商户提供,最长30位,按实际长度给出
        /// </summary>
        public string ORDERID
        {
            get { return _ORDERID; }
            set { _ORDERID = value; }
        }


        private decimal _PAYMENT = 0m;
        /// <summary>
        /// 付款金额  由商户提供,按实际金额给出
        /// </summary>
        public decimal PAYMENT
        {
            get { return _PAYMENT; }
            set { _PAYMENT = value; }
        }


        private string _CURCODE = "";
        /// <summary>
        /// 币种 缺省为01-人民币
        /// </summary>
        public string CURCODE
        {
            get { return _CURCODE; }
            set { _CURCODE = value; }
        }


        private string REMARK1 = "";
        /// <summary>
        /// 备注1  网银不处理,直接传到城综网
        /// </summary>
        public string REMARK11
        {
            get { return REMARK1; }
            set { REMARK1 = value; }
        }


        private string REMARK2 = "";
        /// <summary>
        /// 备注2  网银不处理,直接传到城综网
        /// </summary>
        public string REMARK21
        {
            get { return REMARK2; }
            set { REMARK2 = value; }
        }


        private string _TXCODE = "";
        /// <summary>
        /// 交易码  由建行统一分配为520100
        /// </summary>
        public string TXCODE
        {
            get { return _TXCODE; }
            set { _TXCODE = value; }
        }


        private string _MAC = "";
        /// <summary>
        /// MAC校验域  采用标准MD5算法,由商户实现
        /// </summary>
        public string MAC
        {
            get { return _MAC; }
            set { _MAC = value; }
        }

        private string _url = "";
        /// <summary>
        /// URL
        /// </summary>
        public string Url
        {
            get { return _url; }
            set { _url = value; }
        }

    }
}

我们来准备两个方法吧,一个是Http连接来使用的一个是Md5加密,因为在文档里写到要使用Md5加密哦
[C#] 纯文本查看 复制代码
#region //预定义方法或是变量

        /// <summary>
        /// 请求指定 URL 资源,并获取响应结果
        /// </summary>
        /// <param name="url">需要请求的 URL 资源</param>
        /// <returns>
        /// 响应结果;
        /// 出现任意异常,均返回字串"Runtime Error"
        /// </returns>
        private string RequestContent(string url)
        {
            string content = string.Empty;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.KeepAlive = false;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                content = reader.ReadToEnd();
                reader.Close();
            }
            catch (Exception)
            {
                content = "Runtime Error";
            }
            return content;
        }

        /// <summary>
        /// 传入明文,返回用MD%加密后的字符串
        /// </summary>
        /// <param name="str">要加密的字符串</param>
        /// <returns>用MD5加密后的字符串</returns>
        public static string ToMD5(string str)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5");
        }
        #endregion

看一下充值按钮下面实现吧
[C#] 纯文本查看 复制代码
 if (textBox1.Text.Trim() == "" || textBox1.Text.Trim() == null)
            {
                MessageBoxForm objm = new MessageBoxForm("您输入的金额不能为空!!!", "提示信息");
                objm.ShowDialog();
                return;
            } 
            string orid = OfficeInfo.ofId.ToString().Trim() + "_" + DateTime.Now.Ticks.ToString();
            Alipay objalipay = new Alipay();
            objalipay.APID = orid;
            objalipay.addTime = DateTime.Now;
            objalipay.total_fee = Convert.ToDecimal(textBox1.Text.ToString().Trim());
            objalipay.trade_status = "客户端提交";
            objalipay.Text1 = DateTime.Now.ToString();
            objalipay.Text2 = "建行接口";
            objalipay.Text3 = "";
            objalipay.Text4 = "";
            objalipay.Text5 = "";

            decimal money = Convert.ToDecimal(user.GetListBy(OfficeInfo.ofPara1, 13).ToString().Trim());
            if (money > Convert.ToDecimal(textBox1.Text.Trim()))
            {
                MessageBoxForm objm = new MessageBoxForm("你输入的最小金额不能低于" + money + "元!!!", "提示信息");
                objm.ShowDialog();
                return;
            }

            if (user.AddAlipay(OfficeInfo.ofPara1, objalipay))
            {
                CBBTextModel objcbbText = new CBBTextModel();

                //商户代码 由建行统一分配
                objcbbText.MERCHANTID = "00000000000000";

                //商户柜台代码  由建行统一分配,缺省为000000000

                objcbbText.POSID = "00000000000000";

                //分行代码  由建行统一指定
                objcbbText.BRANCHID = "00000000000000";

                // 定单号 由商户提供,最长30位,按实际长度给出
                objcbbText.ORDERID = orid.Trim();

                //付款金额  由商户提供,按实际金额给出
                objcbbText.PAYMENT = Convert.ToDecimal(textBox1.Text.Trim());

                //币种 缺省为01-人民币
                objcbbText.CURCODE = "01";

                //备注1  网银不处理,直接传到城综网
                objcbbText.REMARK11 = "";

                //备注2  网银不处理,直接传到城综网
                objcbbText.REMARK21 = "";

                //交易码  由建行统一分配为520100
                objcbbText.TXCODE = "520100";

                //MAC校验域  采用标准MD5算法,由商户实现
                objcbbText.MAC = "qwertyuioplkjhgfdsazxcvbnm901234";

                //URL
                objcbbText.Url = "https://ibsbjstar.ccb.com.cn/app/ccbMain";

                //要加密的串
                string canshu = "MERCHANTID=" + objcbbText.MERCHANTID.Trim() +
                    "&POSID=" + objcbbText.POSID.Trim() + "&BRANCHID=" + objcbbText.BRANCHID.Trim()
                    + "&ORDERID=" + objcbbText.ORDERID.Trim() + "&PAYMENT=" + objcbbText.PAYMENT.ToString().Trim()
                    + "&CURCODE=" + objcbbText.CURCODE + "&TXCODE=" + objcbbText.TXCODE.Trim()
                    + "&REMARK1=&REMARK2=";

                objcbbText.MAC = ToMD5(canshu.Trim()).ToLower().Trim();
                string strURl = objcbbText.Url + "?" + canshu + "&MAC=" + objcbbText.MAC.Trim();
                webBrowser1.Url = new Uri(strURl.Trim());
            }
        }

在这里大家一定要注意把 objcbbText.MAC = ToMD5(canshu.Trim()).ToLower().Trim();
加密后的字符串改成小写的

上面所提到的
[C#] 纯文本查看 复制代码
string orid = OfficeInfo.ofId.ToString().Trim() + "_" + DateTime.Now.Ticks.ToString();
            Alipay objalipay = new Alipay();
            objalipay.APID = orid;
            objalipay.addTime = DateTime.Now;
            objalipay.total_fee = Convert.ToDecimal(textBox1.Text.ToString().Trim());
            objalipay.trade_status = "客户端提交";
            objalipay.Text1 = DateTime.Now.ToString();
            objalipay.Text2 = "建行接口";
            objalipay.Text3 = "";
            objalipay.Text4 = "";
            objalipay.Text5 = "";

            decimal money = Convert.ToDecimal(user.GetListBy(OfficeInfo.ofPara1, 13).ToString().Trim());
            if (money > Convert.ToDecimal(textBox1.Text.Trim()))
            {
                MessageBoxForm objm = new MessageBoxForm("你输入的最小金额不能低于" + money + "元!!!", "提示信息");
                objm.ShowDialog();
                return;
            }

这一部分代码是记录日志的,大家可以参考一下
我们现在只要运行程序就会出现如下界面所显示的内容
QQ截图20120912192451.png
下面的操作就是输入你的卡号密码就可以了,
转账成功后我们这一步的工作就算是做完了

银行到商户

接下来的这一步 是很关键的一步,是当我们转账成功后,银行发给我们系统的一个处理结束,里面的参数如下
建行网站生成以下信息,传送到商户网站:
域名
名称
类型
备注
POSID
商户柜台代码
CHAR(9)
从商户传送的信息中获得
BRANCHID
分行代码
CHAR(9)
从商户传送的信息中获得
ORDERID
定单号
CHAR(30)
从商户传送的信息中获得
PAYMENT
付款金额
NUMBER(16,2)
从商户传送的信息中获得
CURCODE
币种
CHAR(2)
从商户传送的信息中获得
REMARK1
备注一
CHAR(30)
从商户传送的信息中获得
REMARK2
备注二
CHAR(30)
从商户传送的信息中获得
SUCCESS
成功标志
CHAR(1)
成功时返回Y
SIGN
数字签名
CHAR(256)

站点间接口的参数传送仍然采用普通的URL方式,信息包含在CGI参数,具体如下所示:
HTTP://MERCHANT.WEB.SITE/MERCHANT_CGI?POSID=000000000&BRANCHID=110000000&ORDERID=19991101234&PAYMENT=500.00&CURCODE=01&REMARK119991101&REMARK2=merchantname&SUCCESS=Y&SIGN=4b3ef029516193b7d969ac1840083635a3e0901b8cd526caa44c1a07
2f496d7f0d4bca3942c0d9030bede37c7809b835cec787eb39e18b7596a724fba9805b24714dfbb0f4a3fb430b32e075254a114d4c38a0ac
52ef46a0ad33dec3fbfc15417402a1399e65e46996c0cf49fc7ffca9222f8cd693c8376b6f928828967bec42
注:?前的URL由商户在签约时提供
参与签名运算的字符及其顺序如下
POSID=000000000&BRANCHID=110000000&ORDERID=19991101234&PAYMENT=500.00&CURCODE=01&REMARK119991101&REMARK2=merchantname&SUCCESS=Y
注:字符串中变量名必须是大写字母。
如果商户的程序将MERCHANTID, POSID,BRANCHID, ORDERID, PAYMENT, CURCODETXCODEMAC作为隐藏域(hidden)
然后使用SUBMIT按纽,注意在 FORMMETHOD中使用“GET”的方式。
         在这里我们首先要新建一个Asp.net的网站,只要在一个网页下面书写代码就成了。
第一步我们要写出来要加密 的串
[C#] 纯文本查看 复制代码
string canshu = "POSID=000000000&BRANCHID=0000000&ORDERID=" + Request.QueryString["ORDERID"].Trim() + "&PAYMENT=" +
                   Request.QueryString["PAYMENT"].Trim() + "&CURCODE=" + Request.QueryString["CURCODE"].Trim() + "&REMARK1=" + Request.QueryString["REMARK1"].Trim()
                   + "&REMARK2=" + Request.QueryString["REMARK2"].Trim() + "&ACC_TYPE=" + Request.QueryString["ACC_TYPE"].Trim()
                   + "&SUCCESS=" + Request.QueryString["SUCCESS"].Trim();


这是在我们接收数据时要用到的,
这里建行提供了一个加密验证为
银行将客户支付信息实时通知给商户时,使用的数字签名算法是MD5withRSA算法。商户验证签名的公钥在商户在网银系统开户,获取数字证书后,登录到网银系统中,通过下载公钥交易获取。
商户获取的公钥用X.509格式表示,并且将其按照每4位(bit)转换为一个16进制数的方式表示,产生16进制的字符串。
网上银行使用标准MD5withRSA算法对给商户的响应进行签名,产生1024位(bit)的签名结果,并且将其按照每4位(bit
转换为一个16进制数的方式表示,形成16进制的字符串,长度为256
下面是对签名结果的表示方式的描述:
1、1024位的交易结果按4位为一个单位进行划分,共获得256
2、将每段看成一个16进制数,如00110X311010Xd
3、将这个数映射到ASCII码表,形成相应的字符,如0X2为“2”,0Xd为“d”。
4、将这些字符连成一个字符串,长度为256
例如:
待签名的字符串为:
POSID=000000000&BRANCHID=110000000&ORDERID=19991101234&PAYMENT=500.00&CURCODE=01&REMARK119991101&REMARK2=merchantname&SUCCESS=Y
签名结果为:
4b3ef029516193b7d969ac1840083635a3e0901b8cd526caa44c1a072f496d7f0d4bca3942c0d9030bede37c7809b835cec787eb39e18b7596a72
4fba9805b24714dfbb0f4a3fb430b32e075254a114d4c38a0ac52ef46a0ad33dec3fbfc15417402a1399e65e46996c0cf49fc7ffca9
222f8cd693c8376b6f928828967bec42
当商户收到银行传来的CGI串后,从中获取签名(格式如上)和需签名的原文。商户端程序
(商户自行开发MD5withRSA签名校验程序)将签名和商户端的公钥转换成二进制格式,与签名的原文一起对签名的正确性进行校验,校验步骤如下:
1)      使用公钥进行签名的逆运算
2)      使用标准MD5算法运算原文
比较1)2)结果。           

下面我们要做的工作就是如何验证这个串是否一致了,先说一下MD5withRSA签名程序吧,这是加密算法是由MD5加密和RSA加密算法组合而来的
具体的说明请大家在网上找找吧,很容易找到这里就不再多说了
我们来看看主要是怎么验证的吧
银行发过来的签名是通过RSA加密后的签名,在签名是会生成一个公钥,这个公钥我们可以从这里下载的到
用我们的账户登录建行的商户平台,如下地方可以下载的到
cbb3.jpg
另外在登录这个系统时要验证客户端的证书,证书的下载可以在建行的主而上直接找到,根据自己的客户号和密码可以下载,具体的大家还得根据建行服务
人员的提示操作的好
    有了这个我们还要一个CCBRSA.dll文件,这个是建行用来验证加密串的具体的使用方法看下面的程序,怎么样添加Dll的引用我就不多说了,大家自己找找
[C#] 纯文本查看 复制代码
//传过来的签名;
                string sign = Request.QueryString["SIGN"];
                //本地Key值
                string mysign = ConfigurationManager.AppSettings["PublicKey"].ToString().Trim();
                CCBRSA.RSASig rsa;
                //注册一下regsvr32  CCBRSA.dll 文件
                rsa = new CCBRSA.RSASigClass();
                bool bRet;
                rsa.setPublicKey(mysign);
                bRet = rsa.verifySigature(sign, canshu);


bRet是一个Boolean值可以直接用它来做IF的判断。
在这里我多说几句如果我们直接这样运行的话可能会报错如下
Retrieving the COM class factory for component with CLSID {A5C5C388-A972-4CCF-93E2-7F97E82C9EBA} failed due to the following error: 80040154.

     由于用到了CCBRSA.dll这个动态链接库文件,所以要先注册一下这个文件,建议把这个文件复制到system32目录下然后开始运行输入 regsvr32  
CCBRSA.dll  确定就可以了.
    另外还要安装一下msjavx86.exe ,java虚拟机。可能是有部分需要调用到java的一些库吧,所以需要安装这个。我把Dll文件和这个文件提供下载
如下  打包下载
msjavx86_3802.rar (5.03 MB, 下载次数: 131)

本帖被以下淘专辑推荐:



1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2012-11-20 00:51:28 | 显示全部楼层
请教商户后台转账的接口,不是像这样需要经过到建行登录,然后转账这样的流程
 楼主| 发表于 2012-11-20 09:49:36 | 显示全部楼层
人间大猫 发表于 2012-11-20 00:51
请教商户后台转账的接口,不是像这样需要经过到建行登录,然后转账这样的流程

后台转账?你说的是那个接口。不太理解
发表于 2012-12-7 11:15:20 | 显示全部楼层
admin 发表于 2012-11-20 09:49
后台转账?你说的是那个接口。不太理解

为什么要获得建行的ip地址呢
 楼主| 发表于 2012-12-7 11:54:36 | 显示全部楼层
1003487863 发表于 2012-12-7 11:15
为什么要获得建行的ip地址呢

这个不是必须的,目的是为了防止其它方式访问这个页面,绑定建行IP之后只有建行IP访问才生效,这样比较安全一些,也会减少不必要的麻烦
发表于 2012-12-7 13:11:30 | 显示全部楼层
比对MD5加密算法是什么意思
发表于 2012-12-7 13:13:44 | 显示全部楼层
获得建行ip地址是什么意思,为啥要获得呢
发表于 2012-12-7 13:14:59 | 显示全部楼层
1003487863qq能联系我吗
 楼主| 发表于 2012-12-7 13:23:50 | 显示全部楼层
1003487863 发表于 2012-12-7 13:11
比对MD5加密算法是什么意思

这个不是必须的,目的是为了防止其它方式访问这个页面,绑定建行IP之后只有建行IP访问才生效,这样比较安全一些,也会减少不必要的麻烦

你看楼上有说

MD5,当然要验证啦,要不然怎么能确定数据是真的还是假的,用户充值10块,银行给你返回100你肯定不愿意吧,所以要比对
发表于 2012-12-7 18:53:00 | 显示全部楼层
怎么比对建行返回的数据和哪个进行比对
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-3-28 21:31

© 2014-2021

快速回复 返回顶部 返回列表