Skip to content

Commit

Permalink
- Payouts new functionality added (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Buedo authored Apr 19, 2021
1 parent 7e2aa92 commit 6ac691d
Show file tree
Hide file tree
Showing 12 changed files with 500 additions and 28 deletions.
160 changes: 156 additions & 4 deletions BitPay/BitPay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,158 @@ public async Task<List<Ledger>> GetLedgers()
}
}

/**
* Submit BitPay Payout Recipients.
*
* @param recipients PayoutRecipients A PayoutRecipients object with request parameters defined.
* @return array A list of BitPay PayoutRecipients objects..
* @throws BitPayException BitPayException class
* @throws PayoutCreationException PayoutCreationException class
*/
public async Task<List<PayoutRecipient>> SubmitPayoutRecipients(PayoutRecipients recipients)
{
try
{
recipients.Token = GetAccessToken(Facade.Payroll);
recipients.Guid = Guid.NewGuid().ToString();
var json = JsonConvert.SerializeObject(recipients);
var response = await Post("recipients", json, true);

var responseString = await ResponseToJsonString(response);
return JsonConvert.DeserializeObject<List<PayoutRecipient>>(responseString,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
}
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new PayoutCreationException(ex);

throw;
}
}

/**
* Retrieve a collection of BitPay Payout Recipients.
*
* @param $status string|null The recipient status you want to query on.
* @param $limit int|null Maximum results that the query will return (useful for paging results).
* result).
* @return array A list of BitPayRecipient objects.
* @throws BitPayException BitPayException class
*/
public async Task<List<PayoutRecipient>> GetPayoutRecipients(string status = null, int limit = 100)
{
try
{
var parameters = InitParams();
if (!string.IsNullOrEmpty(status))
{
parameters.Add("status", status);
}
parameters.Add("limit", limit.ToString());

parameters.Add("token", GetAccessToken(Facade.Payroll));
var response = await Get("recipients", parameters);
var responseString = await ResponseToJsonString(response);
return JsonConvert.DeserializeObject<List<PayoutRecipient>>(responseString,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
}
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new PayoutQueryException();

throw;
}
}

/**
* Retrieve a BitPay payout recipient by batch id using. The client must have been previously authorized for the
* payroll facade.
*
* @param $recipientId string The id of the recipient to retrieve.
* @return PayoutRecipient A BitPay PayoutRecipient object.
* @throws PayoutQueryException BitPayException class
*/
public async Task<PayoutRecipient> GetPayoutRecipient(string batchId)
{
try
{
Dictionary<string, string> parameters;
try
{
parameters = new Dictionary<string, string> {{"token", GetAccessToken(Facade.Payroll)}};
}
catch (BitPayException)
{
// No token for batch.
parameters = null;
}

var response = await Get("recipients/" + batchId, parameters);
var responseString = await ResponseToJsonString(response);
return JsonConvert.DeserializeObject<PayoutRecipient>(responseString,
new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore
});
}
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new PayoutQueryException(ex);

throw;
}
}

/**
* Cancel a BitPay Payout recipient.
*
* @param $recipientId string The id of the recipient to cancel.
* @return PayoutRecipient A BitPay generated PayoutRecipient object.
* @throws PayoutCancellationException BitPayException class
*/
public async Task<bool> DeletePayoutRecipient(string batchId)
{
try
{
bool result;
var b = await GetPayoutRecipient(batchId);

Dictionary<string, string> parameters;
try
{
parameters = new Dictionary<string, string> {{"token", GetAccessToken(Facade.Payroll)}};
}
catch (BitPayException)
{
// No token for batch.
parameters = null;
}

var response = await Delete("recipients/" + batchId, parameters);
var responseString = await ResponseToJsonString(response);
JObject responseObject = JsonConvert.DeserializeObject<dynamic>(responseString);
bool.TryParse(responseObject.GetValue("success").ToString(), out result);

return result;
}
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new PayoutCancellationException();

throw;
}
}

/// <summary>
/// Submit a BitPay Payout batch.
/// </summary>
Expand Down Expand Up @@ -744,7 +896,7 @@ public async Task<PayoutBatch> SubmitPayoutBatch(PayoutBatch batch)
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new BatchException(ex);
throw new PayoutCreationException(ex);

throw;
}
Expand Down Expand Up @@ -777,7 +929,7 @@ public async Task<List<PayoutBatch>> GetPayoutBatches(string status = null)
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new BatchException(ex);
throw new PayoutQueryException();

throw;
}
Expand Down Expand Up @@ -815,7 +967,7 @@ public async Task<PayoutBatch> GetPayoutBatch(string batchId)
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new BatchException(ex);
throw new PayoutQueryException(ex);

throw;
}
Expand Down Expand Up @@ -854,7 +1006,7 @@ public async Task<PayoutBatch> CancelPayoutBatch(string batchId)
catch (Exception ex)
{
if (!(ex.GetType().IsSubclassOf(typeof(BitPayException)) || ex.GetType() == typeof(BitPayException)))
throw new BatchException(ex);
throw new PayoutCancellationException();

throw;
}
Expand Down
18 changes: 18 additions & 0 deletions BitPay/Exceptions/PayoutCancellationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace BitPaySDK.Exceptions
{
public class PayoutCancellationException : BitPayException
{
private const string BitPayCode = "BITPAY-PAYOUT-DELETE";
private const string BitPayMessage = "Failed to create payout batch";

public PayoutCancellationException() : base(BitPayCode, BitPayMessage)
{
}

public PayoutCancellationException(Exception ex) : base(BitPayCode, BitPayMessage, ex)
{
}
}
}
18 changes: 18 additions & 0 deletions BitPay/Exceptions/PayoutCreationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace BitPaySDK.Exceptions
{
public class PayoutCreationException : BitPayException
{
private const string BitPayCode = "BITPAY-PAYOUT-CREATE";
private const string BitPayMessage = "Failed to create payout batch";

public PayoutCreationException() : base(BitPayCode, BitPayMessage)
{
}

public PayoutCreationException(Exception ex) : base(BitPayCode, BitPayMessage, ex)
{
}
}
}
28 changes: 28 additions & 0 deletions BitPay/Exceptions/PayoutException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;

namespace BitPaySDK.Exceptions
{
public class PayoutException : BitPayException
{
private const string BitPayMessage = "An unexpected error occured while trying to manage the payout batch";
private readonly string _bitpayCode = "BITPAY-PAYOUT-GENERIC";

public PayoutException() : base(BitPayMessage)
{
BitpayCode = _bitpayCode;
}

public PayoutException(Exception ex) : base(BitPayMessage, ex)
{
BitpayCode = _bitpayCode;
}

public PayoutException(string bitpayCode, string message) : base(bitpayCode, message)
{
}

public PayoutException(string bitpayCode, string message, Exception cause) : base(bitpayCode, message, cause)
{
}
}
}
18 changes: 18 additions & 0 deletions BitPay/Exceptions/PayoutQueryException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;

namespace BitPaySDK.Exceptions
{
public class PayoutQueryException : BitPayException
{
private const string BitPayCode = "BITPAY-PAYOUT-GET";
private const string BitPayMessage = "Failed to create payout batch";

public PayoutQueryException() : base(BitPayCode, BitPayMessage)
{
}

public PayoutQueryException(Exception ex) : base(BitPayCode, BitPayMessage, ex)
{
}
}
}
18 changes: 11 additions & 7 deletions BitPay/KeyUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,17 @@ public static EcKey CreateEcKeyFromHexStringFile(string privKeyFile)

public static async Task<EcKey> LoadEcKey()
{
using (var fs = File.OpenRead(PrivateKeyFile))
{
var b = new byte[1024];
await fs.ReadAsync(b, 0, b.Length);
var key = EcKey.FromAsn1(b);
return key;
}
// using (var fs = File.OpenRead(PrivateKeyFile))
// {
// var b = new byte[1024];
// await fs.ReadAsync(b, 0, b.Length);
// var key = EcKey.FromAsn1(b);
// return key;
// }

byte[] file = System.IO.File.ReadAllBytes(PrivateKeyFile);
var key = EcKey.FromAsn1(file);
return key;
}

public static string GetKeyStringFromFile(string filename)
Expand Down
Loading

0 comments on commit 6ac691d

Please sign in to comment.