diff --git a/src/main/java/com/checkout/CheckoutApi.java b/src/main/java/com/checkout/CheckoutApi.java index cd78cb7d..2d10f3b6 100644 --- a/src/main/java/com/checkout/CheckoutApi.java +++ b/src/main/java/com/checkout/CheckoutApi.java @@ -10,6 +10,8 @@ import com.checkout.issuing.IssuingClient; import com.checkout.metadata.MetadataClient; import com.checkout.payments.PaymentsClient; +import com.checkout.payments.contexts.PaymentContexts; +import com.checkout.payments.contexts.PaymentContextsClient; import com.checkout.payments.hosted.HostedPaymentsClient; import com.checkout.payments.links.PaymentLinksClient; import com.checkout.reports.ReportsClient; @@ -57,5 +59,7 @@ public interface CheckoutApi extends CheckoutApmApi { IssuingClient issuingClient(); + PaymentContextsClient paymentContextsClient(); + } diff --git a/src/main/java/com/checkout/CheckoutApiImpl.java b/src/main/java/com/checkout/CheckoutApiImpl.java index d24e4e59..2054f5ae 100644 --- a/src/main/java/com/checkout/CheckoutApiImpl.java +++ b/src/main/java/com/checkout/CheckoutApiImpl.java @@ -20,6 +20,9 @@ import com.checkout.metadata.MetadataClientImpl; import com.checkout.payments.PaymentsClient; import com.checkout.payments.PaymentsClientImpl; +import com.checkout.payments.contexts.PaymentContexts; +import com.checkout.payments.contexts.PaymentContextsClient; +import com.checkout.payments.contexts.PaymentContextsClientImpl; import com.checkout.payments.hosted.HostedPaymentsClient; import com.checkout.payments.hosted.HostedPaymentsClientImpl; import com.checkout.payments.links.PaymentLinksClient; @@ -59,6 +62,7 @@ public class CheckoutApiImpl extends AbstractCheckoutApmApi implements CheckoutA private final MetadataClient metadataClient; private final FinancialClient financialClient; private final IssuingClient issuingClient; + private final PaymentContextsClient paymentContextsClient; public CheckoutApiImpl(final CheckoutConfiguration configuration) { super(configuration); @@ -82,6 +86,7 @@ public CheckoutApiImpl(final CheckoutConfiguration configuration) { this.accountsClient = new AccountsClientImpl(this.apiClient, getFilesClient(configuration), configuration); + this.paymentContextsClient = new PaymentContextsClientImpl(this.apiClient, configuration); } @@ -171,6 +176,9 @@ public MetadataClient metadataClient() { @Override public IssuingClient issuingClient() { return issuingClient; } + @Override + public PaymentContextsClient paymentContextsClient() { return paymentContextsClient; } + private ApiClient getFilesClient(final CheckoutConfiguration configuration) { return new ApiClientImpl(configuration, new FilesApiUriStrategy(configuration)); } diff --git a/src/main/java/com/checkout/GsonSerializer.java b/src/main/java/com/checkout/GsonSerializer.java index ba45c4cd..8d1a45a1 100644 --- a/src/main/java/com/checkout/GsonSerializer.java +++ b/src/main/java/com/checkout/GsonSerializer.java @@ -94,6 +94,9 @@ public class GsonSerializer implements Serializer { .registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(com.checkout.payments.response.source.ResponseSource.class, CheckoutUtils.TYPE, true, com.checkout.payments.response.source.AlternativePaymentSourceResponse.class) .registerSubtype(com.checkout.payments.response.source.CardResponseSource.class, identifier(PaymentSourceType.CARD)) .registerSubtype(com.checkout.payments.response.source.CurrencyAccountResponseSource.class, identifier(PaymentSourceType.CURRENCY_ACCOUNT))) + // Payment Contexts + .registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(com.checkout.payments.response.source.contexts.ResponseSource.class, CheckoutUtils.TYPE, true, com.checkout.payments.response.source.contexts.AlternativePaymentSourceResponse.class) + .registerSubtype(com.checkout.payments.response.source.contexts.PaymentContextsPayPayResponseSource.class, identifier(PaymentSourceType.PAYPAL))) // Payments - destination .registerTypeAdapterFactory(RuntimeTypeAdapterFactory.of(com.checkout.payments.response.destination.PaymentResponseDestination.class, CheckoutUtils.TYPE, true, com.checkout.payments.response.destination.PaymentResponseAlternativeDestination.class) .registerSubtype(com.checkout.payments.response.destination.PaymentResponseBankAccountDestination.class, identifier(PaymentDestinationType.BANK_ACCOUNT))) diff --git a/src/main/java/com/checkout/OAuthScope.java b/src/main/java/com/checkout/OAuthScope.java index 91768bda..46a5635a 100644 --- a/src/main/java/com/checkout/OAuthScope.java +++ b/src/main/java/com/checkout/OAuthScope.java @@ -45,7 +45,8 @@ public enum OAuthScope { ISSUING_CLIENT("issuing:client"), ISSUING_CARD_MGMT("issuing:card-mgmt"), ISSUING_CONTROLS_READ("issuing:controls-read"), - ISSUING_CONTROLS_WRITE("issuing:controls-write"); + ISSUING_CONTROLS_WRITE("issuing:controls-write"), + PAYMENT_CONTEXTS("Payment Contexts"); private final String scope; diff --git a/src/main/java/com/checkout/payments/ShippingDetails.java b/src/main/java/com/checkout/payments/ShippingDetails.java index 78201d96..c21e94c9 100644 --- a/src/main/java/com/checkout/payments/ShippingDetails.java +++ b/src/main/java/com/checkout/payments/ShippingDetails.java @@ -37,4 +37,6 @@ public final class ShippingDetails { @SerializedName("method") private ShippingDetailsMethods method; + private Integer delay; + } diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextDetailsResponse.java b/src/main/java/com/checkout/payments/contexts/PaymentContextDetailsResponse.java new file mode 100644 index 00000000..bb034221 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextDetailsResponse.java @@ -0,0 +1,24 @@ +package com.checkout.payments.contexts; + +import com.checkout.HttpMetadata; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +public final class PaymentContextDetailsResponse extends HttpMetadata { + + @SerializedName("payment_request") + private PaymentContextsResponse paymentRequest; + + @SerializedName("partner_metadata") + private PaymentContextsPartnerMetadata partnerMetadata; + + private Object customer; + +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContexts.java b/src/main/java/com/checkout/payments/contexts/PaymentContexts.java new file mode 100644 index 00000000..f7506908 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContexts.java @@ -0,0 +1,45 @@ +package com.checkout.payments.contexts; + +import com.checkout.common.Currency; +import com.checkout.payments.PaymentType; +import com.checkout.payments.ShippingDetails; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PaymentContexts { + + public Long amount; + + public Currency currency; + + @SerializedName("payment_type") + public PaymentType paymentType; + + public boolean capture; + + public ShippingDetails shipping; + + public PaymentContextsProcessing processing; + + @SerializedName("processing_channel_id") + public String processingChannelId; + + public String reference; + + public String description; + + @SerializedName("success_url") + public String successUrl; + + @SerializedName("failure_url") + public String failureUrl; + + public List items; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsAirlineData.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsAirlineData.java new file mode 100644 index 00000000..bacf34be --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsAirlineData.java @@ -0,0 +1,23 @@ +package com.checkout.payments.contexts; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsAirlineData { + + private List ticket; + + private List passenger; + + @SerializedName("flight_leg_details") + private List flightLegDetails; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsClient.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsClient.java new file mode 100644 index 00000000..dccefe23 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsClient.java @@ -0,0 +1,11 @@ +package com.checkout.payments.contexts; + +import java.util.concurrent.CompletableFuture; + +public interface PaymentContextsClient { + + CompletableFuture requestPaymentContexts(PaymentContextsRequest paymentContextsRequest); + + CompletableFuture getPaymentContextDetails(String paymentContextId); + +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsClientImpl.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsClientImpl.java new file mode 100644 index 00000000..cf273943 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsClientImpl.java @@ -0,0 +1,31 @@ +package com.checkout.payments.contexts; + +import com.checkout.AbstractClient; +import com.checkout.ApiClient; +import com.checkout.CheckoutConfiguration; +import com.checkout.SdkAuthorizationType; + +import java.util.concurrent.CompletableFuture; + +import static com.checkout.common.CheckoutUtils.validateParams; + +public class PaymentContextsClientImpl extends AbstractClient implements PaymentContextsClient { + + private static final String PAYMENT_CONTEXTS_PATH = "payment-contexts"; + + public PaymentContextsClientImpl(final ApiClient apiClient, final CheckoutConfiguration configuration) { + super(apiClient, configuration, SdkAuthorizationType.SECRET_KEY_OR_OAUTH); + } + + @Override + public CompletableFuture requestPaymentContexts(final PaymentContextsRequest paymentContextsRequest) { + validateParams("paymentContextsRequest", paymentContextsRequest); + return apiClient.postAsync(PAYMENT_CONTEXTS_PATH, sdkAuthorization(), PaymentContextsRequestResponse.class, paymentContextsRequest, null); + } + + @Override + public CompletableFuture getPaymentContextDetails(final String paymentContextId) { + validateParams("paymentContextId", paymentContextId); + return apiClient.getAsync(buildPath(PAYMENT_CONTEXTS_PATH, paymentContextId), sdkAuthorization(), PaymentContextDetailsResponse.class); + } +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsFlightLegDetails.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsFlightLegDetails.java new file mode 100644 index 00000000..d7040620 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsFlightLegDetails.java @@ -0,0 +1,43 @@ +package com.checkout.payments.contexts; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.Instant; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsFlightLegDetails { + + @SerializedName("flight_number") + private String flightNumber; + + @SerializedName("carrier_code") + private String carrierCode; + + @SerializedName("class_of_travelling") + private String classOfTravelling; + + @SerializedName("departure_airport") + private String departureAirport; + + @SerializedName("departure_date") + private Instant departureDate; + + @SerializedName("departure_time") + private String departureTime; + + @SerializedName("arrival_airport") + private String arrivalAirport; + + @SerializedName("stop_over_code") + private String stopOverCode; + + @SerializedName("fare_basis_code") + private String fareBasisCode; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsItems.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsItems.java new file mode 100644 index 00000000..956bde54 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsItems.java @@ -0,0 +1,37 @@ +package com.checkout.payments.contexts; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsItems { + + private String name; + + private Integer quantity; + + @SerializedName("unit_price") + private Integer unitPrice; + + private String reference; + + @SerializedName("total_amount") + private Integer totalAmount; + + @SerializedName("tax_amount") + private Integer taxAmount; + + @SerializedName("discount_amount") + private Integer discountAmount; + + private String url; + + @SerializedName("image_url") + private String imageUrl; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerCustomerRiskData.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerCustomerRiskData.java new file mode 100644 index 00000000..a04e3e5a --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerCustomerRiskData.java @@ -0,0 +1,17 @@ +package com.checkout.payments.contexts; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsPartnerCustomerRiskData { + + private String key; + + private String value; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerMetadata.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerMetadata.java new file mode 100644 index 00000000..bb88dd4b --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsPartnerMetadata.java @@ -0,0 +1,20 @@ +package com.checkout.payments.contexts; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsPartnerMetadata { + + @SerializedName("order_id") + private String orderId; + + @SerializedName("customer_id") + private String customerId; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsPassenger.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsPassenger.java new file mode 100644 index 00000000..ad3c47a0 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsPassenger.java @@ -0,0 +1,28 @@ +package com.checkout.payments.contexts; + +import com.checkout.common.Address; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.Instant; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsPassenger { + + @SerializedName("first_name") + private String firstName; + + @SerializedName("last_name") + private String lastName; + + @SerializedName("date_of_birth") + private Instant dateOfBirth; + + private Address address; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsProcessing.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsProcessing.java new file mode 100644 index 00000000..3dabdbb2 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsProcessing.java @@ -0,0 +1,44 @@ +package com.checkout.payments.contexts; + +import com.checkout.payments.BillingPlan; +import com.checkout.payments.ShippingPreference; +import com.checkout.payments.UserAction; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsProcessing { + + private BillingPlan plan; + + @SerializedName("shipping_amount") + private Integer shippingAmount; + + @SerializedName("invoice_id") + private String invoiceId; + + @SerializedName("brand_name") + private String brandName; + + private String locale; + + @SerializedName("shipping_preference") + private ShippingPreference shippingPreference; + + @SerializedName("user_action") + private UserAction userAction; + + @SerializedName("partner_customer_risk_data") + private PaymentContextsPartnerCustomerRiskData partnerCustomerRiskData; + + @SerializedName("airline_data") + private List airlineData; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsRequest.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsRequest.java new file mode 100644 index 00000000..a9e6172b --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsRequest.java @@ -0,0 +1,54 @@ +package com.checkout.payments.contexts; + +import com.checkout.common.Currency; +import com.checkout.payments.PaymentType; +import com.checkout.payments.ShippingDetails; +import com.checkout.payments.request.source.AbstractRequestSource; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import java.util.List; + +@Data +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public final class PaymentContextsRequest extends PaymentContexts { + + private AbstractRequestSource source; + + @Builder + private PaymentContextsRequest( + final AbstractRequestSource source, + final Long amount, + final Currency currency, + final PaymentType paymentType, + final boolean capture, + final ShippingDetails shipping, + final PaymentContextsProcessing processing, + final String processingChannelId, + final String reference, + final String description, + final String successUrl, + final String failureUrl, + final List items + ) { + super(); + this.source = source; + this.amount = amount; + this.currency = currency; + this.paymentType = paymentType; + this.capture = capture; + this.shipping = shipping; + this.processing = processing; + this.processingChannelId = processingChannelId; + this.reference = reference; + this.description = description; + this.successUrl = successUrl; + this.failureUrl = failureUrl; + this.items = items; + } +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsRequestResponse.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsRequestResponse.java new file mode 100644 index 00000000..9a80c695 --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsRequestResponse.java @@ -0,0 +1,18 @@ +package com.checkout.payments.contexts; + +import com.checkout.common.Resource; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +public final class PaymentContextsRequestResponse extends Resource { + + private String id; + + private PaymentContextsPartnerMetadata partnerMetadata; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsResponse.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsResponse.java new file mode 100644 index 00000000..155f431b --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsResponse.java @@ -0,0 +1,8 @@ +package com.checkout.payments.contexts; + +import com.checkout.payments.response.source.contexts.ResponseSource; + +public final class PaymentContextsResponse extends PaymentContexts { + + private ResponseSource source; +} diff --git a/src/main/java/com/checkout/payments/contexts/PaymentContextsTicket.java b/src/main/java/com/checkout/payments/contexts/PaymentContextsTicket.java new file mode 100644 index 00000000..2262ffff --- /dev/null +++ b/src/main/java/com/checkout/payments/contexts/PaymentContextsTicket.java @@ -0,0 +1,33 @@ +package com.checkout.payments.contexts; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.Instant; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public final class PaymentContextsTicket { + + private String number; + + @SerializedName("issue_date") + private Instant issueDate; + + @SerializedName("issuing_carrier_code") + private String issuingCarrierCode; + + @SerializedName("travel_package_indicator") + private String travelPackageIndicator; + + @SerializedName("travel_agency_name") + private String travelAgencyName; + + @SerializedName("travel_agency_code") + private String travelAgencyCode; +} diff --git a/src/main/java/com/checkout/payments/request/source/contexts/PaymentContextsPayPalSource.java b/src/main/java/com/checkout/payments/request/source/contexts/PaymentContextsPayPalSource.java new file mode 100644 index 00000000..d8477c77 --- /dev/null +++ b/src/main/java/com/checkout/payments/request/source/contexts/PaymentContextsPayPalSource.java @@ -0,0 +1,21 @@ +package com.checkout.payments.request.source.contexts; + +import com.checkout.common.PaymentSourceType; +import com.checkout.payments.request.source.AbstractRequestSource; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public final class PaymentContextsPayPalSource extends AbstractRequestSource { + + @Builder + private PaymentContextsPayPalSource() { + super(PaymentSourceType.PAYPAL); + } +} diff --git a/src/main/java/com/checkout/payments/response/source/contexts/AbstractPaymentContextsResponseSource.java b/src/main/java/com/checkout/payments/response/source/contexts/AbstractPaymentContextsResponseSource.java new file mode 100644 index 00000000..0870c7b5 --- /dev/null +++ b/src/main/java/com/checkout/payments/response/source/contexts/AbstractPaymentContextsResponseSource.java @@ -0,0 +1,10 @@ +package com.checkout.payments.response.source.contexts; + +import com.checkout.common.PaymentSourceType; +import lombok.Data; + +@Data +public abstract class AbstractPaymentContextsResponseSource { + + public PaymentSourceType type; +} diff --git a/src/main/java/com/checkout/payments/response/source/contexts/AlternativePaymentSourceResponse.java b/src/main/java/com/checkout/payments/response/source/contexts/AlternativePaymentSourceResponse.java new file mode 100644 index 00000000..0cb113a9 --- /dev/null +++ b/src/main/java/com/checkout/payments/response/source/contexts/AlternativePaymentSourceResponse.java @@ -0,0 +1,22 @@ +package com.checkout.payments.response.source.contexts; + +import com.checkout.common.CheckoutUtils; +import com.checkout.common.PaymentSourceType; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.apache.commons.lang3.EnumUtils; + +import java.util.HashMap; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public final class AlternativePaymentSourceResponse extends HashMap implements ResponseSource { + + @Override + public PaymentSourceType getType() { + return EnumUtils.getEnumIgnoreCase(PaymentSourceType.class, (String) get(CheckoutUtils.TYPE)); + } + +} diff --git a/src/main/java/com/checkout/payments/response/source/contexts/PaymentContextsPayPayResponseSource.java b/src/main/java/com/checkout/payments/response/source/contexts/PaymentContextsPayPayResponseSource.java new file mode 100644 index 00000000..698447c6 --- /dev/null +++ b/src/main/java/com/checkout/payments/response/source/contexts/PaymentContextsPayPayResponseSource.java @@ -0,0 +1,14 @@ +package com.checkout.payments.response.source.contexts; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +public final class PaymentContextsPayPayResponseSource extends AbstractPaymentContextsResponseSource implements ResponseSource { + +} diff --git a/src/main/java/com/checkout/payments/response/source/contexts/ResponseSource.java b/src/main/java/com/checkout/payments/response/source/contexts/ResponseSource.java new file mode 100644 index 00000000..fbd03f39 --- /dev/null +++ b/src/main/java/com/checkout/payments/response/source/contexts/ResponseSource.java @@ -0,0 +1,9 @@ +package com.checkout.payments.response.source.contexts; + +import com.checkout.common.PaymentSourceType; + +public interface ResponseSource { + + PaymentSourceType getType(); + +} diff --git a/src/test/java/com/checkout/TestHelper.java b/src/test/java/com/checkout/TestHelper.java index 9b51a150..5802c3c5 100644 --- a/src/test/java/com/checkout/TestHelper.java +++ b/src/test/java/com/checkout/TestHelper.java @@ -10,16 +10,19 @@ import com.checkout.common.Phone; import com.checkout.common.Product; import com.checkout.payments.BillingDescriptor; +import com.checkout.payments.BillingInformation; +import com.checkout.payments.Payer; import com.checkout.payments.PaymentRecipient; import com.checkout.payments.PaymentType; import com.checkout.payments.ProcessingSettings; import com.checkout.payments.RiskRequest; import com.checkout.payments.ShippingDetails; import com.checkout.payments.ThreeDSRequest; -import com.checkout.payments.BillingInformation; -import com.checkout.payments.Payer; +import com.checkout.payments.contexts.PaymentContextsItems; +import com.checkout.payments.contexts.PaymentContextsRequest; import com.checkout.payments.hosted.HostedPaymentRequest; import com.checkout.payments.links.PaymentLinkRequest; +import com.checkout.payments.request.source.contexts.PaymentContextsPayPalSource; import lombok.SneakyThrows; import java.nio.file.Files; @@ -29,8 +32,11 @@ import java.time.ZoneOffset; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.UUID; +import static java.util.Objects.requireNonNull; + public final class TestHelper { private TestHelper() { @@ -170,6 +176,33 @@ public static HostedPaymentRequest createHostedPaymentRequest(final String refer .build(); } + public static PaymentContextsRequest createPaymentContextsRequest() { + + final PaymentContextsPayPalSource source = PaymentContextsPayPalSource.builder().build(); + + final PaymentContextsItems item = PaymentContextsItems.builder() + .name("mask") + .quantity(1) + .unitPrice(2000) + .build(); + + final List items = Arrays.asList( + item + ); + + return PaymentContextsRequest.builder() + .source(source) + .amount(2000L) + .currency(Currency.EUR) + .paymentType(PaymentType.REGULAR) + .capture(true) + .processingChannelId(requireNonNull(System.getenv("CHECKOUT_PROCESSING_CHANNEL_ID"))) + .successUrl("https://example.com/payments/success") + .failureUrl("https://example.com/payments/fail") + .items(items) + .build(); + } + public static PaymentRecipient createRecipient() { return PaymentRecipient.builder() .accountNumber("1234567") @@ -189,7 +222,7 @@ public static Payer getPayer() { .build(); } - public static AccountHolder getAccountHolder(){ + public static AccountHolder getAccountHolder() { return AccountHolder.builder() .firstName("John") .lastName("Doe") diff --git a/src/test/java/com/checkout/payments/contexts/PaymentContextsClientImplTest.java b/src/test/java/com/checkout/payments/contexts/PaymentContextsClientImplTest.java new file mode 100644 index 00000000..952df844 --- /dev/null +++ b/src/test/java/com/checkout/payments/contexts/PaymentContextsClientImplTest.java @@ -0,0 +1,83 @@ +package com.checkout.payments.contexts; + +import com.checkout.ApiClient; +import com.checkout.CheckoutConfiguration; +import com.checkout.SdkAuthorization; +import com.checkout.SdkAuthorizationType; +import com.checkout.SdkCredentials; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class PaymentContextsClientImplTest { + + private PaymentContextsClient client; + + @Mock + private ApiClient apiClient; + + @Mock + private CheckoutConfiguration configuration; + + @Mock + private SdkCredentials sdkCredentials; + + @Mock + private SdkAuthorization authorization; + + @BeforeEach + void setUp() { + when(sdkCredentials.getAuthorization(SdkAuthorizationType.SECRET_KEY_OR_OAUTH)).thenReturn(authorization); + when(configuration.getSdkCredentials()).thenReturn(sdkCredentials); + client = new PaymentContextsClientImpl(apiClient, configuration); + } + + @Test + void shouldRequestPaymentContexts() throws ExecutionException, InterruptedException { + + final PaymentContextsRequest request = mock(PaymentContextsRequest.class); + final PaymentContextsRequestResponse response = mock(PaymentContextsRequestResponse.class); + + when(apiClient.postAsync(eq("payment-contexts"), eq(authorization), eq(PaymentContextsRequestResponse.class), + eq(request), isNull())) + .thenReturn(CompletableFuture.completedFuture(response)); + + final CompletableFuture future = client.requestPaymentContexts(request); + + assertNotNull(future.get()); + assertEquals(response, future.get()); + + } + + @Test + void shouldGetAPaymentContext() throws ExecutionException, InterruptedException { + + final PaymentContextDetailsResponse response = mock(PaymentContextDetailsResponse.class); + + when(apiClient.getAsync( + "payment-contexts/payment_context_id", + authorization, + PaymentContextDetailsResponse.class)) + .thenReturn(CompletableFuture.completedFuture(response)); + + final CompletableFuture future = client.getPaymentContextDetails("payment_context_id"); + + assertNotNull(future.get()); + assertEquals(response, future.get()); + + } + +} diff --git a/src/test/java/com/checkout/payments/contexts/PaymentContextsTestIT.java b/src/test/java/com/checkout/payments/contexts/PaymentContextsTestIT.java new file mode 100644 index 00000000..fd760a79 --- /dev/null +++ b/src/test/java/com/checkout/payments/contexts/PaymentContextsTestIT.java @@ -0,0 +1,54 @@ +package com.checkout.payments.contexts; + +import com.checkout.PlatformType; +import com.checkout.SandboxTestFixture; +import com.checkout.TestHelper; +import com.checkout.common.Currency; +import com.checkout.payments.PaymentType; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class PaymentContextsTestIT extends SandboxTestFixture { + + PaymentContextsTestIT() { + super(PlatformType.DEFAULT); + } + + @Test + void shouldMakeAPaymentContextRequest() { + + final PaymentContextsRequest request = TestHelper.createPaymentContextsRequest(); + + final PaymentContextsRequestResponse response = blocking(() -> checkoutApi.paymentContextsClient().requestPaymentContexts(request)); + + assertNotNull(response); + assertNotNull(response.getId()); + assertNotNull(response.getPartnerMetadata().getOrderId()); + } + + @Test + void shouldGetAPaymentContext() { + + final PaymentContextsRequest request = TestHelper.createPaymentContextsRequest(); + + final PaymentContextsRequestResponse paymentContextsResponse = blocking(() -> checkoutApi.paymentContextsClient().requestPaymentContexts(request)); + + final PaymentContextDetailsResponse response = blocking(() -> checkoutApi.paymentContextsClient().getPaymentContextDetails(paymentContextsResponse.getId())); + + assertNotNull(response); + assertNotNull(response.getPaymentRequest()); + assertEquals(2000, response.getPaymentRequest().getAmount()); + assertEquals(Currency.EUR, response.getPaymentRequest().getCurrency()); + assertEquals(PaymentType.REGULAR, response.getPaymentRequest().getPaymentType()); + assertEquals(true, response.getPaymentRequest().isCapture()); + assertEquals("mask", response.getPaymentRequest().getItems().get(0).getName()); + assertEquals(1, response.getPaymentRequest().getItems().get(0).getQuantity()); + assertEquals(2000, response.getPaymentRequest().getItems().get(0).getUnitPrice()); + assertEquals("https://example.com/payments/success", response.getPaymentRequest().getSuccessUrl()); + assertEquals("https://example.com/payments/fail", response.getPaymentRequest().getFailureUrl()); + assertNotNull(response.getPartnerMetadata()); + assertNotNull(response.getPartnerMetadata().getOrderId()); + } +} \ No newline at end of file