SAP 银企直连 付款报文签名与长度限制处理

前言

银企直连经常会遇到需要对报文签名,加密验证,比如齐商银行,工商银行等。
齐商银行签名字符串很长,而SAP DMEE 中付款报文字段最大长度只有 1500字符,这要怎么处理?
其实只要在发送报文之前对签名字段进行替换即可。


一、付款报文签名字段超长报错

DMEE 付款报文格式树:ZEPIC_CN_QSB_PAYMENT。

树检查日志 - 树标识/版本:ZEPIC_CN_QSB_PAYMENT/001
所有分类字段 (39) 的总长度过长
节点 SignedData 的长度不能超过 1500 个字符。请更改长度

二、详细处理步骤

1.接口文档与示例代码

签名格式:

<?xml version="1.0" encoding="GBK"?>
<msg>
  <msg_head>
    <msg_type>0</msg_type>
    <msg_id>1005</msg_id>
    <msg_sn>0</msg_sn>
    <version>1</version>
  </msg_head>
  <msg_body>
    <origin_data>签名原文</origin_data>
  </msg_body>
</msg>

签名返回结果: 

<?xml version="1.0" encoding="GBK"?>
<msg>
  <msg_head>
    <msg_type>1</msg_type>
    <msg_id>1005</msg_id>
    <msg_sn>0</msg_sn>
    <version>1</version>
  </msg_head>
  <msg_body>
    <signed_data>MIIFKwYJKoZIhvcNIFHDCCBRgCAQExCzAJBgUrDgMCGgUAMBsGCSqGSIb3DQEHAaAOBAznrb7lkI3ljp/mloegggPcMIID2DCCAsCgAwIBAgIFEDkUdEYwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMCQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMjAwNTI3MDMxODMyWhcNMjUwNTI3MDMyNDIxWjCBjzELMAkGA1UEBhMCY24xFTATBgNVBAoTDENGQ0EgVEVTVCBDQTEPMA0GA1UECxMGcXNiYW5rMRkwFwYDVQQLExBPcmdhbml6YXRpb25hbC0xMT0wOwYDVQQDFDRXWUxNQDc4MDFVQVQxMDAwMDAwMDAzMjBAMTAwMDAwMDAwMzIwMTAwMzgwQDAwMDAwMDAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHc4cq1IlNP22Z5oVjlhA/18OdZN4zhh3jsc5rjp5LxHLGlUAU29kyL6Sle79Phg1KKsu5DZkgAFBV2rOVrx2Jsy5bFOiO1ieIAqd6P5s5jUayLIqTGGjFHl3L/5Jat82lVPO0cmm4eBIMAre/HuuMIPsIjKrfQPcQl4vGK3zlCQIDAQABo4H0MIHxMB8GA1UdIwQYMBaAFM9wnWHrnXwuuPfLAkD3CZ3+M3SAMEgGA1UdIARBMD8wPQYIYIEchu8qAQEwMTAvBggrBgEFBQcCARYjaHR0cDovL3d3dy5jZmNhLmNvbS5jbi91cy91cy0xNC5odG0wOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL3VjcmwuY2ZjYS5jb20uY24vUlNBL2NybDc0Njc2LmNybDALBgNVHQ8EBAMCA+gwHQYDVR0OBBYEFAS/vcE8HYt98qQzHCxnuZHwNIzkMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDANBgkqhkiG9w0BAQUFAAOCAQEAraoUmKSWK3diOzrh63ymjEtnTx/29l4dRwBr3v66D7wyp0kw3nk3pDKjkZ3UFwWtpy7gWoG2+hjSubQczFOCY7Zm640rBNOcGxMMvPV4kr34uql7YFeuYvp1XkFbBPS4ohfvVBpmQfWxdg2cIHLWcaKqO2OwL2N3Alpl+amjL4g2k58XE5W2pAG2cPyqBgP0ZEkDifbBDZ8F02GWDWUmDt+jiLtPC0kmQDN7uWsl3DwwWGbAunSB39zrAScdiUi+jE76ht6nkJbPIsn33TGh40uI16jXwMchpLG9vV1dBDvmWlb1ThdP2tfZESkQ3fzd5zbA+MbVx7/CjZdNUJTSZjGCAQcwggEDAgEBMGEwWDELMAkGA1UEBhMCQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTECBRA5FHRGMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYCB/eV+X8mfI3K0Yx9Xtyda8yDRNM1tbjVeE4eARhwH4yZv2zthyTzVbCSbF1bAzAlmhliHVuUQYfcdp44OFl6N1Ncazo6UHQjJDaWAvbdI6vrG3giuYLV9ISWgmk9KfbDAI9O6QRxsrn7uCEpJ1jHEQ==</signed_data>
  </msg_body>
</msg>

签名的JAVA源代码:

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;

public class Test1 {

	private static String charset = "GBK";

	public static void main(String[] args) throws Exception {
		getSignData("123");
		sendSSL("123");
	}

	public static void getSignData(String data) throws Exception {

		String re = "<?xml version=1.0 encoding=\"GBK\"?>"
				+ "<msg><msg_head><msg_type>0</msg_type><msg_id>1005</msg_id>"
				+ "<msg_sn>0</msg_sn><version>1</version></msg_head>" + "<msg_body>" + "<origin_data>" + data
				+ "</origin_data></msg_body></msg>";

		Socket socket = new Socket("36.30.41.178", 8010);
		InputStream is = socket.getInputStream();
		InputStreamReader isr = new InputStreamReader(is, charset);
		OutputStream dos = socket.getOutputStream();
		dos.write(re.getBytes(charset));
		dos.flush();
		BufferedReader br = new BufferedReader(isr);
		String returnInfo = br.readLine();
		System.out.println(returnInfo);
	}

	public static void sendSSL(String data) throws Exception {

		StringBuffer sb = new StringBuffer();
		String url = "http://36.30.41.178:7010/yqbank/APIReqServlet";
		HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
		connection.setRequestMethod("POST");
		connection.setDoInput(true);
		connection.setDoOutput(true);
		BufferedOutputStream o = new BufferedOutputStream(connection.getOutputStream());
		o.write(data.getBytes(charset));
		o.flush();
		BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), charset));
		String line = null;
		while ((line = br.readLine()) != null) {
			sb.append(line + "\n");
		}
		System.out.println(sb.toString());
	}

}

签名的SAP ABAP源代码:

    REPLACE FIRST OCCURRENCE OF '<?xml version="1.0" encoding="UTF-8"?>' IN ls_other_parameters-payment_file WITH ''.
    REPLACE FIRST OCCURRENCE OF '<SignedData/>' IN ls_other_parameters-payment_file WITH '<SignedData>' && lv_signeddata && '</SignedData>'.
    CONCATENATE lv_prestr '<?xml version="1.0" encoding="GBK"?>' ls_other_parameters-payment_file INTO ls_other_parameters-payment_file.

    IF ls_other_parameters-payment_file IS INITIAL.
      MESSAGE i102(epic_example_cn_impl) INTO lv_message_dummy.
      me->append_message( CHANGING ct_messages = et_messages ).
      RETURN.

    ELSEIF ls_other_parameters-item_keys IS INITIAL.
      MESSAGE i101(epic_example_cn_impl) INTO lv_message_dummy.
      me->append_message( CHANGING ct_messages = et_messages  ).
      RETURN.

    ELSE.
      TRY .

付款示例报文格式:

<?xml version="1.0" encoding="GBK"?>
<BankData>
  <Sign>
    <SignedData/>
    <PubKey/>
  </Sign>
  <opReq>
    <opname>otherAccPay</opname>
    <cstNo>1000</cstNo>
    <userNo>100</userNo>
    <serialNo>2021</serialNo>
    <userId>Z</userId>
    <reqTime>20210226155300</reqTime>
    <ReqParam>
      <payAccount>801106</payAccount>
      <payAccountName>XX有限公司</payAccountName>
      <recAccount>15XXXX9</recAccount>
      <recAccountName>XX有限公司</recAccountName>
      <payAmount>100.66</payAmount>
      <currencyType>01</currencyType>
      <recAccountOpenBank>10XXXXX</recAccountOpenBank>
      <recAccountOpenBankName>XXXX分行</recAccountOpenBankName>
      <remRoute>7</remRoute>
      <orderFlowNo>2021022XXXXXXX</orderFlowNo>
      <payUse/>
      <trsDateTime>20210226155300</trsDateTime>
    </ReqParam>
  </opReq>
</BankData>
<?xml version="1.0" encoding="GBK"?>
<BankData>
  <Sign>
    <SignedData></SignedData>
    <!--签名数据域,opReq中所有数据内容的签名数据-->
    <PubKey></PubKey>
  </Sign>
  <opReq>
    <!--交易请求数据-->
    <opname>*********</opname>
    <!--交易名称-->
    <cstNo>*********</cstNo>
    <!--客户号-->
    <userNo>*********</userNo>
    <!--网银中合法的企业操作员号-->
    <serialNo>*********</serialNo>
    <!--交易序列号(客户端交易唯一标识)-->
    <userId>*********</userId>
    <!--客户Id标识-->
    <reqTime>*********</reqTime>
    <!--客户端请求时间(yyyymmddhhmmss)-->
    <ReqParam>
      <Param1>******</Param1>
      <Param2>******</Param2>
      <Param3>******</Param3>
    </ReqParam>
  </opReq>
</BankData>
Tag名称描述数据长度是否必输备注
payAccount付款账号32Y
payAccountName付款账户名64Y
recAccount收款账号32Y
recAccountName收款方户名64Y
payAmount付款金额16Y
remRoute汇划途径1Y5:大额 7:小额
currencyType币种2Y人民币01
recAccountOpenBank收款方开户行12Y收款方行号
recAccountOpenBankName收款方开户行名60Y收款方行名
orderFlowNo指令流水号23Y交易序号与 serialNo相同
payUse付款用途200N
trsDateTime交易时间14Y

2.实现效果

数据载体概况:

  

报文处理:

检查银行通信日志:

付款文件 1000/20210226/00011/001 的状态为 传输成功
付款项目 1000/2020/0100002348/002 的状态为 银行已处理
1 个项目的状态更新成功


总结

遇到接口报错,签名报错等问题时如何处理?

  • 仔细查看接口文档,注意报文字段,节点大小写敏感。
  • 查看前置机接口日志。
  • 字符编码一定要正确,常用的有:GBK,UTF-8。
  • 熟练使用接口测试工具,常用的有:SoapUIPostman,Socket 工具等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SAP爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值