Skip to content

Commit

Permalink
PP-13334 API returns exemption object
Browse files Browse the repository at this point in the history
API should return exemption object in payment responses when appropriate.
  • Loading branch information
SandorArpa committed Dec 19, 2024
1 parent 3424a0d commit f4ae724
Show file tree
Hide file tree
Showing 21 changed files with 502 additions and 16 deletions.
40 changes: 40 additions & 0 deletions openapi/publicapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -1890,6 +1890,27 @@
}
}
},
"Exemption" : {
"type" : "object",
"description" : "A structure representing that 3DS exemption was requested and the outcome of the exemption, if applicable.",
"properties" : {
"outcome" : {
"$ref" : "#/components/schemas/Outcome"
},
"requested" : {
"type" : "boolean",
"description" : "Indicates whether an exemption was requested for the given payment.",
"example" : true,
"readOnly" : true
},
"type" : {
"type" : "string",
"description" : "Indicates the type of exemption. Only present for corporate exemption",
"example" : "corporate",
"readOnly" : true
}
}
},
"ExternalMetadata" : {
"type" : "object",
"example" : "{\"property1\": \"value1\", \"property2\": \"value2\"}\"",
Expand Down Expand Up @@ -1920,6 +1941,19 @@
}
}
},
"Outcome" : {
"type" : "object",
"description" : "A structure representing the outcome of a 3DS exemption, if known.",
"properties" : {
"result" : {
"type" : "string",
"description" : "The outcome of the requested exemption",
"example" : "honoured",
"readOnly" : true
}
},
"readOnly" : true
},
"PaymentDetailForSearch" : {
"type" : "object",
"description" : "Contains payments matching your search criteria.",
Expand Down Expand Up @@ -1978,6 +2012,9 @@
"type" : "string",
"example" : "The paying user’s email address."
},
"exemption" : {
"$ref" : "#/components/schemas/Exemption"
},
"fee" : {
"type" : "integer",
"format" : "int64",
Expand Down Expand Up @@ -2357,6 +2394,9 @@
"type" : "string",
"example" : "The paying user’s email address."
},
"exemption" : {
"$ref" : "#/components/schemas/Exemption"
},
"fee" : {
"type" : "integer",
"format" : "int64",
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/uk/gov/pay/api/model/CardPayment.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,14 @@ public class CardPayment {
@JsonProperty("authorisation_mode")
private AuthorisationMode authorisationMode;

private Exemption exemption;

public CardPayment(String chargeId, long amount, PaymentState state, String returnUrl, String description,
String reference, String email, String paymentProvider, String createdDate,
RefundSummary refundSummary, PaymentSettlementSummary settlementSummary, CardDetails cardDetails,
SupportedLanguage language, boolean delayedCapture, boolean moto, Long corporateCardSurcharge, Long totalAmount,
String providerId, ExternalMetadata metadata, Long fee, Long netAmount, AuthorisationSummary authorisationSummary, String agreementId,
AuthorisationMode authorisationMode) {
AuthorisationMode authorisationMode, Exemption exemption) {
this.paymentId = chargeId;
this.amount = amount;
this.description = description;
Expand All @@ -127,6 +129,7 @@ public CardPayment(String chargeId, long amount, PaymentState state, String retu
this.authorisationSummary = authorisationSummary;
this.agreementId = agreementId;
this.authorisationMode = authorisationMode;
this.exemption = exemption;
}

/**
Expand Down Expand Up @@ -286,6 +289,11 @@ public String getPaymentProvider() {
return paymentProvider;
}

@Schema(description = "Object containing information about 3DS exemption requests")
public Exemption getExemption() {
return exemption;
}

@Override
public String toString() {
// Don't include:
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/uk/gov/pay/api/model/Charge.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.gov.pay.api.model;

import uk.gov.pay.api.utils.AuthorisationSummaryHelper;
import uk.gov.pay.api.utils.ExemptionEvaluator;
import uk.gov.service.payments.commons.model.AuthorisationMode;
import uk.gov.service.payments.commons.model.SupportedLanguage;
import uk.gov.service.payments.commons.model.charge.ExternalMetadata;
Expand Down Expand Up @@ -60,13 +61,16 @@ public class Charge {

private AuthorisationMode authorisationMode;

private Exemption exemption;

public Charge(String chargeId, Long amount, PaymentState state, String returnUrl, String description,
String reference, String email, String paymentProvider, String createdDate,
SupportedLanguage language, boolean delayedCapture, boolean moto, RefundSummary refundSummary,
PaymentSettlementSummary settlementSummary, CardDetails cardDetails,
List<PaymentConnectorResponseLink> links, Long corporateCardSurcharge, Long totalAmount,
String gatewayTransactionId, ExternalMetadata metadata, Long fee, Long netAmount,
AuthorisationSummary authorisationSummary, String agreementId, AuthorisationMode authorisationMode) {
AuthorisationSummary authorisationSummary, String agreementId, AuthorisationMode authorisationMode,
Exemption exemption) {
this.chargeId = chargeId;
this.amount = amount;
this.state = state;
Expand All @@ -92,6 +96,7 @@ public Charge(String chargeId, Long amount, PaymentState state, String returnUrl
this.authorisationSummary = authorisationSummary;
this.agreementId = agreementId;
this.authorisationMode = authorisationMode;
this.exemption = exemption;
}

public static Charge from(ChargeFromResponse chargeFromResponse) {
Expand Down Expand Up @@ -122,7 +127,8 @@ public static Charge from(ChargeFromResponse chargeFromResponse) {
chargeFromResponse.getNetAmount(),
AuthorisationSummaryHelper.includeAuthorisationSummaryWhen3dsRequired(chargeFromResponse.getAuthorisationSummary()),
chargeFromResponse.getAgreementId(),
chargeFromResponse.getAuthorisationMode()
chargeFromResponse.getAuthorisationMode(),
ExemptionEvaluator.evaluateExemption(chargeFromResponse.getExemption())
);
}

Expand Down Expand Up @@ -154,7 +160,9 @@ public static Charge from(TransactionResponse transactionResponse) {
transactionResponse.getNetAmount(),
AuthorisationSummaryHelper.includeAuthorisationSummaryWhen3dsRequired(transactionResponse.getAuthorisationSummary()),
null,
transactionResponse.getAuthorisationMode());
transactionResponse.getAuthorisationMode(),
ExemptionEvaluator.evaluateExemption(transactionResponse.getExemption())
);
}

public Optional<ExternalMetadata> getMetadata() {
Expand Down Expand Up @@ -260,4 +268,8 @@ public String getAgreementId() {
public AuthorisationMode getAuthorisationMode() {
return authorisationMode;
}

public Exemption getExemption() {
return exemption;
}
}
6 changes: 6 additions & 0 deletions src/main/java/uk/gov/pay/api/model/ChargeFromResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public class ChargeFromResponse {
@JsonDeserialize(using = WalletDeserializer.class)
private Wallet walletType;

private Exemption exemption;

public Optional<ExternalMetadata> getMetadata() {
return Optional.ofNullable(metadata);
}
Expand Down Expand Up @@ -232,4 +234,8 @@ public AuthorisationMode getAuthorisationMode() {
public Optional<Wallet> getWalletType() {
return Optional.ofNullable(walletType);
}

public Exemption getExemption() {
return exemption;
}
}
44 changes: 44 additions & 0 deletions src/main/java/uk/gov/pay/api/model/Exemption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package uk.gov.pay.api.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;

import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "Exemption", description = "A structure representing that 3DS exemption was requested and the outcome of the exemption, if applicable.")
public class Exemption {
@JsonProperty("requested")
private boolean requested;
@JsonProperty("type")
private String type;
@JsonProperty("outcome")
private ExemptionOutcome outcome;

public Exemption() {
}

public Exemption(Boolean requested, String type, ExemptionOutcome outcome) {
this.requested = requested;
this.type = type;
this.outcome = outcome;
}

@Schema(description = "Indicates whether an exemption was requested for the given payment.", example = "true", accessMode = READ_ONLY)
public boolean getRequested() {
return requested;
}

@Schema(description = "Indicates the type of exemption. Only present for corporate exemption", example = "corporate", accessMode = READ_ONLY)
public String getType() {
return type;
}

@Schema(description = "The outcome of the requested exemption", accessMode = READ_ONLY)
public ExemptionOutcome getOutcome() {
return outcome;
}
}
28 changes: 28 additions & 0 deletions src/main/java/uk/gov/pay/api/model/ExemptionOutcome.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package uk.gov.pay.api.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;

import static io.swagger.v3.oas.annotations.media.Schema.AccessMode.READ_ONLY;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Schema(name = "Outcome", description = "A structure representing the outcome of a 3DS exemption, if known.")
public class ExemptionOutcome {
@JsonProperty("result")
private String result;

public ExemptionOutcome() {

}
public ExemptionOutcome(String result) {
this.result = result;
}

@Schema(description = "The outcome of the requested exemption", example = "honoured", accessMode = READ_ONLY)
public String getResult() {
return result;
}
}
7 changes: 7 additions & 0 deletions src/main/java/uk/gov/pay/api/model/TransactionResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ public class TransactionResponse {
@JsonDeserialize(using = WalletDeserializer.class)
private Wallet walletType;

@JsonProperty("exemption")
private Exemption exemption;

public Optional<ExternalMetadata> getMetadata() {
return Optional.ofNullable(metadata);
}
Expand Down Expand Up @@ -199,4 +202,8 @@ public AuthorisationMode getAuthorisationMode() {
public Optional<Wallet> getWalletType() {
return Optional.ofNullable(walletType);
}

public Exemption getExemption() {
return exemption;
}
}
25 changes: 17 additions & 8 deletions src/main/java/uk/gov/pay/api/model/links/PaymentWithAllLinks.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import uk.gov.pay.api.model.CardDetails;
import uk.gov.pay.api.model.CardPayment;
import uk.gov.pay.api.model.Charge;
import uk.gov.pay.api.model.Exemption;
import uk.gov.pay.api.model.PaymentConnectorResponseLink;
import uk.gov.pay.api.model.PaymentSettlementSummary;
import uk.gov.pay.api.model.PaymentState;
Expand All @@ -26,14 +27,15 @@ public PaymentLinks getLinks() {
}

private PaymentWithAllLinks(String chargeId, long amount, PaymentState state, String returnUrl, String description,
String reference, String email, String paymentProvider, String createdDate, SupportedLanguage language,
boolean delayedCapture, boolean moto, RefundSummary refundSummary, PaymentSettlementSummary settlementSummary, CardDetails cardDetails,
List<PaymentConnectorResponseLink> paymentConnectorResponseLinks, URI selfLink, URI paymentEventsUri, URI paymentCancelUri,
URI paymentRefundsUri, URI paymentCaptureUri, URI paymentAuthorisationUri, Long corporateCardSurcharge, Long totalAmount, String providerId, ExternalMetadata metadata,
Long fee, Long netAmount, AuthorisationSummary authorisationSummary, String agreementId, AuthorisationMode authorisationMode) {
String reference, String email, String paymentProvider, String createdDate, SupportedLanguage language,
boolean delayedCapture, boolean moto, RefundSummary refundSummary, PaymentSettlementSummary settlementSummary, CardDetails cardDetails,
List<PaymentConnectorResponseLink> paymentConnectorResponseLinks, URI selfLink, URI paymentEventsUri, URI paymentCancelUri,
URI paymentRefundsUri, URI paymentCaptureUri, URI paymentAuthorisationUri, Long corporateCardSurcharge, Long totalAmount, String providerId, ExternalMetadata metadata,
Long fee, Long netAmount, AuthorisationSummary authorisationSummary, String agreementId, AuthorisationMode authorisationMode,
Exemption exemption) {
super(chargeId, amount, state, returnUrl, description, reference, email, paymentProvider, createdDate,
refundSummary, settlementSummary, cardDetails, language, delayedCapture, moto, corporateCardSurcharge, totalAmount,
providerId, metadata, fee, netAmount, authorisationSummary, agreementId, authorisationMode);
providerId, metadata, fee, netAmount, authorisationSummary, agreementId, authorisationMode, exemption);
this.links.addSelf(selfLink.toString());
this.links.addKnownLinksValueOf(paymentConnectorResponseLinks, paymentAuthorisationUri);
this.links.addEvents(paymentEventsUri.toString());
Expand Down Expand Up @@ -87,6 +89,7 @@ public static PaymentWithAllLinks valueOf(Charge paymentConnector,
.withAuthorisationSummary(paymentConnector.getAuthorisationSummary())
.withAgreementId(paymentConnector.getAgreementId())
.withAuthorisationMode(paymentConnector.getAuthorisationMode())
.withExemption(paymentConnector.getExemption())
.build();
}

Expand Down Expand Up @@ -134,6 +137,7 @@ public static class PaymentWithAllLinksBuilder {
private AuthorisationSummary authorisationSummary;
private String agreementId;
private AuthorisationMode authorisationMode;
private Exemption exemption;

public PaymentWithAllLinksBuilder withChargeId(String chargeId) {
this.chargeId = chargeId;
Expand Down Expand Up @@ -290,12 +294,17 @@ public PaymentWithAllLinksBuilder withAuthorisationMode(AuthorisationMode author
return this;
}

public PaymentWithAllLinksBuilder withExemption(Exemption exemption) {
this.exemption = exemption;
return this;
}

public PaymentWithAllLinks build() {
return new PaymentWithAllLinks(chargeId, amount, state, returnUrl, description, reference, email,
return new PaymentWithAllLinks(chargeId, amount, state, returnUrl, description, reference, email,
paymentProvider, createdDate, language, delayedCapture, moto, refundSummary, settlementSummary,
cardDetails, paymentConnectorResponseLinks, selfLink, paymentEventsUri, paymentCancelUri,
paymentRefundsUri, paymentCaptureUri, paymentAuthorisationUri, corporateCardSurcharge, totalAmount,
providerId, metadata, fee, netAmount, authorisationSummary, agreementId, authorisationMode);
providerId, metadata, fee, netAmount, authorisationSummary, agreementId, authorisationMode, exemption);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import uk.gov.pay.api.model.AuthorisationSummary;
import uk.gov.pay.api.model.CardDetails;
import uk.gov.pay.api.model.CardPayment;
import uk.gov.pay.api.model.Exemption;
import uk.gov.pay.api.model.PaymentConnectorResponseLink;
import uk.gov.pay.api.model.PaymentSettlementSummary;
import uk.gov.pay.api.model.PaymentState;
Expand All @@ -30,11 +31,12 @@ public PaymentForSearchResult(String chargeId, long amount, PaymentState state,
boolean delayedCapture, boolean moto, RefundSummary refundSummary, PaymentSettlementSummary settlementSummary, CardDetails cardDetails,
List<PaymentConnectorResponseLink> links, URI selfLink, URI paymentEventsLink, URI paymentCancelLink, URI paymentRefundsLink, URI paymentCaptureUri,
Long corporateCardSurcharge, Long totalAmount, String providerId, ExternalMetadata externalMetadata,
Long fee, Long netAmount, AuthorisationSummary authorisationSummary, AuthorisationMode authorisationMode) {
Long fee, Long netAmount, AuthorisationSummary authorisationSummary, AuthorisationMode authorisationMode,
Exemption exemption) {

super(chargeId, amount, state, returnUrl, description, reference, email, paymentProvider,
createdDate, refundSummary, settlementSummary, cardDetails, language, delayedCapture, moto, corporateCardSurcharge, totalAmount, providerId, externalMetadata,
fee, netAmount, authorisationSummary, null, authorisationMode);
fee, netAmount, authorisationSummary, null, authorisationMode, exemption);
this.links.addSelf(selfLink.toString());
this.links.addEvents(paymentEventsLink.toString());
this.links.addRefunds(paymentRefundsLink.toString());
Expand Down Expand Up @@ -86,7 +88,8 @@ public static PaymentForSearchResult valueOf(
paymentResult.getFee(),
paymentResult.getNetAmount(),
AuthorisationSummaryHelper.includeAuthorisationSummaryWhen3dsRequired(paymentResult.getAuthorisationSummary()),
paymentResult.getAuthorisationMode());
paymentResult.getAuthorisationMode(),
paymentResult.getExemption());
}

public PaymentLinksForSearch getLinks() {
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/uk/gov/pay/api/utils/ExemptionEvaluator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package uk.gov.pay.api.utils;

import uk.gov.pay.api.model.Exemption;

import java.util.Optional;

public class ExemptionEvaluator {
public static Exemption evaluateExemption(Exemption maybeExemption) {
return Optional.ofNullable(maybeExemption)
.map(exemption -> {
if (exemption.getType() != null
&& exemption.getType().equals("corporate")
&& exemption.getOutcome() != null) {
return exemption;
}
return null;
})
.orElse(null);
}
}
Loading

0 comments on commit f4ae724

Please sign in to comment.