# API overview

# DidaTravel provide types of api as follows:

  1. Search&Book API:Search, Verify, Book, Pay Verify etc.
  2. Ticketing API:ApplyTicket, InformTicket/OrderDetails, PNRRetrieve etc.
  3. Ancillary API:AncillarySearch, AncillaryBook, AncillaryPay, AncillaryDetails etc.
  4. Refund/Change API: Refund/Change Apply, Refund/Change Confirm, Refund/Change Cancel, Refund/Change Details, AttachUpload etc.

# Test/Production Enviroment Params,it will be provided after commercial agreement signed:

  1. CID
  2. APPKEY(AK)
  3. SECRETKEY(SK)

# API specification

  1. We provide API http to intervide URL, the Unicode is UTF-8
  2. The API http request Content-Type="text/plain", Accept-Encoding: gzip
  3. The API according to http post to request API URL and send the body which is compliance with requirements about JSON
  4. The API Header must include
Header Description
X-Key API identifier (APP-KEY),will be provided after commercial agreement signed
X-Timestamp unix timestamp(13)
X-Signature Character After signature, see《X-Signature Signature Method》, the client's ip must in the DidaTravel's whitelist
  1. Book, PayVerify should using AES encryption, and the key is satisfied with 128,The production APP KEY and SECRET KEY will be send after partener is certified to go live on production enviroment. see《AES Encryption Method》
  2. QPS Limit。DidaTravel's default QPS:QPS=30. Too much request will be rejected。contact us for more QPS.
  3. The Customer must support the gzip, all the response will be returned with gzip compression.

# X-Signature Signature Method

  • Content to be Signature(stringToBeSigned):Http Method&Content-Type&Accept-Encoding&X-Timestamp&MD5(PAYLOAD)

  • SHA256 asymmetric encryption using SECRET-KEY

  • e.g.

    SECRETKEY: abcdefghijklmnopqrst

    PAYLOAD:{"cid":"TESTCID","fromCity":"LON","toCity":"SIN","fromDate":"20221010","retDate":"","tripType":"1","adultNumber":"1","childNumber":"0","currency":"CNY"}

    stringToBeSigned: POST&text/plain&gzip&1654742612768&f5c15d19e356eee91dec15366f5c1f01

    X-Signature: MTY5ODFiY2Y4YWI5N2MwMDQ0MmIzY2E3ZWZmNWRhZmM5M2IwMGI2OTgwY2I0MTFlNjUzMzQzN2JlNzNjYTIwYg==

  • Sample Code

String secretKey = "1234567890123456";
String httpMethod = "POST";
String contentType = "text/plain"
String gzip = "gzip";
// String timestamp = String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli())  // eg: UTC+8
String timestamp = "1654742612768";
String payload = "{\"cid\":\"TESTCID\",\"fromCity\":\"LON\",\"toCity\":\"SIN\",\"fromDate\":\"20221010\",\"retDate\":\"\",\"tripType\":\"1\",\"adultNumber\":\"1\",\"childNumber\":\"0\",\"currency\":\"CNY\"}";
String md5Payload = DigestUtils.md5Hex(payload);
String str2Sign = String.join("&", httpMethod, contentType, gzip, timestamp, md5Payload);

String algorithm = HmacAlgorithms.HMAC_SHA_256.getName();
Mac hmacSha256 = Mac.getInstance(algorithm);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), algorithm);
hmacSha256.init(secretKeySpec);

byte[] bytes = hmacSha256.doFinal(str2Sign.getBytes(StandardCharsets.UTF_8));
String hexString = Hex.encodeHexString(bytes);

String xSign = Base64.getEncoder().encodeToString(hexString.getBytes(StandardCharsets.UTF_8));

# AES Encryption Method

  • Encryption mode:AES/CBC/PKCS5Padding

  • Encryption initialization vector:The empty byte array with length of 16.

  • e.g.

    Secret-Key: 1234567890123456

    Original: abcdefghigklmnopqrstuvwxyz0123456789

    Encrypted: 8Z3dZzqn05FmiuBLowExK0CAbs4TY2GorC2dDPVlsn/tP+VuJGePqIMv1uSaVErr

  • Sample Code

String encode = StringUtils.EMPTY;
String secretKey = "1234567890123456";
String original = "abcdefghigklmnopqrstuvwxyz0123456789";

byte[] keyBytes = secretKey.getBytes();
byte[] targetBytes = new byte[16];

for (int i =0; i < keyBytes.length && i < targetBytes.length; i++) {
    targetBytes[i] = keyBytes[i];
}
SecretKeySpec secretKeySpec = new SecretKeySpec(targetBytes, "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[16]);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

byte[] encrypt = cipher.doFinal(src.getBytes());
encode = Base64.getEncoder().encodeToString(encrypt);