Complex JSON Web Token Array in webapi with OWIN - c#

I'm in process of trying to learn JWT and ouath. I have came across form of JWT which would help me in development of my authorization server.
The format I came across is following :
{
iat: 1416929061,
jti: "802057ff9b5b4eb7fbb8856b6eb2cc5b",
scopes: {
users: {
actions: ['read', 'create']
},
users_app_metadata: {
actions: ['read', 'create']
}
}
}
However since in adding claims we can only add simple string how something like this can be achieved ?
The only way I have seen till now was to use JSON.serialization - coming from https://stackoverflow.com/a/27279400/2476347
new Claim(someClass,JsonConvert.SerializeObject(result)
any guidelines would be much appreciated! Thanks!
Code used for testing
Class I would like to use in JWT
public class MyTes
{
public string area { get; set; }
public List<string> areapermissions { get; set; }
}
And then I use the following code for token generation
var identity = new ClaimsIdentity("JWT");
var cos = new List<string>();
cos.Add("aaa");
cos.Add("bbb");
MyTes vario = new MyTes()
{
area = "someregion",
areapermissions = cos
};
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim(ClaimTypes.Role, "Manager"));
identity.AddClaim(new Claim(ClaimTypes.Role, "Supervisor"));
identity.AddClaim(new Claim("scope", "xyz1"));
identity.AddClaim(new Claim("scope", "xyz2"));
identity.AddClaim(new Claim("scope", "xyz3"));
identity.AddClaim(new Claim("APIs", JsonConvert.SerializeObject(cos)));
identity.AddClaim(new Claim("APIs2", JsonConvert.SerializeObject(vario)));
This gives no errors and when I decode the ticket I get now :
{
"unique_name": "Rafski",
"sub": "Rafski",
"role": [
"Manager",
"Supervisor"
],
"scope": [
"xyz1",
"xyz2",
"xyz3"
],
"APIs": "[\"aaa\",\"bbb\"]",
"APIs2": "{\"area\":\"someregion\",\"areapermissions\":[\"aaa\",\"bbb\"]}",
"iss": "http://kurwa.mac",
"aud": "7aaa70ed8f0b4807a01596e2abfbd44d",
"exp": 1429351056,
"nbf": 1429349256
}

Here's how to create a JWT token with complex JSON claims using .Net.
Use Nuget to get the Library: System.IdentityModel.Tokens.Jwt
Then use the following code to create a JWT token.
var keybytes = Convert.FromBase64String(YOUR_CLIENT_SECRET);
var signingCredentials = new SigningCredentials(
new InMemorySymmetricSecurityKey(keybytes),
SecurityAlgorithms.HmacSha256Signature,
SecurityAlgorithms.Sha256Digest);
var nbf = DateTime.UtcNow.AddSeconds(-1);
var exp = DateTime.UtcNow.AddSeconds(120);
var payload = new JwtPayload(null, "", new List<Claim>(), nbf, exp);
var users = new Dictionary<string, object>();
users.Add("actions", new List<string>() { "read", "create" });
var scopes = new Dictionary<string, object>();
scopes.Add("users", users);
payload.Add("scopes", scopes);
var jwtToken = new JwtSecurityToken(new JwtHeader(signingCredentials), payload);
var jwtTokenHandler = new JwtSecurityTokenHandler();
return jwtTokenHandler.WriteToken(jwtToken);
Which would produce a token such as
{
"typ": "JWT",
"alg": "HS256"
}
{
"exp": 1433254394,
"nbf": 1433254273,
"scopes": {
"users": {
"actions": [
"read", "create"
]
}
}
}

This has been never an issue these days. It can be solved using the
Payload section of the token.
**using System.IdentityModel.Tokens.Jwt;** //Vesrion 5.5.0
Sample code
public static string Generate()
{
IList<User> users = new List<User> {
new User { Id = 1, Name = "User One" },
new User { Id = 2, Name = "User Two" },
new User { Id = 3, Name = "User Three" }
};
IList<Company> companies = new List<Company>
{
new Company{ Id = 1, Code = "C01", Name = "Company I", Users = users },
new Company{ Id = 2, Code = "C03", Name = "Company II", Users = null },
new Company{ Id = 3, Code = "C03", Name = "Company III", Users = users }
};
IList<Branch> branches = new List<Branch>
{
new Branch{Id = 1, CompanyId = 1, Code="B01", Name = "Branch 1.1"},
new Branch{Id = 2, CompanyId = 1, Code="B02", Name = "Branch 1.2"},
new Branch{Id = 3, CompanyId = 1, Code="B03", Name = "Branch 1.3"},
new Branch{Id = 4, CompanyId = 2, Code="B04", Name = "Branch 2.1"},
new Branch{Id = 5, CompanyId = 2, Code="B05", Name = "Branch 2.2"},
};
var payload = new JwtPayload {
{ "companies", companies },
{ "branches", branches }
};
string key = "eyJjb21wYW5pZXMiOlt7IklkIjoxLCJDb2RlIjoiQzAxIiwiTmFtZSI6IkNvbXBhbnkgSSIsIkJyYW5jaGVzIjpudWxsLCJVc2VycyI6W3siSWQiOjEsIk5hbWUiOiJV";
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
var header = new JwtHeader(credentials);
var secToken = new JwtSecurityToken(header, payload);
var handler = new JwtSecurityTokenHandler();
var tokenString = handler.WriteToken(secToken);
Console.WriteLine(secToken);
Console.WriteLine(tokenString);
return tokenString;
}
Output
{
"companies": [
{
"Id": 1,
"Code": "C01",
"Name": "Company I",
"Branches": null,
"Users": [
{
"Id": 1,
"Name": "User One"
},
{
"Id": 2,
"Name": "User Two"
},
{
"Id": 3,
"Name": "User Three"
}
]
},
{
"Id": 2,
"Code": "C03",
"Name": "Company II",
"Branches": null,
"Users": null
},
{
"Id": 3,
"Code": "C03",
"Name": "Company III",
"Branches": null,
"Users": [
{
"Id": 1,
"Name": "User One"
},
{
"Id": 2,
"Name": "User Two"
},
{
"Id": 3,
"Name": "User Three"
}
]
}
],
"branches": [
{
"Id": 1,
"CompanyId": 1,
"Code": "B01",
"Name": "Branch 1.1"
},
{
"Id": 2,
"CompanyId": 1,
"Code": "B02",
"Name": "Branch 1.2"
},
{
"Id": 3,
"CompanyId": 1,
"Code": "B03",
"Name": "Branch 1.3"
},
{
"Id": 4,
"CompanyId": 2,
"Code": "B04",
"Name": "Branch 2.1"
},
{
"Id": 5,
"CompanyId": 2,
"Code": "B05",
"Name": "Branch 2.2"
}
]
}
Token
eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJjb21wYW5pZXMiOlt7IklkIjoxLCJDb2RlIjoiQzAxIiwiTmFtZSI6IkNvbXBhbnkgSSIsIkJyYW5jaGVzIjpudWxsLCJVc2VycyI6W3siSWQiOjEsIk5hbWUiOiJVc2VyIE9uZSJ9LHsiSWQiOjIsIk5hbWUiOiJVc2VyIFR3byJ9LHsiSWQiOjMsIk5hbWUiOiJVc2VyIFRocmVlIn1dfSx7IklkIjoyLCJDb2RlIjoiQzAzIiwiTmFtZSI6IkNvbXBhbnkgSUkiLCJCcmFuY2hlcyI6bnVsbCwiVXNlcnMiOm51bGx9LHsiSWQiOjMsIkNvZGUiOiJDMDMiLCJOYW1lIjoiQ29tcGFueSBJSUkiLCJCcmFuY2hlcyI6bnVsbCwiVXNlcnMiOlt7IklkIjoxLCJOYW1lIjoiVXNlciBPbmUifSx7IklkIjoyLCJOYW1lIjoiVXNlciBUd28ifSx7IklkIjozLCJOYW1lIjoiVXNlciBUaHJlZSJ9XX1dLCJicmFuY2hlcyI6W3siSWQiOjEsIkNvbXBhbnlJZCI6MSwiQ29kZSI6IkIwMSIsIk5hbWUiOiJCcmFuY2ggMS4xIn0seyJJZCI6MiwiQ29tcGFueUlkIjoxLCJDb2RlIjoiQjAyIiwiTmFtZSI6IkJyYW5jaCAxLjIifSx7IklkIjozLCJDb21wYW55SWQiOjEsIkNvZGUiOiJCMDMiLCJOYW1lIjoiQnJhbmNoIDEuMyJ9LHsiSWQiOjQsIkNvbXBhbnlJZCI6MiwiQ29kZSI6IkIwNCIsIk5hbWUiOiJCcmFuY2ggMi4xIn0seyJJZCI6NSwiQ29tcGFueUlkIjoyLCJDb2RlIjoiQjA1IiwiTmFtZSI6IkJyYW5jaCAyLjIifV19.ysjwBa3YeYNmVB0fVEh95wL0zt8Krb-T4VRpWKWIfbU

So the key to this problem is understanding :) Firs what should be noted is the following escape characters .
That basically made me understand that all I need is proper serialization/deserialization of custom array objects.
So I have created the following as base of each scope
Dictionary<string, List<string>> xx3 = new Dictionary<string, List<string>>()
{
{
"s3",new List<string>()
{
"access1" , "access2"
}
}
};
Then simply serialized this object and added as claim
var cos3 = JsonConvert.SerializeObject(xx3, Formatting.Indented);
identity.AddClaim(new Claim("scopes", cos1));
Now what has left as challenge was appropriate authorization on my resources.So I have added customized AuthorizationFilterAttribute
Within there I have deserialized claims using code from here
For those who would be looking for some more of code this is snippet from my custom filter:
// Check if we have scopes
var AllScopes = principal.Claims.Where(p => p.Type == "scopes");
// Check if we have desired scope
foreach (var singlescope in AllScopes)
{
Dictionary<string, List<string>> userscopes = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(singlescope.Value);
if (userscopes.Single(kvp => kvp.Key == ScopeName).Value.Contains(ScopeAccess))
{
//User is Authorized, complete execution
return Task.FromResult<object>(null);
}
}
I hope this will help someone!

Here is how I created my complex token:
var securityKey = new InMemorySymmetricSecurityKey(Encoding.Default.GetBytes("401b09eab3c013d4ca54922bb802bec8fd5318192b0a75f201d8b3727429090fb337591abd3e44453b954555b7a0812e1081c39b740293f765eae731f5a65ed1"));
var signingCredentials = new SigningCredentials(securityKey,
SecurityAlgorithms.HmacSha256Signature,
SecurityAlgorithms.Sha256Digest);
var header = new JwtHeader(signingCredentials);
var payload = new JwtPayload();
payload.AddClaims(claims);
payload.Add("tags", _tags.ToArray()); // this guy accepts object!
var token = new JwtSecurityToken(header, payload);
var tokenString = securityTokenHandler.WriteToken(token);

Related

How to generate treeview using Linq

I have the following three tables,
Region Table,
RegionId
RegionName
1
Admin
2
North Region
3
South Region
Branch Table
BranchId
BranchName
FkRegionId
1
Roswell Rd
3
2
Test
2
3
Piedmont Ave
2
4
Ashford Dunwoody
1
User Table
UserId
FirstName
FkBranchId
1
Hasa
9
2
Jane
1
3
Joyce
7
4
Jane
1
5
John
3
6
Sharon
8
As mentioned above, each branch has its region and each user has a branch. I need to create following JSON for my frond-end usage. Therefore I need to populate data in order to create this JSON.
Region1
Branch1
Jane
Paul
Alex
Branch2
Neil
Kaja
Alex
Region2
Branch4
Ama
Hema
Ira
Branch5
Laura
Tim
Yea
How can I do this using C# and linq?
You need to use Linq Join and GroupBy as following:
var regions = new List<Region>()
{
new Region() { RegionId = 1, RegionName = "Admin" },
new Region() { RegionId = 2, RegionName = "North Region" },
new Region() { RegionId = 3, RegionName = "South Region" }
};
var branchs = new List<Branch>()
{
new Branch() {BranchId = 1, BranchName = "Roswell Rd", FkRegionId = 3},
new Branch() {BranchId = 2, BranchName = "Test", FkRegionId = 2},
new Branch() {BranchId = 3, BranchName = "Piedmont Ave ", FkRegionId = 2},
new Branch() {BranchId = 4, BranchName = "Ashford Dunwoody ", FkRegionId = 1},
};
var users = new List<User>()
{
new User() {UserId = 1, FirstName = "Hasa", FkBranchId = 9},
new User() {UserId = 2, FirstName = "Jane", FkBranchId = 1},
new User() {UserId = 3, FirstName = "Joyce", FkBranchId = 7},
new User() {UserId = 4, FirstName = "Jane", FkBranchId = 1},
new User() {UserId = 5, FirstName = "John", FkBranchId = 3},
new User() {UserId = 6, FirstName = "Sharon", FkBranchId = 8},
};
var tree = from user in users
join branch in branchs on user.FkBranchId equals branch.BranchId
join region in regions on branch.FkRegionId equals region.RegionId
group region by new { region.RegionId, branch.BranchId } into grp
select new
{
RegionName = regions.FirstOrDefault(s => s.RegionId == grp.Key.RegionId).RegionName,
Branchs = new
{
BranchName = branchs.FirstOrDefault(s => s.FkRegionId == grp.Key.RegionId).BranchName,
Users = users.Where(i => i.FkBranchId == grp.Key.BranchId).Select(s => new
{
FirstName = s.FirstName
})
}
};
var json = JsonConvert.SerializeObject(tree, Formatting.Indented);
This will give you an expected result:
[
{
"RegionName": "South Region",
"Branchs": {
"BranchName": "Roswell Rd",
"Users": [
{
"FirstName": "Jane"
},
{
"FirstName": "Jane"
}
]
}
},
{
"RegionName": "North Region",
"Branchs": {
"BranchName": "Test",
"Users": [
{
"FirstName": "John"
}
]
}
}
]
var jsonResponse = "[{\"UserId\":195,\"FirstName\":\"Carlton\",\"BranchId\":4,\"BranchName\":\"Test\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":223,\"FirstName\":\"Lorenza\",\"BranchId\":4,\"BranchName\":\"Test\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":163,\"FirstName\":\"Alice\",\"BranchId\":17,\"BranchName\":\"Ratnapura\",\"RegionId\":1,\"RegionName\":\"Admin\"},{\"UserId\":264,\"FirstName\":\"Karen\",\"BranchId\":7,\"BranchName\":\"Peachtree\",\"RegionId\":3,\"RegionName\":\"South Region\"},{\"UserId\":266,\"FirstName\":\"Starla\",\"BranchId\":7,\"BranchName\":\"Peachtree\",\"RegionId\":3,\"RegionName\":\"South Region\"},{\"UserId\":30,\"FirstName\":\"Jane\",\"BranchId\":9,\"BranchName\":\"Henderson Mill\",\"RegionId\":3,\"RegionName\":\"South Region\"}]";
var myDeserializedClass = JsonConvert.DeserializeObject < List < Root >> (jsonResponse);
var jsonResponseList = myDeserializedClass.GroupBy(item = >item.RegionId).Select(grp = >grp.GroupBy(item = >item.BranchId)).Select(grp = >grp.Select(innerg = >innerg.GroupBy(item = >item.UserId))).ToList();
var serializer = JsonConvert.SerializeObject(jsonResponseList, Formatting.Indented);
Root class
public class Root
{
public int UserId { get; set; }
public string FirstName { get; set; }
public int BranchId { get; set; }
public string BranchName { get; set; }
public int RegionId { get; set; }
public string RegionName { get; set; }
}
and the output:
[
[
[
[
{
"UserId": 195,
"FirstName": "Carlton",
"BranchId": 4,
"BranchName": "Test",
"RegionId": 1,
"RegionName": "Admin"
}
],
[
{
"UserId": 223,
"FirstName": "Lorenza",
"BranchId": 4,
"BranchName": "Test",
"RegionId": 1,
"RegionName": "Admin"
}
]
],
[
[
{
"UserId": 163,
"FirstName": "Alice",
"BranchId": 17,
"BranchName": "Ratnapura",
"RegionId": 1,
"RegionName": "Admin"
}
]
]
],
[
[
[
{
"UserId": 264,
"FirstName": "Karen",
"BranchId": 7,
"BranchName": "Peachtree",
"RegionId": 3,
"RegionName": "South Region"
}
],
[
{
"UserId": 266,
"FirstName": "Starla",
"BranchId": 7,
"BranchName": "Peachtree",
"RegionId": 3,
"RegionName": "South Region"
}
]
],
[
[
{
"UserId": 30,
"FirstName": "Jane",
"BranchId": 9,
"BranchName": "Henderson Mill",
"RegionId": 3,
"RegionName": "South Region"
}
]
]
]
]
If these are physically related tables then EF has taken care of it already. Just make sure your lazy loading is ON or you can eager load data as well by using include and then display data as it is. If you want to eager load information then try this query
using(var db = new DBContext){
var result = db.region.include(x => x.branches).theninclude(x => x.users).toList();
}
result will contain all of your data then bind that data into your custom define DTOs or you can directly bind entity models into views.
Its an overview of the code you can have your own implementation.
If there is no physical relations in between tables then use join using linq here is the link you can follow how joins works in linq.
link

System.Text.Json Serialize multiple objects/array

Could someone help me. I'm having problem serializing multiple elements.
I'm getting this result which has multiple root elements.
[
{
"TITLE": "title1",
"Total EP": 16,
"Current EP": 1,
"URL": "https://www...",
}
]
[
{
"TITLE": "title2",
"Total EP": 16,
"Current EP": 2,
"URL": "https://www...",
}
]
[
{
"TITLE": "title3",
"Total EP": 16,
"Current EP": 3,
"URL": "https://www....",
}
]
How I can make the result like this? I don't want to have multiple objects. instead I want them merge in the same object.
[
{
"TITLE": "title",
"Total EP": 16,
"Current EP": 1,
"URL": "https://www...",
},
{
"TITLE": "title",
"Total EP": 16,
"Current EP": 2,
"URL": "https://www...",
},
{
"TITLE": "title",
"Total EP": 16,
"Current EP": 3,
"URL": "https://www....",
}
]
This is the code I'm using u
var total = root.Get("total")?.GetInt32();
var title = root.Get("title")?.GetString();
foreach (var url in root.Get("response")?.EnumerateArray()) {
var currentEp = url.Get("number")?.GetInt32();
var url = url.Get("url")?.GetString();
var options = new JsonWriterOptions {
Indented = true
};
using (var stream = new MemoryStream()) {
using (var writer = new Utf8JsonWriter(stream, options)) {
writer.WriteStartObject();
writer.WriteString("TITLE", title);
writer.WriteNumber("Total EP", total);
writer.WriteNumber("Current EP", currentEp);
writer.WriteString("URL", url);
writer.WriteEndObject();
}
string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
}
}
Here's the example of json.
{
"pagination":{
"previous":null,
"next":null
},
"total":10,
"title": main title,
"response":[
{
"url":"https.....id1", //URL have different ids
"number":"1",
},
{
"url":"https.....id2",
"number":"2",
},
{
"url":"https.....id3",
"number":"3",
},
{
"url":"https.....id4",
"number":"4",
},
{
"url":"https.....id5",
"number":"5",
},
]
}
Thank you for the help.
Try this code
using (var stream = new MemoryStream())
{
var options = new JsonWriterOptions
{
Indented = true
};
using (var writer = new Utf8JsonWriter(stream, options))
{
writer.WriteStartArray();
for (int i = 0; i < 10; i++)
{
var currentEp = i;
var total = i;
var title = $"title{i}";
var url = $"url:{i}";
writer.WriteStartObject();
writer.WriteString("TITLE", title);
writer.WriteNumber("Total EP", total);
writer.WriteNumber("Current EP", currentEp);
writer.WriteString("URL", url);
writer.WriteEndObject();
}
writer.WriteEndArray();
}
string json2 = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json2);
}

Getting declined (2046: Transaction Refused) from Paypal Sandbox transaction

I'm using Braintree SDK in .NET. Implemented the SDK and followed the documentation.
Created Sandbox Merchant Account
Created Sandbox Personal Account
I'm using the Access Token for the transaction. Please refer the following code snippet:
//--------------------------- Get Token for client ---------------------------
public PaypalHelper.Paypal_ResponseObj<string> GetPaypalClientToken()
{
string PaypalAccessToken = "XXXXXXXXXXXXXXXXXXX";
if (PaypalAccessToken != null)
{
BraintreeGateway gateway = new BraintreeGateway(PaypalAccessToken);
string clientToken = gateway.ClientToken.Generate();
return new PaypalHelper.Paypal_ResponseObj<string>()
{
Code = HttpStatusCode.OK,
Message = "Payment from paypal successfully initiated.",
Response = clientToken
};
}
else
{
return new PaypalHelper.Paypal_ResponseObj<string>()
{
Code = HttpStatusCode.Unauthorized,
Message = "Unauthorized! Paypal access token is not set or invalid.",
Response = null
};
}
}
//--------------------------- Do Paypal transaction ---------------------------
public PaypalHelper.Paypal_ResponseObj<Result<Transaction>> PayPalTransaction(string Nonce, decimal Amount)
{
if (!string.IsNullOrEmpty(Nonce) && !string.IsNullOrWhiteSpace(Nonce) && Amount > 0)
{
string PaypalAccessToken = "XXXXXXXXXXXXXXXXXXX";
if (PaypalAccessToken != null)
{
BraintreeGateway gateway = new BraintreeGateway(PaypalAccessToken);
var request = new TransactionRequest
{
Amount = Amount,
PaymentMethodNonce = Nonce,
Options = new TransactionOptionsRequest
{
SubmitForSettlement = true
}
};
var result = gateway.Transaction.Sale(request);
if (result.IsSuccess())
{
if (result.Errors == null && result.Target != null)
{
return new PaypalHelper.Paypal_ResponseObj<Result<Transaction>>()
{
Code = HttpStatusCode.OK,
Message = "Payment from paypal successfully initiated.",
Response = result
};
}
else
{
return new PaypalHelper.Paypal_ResponseObj<Result<Transaction>>()
{
Code = HttpStatusCode.Conflict,
Message = "Unable to process this request.",
Response = result
};
}
}
else
{
return new PaypalHelper.Paypal_ResponseObj<Result<Transaction>>()
{
Code = HttpStatusCode.Conflict,
Message = "Payment unsuccessfull.",
Response = result
};
}
}
else
{
return new PaypalHelper.Paypal_ResponseObj<Result<Transaction>>()
{
Code = HttpStatusCode.Unauthorized,
Message = "Un authorized! Paypal access token is not set or invalid.",
Response = null
};
}
}
else {
return new PaypalHelper.Paypal_ResponseObj<Result<Transaction>>()
{
Code = HttpStatusCode.BadRequest,
Message = "input can't be null!",
Response = null
};
}
}
Just to summarize all, we have a PayPal business account and we also created a Sandbox business merchant account and Sandbox personal account to test this scenario.
Please refer the following payload being sent to PayPal for the transaction:
{
"CreditCard":null,
"Amount":235.0000,
"DeviceData":null,
"DeviceSessionId":null,
"FraudMerchantId":null,
"Channel":null,
"OrderId":"SWS-O-RQ-894XX",
"Recurring":null,
"TransactionSource":null,
"MerchantAccountId":"USD",
"PurchaseOrderNumber":null,
"Customer":{
"Id":null,
"DeviceData":null,
"CustomerId":null,
"FirstName":"John",
"LastName":"Doe",
"Company":null,
"Email":"johndoe#swsn.com",
"Phone":"330459218319",
"Fax":null,
"Website":null,
"PaymentMethodNonce":null,
"DefaultPaymentMethodToken":null,
"CustomFields":null,
"CreditCard":null,
"UsBankAccount":null,
"RiskData":null,
"Options":null
},
"Descriptor":null,
"Industry":null,
"BillingAddress":null,
"ShippingAddress":{
"FirstName":"John",
"LastName":"Doe",
"Company":null,
"StreetAddress":"XX Boulevard Haussmann",
"ExtendedAddress":null,
"Locality":"Paris",
"Region":null,
"PostalCode":"75008",
"CountryCodeAlpha2":"FR",
"CountryCodeAlpha3":null,
"CountryCodeNumeric":null,
"CountryName":null
},
"PayPalAccount":null,
"TaxAmount":null,
"TaxExempt":null,
"Type":null,
"CustomFields":{
},
"Options":{
"HoldInEscrow":null,
"StoreInVault":null,
"StoreInVaultOnSuccess":null,
"AddBillingAddressToPaymentMethod":null,
"StoreShippingAddressInVault":null,
"SubmitForSettlement":true,
"VenmoSdkSession":null,
"PayeeId":null,
"PayeeEmail":null,
"SkipAdvancedFraudChecking":null,
"SkipAvs":null,
"SkipCvv":null,
"PayPal":null,
"ThreeDSecure":null,
"AmexRewards":null,
"Venmo":null,
"CreditCard":null
},
"ThreeDSecurePassThru":null,
"PaymentMethodToken":null,
"CustomerId":null,
"ShippingAddressId":null,
"BillingAddressId":null,
"VenmoSdkPaymentMethodCode":null,
"PaymentMethodNonce":"799178b2-1e00-0ac7-6db0-034a9a668b1a",
"ServiceFeeAmount":null,
"SharedPaymentMethodToken":null,
"SharedPaymentMethodNonce":null,
"SharedCustomerId":null,
"SharedShippingAddressId":null,
"SharedBillingAddressId":null,
"ThreeDSecureToken":null,
"RiskData":null,
"DiscountAmount":null,
"ShippingAmount":null,
"ShipsFromPostalCode":null,
"LineItems":null,
"ExternalVault":null
}
Please refer the following response object that we are getting from PayPal after initiating a transaction:
{
"CreditCardVerification":null,
"Transaction":{
"Id":"r9b19cwh",
"AddOns":[
],
"Amount":235,
"AvsErrorResponseCode":null,
"AvsPostalCodeResponseCode":"I",
"AvsStreetAddressResponseCode":"I",
"BillingAddress":{
"Id":null,
"CustomerId":null,
"FirstName":null,
"LastName":null,
"Company":null,
"StreetAddress":null,
"ExtendedAddress":null,
"Locality":null,
"Region":null,
"PostalCode":null,
"CountryCodeAlpha2":null,
"CountryCodeAlpha3":null,
"CountryCodeNumeric":null,
"CountryName":null,
"CreatedAt":null,
"UpdatedAt":null
},
"Channel":null,
"CreatedAt":"2020-03-31T19:25:43Z",
"CreditCard":{
"Bin":null,
"CardholderName":null,
"CardType":{
},
"CreatedAt":null,
"CustomerId":null,
"IsDefault":null,
"IsVenmoSdk":false,
"IsExpired":null,
"CustomerLocation":{
},
"LastFour":null,
"UniqueNumberIdentifier":null,
"Subscriptions":[
],
"Token":null,
"UpdatedAt":null,
"BillingAddress":{
"Id":null,
"CustomerId":null,
"FirstName":null,
"LastName":null,
"Company":null,
"StreetAddress":null,
"ExtendedAddress":null,
"Locality":null,
"Region":null,
"PostalCode":null,
"CountryCodeAlpha2":null,
"CountryCodeAlpha3":null,
"CountryCodeNumeric":null,
"CountryName":null,
"CreatedAt":null,
"UpdatedAt":null
},
"ExpirationMonth":null,
"ExpirationYear":null,
"Prepaid":{
},
"Payroll":{
},
"Debit":{
},
"Commercial":{
},
"Healthcare":{
},
"DurbinRegulated":{
},
"ImageUrl":"https://assets.braintreegateway.com/payment_method_logo/unknown.png?environment=sandbox",
"Verification":null,
"AccountType":null,
"CountryOfIssuance":"Unknown",
"IssuingBank":"Unknown",
"ProductId":"Unknown",
"ExpirationDate":"/",
"MaskedNumber":"**"
},
"CurrencyIsoCode":"USD",
"CustomerDetails":{
"Id":null,
"FirstName":"John",
"LastName":"Doe",
"Company":null,
"Email":"johndoe#swsln.com",
"Phone":"000459210000",
"Fax":null,
"Website":null
},
"CvvResponseCode":"I",
"Descriptor":{
"Name":null,
"Phone":null,
"Url":null
},
"Discounts":[
],
"Disputes":[
],
"GatewayRejectionReason":{
},
"MerchantAccountId":"USD",
"OrderId":"SWS-O-RQ-894XX",
"PlanId":null,
"ProcessorAuthorizationCode":null,
"ProcessorResponseType":{
},
"ProcessorResponseCode":"2046",
"ProcessorResponseText":"Declined",
"ProcessorSettlementResponseCode":null,
"ProcessorSettlementResponseText":null,
"AdditionalProcessorResponse":"2046 : TRANSACTION_REFUSED",
"VoiceReferralNumber":null,
"PurchaseOrderNumber":null,
"Recurring":false,
"RefundedTransactionId":null,
"RefundIds":[
],
"PartialSettlementTransactionIds":[
],
"AuthorizedTransactionId":null,
"SettlementBatchId":null,
"ShippingAddress":{
"Id":null,
"CustomerId":null,
"FirstName":"John",
"LastName":"Doe",
"Company":null,
"StreetAddress":"XX Boulevard XXXX",
"ExtendedAddress":null,
"Locality":"Paris",
"Region":null,
"PostalCode":"75008",
"CountryCodeAlpha2":"FR",
"CountryCodeAlpha3":"FRA",
"CountryCodeNumeric":"250",
"CountryName":"France",
"CreatedAt":null,
"UpdatedAt":null
},
"EscrowStatus":{
},
"Status":{
},
"StatusHistory":[
{
"Amount":235,
"Status":{
},
"Timestamp":"2020-03-31T19:25:48Z",
"Source":{
},
"User":null
}
],
"AuthorizationAdjustments":[
],
"SubscriptionId":null,
"SubscriptionDetails":{
"BillingPeriodEndDate":null,
"BillingPeriodStartDate":null
},
"TaxAmount":null,
"TaxExempt":false,
"Type":{
},
"UpdatedAt":"2020-03-31T19:25:48Z",
"CustomFields":{
},
"ServiceFeeAmount":null,
"DisbursementDetails":{
"SettlementAmount":null,
"SettlementCurrencyIsoCode":null,
"SettlementCurrencyExchangeRate":null,
"FundsHeld":null,
"Success":null,
"DisbursementDate":null
},
"ApplePayDetails":null,
"AndroidPayDetails":null,
"AmexExpressCheckoutDetails":null,
"PayPalDetails":{
"PayerEmail":"sb-zkd0t1338940#personal.example.com",
"PaymentId":null,
"AuthorizationId":null,
"Token":null,
"ImageUrl":"https://assets.braintreegateway.com/payment_method_logo/paypal.png?environment=sandbox",
"DebugId":"20ac958b09914",
"PayeeId":null,
"PayeeEmail":null,
"CustomField":null,
"PayerId":null,
"PayerFirstName":null,
"PayerLastName":null,
"PayerStatus":null,
"SellerProtectionStatus":null,
"CaptureId":null,
"RefundId":null,
"TransactionFeeAmount":null,
"TransactionFeeCurrencyIsoCode":null,
"RefundFromTransactionFeeAmount":null,
"RefundFromTransactionFeeCurrencyIsoCode":null,
"Description":null
},
"LocalPaymentDetails":null,
"CoinbaseDetails":null,
"VenmoAccountDetails":null,
"UsBankAccountDetails":null,
"IdealPaymentDetails":null,
"VisaCheckoutCardDetails":null,
"MasterpassCardDetails":null,
"SamsungPayCardDetails":null,
"PaymentInstrumentType":{
},
"RiskData":null,
"ThreeDSecureInfo":null,
"FacilitatedDetails":null,
"FacilitatorDetails":null,
"DiscountAmount":null,
"ShippingAmount":null,
"ShipsFromPostalCode":null,
"NetworkTransactionId":null,
"AuthorizationExpiresAt":null
},
"Subscription":null,
"Errors":{
"Count":0,
"DeepCount":0
},
"Parameters":{
"transaction[amount]":"235.00",
"transaction[order_id]":"SWS-O-RQ-894XX",
"transaction[payment_method_nonce]":"799178b2-1e00-0ac7-6db0-034a9a668bXX",
"transaction[merchant_account_id]":"USD",
"transaction[type]":"sale",
"transaction[customer][first_name]":"John",
"transaction[customer][last_name]":"Doe",
"transaction[customer][email]":"johndoe#swsln.com",
"transaction[customer][phone]":"330459218319",
"transaction[shipping][first_name]":"John",
"transaction[shipping][last_name]":"Doe",
"transaction[shipping][street_address]":"63 Boulevard Haussmann",
"transaction[shipping][locality]":"Paris",
"transaction[shipping][postal_code]":"75008",
"transaction[shipping][country_code_alpha2]":"FR",
"transaction[options][submit_for_settlement]":"true"
},
"Message":"Declined",
"Target":null
}
Anyone? who can help me to figure out this issue. Is there something I'm missing?

Create private message for each signer

According to the DocuSign Documentation, it is possible to send an envelope where each signer in the envelope receives a "Private Message". I have reviewed the DocuSign REST API documentation and was unable to find any reference to a private message, or details on how to create one.
Could someone provide details on the REST API implementation of the "private message" feature? Additionally an example the DocuSign .Net SDK would be great.
You can specify the emailNotification property for each recipient. Documentation here
Here is a sample createEnvelope request.
POST /v2/accounts/{accountId}/envelopes
{
"status": "sent",
"recipients": {
"signers": [
{
"email": "janedoe#acme.com",
"name": "jane doe",
"recipientId": 1,
"emailNotification": {
"emailSubject": "Please sign the document(s) (jane doe)",
"emailBody": "Hello Jane Doe,\r\n\r\nYour have a new document to view and sign. Please click on the View Documents link below, review the content, and sign the document. ",
"supportedLanguage": "en"
},
"tabs": {"signHereTabs": [ { "documentId": "1", "pageNumber": "1", "xPosition": "80", "yPosition": "80"}]}
},
{
"email": "johnsmith#acme.com",
"name": "john smith",
"recipientId": 2,
"emailNotification": {
"emailSubject": "Please sign the document(s) (john smith)",
"emailBody": "Hello john smith,\r\n\r\nYour have a new document to view and sign. Please click on the View Documents link below, review the content, and sign the document. ",
"supportedLanguage": "en"
},
"tabs": {"signHereTabs": [ { "documentId": "1", "pageNumber": "1", "xPosition": "80", "yPosition": "180"}]}
}
]
},
"documents": [
{
"documentId": "1", "name": "Contract", "fileExtension": "txt", "documentBase64": "RG9jIFRXTyBUV08gVFdP"
}
]
}
Using the C# SDK
Complete code here
public void CreateEnvelopeSeparateEmailNotificationForRecipients()
{
string accountID = Init();
byte[] fileBytes = System.IO.File.ReadAllBytes(#"C:\temp\test.pdf");
var envDef = new EnvelopeDefinition()
{
Status = "sent",
Recipients = new Recipients()
{
Signers = new List<Signer>()
{
new Signer()
{
Email = "janedoe#acme.com",
Name = "jane doe",
RecipientId = "1",
RoutingOrder = "1",
EmailNotification = new RecipientEmailNotification()
{
EmailSubject = "Please sign the document(s) (jane doe)",
EmailBody = "This is email body for Jane Doe"
},
Tabs = new Tabs() { SignHereTabs = new List<SignHere>(){ new SignHere() { DocumentId = "1", XPosition = "100",YPosition = "300", PageNumber = "1" } } }
},
new Signer()
{
Email = "johnsmith#acme.com",
Name = "JohnSmith",
RecipientId = "2",
RoutingOrder = "1",
EmailNotification = new RecipientEmailNotification()
{
EmailSubject = "Please sign the document(s) (John Smith)",
EmailBody = "This is email body for John Smith"
},
Tabs = new Tabs() { SignHereTabs = new List<SignHere>(){ new SignHere() { DocumentId = "1", XPosition = "200",YPosition = "300", PageNumber = "1" } } }
}
}
},
Documents = new List<Document>()
{
new Document()
{
DocumentBase64 = System.Convert.ToBase64String(fileBytes),
Name = "Contract",
DocumentId = "1"
}
}
};
EnvelopesApi envelopesApi = new EnvelopesApi();
EnvelopeSummary envelopeSummary = envelopesApi.CreateEnvelope(accountID, envDef);
}

Creating JSON out of string

I want to get JSON similar to this
{
"Name": "xxxxx",
"ApplicationId": "xxxxx",
"Features": [
{
"Name": "xxxxx",
"Code": "xxxxx",
}
]
}
and my code is so far is
var json = JsonConvert.SerializeObject(
new {
Name = name ,
ApplicationId = applicationID ,
Features = (new[]{feature_name , feature_code})
}, Formatting.None);
I can not figure out the feature part, it won't get created as in the example.
I read so many post, but did not find anything about inner objects.
You didn't give the features appropriate names, hence then variable names are used.
Use this instead:
new[] { new { Name = feature_name, Code = feature_code } }
Also, you have to supply a list of features, for example using LINQ.
features.Select(f => new { Name = f.feature_name, Code = f.feature_code })
Another way of doing this can be like:
var createJson = new {
Name = "xxxxx",
ApplicationId = "xxxxx",
Features = new[] {
new { Name = "xxxxx", Code = "xxxxx" },
new { Name = "xxxxx", Code = "xxxxx" }
}
};
var json = JsonConvert.SerializeObject(createjson, Formatting.Indented);

Categories

Resources