PureBasic
PureBasic
Get E-way Bill System Access Token
See more HTTP Misc Examples
Sends a request to get an E-way bill system access token.Chilkat PureBasic Downloads
IncludeFile "CkPublicKey.pb"
IncludeFile "CkJsonObject.pb"
IncludeFile "CkPrng.pb"
IncludeFile "CkHttpResponse.pb"
IncludeFile "CkFileAccess.pb"
IncludeFile "CkHttp.pb"
IncludeFile "CkCrypt2.pb"
IncludeFile "CkStringBuilder.pb"
IncludeFile "CkRsa.pb"
IncludeFile "CkBinData.pb"
Procedure ChilkatExample()
success.i = 0
; This example requires the Chilkat API to have been previously unlocked.
; See Global Unlock Sample for sample code.
; First load the public key provided by the E-way bill System
pubkey.i = CkPublicKey::ckCreate()
If pubkey.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkPublicKey::ckLoadFromFile(pubkey,"qa_data/pem/eway_publickey.pem")
If success = 0
Debug CkPublicKey::ckLastErrorText(pubkey)
CkPublicKey::ckDispose(pubkey)
ProcedureReturn
EndIf
; Encrypt the password using the RSA public key provided by eway..
password.s = "my_wepgst_password"
rsa.i = CkRsa::ckCreate()
If rsa.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkRsa::setCkCharset(rsa, "utf-8")
CkRsa::setCkEncodingMode(rsa, "base64")
success = CkRsa::ckUsePublicKey(rsa,pubkey)
If success = 0
Debug CkRsa::ckLastErrorText(rsa)
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
; Returns the encrypted password as base64 (because the EncodingMode = "base64")
encPassword.s = CkRsa::ckEncryptStringENC(rsa,password,0)
If CkRsa::ckLastMethodSuccess(rsa) = 0
Debug CkRsa::ckLastErrorText(rsa)
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
ProcedureReturn
EndIf
; Generate a random app_key. This should be 32 bytes (us-ascii chars)
; We need 32 bytes because we'll be doing 256-bit AES ECB encryption, and 32 bytes = 256 bits.
prng.i = CkPrng::ckCreate()
If prng.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Generate a random string containing some numbers, uppercase, and lowercase.
app_key.s = CkPrng::ckRandomString(prng,32,1,1,1)
Debug "app_key = " + app_key
; RSA encrypt the app_key.
encAppKey.s = CkRsa::ckEncryptStringENC(rsa,app_key,0)
If CkRsa::ckLastMethodSuccess(rsa) = 0
Debug CkRsa::ckLastErrorText(rsa)
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
CkPrng::ckDispose(prng)
ProcedureReturn
EndIf
; Prepare the JSON body for the HTTP POST that gets the access token.
jsonBody.i = CkJsonObject::ckCreate()
If jsonBody.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckUpdateString(jsonBody,"action","ACCESSTOKEN")
; Use your username instead of "09ABDC24212B1FK".
CkJsonObject::ckUpdateString(jsonBody,"username","09ABDC24212B1FK")
CkJsonObject::ckUpdateString(jsonBody,"password",encPassword)
CkJsonObject::ckUpdateString(jsonBody,"app_key",encAppKey)
http.i = CkHttp::ckCreate()
If http.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
; Add required headers.
; Use your ewb-user-id instead of "03AEXPR16A9M010"
CkHttp::ckSetRequestHeader(http,"ewb-user-id","03AEXPR16A9M010")
; The Gstin should be the same as the username in the jsonBody above.
CkHttp::ckSetRequestHeader(http,"Gstin","09ABDC24212B1FK")
CkHttp::setCkAccept(http, "application/json")
; POST the JSON...
resp.i = CkHttpResponse::ckCreate()
If resp.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
success = CkHttp::ckHttpJson(http,"POST","http://ewb.wepgst.com/api/Authenticate",jsonBody,"application/json",resp)
If success = 0
Debug CkHttp::ckLastErrorText(http)
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
CkPrng::ckDispose(prng)
CkJsonObject::ckDispose(jsonBody)
CkHttp::ckDispose(http)
CkHttpResponse::ckDispose(resp)
ProcedureReturn
EndIf
respStatusCode.i = CkHttpResponse::ckStatusCode(resp)
Debug "response status code =" + Str(respStatusCode)
Debug "response body:"
Debug CkHttpResponse::ckBodyStr(resp)
If respStatusCode <> 200
Debug "Failed in some unknown way."
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
CkPrng::ckDispose(prng)
CkJsonObject::ckDispose(jsonBody)
CkHttp::ckDispose(http)
CkHttpResponse::ckDispose(resp)
ProcedureReturn
EndIf
; When the response status code = 200, we'll have either
; success response like this:
; {"status":"1","authtoken":"...","sek":"..."}
;
; or a failed response like this:
;
; {"status":"0","error":"eyJlcnJvckNvZGVzIjoiMTA4In0="}
; Load the response body into a JSON object.
json.i = CkJsonObject::ckCreate()
If json.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckLoad(json,CkHttpResponse::ckBodyStr(resp))
status.i = CkJsonObject::ckIntOf(json,"status")
Debug "status = " + Str(status)
If status <> 1
; Failed. Base64 decode the error
; {"status":"0","error":"eyJlcnJvckNvZGVzIjoiMTA4In0="}
; For an invalid password, the error is: {"errorCodes":"108"}
sbError.i = CkStringBuilder::ckCreate()
If sbError.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckStringOfSb(json,"error",sbError)
CkStringBuilder::ckDecode(sbError,"base64","utf-8")
Debug "error: " + CkStringBuilder::ckGetAsString(sbError)
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
CkPrng::ckDispose(prng)
CkJsonObject::ckDispose(jsonBody)
CkHttp::ckDispose(http)
CkHttpResponse::ckDispose(resp)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbError)
ProcedureReturn
EndIf
; At this point, we know the request was entirely successful.
authToken.s = CkJsonObject::ckStringOf(json,"authtoken")
; Decrypt the sek key using our app_key.
crypt.i = CkCrypt2::ckCreate()
If crypt.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkCrypt2::setCkCryptAlgorithm(crypt, "aes")
CkCrypt2::setCkCipherMode(crypt, "ecb")
CkCrypt2::setCkKeyLength(crypt, 256)
CkCrypt2::ckSetEncodedKey(crypt,app_key,"us-ascii")
CkCrypt2::setCkEncodingMode(crypt, "base64")
bdSek.i = CkBinData::ckCreate()
If bdSek.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkBinData::ckAppendEncoded(bdSek,CkJsonObject::ckStringOf(json,"sek"),"base64")
CkCrypt2::ckDecryptBd(crypt,bdSek)
; bdSek now contains the decrypted symmetric encryption key...
; We'll use it to encrypt the JSON payloads we send.
; Let's persist our authtoken and decrypted sek (symmetric encryption key).
; To send EWAY requests (such as to create an e-way bill), we'll just load
; and use these pre-obtained credentials.
jsonEwayAuth.i = CkJsonObject::ckCreate()
If jsonEwayAuth.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkJsonObject::ckUpdateString(jsonEwayAuth,"authToken",authToken)
CkJsonObject::ckUpdateString(jsonEwayAuth,"decryptedSek",CkBinData::ckGetEncoded(bdSek,"base64"))
CkJsonObject::setCkEmitCompact(jsonEwayAuth, 0)
fac.i = CkFileAccess::ckCreate()
If fac.i = 0
Debug "Failed to create object."
ProcedureReturn
EndIf
CkFileAccess::ckWriteEntireTextFile(fac,"qa_data/tokens/ewayAuth.json",CkJsonObject::ckEmit(jsonEwayAuth),"utf-8",0)
Debug "Saved:"
Debug CkJsonObject::ckEmit(jsonEwayAuth)
; Sample output:
; {
; "authToken": "IBTeFtxNfVurg71LTzZ2r0xK7",
; "decryptedSek": "5g1TyTie7yoslU3DrbYATa7mWyPazlODE7cEh5Vy4Ho="
;
CkPublicKey::ckDispose(pubkey)
CkRsa::ckDispose(rsa)
CkPrng::ckDispose(prng)
CkJsonObject::ckDispose(jsonBody)
CkHttp::ckDispose(http)
CkHttpResponse::ckDispose(resp)
CkJsonObject::ckDispose(json)
CkStringBuilder::ckDispose(sbError)
CkCrypt2::ckDispose(crypt)
CkBinData::ckDispose(bdSek)
CkJsonObject::ckDispose(jsonEwayAuth)
CkFileAccess::ckDispose(fac)
ProcedureReturn
EndProcedure