Feng’ Blog

Odoo(Python2)-调用中国农业银行银企直联
关于通讯方式CMEICC与CMEICS、CMEM与CMEICS之间的交易数据包都采用TCP/IP协议的Socket...
扫描右侧二维码阅读全文
20
2018/12

Odoo(Python2)-调用中国农业银行银企直联

1231321d.png

关于通讯方式

CMEICC与CMEICS、CMEM与CMEICS之间的交易数据包都采用TCP/IP协议的Socket同步短连接方式。
CMEICS与CMF之间通过CICS中间件方式通讯。
CMEICC与CMEICS:Socket方式报文结构为:包头+数据包,报头为1个字节的是否为加密包标志,加上6个字节的字符表示数据包的长度,如果长度不足6位则右边用空格补足,比如:“1234 ”。比如汇兑的长度为1234字节的数据包,其包头为“11234 ”共7位;查询单账户余额的长度为1000字节的数据包,其包头为“01000 ”共7位。其中数据包长度包含加密包标志位。
关于XML约定
XML(包括XML数据包和XML文件)都不包含头部的XML声明(即<?xml version="1.0"?>);
除非有特别的说明,否则所有XML的根元素的标记名都为<ap>;
接口中字段名即对应了元素的标记名(包含了相对于根的路径名);
在XML数据包中所有元素的数据都不采用属性,而一律用字符数据的文本块来表示。

请求报文公共字段

<ap>

<CCTransCode>内部交易代码</CCTransCode>

<ProductID>ICC</ProductID>

<ChannelType>ERP</ChannelType>

<CorpNo>企业技监局号码/客户号</CorpNo>

<OpNo>企业操作员编号</OpNo>

<AuthNo>认证码</AuthNo>

<ReqSeqNo>请求方流水号</ReqSeqNo>

<ReqDate>请求日期</ReqDate>

<ReqTime>请求时间</ReqTime>

<Sign>数字签名</Sign>

</ap>

组装示例XML


1. def search_abc_bal(cls):
2. ​    """查询农业银行账户余额xml"""
3. ​    # 企业技监局号码/客户号
4. ​    abc_client_number = request.env['ir.values'].get_default('interface.bank.settings', 'abc_client_number')
5. ​    # 企业操作员编号
6. ​    abc_operator_number = request.env['ir.values'].get_default('interface.bank.settings', 'abc_operator_number')
7. ​    # 认证码
8. ​    abc_auth_no = request.env['ir.values'].get_default('interface.bank.settings', 'abc_auth_no')
9. ​    # 数字签名
10. ​    abc_sign = request.env['ir.values'].get_default('interface.bank.settings', 'abc_sign')
11. ​    str_xml = {
12. ​        'CCTransCode': 'CQRA06',
13. ​        'ProductID': 'ICC',
14. ​        'ChannelType': 'ERP',
15. ​        'CorpNo': abc_client_number,
16. ​        'OpNo': abc_operator_number,
17. ​        'AuthNo': abc_auth_no,
18. ​        'Sign': abc_sign,
19. ​        'Cmp': {
20. ​            'DbAccNo': '1234567890',
21. ​            'DbProv': '01',
22. ​            'DbCur': '01',
23. ​        }
24. ​    }
25. ​    str_xml = cls.dict_to_xml('ap', str_xml)
26. ​    return tostring(str_xml)

将组装的dict转换为xml


1. @classmethod
2. ​    def dict_to_xml(cls, tag, dic):
3. ​        """将传递的dict转换为xml(不包含声明信息)
4. ​        :param tag: 转换节点名称
5. ​        :param dic: 需要转换的dict字典
6. ​        :return :Element Object 需要使用tostring方法获取字符串
7. ​        """
8. ​        elem = Element(tag)
9. ​        for key, val in dic.items():
10. ​            if isinstance(val, dict):
11. ​                elem.append(cls.dict_to_xml(key, val))
12. ​            else:
13. ​                child = Element(key)
14. ​                child.text = str(val)
15. ​                elem.append(child)
16. ​        return elem

安装要求组装数据


1. @classmethod
2. def pack_xml_top(cls, sign, xml_str):
3. ​    """
4. ​    请求数据:sign加密标识(1加密,0不加密) + 请求xml数据的长度(默认7位,不够补空格) + 请求的xml
5. ​    :param sign: sign加密标识(1加密,0不加密)
6. ​    :param xml_str: 需要生成的xml
7. ​    :return: 请求的xml
8. ​    """
9. ​    xml_len = str(sign) + str(len(xml_str))
10. ​    i = 0
11. ​    while i < 7 - (len(xml_len)):
12. ​        xml_len = xml_len + ' '
13. ​    str_xml = '{}{}'.format(xml_len, xml_str)
14. ​    return str_xml

发送报文到农行前置机


1. @classmethod
2. def send_tcp(cls, ip, port, xml_str):
3. ​    """
4. ​    使用tcp发送请求报文
5. ​    :param ip:IP地址
6. ​    :param port: 端口
7. ​    :param xml_str: xml报文
8. ​    """
9. ​    xml_str = cls.pack_xml_top(0, xml_str)
10. ​    logging.info(xml_str)
11. ​    address = (ip, int(port))
12. ​    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
13. ​    try:
14. ​        client.connect(address)
15. ​    except socket.error:
16. ​        raise UserError(u"尝试连接到农业银行前置机发生错误!无法连接!")
17. ​    by = xml_str.encode(encoding='gbk')  # 转为字节数组
18. ​    client.send(by)
19. ​    print u"tcp发送成功"
20. ​    data = client.recv(1024)  # 接受响应信息
21. ​    data = data.decode('gbk')
22. ​    print u"接受响应成功"
23. ​    logging.info(data)
24. ​    client.close()

调用并发送报文


 str_xml = cls.search_abc_bal()
 send_tcp(‘123.123.123.123’, ‘1234’, str_xml)

三方包


from xml.etree.ElementTree import Element
from xml.etree.ElementTree import tostring
import socket
import logging
Last modification:January 9th, 2019 at 01:53 pm
If you think my article is useful to you, please feel free to appreciate

Leave a Comment