diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aaa59af..cc66891c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.20.0 +- Add `SUBSCRIPTIONBILLINGSKIPPED` webhook notification support +- Add `implicitlyVaultedPaymentMethodToken` and `implicitlyVaultedPaymentMethodGlobalId` to `LocalPaymentDetails` + ## 5.19.0 - Add `MerchantTokenIdentifier`, `SourceCardLast4` to `ApplePayCard` and `ApplePayDetails` - Add `ThreeDSecureAuthenticationId` to `CustomerRequest` and `PaymentMethodRequest` diff --git a/src/Braintree/Braintree.csproj b/src/Braintree/Braintree.csproj index 2957b85a..91f2ef5b 100644 --- a/src/Braintree/Braintree.csproj +++ b/src/Braintree/Braintree.csproj @@ -4,7 +4,7 @@ Braintree Client Library Copyright © Braintree, a division of PayPal, Inc. 2021 - 5.19.0 + 5.20.0 Braintree net452;netstandard2.0 @@ -12,13 +12,8 @@ Braintree braintree;paypal;venmo;intenational;payments;gateway;currencies;money;visa;mastercard;bitcoin;maestro;apple pay;android pay;amex;jcb;diners club;discover;american express - - Add `MerchantTokenIdentifier`, `SourceCardLast4` to `ApplePayCard` and `ApplePayDetails` - - Add `ThreeDSecureAuthenticationId` to `CustomerRequest` and `PaymentMethodRequest` - - Add `processing_overrides` to `Transaction.sale` options - - Add industry data fields to `TransactionRequest` - - `ArrivalDate` - - `TicketIssuerAddress` - - Remove `byte[]` to `String` content conversion for requests containing files in `BraintreeService` + - Add `SUBSCRIPTIONBILLINGSKIPPED` webhook notification support + - Add `implicitlyVaultedPaymentMethodToken` and `implicitlyVaultedPaymentMethodGlobalId` to `LocalPaymentDetails` https://github.com/braintree/braintree_dotnet false diff --git a/src/Braintree/LocalPaymentDetails.cs b/src/Braintree/LocalPaymentDetails.cs index e03918c8..192e973f 100644 --- a/src/Braintree/LocalPaymentDetails.cs +++ b/src/Braintree/LocalPaymentDetails.cs @@ -9,6 +9,8 @@ public class LocalPaymentDetails public virtual string DebugId { get; protected set; } public virtual string Description { get; protected set; } public virtual string FundingSource { get; protected set; } + public virtual string ImplicitlyVaultedPaymentMethodGlobalId { get; protected set; } + public virtual string ImplicitlyVaultedPaymentMethodToken { get; protected set; } public virtual string PayerId { get; protected set; } public virtual string PaymentId { get; protected set; } public virtual string RefundFromTransactionFeeAmount { get; protected set; } @@ -24,6 +26,8 @@ protected internal LocalPaymentDetails(NodeWrapper node) DebugId = node.GetString("debug-id"); Description = node.GetString("description"); FundingSource = node.GetString("funding-source"); + ImplicitlyVaultedPaymentMethodGlobalId = node.GetString("implicitly-vaulted-payment-method-global-id"); + ImplicitlyVaultedPaymentMethodToken = node.GetString("implicitly-vaulted-payment-method-token"); PayerId = node.GetString("payer-id"); PaymentId = node.GetString("payment-id"); RefundFromTransactionFeeAmount = node.GetString("refund-from-transaction-fee-amount"); diff --git a/src/Braintree/Properties/AssemblyInfo.cs b/src/Braintree/Properties/AssemblyInfo.cs index 5f90b82d..213d902d 100644 --- a/src/Braintree/Properties/AssemblyInfo.cs +++ b/src/Braintree/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // Build Number // Revision // -[assembly: AssemblyVersion("5.19.0.0")] -[assembly: AssemblyFileVersion("5.19.0.0")] +[assembly: AssemblyVersion("5.20.0.0")] +[assembly: AssemblyFileVersion("5.20.0.0")] diff --git a/src/Braintree/WebhookNotification.cs b/src/Braintree/WebhookNotification.cs index 397982a4..7cdac24f 100644 --- a/src/Braintree/WebhookNotification.cs +++ b/src/Braintree/WebhookNotification.cs @@ -33,6 +33,7 @@ public enum WebhookKind [Description("payment_method_customer_data_updated")] PAYMENT_METHOD_CUSTOMER_DATA_UPDATED, [Description("payment_method_revoked_by_customer")] PAYMENT_METHOD_REVOKED_BY_CUSTOMER, [Description("recipient_updated_granted_payment_method")] RECIPIENT_UPDATED_GRANTED_PAYMENT_METHOD, + [Description("subscription_billing_skipped")] SUBSCRIPTION_BILLING_SKIPPED, [Description("subscription_canceled")] SUBSCRIPTION_CANCELED, [Description("subscription_expired")] SUBSCRIPTION_EXPIRED, [Description("subscription_charged_successfully")] SUBSCRIPTION_CHARGED_SUCCESSFULLY, diff --git a/src/Braintree/WebhookTestingGateway.cs b/src/Braintree/WebhookTestingGateway.cs index bb6af6fc..1db34af8 100644 --- a/src/Braintree/WebhookTestingGateway.cs +++ b/src/Braintree/WebhookTestingGateway.cs @@ -88,6 +88,8 @@ private string SubjectSampleXml(WebhookKind kind, string id) return DisputeDisputedSampleXml(id); } else if (kind == WebhookKind.DISPUTE_EXPIRED) { return DisputeExpiredSampleXml(id); + } else if (kind == WebhookKind.SUBSCRIPTION_BILLING_SKIPPED) { + return SubscriptionBillingSkippedSampleXml(id); } else if (kind == WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY) { return SubscriptionChargedSuccessfullySampleXml(id); } else if (kind == WebhookKind.SUBSCRIPTION_CHARGED_UNSUCCESSFULLY) { @@ -427,6 +429,16 @@ private string SubscriptionXml(string id) ); } + private string SubscriptionBillingSkippedSampleXml(string id) + { + return Node("subscription", + Node("id", id), + NodeAttr("transactions", TYPE_ARRAY), + NodeAttr("add_ons", TYPE_ARRAY), + NodeAttr("discounts", TYPE_ARRAY) + ); + } + private string SubscriptionChargedSuccessfullySampleXml(string id) { return Node("subscription", diff --git a/test/Braintree.Tests.Integration/TransactionIntegrationTest.cs b/test/Braintree.Tests.Integration/TransactionIntegrationTest.cs index be326766..32465de8 100644 --- a/test/Braintree.Tests.Integration/TransactionIntegrationTest.cs +++ b/test/Braintree.Tests.Integration/TransactionIntegrationTest.cs @@ -10211,7 +10211,7 @@ public void Sale_NetworkTokenizedTransaction() { Assert.IsTrue(transactionResult.IsSuccess()); Transaction transaction = transactionResult.Target; Assert.IsTrue(transaction.ProcessedWithNetworkToken); - Assert.IsNull(transaction.Retried); + Assert.IsFalse(transaction.Retried); } [Test] @@ -10271,7 +10271,7 @@ public void Sale_NotAvailableForRetry() var transactionResult = gateway.Transaction.Sale(request); Assert.IsTrue(transactionResult.IsSuccess()); Transaction transaction = transactionResult.Target; - Assert.IsNull(transaction.Retried); + Assert.IsFalse(transaction.Retried); } [Test] diff --git a/test/Braintree.Tests/LocalPaymentDetailsTest.cs b/test/Braintree.Tests/LocalPaymentDetailsTest.cs new file mode 100644 index 00000000..9b03ffd0 --- /dev/null +++ b/test/Braintree.Tests/LocalPaymentDetailsTest.cs @@ -0,0 +1,57 @@ +using System.Xml; +using NUnit.Framework; + +namespace Braintree.Tests +{ + [TestFixture] + public class LocalPaymentDetailsTest + { + private NodeWrapper nodeFromXml(string xml) + { + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + XmlNode newNode = doc.DocumentElement; + return new NodeWrapper(newNode); + } + + [Test] + public void IncludesFields() + { + string xml = "" + + + "CAT-1234" + + "whatever" + + "DEB-1234" + + "Detailed text" + + "ideal" + + "abcdefgabcdefg" + + "cx9rav" + + "nothing" + + "ABC12345" + + "2.00" + + "EUR" + + "REF-1234" + + "10.00" + + "EUR" + + ""; + var node = nodeFromXml(xml); + + LocalPaymentDetails details = new LocalPaymentDetails(node); + + Assert.AreEqual("CAT-1234", details.CaptureId); + Assert.AreEqual("whatever", details.CustomField); + Assert.AreEqual("DEB-1234", details.DebugId); + Assert.AreEqual("Detailed text", details.Description); + Assert.AreEqual("ideal", details.FundingSource); + Assert.AreEqual("abcdefgabcdefg", details.ImplicitlyVaultedPaymentMethodGlobalId); + Assert.AreEqual("cx9rav", details.ImplicitlyVaultedPaymentMethodToken); + Assert.AreEqual("nothing", details.PayerId); + Assert.AreEqual("ABC12345", details.PaymentId); + Assert.AreEqual("2.00", details.RefundFromTransactionFeeAmount); + Assert.AreEqual("EUR", details.RefundFromTransactionFeeCurrencyIsoCode); + Assert.AreEqual("REF-1234", details.RefundId); + Assert.AreEqual("10.00", details.TransactionFeeAmount); + Assert.AreEqual("EUR", details.TransactionFeeCurrencyIsoCode); + } + } +} diff --git a/test/Braintree.Tests/WebhookNotificationTest.cs b/test/Braintree.Tests/WebhookNotificationTest.cs index b6324c55..8847f7c9 100644 --- a/test/Braintree.Tests/WebhookNotificationTest.cs +++ b/test/Braintree.Tests/WebhookNotificationTest.cs @@ -435,6 +435,20 @@ public void SampleNotification_ReturnsANotificationForAConnectedMerchantPayPalSt Assert.AreEqual("oauth_application_client_id", notification.ConnectedMerchantPayPalStatusChanged.OAuthApplicationClientId); } + [Test] + public void SampleNotification_ReturnsANotificationForSubscriptionBillingSkipped() + { + Dictionary sampleNotification = gateway.WebhookTesting.SampleNotification(WebhookKind.SUBSCRIPTION_BILLING_SKIPPED, "my_id"); + + WebhookNotification notification = gateway.WebhookNotification.Parse(sampleNotification["bt_signature"], sampleNotification["bt_payload"]); + + Assert.AreEqual(WebhookKind.SUBSCRIPTION_BILLING_SKIPPED, notification.Kind); + Assert.AreEqual("my_id", notification.Subscription.Id); + Assert.AreEqual(0, notification.Subscription.Transactions.Count); + Assert.AreEqual(0, notification.Subscription.Discounts.Count); + Assert.AreEqual(0, notification.Subscription.AddOns.Count); + } + [Test] public void SampleNotification_ReturnsANotificationForSubscriptionChargedSuccessfully() {