Skip to content

Commit

Permalink
5.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
braintreeps committed Apr 13, 2021
1 parent 5b0c023 commit 8278c80
Show file tree
Hide file tree
Showing 20 changed files with 447 additions and 63 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Unreleased
* Add `PhoneNumber` to `Address` (thanks @glennsdavis!)
## 5.5.0
- Add `StoreId` and `StoreIds` to `TransactionSearchRequest`
- Add support for `LocalPaymentReversed` webhook notifications
- Add `Transaction.AdjustAuthorization` method to support for multiple authorizations for a single transaction
- Add `MerchantAccountId` to `TransactionRefundRequest`
- Add `PhoneNumber` to `Address` (thanks @glennsdavis!)

## 5.4.0
- Add missing `ExpirationMonth`, `ExpirationYear`, and `IsNetworkTokenized` fields in `PaymentMethodNonceDetails` (thanks @glennsdavis for `ExpirationMonth` and `ExpirationYear`!)
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ Braintree employs a deprecation policy for our SDKs. For more information on the
| Major version number | Status | Released | Deprecated | Unsupported |
| -------------------- | ----------- | --------------- | ------------ | ------------ |
| 5.x.x | Active | August 2020 | TBA | TBA |
| 4.x.x | Inactive | March 2018 | June 2022 | June 2023 |
| 3.x.x | Unsupported | September 2016 | March 2018 | March 2018 |
| 2.x.x | Unsupported | April 2010 | March 2018 | March 2018 |
| 1.x.x | Unsupported | April 2010 | March 2018 | March 2018 |

| 4.x.x | Inactive | March 2018 | August 2022 | August 2023 |

## Documentation

Expand Down
12 changes: 6 additions & 6 deletions src/Braintree/Braintree.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
<PropertyGroup>
<Description>Braintree Client Library</Description>
<Copyright>Copyright © Braintree, a division of PayPal, Inc. 2021</Copyright>
<VersionPrefix>5.4.0</VersionPrefix>
<VersionPrefix>5.5.0</VersionPrefix>
<Authors>Braintree</Authors>
<!-- We target NET standard 2.0 so that we can support NET Core 2.1. When NET Core 2.1 reaches EOL, we can update to Net Standard 2.1 -->
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<AssemblyName>Braintree</AssemblyName>
<PackageId>Braintree</PackageId>
<PackageTags>braintree;paypal;venmo;intenational;payments;gateway;currencies;money;visa;mastercard;bitcoin;maestro;apple pay;android pay;amex;jcb;diners club;discover;american express</PackageTags>
<PackageReleaseNotes>
- Add missing `ExpirationMonth`, `ExpirationYear`, and `IsNetworkTokenized` fields in `PaymentMethodNonceDetails` (thanks @glennsdavis for `ExpirationMonth` and `ExpirationYear`!)
- Add `ThreeDSecureAuthenticationInfo` and `ThreeDSecureLookupInfo` classes
- Add `AcsTransactionId`, `ParesStatus`, `ThreeDSecureTransactionId`, `Lookup`, and `Authentication` to `ThreeDSecureInfo`
- Add `DecisionReasons` and `TransactionRiskScore` fields to `RiskData`
- Add overload on `SubmitForSettlementAsync` method to include `TransactionRequest` (thanks @edtyl3r!)
- Add `StoreId` and `StoreIds` to `TransactionSearchRequest`
- Add support for `LocalPaymentReversed` webhook notifications
- Add `Transaction.AdjustAuthorization` method to support for multiple authorizations for a single transaction
- Add `MerchantAccountId` to `TransactionRefundRequest`
- Add `PhoneNumber` to `Address`
</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/braintree/braintree_dotnet</PackageProjectUrl>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
Expand Down
3 changes: 3 additions & 0 deletions src/Braintree/HttpService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public class HttpService
public HttpService(Configuration configuration)
{
Configuration = configuration;
// NEXT_MAJOR_VERSION setting Configuration in an existing gateway instance does NOT update
// the underlying httpClient in this service. We should pull Proxy and Timeout settings out
// of the Configuration class for easier setting an existing gateway
#if netcore
var httpClientHandler = new HttpClientHandler
{
Expand Down
2 changes: 2 additions & 0 deletions src/Braintree/ITransactionGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace Braintree
/// </summary>
public interface ITransactionGateway
{
Result<Transaction> AdjustAuthorization(string id, decimal amount);
Task<Result<Transaction>> AdjustAuthorizationAsync(string id, decimal amount);
Result<Transaction> CancelRelease(string id);
Task<Result<Transaction>> CancelReleaseAsync(string id);
Result<Transaction> CloneTransaction(string id, TransactionCloneRequest cloneRequest);
Expand Down
17 changes: 17 additions & 0 deletions src/Braintree/LocalPaymentReversed.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;

namespace Braintree
{
public class LocalPaymentReversed
{
public virtual string PaymentId { get; protected set; }

protected internal LocalPaymentReversed(NodeWrapper node, IBraintreeGateway gateway)
{
PaymentId = node.GetString("payment-id");
}

[Obsolete("Mock Use Only")]
protected internal LocalPaymentReversed() { }
}
}
4 changes: 2 additions & 2 deletions src/Braintree/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("5.4.0.0")]
[assembly: AssemblyFileVersion("5.4.0.0")]
[assembly: AssemblyVersion("5.5.0.0")]
[assembly: AssemblyFileVersion("5.5.0.0")]
22 changes: 22 additions & 0 deletions src/Braintree/TransactionGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,28 @@ protected internal TransactionGateway(IBraintreeGateway gateway)
service = gateway.Service;
}

public virtual Result<Transaction> AdjustAuthorization(string id, decimal amount)
{
var request = new TransactionRequest
{
Amount = amount
};
XmlNode response = service.Put(service.MerchantPath() + "/transactions/" + id + "/adjust_authorization", request);

return new ResultImpl<Transaction>(new NodeWrapper(response), gateway);
}

public virtual async Task<Result<Transaction>> AdjustAuthorizationAsync(string id, decimal amount)
{
var request = new TransactionRequest
{
Amount = amount
};
XmlNode response = await service.PutAsync(service.MerchantPath() + "/transactions/" + id + "/adjust_authorization", request).ConfigureAwait(false);

return new ResultImpl<Transaction>(new NodeWrapper(response), gateway);
}

public virtual Result<Transaction> CancelRelease(string id)
{
var request = new TransactionRequest();
Expand Down
2 changes: 2 additions & 0 deletions src/Braintree/TransactionRefundRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Braintree
public class TransactionRefundRequest : Request
{
public decimal Amount { get; set; }
public string MerchantAccountId { get; set; }
public string OrderId { get; set; }

public override string ToXml()
Expand Down Expand Up @@ -34,6 +35,7 @@ protected virtual RequestBuilder BuildRequest(string root)
if (Amount != 0)
builder.AddElement("amount", Amount);

builder.AddElement("merchant-account-id", MerchantAccountId);
builder.AddElement("order-id", OrderId);

return builder;
Expand Down
4 changes: 4 additions & 0 deletions src/Braintree/TransactionSearchRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ public class TransactionSearchRequest : SearchRequest

public EnumMultipleValueNode<TransactionSearchRequest, TransactionSource> Source => new EnumMultipleValueNode<TransactionSearchRequest, TransactionSource>("source", this);

public TextNode<TransactionSearchRequest> StoreId => new TextNode<TransactionSearchRequest>("store-id", this);

public MultipleValueNode<TransactionSearchRequest, string> StoreIds => new MultipleValueNode<TransactionSearchRequest, string>("store-ids", this);

public EnumMultipleValueNode<TransactionSearchRequest, TransactionType> Type => new EnumMultipleValueNode<TransactionSearchRequest, TransactionType>("type", this);

public DateRangeNode<TransactionSearchRequest> VoidedAt => new DateRangeNode<TransactionSearchRequest>("voided-at", this);
Expand Down
10 changes: 9 additions & 1 deletion src/Braintree/ValidationErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public enum ValidationErrorCode
ADDRESS_STREET_ADDRESS_IS_REQUIRED = 81811,
ADDRESS_STREET_ADDRESS_IS_TOO_LONG = 81812,
ADDRESS_TOO_MANY_ADDRESSES_PER_CUSTOMER = 91818,

APPLE_PAY_CARDS_ARE_NOT_ACCEPTED = 83501,
APPLE_PAY_CUSTOMER_ID_IS_REQUIRED_FOR_VAULTING = 83502,
APPLE_PAY_TOKEN_IS_IN_USE = 93503,
Expand Down Expand Up @@ -428,6 +428,8 @@ public enum ValidationErrorCode
MERCHANT_ACCOUNT_INDIVIDUAL_ADDRESS_POSTAL_CODE_IS_REQUIRED = 82659,
MERCHANT_ACCOUNT_INDIVIDUAL_ADDRESS_REGION_IS_INVALID = 82668,
MERCHANT_ACCOUNT_INDIVIDUAL_ADDRESS_REGION_IS_REQUIRED = 82660,

NO_NET_AMOUNT_TO_PERFORM_AUTH_ADJUSTMENT = 95606,

OAUTH_INVALID_GRANT = 93801,
OAUTH_INVALID_CREDENTIALS = 93802,
Expand Down Expand Up @@ -462,6 +464,10 @@ public enum ValidationErrorCode
PAYPAL_ACCOUNT_PAYPAL_ACCOUNTS_ARE_NOT_ACCEPTED = 82904,
PAYPAL_ACCOUNT_PAYPAL_COMMUNICATION_ERROR = 92910,
PAYPAL_ACCOUNT_TOKEN_IS_IN_USE = 92906,

PROCESSOR_DOES_NOT_SUPPORT_AUTH_ADJUSTMENT = 915222,
PROCESSOR_DOES_NOT_SUPPORT_INCREMENTAL_AUTH = 915220,
PROCESSOR_DOES_NOT_SUPPORT_PARTIAL_AUTH_REVERSAL = 915221,

SETTLEMENT_BATCH_SUMMARY_CUSTOM_FIELD_IS_INVALID = 82303,
SETTLEMENT_BATCH_SUMMARY_SETTLEMENT_DATE_IS_INVALID = 82302,
Expand Down Expand Up @@ -569,6 +575,7 @@ public enum ValidationErrorCode
TRANSACTION_CUSTOMER_DOES_NOT_HAVE_CREDIT_CARD = 91511,
TRANSACTION_CUSTOMER_ID_IS_INVALID = 91510,
TRANSACTION_HAS_ALREADY_BEEN_REFUNDED = 91512,
TRANSACTION_IS_NOT_ELIGIBLE_FOR_ADJUSTMENT = 915219,
TRANSACTION_TOO_MANY_LINE_ITEMS = 915157,
TRANSACTION_LINE_ITEMS_EXPECTED = 915158,
TRANSACTION_MERCHANT_ACCOUNT_DOES_NOT_MATCH3_D_SECURE_MERCHANT_ACCOUNT = 91584,
Expand All @@ -577,6 +584,7 @@ public enum ValidationErrorCode
TRANSACTION_MERCHANT_ACCOUNT_ID_DOES_NOT_MATCH_SUBSCRIPTION = 915180,
TRANSACTION_MERCHANT_ACCOUNT_ID_IS_INVALID = 91513,
TRANSACTION_MERCHANT_ACCOUNT_IS_SUSPENDED = 91514,
TRANSACTION_MUST_BE_IN_STATE_AUTHORIZED = 915218,
TRANSACTION_OPTIONS_PAY_PAL_CUSTOM_FIELD_TOO_LONG = 91580,
TRANSACTION_OPTIONS_SUBMIT_FOR_SETTLEMENT_IS_REQUIRED_FOR_CLONING = 91544,
TRANSACTION_OPTIONS_SUBMIT_FOR_SETTLEMENT_IS_REQUIRED_FOR_PAYPAL_UNILATERAL = 91582,
Expand Down
76 changes: 41 additions & 35 deletions src/Braintree/WebhookNotification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,65 @@ namespace Braintree
{
public enum WebhookKind
{
[Description("account_updater_daily_report")] ACCOUNT_UPDATER_DAILY_REPORT,
[Description("check")] CHECK,
[Description("connected_merchant_paypal_status_changed")] CONNECTED_MERCHANT_PAYPAL_STATUS_CHANGED,
[Description("connected_merchant_status_transitioned")] CONNECTED_MERCHANT_STATUS_TRANSITIONED,
[Description("disbursement")] DISBURSEMENT,
[Description("disbursement_exception")] DISBURSEMENT_EXCEPTION,
[Description("dispute_accepted")] DISPUTE_ACCEPTED,
[Description("dispute_disputed")] DISPUTE_DISPUTED,
[Description("dispute_expired")] DISPUTE_EXPIRED,
[Description("dispute_lost")] DISPUTE_LOST,
[Description("dispute_opened")] DISPUTE_OPENED,
[Description("dispute_won")] DISPUTE_WON,
[Description("grantor_updated_granted_payment_method")] GRANTOR_UPDATED_GRANTED_PAYMENT_METHOD,
[Description("granted_payment_method_revoked")] GRANTED_PAYMENT_METHOD_REVOKED,
[Description("local_payment_completed")] LOCAL_PAYMENT_COMPLETED,
[Description("local_payment_reversed")] LOCAL_PAYMENT_REVERSED,
[Description("oauth_access_revoked")] OAUTH_ACCESS_REVOKED,
[Description("partner_merchant_connected")] PARTNER_MERCHANT_CONNECTED,
[Description("partner_merchant_disconnected")] PARTNER_MERCHANT_DISCONNECTED,
[Description("partner_merchant_declined")] PARTNER_MERCHANT_DECLINED,
[Description("oauth_access_revoked")] OAUTH_ACCESS_REVOKED,
[Description("connected_merchant_status_transitioned")] CONNECTED_MERCHANT_STATUS_TRANSITIONED,
[Description("connected_merchant_paypal_status_changed")] CONNECTED_MERCHANT_PAYPAL_STATUS_CHANGED,
[Description("partner_merchant_disconnected")] PARTNER_MERCHANT_DISCONNECTED,
[Description("payment_method_revoked_by_customer")] PAYMENT_METHOD_REVOKED_BY_CUSTOMER,
[Description("recipient_updated_granted_payment_method")] RECIPIENT_UPDATED_GRANTED_PAYMENT_METHOD,
[Description("subscription_canceled")] SUBSCRIPTION_CANCELED,
[Description("subscription_expired")] SUBSCRIPTION_EXPIRED,
[Description("subscription_charged_successfully")] SUBSCRIPTION_CHARGED_SUCCESSFULLY,
[Description("subscription_charged_unsuccessfully")] SUBSCRIPTION_CHARGED_UNSUCCESSFULLY,
[Description("subscription_expired")] SUBSCRIPTION_EXPIRED,
[Description("subscription_trial_ended")] SUBSCRIPTION_TRIAL_ENDED,
[Description("subscription_went_active")] SUBSCRIPTION_WENT_ACTIVE,
[Description("subscription_went_past_due")] SUBSCRIPTION_WENT_PAST_DUE,
[Description("sub_merchant_account_approved")] SUB_MERCHANT_ACCOUNT_APPROVED,
[Description("sub_merchant_account_declined")] SUB_MERCHANT_ACCOUNT_DECLINED,
[Description("unrecognized")] UNRECOGNIZED,
[Description("transaction_disbursed")] TRANSACTION_DISBURSED,
[Description("transaction_settled")] TRANSACTION_SETTLED,
[Description("transaction_settlement_declined")] TRANSACTION_SETTLEMENT_DECLINED,
[Description("disbursement_exception")] DISBURSEMENT_EXCEPTION,
[Description("disbursement")] DISBURSEMENT,
[Description("dispute_opened")] DISPUTE_OPENED,
[Description("dispute_lost")] DISPUTE_LOST,
[Description("dispute_won")] DISPUTE_WON,
[Description("dispute_accepted")] DISPUTE_ACCEPTED,
[Description("dispute_disputed")] DISPUTE_DISPUTED,
[Description("dispute_expired")] DISPUTE_EXPIRED,
[Description("account_updater_daily_report")] ACCOUNT_UPDATER_DAILY_REPORT,
[Description("grantor_updated_granted_payment_method")] GRANTOR_UPDATED_GRANTED_PAYMENT_METHOD,
[Description("recipient_updated_granted_payment_method")] RECIPIENT_UPDATED_GRANTED_PAYMENT_METHOD,
[Description("granted_payment_method_revoked")] GRANTED_PAYMENT_METHOD_REVOKED,
[Description("payment_method_revoked_by_customer")] PAYMENT_METHOD_REVOKED_BY_CUSTOMER,
[Description("local_payment_completed")] LOCAL_PAYMENT_COMPLETED
[Description("unrecognized")] UNRECOGNIZED
}

public class WebhookNotification
{
public virtual AccountUpdaterDailyReport AccountUpdaterDailyReport { get; protected set; }
public virtual ConnectedMerchantPayPalStatusChanged ConnectedMerchantPayPalStatusChanged { get; protected set; }
public virtual ConnectedMerchantStatusTransitioned ConnectedMerchantStatusTransitioned { get; protected set; }
public virtual Disbursement Disbursement { get; protected set; }
public virtual Dispute Dispute { get; protected set; }
public virtual ValidationErrors Errors { get; protected set; }
public virtual GrantedPaymentInstrumentUpdate GrantedPaymentInstrumentUpdate { get; protected set; }
public virtual WebhookKind Kind { get; protected set; }
public virtual Subscription Subscription { get; protected set; }
public virtual MerchantAccount MerchantAccount { get; protected set; }
public virtual ValidationErrors Errors { get; protected set; }
public virtual LocalPaymentCompleted LocalPaymentCompleted { get; protected set; }
public virtual LocalPaymentReversed LocalPaymentReversed { get; protected set; }
public virtual PartnerMerchant PartnerMerchant { get; protected set; }
public virtual string Message { get; protected set; }
public virtual RevokedPaymentMethodMetadata RevokedPaymentMethodMetadata { get; protected set; }
public virtual string SourceMerchantId { get; protected set; }
public virtual Subscription Subscription { get; protected set; }
public virtual DateTime? Timestamp { get; protected set; }
public virtual Transaction Transaction { get; protected set; }
public virtual Disbursement Disbursement { get; protected set; }
public virtual Dispute Dispute { get; protected set; }
public virtual PartnerMerchant PartnerMerchant { get; protected set; }
public virtual OAuthAccessRevocation OAuthAccessRevocation { get; protected set; }
public virtual ConnectedMerchantStatusTransitioned ConnectedMerchantStatusTransitioned { get; protected set; }
public virtual ConnectedMerchantPayPalStatusChanged ConnectedMerchantPayPalStatusChanged { get; protected set; }
public virtual AccountUpdaterDailyReport AccountUpdaterDailyReport { get; protected set; }
public virtual GrantedPaymentInstrumentUpdate GrantedPaymentInstrumentUpdate { get; protected set; }
public virtual RevokedPaymentMethodMetadata RevokedPaymentMethodMetadata { get; protected set; }
public virtual string SourceMerchantId { get; protected set; }
public virtual LocalPaymentCompleted LocalPaymentCompleted { get; protected set; }



public WebhookNotification(NodeWrapper node, IBraintreeGateway gateway)
{
Timestamp = node.GetDateTime("timestamp");
Expand Down Expand Up @@ -155,9 +156,14 @@ public WebhookNotification(NodeWrapper node, IBraintreeGateway gateway)
if (WrapperNode.GetNode("local-payment") != null)
{
LocalPaymentCompleted = new LocalPaymentCompleted(WrapperNode.GetNode("local-payment"), gateway);
}

if (WrapperNode.GetNode("local-payment-reversed") != null)
{
LocalPaymentReversed = new LocalPaymentReversed(WrapperNode.GetNode("local-payment-reversed"), gateway);
}
}

protected internal WebhookNotification() { }
}
}
8 changes: 8 additions & 0 deletions src/Braintree/WebhookTestingGateway.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ private string SubjectSampleXml(WebhookKind kind, string id)
return PaymentMethodRevokedByCustomerSampleXml(id);
} else if (kind == WebhookKind.LOCAL_PAYMENT_COMPLETED) {
return LocalPaymentCompletedSampleXml();
} else if (kind == WebhookKind.LOCAL_PAYMENT_REVERSED) {
return LocalPaymentReversedSampleXml();
} else {
return SubscriptionXml(id);
}
Expand Down Expand Up @@ -547,6 +549,12 @@ private static string LocalPaymentCompletedSampleXml() {
);
}

private static string LocalPaymentReversedSampleXml() {
return Node("local-payment-reversed",
Node("payment-id", "a-payment-id")
);
}

private static string Node(string name, params string[] contents) {
return NodeAttr(name, null, contents);
}
Expand Down
1 change: 1 addition & 0 deletions test/Braintree.TestUtil/MerchantAccountIDs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public class MerchantAccountIDs
public static string ADYEN_MERCHANT_ACCOUNT_ID = "adyen_ma";
public static string BRAZIL_MERCHANT_ACCOUNT_ID = "hiper_brl";
public static string CARD_PROCESSOR_BRAZIL_MERCHANT_ACCOUNT_ID = "card_processor_brl";
public static string FAKE_FIRST_DATA_MERCHANT_ACCOUNT_ID = "fake_first_data_merchant_account";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public BraintreeGateway GetGateway()
}

[Test]
[Ignore("unpend when we have a more stable CI")]
public void TokenizeRawCreditCardDetailsWithGraphQL_isSuccessful()
{
BraintreeGateway gateway = GetGateway();
Expand Down Expand Up @@ -71,6 +72,7 @@ ... on CreditCardDetails {
}

[Test]
[Ignore("unpend when we have a more stable CI")]
#if netcore
public async Task TokenizeRawCreditCardDetailsWithGraphQLAsync_isSuccessful()
#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,6 @@ public void VerifyValidCreditCardWithVerificationRiskData()
Assert.IsNotNull(verification.RiskData);
Assert.IsNotNull(verification.RiskData.decision);
Assert.IsNotNull(verification.RiskData.DecisionReasons);
Assert.IsNotNull(verification.RiskData.fraudServiceProvider);
Assert.IsNotNull(verification.RiskData.id);
}

Expand Down
Loading

0 comments on commit 8278c80

Please sign in to comment.