Skip to content

Commit

Permalink
[MSUE-43] [MSUE-123] - Verification API Endpoints Integration + Merch…
Browse files Browse the repository at this point in the history
…ant API (#22)

* Verification API Endpoints Integration
* Webhook Validation Implementation
* Merchants API Integration
  • Loading branch information
vineethKExalture authored Nov 18, 2022
1 parent 94b9456 commit d366091
Show file tree
Hide file tree
Showing 10 changed files with 1,100 additions and 4 deletions.
34 changes: 34 additions & 0 deletions Sift/Core/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,40 @@ public async Task<WorkflowStatusResponse> SendAsync(WorkflowStatusRequest workfl
{
return await SendAsync<WorkflowStatusResponse>(workflowStatusRequest);
}
public async Task<VerificationCheckResponse> SendAsync(VerificationCheckRequest verificationCheckRequest)
{
return await SendAsync<VerificationCheckResponse>(verificationCheckRequest);
}

public async Task<VerificationSendResponse> SendAsync(VerificationSendRequest verificationSendRequest)
{
return await SendAsync<VerificationSendResponse>(verificationSendRequest);
}

public async Task<VerificationReSendResponse> SendAsync(VerificationReSendRequest verificationReSendRequest)
{
return await SendAsync<VerificationReSendResponse>(verificationReSendRequest);
}

public async Task<GetMerchantsResponse> SendAsync(GetMerchantsRequest getMerchantRequest)
{
return await SendAsync<GetMerchantsResponse>(getMerchantRequest);
}

public async Task<CreateMerchantResponse> SendAsync(CreateMerchantRequest createMerchantRequest)
{
return await SendAsync<CreateMerchantResponse>(createMerchantRequest);
}

public async Task<UpdateMerchantResponse> SendAsync(UpdateMerchantRequest updateMerchantRequest)
{
return await SendAsync<UpdateMerchantResponse>(updateMerchantRequest);
}

public async Task<GetMerchantDetailsResponse> SendAsync(GetMerchantDetailsRequest getMerchantRequest)
{
return await SendAsync<GetMerchantDetailsResponse>(getMerchantRequest);
}

async Task<T> SendAsync<T>(SiftRequest siftRequest) where T : SiftResponse
{
Expand Down
61 changes: 61 additions & 0 deletions Sift/Core/WebhookValidator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace Sift.Core
{
public class WebhookValidator
{
private const string Sha1Prefix = "sha1=";

public bool IsValidWebhook(string payload, string secretKey, string signatureWithPrefix)
{
if (string.IsNullOrWhiteSpace(payload))
{
throw new ArgumentNullException(nameof(payload));
}
if (string.IsNullOrWhiteSpace(secretKey))
{
throw new ArgumentNullException(nameof(secretKey));
}
if (string.IsNullOrWhiteSpace(signatureWithPrefix))
{
throw new ArgumentNullException(nameof(signatureWithPrefix));
}

if (signatureWithPrefix.StartsWith(Sha1Prefix, StringComparison.OrdinalIgnoreCase))
{
var signature = signatureWithPrefix.Substring(Sha1Prefix.Length);
var secret = Encoding.ASCII.GetBytes(secretKey);
var payloadBytes = Encoding.ASCII.GetBytes(payload);

using (var hmSha1 = new HMACSHA1(secret))
{
var hash = hmSha1.ComputeHash(payloadBytes);

var hashString = ToHexString(hash);

if (hashString.Equals(signature))
{
return true;
}
}
}

return false;
}


public static string ToHexString(byte[] bytes)
{
var builder = new StringBuilder(bytes.Length * 2);
foreach (byte b in bytes)
{
builder.AppendFormat("{0:x2}", b);
}

return builder.ToString();
}
}
}
83 changes: 83 additions & 0 deletions Sift/Request/GetMerchantsRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

namespace Sift
{
public class GetMerchantsRequest : SiftRequest
{
static readonly String GetMerchantsUrl = @"https://api.sift.com/v3/accounts/{0}/psp_management/merchants";

public string AccountId { get; set; }
public string BatchToken { get; set; }
public int? BatchSize { get; set; }


public override HttpRequestMessage Request
{
get
{
var request = new HttpRequestMessage(HttpMethod.Get, Url);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes(ApiKey)));
return request;
}
}

protected override Uri Url
{
get
{
var url = new Uri(String.Format(GetMerchantsUrl,
Uri.EscapeDataString(AccountId)));


if (!String.IsNullOrEmpty(BatchToken))
{
url = url.AddQuery("batch_token", BatchToken);
}

if (BatchSize.HasValue)
{
url = url.AddQuery("limit", BatchSize.Value.ToString());
}


return url;
}
}

}

public class GetMerchantDetailsRequest : SiftRequest
{
static readonly String GetMerchantsUrl = @"https://api.sift.com/v3/accounts/{0}/psp_management/merchants/{1}";

public string AccountId { get; set; }
public string MerchantId { get; set; }

public override HttpRequestMessage Request
{
get
{
var request = new HttpRequestMessage(HttpMethod.Get, Url);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes(ApiKey)));
return request;
}
}

protected override Uri Url
{
get
{
var url = new Uri(String.Format(GetMerchantsUrl,
Uri.EscapeDataString(AccountId),
Uri.EscapeDataString(MerchantId)));
return url;
}
}

}

}
163 changes: 163 additions & 0 deletions Sift/Request/MerchantRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

namespace Sift
{
public class CreateMerchantRequest : SiftRequest
{
static readonly String CreateMerchantUrl = @"https://api.sift.com/v3/accounts/{0}/psp_management/merchants";

[JsonIgnore]
public string AccountId { get; set; }

[JsonIgnore]
public override string ApiKey { get; set; }

[JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
public string Id { get; set; }

[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }

[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }

[JsonProperty("address")]
public MerchantAddress Address { get; set; }

[JsonProperty("category", NullValueHandling = NullValueHandling.Ignore)]
public string Category { get; set; }

[JsonProperty("service_level", NullValueHandling = NullValueHandling.Ignore)]
public string ServiceLevel { get; set; }

[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
public string Status { get; set; }

[JsonProperty("risk_profile")]
public MerchantRiskProfile RiskProfile { get; set; }

[JsonIgnore]
public override HttpRequestMessage Request
{
get
{
var request = new HttpRequestMessage(HttpMethod.Post, Url);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes(ApiKey)));
request.Content = new StringContent(JsonConvert.SerializeObject(this), Encoding.UTF8, "application/json");
return request;
}
}

[JsonIgnore]
protected override Uri Url
{
get
{
return new Uri(String.Format(CreateMerchantUrl,
Uri.EscapeDataString(AccountId)));
}
}
}

public class UpdateMerchantRequest : SiftRequest
{
static readonly String UpdateMerchantUrl = @"https://api.sift.com/v3/accounts/{0}/psp_management/merchants/{1}";

[JsonIgnore]
public string AccountId { get; set; }

[JsonIgnore]
public string MerchantId { get; set; }

[JsonIgnore]
public override string ApiKey { get; set; }

[JsonProperty("id")]
public string Id { get; set; }

[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }

[JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)]
public string Description { get; set; }

[JsonProperty("address")]
public MerchantAddress Address { get; set; }

[JsonProperty("category", NullValueHandling = NullValueHandling.Ignore)]
public string Category { get; set; }

[JsonProperty("service_level", NullValueHandling = NullValueHandling.Ignore)]
public string ServiceLevel { get; set; }

[JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)]
public string Status { get; set; }

[JsonProperty("risk_profile")]
public MerchantRiskProfile RiskProfile { get; set; }

[JsonIgnore]
public override HttpRequestMessage Request
{
get
{
var request = new HttpRequestMessage(HttpMethod.Put, Url);
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.Default.GetBytes(ApiKey)));
request.Content = new StringContent(JsonConvert.SerializeObject(this), Encoding.UTF8, "application/json");
return request;
}
}

[JsonIgnore]
protected override Uri Url
{
get
{
return new Uri(String.Format(UpdateMerchantUrl,
Uri.EscapeDataString(AccountId),
Uri.EscapeDataString(MerchantId)));
}
}
}

public class MerchantAddress
{
[JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)]
public string Name { get; set; }

[JsonProperty("address_1", NullValueHandling = NullValueHandling.Ignore)]
public string Address1 { get; set; }

[JsonProperty("address_2", NullValueHandling = NullValueHandling.Ignore)]
public string Address2 { get; set; }

[JsonProperty("city", NullValueHandling = NullValueHandling.Ignore)]
public string City { get; set; }

[JsonProperty("region", NullValueHandling = NullValueHandling.Ignore)]
public string Region { get; set; }

[JsonProperty("country", NullValueHandling = NullValueHandling.Ignore)]
public string Country { get; set; }

[JsonProperty("zipcode", NullValueHandling = NullValueHandling.Ignore)]
public string ZipCode { get; set; }

[JsonProperty("phone", NullValueHandling = NullValueHandling.Ignore)]
public string Phone { get; set; }
}

public class MerchantRiskProfile
{
[JsonProperty("level", NullValueHandling = NullValueHandling.Ignore)]
public string Level { get; set; }

[JsonProperty("score", NullValueHandling = NullValueHandling.Ignore)]
public int Score { get; set; }
}
}
Loading

0 comments on commit d366091

Please sign in to comment.