iT邦幫忙

2021 iThome 鐵人賽

DAY 19
0
永豐金融APIs

30天全端挑戰!React+Spring Boot+Mongo DB 串接永豐API 打造金融網站系列 第 19

[Day 19] - 初探永豐銀行線上收款API - 訂單查詢及其他(1)

  • 分享至 

  • xImage
  •  

繼續昨天的內容,在建立訂單後,如果是信用卡訂單,api會回給一個付款頁面,
https://ithelp.ithome.com.tw/upload/images/20211004/20128973PXXaSKh8ir.png
在這個頁面用測試資料付款完成後,頁面會跳轉到當初打api時,我所設定的ReturnUrl,
https://ithelp.ithome.com.tw/upload/images/20211004/20128973JyJlidPikO.png
在測試時我塞google.com,
付完款果然轉到google了,並且不是只是單純轉址,是以Post的方式附帶了PayToken
https://ithelp.ithome.com.tw/upload/images/20211004/20128973sloVfKvJbL.png

這個PayToken可以拿來發到api的另一個功能OrderPayQuery,查詢單筆訂單的詳細狀態。
也就是說,一個完整的信用卡訂單流程會是
下訂→跳轉永豐交易頁面→跳轉回自己的ReturnUrl,
這個returnUrl頁面要處理PayToken,藉此查詢客戶的該筆訂單,再show給客戶看

那麼就來實作OrderPayQuery的串接吧

一樣照著規格書寫出req跟res的Data Object:

import lombok.Data;

@Data
public class OrderPayQueryReq {
    private String ShopNo;
    private String PayToken;
}
import lombok.Data;

@Data
public class OrderPayQueryRes {

    public enum Status { S, F };
    public enum APType { PayOut, CaptureOut, RegularOut, RegularEnd };
    public enum PayType { A, C };

    @Data
    public class TSResultContent{
        private APType APType;
        private String TSNo;
        private String OrderNo;
        private String ShopNo;
        private PayType PayType;
        private Integer Amount;
        private Status Status;
        private String Description;
        private String Param1;
        private String Param2;
        private String Param3;
        private String LeftCCNo;
        private String RightCCNo;
        private String CCExpDate;
        private String CCToken;
        private String PayDate;
        private String MasterOrderNo;
    }

    private String ShopNo;
    private String PayToken;
    private String Date;
    private String Status;
    private String Description;
    private TSResultContent TSResultContent;

}

照著之前的orderCreate方法複製貼上稍微改一下,又是一條好漢
騙誰啊/images/emoticon/emoticon20.gif
目前都是以能跑為目的在寫code,說實在寫得很爛/images/emoticon/emoticon02.gif
這個call api的方法應該還有更好的寫法,之後再調整

public String orderPayQuery(OrderPayQueryReq orderPayQueryReq)throws IOException{
    //1.nonce
    String nonce=getNonce();
    //2.hashID
    String hashID=getHashID();
    //3.iv
    String iv = getIV(nonce);
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(new QpayPropNamingStrategy());
    Map<String, Object> map = 
    mapper.convertValue(orderPayQueryReq, new TypeReference<TreeMap<String, Object>>() {});
    //remove null
    map.values().removeIf(Objects::isNull);
    map.forEach((k, v) -> {
        if(v.getClass().equals(java.util.LinkedHashMap.class)){
            LinkedHashMap<Object,Object>m =(LinkedHashMap<Object, Object>) v;
            m.values().removeIf(Objects::isNull);
            map.replace(k, v, m);
        }
    });

    //4.message
    String jsonContent ="";
    jsonContent = new ObjectMapper().writeValueAsString(map);

    String message = "";
        try {
            message= encryptUtil.encrypt(jsonContent, hashID, iv);
        } catch (IOException | GeneralSecurityException e) {
            e.printStackTrace();
        }

    //5.sign
    String sign = getSign(map,nonce,hashID);

    //send to api
    Map<String,String> request = new HashMap<String,String>();
    request.put("Version", "1.0.0");
    request.put("ShopNo", "NA0001_001");
    request.put("APIService", "OrderPayQuery");
    request.put("Sign", sign);        
    request.put("Nonce", nonce);
    request.put("Message", message);

    String reqJson="";
    reqJson = new ObjectMapper().writeValueAsString(request);

    String res="";
    try {
        res=util.post("https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Order", reqJson);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Map<String, String> resMap =new HashMap<String,String>();
    resMap = mapper.readValue(res, new TypeReference<HashMap<String, String>>() {});

    String resSign =resMap.get("Sign");
    String resNonce =resMap.get("Nonce");
    String resMessage =resMap.get("Message");

    String resiv= getIV(resNonce);

    try {
        resMessage=encryptUtil.decrypt(resMessage, hashID, resiv);
    } catch (IOException | GeneralSecurityException | DecoderException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Map<String, Object> resMessageMap =new TreeMap<String,Object>();
    resMessageMap = mapper.readValue(resMessage, new TypeReference<TreeMap<String, Object>>() {});

    resMessageMap.forEach((k, v) ->System.out.println(k+":"+v));

    String resForUser = "";
    String signCheck = getSign(resMessageMap, resNonce, hashID);

    if(signCheck.equals(resSign)){
        System.out.println("Sign Check OK:"+signCheck);
    }else{
        resForUser="永豐回傳簽章驗證失敗"+"\nA:"+signCheck+"\nresSign:"+resSign;
        return resForUser;
    }

    if(resMessageMap.containsKey("Description")){
        resForUser=resMessageMap.get("Description").toString();
    }else{
        resForUser="待續";
    }

    return resForUser;

}   


上一篇
[Day 18] - 初探永豐銀行線上收款API - 豐收款 - 建立訂單!
下一篇
[Day 20] - 初探永豐銀行線上收款API - 訂單查詢及其他(2)
系列文
30天全端挑戰!React+Spring Boot+Mongo DB 串接永豐API 打造金融網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言