Permalink
Browse files

braintree .net client library 1.0.0

  • Loading branch information...
0 parents commit 71487bbc9839e8bf368638d397513c07ba2b358c @braintreeps braintreeps committed Feb 23, 2010
Showing with 4,396 additions and 0 deletions.
  1. +13 −0 Braintree.Tests.VisualState.xml
  2. +9 −0 Braintree.Tests.nunit
  3. +174 −0 Braintree.Tests/AddressTest.cs
  4. +74 −0 Braintree.Tests/Braintree.Tests.csproj
  5. +13 −0 Braintree.Tests/Braintree.Tests.csproj.VisualState.xml
  6. +57 −0 Braintree.Tests/ConfigurationTest.cs
  7. +264 −0 Braintree.Tests/CreditCardTest.cs
  8. +71 −0 Braintree.Tests/CreditCardVerificationTest.cs
  9. +28 −0 Braintree.Tests/CryptoTest.cs
  10. +377 −0 Braintree.Tests/CustomerTest.cs
  11. +72 −0 Braintree.Tests/QueryStringTest.cs
  12. +40 −0 Braintree.Tests/TestHelper.cs
  13. +802 −0 Braintree.Tests/TransactionTest.cs
  14. +223 −0 Braintree.Tests/ValidationErrorsTest.cs
  15. +22 −0 Braintree.Tests/WebServiceGatewayTest.cs
  16. +3 −0 Braintree.Tests/app.config
  17. +26 −0 Braintree.sln
  18. +166 −0 Braintree.sln.cache
  19. BIN Braintree.suo
  20. +39 −0 Braintree/Address.cs
  21. +36 −0 Braintree/AddressGateway.cs
  22. +63 −0 Braintree/AddressRequest.cs
  23. +88 −0 Braintree/Braintree.csproj
  24. +9 −0 Braintree/Braintree.csproj.VisualState.xml
  25. +1 −0 Braintree/Braintree.csproj.user
  26. +59 −0 Braintree/BraintreeGateway.cs
  27. +27 −0 Braintree/Configuration.cs
  28. +61 −0 Braintree/CreditCard.cs
  29. +54 −0 Braintree/CreditCardGateway.cs
  30. +38 −0 Braintree/CreditCardOptionsRequest.cs
  31. +66 −0 Braintree/CreditCardRequest.cs
  32. +31 −0 Braintree/CreditCardVerification.cs
  33. +25 −0 Braintree/Crypto.cs
  34. +62 −0 Braintree/Customer.cs
  35. +54 −0 Braintree/CustomerGateway.cs
  36. +68 −0 Braintree/CustomerRequest.cs
  37. +18 −0 Braintree/Environment.cs
  38. +168 −0 Braintree/NodeWrapper.cs
  39. +10 −0 Braintree/NotFoundError.cs
  40. +29 −0 Braintree/PagedCollection.cs
  41. +33 −0 Braintree/Properties/AssemblyInfo.cs
  42. +82 −0 Braintree/QueryString.cs
  43. +58 −0 Braintree/Request.cs
  44. +55 −0 Braintree/Result.cs
  45. +20 −0 Braintree/SandboxValues.cs
  46. +40 −0 Braintree/TrUtil.cs
  47. +88 −0 Braintree/Transaction.cs
  48. +108 −0 Braintree/TransactionGateway.cs
  49. +47 −0 Braintree/TransactionOptionsRequest.cs
  50. +79 −0 Braintree/TransactionRequest.cs
  51. +48 −0 Braintree/TransparentRedirectRequest.cs
  52. +18 −0 Braintree/ValidationError.cs
  53. +87 −0 Braintree/ValidationErrors.cs
  54. +104 −0 Braintree/WebServiceGateway.cs
  55. +3 −0 Braintree/app.config
  56. +25 −0 LICENSE
  57. +49 −0 README.md
  58. +12 −0 default.ps1
13 Braintree.Tests.VisualState.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ShowCheckBoxes="false">
+ <TopNode>[0-1000]C:\Users\pair\braintree-dotnet\Braintree.Tests.nunit</TopNode>
+ <SelectedNode>[0-1000]C:\Users\pair\braintree-dotnet\Braintree.Tests.nunit</SelectedNode>
+ <ExcludeCategories>false</ExcludeCategories>
+ <Nodes>
+ <Node UniqueName="[0-1005]C:\Users\pair\braintree-dotnet\Braintree.Tests\bin\Release\Braintree.Tests.dll" Expanded="true" />
+ <Node UniqueName="[0-1006]Braintree" Expanded="true" />
+ <Node UniqueName="[0-1007]Braintree.Tests" Expanded="true" />
+ <Node UniqueName="[0-1001]Braintree.Tests.Class1Test" Expanded="true" />
+ <Node UniqueName="[0-1003]Braintree.Tests.CustomerTest" Expanded="true" />
+ </Nodes>
+</VisualState>
9 Braintree.Tests.nunit
@@ -0,0 +1,9 @@
+<NUnitProject>
+ <Settings activeconfig="Release" />
+ <Config name="Debug" binpathtype="Auto">
+ <assembly path="Braintree.Tests\bin\Debug\Braintree.Tests.dll" />
+ </Config>
+ <Config name="Release" binpathtype="Auto">
+ <assembly path="Braintree.Tests\bin\Release\Braintree.Tests.dll" />
+ </Config>
+</NUnitProject>
174 Braintree.Tests/AddressTest.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class AddressTest
+ {
+ private BraintreeGateway gateway;
+
+ [SetUp]
+ public void Setup()
+ {
+ gateway = new BraintreeGateway
+ {
+ Environment = Environment.DEVELOPMENT,
+ MerchantID = "integration_merchant_id",
+ PublicKey = "integration_public_key",
+ PrivateKey = "integration_private_key"
+ };
+ }
+
+ [Test]
+ public void Create_CreatesAddressForGivenCustomerID()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var addressRequest = new AddressRequest
+ {
+ CustomerID = customer.ID,
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Angelo Co.",
+ StreetAddress = "1 E Main St",
+ ExtendedAddress = "Apt 3",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America"
+ };
+
+ Address address = gateway.Address.Create(customer.ID, addressRequest).Target;
+
+ Assert.AreEqual("Michael", address.FirstName);
+ Assert.AreEqual("Angelo", address.LastName);
+ Assert.AreEqual("Angelo Co.", address.Company);
+ Assert.AreEqual("1 E Main St", address.StreetAddress);
+ Assert.AreEqual("Apt 3", address.ExtendedAddress);
+ Assert.AreEqual("Chicago", address.Locality);
+ Assert.AreEqual("IL", address.Region);
+ Assert.AreEqual("60622", address.PostalCode);
+ Assert.AreEqual("United States of America", address.CountryName);
+ }
+
+ [Test]
+ public void Find_FindsAddress()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var addressRequest = new AddressRequest
+ {
+ CustomerID = customer.ID,
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Angelo Co.",
+ StreetAddress = "1 E Main St",
+ ExtendedAddress = "Apt 3",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America"
+ };
+
+ Address createdAddress = gateway.Address.Create(customer.ID, addressRequest).Target;
+ Address address = gateway.Address.Find(customer.ID, createdAddress.ID).Target;
+
+ Assert.AreEqual("Michael", address.FirstName);
+ Assert.AreEqual("Angelo", address.LastName);
+ Assert.AreEqual("Angelo Co.", address.Company);
+ Assert.AreEqual("1 E Main St", address.StreetAddress);
+ Assert.AreEqual("Apt 3", address.ExtendedAddress);
+ Assert.AreEqual("Chicago", address.Locality);
+ Assert.AreEqual("IL", address.Region);
+ Assert.AreEqual("60622", address.PostalCode);
+ Assert.AreEqual("United States of America", address.CountryName);
+ }
+
+ [Test]
+ public void Update_UpdatesAddressForGivenCustomerIDAndAddressID()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var addressCreateRequest = new AddressRequest
+ {
+ CustomerID = customer.ID,
+ FirstName = "Dave",
+ LastName = "Inchy",
+ Company = "Leon Ardo Co.",
+ StreetAddress = "1 E State St",
+ ExtendedAddress = "Apt 4",
+ Locality = "Boston",
+ Region = "MA",
+ PostalCode = "11111",
+ CountryName = "Canada"
+ };
+
+ Address originalAddress = gateway.Address.Create(customer.ID, addressCreateRequest).Target;
+
+ var addressUpdateRequest = new AddressRequest
+ {
+ CustomerID = customer.ID,
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Angelo Co.",
+ StreetAddress = "1 E Main St",
+ ExtendedAddress = "Apt 3",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America"
+ };
+
+ Address address = gateway.Address.Update(customer.ID, originalAddress.ID, addressUpdateRequest).Target;
+
+ Assert.AreEqual("Michael", address.FirstName);
+ Assert.AreEqual("Angelo", address.LastName);
+ Assert.AreEqual("Angelo Co.", address.Company);
+ Assert.AreEqual("1 E Main St", address.StreetAddress);
+ Assert.AreEqual("Apt 3", address.ExtendedAddress);
+ Assert.AreEqual("Chicago", address.Locality);
+ Assert.AreEqual("IL", address.Region);
+ Assert.AreEqual("60622", address.PostalCode);
+ Assert.AreEqual("United States of America", address.CountryName);
+ }
+
+ [Test]
+ public void Delete_DeletesTheAddress()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var addressRequest = new AddressRequest
+ {
+ CustomerID = customer.ID,
+ StreetAddress = "1 E Main St",
+ ExtendedAddress = "Apt 3",
+ };
+
+ Address createdAddress = gateway.Address.Create(customer.ID, addressRequest).Target;
+ Assert.AreEqual(createdAddress.ID, gateway.Address.Find(customer.ID, createdAddress.ID).Target.ID);
+ gateway.Address.Delete(customer.ID, createdAddress.ID);
+ Assert.Throws<NotFoundError>(() => gateway.Address.Find(customer.ID, createdAddress.ID));
+ }
+
+ [Test]
+ public void Create_ReturnsAnErrorResult()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+ AddressRequest request = new AddressRequest() { CountryName = "United States of Hammer" };
+
+ Result<Address> createResult = gateway.Address.Create(customer.ID, request);
+ Assert.IsFalse(createResult.IsSuccess());
+ Dictionary<String, String> parameters = createResult.Parameters;
+ Assert.AreEqual("integration_merchant_id", parameters["merchant_id"]);
+ Assert.AreEqual(customer.ID, parameters["customer_id"]);
+ Assert.AreEqual("United States of Hammer", parameters["address[country_name]"]);
+ }
+ }
+}
74 Braintree.Tests/Braintree.Tests.csproj
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{60234E7B-1181-4EFF-96EE-624B4524D788}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Braintree.Tests</RootNamespace>
+ <AssemblyName>Braintree.Tests</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkSubset>
+ </TargetFrameworkSubset>
+ <StartupObject>
+ </StartupObject>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <ItemGroup>
+ <Reference Include="nunit.framework, Version=2.5.2.9222, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AddressTest.cs" />
+ <Compile Include="ConfigurationTest.cs" />
+ <Compile Include="CreditCardTest.cs" />
+ <Compile Include="CreditCardVerificationTest.cs" />
+ <Compile Include="CryptoTest.cs" />
+ <Compile Include="CustomerTest.cs" />
+ <Compile Include="QueryStringTest.cs" />
+ <Compile Include="TestHelper.cs" />
+ <Compile Include="TransactionTest.cs" />
+ <Compile Include="ValidationErrorsTest.cs" />
+ <Compile Include="WebServiceGatewayTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Braintree\Braintree.csproj">
+ <Project>{D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}</Project>
+ <Name>Braintree</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+</Project>
13 Braintree.Tests/Braintree.Tests.csproj.VisualState.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<VisualState xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ShowCheckBoxes="false">
+ <TopNode>[0-1000]C:\Users\pair\braintree-dotnet\Braintree.Tests\Braintree.Tests.csproj</TopNode>
+ <SelectedNode>[0-1008]Braintree.Tests.CustomerTest.Delete_DeletesTheCustomer</SelectedNode>
+ <ExcludeCategories>false</ExcludeCategories>
+ <Nodes>
+ <Node UniqueName="[0-1000]C:\Users\pair\braintree-dotnet\Braintree.Tests\Braintree.Tests.csproj" Expanded="true" />
+ <Node UniqueName="[0-1009]C:\Users\pair\braintree-dotnet\Braintree.Tests\bin\Debug\Braintree.Tests.dll" Expanded="true" />
+ <Node UniqueName="[0-1010]Braintree" Expanded="true" />
+ <Node UniqueName="[0-1011]Braintree.Tests" Expanded="true" />
+ <Node UniqueName="[0-1001]Braintree.Tests.CustomerTest" Expanded="true" />
+ </Nodes>
+</VisualState>
57 Braintree.Tests/ConfigurationTest.cs
@@ -0,0 +1,57 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class ConfigurationTest
+ {
+ [Test]
+ public void BaseMerchantURL_ReturnsDevelopmentURL()
+ {
+ Configuration.Environment = Environment.DEVELOPMENT;
+ Configuration.MerchantID = "integration_merchant_id";
+ Configuration.PublicKey = "integration_public_key";
+ Configuration.PrivateKey = "integration_private_key";
+
+ Assert.AreEqual("http://192.168.65.1:3000/merchants/integration_merchant_id", Configuration.BaseMerchantURL());
+ }
+
+ [Test]
+ public void BaseMerchantURL_ReturnsSandboxURL()
+ {
+ Configuration.Environment = Environment.SANDBOX;
+ Configuration.MerchantID = "integration_merchant_id";
+ Configuration.PublicKey = "integration_public_key";
+ Configuration.PrivateKey = "integration_private_key";
+
+ Assert.AreEqual("https://sandbox.braintreegateway.com:443/merchants/integration_merchant_id", Configuration.BaseMerchantURL());
+ }
+
+ [Test]
+ public void BaseMerchantURL_ReturnsProductionURL()
+ {
+ Configuration.Environment = Environment.PRODUCTION;
+ Configuration.MerchantID = "integration_merchant_id";
+ Configuration.PublicKey = "integration_public_key";
+ Configuration.PrivateKey = "integration_private_key";
+
+
+ Assert.AreEqual("https://www.braintreegateway.com:443/merchants/integration_merchant_id", Configuration.BaseMerchantURL());
+ }
+
+ [Test]
+ public void GetAuthorizationHeader_ReturnsBase64EncodePublicAndPrivateKeys()
+ {
+ Configuration.Environment = Environment.DEVELOPMENT;
+ Configuration.MerchantID = "integration_merchant_id";
+ Configuration.PublicKey = "integration_public_key";
+ Configuration.PrivateKey = "integration_private_key";
+ Assert.AreEqual("Basic aW50ZWdyYXRpb25fcHVibGljX2tleTppbnRlZ3JhdGlvbl9wcml2YXRlX2tleQ==", Configuration.GetAuthorizationHeader());
+
+ }
+ }
+}
264 Braintree.Tests/CreditCardTest.cs
@@ -0,0 +1,264 @@
+using System;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class CreditCardTest
+ {
+ private BraintreeGateway gateway;
+
+ [SetUp]
+ public void Setup()
+ {
+ gateway = new BraintreeGateway
+ {
+ Environment = Environment.DEVELOPMENT,
+ MerchantID = "integration_merchant_id",
+ PublicKey = "integration_public_key",
+ PrivateKey = "integration_private_key"
+ };
+ }
+
+ [Test]
+ public void TransparentRedirectURLForCreate_ReturnsCorrectValue()
+ {
+ Assert.AreEqual(Configuration.BaseMerchantURL() + "/payment_methods/all/create_via_transparent_redirect_request",
+ gateway.CreditCard.TransparentRedirectURLForCreate());
+ }
+
+ [Test]
+ public void TransparentRedirectURLForUpdate_ReturnsCorrectValue()
+ {
+ Assert.AreEqual(Configuration.BaseMerchantURL() + "/payment_methods/all/update_via_transparent_redirect_request",
+ gateway.CreditCard.TransparentRedirectURLForUpdate());
+ }
+
+ [Test]
+ public void TrData_ReturnsValidTrDataHash()
+ {
+ String trData = gateway.TrData(new CreditCardRequest(), "http://example.com");
+ Assert.IsTrue(TrUtil.IsTrDataValid(trData));
+ }
+
+
+ [Test]
+ public void Create_CreatesCreditCardForGivenCustomerID()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var creditCardRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo"
+ };
+
+ CreditCard creditCard = gateway.CreditCard.Create(creditCardRequest).Target;
+
+ Assert.AreEqual("510510", creditCard.Bin);
+ Assert.AreEqual("5100", creditCard.LastFour);
+ Assert.AreEqual("05", creditCard.ExpirationMonth);
+ Assert.AreEqual("2012", creditCard.ExpirationYear);
+ Assert.AreEqual("Michael Angelo", creditCard.CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.UpdatedAt.Year);
+ }
+
+ [Test]
+ public void ConfirmTransparentRedirectCreate_CreatesTheCreditCard()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ CreditCardRequest trParams = new CreditCardRequest { CustomerID = customer.ID };
+
+ CreditCardRequest request = new CreditCardRequest
+ {
+ CardholderName = "John Doe",
+ Number = "5105105105105100",
+ ExpirationDate = "05/12"
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.CreditCard.TransparentRedirectURLForCreate());
+ Result<CreditCard> result = gateway.CreditCard.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ CreditCard card = result.Target;
+ Assert.AreEqual("John Doe", card.CardholderName);
+ Assert.AreEqual("510510", card.Bin);
+ Assert.AreEqual("05", card.ExpirationMonth);
+ Assert.AreEqual("2012", card.ExpirationYear);
+ Assert.AreEqual("05/2012", card.ExpirationDate);
+ Assert.AreEqual("5100", card.LastFour);
+ Assert.IsTrue(card.Token != null);
+ }
+
+ [Test]
+ public void Find_FindsCreditCardByToken()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var creditCardRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo"
+ };
+
+ CreditCard originalCreditCard = gateway.CreditCard.Create(creditCardRequest).Target;
+ CreditCard creditCard = gateway.CreditCard.Find(originalCreditCard.Token).Target;
+
+ Assert.AreEqual("510510", creditCard.Bin);
+ Assert.AreEqual("5100", creditCard.LastFour);
+ Assert.AreEqual("05", creditCard.ExpirationMonth);
+ Assert.AreEqual("2012", creditCard.ExpirationYear);
+ Assert.AreEqual("Michael Angelo", creditCard.CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.UpdatedAt.Year);
+ }
+
+ [Test]
+ public void Update_UpdatesCreditCardByToken()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var creditCardCreateRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo"
+ };
+
+ CreditCard originalCreditCard = gateway.CreditCard.Create(creditCardCreateRequest).Target;
+
+ var creditCardUpdateRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ Number = "4111111111111111",
+ ExpirationDate = "12/05",
+ CVV = "321",
+ CardholderName = "Dave Inchy"
+ };
+
+ CreditCard creditCard = gateway.CreditCard.Update(originalCreditCard.Token, creditCardUpdateRequest).Target;
+
+ Assert.AreEqual("411111", creditCard.Bin);
+ Assert.AreEqual("1111", creditCard.LastFour);
+ Assert.AreEqual("12", creditCard.ExpirationMonth);
+ Assert.AreEqual("2005", creditCard.ExpirationYear);
+ Assert.AreEqual("Dave Inchy", creditCard.CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, creditCard.UpdatedAt.Year);
+ }
+
+ [Test]
+ public void UpdateViaTransparentRedirect()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+ CreditCardRequest createRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ CardholderName = "John Doe",
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ BillingAddress = new AddressRequest
+ {
+ PostalCode = "44444"
+ }
+ };
+ CreditCard createdCard = gateway.CreditCard.Create(createRequest).Target;
+
+ CreditCardRequest trParams = new CreditCardRequest
+ {
+ PaymentMethodToken = createdCard.Token
+ };
+
+ CreditCardRequest request = new CreditCardRequest
+ {
+ CardholderName = "Joe Cool"
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.CreditCard.TransparentRedirectURLForUpdate());
+ Result<CreditCard> result = gateway.CreditCard.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ CreditCard card = result.Target;
+ Assert.AreEqual("Joe Cool", card.CardholderName);
+ Assert.AreEqual("44444", card.BillingAddress.PostalCode);
+ }
+
+ [Test]
+ public void Delete_DeletesTheCreditCard()
+ {
+ String id = Guid.NewGuid().ToString();
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ var creditCardRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo"
+ };
+
+ CreditCard creditCard = gateway.CreditCard.Create(creditCardRequest).Target;
+
+ Assert.AreEqual(creditCard.Token, gateway.CreditCard.Find(creditCard.Token).Target.Token);
+ gateway.CreditCard.Delete(creditCard.Token);
+ Assert.Throws<NotFoundError>(() => gateway.CreditCard.Find(creditCard.Token));
+ }
+
+ [Test]
+ public void verifyValidCreditCard()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+ CreditCardRequest request = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ CardholderName = "John Doe",
+ CVV = "123",
+ Number = "4111111111111111",
+ ExpirationDate = "05/12",
+ Options = new CreditCardOptionsRequest
+ {
+ VerifyCard = "true"
+ }
+ };
+
+ Result<CreditCard> result = gateway.CreditCard.Create(request);
+ Assert.IsTrue(result.IsSuccess());
+ }
+
+ [Test]
+ public void verifyInvalidCreditCard()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+ CreditCardRequest request = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ CardholderName = "John Doe",
+ CVV = "123",
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ Options = new CreditCardOptionsRequest
+ {
+ VerifyCard = "true"
+ }
+ };
+
+ Result<CreditCard> result = gateway.CreditCard.Create(request);
+ Assert.IsFalse(result.IsSuccess());
+ CreditCardVerification verification = result.CreditCardVerification;
+ Assert.AreEqual("processor_declined", verification.Status);
+ }
+ }
+}
71 Braintree.Tests/CreditCardVerificationTest.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+using System.Xml;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class CreditCardVerificationTest
+ {
+ [Test]
+ public void ConstructFromResponse()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <verification>");
+ builder.Append(" <avs-error-response-code nil=\"true\"></avs-error-response-code>");
+ builder.Append(" <avs-postal-code-response-code>I</avs-postal-code-response-code>");
+ builder.Append(" <status>processor_declined</status>");
+ builder.Append(" <processor-response-code>2000</processor-response-code>");
+ builder.Append(" <avs-street-address-response-code>I</avs-street-address-response-code>");
+ builder.Append(" <processor-response-text>Do Not Honor</processor-response-text>");
+ builder.Append(" <cvv-response-code>M</cvv-response-code>");
+ builder.Append(" </verification>");
+ builder.Append(" <errors>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+
+ CreditCardVerification verification = new CreditCardVerification(new NodeWrapper(doc).GetNode("//verification"));
+ Assert.AreEqual(null, verification.AvsErrorResponseCode);
+ Assert.AreEqual("I", verification.AvsPostalCodeResponseCode);
+ Assert.AreEqual("processor_declined", verification.Status);
+ Assert.AreEqual("2000", verification.ProcessorResponseCode);
+ Assert.AreEqual("I", verification.AvsStreetAddressResponseCode);
+ Assert.AreEqual("Do Not Honor", verification.ProcessorResponseText);
+ Assert.AreEqual("M", verification.CvvResponseCode);
+ }
+
+ [Test]
+ public void ConstructFromResponseWithNoVerification()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <errors>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+
+ CreditCardVerification verification = new CreditCardVerification(new NodeWrapper(doc).GetNode("//verification"));
+ Assert.AreEqual(null, verification.AvsErrorResponseCode);
+ Assert.AreEqual(null, verification.AvsPostalCodeResponseCode);
+ Assert.AreEqual(null, verification.Status);
+ Assert.AreEqual(null, verification.ProcessorResponseCode);
+ Assert.AreEqual(null, verification.AvsStreetAddressResponseCode);
+ Assert.AreEqual(null, verification.ProcessorResponseText);
+ Assert.AreEqual(null, verification.CvvResponseCode);
+ }
+
+ }
+}
28 Braintree.Tests/CryptoTest.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class CryptoTest
+ {
+ [Test]
+ public void hmacHash_ReturnsCorrectHash()
+ {
+ String actual = new Crypto().HmacHash("secretKey", "hello world");
+ Assert.AreEqual("D503D7A1A6ADBA1E6474E9FF2C4167F9DFDF4247", actual);
+ }
+
+ [Test]
+ public void Sha1Bytes_ReturnsCorrectHash()
+ {
+ byte[] bytes = new Crypto().Sha1Bytes("hello world");
+ String hex = BitConverter.ToString(bytes);
+ String actual = hex.Replace("-", "");
+ Assert.AreEqual("2AAE6C35C94FCFB415DBE95F408B9CE91EE846ED", actual);
+ }
+ }
+}
377 Braintree.Tests/CustomerTest.cs
@@ -0,0 +1,377 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class CustomerTest
+ {
+ private BraintreeGateway gateway;
+
+ [SetUp]
+ public void Setup()
+ {
+ gateway = new BraintreeGateway
+ {
+ Environment = Environment.DEVELOPMENT,
+ MerchantID = "integration_merchant_id",
+ PublicKey = "integration_public_key",
+ PrivateKey = "integration_private_key"
+ };
+ }
+
+ [Test]
+ public void Find_FindsCustomerWithGivenId()
+ {
+ String id = Guid.NewGuid().ToString();
+ var createRequest = new CustomerRequest
+ {
+ ID = id,
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Some Company",
+ Email = "hansolo64@compuserver.com",
+ Phone = "312.555.1111",
+ Fax = "312.555.1112",
+ Website = "www.disney.com",
+ CreditCard = new CreditCardRequest
+ {
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo",
+ BillingAddress = new AddressRequest()
+ {
+ FirstName = "Mike",
+ LastName = "Smith",
+ Company = "Smith Co.",
+ StreetAddress = "1 W Main St",
+ ExtendedAddress = "Suite 330",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America"
+ }
+ }
+ };
+
+ Customer createdCustomer = gateway.Customer.Create(createRequest).Target;
+ Customer customer = gateway.Customer.Find(createdCustomer.ID).Target;
+ Assert.AreEqual(id, customer.ID);
+ Assert.AreEqual("Michael", customer.FirstName);
+ Assert.AreEqual("Angelo", customer.LastName);
+ Assert.AreEqual("Some Company", customer.Company);
+ Assert.AreEqual("hansolo64@compuserver.com", customer.Email);
+ Assert.AreEqual("312.555.1111", customer.Phone);
+ Assert.AreEqual("312.555.1112", customer.Fax);
+ Assert.AreEqual("www.disney.com", customer.Website);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.UpdatedAt.Year);
+ Assert.AreEqual(1, customer.CreditCards.Length);
+ Assert.AreEqual("510510", customer.CreditCards[0].Bin);
+ Assert.AreEqual("5100", customer.CreditCards[0].LastFour);
+ Assert.AreEqual("05", customer.CreditCards[0].ExpirationMonth);
+ Assert.AreEqual("2012", customer.CreditCards[0].ExpirationYear);
+ Assert.AreEqual("Michael Angelo", customer.CreditCards[0].CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].UpdatedAt.Year);
+ Assert.AreEqual("Mike", customer.Addresses[0].FirstName);
+ Assert.AreEqual("Smith", customer.Addresses[0].LastName);
+ Assert.AreEqual("Smith Co.", customer.Addresses[0].Company);
+ Assert.AreEqual("1 W Main St", customer.Addresses[0].StreetAddress);
+ Assert.AreEqual("Suite 330", customer.Addresses[0].ExtendedAddress);
+ Assert.AreEqual("Chicago", customer.Addresses[0].Locality);
+ Assert.AreEqual("IL", customer.Addresses[0].Region);
+ Assert.AreEqual("60622", customer.Addresses[0].PostalCode);
+ Assert.AreEqual("United States of America", customer.Addresses[0].CountryName);
+ }
+
+ [Test]
+ public void Find_RaisesIfIDIsInvalid()
+ {
+ Assert.Throws<NotFoundError>(() => gateway.Customer.Find("DOES_NOT_EXIST_999"));
+ }
+
+ [Test]
+ public void Create_CanSetCustomFields()
+ {
+ var customFields = new Dictionary<String, String>();
+ customFields.Add("store_me", "a custom value");
+ var expectedCustomFields = new Dictionary<String, String>();
+ expectedCustomFields.Add("store-me", "a custom value");
+ var createRequest = new CustomerRequest()
+ {
+ CustomFields = customFields
+ };
+
+ Customer customer = gateway.Customer.Create(createRequest).Target;
+ Assert.AreEqual(expectedCustomFields, customer.CustomFields);
+ }
+
+ [Test]
+ public void Create_CreatesCustomerWithSpecifiedValues()
+ {
+ var createRequest = new CustomerRequest()
+ {
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Some Company",
+ Email = "hansolo64@compuserver.com",
+ Phone = "312.555.1111",
+ Fax = "312.555.1112",
+ Website = "www.disney.com"
+ };
+
+ Customer customer = gateway.Customer.Create(createRequest).Target;
+ Assert.AreEqual("Michael", customer.FirstName);
+ Assert.AreEqual("Angelo", customer.LastName);
+ Assert.AreEqual("Some Company", customer.Company);
+ Assert.AreEqual("hansolo64@compuserver.com", customer.Email);
+ Assert.AreEqual("312.555.1111", customer.Phone);
+ Assert.AreEqual("312.555.1112", customer.Fax);
+ Assert.AreEqual("www.disney.com", customer.Website);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.UpdatedAt.Year);
+ }
+
+ [Test]
+ public void Create_CreateCustomerWithCreditCard()
+ {
+ var createRequest = new CustomerRequest()
+ {
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Some Company",
+ Email = "hansolo64@compuserver.com",
+ Phone = "312.555.1111",
+ Fax = "312.555.1112",
+ Website = "www.disney.com",
+ CreditCard = new CreditCardRequest()
+ {
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo"
+ }
+ };
+
+ Customer customer = gateway.Customer.Create(createRequest).Target;
+ Assert.AreEqual("Michael", customer.FirstName);
+ Assert.AreEqual("Angelo", customer.LastName);
+ Assert.AreEqual("Some Company", customer.Company);
+ Assert.AreEqual("hansolo64@compuserver.com", customer.Email);
+ Assert.AreEqual("312.555.1111", customer.Phone);
+ Assert.AreEqual("312.555.1112", customer.Fax);
+ Assert.AreEqual("www.disney.com", customer.Website);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.UpdatedAt.Year);
+ Assert.AreEqual(1, customer.CreditCards.Length);
+ Assert.AreEqual("510510", customer.CreditCards[0].Bin);
+ Assert.AreEqual("5100", customer.CreditCards[0].LastFour);
+ Assert.AreEqual("05", customer.CreditCards[0].ExpirationMonth);
+ Assert.AreEqual("2012", customer.CreditCards[0].ExpirationYear);
+ Assert.AreEqual("Michael Angelo", customer.CreditCards[0].CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].UpdatedAt.Year);
+ }
+
+ [Test]
+ public void Create_CreateCustomerWithCreditCardAndBillingAddress()
+ {
+ var createRequest = new CustomerRequest()
+ {
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Some Company",
+ Email = "hansolo64@compuserver.com",
+ Phone = "312.555.1111",
+ Fax = "312.555.1112",
+ Website = "www.disney.com",
+ CreditCard = new CreditCardRequest()
+ {
+ Number = "5105105105105100",
+ ExpirationDate = "05/12",
+ CVV = "123",
+ CardholderName = "Michael Angelo",
+ BillingAddress = new AddressRequest()
+ {
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Angelo Co.",
+ StreetAddress = "1 E Main St",
+ ExtendedAddress = "Apt 3",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America"
+ }
+ }
+ };
+
+ Customer customer = gateway.Customer.Create(createRequest).Target;
+ Assert.AreEqual("Michael", customer.FirstName);
+ Assert.AreEqual("Angelo", customer.LastName);
+ Assert.AreEqual("Some Company", customer.Company);
+ Assert.AreEqual("hansolo64@compuserver.com", customer.Email);
+ Assert.AreEqual("312.555.1111", customer.Phone);
+ Assert.AreEqual("312.555.1112", customer.Fax);
+ Assert.AreEqual("www.disney.com", customer.Website);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.UpdatedAt.Year);
+ Assert.AreEqual(1, customer.CreditCards.Length);
+ Assert.AreEqual("510510", customer.CreditCards[0].Bin);
+ Assert.AreEqual("5100", customer.CreditCards[0].LastFour);
+ Assert.AreEqual("05", customer.CreditCards[0].ExpirationMonth);
+ Assert.AreEqual("2012", customer.CreditCards[0].ExpirationYear);
+ Assert.AreEqual("Michael Angelo", customer.CreditCards[0].CardholderName);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, customer.CreditCards[0].UpdatedAt.Year);
+ Assert.AreEqual(customer.Addresses[0].ID, customer.CreditCards[0].BillingAddress.ID);
+ Assert.AreEqual("Michael", customer.Addresses[0].FirstName);
+ Assert.AreEqual("Angelo", customer.Addresses[0].LastName);
+ Assert.AreEqual("Angelo Co.", customer.Addresses[0].Company);
+ Assert.AreEqual("1 E Main St", customer.Addresses[0].StreetAddress);
+ Assert.AreEqual("Apt 3", customer.Addresses[0].ExtendedAddress);
+ Assert.AreEqual("Chicago", customer.Addresses[0].Locality);
+ Assert.AreEqual("IL", customer.Addresses[0].Region);
+ Assert.AreEqual("60622", customer.Addresses[0].PostalCode);
+ Assert.AreEqual("United States of America", customer.Addresses[0].CountryName);
+ }
+
+ [Test]
+ public void ConfirmTransparentRedirect_CreatesTheCustomer()
+ {
+ CustomerRequest trParams = new CustomerRequest();
+
+ CustomerRequest request = new CustomerRequest
+ {
+ FirstName = "John",
+ LastName = "Doe"
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.Customer.TransparentRedirectURLForCreate());
+ Result<Customer> result = gateway.Customer.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ Customer customer = result.Target;
+ Assert.AreEqual("John", customer.FirstName);
+ Assert.AreEqual("Doe", customer.LastName);
+ }
+
+ [Test]
+ public void ConfirmTransparentRedirect_CreatesNestedElementsAndCustomFields()
+ {
+ CustomerRequest trParams = new CustomerRequest();
+
+ CustomerRequest request = new CustomerRequest
+ {
+ FirstName = "John",
+ LastName = "Doe",
+ CreditCard = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ CardholderName = "John Doe",
+ ExpirationDate = "05/10"
+ },
+ CustomFields = new Dictionary<String, String>
+ {
+ { "store_me", "a custom value" }
+ }
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.Customer.TransparentRedirectURLForCreate());
+ Result<Customer> result = gateway.Customer.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ Customer customer = result.Target;
+ Assert.AreEqual("John", customer.FirstName);
+ Assert.AreEqual("Doe", customer.LastName);
+ Assert.AreEqual("John Doe", customer.CreditCards[0].CardholderName);
+ Assert.AreEqual("a custom value", customer.CustomFields["store-me"]);
+ }
+
+ [Test]
+ public void ConfirmTransparentRedirect_UpdatesTheCustomer()
+ {
+ CustomerRequest createRequest = new CustomerRequest
+ {
+ FirstName = "Jane",
+ LastName = "Deer"
+ };
+ Customer createdCustomer = gateway.Customer.Create(createRequest).Target;
+
+ CustomerRequest trParams = new CustomerRequest
+ {
+ CustomerID = createdCustomer.ID
+ };
+
+ CustomerRequest request = new CustomerRequest
+ {
+ FirstName = "John",
+ LastName = "Doe"
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.Customer.TransparentRedirectURLForUpdate());
+ Result<Customer> result = gateway.Customer.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ Customer customer = result.Target;
+ Assert.AreEqual("John", customer.FirstName);
+ Assert.AreEqual("Doe", customer.LastName);
+ }
+
+ [Test]
+ public void Update_UpdatesCustomerWithNewValues()
+ {
+ string oldID = Guid.NewGuid().ToString();
+ string newID = Guid.NewGuid().ToString();
+ var createRequest = new CustomerRequest()
+ {
+ ID = oldID,
+ FirstName = "Old First",
+ LastName = "Old Last",
+ Company = "Old Company",
+ Email = "old@example.com",
+ Phone = "312.555.1111 xOld",
+ Fax = "312.555.1112 xOld",
+ Website = "old.example.com"
+ };
+
+ var originalCustomer = gateway.Customer.Create(createRequest);
+
+ var updateRequest = new CustomerRequest()
+ {
+ ID = newID,
+ FirstName = "Michael",
+ LastName = "Angelo",
+ Company = "Some Company",
+ Email = "hansolo64@compuserver.com",
+ Phone = "312.555.1111",
+ Fax = "312.555.1112",
+ Website = "www.disney.com"
+ };
+
+ Customer updatedCustomer = gateway.Customer.Update(oldID, updateRequest).Target;
+ Assert.AreEqual(newID, updatedCustomer.ID);
+ Assert.AreEqual("Michael", updatedCustomer.FirstName);
+ Assert.AreEqual("Angelo", updatedCustomer.LastName);
+ Assert.AreEqual("Some Company", updatedCustomer.Company);
+ Assert.AreEqual("hansolo64@compuserver.com", updatedCustomer.Email);
+ Assert.AreEqual("312.555.1111", updatedCustomer.Phone);
+ Assert.AreEqual("312.555.1112", updatedCustomer.Fax);
+ Assert.AreEqual("www.disney.com", updatedCustomer.Website);
+ Assert.AreEqual(DateTime.Now.Year, updatedCustomer.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, updatedCustomer.UpdatedAt.Year);
+ }
+
+ [Test]
+ public void Delete_DeletesTheCustomer()
+ {
+ String id = Guid.NewGuid().ToString();
+ gateway.Customer.Create(new CustomerRequest() { ID = id });
+ Assert.AreEqual(id, gateway.Customer.Find(id).Target.ID);
+ gateway.Customer.Delete(id);
+ Assert.Throws<NotFoundError>(() => gateway.Customer.Find(id));
+ }
+ }
+}
72 Braintree.Tests/QueryStringTest.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class QueryStringTest
+ {
+ [Test]
+ public void Append()
+ {
+ String actual = new QueryString().Append("foo", "f").Append("bar", "b").ToString();
+ Assert.AreEqual("foo=f&bar=b", actual);
+ }
+
+ [Test]
+ public void AppendEmptyStringOrNulls()
+ {
+ String actual = new QueryString().
+ Append("foo", "f").
+ Append("", "b").
+ Append("bar", "").
+ Append("boom", null).
+ Append("", "c").ToString();
+
+ Assert.AreEqual("foo=f&bar=", actual);
+ }
+
+ [Test]
+ public void AppendOtherObjectsWithCanBeConvertedToStrings()
+ {
+ String actual = new QueryString().
+ Append("foo", 10).
+ Append("bar", "20.00").ToString();
+
+ Assert.AreEqual("foo=10&bar=20.00", actual);
+ }
+
+ [Test]
+ public void AppendWithRequest()
+ {
+ Request request = new CreditCardRequest
+ {
+ CVV = "123",
+ CardholderName = "Drew"
+ };
+
+ String actual = new QueryString().Append("[credit_card]", request).ToString();
+ Assert.AreEqual("%5bcredit_card%5d%5bcardholder_name%5d=Drew&%5bcredit_card%5d%5bcvv%5d=123", actual);
+ }
+
+ [Test]
+ public void AppendWithNestedRequest()
+ {
+ Request request = new CreditCardRequest
+ {
+ CVV = "123",
+ CardholderName = "Drew",
+ Options = new CreditCardOptionsRequest
+ {
+ VerifyCard = "true"
+ }
+ };
+
+ String actual = new QueryString().Append("[credit_card]", request).ToString();
+ Assert.AreEqual("%5bcredit_card%5d%5boptions%5d%5bverify_card%5d=true&%5bcredit_card%5d%5bcardholder_name%5d=Drew&%5bcredit_card%5d%5bcvv%5d=123", actual);
+ }
+ }
+}
40 Braintree.Tests/TestHelper.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web;
+using System.Net;
+using System.IO;
+
+namespace Braintree.Tests
+{
+ public class TestHelper
+ {
+ public static String QueryStringForTR(Request trParams, Request req, String postURL)
+ {
+ String trData = TrUtil.BuildTrData(trParams, "http://example.com");
+ String postData = "tr_data=" + HttpUtility.UrlEncode(trData, Encoding.UTF8) + "&";
+ postData += req.ToQueryString();
+
+ var request = WebRequest.Create(postURL) as HttpWebRequest;
+ request.Headers.Add("X-ApiVersion", "1");
+ request.UserAgent = "Braintree .NET Tests";
+
+ request.Method = "POST";
+ request.KeepAlive = false;
+
+ byte[] buffer = Encoding.UTF8.GetBytes(postData);
+ request.ContentType = "application/x-www-form-urlencoded";
+ request.ContentLength = buffer.Length;
+ Stream requestStream = request.GetRequestStream();
+ requestStream.Write(buffer, 0, buffer.Length);
+ requestStream.Close();
+
+ var response = request.GetResponse() as HttpWebResponse;
+ String query = response.ResponseUri.Query;
+
+ response.Close();
+
+ return query;
+ }
+ }
+}
802 Braintree.Tests/TransactionTest.cs
@@ -0,0 +1,802 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class TransactionTest
+ {
+ private BraintreeGateway gateway;
+
+ [SetUp]
+ public void Setup()
+ {
+ gateway = new BraintreeGateway
+ {
+ Environment = Environment.DEVELOPMENT,
+ MerchantID = "integration_merchant_id",
+ PublicKey = "integration_public_key",
+ PrivateKey = "integration_private_key"
+ };
+ }
+
+ [Test]
+ public void SaleTrData_ReturnsValidTrDataHash()
+ {
+ String trData = gateway.Transaction.SaleTrData(new TransactionRequest(), "http://example.com");
+ Assert.IsTrue(trData.Contains("sale"));
+ Assert.IsTrue(TrUtil.IsTrDataValid(trData));
+ }
+
+ [Test]
+ public void CreditTrData_ReturnsValidTrDataHash()
+ {
+ String trData = gateway.Transaction.CreditTrData(new TransactionRequest(), "http://example.com");
+ Assert.IsTrue(trData.Contains("credit"));
+ Assert.IsTrue(TrUtil.IsTrDataValid(trData));
+ }
+
+ [Test]
+ public void Sale_ReturnsSuccessfulResponse()
+ {
+ var request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009",
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(1000.00, transaction.Amount);
+ Assert.AreEqual(TransactionType.SALE, transaction.Type);
+ Assert.AreEqual(TransactionStatus.AUTHORIZED, transaction.Status);
+ Assert.AreEqual(DateTime.Now.Year, transaction.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, transaction.UpdatedAt.Year);
+
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.AreEqual("411111", creditCardDetails.Bin);
+ Assert.AreEqual("1111", creditCardDetails.LastFour);
+ Assert.AreEqual("05", creditCardDetails.ExpirationMonth);
+ Assert.AreEqual("2009", creditCardDetails.ExpirationYear);
+ Assert.AreEqual("05/2009", creditCardDetails.ExpirationDate);
+ }
+
+ [Test]
+ public void Sale_WithAllAttributes()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ OrderId = "123",
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ CVV = "321",
+ ExpirationDate = "05/2009"
+ },
+ CustomerRequest = new CustomerRequest
+ {
+ FirstName = "Dan",
+ LastName = "Smith",
+ Company = "Braintree Payment Solutions",
+ Email = "dan@example.com",
+ Phone = "419-555-1234",
+ Fax = "419-555-1235",
+ Website = "http://braintreepaymentsolutions.com"
+ },
+ BillingAddressRequest = new AddressRequest
+ {
+ FirstName = "Carl",
+ LastName = "Jones",
+ Company = "Braintree",
+ StreetAddress = "123 E Main St",
+ ExtendedAddress = "Suite 403",
+ Locality = "Chicago",
+ Region = "IL",
+ PostalCode = "60622",
+ CountryName = "United States of America",
+ },
+ ShippingAddressRequest = new AddressRequest
+ {
+ FirstName = "Andrew",
+ LastName = "Mason",
+ Company = "Braintree Shipping",
+ StreetAddress = "456 W Main St",
+ ExtendedAddress = "Apt 2F",
+ Locality = "Bartlett",
+ Region = "MA",
+ PostalCode = "60103",
+ CountryName = "Mexico",
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(1000.00, transaction.Amount);
+ Assert.AreEqual(TransactionStatus.AUTHORIZED, transaction.Status);
+ Assert.AreEqual("123", transaction.OrderId);
+ Assert.IsNull(transaction.GetVaultCreditCard());
+ Assert.IsNull(transaction.GetVaultCustomer());
+
+ Assert.IsNull(transaction.GetVaultCreditCard());
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.AreEqual("411111", creditCardDetails.Bin);
+ Assert.AreEqual("1111", creditCardDetails.LastFour);
+ Assert.AreEqual("05", creditCardDetails.ExpirationMonth);
+ Assert.AreEqual("2009", creditCardDetails.ExpirationYear);
+ Assert.AreEqual("05/2009", creditCardDetails.ExpirationDate);
+
+ Assert.IsNull(transaction.GetVaultCustomer());
+ Customer customer = transaction.CustomerDetails;
+ Assert.AreEqual("Dan", customer.FirstName);
+ Assert.AreEqual("Smith", customer.LastName);
+ Assert.AreEqual("Braintree Payment Solutions", customer.Company);
+ Assert.AreEqual("dan@example.com", customer.Email);
+ Assert.AreEqual("419-555-1234", customer.Phone);
+ Assert.AreEqual("419-555-1235", customer.Fax);
+ Assert.AreEqual("http://braintreepaymentsolutions.com", customer.Website);
+
+ Assert.IsNull(transaction.GetVaultBillingAddress());
+ Address billingDetails = transaction.BillingAddressDetails;
+ Assert.AreEqual("Carl", billingDetails.FirstName);
+ Assert.AreEqual("Jones", billingDetails.LastName);
+ Assert.AreEqual("Braintree", billingDetails.Company);
+ Assert.AreEqual("123 E Main St", billingDetails.StreetAddress);
+ Assert.AreEqual("Suite 403", billingDetails.ExtendedAddress);
+ Assert.AreEqual("Chicago", billingDetails.Locality);
+ Assert.AreEqual("IL", billingDetails.Region);
+ Assert.AreEqual("60622", billingDetails.PostalCode);
+ Assert.AreEqual("United States of America", billingDetails.CountryName);
+
+ Assert.IsNull(transaction.GetVaultShippingAddress());
+ Address shippingDetails = transaction.ShippingAddressDetails;
+ Assert.AreEqual("Andrew", shippingDetails.FirstName);
+ Assert.AreEqual("Mason", shippingDetails.LastName);
+ Assert.AreEqual("Braintree Shipping", shippingDetails.Company);
+ Assert.AreEqual("456 W Main St", shippingDetails.StreetAddress);
+ Assert.AreEqual("Apt 2F", shippingDetails.ExtendedAddress);
+ Assert.AreEqual("Bartlett", shippingDetails.Locality);
+ Assert.AreEqual("MA", shippingDetails.Region);
+ Assert.AreEqual("60103", shippingDetails.PostalCode);
+ Assert.AreEqual("Mexico", shippingDetails.CountryName);
+ }
+
+ [Test]
+ public void Sale_WithStoreInVaultAndSpecifyingToken()
+ {
+ String customerId = new Random().Next(1000000).ToString();
+ String paymentToken = new Random().Next(1000000).ToString();
+
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Token = paymentToken,
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ },
+ CustomerRequest = new CustomerRequest
+ {
+ ID = customerId,
+ FirstName = "Jane",
+ },
+ TransactionOptionsRequest = new TransactionOptionsRequest
+ {
+ StoreInVault = true
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.AreEqual(paymentToken, creditCardDetails.Token);
+ Assert.AreEqual("05/2009", transaction.GetVaultCreditCard().ExpirationDate);
+
+ Customer customer = transaction.CustomerDetails;
+ Assert.AreEqual(customerId, customer.ID);
+ Assert.AreEqual("Jane", transaction.GetVaultCustomer().FirstName);
+ }
+
+ [Test]
+ public void Sale_WithStoreInVaultWithoutSpecifyingToken()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009",
+ },
+ CustomerRequest = new CustomerRequest
+ {
+ FirstName = "Jane"
+ },
+ TransactionOptionsRequest = new TransactionOptionsRequest
+ {
+ StoreInVault = true
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.IsNotNull(creditCardDetails.Token);
+ Assert.AreEqual("05/2009", transaction.GetVaultCreditCard().ExpirationDate);
+
+ Customer customerDetails = transaction.CustomerDetails;
+ Assert.IsNotNull(customerDetails.ID);
+ Assert.AreEqual("Jane", transaction.GetVaultCustomer().FirstName);
+ }
+
+ [Test]
+ public void Sale_WithStoreInVaultForBillingAndShipping()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009",
+ },
+ BillingAddressRequest = new AddressRequest
+ {
+ FirstName = "Carl",
+ },
+ ShippingAddressRequest = new AddressRequest
+ {
+ FirstName = "Andrew"
+ },
+ TransactionOptionsRequest = new TransactionOptionsRequest
+ {
+ StoreInVault = true,
+ AddBillingAddressToPaymentMethod = true,
+ StoreShippingAddressInVault = true
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ CreditCard creditCard = transaction.GetVaultCreditCard();
+ Assert.AreEqual("Carl", creditCard.BillingAddress.FirstName);
+ Assert.AreEqual("Carl", transaction.GetVaultBillingAddress().FirstName);
+ Assert.AreEqual("Andrew", transaction.GetVaultShippingAddress().FirstName);
+
+ Customer customer = transaction.GetVaultCustomer();
+ Assert.AreEqual(2, customer.Addresses.Length);
+
+ List<Address> addresses = new List<Address>(customer.Addresses);
+ Assert.AreEqual("Carl", customer.Addresses[0].FirstName);
+ Assert.AreEqual("Andrew", customer.Addresses[1].FirstName);
+
+ Assert.IsNotNull(transaction.BillingAddressDetails.ID);
+ Assert.IsNotNull(transaction.ShippingAddressDetails.ID);
+ }
+
+ [Test]
+ public void Sale_Declined()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.DECLINE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(2000.00, transaction.Amount);
+ Assert.AreEqual(TransactionStatus.PROCESSOR_DECLINED, transaction.Status);
+ Assert.AreEqual("2000", transaction.ProcessorResponseCode);
+ Assert.IsNotNull(transaction.ProcessorResponseText);
+
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.AreEqual("411111", creditCardDetails.Bin);
+ Assert.AreEqual("1111", creditCardDetails.LastFour);
+ Assert.AreEqual("05", creditCardDetails.ExpirationMonth);
+ Assert.AreEqual("2009", creditCardDetails.ExpirationYear);
+ Assert.AreEqual("05/2009", creditCardDetails.ExpirationDate);
+ }
+
+ [Test]
+ public void Sale_WithCustomFields()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.DECLINE,
+ CustomFields = new Dictionary<String, String>
+ {
+ { "store_me", "custom value" },
+ { "another_stored_field", "custom value2" }
+ },
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual("custom value", transaction.CustomFields["store-me"]);
+ Assert.AreEqual("custom value2", transaction.CustomFields["another-stored-field"]);
+ }
+
+ [Test]
+ public void Sale_WithUnregisteredCustomField()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.DECLINE,
+ CustomFields = new Dictionary<String, String>
+ {
+ { "unkown_custom_field", "custom value" }
+ },
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsFalse(result.IsSuccess());
+ Assert.AreEqual("91526", result.Errors.ForObject("transaction").OnField("custom_fields").Code);
+ }
+
+ [Test]
+ public void Sale_WithPaymentMethodToken()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+ CreditCardRequest creditCardRequest = new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ CVV = "123",
+ Number = "5105105105105100",
+ ExpirationDate = "05/12"
+ };
+
+ CreditCard creditCard = gateway.CreditCard.Create(creditCardRequest).Target;
+
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ PaymentMethodToken = creditCard.Token
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(creditCard.Token, transaction.CreditCardDetails.Token);
+ Assert.AreEqual("510510", transaction.CreditCardDetails.Bin);
+ Assert.AreEqual("05/2012", transaction.CreditCardDetails.ExpirationDate);
+ }
+
+ [Test]
+ public void Sale_UsesShippingAddressFromVault()
+ {
+ Customer customer = gateway.Customer.Create(new CustomerRequest()).Target;
+
+ gateway.CreditCard.Create(new CreditCardRequest
+ {
+ CustomerID = customer.ID,
+ CVV = "123",
+ Number = "5105105105105100",
+ ExpirationDate = "05/12"
+ });
+
+ Address shippingAddress = gateway.Address.Create(customer.ID, new AddressRequest { FirstName = "Carl" }).Target;
+
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CustomerID = customer.ID,
+ ShippingAddressId = shippingAddress.ID
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(shippingAddress.ID, transaction.ShippingAddressDetails.ID);
+ Assert.AreEqual("Carl", transaction.ShippingAddressDetails.FirstName);
+ }
+
+ [Test]
+ public void Sale_WithValidationError()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ CreditCardRequest = new CreditCardRequest
+ {
+ ExpirationMonth = "05",
+ ExpirationYear = "2010"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Sale(request);
+ Assert.IsFalse(result.IsSuccess());
+ Assert.IsNull(result.Target);
+
+ Assert.AreEqual("81502", result.Errors.ForObject("transaction").OnField("amount").Code);
+ Dictionary<String, String> parameters = result.Parameters;
+ Assert.IsFalse(parameters.ContainsKey("transaction[amount]"));
+ Assert.AreEqual("05", parameters["transaction[credit_card][expiration_month]"]);
+ Assert.AreEqual("2010", parameters["transaction[credit_card][expiration_year]"]);
+ }
+
+ [Test]
+ public void ConfirmTransparentRedirect_CreatesTheTransaction()
+ {
+ TransactionRequest trParams = new TransactionRequest
+ {
+ Type = TransactionType.SALE
+ };
+
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009",
+ }
+ };
+
+ String queryString = TestHelper.QueryStringForTR(trParams, request, gateway.Transaction.TransparentRedirectURLForCreate());
+ Result<Transaction> result = gateway.Transaction.ConfirmTransparentRedirect(queryString);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(1000.00, transaction.Amount);
+ Assert.AreEqual(TransactionType.SALE, transaction.Type);
+ Assert.AreEqual(TransactionStatus.AUTHORIZED, transaction.Status);
+ Assert.AreEqual(DateTime.Now.Year, transaction.CreatedAt.Year);
+ Assert.AreEqual(DateTime.Now.Year, transaction.UpdatedAt.Year);
+
+ CreditCard creditCardDetails = transaction.CreditCardDetails;
+ Assert.AreEqual("411111", creditCardDetails.Bin);
+ Assert.AreEqual("1111", creditCardDetails.LastFour);
+ Assert.AreEqual("05", creditCardDetails.ExpirationMonth);
+ Assert.AreEqual("2009", creditCardDetails.ExpirationYear);
+ Assert.AreEqual("05/2009", creditCardDetails.ExpirationDate);
+ }
+
+ [Test]
+ public void Credit_WithValidParams()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Credit(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual(1000.00, transaction.Amount);
+ Assert.AreEqual(TransactionType.CREDIT, transaction.Type);
+ Assert.AreEqual(TransactionStatus.SUBMITTED_FOR_SETTLEMENT, transaction.Status);
+
+ CreditCard creditCard = transaction.CreditCardDetails;
+ Assert.AreEqual("411111", creditCard.Bin);
+ Assert.AreEqual("1111", creditCard.LastFour);
+ Assert.AreEqual("05", creditCard.ExpirationMonth);
+ Assert.AreEqual("2009", creditCard.ExpirationYear);
+ Assert.AreEqual("05/2009", creditCard.ExpirationDate);
+ }
+
+ [Test]
+ public void Credit_WithCustomFields()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.DECLINE,
+ CustomFields = new Dictionary<String, String>
+ {
+ { "store_me", "custom value"},
+ { "another_stored_field", "custom value2" }
+ },
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2009"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Credit(request);
+ Assert.IsTrue(result.IsSuccess());
+ Transaction transaction = result.Target;
+
+ Assert.AreEqual("custom value", transaction.CustomFields["store-me"]);
+ Assert.AreEqual("custom value2", transaction.CustomFields["another-stored-field"]);
+ }
+
+ [Test]
+ public void Credit_WithValidationError()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ CreditCardRequest = new CreditCardRequest
+ {
+ ExpirationMonth = "05",
+ ExpirationYear = "2010"
+ }
+ };
+
+ Result<Transaction> result = gateway.Transaction.Credit(request);
+ Assert.IsFalse(result.IsSuccess());
+ Assert.IsNull(result.Target);
+
+ Assert.AreEqual("81502", result.Errors.ForObject("transaction").OnField("amount").Code);
+
+ Dictionary<String, String> parameters = result.Parameters;
+ Assert.IsFalse(parameters.ContainsKey("transaction[amount]"));
+ Assert.AreEqual("05", parameters["transaction[credit_card][expiration_month]"]);
+ Assert.AreEqual("2010", parameters["transaction[credit_card][expiration_year]"]);
+ }
+
+ [Test]
+ public void Find_WithAValidTransactionID()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+
+ Transaction foundTransaction = gateway.Transaction.Find(transaction.ID);
+
+ Assert.AreEqual(transaction.ID, foundTransaction.ID);
+ Assert.AreEqual(TransactionStatus.AUTHORIZED, foundTransaction.Status);
+ Assert.AreEqual("05/2008", foundTransaction.CreditCardDetails.ExpirationDate);
+ }
+
+ [Test]
+ public void Find_WithBadId()
+ {
+ Assert.Throws<NotFoundError>(() => gateway.Transaction.Find("badId"));
+ }
+
+ [Test]
+ public void Void_VoidsTheTransaction()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Result<Transaction> result = gateway.Transaction.Void(transaction.ID);
+ Assert.IsTrue(result.IsSuccess());
+
+ Assert.AreEqual(transaction.ID, result.Target.ID);
+ Assert.AreEqual(TransactionStatus.VOIDED, result.Target.Status);
+ }
+
+ [Test]
+ public void Void_WithBadId()
+ {
+ Assert.Throws<NotFoundError>(() => gateway.Transaction.Void("badId"));
+ }
+
+ [Test]
+ public void Void_WithValidationError()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Result<Transaction> result = gateway.Transaction.Void(transaction.ID);
+ Assert.IsTrue(result.IsSuccess());
+
+ result = gateway.Transaction.Void(transaction.ID);
+ Assert.IsFalse(result.IsSuccess());
+ Assert.AreEqual("91504", result.Errors.ForObject("transaction").OnField("base").Code);
+ }
+
+ [Test]
+ public void SubmitForSettlement_WithoutAmount()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+
+ Result<Transaction> result = gateway.Transaction.SubmitForSettlement(transaction.ID);
+
+ Assert.IsTrue(result.IsSuccess());
+ Assert.AreEqual(TransactionStatus.SUBMITTED_FOR_SETTLEMENT, result.Target.Status);
+ Assert.AreEqual(SandboxValues.TransactionAmount.AUTHORIZE, result.Target.Amount);
+ }
+
+ [Test]
+ public void SubmitForSettlement_WithAmount()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Result<Transaction> result = gateway.Transaction.SubmitForSettlement(transaction.ID, Decimal.Parse("50.00"));
+
+ Assert.IsTrue(result.IsSuccess());
+ Assert.AreEqual(TransactionStatus.SUBMITTED_FOR_SETTLEMENT, result.Target.Status);
+ Assert.AreEqual(50.00, result.Target.Amount);
+ }
+
+ [Test]
+ public void SubmitForSettlement_WithValidationError()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Result<Transaction> result = gateway.Transaction.SubmitForSettlement(transaction.ID);
+ Assert.IsTrue(result.IsSuccess());
+
+ result = gateway.Transaction.SubmitForSettlement(transaction.ID);
+ Assert.IsFalse(result.IsSuccess());
+ Assert.AreEqual("91507", result.Errors.ForObject("transaction").OnField("base").Code);
+ }
+
+ [Test]
+ public void SubmitForSettlement_WithBadId()
+ {
+ Assert.Throws<NotFoundError>(() => gateway.Transaction.SubmitForSettlement("badId"));
+ }
+
+ [Test]
+ public void Search_WithMatches()
+ {
+ PagedCollection pagedCollection = gateway.Transaction.Search("411111");
+
+ Assert.IsTrue(pagedCollection.TotalItems > 0);
+ Assert.IsTrue(pagedCollection.PageSize > 0);
+ Assert.AreEqual(1, pagedCollection.CurrentPageNumber);
+ Assert.AreEqual("411111", pagedCollection.Transactions[0].CreditCardDetails.Bin);
+ }
+
+ [Test]
+ public void Search_WithPageNumber()
+ {
+ PagedCollection pagedCollection = gateway.Transaction.Search("411111", 2);
+ Assert.AreEqual(2, pagedCollection.CurrentPageNumber);
+ }
+
+ [Test]
+ public void Search_CanTraversePages()
+ {
+ PagedCollection pagedCollection = gateway.Transaction.Search("411111");
+ Assert.AreEqual(1, pagedCollection.CurrentPageNumber);
+
+ PagedCollection nextPage = pagedCollection.GetNextPage();
+ Assert.AreEqual(2, nextPage.CurrentPageNumber);
+ Assert.AreNotEqual(pagedCollection.Transactions[0].ID, nextPage.Transactions[0].ID);
+ }
+
+ [Test]
+ public void Refund_WithABasicTransaction()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ },
+ TransactionOptionsRequest = new TransactionOptionsRequest
+ {
+ SubmitForSettlement = true
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Settle(transaction.ID);
+
+ Result<Transaction> result = gateway.Transaction.Refund(transaction.ID);
+ Assert.IsTrue(result.IsSuccess());
+ Assert.AreEqual(TransactionType.CREDIT, result.Target.Type);
+ Assert.AreEqual(transaction.Amount, result.Target.Amount);
+ }
+
+ private void Settle(String transactionId)
+ {
+ NodeWrapper response = new NodeWrapper(WebServiceGateway.Put("/transactions/" + transactionId + "/settle"));
+ Assert.IsTrue(response.IsSuccess());
+ }
+
+ [Test]
+ public void Settle_RefundFailsWithNonSettledTransaction()
+ {
+ TransactionRequest request = new TransactionRequest
+ {
+ Amount = SandboxValues.TransactionAmount.AUTHORIZE,
+ CreditCardRequest = new CreditCardRequest
+ {
+ Number = SandboxValues.CreditCardNumber.VISA,
+ ExpirationDate = "05/2008"
+ }
+ };
+
+ Transaction transaction = gateway.Transaction.Sale(request).Target;
+ Assert.AreEqual(TransactionStatus.AUTHORIZED, transaction.Status);
+
+ Result<Transaction> result = gateway.Transaction.Refund(transaction.ID);
+ Assert.IsFalse(result.IsSuccess());
+
+ Assert.AreEqual("91506", result.Errors.ForObject("transaction").OnField("base").Code);
+ }
+ }
+}
223 Braintree.Tests/ValidationErrorsTest.cs
@@ -0,0 +1,223 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using Braintree;
+using System.Xml;
+
+namespace Braintree.Tests
+{
+ [TestFixture]
+ class ValidationErrorsTest
+ {
+ [Test]
+ public void OnField_WithValidationError()
+ {
+ ValidationErrors errors = new ValidationErrors();
+ errors.AddError("country_name", new ValidationError("1", "invalid country"));
+ Assert.AreEqual("1", errors.OnField("country_name").Code);
+ Assert.AreEqual("invalid country", errors.OnField("country_name").Message);
+ }
+
+ [Test]
+ public void OnField_WithNonExistingField()
+ {
+ ValidationErrors errors = new ValidationErrors();
+ Assert.IsNull(errors.OnField("foo"));
+ }
+
+ [Test]
+ public void ForObject_WithNestedErrors()
+ {
+ ValidationErrors addressErrors = new ValidationErrors();
+ addressErrors.AddError("country_name", new ValidationError("1", "invalid country"));
+
+ ValidationErrors errors = new ValidationErrors();
+ errors.AddErrors("address", addressErrors);
+ Assert.AreEqual("1", errors.ForObject("address").OnField("country_name").Code);
+ Assert.AreEqual("invalid country", errors.ForObject("address").OnField("country_name").Message);
+ }
+
+ [Test]
+ public void ForObject_WithNonExistingObject()
+ {
+ ValidationErrors errors = new ValidationErrors();
+ Assert.IsNull(errors.ForObject("address"));
+ }
+
+ [Test]
+ public void Size_WithShallowErrors()
+ {
+ ValidationErrors errors = new ValidationErrors();
+ errors.AddError("country_name", new ValidationError("1", "invalid country"));
+ errors.AddError("another_field", new ValidationError("2", "another message"));
+ Assert.AreEqual(2, errors.size());
+ }
+
+ [Test]
+ public void DeepSize_WithNestedErrors()
+ {
+ ValidationErrors addressErrors = new ValidationErrors();
+ addressErrors.AddError("country_name", new ValidationError("1", "invalid country"));
+ addressErrors.AddError("another_field", new ValidationError("2", "another message"));
+
+ ValidationErrors errors = new ValidationErrors();
+ errors.AddError("some_field", new ValidationError("3", "some message"));
+ errors.AddErrors("address", addressErrors);
+
+ Assert.AreEqual(3, errors.DeepSize());
+ Assert.AreEqual(1, errors.size());
+
+ Assert.AreEqual(2, errors.ForObject("address").DeepSize());
+ Assert.AreEqual(2, errors.ForObject("address").size());
+ }
+
+ [Test]
+ public void Constructor_ParsesSimpleValidationErrors()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <errors>");
+ builder.Append(" <address>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>91803</code>");
+ builder.Append(" <message>Country name is not an accepted country.</message>");
+ builder.Append(" <attribute type=\"symbol\">country_name</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" </address>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+ ValidationErrors errors = new ValidationErrors(new NodeWrapper(doc.ChildNodes[1]));
+ Assert.AreEqual(1, errors.DeepSize());
+ Assert.AreEqual("91803", errors.ForObject("address").OnField("country_name").Code);
+ }
+
+ [Test]
+ public void Constructor_ParsesMulitpleValidationErrorsOnOneObject()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <errors>");
+ builder.Append(" <address>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>1</code>");
+ builder.Append(" <message>Country name is not an accepted country.</message>");
+ builder.Append(" <attribute type=\"symbol\">country_name</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" <error>");
+ builder.Append(" <code>2</code>");
+ builder.Append(" <message>Street address is too long.</message>");
+ builder.Append(" <attribute type=\"symbol\">street_address</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" </address>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+ ValidationErrors errors = new ValidationErrors(new NodeWrapper(doc.ChildNodes[1]));
+ Assert.AreEqual(2, errors.DeepSize());
+ Assert.AreEqual("1", errors.ForObject("address").OnField("country_name").Code);
+ Assert.AreEqual("2", errors.ForObject("address").OnField("street_address").Code);
+ }
+
+ [Test]
+ public void Constructor_ParsesValidationErrorOnNestedObject()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <errors>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" <credit-card>");
+ builder.Append(" <billing-address>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>91803</code>");
+ builder.Append(" <message>Country name is not an accepted country.</message>");
+ builder.Append(" <attribute type=\"symbol\">country_name</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" </billing-address>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </credit-card>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+ ValidationErrors errors = new ValidationErrors(new NodeWrapper(doc.ChildNodes[1]));
+ Assert.AreEqual(1, errors.DeepSize());
+ Assert.AreEqual("91803", errors.ForObject("credit-card").ForObject("billing-address").OnField("country_name").Code);
+ }
+
+ [Test]
+ public void Constructor_ParsesValidationErrorsAtMultipleLevels()
+ {
+ StringBuilder builder = new StringBuilder();
+ builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ builder.Append("<api-error-response>");
+ builder.Append(" <errors>");
+ builder.Append(" <customer>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>81608</code>");
+ builder.Append(" <message>First name is too long.</message>");
+ builder.Append(" <attribute type=\"symbol\">first_name</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" <credit-card>");
+ builder.Append(" <billing-address>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>91803</code>");
+ builder.Append(" <message>Country name is not an accepted country.</message>");
+ builder.Append(" <attribute type=\"symbol\">country_name</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" </billing-address>");
+ builder.Append(" <errors type=\"array\">");
+ builder.Append(" <error>");
+ builder.Append(" <code>81715</code>");
+ builder.Append(" <message>Credit card number is invalid.</message>");
+ builder.Append(" <attribute type=\"symbol\">number</attribute>");
+ builder.Append(" </error>");
+ builder.Append(" </errors>");
+ builder.Append(" </credit-card>");
+ builder.Append(" </customer>");
+ builder.Append(" <errors type=\"array\"/>");
+ builder.Append(" </errors>");
+ builder.Append("</api-error-response>");
+
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(builder.ToString());
+ ValidationErrors errors = new ValidationErrors(new NodeWrapper(doc.ChildNodes[1]));
+
+ Assert.AreEqual(3, errors.DeepSize());
+ Assert.AreEqual(0, errors.size());
+
+ Assert.AreEqual(3, errors.ForObject("customer").DeepSize());
+ Assert.AreEqual(1, errors.ForObject("customer").size());
+ Assert.AreEqual("81608", errors.ForObject("customer").OnField("first_name").Code);
+
+ Assert.AreEqual(2, errors.ForObject("customer").ForObject("credit-card").DeepSize());
+ Assert.AreEqual(1, errors.ForObject("customer").ForObject("credit-card").size());
+ Assert.AreEqual("81715", errors.ForObject("customer").ForObject("credit-card").OnField("number").Code);
+
+ Assert.AreEqual(1, errors.ForObject("customer").ForObject("credit-card").ForObject("billing-address").DeepSize());
+ Assert.AreEqual(1, errors.ForObject("customer").ForObject("credit-card").ForObject("billing-address").size());
+ Assert.AreEqual("91803", errors.ForObject("customer").ForObject("credit-card").ForObject("billing-address").OnField("country_name").Code);
+ }
+ }
+}
22 Braintree.Tests/WebServiceGatewayTest.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+
+namespace Braintree
+{
+ [TestFixture]
+ class WebServiceGatewayTest
+ {
+ [Test]
+ public void SslCertificateSuccessful()
+ {
+ Configuration.Environment = Environment.QA;
+ Configuration.MerchantID = "integration_merchant_id";
+ Configuration.PublicKey = "integration_public_key";
+ Configuration.PrivateKey = "integration_private_key";
+
+ WebServiceGateway.Get("/customers/131866");
+ }
+ }
+}
3 Braintree.Tests/app.config
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
26 Braintree.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C# Express 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Braintree", "Braintree\Braintree.csproj", "{D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Braintree.Tests", "Braintree.Tests\Braintree.Tests.csproj", "{60234E7B-1181-4EFF-96EE-624B4524D788}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D0A473FA-E30B-4AF8-BB78-C1D81C9CAAB5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {60234E7B-1181-4EFF-96EE-624B4524D788}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {60234E7B-1181-4EFF-96EE-624B4524D788}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {60234E7B-1181-4EFF-96EE-624B4524D788}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {60234E7B-1181-4EFF-96EE-624B4524D788}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
166 Braintree.sln.cache
@@ -0,0 +1,166 @@
+<Project DefaultTargets="Build" ToolsVersion="3.5" InitialTargets="ValidateSolutionConfiguration;ValidateToolsVersions" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <_SolutionProjectConfiguration>Debug|Any CPU</_SolutionProjectConfiguration>
+ <_SolutionProjectToolsVersion>3.5</_SolutionProjectToolsVersion>
+ <_SolutionProjectCacheVersion>3.5</_SolutionProjectCacheVersion>
+ </PropertyGroup>
+ <ItemGroup>
+ <_SolutionProjectProjects Include="Braintree.Tests\Braintree.Tests.csproj" />
+ <_SolutionProjectProjects Include="Braintree\Braintree.csproj" />
+ </ItemGroup>
+ <ItemGroup Condition=" ('$(Configuration)' == 'Debug') and ('$(Platform)' == 'Any CPU') ">
+ <BuildLevel0 Include="Braintree\Braintree.csproj">
+ <Configuration>Debug</Configuration>