招商銀行銀企直聯開發點滴記錄

來源:互聯網
上載者:User
1. 概述 最近工作中用到了招商銀行的銀企直聯絡統,作為資金支出渠道。招行系統提供兩種方式與企業財務系統對接:一種是前置機式;一種是嵌入式。而“嵌入式直聯方式僅作向下相容支援,新增客戶請使用前置機式直聯”。因此使用了前置機方式。 使用到的介面文檔為《招商銀行銀企直串連口說明書version 5.21.0》和《網銀互聯結口說明書Version 1.0》。針對前者,使用了其3.6節“直接支付”介面進行招行內支付,並使用3.3節“查詢支付結果”介面進行結果查詢;針對後者,使用其第2章節“網銀貸記”介面進行跨行支付,並使用1.2節的“交易查詢”介面進行支付結果查詢。 前置機的安裝參照了文檔《銀企直聯安裝流程(測試環境專用)》及《招商銀行直聯絡統開發指南version 3.9.0》,文中講解得十分詳細,並且提供了範例程式碼。 開發使用語言為JAVA。 2.開發中遇到的問題及解決

  存在許多問題,在使用測試環境帳號、參數時無法發現,直到上了生產環境才出現。在此將遇到的一個個問題彙集如下,以期對後來開發人員提供借鑒。 2.1 測試

關於調用查詢介面,查詢支付結果,使用的時間段的問題:

(1).測試時使用本地的前置機,且一直使用招行商務人員提供的測試帳號,發現支付時能夠即時返回請求被受理的結果,卻查詢不到支付記錄。經過詢問銀行技術人員,得知銀行測試伺服器時間不是目前時間,需要用一個工具軟體查詢測試伺服器日期。使用此日期後查詢到了支付結果。

(2).查詢交易記錄時需要注意,”起始日期和結束日期的間隔不能超過100天”。並且查詢時間段應該至少包含支付日期的前一天及後一天,因為在0點附近的交易可能會處於前一天,也可能屬於後一天。

  另外,使用前置機,不需要報文格式轉換外掛程式,因為採用demo中所示的程式,我們使用的已經是格式三的報文了。 2.2 程式

  使用HTTP方式向前置機發送請求,在處理支付及查詢的返回報文時,對樣本程式作出少許修改,對多條結果處理的方式如下(以直接支付為例):

    /**     * 處理返回的報文     * @param result 前置機返回的報文     */    private List<NTQPAYRQZ> processResult(String result) {        List<NTQPAYRQZ>  ntqpayrqzs = null;        if (result != null && result.length() > 0) {            XmlPacket pktRsp = XmlPacket.valueOf(result);            if (pktRsp != null) {                String sRetCod = pktRsp.getRETCOD();                if (sRetCod.equals("0")) {                        /*start 批量支付封裝返回的報文開始*/                        Vector<Map> vector = pktRsp.getProperty("NTQPAYRQZ");                        ntqpayrqzs = new ArrayList<NTQPAYRQZ>();                        if(vector!=null){                            for (Map map : vector) {                                NTQPAYRQZ  ntqpayrqz = new NTQPAYRQZ();                                ntqpayrqz=(NTQPAYRQZ) DataUtil.transMap2Bean(map,ntqpayrqz);                                ntqpayrqzs.add(ntqpayrqz);                            }                        }                        /*end 批量支付封裝返回的報文結束*/                       /* 此處應為對多比交易返回結果的處理 */                    //下面為單筆時的處理                    int sectionSize = pktRsp.getSectionSize("NTQPAYRQZ");                    Map propPayResult = pktRsp.getProperty("NTQPAYRQZ", 0);//由於本人在項目中是單筆支付的,所以最多會返回一條記錄,故此處取0。                    String sREQSTS = (String) propPayResult.get("REQSTS");                    String sRTNFLG = (String) propPayResult.get("RTNFLG");                    if (sREQSTS.equals("FIN") && sRTNFLG.equals("F")) {                        logger.info("支付失敗:"                                + propPayResult.get("ERRTXT"));                    } else {                        logger.info("支付已被銀行受理(支付狀態:" + sREQSTS + ")");                    }                } else if (sRetCod.equals("-9")) {                    logger.info("支付未知異常,請查詢支付結果確認支付狀態,錯誤資訊:"                            + pktRsp.getERRMSG());                } else {                    logger.info("支付失敗:" + pktRsp.getERRMSG());                }            } else {                logger.info("響應報文解析失敗");            }        }        return ntqpayrqzs;    }    備忘:NTQPAYRQZ 為以返回報文的節點構造的類,以節點NTQPAYRQZ下的各個欄位作為類的屬性。

其中,用到的工具方法如下:

    /**     * 取得指定介面的資料記錄     * @param sSectionName     * @param index 索引,從0開始     * @return Map<String,String>     */    public Map getProperty(String sSectionName, int index){        if(data.containsKey(sSectionName)){            return (Map)((Vector)data.get(sSectionName)).get(index);        }else{            return null;        }    }      /**     * 取得指定介面的所有資料記錄     * @param sSectionName     * @return Map<String,String>     */    public Vector getProperty(String sSectionName){        if(data.containsKey(sSectionName)){            return (Vector)data.get(sSectionName);        }else{            return null;        }    }    // Map --> Bean 1: 利用Introspector,PropertyDescriptor實現 Map --> Bean      public static Object transMap2Bean(Map<String, Object> map, Object obj) {          try {              BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());              PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();              for (PropertyDescriptor property : propertyDescriptors) {                  String key = property.getName();                  if (map.containsKey(key)) {                      Object value = map.get(key);                      // 得到property對應的setter方法                      Method setter = property.getWriteMethod();                      setter.invoke(obj, value);                  }              }          } catch (Exception e) {              logger.error("transMap2Bean Error:",e);          }          return obj;      }  
2.3 生產

(1).生產環境應用伺服器串連不上前置機伺服器

  營運人員對於串連前置機的伺服器IP進行了限制;另外,還需要財務人員遠程登入前置機伺服器,開啟前置機;
  
(2).返回錯誤資訊:有審批業務,不可直接經辦

  編寫程式時忽略了介面文檔中的BUSMOD欄位值,採用了文檔中的樣本BUSMOD= 00001。對比參照之前生產環境前置機的報文,發現支付成功的報文中此欄位值為00002,修改程式後成功。此欄位表示“支付結算業務所採用的業務審批模式”。
  而報文中的另外一個值:“業務類型”欄位BUSCOD,指的是“支付、集團支付或內部轉帳等”,如BUSCOD=N02031。這兩個欄位容易混淆,需特別注意,並且它們的長度也不一樣。
  
(3).行內支付使用直接支付介面,返回錯誤資訊:收方必須為商戶賬戶

  諮詢招行技術人員得知是因為我們公司在招行的賬戶受到限制,收款方必須加入白名單才能打款。詢問財務人員,確實如此,經加入白名單後,打款成功。

  跨行未受到限制,估計是因為走的是央行的超級網銀渠道,所以沒有限制。
  
(4).跨行支付收款方行號的問題

  跨行支付時需要輸入收款行行號(網銀貸記介面中的CDTBRD欄位),只能輸入總行的行號,輸入支行的行號報錯。諮詢招行技術人員,回複是系統中沒有支行的行號。與招行對接時商務人員會提供“人行網銀互聯(跨行清算系統)聯行號資訊.txt”,其中有各銀行及對應的聯行號。
   2.4 關於並發請求的問題

  在文檔《招商銀行直聯絡統開發指南version 3.9.0》的3.4及3.5節,有調用頻率及並發效能的說明。
  摘錄如下:
  

3.4調用頻率     請求調用間隔:本次請求調用與上次請求調用之間的時間差;     調用頻率控制按介面種類區別控制: 經辦類請求:兩次經辦類請求最小調用間隔為1秒; 查詢類請求:兩次查詢類請求最小調用間隔為2秒; 通知類請求:兩次通知類請求最小調用間隔為5秒。    當調用頻率沒有滿足以上條件時(實際調用間隔小於最小調用間隔),系統預設會內部等待,等待時間為:最小調用間隔 — 實際調用間隔,等待完成後再處理該請求。    當調用頻率滿足以上條件時(實際調用間隔大於或等於最小調用間隔),系統立即處理該請求並轉寄到銀行後台系統。    調用頻率控制以登陸使用者為單位,不同登陸使用者之間不受影響。
3.5 並發效能    本系統支援多使用者並發請求,同一使用者的多個請求按照優先隊列排隊處理,為了避免請求等待時間過長,建議同一使用者並發請求不要超過50個,登陸使用者數沒有限制。備忘:一台電腦只能安裝一個招行前置機,多台電腦允許安裝多個招行前置機。

  開發、測試、上線此通道,前後經曆約一個月,與銀行商務及技術人員保持了電話及QQ溝通。感謝銀行技術人員耐心的講解及熱情的協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.