iT邦幫忙

2021 iThome 鐵人賽

DAY 17
0
永豐金融APIs

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

[Day 17] - 初探永豐銀行線上收款API - 豐收款 - Sign值計算(2)

  • 分享至 

  • xImage
  •  

來實作Sign值的計算

我的想法是把要發送到api的request寫成一個Object,像這樣

import lombok.Data;

@Data
public class OrderCreateReq {

    public enum PayType { A, C };
    public enum AutoBilling { Y, N };
    
    @Data
    public class ATMParam{
        private Integer ExpireDate;
    }
    @Data
    public class CardParam{
        private AutoBilling AutoBilling;
        private Integer ExpBillingDays;
        private Integer ExpMinutes;
        private String PayTypeSub;
    }
    
    private String ShopNo;
    private String OrderNo;
    private Integer Amount;
    private String CurrencyID;
    private String PrdtName;
    private String Memo;
    private String Param1;
    private String Param2;
    private String Param3;
    private String ReturnURL;
    private String BackendURL;
    private PayType PayType;
    private ATMParam ATMParam;
    private CardParam CardParam;

}

回到QpayHelper,建一個getSign方法,
到時候我會先用ObjectMapper將OrderCreateReq轉為TreeMap,
因此這邊先訂定接收的是Map物件

因為ObjectMapper會將含有sub object的object轉為LinkedHashMap,
我們可以透過指定移除value的class為LinkedHashMap的物件
以此來把多節點參數給拿掉

再來因為轉為TreeMap時,透過TreeMap自動排序的特性,已經把map中的key由小到大排列了,不用再多做處理

因此getSign方法只需要:
1.將map轉為key1=vale1&key2=value2...這樣格式的字串
2.將字串接上nonce、Hash ID
3.最後,只要再用DigestUtils轉為sha256、轉大寫就完成sign了。

    private String getSign(Map<String, Object> map,String nonce,String hashid){
        //remove sub object
        map.values().removeIf(entries->entries.getClass().equals(java.util.LinkedHashMap.class)
        ||entries.toString().isBlank());
        //order
        String param=map.entrySet().stream()
          .map(p -> p.getKey() + "=" + p.getValue())
          .reduce((p1, p2) -> p1 + "&" + p2)
          .orElse("");

        //convert to string
        StringBuilder content = new StringBuilder();

        content.append(param).
                append(nonce).
                append(hashid);
        String sign= DigestUtils.sha256Hex(content.toString()).toUpperCase(); 
        return sign;
    }

現在Sign也有了,剩下message
https://ithelp.ithome.com.tw/upload/images/20211002/201289739YsspIn8xe.png
依規格書所述,要以AES CBC進行加密,因此先寫加密方法
我找了網路上一個簡單的AES CBC加密的範例來改寫,其他解密之類的之後有需要再補

建一個EncryptUtil.java,傳入欲加密的內容、key、iv,回傳加密後的Hex字串

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.springframework.stereotype.Component;

@Component
public class EncryptUtil {
    public String encrypt(String content, String key,String iv) throws Exception {

        byte[] raw = key.getBytes("UTF-8");
        SecretKeySpec keySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes("UTF-8"));
        cipher.init(Cipher.ENCRYPT_MODE,keySpec,ips);
        byte[] encrypted = cipher.doFinal(content.getBytes());

        return Hex.encodeHexString(encrypted);

    }
}

東西都準備得差不多,
接下來就可以開始串前面的寫的東西了/images/emoticon/emoticon29.gif


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

尚未有邦友留言

立即登入留言