Skip to content

Commit

Permalink
3.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
braintreeps committed Jan 23, 2017
1 parent 24eeb6c commit 5fafadf
Show file tree
Hide file tree
Showing 22 changed files with 216 additions and 43 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,8 @@
## 3.5.0
* Stop sending account_description field from us bank accounts
* Add multi-currency support for OAuth Onboarded Merchants
* Add functionality to list all merchant accounts for a merchant with `MerchantAccount.all`

## 3.4.0
* Add payer_status accessor to paypal_details object
* Add option `skip_advanced_fraud_check` for transaction flows
Expand Down
2 changes: 1 addition & 1 deletion README.md
@@ -1,4 +1,4 @@
# Braintree .NET Client Library
# Braintree .NET Server Library

The Braintree assembly provides integration access to the Braintree Gateway.

Expand Down
21 changes: 21 additions & 0 deletions src/Braintree/AchMandate.cs
@@ -0,0 +1,21 @@
using System;

namespace Braintree
{
public class AchMandate
{
public virtual string Text { get; protected set; }
public virtual DateTime? AcceptedAt { get; protected set; }

protected internal AchMandate(NodeWrapper node)
{
if (node == null) return;

Text = node.GetString("text");
AcceptedAt = node.GetDateTime("accepted-at");
}

[Obsolete("Mock Use Only")]
protected AchMandate() { }
}
}
5 changes: 4 additions & 1 deletion src/Braintree/Braintree.xproj
Expand Up @@ -9,7 +9,7 @@
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Braintree</RootNamespace>
<AssemblyName>Braintree-3.4.0</AssemblyName>
<AssemblyName>Braintree-3.5.0</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
Expand Down Expand Up @@ -50,6 +50,7 @@
-->
<ItemGroup>
<Compile Include="AccountUpdaterDailyReport.cs" />
<Compile Include="AchMandate.cs" />
<Compile Include="AddAddOnRequest.cs" />
<Compile Include="AddDiscountRequest.cs" />
<Compile Include="AddModificationRequest.cs" />
Expand Down Expand Up @@ -163,6 +164,8 @@
<Compile Include="OAuthGateway.cs" />
<Compile Include="OAuthResult.cs" />
<Compile Include="OAuthRevokeAccessTokenRequest.cs" />
<Compile Include="PaginatedCollection.cs" />
<Compile Include="PaginatedResult.cs" />
<Compile Include="PartnerMerchant.cs" />
<Compile Include="PartialMatchNode.cs" />
<Compile Include="PaymentMethod.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/Braintree/IMerchantAccountGateway.cs
Expand Up @@ -8,5 +8,6 @@ public interface IMerchantAccountGateway
Result<MerchantAccount> CreateForCurrency(MerchantAccountCreateForCurrencyRequest request);
MerchantAccount Find(string id);
Result<MerchantAccount> Update(string id, MerchantAccountRequest request);
PaginatedCollection<MerchantAccount> All();
}
}
22 changes: 22 additions & 0 deletions src/Braintree/MerchantAccountGateway.cs
@@ -1,4 +1,5 @@
using Braintree.Exceptions;
using System.Collections.Generic;
using System.Xml;

namespace Braintree
Expand Down Expand Up @@ -47,5 +48,26 @@ public virtual MerchantAccount Find(string id)

return new MerchantAccount(new NodeWrapper(merchantAccountXML));
}

public virtual PaginatedCollection<MerchantAccount> All()
{
return new PaginatedCollection<MerchantAccount>(FetchMerchantAccounts);
}

private PaginatedResult<MerchantAccount> FetchMerchantAccounts(int page)
{
XmlNode merchantAccountXML = service.Get(service.MerchantPath() + "/merchant_accounts?page=" + page);
var nodeWrapper = new NodeWrapper(merchantAccountXML);

var totalItems = nodeWrapper.GetInteger("total-items").Value;
var pageSize = nodeWrapper.GetInteger("page-size").Value;
var merchantAccounts = new List<MerchantAccount>();
foreach (var node in nodeWrapper.GetList("merchant-account"))
{
merchantAccounts.Add(new MerchantAccount(node));
}

return new PaginatedResult<MerchantAccount>(totalItems, pageSize, merchantAccounts);
}
}
}
47 changes: 47 additions & 0 deletions src/Braintree/PaginatedCollection.cs
@@ -0,0 +1,47 @@
using System.Collections.Generic;

namespace Braintree
{
public class PaginatedCollection<T> : IEnumerable<T> where T : class
{
public int Size { get { return TotalItems; } }

private int PageSize = 0;
private int CurrentPage = 0;
private int Index = 0;
private int TotalItems = 0;
private List<T> Items = new List<T>();
private System.Func<int, PaginatedResult<T>> Pager;

public PaginatedCollection(System.Func<int, PaginatedResult<T>> pager)
{
Pager = pager;
}

public IEnumerator<T> GetEnumerator()
{
do
{
if (CurrentPage == 0 || Index % PageSize == 0)
{
CurrentPage++;
var results = Pager(CurrentPage);
TotalItems = results.TotalItems;
PageSize = results.PageSize;
Items = results.Items;
}

foreach (T item in Items)
{
Index++;
yield return item;
}
} while(Index < TotalItems);
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
18 changes: 18 additions & 0 deletions src/Braintree/PaginatedResult.cs
@@ -0,0 +1,18 @@
using System.Collections.Generic;

namespace Braintree
{
public class PaginatedResult<T> where T : class
{
public int TotalItems { get; private set; }
public int PageSize { get; private set; }
public List<T> Items { get; private set; }

public PaginatedResult(int totalItems, int pageSize, List<T> items)
{
TotalItems = totalItems;
PageSize = pageSize;
Items = items;
}
}
}
15 changes: 11 additions & 4 deletions src/Braintree/TransactionGateway.cs
Expand Up @@ -204,12 +204,19 @@ private List<Transaction> FetchTransactions(TransactionSearchRequest query, stri

var response = new NodeWrapper(service.Post(service.MerchantPath() + "/transactions/advanced_search", query));

var transactions = new List<Transaction>();
foreach (var node in response.GetList("transaction"))
if (response.GetName() == "credit-card-transactions")
{
transactions.Add(new Transaction(node, gateway));
var transactions = new List<Transaction>();
foreach (var node in response.GetList("transaction"))
{
transactions.Add(new Transaction(node, gateway));
}
return transactions;
}
else
{
throw new DownForMaintenanceException();
}
return transactions;
}
}
}
4 changes: 2 additions & 2 deletions src/Braintree/UsBankAccount.cs
Expand Up @@ -7,25 +7,25 @@ public class UsBankAccount : PaymentMethod
public virtual string RoutingNumber { get; protected set; }
public virtual string Last4 { get; protected set; }
public virtual string AccountType { get; protected set; }
public virtual string AccountDescription { get; protected set; }
public virtual string AccountHolderName { get; protected set; }
public virtual string Token { get; protected set; }
public virtual string ImageUrl { get; protected set; }
public virtual string BankName { get; protected set; }
public virtual string CustomerId { get; protected set; }
public virtual AchMandate AchMandate { get; protected set; }
public virtual bool? IsDefault { get; protected set; }

protected internal UsBankAccount(NodeWrapper node)
{
RoutingNumber = node.GetString("routing-number");
Last4 = node.GetString("last-4");
AccountType = node.GetString("account-type");
AccountDescription = node.GetString("account-description");
AccountHolderName = node.GetString("account-holder-name");
Token = node.GetString("token");
ImageUrl = node.GetString("image-url");
BankName = node.GetString("bank-name");
CustomerId = node.GetString("customer-id");
AchMandate = new AchMandate(node.GetNode("ach-mandate"));
IsDefault = node.GetBoolean("default");
}

Expand Down
4 changes: 2 additions & 2 deletions src/Braintree/UsBankAccountDetails.cs
Expand Up @@ -5,22 +5,22 @@ public class UsBankAccountDetails
public virtual string RoutingNumber { get; protected set; }
public virtual string Last4 { get; protected set; }
public virtual string AccountType { get; protected set; }
public virtual string AccountDescription { get; protected set; }
public virtual string AccountHolderName { get; protected set; }
public virtual string Token { get; protected set; }
public virtual string ImageUrl { get; protected set; }
public virtual string BankName { get; protected set; }
public virtual AchMandate AchMandate { get; protected set; }

protected internal UsBankAccountDetails(NodeWrapper node)
{
RoutingNumber = node.GetString("routing-number");
Last4 = node.GetString("last-4");
AccountType = node.GetString("account-type");
AccountDescription = node.GetString("account-description");
AccountHolderName = node.GetString("account-holder-name");
Token = node.GetString("token");
ImageUrl = node.GetString("image-url");
BankName = node.GetString("bank-name");
AchMandate = new AchMandate(node.GetNode("ach-mandate"));
}
}
}
7 changes: 4 additions & 3 deletions src/Braintree/project.json
Expand Up @@ -6,11 +6,12 @@
"dependencies": { },
"buildOptions": {
},
"version": "3.4.0-*",
"version": "3.5.0-*",
"packOptions": {
"releaseNotes": "
* Add payer_status accessor to paypal_details object
* Add option `skip_advanced_fraud_check` for transaction flows
* Stop sending account_description field from us bank accounts
* Add multi-currency support for OAuth Onboarded Merchants
* Add functionality to list all merchant accounts for a merchant with `MerchantAccount.all`
",
"summary": "
The Braintree .NET Client Library will allow you to take payments securely for
Expand Down
2 changes: 1 addition & 1 deletion test/Braintree.TestUtil/TestHelper.cs
Expand Up @@ -56,7 +56,7 @@ public static string GenerateValidUsBankAccountNonce(BraintreeGateway gateway)
""account_holder_name"": ""Dan Schulman"",
""account_description"": ""PayPal Checking - 1234"",
""ach_mandate"": {
""text"": """"
""text"": ""cl mandate text""
}
}";

Expand Down
2 changes: 0 additions & 2 deletions test/Braintree.Tests.Integration/CustomerIntegrationTest.cs
Expand Up @@ -134,7 +134,6 @@ public void Find_IncludesUsBankAccountInPaymentMethods()
Assert.AreEqual("1234", usBankAccount.Last4);
Assert.AreEqual("checking", usBankAccount.AccountType);
Assert.AreEqual("Dan Schulman", usBankAccount.AccountHolderName);
Assert.AreEqual("PayPal Checking - 1234", usBankAccount.AccountDescription);
Assert.IsTrue(Regex.IsMatch(usBankAccount.BankName, ".*CHASE.*"));
}

Expand Down Expand Up @@ -617,7 +616,6 @@ public void Create_WithUsBankAccountPaymentMethodNonce()
Assert.AreEqual("1234", usBankAccount.Last4);
Assert.AreEqual("checking", usBankAccount.AccountType);
Assert.AreEqual("Dan Schulman", usBankAccount.AccountHolderName);
Assert.AreEqual("PayPal Checking - 1234", usBankAccount.AccountDescription);
Assert.IsTrue(Regex.IsMatch(usBankAccount.BankName, ".*CHASE.*"));
}

Expand Down
59 changes: 59 additions & 0 deletions test/Braintree.Tests.Integration/MerchantAccountIntegrationTest.cs
@@ -1,3 +1,4 @@
using Braintree.TestUtil;
using NUnit.Framework;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -434,6 +435,64 @@ public void CreateForCurrency_HandlesExistingMerchantAccountForId()
Assert.AreEqual(ValidationErrorCode.MERCHANT_MERCHANT_ACCOUNT_EXISTS_FOR_ID, errors[0].Code);
}

[Test]
public void All_ReturnsAllMerchantAccounts()
{
gateway = new BraintreeGateway(
"client_id$development$integration_client_id",
"client_secret$development$integration_client_secret"
);

var code = OAuthTestHelper.CreateGrant(gateway, "integration_merchant_id", "read_write");
ResultImpl<OAuthCredentials> accessTokenResult = gateway.OAuth.CreateTokenFromCode(new OAuthCredentialsRequest
{
Code = code,
Scope = "read_write"
});

BraintreeGateway OAuthGateway = new BraintreeGateway(accessTokenResult.Target.AccessToken);

var merchantAccountResults = OAuthGateway.MerchantAccount.All();

var merchantAccounts = new List<MerchantAccount>();
foreach (var merchantAccount in merchantAccountResults)
{
merchantAccounts.Add(merchantAccount);
}
Assert.IsTrue(merchantAccounts.Count > 20);
}

[Test]
public void All_ReturnsMerchantAccountWithCorrectAttributes()
{
gateway = new BraintreeGateway(
"client_id$development$integration_client_id",
"client_secret$development$integration_client_secret"
);

ResultImpl<Merchant> result = gateway.Merchant.Create(new MerchantRequest {
Email = "name@email.com",
CountryCodeAlpha3 = "USA",
PaymentMethods = new string[] {"credit_card", "paypal"},
Scope = "read_write,shared_vault_transactions",
});

BraintreeGateway OAuthGateway = new BraintreeGateway(result.Target.Credentials.AccessToken);

PaginatedCollection<MerchantAccount> merchantAccountResults = OAuthGateway.MerchantAccount.All();
var merchantAccounts = new List<MerchantAccount>();
foreach (var ma in merchantAccountResults)
{
merchantAccounts.Add(ma);
}
Assert.AreEqual(1, merchantAccounts.Count);

MerchantAccount merchantAccount = merchantAccounts[0];
Assert.AreEqual("USD", merchantAccount.CurrencyIsoCode);
Assert.AreEqual(MerchantAccountStatus.ACTIVE, merchantAccount.Status);
Assert.IsTrue(merchantAccount.IsDefault);
}

private MerchantAccountRequest deprecatedCreateRequest(string id)
{
return new MerchantAccountRequest
Expand Down
Expand Up @@ -313,7 +313,6 @@ public void Create_CreatesUsBankAccountWithNonce()
Assert.AreEqual("1234", usBankAccount.Last4);
Assert.AreEqual("checking", usBankAccount.AccountType);
Assert.AreEqual("Dan Schulman", usBankAccount.AccountHolderName);
Assert.AreEqual("PayPal Checking - 1234", usBankAccount.AccountDescription);
Assert.IsTrue(Regex.IsMatch(usBankAccount.BankName, ".*CHASE.*"));
var found = gateway.PaymentMethod.Find(usBankAccount.Token);
Assert.IsInstanceOf(typeof(UsBankAccount), found);
Expand Down

0 comments on commit 5fafadf

Please sign in to comment.