diff --git a/src/Stripe.net/Entities/PaymentIntents/PaymentIntent.cs b/src/Stripe.net/Entities/PaymentIntents/PaymentIntent.cs index d73abf0755..6ccc56e5ee 100644 --- a/src/Stripe.net/Entities/PaymentIntents/PaymentIntent.cs +++ b/src/Stripe.net/Entities/PaymentIntents/PaymentIntent.cs @@ -87,6 +87,9 @@ internal object InternalCustomer [JsonProperty("description")] public string Description { get; set; } + [JsonProperty("last_payment_error")] + public PaymentIntentLastPaymentError LastPaymentError { get; set; } + [JsonProperty("livemode")] public bool Livemode { get; set; } diff --git a/src/Stripe.net/Entities/PaymentIntents/PaymentIntentLastPaymentError.cs b/src/Stripe.net/Entities/PaymentIntents/PaymentIntentLastPaymentError.cs new file mode 100644 index 0000000000..8aa6ad2bf9 --- /dev/null +++ b/src/Stripe.net/Entities/PaymentIntents/PaymentIntentLastPaymentError.cs @@ -0,0 +1,34 @@ +namespace Stripe +{ + using System.Runtime.Serialization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using Stripe.Infrastructure; + + public class PaymentIntentLastPaymentError : StripeEntity + { + [JsonProperty("charge")] + public string ChargeId { get; set; } + + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("decline_code")] + public string DeclineCode { get; set; } + + [JsonProperty("doc_url")] + public string DocUrl { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("param")] + public string Param { get; set; } + + [JsonProperty("source")] + public IPaymentSource Source { get; set; } + + [JsonProperty("type")] + public string Type { get; set; } + } +} diff --git a/src/StripeTests/Entities/PaymentIntents/PaymentIntentTest.cs b/src/StripeTests/Entities/PaymentIntents/PaymentIntentTest.cs index 66184fb8d0..1af0f54fc8 100644 --- a/src/StripeTests/Entities/PaymentIntents/PaymentIntentTest.cs +++ b/src/StripeTests/Entities/PaymentIntents/PaymentIntentTest.cs @@ -91,5 +91,23 @@ public void DeserializeNextSourceActionUnknown() Assert.Equal("foo", intent.NextSourceAction.Type); Assert.Null(intent.NextSourceAction.AuthorizeWithUrl); } + + [Fact] + public void DeserializeLastPaymentError() + { + var json = GetResourceAsString("api_fixtures.payment_intent.last_payment_error.json"); + var intent = Mapper.MapFromJson(json); + + Assert.NotNull(intent); + Assert.IsType(intent); + Assert.NotNull(intent.Id); + Assert.Equal("payment_intent", intent.Object); + + var lastPaymentError = intent.LastPaymentError; + Assert.NotNull(lastPaymentError); + Assert.Equal("generic_decline", lastPaymentError.DeclineCode); + Assert.IsType(lastPaymentError.Source); + Assert.Equal("card_123", lastPaymentError.Source.Id); + } } } diff --git a/src/StripeTests/Resources/api_fixtures/payment_intent/last_payment_error.json b/src/StripeTests/Resources/api_fixtures/payment_intent/last_payment_error.json new file mode 100644 index 0000000000..7029abf22c --- /dev/null +++ b/src/StripeTests/Resources/api_fixtures/payment_intent/last_payment_error.json @@ -0,0 +1,64 @@ +{ + "id": "pi_123", + "object": "payment_intent", + "allowed_source_types": [ + "card" + ], + "amount": 100, + "amount_capturable": 0, + "amount_received": 0, + "application": null, + "application_fee_amount": null, + "canceled_at": null, + "cancellation_reason": null, + "capture_method": "automatic", + "charges": { + "object": "list", + "data": [ + { + "id": "ch_123", + "object": "charge" + } + ], + "has_more": false, + "total_count": 1, + "url": "\/v1\/charges?payment_intent=pi_123" + }, + "client_secret": null, + "confirmation_method": "publishable", + "created": 1541614878, + "currency": "eur", + "customer": "cus_DvnENrEbZJeIQE", + "description": "PaymentIntent Description", + "last_payment_error": { + "charge": "ch_123", + "code": "card_declined", + "decline_code": "generic_decline", + "doc_url": "https:\/\/stripe.com\/docs\/error-codes\/card-declined", + "message": "Your card was declined.", + "source": { + "id": "card_123", + "object": "card", + "brand": "Visa", + "country": "US", + "customer": "cus_123", + "exp_month": 9, + "exp_year": 2019, + "fingerprint": "fingerprint", + "last4": "0341" + }, + "type": "card_error" + }, + "livemode": false, + "next_source_action": null, + "on_behalf_of": null, + "receipt_email": null, + "return_url": null, + "review": null, + "shipping": null, + "source": null, + "statement_descriptor": null, + "status": "requires_source", + "transfer_data": null, + "transfer_group": null +}