Trying to tackle the Kraken API. Using ColdFusion 2016.
I have a few tries in here, but can't seem to quite get it.
So testing message, message2, message3 attempts.
https://docs.kraken.com/rest/#section/Authentication/Headers-and-Signature
HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
EXPECTED RESULT:
4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
<cfset _key = "APIKEY">
<cfset _s = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F">
<cfset nonce = "1616492376594">
<cfset payload = "nonce=1616492376594&ordertype=limit&pair=XBTUSD&price=37500&type=buy&volume=1.25">
<cfset URIPath = "/0/private/AddOrder">
<cfscript>
apiKey = "#_key#";
apiSecret = "#_s#";
theKeyBytes = charsetDecode(#_s#, "UTF-8");
_Secret64 = toBase64(#_s#);
// get_kraken_signature(urlpath, data, secret):
h = '#uripath#' & #payload#;
_hash = hmac(h, theKeyBytes, "HMACSHA256");
//HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
//SHA256(nonce + POST data))
_256 = hmac(payload, "HMACSHA256");
_sign = hmac(payload, theKeyBytes, "HMACSHA256");
// HMAC-SHA512 of (URI path + SHA256(nonce + POST data))
message = '#uripath#' & #_256#;
message2 = '#uripath#' & #_256# & #_Secret64#;
message3 = '#uripath#' & #_sign# & #_Secret64#;
_512 = hmac(#message#, "HMACSHA512");
_512_2 = hmac(#message2#, "HMACSHA512");
_512_3 = hmac(#message3#, "HMACSHA512");
_512_H = hmac(#_hash#, "HMACSHA512");
S_H = hmac(#_512_h#, #_s#, "HmacSHA512");
H64 = toBase64(binaryDecode(#s_h#, "hex"));
// base64 decoded secret API key
_64 = toBase64(#_512#);
S_Hex = hmac(#_512#, #_s#, "HmacSHA512");
Hex64 = toBase64(binaryDecode(#s_hex#, "hex"));
S_Hex2 = hmac(#_512_2#, #_s#, "HmacSHA512");
Hex642 = toBase64(binaryDecode(#s_hex2#, "hex"));
S_Hex3 = hmac(#_512_3#, #_s#, "HmacSHA512");
Hex643 = toBase64(binaryDecode(#s_hex3#, "hex"));
</cfscript>
EXPECTED RESULT:
4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
Hex64 Gets:
w1PXl7IDLs1Pri1Vf++UcLFWIFedkxgpceFVkVFbxt7wvjj/Q0wtwwLSMJxV7bMOdFi+BEN3lHuX+CWRx2SxAQ==
Hex642 Gets:
Zxd+96KuI3wSQJ/b0l79djB1M7FMsczoWOfs9Ha5YWIC6sc6uryEGn4MgkcHnF/ndsxDQ2y/jSHl0RxTIuc7PA==
Hex643 Gets:
5KCKhgRGexBPF7SgnSB5G0m3bu+2ecf4fAOndDG0pvYLh0PeWC1nWodi5szigcGU4TyLLb80jPNAR7OmK0t0Sw==
Taking this question as an exercise, I've managed to translate the python function from KrakenAPI docs to CFML script. That function should help you and others with a practical solution. Also publishing it here for my own documentation:
<cfscript>
public string function getKrakenSignature( urlpath, postdata, nonce, secretAsBase64) localmode=true {
// assign arguments to local variables
urlpath= arguments.urlpath;
nonce= arguments.nonce;
postdata = arguments.postdata;
secretAsBase64= arguments.secretAsBase64;
// convert urlpath to a binary Hex representation
urlpathBinary= toBinary( toBase64( urlpath ));
urlpathBinaryAsHex= BinaryEncode( urlpathBinary, "HEX");
// convert secret to binary
secretBinary= ToBinary( arguments.secretAsBase64 );
// concatenate nonce and postdata
noncePostdata = nonce & postdata;
//get binary digest as Hex representation
noncePostdataDigestBinaryAsHex= hash( noncePostdata, "SHA-256" );
// concatenate urlPath binary (hex) and oncePostdataDigest binary (hex)
messageBinaryAsHex= urlpathBinaryAsHex & noncePostdataDigestBinaryAsHex;
// convert message hex representation to binary
messageBinary= BinaryDecode( messageBinaryAsHex, "HEX");
// sign the message with hmac function
messageHmacDigestBinaryAsHex = hmac( messageBinary, secretBinary, "HMACSHA512");
messageHmacDigestBinary=BinaryDecode( messageHmacDigestBinaryAsHex, "HEX");
return binaryEncode( messageHmacDigestBinary, "base64" );
}
encodedPayLoad="nonce=1616492376594&ordertype=limit&pair=XBTUSD&price=37500&type=buy&volume=1.25";
nonce="1616492376594";
api_sec = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg==";
urlpath="/0/private/AddOrder";
signature = getKrakenSignature( urlpath, encodedPayLoad, nonce, api_sec);
writeoutput( signature );
</cfscript>
Find a gist here at tryCf.com
Yes answer above works.
Arrrgh - I had the wrong Secret Key - Cut Paste issue. I only figured it out when reversing the secretkey - that script below as well
kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F
vs
kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg==
Credit AndreasRu above for that answer and method.
I am posting another method below. I have used this one for most of the Crypto API's.
HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
<cfset _key = "APIKEY">
<cfset _s = "kQH5HW/8p1uGOVjbgWA7FunAmGO8lsSUXNsu3eow76sz84Q18fWxnyRzBHCd3pd5nE9qa99HAZtuZuj6F1huXg==">
<cfset nonce = "1616492376594">
<cfset payload = "nonce=1616492376594&ordertype=limit&pair=XBTUSD&price=37500&type=buy&volume=1.25">
<cfset URIPath = "/0/private/AddOrder">
<cfscript>
// URIPATH to a binary Hex
BURL64 = toBinary(toBase64(#URIPath#));
URLHEX = BinaryEncode(BURL64,"HEX");
// Secret to binary
SB = ToBinary(#_s#);
// SHA256(nonce + POST data)
SHA256_Post = '#nonce#' & #payload#;
SHA_256 = hash(#SHA256_Post#, "SHA-256", "UTF-8");
// BUILD SHA-512
URI256POST = '#urlhex#' & #SHA_256#;
// convert SHA512 buid to message hex
MESSAGEHEX = BinaryDecode(URI256POST,"HEX");
// messageHex to HMAC SHA-512
M512 = hmac(#MESSAGEHEX#, #SB#, "HMACSHA512");
M512HEX = BinaryDecode(M512,"HEX");
// Final Signature
SignFinal = toBase64(M512HEX);
</cfscript>
<cfoutput>
EXPECTED RESULT:
4/dpxb3iT4tp/ZCVEwSnEsLxx0bqyhLpdfOpc6fn7OR8+UClSV5n9E6aSS8MPtnRfp32bAb0nmbRn6H8ndwLUQ==
#signfinal#
</cfoutput>
Figuring out secret code below. Not needed for Kraken API-Sign
<cfscript>
hexEncoded = binaryEncode(secretBinary, "hex");
base64Encoded = binaryEncode(secretBinary, "base64");
writeDump
([
secretBinary,
hexEncoded,
base64Encoded,
binaryDecode(hexEncoded, "hex"),
binaryDecode(base64Encoded, "base64")
]);
</cfscript>
Related
I need help constructing the Authorization header to PUT a block blob.
PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat, 25 Feb 2017 22:20:13 GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n
I take this, UTF 8 encode it. Then I take my access key in my Azure account and HMAC sha256 this UTF 8 encoded string with the key. Then I output that in base64. Let's call this output string.
My authorization header looks like this: SharedKey myaccountname:output string
It is not working.
The header in Postman also has x-ms-blob-type, x-ms-date, x-ms-version, Content-Length, and Authorization. The body for now says hello world.
Can anyone help me make this successful request in Postman?
<?xml version="1.0" encoding="utf-8"?>
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:cdeb9a5e-0001-0029-5fb5-8f7995000000
Time:2017-02-25T22:22:32.0300016Z</Message>
<AuthenticationErrorDetail>The MAC signature found in the HTTP request 'jiJtirohvi1syXulqkPKESnmQEJI4GpDU5JBn7BM/xY=' is not the same as any computed signature. Server used following string to sign: 'PUT
11
text/plain;charset=UTF-8
x-ms-date:Sat, 25 Feb 2017 22:20:13 GMT
x-ms-version:2015-02-21
/myaccountname/mycontainername/blob.txt'.</AuthenticationErrorDetail>
</Error>
EDIT:
First, I want to thank you and everyone who responded. I truly truly appreciate it. I have one last question and then I think I'll be set!! I'm not using that code - I'm doing this all by hand. If I have my key: X2iiy6v47j1jZZH5555555555zzQRrIAdxxVs55555555555av8uBUNGcBMotmS7tDqas14gU5O/w== changed slightly for anonymity - do I decode it: using an online base64decoder. Then, when I have my string which now looks like this: PUT\n\n\n11\n\ntext/plain;charset=UTF-8\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Mon, 27 Feb 2017 21:53:13 GMT\nx-ms-version:2015-02-21\n/myaccount/mycontainer/blob.txt\n so I run this in https://mothereff.in/utf-8 and then use this in HMAC with my decoded key: https://www.liavaag.org/English/SHA-Generator/HMAC/ - using sha256 and base64 at the end.
Is that how I get the correct string to put here?: SharedKey myaccount:<string here>
I believe there's an issue with how you're specifying StringToSign here:
PUT\n\n\n11\n\n\n\n\n\n\n\n\nx-ms-blob-type:BlockBlob\nx-ms-date:Sat,
25 Feb 2017 22:20:13
GMT\nx-ms-version:2015-02-21\n/myaccountname/mycontainername/blob.txt\n
If you notice the error message returned from the server, string to sign by server is different than yours and the difference is that the server is using Content-Type (text/plain;charset=UTF-8) in signature calculation while you're not. Please include this content type in your code and things should work just fine.
Here's the sample code (partial only) I used:
var requestMethod = "PUT";
var urlPath = "test" + "/" + "myblob.txt";
var storageServiceVersion = "2015-12-11";
var date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
var blobType = "BlockBlob";
var contentBytes = Encoding.UTF8.GetBytes("Hello World");
var canonicalizedResource = "/" + accountName + "/" + urlPath;
var canonicalizedHeaders = "x-ms-blob-type:" + blobType + "\nx-ms-date:" + date + "\nx-ms-version:" + storageServiceVersion + "\n";
var stringToSign = requestMethod + "\n" +
"\n" + //Content Encoding
"\n" + //Content Language
"11\n" + //Content Length
"\n" + //Content MD5
"text/plain;charset=UTF-8" + "\n" + //Content Type
"\n" + //Date
"\n" + //If - Modified - Since
"\n" + //If - Match
"\n" + //If - None - Match
"\n" + //If - Unmodified - Since
"\n" + //Range +
canonicalizedHeaders +
canonicalizedResource;
string authorizationHeader = GenerateSharedKey(stringToSign, accountKey, accountName);
private static string GenerateSharedKey(string stringToSign, string key, string account)
{
string signature;
var unicodeKey = Convert.FromBase64String(key);
using (var hmacSha256 = new HMACSHA256(unicodeKey))
{
var dataToHmac = Encoding.UTF8.GetBytes(stringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
return string.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}", "SharedKey", account, signature);
}
According to your error message, it indicates that authorization signature is incorrect.
If the Content-Type "text/plain; charset=UTF-8" is not included in the header, please add it in the stringTosign and postman.
When we try to get the signature, we need to make sure the length of the blob.txt matches the Content length in the stringTosign. That means request body length should match the content length in the stringTosign.
I test it with Postman, it works correctly. We can get the signature with the code in another SO Thread. The following is my detail steps
Add the following header
Add the request body (example: Hello World)
Send the put blob request.
Update :
Please have a try to use the online tool to generate signature for test.
I am trying to use https://api.periscope.tv/api/v2/loginTwitter to get a response from the server so that I can obtain a cookie for periscope API calls.
I have all of the required values for the request query, but I continue to get the "Bad Request" error (error code 400). Is anyone able to use the loginTwitter API still?
Request headers:
POST /api/v2/loginTwitter?bundle_id=com.bountylabs.periscope&phone_number=&session_key=xxxxxxxx&session_secret=xxxxxxxx&user_id=xxxxxxxx&user_name=xxxxxxxx&vendor_id=81EA8A9B-2950-40CD-9365-40535404DDE4 HTTP/1.1
Authorization:
OAuth oauth_consumer_key="xxxxxxxx",oauth_nonce="cecf203cda273c845cd5121007232666",oauth_signature="xxxxxxxx%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1474786616",oauth_token="xxxxxxxx",oauth_version="1.0"
Oauth signature:
POST&https%3A%2F%2Fapi.periscope.tv%2Fapi%2Fv2%2FloginTwitter%3Fbundle_id%3Dcom.bountylabs.periscope%26phone_number%3D%26session_key%xxxxxxxx%26session_secret%3xxxxxxxx%26user_id%3xxxxxxxx%26user_name%xxxxxxxx%26vendor_id%3D81EA8A9B-2950-40CD-9365-40535404DDE4&bundle_id%3Dcom.bountylabs.periscope%26oauth_consumer_key%3xxxxxxxx%26oauth_nonce%3Dcecf203cda273c845cd5121007232666%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1474786616%26oauth_token%xxxxxxxx%26oauth_version%3D1.0%26phone_number%3D%26session_key%xxxxxxxxMX%26session_secret%xxxxxxxxt%26user_id%xxxxxxxx4%26user_name%xxxxxxxx%26vendor_id%3D81EA8A9B-2950-40CD-9365-40535404DDE4
I have solved the problem thanks to help from another. The problem was that I was passing the request parameters in the URL without encoding them into json. For any that are looking to resolve this problem, here is the solution I arrived at with c#.
var httpWebRequest = ( HttpWebRequest )WebRequest.Create( "https://api.periscope.tv/api/v2/loginTwitter" );
httpWebRequest.ContentType = "application/json; charset=UTF-8";
httpWebRequest.Method = "POST";
using( var streamWriter = new StreamWriter( httpWebRequest.GetRequestStream() ) ){
string json = "{" +
"\"bundle_id\":\"com.bountylabs.periscope\"," +
"\"phone_number\":\"\"," +
"\"session_key\":\""+final_oauth_token+"\"," +
"\"session_secret\":\""+final_oauth_token_secret+"\"," +
"\"user_id\":\""+user_id+"\"," +
"\"user_name\":\""+screen_name+"\"," +
"\"vendor_id\":\"81EA8A9B-2950-40CD-9365-40535404DDE4\"" +
"}";
streamWriter.Write( json );
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = ( HttpWebResponse )httpWebRequest.GetResponse();
using( var streamReader = new StreamReader( httpResponse.GetResponseStream() ) ){
var result = streamReader.ReadToEnd();
display.Text = "cookie: "+result;
}
}
The result yields a cookie in the server's response.
Reference for more detail on this process: Twitter login POST request in Periscope API
I'm trying to get a simple post request to work to create a customer via the Stripe.js API.
https://stripe.com/docs/api/java#authentication
I'm doing this in vb.net and don't want to use the stripe.net library.
I keep getting authorization failed. All I have to pass is the username in the header, or in this case the username is my test api key.
Here's a chunk of the code:
Dim asPostRequest As HttpWebRequest = WebRequest.Create(String.Format(ApiEndpoint))
Dim as_ByteArray As Byte() = Encoding.UTF8.GetBytes(stripeccw.ToString)
asPostRequest.Method = "POST"
asPostRequest.ContentType = "application/json"
'asPostRequest.Headers("Authorization") = "Basic" + apikey
'asPostRequest.Credentials("bearer", apikey)
'asPostRequest.Headers.Add("Authorization") = apikey
'asPostRequest.Credentials("Username") = apikey
'asPostRequest.Credentials = New NetworkCredential(apikey, "")
asPostRequest.ContentLength = as_ByteArray.Length
Dim as_DataStream As Stream = asPostRequest.GetRequestStream()
as_DataStream.Write(as_ByteArray, 0, as_ByteArray.Length)
as_DataStream.Close()
Where I've commented out... those are different ways that I've tried. I know some are just stupid attempts, but just getting frustrated. I know for a fact my api key is correct. I can verify this by navigating to https://api.stripe.com/v1/customers and entering it in for my username only.
Hoping someone can spot something simple :)
Thank you!
If I were in your shoes, the first thing I'd do is take a look at how Stripe.Net does it. Even if you don't want to use that library yourself, that doesn't mean you can't use the source code as a reference.
From Requestor.cs:
internal static WebRequest GetWebRequest(string url, string method, string apiKey = null, bool useBearer = false)
{
apiKey = apiKey ?? StripeConfiguration.GetApiKey();
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = method;
if(!useBearer)
request.Headers.Add("Authorization", GetAuthorizationHeaderValue(apiKey));
else
request.Headers.Add("Authorization", GetAuthorizationHeaderValueBearer(apiKey));
request.Headers.Add("Stripe-Version", StripeConfiguration.ApiVersion);
request.ContentType = "application/x-www-form-urlencoded";
request.UserAgent = "Stripe.net (https://github.com/jaymedavis/stripe.net)";
return request;
}
private static string GetAuthorizationHeaderValue(string apiKey)
{
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:", apiKey)));
return string.Format("Basic {0}", token);
}
private static string GetAuthorizationHeaderValueBearer(string apiKey)
{
return string.Format("Bearer {0}", apiKey);
}
So it seems there are two ways to do it. You can either use "Bearer" format, which is:
asPostRequest.Headers.Add("Authorization", "Bearer " & apiKey)
or you can use "Basic" format which is:
asPostRequest.Headers.Add("Authorization", _
"Basic " & Convert.ToBase64String(Encoding.UTF8.GetBytes(apiKey & ":")))
Trying to Construct a Shared Access Signature URI for a Blob access in a container
BlobHelper BlobHelper = new BlobHelper(StorageAccount, StorageKey);
string signature = "";
string signedstart = DateTime.UtcNow.AddMinutes(-1).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
string signedexpiry = DateTime.UtcNow.AddMinutes(2).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'");
//// SET CONTAINER LEVEL ACCESS POLICY
string accessPolicyXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<SignedIdentifiers>\n" +
" <SignedIdentifier>\n" +
" <Id>twominutepolicy</Id>\n" +
" <AccessPolicy>\n" +
" <Start>" + signedstart + "</Start>\n" +
" <Expiry>" + signedexpiry + "</Expiry>\n" +
" <Permission>r</Permission>\n" +
" </AccessPolicy>\n" +
" </SignedIdentifier>\n" +
"</SignedIdentifiers>\n";
BlobHelper.SetContainerAccessPolicy("xxxxxxx", "container", accessPolicyXml));
string canonicalizedresource = "/xxxxxxx/501362787";
string StringToSign = String.Format("{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n{6}\n{7}\n{8}\n{9}\n{10}",
"r",
signedstart,
signedexpiry,
canonicalizedresource,
"twominutepolicy",
"2013-08-15",
"rscc",
"rscd",
"rsce",
"rscl",
"rsct"
);
using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(StorageKey)))
{
Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
}
StringBuilder sasToken = new StringBuilder();
sasToken.Append(BlobHelper.DecodeFrom64(e.Item.ToolTip).ToString().Replace("http","https") + "?");
//signedversion
sasToken.Append("sv=2013-08-15&");
sasToken.Append("sr=b&");
//
sasToken.Append("si=twominutepolicy&");
sasToken.Append("sig=" + signature + "&");
//
sasToken.Append("st=" + HttpUtility.UrlEncode(signedstart).ToUpper() + "&");
//
sasToken.Append("se=" + HttpUtility.UrlEncode(signedexpiry).ToUpper() + "&");
//
sasToken.Append("sp=r");
string url = sasToken.ToString();
I am getting the following exception below
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. RequestId:e424e1ac-fd96-4557-866a-992fc8c41841 Time:2014-05-22T18:46:15.3436786Z</Message>
<AuthenticationErrorDetail>Signature did not match. String to sign used was r 2014-05-22T18:45:06Z 2014-05-22T18:48:06Z /xxxxxxx/501362787/State.SearchResults.pdf twominutepolicy 2013-08-15 </AuthenticationErrorDetail>
</Error>
rscc, rscd, rsce, rscl, rsct are placeholders for overridden response headers. Your sasToken variable does not seem to override response headers, so you should just use empty strings with a new-line character when signing them. Moreover, it looks like your canonicalized resource also does not match the server's resource.
By the way, did you look at Azure Storage Client Library to create Shared Access Signature tokens? It provides lots of features and is the official SDK to access Microsoft Azure Storage.
I'm using DocuSign to add eSignature to my requests and everything's working well. Right now I send my signature requests,by using Embedded method- to initiate my workflows immediately by navigating to a URL.
After login,and execute the bellow code,i get the (Embedded View: https://demo.docusign.net/Member/StartInSession.aspx?StartConsole=1&t=32598057-5a59-4d0b-bad8-a8ff8f2407f6&DocuEnvelope=168bc155-e013-4ffd-abb4-7608b56647f8&send=1), but whene i paste the url to try signing document in navigate, but will redirect me to an other url is(http://www.docusign.com/?event=Send&envelopeId=168bc155-e013-4ffd-abb4-7608b56647f8),
how can'i start wotkflow process to sign my enveloppe ?? i can't see my enveloppe to sign it.
// STEP 2 - Create an envelope with one recipient, document, and tab and send
//
String jsonBody = "{\"emailBlurb\":\"partail\"," +
"\"emailSubject\":\"API Call for adding signature request to document and sending\"," +
"\"documents\":[{" +
"\"documentId\":\"1\"," +
"\"name\":\"test.pdf\"}]," +
"\"recipients\":{" +
"\"signers\":[{" +
"\"email\":\"" + EmailRecipients + "\"," +
"\"name\":\"name\"," +
"\"recipientId\":\"1\"," +
"\"routingOrder\":\"1\","+
"\"clientUserId\":\"1000\","+
"\"tabs\":{" +
"\"signHereTabs\":[{" +
"\"xPosition\":\"300\"," +
"\"yPosition\":\"600\"," +
"\"documentId\":\"1\"," +
"\"pageNumber\":\"1\"" + "}]}}]}," +
"\"status\":\"sent\"}";
//DemandeSign.getenvelope();
File file = new File("D:/test.pdf");
InputStream inputStream = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
inputStream.read(bytes);
inputStream.close();
String requestBody = "\r\n\r\n--BOUNDARY\r\n" +
"Content-Type: application/json\r\n" +
"Content-Disposition: form-data\r\n" +
"\r\n" +
jsonBody + "\r\n\r\n--BOUNDARY\r\n" + // our json formatted request body
"Content-Type: application/pdf\r\n" +
"Content-Disposition: file; filename=\"test.pdf\"; documentId=1\r\n" +
"\r\n";
// we break this up into two string since the PDF doc bytes go here and are not in string format.
// see further below where we write to the outputstream...
String reqBody2 = "\r\n" + "--BOUNDARY--\r\n\r\n";
// append "/envelopes" to the baseUrl and use in the request
conn = (HttpURLConnection)new URL(baseURL + "/envelopes").openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("X-DocuSign-Authentication", authenticateStr);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=BOUNDARY");
conn.setRequestProperty("Content-Length", Integer.toString(requestBody.toString().length()));
conn.setRequestProperty("Accept", "application/xml");
// write the body of the request...
DataOutputStream dos = new DataOutputStream( conn.getOutputStream() );
dos.writeBytes(requestBody.toString());
dos.write(bytes);
dos.writeBytes(reqBody2.toString());
dos.flush(); dos.close();
status = conn.getResponseCode(); // triggers the request
if( status != 201 ) // 201 = Created
{
System.out.println("Error calling webservice, status is: " + status);
InputStreamReader isr = new InputStreamReader( conn.getErrorStream() );
br = new BufferedReader(isr);
StringBuilder error_response = new StringBuilder();
while ( (line = br.readLine()) != null)
error_response.append(line);
System.out.println("Error response is " + error_response.toString() );
System.exit(-1);
}
// Read the response
InputStreamReader isr = new InputStreamReader( conn.getInputStream() );
br = new BufferedReader(isr);
StringBuilder response2 = new StringBuilder();
while ( (line = br.readLine()) != null)
response2.append(line);
//token1 = "//*[1]/*[local-name()='envelopeId']";
//String envelopeId = xPath.evaluate(token1, new InputSource(new StringReader(response2.toString())));
//--- display results
//System.out.println("Document sent! envelopeId is " + envelopeId );//envelopeId is e4c0659a-9d01-4ac3-a45f-02a80fd6bd96 at 04/07/2013 17:24
token1 = "//*[1]/*[local-name()='uri']";
String uri = xPath.evaluate(token1, new InputSource(new StringReader(response2.toString())));
//--- display results
System.out.println("uri = " + uri );
/// Step3
// construct another outgoing XML request body
String reqBody = "<returnUrlRequest xmlns=\"http://www.docusign.com/restapi\">" +
"<authenticationMethod>email</authenticationMethod>" +
"<email>***test#gmail.com***</email>" +
"<returnUrl>http://www.docusign.com</returnUrl>" +
"<userName>name</userName>" +
"<clientUserId>1000</clientUserId>" +
"</returnUrlRequest>";
// append uri + "/views/sender" to the baseUrl and use in the request
conn = (HttpURLConnection)new URL(baseURL + uri + "/views/sender").openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("X-DocuSign-Authentication", authenticateStr);
conn.setRequestProperty("Content-Type", "application/xml");
conn.setRequestProperty("Content-Length", Integer.toString(reqBody.length()));
conn.setRequestProperty("Accept", "application/xml");
// write the body of the request...
dos = new DataOutputStream( conn.getOutputStream() );
dos.writeBytes(reqBody); dos.flush(); dos.close();
status = conn.getResponseCode(); // triggers the request
if( status != 201 ) // 201 = Created
{
System.out.println("Error calling webservice, status is: " + status);
System.exit(-1);
}
// Read the response
isr = new InputStreamReader( conn.getInputStream() );
br = new BufferedReader(isr);
StringBuilder response3 = new StringBuilder();
while ( (line = br.readLine()) != null)
response3.append(line);
token1 = "//*[1]/*[local-name()='url']";
//--- display results
System.out.println("Embedded View: " + xPath.evaluate(token1, new InputSource(new StringReader(response3.toString()))));`
Are you trying to access the URL immediately or are you waiting at all? Once you generate a URL token to access a given envelope it has a TTL (time to life) of 5 mins, meaning it expires after 5 minutes and you then need to generate a new one.
If that's not it, your problem might be related to how you are identifying your recipient. A recipient in DocuSign is identified by the unique combination of their name, email, recipientId, and in the case of embedding, the clientUserId. You seem to be setting all of those, however whatever the combination is when you first create the envelope, you need to refer to the same combination when you are requesting the Embedded URL token.
When you create your envelope I see you are setting the name literally to "name" and that you are setting the email through a variable called "EmailRecipients". But when you request the URL token you are using email "test#gmail.com", that might be causing your issue too.