eformsign API Service
Create a Service Class
EformSignService.java
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import reactor.core.publisher.Mono;
@Service
public class EformSignService {
private static String apiKey = "your api key";
private static String privateKeyHex = "your private key";
private static String publickKeyHex = "your public key";
private WebClient webClient = WebClient.create();
Provide your API key, private key, and public key.
Verify eformsign Signature
/**
* verifySignature - verify Webhook signature using data and PublicKey
*
* @input response header(signature) and body(data)
* @input publickKey
* @return true/false
*/
public static boolean verifySignature(String resSignature, String resData) {
Signature signature;
boolean valid = false;
try {
KeyFactory publicKeyFact = KeyFactory.getInstance("EC");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(new BigInteger(publickKeyHex,16).toByteArray());
PublicKey publicKey = publicKeyFact.generatePublic(x509KeySpec);
signature = Signature.getInstance("SHA256withECDSA");
signature.initVerify(publicKey);
signature.update(resData.getBytes("UTF-8"));
if(signature.verify(new BigInteger(resSignature,16).toByteArray())) {valid = true;}
else {valid = false;}
} catch (Exception e) {
e.printStackTrace();
}
return valid;
}
Get Access Token
// Access Token Structure for your understanding. Do not add to the project.
{
"api_key": {
"name": "Tutorial",
"alias": "Tutorial",
"company": {
"company_id": "2b99ef0cac464344b1983d44ec4af427",
"name": "eformsign Bootcamp",
"api_url": "https://sg-api.eformsign.com"
}
},
"oauth_token": {
"expires_in": 3600,
"token_type": "JWT",
"refresh_token": "8a43b797-xxxx-xxxx-xxxx-3ea8f4b872e0",
"access_token": "eyJh...WijgnU" // 4Kbytes
}
}
/**
* getEformsignSignature - generate eformsign signature using privateKey
*
* @input privateKey
* @return execution_time, eformsign_signature
*/
private static String[] getEformsignSignature() throws Exception {
KeyFactory keyFact = KeyFactory.getInstance("EC");
PKCS8EncodedKeySpec psks8KeySpec = new PKCS8EncodedKeySpec(new BigInteger(privateKeyHex,16).toByteArray());
PrivateKey privateKey = keyFact.generatePrivate(psks8KeySpec);
String execution_time = String.valueOf(new Date().getTime());
Signature ecdsa = Signature.getInstance("SHA256withECDSA");
ecdsa.initSign(privateKey);
ecdsa.update(execution_time.getBytes("UTF-8"));
String eformsign_signature = new BigInteger(ecdsa.sign()).toString(16);
String[] res = new String[2];
res[0]= execution_time;
res[1]= eformsign_signature;
return res;
}
/**
* getAccessToken
*
* @method POST
* @path /api_auth/refresh_token
* @header Bearer API Key
* @header eformsign_signature
* @body memberId "john.kim@forcs.com"
* @body execution_time
* @return access token in JSON
* accessToken expires in 3600 seconds
*/
public Mono<JsonNode> getAccessToken(String memberId) throws Exception {
String base64ApiKey = Base64.getEncoder().encodeToString(apiKey.getBytes("UTF-8"));
String[] signature = getEformsignSignature();
String execution_time = signature[0];
String eformsign_signature = signature[1];
Map<String, Object> reqBody = new HashMap<>();
reqBody.put("execution_time", execution_time);
reqBody.put("member_id", memberId);
return webClient.post()
.uri("https://api.eformsign.com", uriBuilder -> uriBuilder
.path("/v2.0/api_auth/access_token")
.build())
.header("Authorization", "Bearer " + base64ApiKey)
.header("eformsign_signature", eformsign_signature)
.bodyValue(reqBody)
.retrieve()
.onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
.flatMap(error -> Mono.error(new RuntimeException(error))))
.bodyToMono(JsonNode.class);
}
Get Refresh Token
/**
* getRefreshToken - call when the token expired (3600 seconds have passed)
*
* @method POST
* @path /v2.0/api_auth/refresh_token
* @header access_token
* @param refresh_token
* @return new access_token
*/
public Mono<JsonNode> getRefreshToken(JsonNode token) {
return webClient.post()
.uri(token.get("apiUrl").asText(), uriBuilder -> uriBuilder
.path("/v2.0/api_auth/refresh_token")
.queryParam("refresh_token", token.get("refreshToken").asText())
.build())
.header("Authorization", "Bearer " + token.get("accessToken").asText())
.retrieve()
.onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
.flatMap(error -> Mono.error(new RuntimeException(error))))
.bodyToMono(JsonNode.class);
}
Download Documents
/**
* Download Document File
*
* @method GET
* @path /v2.0/api/documents/{document_id}/download_files
* @header access_token
* @param fileType file type : "document" | "audit_trail" | "document,audit_trail"
* @return files in byte stream
*/
public Mono<byte[]> downloadDocument(JsonNode token, String documentId, String fileType) {
return webClient.get()
.uri(token.get("apiUrl").asText(), uriBuilder -> uriBuilder
.path("/v2.0/api/documents/" + documentId + "/download_files")
.queryParam("file_type", fileType)
.build(documentId))
.header("Authorization", "Bearer " + token.get("accessToken").asText())
.retrieve()
.onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
.flatMap(error -> Mono.error(new RuntimeException(error))))
.bodyToMono(byte[].class);
}
Delete Document
/**
* Delete Document
*
* @method DELETE
* @path /v2.0/api/documents/
* @header access_token
* @body document id array
* @return {"code": "-1", "message": "Completed.", "status": "200"}
*/
public Mono<JsonNode> deleteDocument(JsonNode token, String documentId) {
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = objectMapper.createObjectNode();
ArrayNode arrayNode = objectNode.withArray("document_ids");
arrayNode.add(documentId);
return webClient.method(HttpMethod.DELETE)
.uri(token.get("apiUrl").asText(), uriBuilder -> uriBuilder
.path("/v2.0/api/documents/")
.build())
.header("Authorization", "Bearer " + token.get("accessToken").asText())
.bodyValue(objectNode)
.retrieve()
.onStatus(HttpStatus::isError, res -> res.bodyToMono(String.class)
.flatMap(error -> Mono.error(new RuntimeException(error))))
.bodyToMono(JsonNode.class);
}
Last updated