From 23b08a253137197755497039159c529775c80095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armando=20Rodr=C3=ADguez?= <127134616+armando-rodriguez-cko@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:52:06 +0200 Subject: [PATCH] Update payment response post and get with account holder and payment plan. Add payment context sources (#433) --- src/CheckoutSdk/Common/PaymentSourceType.cs | 3 +- .../Payments/AccountUpdateStatus.cs | 19 +++++++ .../Payments/AmountVariabilityType.cs | 13 +++++ src/CheckoutSdk/Payments/PaymentPlan.cs | 24 +++++++++ .../Contexts/PaymentContextsStcpaySource.cs | 11 ++++ .../Contexts/PaymentContextsTabbySource.cs | 11 ++++ .../Payments/Response/GetPaymentResponse.cs | 32 +++++++----- .../Payments/Response/PaymentResponse.cs | 52 ++++++++++--------- .../Response/Source/CardResponseSource.cs | 4 ++ .../PaymentContextsStcpayResponseSource.cs | 12 +++++ .../PaymentContextsTabbyResponseSource.cs | 12 +++++ .../PaymentResponseSourceTypeConverter.cs | 10 ++++ .../PaymentContextsIntegrationTest.cs | 49 +++++++++++++++++ .../RequestApmPaymentsIntegrationTest.cs | 2 +- 14 files changed, 215 insertions(+), 39 deletions(-) create mode 100644 src/CheckoutSdk/Payments/AccountUpdateStatus.cs create mode 100644 src/CheckoutSdk/Payments/AmountVariabilityType.cs create mode 100644 src/CheckoutSdk/Payments/PaymentPlan.cs create mode 100644 src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsStcpaySource.cs create mode 100644 src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsTabbySource.cs create mode 100644 src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsStcpayResponseSource.cs create mode 100644 src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsTabbyResponseSource.cs diff --git a/src/CheckoutSdk/Common/PaymentSourceType.cs b/src/CheckoutSdk/Common/PaymentSourceType.cs index 550835fd..51b3020f 100644 --- a/src/CheckoutSdk/Common/PaymentSourceType.cs +++ b/src/CheckoutSdk/Common/PaymentSourceType.cs @@ -56,6 +56,7 @@ public enum PaymentSourceType [EnumMember(Value = "trustly")] Trustly, [EnumMember(Value = "cvconnect")] Cvconnect, [EnumMember(Value = "sepa")] Sepa, - [EnumMember(Value = "sequra")] Sequra + [EnumMember(Value = "sequra")] Sequra, + [EnumMember(Value = "tabby")] Tabby } } \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/AccountUpdateStatus.cs b/src/CheckoutSdk/Payments/AccountUpdateStatus.cs new file mode 100644 index 00000000..5f3b3101 --- /dev/null +++ b/src/CheckoutSdk/Payments/AccountUpdateStatus.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace Checkout.Payments +{ + public enum AccountUpdateStatus + { + [EnumMember(Value = "card_updated")] + CardUpdated, + + [EnumMember(Value = "card_expiry_updated")] + CardExpiryUpdated, + + [EnumMember(Value = "card_closed")] + CardClosed, + + [EnumMember(Value = "contact_cardholder")] + ContactCardholder + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/AmountVariabilityType.cs b/src/CheckoutSdk/Payments/AmountVariabilityType.cs new file mode 100644 index 00000000..f3bde86d --- /dev/null +++ b/src/CheckoutSdk/Payments/AmountVariabilityType.cs @@ -0,0 +1,13 @@ +using System.Runtime.Serialization; + +namespace Checkout.Payments +{ + public enum AmountVariabilityType + { + [EnumMember(Value = "Fixed")] + Fixed, + + [EnumMember(Value = "Variable")] + Variable + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/PaymentPlan.cs b/src/CheckoutSdk/Payments/PaymentPlan.cs new file mode 100644 index 00000000..7e860a98 --- /dev/null +++ b/src/CheckoutSdk/Payments/PaymentPlan.cs @@ -0,0 +1,24 @@ +using System; + +namespace Checkout.Payments +{ + public class PaymentPlan + { + // Recurring + public AmountVariabilityType? AmountVariability { get; set; } + + // Installment + public bool? Financing { get; set; } + + public string Amount { get; set; } + + // Common properties + public int? DaysBetweenPayments { get; set; } + + public int? TotalNumberOfPayments { get; set; } + + public int? CurrentPaymentNumber { get; set; } + + public DateTime Expiry { get; set; } + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsStcpaySource.cs b/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsStcpaySource.cs new file mode 100644 index 00000000..ab1798a8 --- /dev/null +++ b/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsStcpaySource.cs @@ -0,0 +1,11 @@ +using Checkout.Common; + +namespace Checkout.Payments.Request.Source.Contexts +{ + public class PaymentContextsStcpaySource : AbstractRequestSource + { + public PaymentContextsStcpaySource() : base(PaymentSourceType.Stcpay) + { + } + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsTabbySource.cs b/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsTabbySource.cs new file mode 100644 index 00000000..d41d2a83 --- /dev/null +++ b/src/CheckoutSdk/Payments/Request/Source/Contexts/PaymentContextsTabbySource.cs @@ -0,0 +1,11 @@ +using Checkout.Common; + +namespace Checkout.Payments.Request.Source.Contexts +{ + public class PaymentContextsTabbySource : AbstractRequestSource + { + public PaymentContextsTabbySource() : base(PaymentSourceType.Tabby) + { + } + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Response/GetPaymentResponse.cs b/src/CheckoutSdk/Payments/Response/GetPaymentResponse.cs index 0d1c3668..81fb13be 100644 --- a/src/CheckoutSdk/Payments/Response/GetPaymentResponse.cs +++ b/src/CheckoutSdk/Payments/Response/GetPaymentResponse.cs @@ -17,36 +17,42 @@ public class GetPaymentResponse : Resource public DateTime? RequestedOn { get; set; } + public string ProcessedOn { get; set; } + [JsonConverter(typeof(PaymentResponseSourceTypeConverter))] public IResponseSource Source { get; set; } [JsonConverter(typeof(PaymentResponseDestinationTypeConverter))] public IPaymentResponseDestination Destination { get; set; } - [JsonConverter(typeof(PaymentResponseSenderTypeConverter))] - public ISender Sender { get; set; } - public long? Amount { get; set; } public long? AmountRequested { get; set; } - + + [JsonConverter(typeof(PaymentResponseSenderTypeConverter))] + public ISender Sender { get; set; } + public Currency? Currency { get; set; } public PaymentType? PaymentType { get; set; } - public string Reference { get; set; } + public PaymentPlan PaymentPlan { get; set; } + public string Reference { get; set; } + public string Description { get; set; } - + public bool? Approved { get; set; } - + public DateTime? ExpiresOn { get; set; } - + public PaymentStatus? Status { get; set; } - + public PaymentResponseBalances Balances { get; set; } - - [JsonProperty(PropertyName = "3ds")] public ThreeDsData ThreeDs { get; set; } + + + [JsonProperty(PropertyName = "3ds")] + public ThreeDsData ThreeDs { get; set; } public RiskAssessment Risk { get; set; } @@ -83,8 +89,8 @@ public class GetPaymentResponse : Resource public bool? CkoNetworkTokenAvailable { get; set; } - public string ProcessedOn { get; set; } - public PaymentInstruction Instruction { get; set; } + + } } \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Response/PaymentResponse.cs b/src/CheckoutSdk/Payments/Response/PaymentResponse.cs index 1897b779..ae26a2d2 100644 --- a/src/CheckoutSdk/Payments/Response/PaymentResponse.cs +++ b/src/CheckoutSdk/Payments/Response/PaymentResponse.cs @@ -9,47 +9,51 @@ namespace Checkout.Payments.Response { public class PaymentResponse : Resource { + public string Id { get; set; } + public string ActionId { get; set; } public long? Amount { get; set; } - - public bool? Approved { get; set; } - - public string AuthCode { get; set; } - - public string Id { get; set; } - + + public long? AmountRequested { get; set; } + public Currency? Currency { get; set; } - public CustomerResponse Customer { get; set; } - - [JsonConverter(typeof(PaymentResponseSourceTypeConverter))] - public IResponseSource Source { get; set; } - + public bool? Approved { get; set; } + public PaymentStatus? Status { get; set; } - [JsonProperty(PropertyName = "3ds")] public ThreeDsEnrollment ThreeDs { get; set; } - - public string Reference { get; set; } - + public string AuthCode { get; set; } + public string ResponseCode { get; set; } - + public string ResponseSummary { get; set; } - + + + public DateTime? ExpiresOn { get; set; } + + [JsonProperty(PropertyName = "3ds")] + public ThreeDsEnrollment ThreeDs { get; set; } + public RiskAssessment Risk { get; set; } - + + [JsonConverter(typeof(PaymentResponseSourceTypeConverter))] + public IResponseSource Source { get; set; } + + public CustomerResponse Customer { get; set; } + + public PaymentResponseBalances Balances { get; set; } + public DateTime? ProcessedOn { get; set; } - public DateTime? ExpiresOn { get; set; } - - public PaymentResponseBalances Balances { get; set; } + public string Reference { get; set; } public PaymentProcessing Processing { get; set; } - + public string Eci { get; set; } public string SchemeId { get; set; } - + public PaymentRetryResponse Retry { get; set; } } } \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Response/Source/CardResponseSource.cs b/src/CheckoutSdk/Payments/Response/Source/CardResponseSource.cs index 4c5b8210..39e571d4 100644 --- a/src/CheckoutSdk/Payments/Response/Source/CardResponseSource.cs +++ b/src/CheckoutSdk/Payments/Response/Source/CardResponseSource.cs @@ -48,6 +48,10 @@ public class CardResponseSource : AbstractResponseSource, IResponseSource public string EncryptedCardNumber { get; set; } + public AccountUpdateStatus? AccountUpdateStatus { get; set; } + + public AccountHolder AccountHolder { get; set; } + public new PaymentSourceType? Type() { return base.Type; diff --git a/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsStcpayResponseSource.cs b/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsStcpayResponseSource.cs new file mode 100644 index 00000000..6b31aea7 --- /dev/null +++ b/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsStcpayResponseSource.cs @@ -0,0 +1,12 @@ +using Checkout.Common; + +namespace Checkout.Payments.Response.Source.Contexts +{ + public class PaymentContextsStcpayResponseSource : AbstractPaymentContextsResponseSource, IResponseSource + { + public new PaymentSourceType? Type() + { + return base.Type; + } + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsTabbyResponseSource.cs b/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsTabbyResponseSource.cs new file mode 100644 index 00000000..3c2c701c --- /dev/null +++ b/src/CheckoutSdk/Payments/Response/Source/Contexts/PaymentContextsTabbyResponseSource.cs @@ -0,0 +1,12 @@ +using Checkout.Common; + +namespace Checkout.Payments.Response.Source.Contexts +{ + public class PaymentContextsTabbyResponseSource : AbstractPaymentContextsResponseSource, IResponseSource + { + public new PaymentSourceType? Type() + { + return base.Type; + } + } +} \ No newline at end of file diff --git a/src/CheckoutSdk/Payments/Util/PaymentResponseSourceTypeConverter.cs b/src/CheckoutSdk/Payments/Util/PaymentResponseSourceTypeConverter.cs index ae4a30d4..dcbf9d7f 100644 --- a/src/CheckoutSdk/Payments/Util/PaymentResponseSourceTypeConverter.cs +++ b/src/CheckoutSdk/Payments/Util/PaymentResponseSourceTypeConverter.cs @@ -69,6 +69,16 @@ private static IResponseSource CreateResponse(string sourceType) { return new PaymentContextsKlarnaResponseSource(); } + + if (CheckoutUtils.GetEnumMemberValue(PaymentSourceType.Stcpay).Equals(sourceType)) + { + return new PaymentContextsStcpayResponseSource(); + } + + if (CheckoutUtils.GetEnumMemberValue(PaymentSourceType.Tabby).Equals(sourceType)) + { + return new PaymentContextsTabbyResponseSource(); + } return new AlternativePaymentSourceResponse(); } diff --git a/test/CheckoutSdkTest/Payments/Contexts/PaymentContextsIntegrationTest.cs b/test/CheckoutSdkTest/Payments/Contexts/PaymentContextsIntegrationTest.cs index ab910450..c386c180 100644 --- a/test/CheckoutSdkTest/Payments/Contexts/PaymentContextsIntegrationTest.cs +++ b/test/CheckoutSdkTest/Payments/Contexts/PaymentContextsIntegrationTest.cs @@ -1,4 +1,5 @@ using Checkout.Common; +using Checkout.Payments.Request.Source.Apm; using Checkout.Payments.Request.Source.Contexts; using Checkout.Sessions; using Shouldly; @@ -73,6 +74,54 @@ await CheckErrorItem( async () => await DefaultApi.PaymentContextsClient().RequestPaymentContexts(paymentContextsRequest), "apm_service_unavailable"); } + + [Fact(Skip = "unavailable")] + private async Task ShouldMakeAStcpayPaymentContextRequest() + { + var paymentContextsRequest = new PaymentContextsRequest + { + Source = new PaymentContextsStcpaySource(), + Amount = 1000, + Currency = Currency.EUR, + PaymentType = PaymentType.Regular, + Capture = true, + ProcessingChannelId = System.Environment.GetEnvironmentVariable("CHECKOUT_PROCESSING_CHANNEL_ID"), + SuccessUrl = "https://example.com/payments/success", + FailureUrl = "https://example.com/payments/fail", + Items = new List + { + new PaymentContextsItems { Name = "mask", Quantity = 1, UnitPrice = 1000, TotalAmount = 1000 } + }, + }; + + await CheckErrorItem( + async () => await DefaultApi.PaymentContextsClient().RequestPaymentContexts(paymentContextsRequest), + "apm_not_supported"); + } + + [Fact] + private async Task ShouldMakeATabbyPaymentContextRequest() + { + var paymentContextsRequest = new PaymentContextsRequest + { + Source = new PaymentContextsTabbySource(), + Amount = 1000, + Currency = Currency.EUR, + PaymentType = PaymentType.Regular, + Capture = true, + ProcessingChannelId = System.Environment.GetEnvironmentVariable("CHECKOUT_PROCESSING_CHANNEL_ID"), + SuccessUrl = "https://example.com/payments/success", + FailureUrl = "https://example.com/payments/fail", + Items = new List + { + new PaymentContextsItems { Name = "mask", Quantity = 1, UnitPrice = 1000, TotalAmount = 1000 } + }, + }; + + await CheckErrorItem( + async () => await DefaultApi.PaymentContextsClient().RequestPaymentContexts(paymentContextsRequest), + "currency_not_supported"); + } [Fact] private async Task ShouldGetAPaymentContext() diff --git a/test/CheckoutSdkTest/Payments/RequestApmPaymentsIntegrationTest.cs b/test/CheckoutSdkTest/Payments/RequestApmPaymentsIntegrationTest.cs index 9f41235c..824bca9f 100644 --- a/test/CheckoutSdkTest/Payments/RequestApmPaymentsIntegrationTest.cs +++ b/test/CheckoutSdkTest/Payments/RequestApmPaymentsIntegrationTest.cs @@ -690,7 +690,7 @@ await CheckErrorItem(async () => await DefaultApi.PaymentsClient().RequestPaymen ApmCurrencyNotSupported); } - [Fact] + [Fact(Skip = "unavailable")] private async Task ShouldMakePlaidPayment() { var request = new PaymentRequest