前言
银企直连经常会遇到需要对报文签名,加密验证,比如齐商银行,工商银行等。
齐商银行签名字符串很长,而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 | 付款账号 | 32 | Y | |
payAccountName | 付款账户名 | 64 | Y | |
recAccount | 收款账号 | 32 | Y | |
recAccountName | 收款方户名 | 64 | Y | |
payAmount | 付款金额 | 16 | Y | |
remRoute | 汇划途径 | 1 | Y | 5:大额 7:小额 |
currencyType | 币种 | 2 | Y | 人民币01 |
recAccountOpenBank | 收款方开户行 | 12 | Y | 收款方行号 |
recAccountOpenBankName | 收款方开户行名 | 60 | Y | 收款方行名 |
orderFlowNo | 指令流水号 | 23 | Y | 交易序号与 serialNo相同 |
payUse | 付款用途 | 200 | N | |
trsDateTime | 交易时间 | 14 | Y |
2.实现效果
数据载体概况:
报文处理:
检查银行通信日志:
付款文件 1000/20210226/00011/001 的状态为 传输成功
付款项目 1000/2020/0100002348/002 的状态为 银行已处理
1 个项目的状态更新成功
总结
遇到接口报错,签名报错等问题时如何处理?