繼續昨天的內容,在建立訂單後,如果是信用卡訂單,api會回給一個付款頁面,
在這個頁面用測試資料付款完成後,頁面會跳轉到當初打api時,我所設定的ReturnUrl,
在測試時我塞google.com,
付完款果然轉到google了,並且不是只是單純轉址,是以Post的方式附帶了PayToken
這個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方法複製貼上稍微改一下,又是一條好漢
騙誰啊
目前都是以能跑為目的在寫code,說實在寫得很爛
這個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;
}