diff --git a/pom.xml b/pom.xml index 4d1edb7..ff73f5d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,19 +5,25 @@ 4.0.0 com.trustly.api - trustly-java-client + trustly-java ${revision} + pom - trustly-java-client Client for executing requests against Trustly's API https://github.com/trustly/trustly-client-java + + trustly-java-models + trustly-java-client + trustly-java-util + + - 1.8 - 1.8 + 11 + ${java.version} + ${java.version} 1.0.0-SNAPSHOT UTF-8 - ${project.build.directory}/delombok @@ -35,8 +41,8 @@ - Team Ceres - ceres@trustly.com + Merchant Experience + merchant-experience@trustly.com Trustly https://trustly.com @@ -53,233 +59,62 @@ - - - - - org.bouncycastle - bcpkix-jdk15on - 1.70 - - - - com.fasterxml.jackson.core - jackson-databind - 2.14.2 - - - - org.slf4j - slf4j-api - 2.0.6 - - - - - commons-httpclient - commons-httpclient - 3.1 - provided - - - org.apache.httpcomponents - httpclient - 4.5.14 - provided - - - org.apache.httpcomponents.client5 - httpclient5 - 5.2.1 - provided - - - - org.hibernate - hibernate-validator - 7.0.5.Final - provided - + + + + + org.bouncycastle + bcpkix-jdk15on + 1.70 + + + + com.fasterxml.jackson.core + jackson-databind + 2.14.2 + + + + com.fasterxml.jackson.core + jackson-annotations + 2.17.1 + + + + jakarta.validation + jakarta.validation-api + 3.1.0 + + + + org.junit.jupiter + junit-jupiter-api + 5.9.2 + + + + org.junit.jupiter + junit-jupiter-params + 5.9.2 + + + - - javax.servlet - javax.servlet-api - 4.0.1 - provided - - - - jakarta.servlet - jakarta.servlet-api - 5.0.0 - provided - - - - org.projectlombok - lombok - 1.18.26 - provided - + org.junit.jupiter junit-jupiter-api - 5.9.2 test org.junit.jupiter junit-jupiter-params - 5.9.2 test - - - - - org.codehaus.mojo - flatten-maven-plugin - 1.5.0 - - true - resolveCiFriendliesOnly - - - - flatten - process-resources - - flatten - - - - flatten.clean - clean - - clean - - - - - - - org.projectlombok - lombok-maven-plugin - 1.18.20.0 - - - generate-sources - - delombok - - - - - src/main/java - ${delombok.output} - false - UTF-8 - - - - org.apache.maven.plugins - maven-antrun-plugin - 1.8 - - - generate-delomboked-sources-jar - package - - run - - - - - - - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.4.0 - - - attach-delomboked-sources-jar - package - - attach-artifact - - - - - ${project.build.directory}/${project.build.finalName}-sources.jar - jar - sources - - - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.13 - true - - ossrh - https://s01.oss.sonatype.org/ - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.5.0 - - - attach-javadoc - - jar - - - - - ${delombok.output} - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - --pinentry-mode - loopback - - - - - - - - diff --git a/src/main/java/com/trustly/api/client/JsonRpcFactory.java b/src/main/java/com/trustly/api/client/JsonRpcFactory.java deleted file mode 100644 index 78812a9..0000000 --- a/src/main/java/com/trustly/api/client/JsonRpcFactory.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.trustly.api.client; - -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.RequestParams; -import java.util.UUID; - -public class JsonRpcFactory { - - public JsonRpcRequest create(D requestData, String method) { - return this.create(requestData, method, null); - } - - public JsonRpcRequest create(D requestData, String method, String uuid) { - - if (uuid == null) { - uuid = UUID.randomUUID().toString(); - } - - return JsonRpcRequest.builder() - .method(method) - .params( - RequestParams.builder() - .uuid(uuid) - .data(requestData) - .build() - ) - .build(); - } -} diff --git a/src/main/java/com/trustly/api/client/JsonRpcSigner.java b/src/main/java/com/trustly/api/client/JsonRpcSigner.java deleted file mode 100644 index 8a07339..0000000 --- a/src/main/java/com/trustly/api/client/JsonRpcSigner.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.trustly.api.client; - -import com.fasterxml.jackson.databind.JsonNode; -import com.trustly.api.domain.base.IRequest; -import com.trustly.api.domain.base.IRequestParams; -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.base.IResponseResultData; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.exceptions.TrustlySignatureException; - -public interface JsonRpcSigner { - - JsonRpcRequest sign(JsonRpcRequest request); - - JsonRpcResponse sign(JsonRpcResponse response); - - > void verify(IRequest

request) throws TrustlySignatureException; - - void verify(JsonRpcResponse response, JsonNode nodeResponse) throws TrustlySignatureException; -} diff --git a/src/main/java/com/trustly/api/client/NotificationArgs.java b/src/main/java/com/trustly/api/client/NotificationArgs.java deleted file mode 100644 index 25e49e6..0000000 --- a/src/main/java/com/trustly/api/client/NotificationArgs.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.trustly.api.client; - -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.exceptions.TrustlyValidationException; -import jakarta.validation.Valid; -import java.io.IOException; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class NotificationArgs { - - @FunctionalInterface - public interface NotificationOkHandler { - - void handle(String method, String uuid) throws IOException, TrustlyValidationException; - } - - @FunctionalInterface - public interface NotificationFailHandler { - - void handle(String method, String uuid, String message) throws IOException, TrustlyValidationException; - } - - @Getter - @Valid - private final D data; - - private final String method; - private final String uuid; - - private final NotificationOkHandler onOK; - private final NotificationFailHandler onFailed; - - public void respondWithOk() throws TrustlyValidationException, IOException { - this.onOK.handle(this.method, this.uuid); - } - - public void respondWithFailed(String message) throws TrustlyValidationException, IOException { - this.onFailed.handle(this.method, this.uuid, message); - } -} diff --git a/src/main/java/com/trustly/api/client/NotificationEvent.java b/src/main/java/com/trustly/api/client/NotificationEvent.java deleted file mode 100644 index 23adf42..0000000 --- a/src/main/java/com/trustly/api/client/NotificationEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.trustly.api.client; - -import com.trustly.api.domain.base.IFromTrustlyRequestData; -import com.trustly.api.domain.exceptions.TrustlyValidationException; -import java.io.IOException; - -@FunctionalInterface -public interface NotificationEvent { - - void onNotification(NotificationArgs args) throws IOException, TrustlyValidationException; -} diff --git a/src/main/java/com/trustly/api/client/TrustlyApiClient.java b/src/main/java/com/trustly/api/client/TrustlyApiClient.java deleted file mode 100644 index f49a34c..0000000 --- a/src/main/java/com/trustly/api/client/TrustlyApiClient.java +++ /dev/null @@ -1,758 +0,0 @@ -package com.trustly.api.client; - -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.trustly.api.client.NotificationArgs.NotificationFailHandler; -import com.trustly.api.client.NotificationArgs.NotificationOkHandler; -import com.trustly.api.domain.base.IFromTrustlyRequestData; -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.base.IResponseResultData; -import com.trustly.api.domain.base.IToTrustlyRequestParams; -import com.trustly.api.domain.base.IWithRejectionResult; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.base.NotificationRequest; -import com.trustly.api.domain.base.ResponseResult; -import com.trustly.api.domain.exceptions.TrustlyErrorResponseException; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationListenerException; -import com.trustly.api.domain.exceptions.TrustlyRejectionException; -import com.trustly.api.domain.exceptions.TrustlyRequestException; -import com.trustly.api.domain.exceptions.TrustlySignatureException; -import com.trustly.api.domain.exceptions.TrustlyValidationException; -import com.trustly.api.domain.methods.accountledger.AccountLedgerRequestData; -import com.trustly.api.domain.methods.accountledger.AccountLedgerResponseData; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutRequestData; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutResponseData; -import com.trustly.api.domain.methods.approvewithdrawal.ApproveWithdrawalRequestData; -import com.trustly.api.domain.methods.approvewithdrawal.ApproveWithdrawalResponseData; -import com.trustly.api.domain.methods.balance.BalanceRequestData; -import com.trustly.api.domain.methods.balance.BalanceResponseData; -import com.trustly.api.domain.methods.cancelcharge.CancelChargeRequestData; -import com.trustly.api.domain.methods.cancelcharge.CancelChargeResponseData; -import com.trustly.api.domain.methods.charge.ChargeRequestData; -import com.trustly.api.domain.methods.charge.ChargeRequestDataAttributes; -import com.trustly.api.domain.methods.charge.ChargeResponseData; -import com.trustly.api.domain.methods.createaccount.CreateAccountRequestData; -import com.trustly.api.domain.methods.createaccount.CreateAccountResponseData; -import com.trustly.api.domain.methods.denywithdrawal.DenyWithdrawalRequestData; -import com.trustly.api.domain.methods.denywithdrawal.DenyWithdrawalResponseData; -import com.trustly.api.domain.methods.deposit.DepositRequestData; -import com.trustly.api.domain.methods.deposit.DepositResponseData; -import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsRequestData; -import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsResponseData; -import com.trustly.api.domain.methods.merchantsettlement.MerchantSettlementRequestData; -import com.trustly.api.domain.methods.merchantsettlement.MerchantSettlementResponseData; -import com.trustly.api.domain.methods.refund.RefundRequestData; -import com.trustly.api.domain.methods.refund.RefundResponseData; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountRequestData; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountResponseData; -import com.trustly.api.domain.methods.registeraccountpayout.RegisterAccountPayoutRequestData; -import com.trustly.api.domain.methods.registeraccountpayout.RegisterAccountPayoutResponseData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestDataAttributes; -import com.trustly.api.domain.methods.selectaccount.SelectAccountResponseData; -import com.trustly.api.domain.methods.settlementreport.SettlementReportRequestData; -import com.trustly.api.domain.methods.settlementreport.SettlementReportResponseData; -import com.trustly.api.domain.methods.withdraw.WithdrawRequestData; -import com.trustly.api.domain.methods.withdraw.WithdrawResponseData; -import com.trustly.api.domain.notifications.AccountNotificationData; -import com.trustly.api.domain.notifications.CancelNotificationData; -import com.trustly.api.domain.notifications.CreditNotificationData; -import com.trustly.api.domain.notifications.DebitNotificationData; -import com.trustly.api.domain.notifications.PayoutConfirmationNotificationData; -import com.trustly.api.domain.notifications.PendingNotificationData; -import com.trustly.api.domain.notifications.UnknownNotificationData; -import com.trustly.api.request.ApacheHttpClient3HttpRequesterLoader; -import com.trustly.api.request.ApacheHttpClient4HttpRequesterLoader; -import com.trustly.api.request.ApacheHttpClient5HttpRequesterLoader; -import com.trustly.api.request.HttpRequester; -import com.trustly.api.request.HttpRequesterLoader; -import com.trustly.api.request.JavaUrlConnectionHttpRequesterLoader; -import com.trustly.api.util.TrustlyStringUtils; -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import lombok.Value; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -public class TrustlyApiClient implements Closeable { - - private static final List STATIC_REGISTERED_CLIENTS = new ArrayList<>(); - - private static final HttpRequesterLoader[] AVAILABLE_HTTP_REQUESTERS = new HttpRequesterLoader[]{ - new ApacheHttpClient5HttpRequesterLoader(), - new ApacheHttpClient4HttpRequesterLoader(), - new ApacheHttpClient3HttpRequesterLoader(), - new JavaUrlConnectionHttpRequesterLoader() - }; - - private static HttpRequester getFirstAvailableHttpRequester() { - - HttpRequester foundHttpRequester = null; - for (HttpRequesterLoader loader : AVAILABLE_HTTP_REQUESTERS) { - - foundHttpRequester = loader.create(); - if (foundHttpRequester != null) { - break; - } - } - - if (foundHttpRequester == null) { - throw new IllegalStateException("Could not find a suitable http requester factory"); - } - - return foundHttpRequester; - } - - @Value - private static class NotificationMeta { - - Class dataClass; - List> listeners = new ArrayList<>(); - } - - private final TrustlyApiClientSettings settings; - - private final ObjectMapper objectMapper = new ObjectMapper(); - private final JsonRpcFactory objectFactory = new JsonRpcFactory(); - private final JsonRpcSigner signer; - private final JsonRpcValidator validator = new JsonRpcValidator(); - private final HttpRequester httpRequester; - - private final Map> onNotification = new HashMap<>(); - - public TrustlyApiClientSettings getSettings() { - return settings; - } - - public TrustlyApiClient(TrustlyApiClientSettings settings) { - this(settings, new DefaultJsonRpcSigner(new Serializer(), settings), TrustlyApiClient.getFirstAvailableHttpRequester()); - } - - public TrustlyApiClient(TrustlyApiClientSettings settings, JsonRpcSigner signer) { - this(settings, signer, TrustlyApiClient.getFirstAvailableHttpRequester()); - } - - public TrustlyApiClient(TrustlyApiClientSettings settings, HttpRequester httpRequester) { - this(settings, new DefaultJsonRpcSigner(new Serializer(), settings), httpRequester); - } - - public TrustlyApiClient(TrustlyApiClientSettings settings, JsonRpcSigner signer, HttpRequester httpRequester) { - this.settings = settings; - this.signer = signer; - this.httpRequester = httpRequester; - - TrustlyApiClient.STATIC_REGISTERED_CLIENTS.add(this); - } - - @Override - public void close() { - TrustlyApiClient.STATIC_REGISTERED_CLIENTS.remove(this); - } - - public static Iterable getRegisteredClients() { - return STATIC_REGISTERED_CLIENTS; - } - - // Methods - - /** - * Fetches the account ledger for the specified time period. - *

- * This report includes all the transactions (both incoming and outgoing transactions) that affect the merchant's Trustly account - * balance. - *

- * Only settled transactions are included. - */ - public AccountLedgerResponseData accountLedger(AccountLedgerRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, AccountLedgerResponseData.class, "AccountLedger", null); - } - - /** - * This method is used by merchants to transfer money to their customer's bank accounts. - *

- * The merchant specifies the receiving bank account in {@link AccountPayoutRequestData#setAccountId}, which is a unique identifier - * generated by Trustly. - *

- * The merchant can get the {@code AccountID} from {@link NotificationRequest}<{@link AccountNotificationData}> which is sent after - * a {@link TrustlyApiClient#selectAccount} or {@link TrustlyApiClient#deposit} order has been completed. - *

- * Alternatively, the {@link TrustlyApiClient#registerAccount} method can be used to get the {@code AccountID}, if the merchant already - * has the bank account details and want to register them in Trustly's system. - *

- * Funds must be transferred to the merchant's Trustly account before the payout can be made. No credit is given. To see how much money - * you have on your Trustly account you can use the {@link TrustlyApiClient#balance} method or simply log in to the Trustly backoffice. - *

- *

Example flow 1: SelectAccount + AccountPayout

- *
    - *
  1. The merchant makes an API-call to {@link TrustlyApiClient#selectAccount} and redirects the end-user to {@link SelectAccountResponseData#getUrl()}.
  2. - *
  3. The end-user logs in to their bank and selects their bank account.
  4. - *
  5. Trustly sends an {@link NotificationRequest}<{@link AccountNotificationData}> to the merchant's system with an {@code AccountID} for the selected account.
  6. - *
  7. The merchant makes an API-call using this method with the {@link AccountPayoutRequestData#setAmount} and {@link AccountPayoutRequestData#setCurrency} to transfer.
  8. - *
  9. Trustly's API replies with a synchronous response to let the merchant know that the AccountPayout request was received.
  10. - *
  11. - * A {@link NotificationRequest}<{@link PayoutConfirmationNotificationData}> is sent to the merchant when the transfer has been confirmed. - *

    - * Note: this notification is not enabled by default. Please speak to your Trustly contact person if you want to have it enabled. - *

    - * If the payout fails, a {@link NotificationRequest}<{@link CreditNotificationData}> is sent (see more details here). - *

  12. - *
- * - *

Example flow 2: RegisterAccount + AccountPayout

- *
    - *
  1. The merchant makes an API-call to {@link TrustlyApiClient#registerAccount} method with the recipient's bank account details.
  2. - *
  3. Trustly's {@link TrustlyApiClient#registerAccount} API responds with {@link RegisterAccountResponseData#getAccountId()} of the recipient's account.
  4. - *
  5. The merchant makes an API-call to this method with the {@link AccountPayoutRequestData#setAmount} and {@link AccountPayoutRequestData#setCurrency} to transfer.
  6. - *
  7. Trustly's API replies with a synchronous response to let the merchant know that the AccountPayout request was received.
  8. - *
  9. - * A {@link NotificationRequest}<{@link PayoutConfirmationNotificationData}> is sent to the merchant when the transfer has been confirmed. - *

    - * Note: this notification is not enabled by default. Please speak to your Trustly contact person if you want to have it enabled. - *

    - * If the payout fails, a {@link NotificationRequest}<{@link CreditNotificationData}> is sent (see more details here). - *

    - * An {@code AccountID} does not expire in Trustly's system, so it can be used for multiple AccountPayout requests. - *

  10. - *
- */ - public AccountPayoutResponseData accountPayout(AccountPayoutRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, AccountPayoutResponseData.class, "AccountPayout", null); - } - - /** - * Approves a withdrawal prepared by the user. Please contact your integration manager at Trustly if you want to enable automatic approval - * of the withdrawals. - */ - public ApproveWithdrawalResponseData approveWithdrawal(ApproveWithdrawalRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, ApproveWithdrawalResponseData.class, "ApproveWithdrawal", null); - } - - /** - * This method returns the current balance for all currencies available on the merchant's Trustly account. - *

- * 🚧 Please do not use this method more than once every 15 minutes. - */ - public BalanceResponseData balance(BalanceRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, BalanceResponseData.class, "Balance", null); - } - - /** - * For {@link TrustlyApiClient#charge} requests that have a future {@link ChargeRequestDataAttributes#setPaymentDate}, it’s possible to - * cancel the Charge up until 18:30 on the {@code PaymentDate}. - *

- * A {@code Charge} request that doesn’t have any {@code PaymentDate} specified cannot be canceled. It’s also not possible to cancel a - * {@code Charge} request if the {@code PaymentDate} is equal to the date when {@code Charge} request was sent. - */ - public CancelChargeResponseData cancelCharge(CancelChargeRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, CancelChargeResponseData.class, "CancelCharge", null); - } - - /** - * Charges a specific {@link ChargeRequestData#setAccountId} using direct debit. - *

- * A previously approved direct debit mandate must exist on the {@link ChargeRequestData#setAccountId} (see - * {@link TrustlyApiClient#selectAccount} for details). - */ - public ChargeResponseData charge(ChargeRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, ChargeResponseData.class, "Charge", null); - } - - /** - * Denies a withdrawal prepared by the user. - *

- * Please contact your integration manager at Trustly if you want to enable automatic approval of the withdrawals. - */ - public DenyWithdrawalResponseData denyWithdrawal(DenyWithdrawalRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, DenyWithdrawalResponseData.class, "DenyWithdrawal", null); - } - - /** - * This method returns {@link DepositResponseData#getUrl()} where the end-user can make a payment from their bank account. - *

- * A typical Deposit flow is: - *

    - *
  1. The merchant sends a Deposit API call and receives a {@link DepositResponseData#getUrl()} back from Trustly's API.
  2. - *
  3. The merchant displays the {@link DepositResponseData#getUrl()} to the end-user (you can find more information about how to display the Trustly URL here).
  4. - *
  5. The end-user selects their bank and completes the payment (in case the payment is not completed, a {@link NotificationRequest}<{@link CancelNotificationData}> is sent).
  6. - *
  7. - * Trustly sends a {@link NotificationRequest}<{@link PendingNotificationData}> to the {@link DepositRequestData#setNotificationUrl} when the end-user has completed the payment process, - * and a {@link NotificationRequest}<{@link CreditNotificationData}> is sent when the payment is confirmed. - * When the funds have settled, they will be credited to the merchant's Trustly account balance. - *
  8. - *
  9. - * (Optional) An {@link NotificationRequest}<{@link AccountNotificationData}> is sent to provide the merchant with more information about the account that was used to make the payment. - *

    - * This notification is not enabled by default, please reach out to your Trustly contact if you want to receive it. - *

  10. - *
  11. - * In case the Deposit fails, a {@link NotificationRequest}<{@link DebitNotificationData}> is sent - * (see more information here). - *
  12. - *
- */ - public DepositResponseData deposit(DepositRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, DepositResponseData.class, "Deposit", null); - } - - /** - * This method returns the details of a payout (works for the {@link TrustlyApiClient#withdraw}, {@link TrustlyApiClient#accountPayout} - * and {@link TrustlyApiClient#refund} methods). - */ - public GetWithdrawalsResponseData getWithdrawals(GetWithdrawalsRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, GetWithdrawalsResponseData.class, "GetWithdrawals", null); - } - - /** - * Refunds the customer on a previous {@link TrustlyApiClient#deposit} or {@link TrustlyApiClient#charge}. - *

- * The Refund will always be made to the same bank account that was used in the original payment. - *

- * You must have sufficient funds on your merchant account to make the refund. No credit is given. If the deposit has not yet been settled - * when the refund request is received, the refund will be queued and executed once the money for the deposit has been received. - */ - public RefundResponseData refund(RefundRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, RefundResponseData.class, "Refund", null); - } - - public CreateAccountResponseData createAccount(CreateAccountRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, CreateAccountResponseData.class, "CreateAccount", null); - } - - /** - * Initiates a new order where the end-user can select and verify one of his/her bank accounts. - *

- * You can find more information about how to display the Trustly URL here. - *

- * When the account has been verified an account notification is immediately sent to the - * {@link SelectAccountRequestData#setNotificationUrl}. - *

- * A typical flow is: - *

    - *
  1. The merchant makes an API-call to this method and redirects the end-user to {@link SelectAccountResponseData#getUrl()}.
  2. - *
  3. The end-user selects his/her bank and completes the identification process.
  4. - *
  5. The end-user is redirected back to the merchant at {@link SelectAccountRequestDataAttributes#setSuccessUrl}. Note that the account might not be verified yet at this point.
  6. - *
  7. When the account is verified, Trustly sends an account notification to the merchant's system with information about the selected account
  8. - *
- */ - public SelectAccountResponseData selectAccount(SelectAccountRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, SelectAccountResponseData.class, "SelectAccount", null); - } - - /** - * Registers and verifies the format of an account to be used in {@link TrustlyApiClient#accountPayout}. - *

- * A typical payout flow is: - *

    - *
  1. The merchant makes an API-call to this method and receives an {@link RegisterAccountResponseData#getAccountId()} in response.
  2. - *
  3. The merchant saves the {@code accountid} as a valid payout option for the end user.
  4. - *
  5. - * When it's time to actually do a payout the merchant makes an API-call to - * {@link TrustlyApiClient#accountPayout} with the {@link AccountPayoutRequestData#setAmount}, - * {@link AccountPayoutRequestData#setCurrency} and saved {@link RegisterAccountResponseData#getAccountId()}. - *
  6. - *
- * Multiple calls to this method with the same bank account details will result in the same {@link RegisterAccountResponseData#getAccountId()} being returned. - */ - public RegisterAccountResponseData registerAccount(RegisterAccountRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, RegisterAccountResponseData.class, "RegisterAccount", null); - } - - public RegisterAccountPayoutResponseData registerAccountPayout(RegisterAccountPayoutRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, RegisterAccountPayoutResponseData.class, "RegisterAccountPayout", null); - } - - /** - * Initiate a settlement of funds, which will always be sent to the last settlement account for that specific currency. - *

- * The first settlement is required to be done through Trustly Back Office as the receiving bank account needs to be registered before a settlement can be processed. - */ - public MerchantSettlementResponseData registerMerchantSettlement(MerchantSettlementRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, MerchantSettlementResponseData.class, "MerchantSettlement", null); - } - - public SettlementReportResponseData settlementReport(SettlementReportRequestData request) throws TrustlyRequestException { - return this.sendRequest( - request, SettlementReportResponseData.class, "ViewAutomaticSettlementDetailsCSV", null - ); - } - - /** - * Initiates a new withdrawal, returning the URL where the end-user can complete the withdrawal process. - *

- * You can find more information about how to display the Trustly URL here. - *

- * A typical withdrawal flow is: - * - *

    - *
  1. The merchant sends a Withdraw API call and receives a {@link WithdrawResponseData#getUrl()} back from Trustly's API.
  2. - *
  3. The merchant displays {@link WithdrawResponseData#getUrl()} to the end-user (you can find more information about how to display it here).
  4. - *
  5. - * The end-user selects the amount to withdraw and provides his/her bank account details. - *
      - *
    • If the Withdrawal process is not completed, a {@link NotificationRequest}<{@link CancelNotificationData}> is sent.
    • - *
    - *
  6. - *
  7. - * - * When the end-user has completed the withdrawal process using the {@link WithdrawResponseData#getUrl()}, - * Trustly sends a {@link NotificationRequest}<{@link DebitNotificationData}> to {@link WithdrawRequestData#getNotificationUrl()}. - * The merchant should try to deduct the specified {@link DebitNotificationData#getAmount()} from the end-user's balance in the merchant's system. - * - *
      - *
    • If the merchant is able to deduct {@link DebitNotificationData#getAmount()} from the user's balance, the debit notification response should be sent with {@code "status": "OK"}.
    • - *
    • - * If the merchant is NOT able to deduct {@link DebitNotificationData#getAmount()} from the user's balance, the debit notification response should be sent with {@code "status": "FAILED"}. - * The withdrawal is then aborted on Trustly's side and an error message is shown to the end-user. A {@link NotificationRequest}<{@link CancelNotificationData}> is sent to the merchant. - *
    • - *
    - *
  8. - *
  9. - * (Optional) An {@link NotificationRequest}<{@link AccountNotificationData}> is sent to provide the merchant with more information about the account that was selected by the end user. - * This notification is not enabled by default, please reach out to your Trustly contact if you want to receive it. - * This information can be used by the merchant to determine if the Withdrawal should be approved or not (see next step). - *
  10. - *
  11. - * - * If manual approval is required, Trustly does nothing with the withdrawal request until it has been approved or denied by the merchant with {@link TrustlyApiClient#approveWithdrawal} / {@link TrustlyApiClient#denyWithdrawal}. - * (it is also possible for the merchant to approve or deny the withdrawal in Trustly's backoffice). - * Auto-approval can be enabled if requested. - * - *
      - *
    • If {@link TrustlyApiClient#denyWithdrawal} is sent, the withdrawal is aborted on Trustly's side and a {@link NotificationRequest}<{@link CancelNotificationData}> and {@link NotificationRequest}<{@link CreditNotificationData}> is sent to the merchant.
    • - *
    - *
  12. - *
  13. If the Withdrawal is approved, Trustly will process the withdrawal.
  14. - *
  15. - * (Optional) A {@link NotificationRequest}<{@link PayoutConfirmationNotificationData}> is sent to the merchant when the transfer has been confirmed. - * Note: this notification is not enabled by default. Please speak to your Trustly contact if you want to have it enabled. - *
  16. - *
  17. If the withdrawal fails, Trustly will send a {@link NotificationRequest}<{@link CreditNotificationData}> notification and a {@link NotificationRequest}<{@link CancelNotificationData}> - * (see more details here).
  18. - *
- */ - public WithdrawResponseData withdraw(WithdrawRequestData request) throws TrustlyRequestException { - return this.sendRequest(request, WithdrawResponseData.class, "Withdraw", null); - } - - // Notifications - - /** - * Add a custom listener for a certain notification type. - *

- * This method should only be used if there is no existing {@code addOnXyzListener} method for the notification you want. - */ - public void addNotificationListener(String method, Class dataClass, - NotificationEvent listener) { - - NotificationMeta meta = (NotificationMeta) this.onNotification.computeIfAbsent(method, k -> new NotificationMeta<>(dataClass)); - if (!meta.getDataClass().equals(dataClass)) { - throw new IllegalArgumentException( - String.format("Each notification method must be registered with the same type (%s vs %s)", dataClass, meta.getDataClass())); - } - - meta.getListeners().add(listener); - } - - public void addOnAccountListener(NotificationEvent listener) { - this.addNotificationListener("account", AccountNotificationData.class, listener); - } - - public void addOnCancelListener(NotificationEvent listener) { - this.addNotificationListener("cancel", CancelNotificationData.class, listener); - } - - public void addOnCreditListener(NotificationEvent listener) { - this.addNotificationListener("credit", CreditNotificationData.class, listener); - } - - public void addOnDebitListener(NotificationEvent listener) { - this.addNotificationListener("debit", DebitNotificationData.class, listener); - } - - public void addOnPayoutConfirmation(NotificationEvent listener) { - this.addNotificationListener("payoutconfirmation", PayoutConfirmationNotificationData.class, listener); - } - - public void addOnPending(NotificationEvent listener) { - this.addNotificationListener("pending", PendingNotificationData.class, listener); - } - - public void addOnUnknownNotification(NotificationEvent listener) { - this.addNotificationListener("", UnknownNotificationData.class, listener); - } - - // Base functionality - - /** - * Used internally to create a request package. You usually do not need to directly call this method unless you are creating a custom - * request that exist in the documentation but not as a managed type in this class. - * - * @param requestData The request data that will be used for the request - * @param method The method of the JsonRpc package - * @param uuid The UUID for the message, if null one will be generated for you. - * @param The type of the request data - * @return The JsonRpc response data - * @throws TrustlyValidationException Thrown if the request does not pass proper validations - */ - public JsonRpcRequest createRequestPackage( - T requestData, - String method, - String uuid - ) throws TrustlyValidationException { - - JsonRpcRequest rpcRequest = this.objectFactory.create(requestData, method, uuid); - JsonRpcRequest signedRpcRequest = this.signer.sign(rpcRequest); - - this.validator.validate(signedRpcRequest); - - return signedRpcRequest; - } - - /** - * Used internally to create a response package. - * - * @param method The method of the JsonRpc package - * @param uuid The UUID for the message, if null one will be generated for you - * @param responseData The response data that was received remotely - * @param The type of the response data - * @return A signed and validated JsonRpc response package - * @throws TrustlyValidationException Thrown if the response does not pass proper validations - */ - public JsonRpcResponse createResponsePackage( - String method, - String uuid, - R responseData - ) throws TrustlyValidationException { - - JsonRpcResponse rpcResponse = JsonRpcResponse.builder() - .version("1.1") - .result( - ResponseResult.builder() - .data(responseData) - .method(method) - .uuid(uuid) - .build() - ) - .build(); - - JsonRpcResponse signedResponse = this.signer.sign(rpcResponse); - - this.validator.validate(signedResponse); - - return signedResponse; - } - - /** - * Manually send a request to Trustly with the specified data and method and uuid. - *

- * Should only be used if you need to call an undocumented/newly released method that is not yet added to this library. - */ - public R sendRequest( - T requestData, - Class clazz, - String method, - String uuid - ) throws TrustlyRequestException { - - try { - return this.sendRequestWithSpecificExceptions(requestData, clazz, method, uuid); - } catch (IOException - | TrustlyValidationException - | TrustlyErrorResponseException - | TrustlyRejectionException - | TrustlySignatureException e) { - - throw new TrustlyRequestException(e); - } - } - - /** - * Sends given request to Trustly. - * - * @param requestData Request to send to Trustly API - * @param clazz Type of the JsonRpc response data - * @param method The RPC method name of the request - * @param uuid Optional UUID for the request. If not specified, one will be generated - * @param The outgoing JsonRpc request data type - * @param The expected JsonRpc response data type - * @return Response generated from the request - * @throws IOException If the remote end could not be contacted - * @throws TrustlyErrorResponseException If the response from Trustly contains an error body - * @throws TrustlyRejectionException If the request was rejected by Trustly from their server - * @throws TrustlySignatureException If the signature of the request or response could not be verified - * @throws TrustlyValidationException If the request or response could not be properly validated - */ - private R sendRequestWithSpecificExceptions( - T requestData, - Class clazz, - String method, - String uuid - ) throws TrustlyErrorResponseException, IOException, TrustlyRejectionException, TrustlySignatureException, TrustlyValidationException { - - requestData.setUsername(this.settings.getUsername()); - requestData.setPassword(this.settings.getPassword()); - - JsonRpcRequest rpcRequest = this.createRequestPackage(requestData, method, uuid); - - String requestString = this.objectMapper.writeValueAsString(rpcRequest); - - String responseString = this.httpRequester.request(this.settings, requestString); - - JsonNode rpcNodeResponse = this.objectMapper.readTree(responseString); - JavaType javaResponseType = this.objectMapper.getTypeFactory().constructParametricType(JsonRpcResponse.class, clazz); - JsonRpcResponse rpcResponse = this.objectMapper.readValue(responseString, javaResponseType); - - assertSuccessful(rpcResponse); - assertWithoutRejection(rpcResponse); - - this.signer.verify(rpcResponse, rpcNodeResponse); - - if (TrustlyStringUtils.isBlank(rpcResponse.getUUID()) || !rpcResponse.getUUID().equals(rpcRequest.getParams().getUuid())) { - throw new TrustlyValidationException( - String.format("Incoming UUID is not valid. Expected %s but got back %s", rpcRequest.getParams().getUuid(), rpcResponse.getUUID()) - ); - } - - return rpcResponse.getResult().getData(); - } - - private static void assertWithoutRejection(JsonRpcResponse rpcResponse) - throws TrustlyRejectionException { - - if (rpcResponse.getResult().getData() instanceof IWithRejectionResult) { - IWithRejectionResult rejectionResult = (IWithRejectionResult) rpcResponse.getResult().getData(); - - if (!rejectionResult.isResult()) { - - String message = rejectionResult.getRejected(); - if (TrustlyStringUtils.isBlank(message)) { - message = "The request was rejected for an unknown reason"; - } - - throw new TrustlyRejectionException( - "Received a rejection response from the Trustly API: " + message, - rejectionResult.getRejected() - ); - } - } - } - - private static void assertSuccessful(JsonRpcResponse rpcResponse) - throws TrustlyErrorResponseException { - - if (!rpcResponse.isSuccessfulResult()) { - - String message = null; - if (rpcResponse.getError() != null) { - message = rpcResponse.getError().getMessage(); - if (TrustlyStringUtils.isBlank(message)) { - message = rpcResponse.getError().getName(); - if (TrustlyStringUtils.isBlank(message)) { - message = ("" + rpcResponse.getError().getCode()); - } - } - } - - throw new TrustlyErrorResponseException(String.format("Received an error response from the Trustly API: %s", message), null, - rpcResponse.getError() - ); - } - } - - /** - * Will deserialize, verify and validate the incoming payload for you. - *

- * It will then call the appropriate notification listeners for this client only. If the incoming notification method does not have a - * listener, the {@code Unknown} notification listener will be called. - *

- * It is up to your listener to call the appropriate {@link NotificationArgs#respondWithOk()} or - * {@link NotificationArgs#respondWithFailed} methods, which will callback to your here given {@code onOK} or {@code onFailed} arguments. - *

- * It is recommended to not use this method directly if possible, and instead use - * {@link TrustlyApiClientExtensions#handleNotificationRequest} which will call all registered {@link TrustlyApiClient} notification - * listeners, and handle the servlet request reading and response writing. - *

- * If you want to handle the reading and writing yourself, then call this method from your own controller or servlet to help with the - * handling of an incoming notification. - * - * @param jsonString The incoming notification as a JSON string - * @param onOK The callback which will be executed if a listener calls {@link NotificationArgs#respondWithOk()}. - * @param onFailed The callback which will be executed if a listener calls {@link NotificationArgs#respondWithFailed(String)}. - * - * @throws IOException If the JSON string could not be deserialized or the response could not be sent. - * @throws TrustlyNoNotificationListenerException If there was no listener for the notification, nor one for unknown ones. - * @throws TrustlyValidationException If the response data could not be properly validated. - * @throws TrustlySignatureException If the signature of the response could not be properly verified. - */ - public void handleNotification( - String jsonString, - NotificationOkHandler onOK, - NotificationFailHandler onFailed - ) throws IOException, TrustlyNoNotificationListenerException, TrustlyValidationException, TrustlySignatureException { - - JsonNode jsonToken = this.objectMapper.readTree(jsonString); - String methodValue = jsonToken.at("/method").asText("").toLowerCase(Locale.ROOT); - - NotificationMeta mapper = this.onNotification.get(methodValue); - - if (mapper == null || mapper.getListeners().isEmpty()) { - log.warn(String.format("There is no listener for incoming notification '%s'. Will fallback on 'unknown' listener", methodValue)); - mapper = this.onNotification.get(""); - if (mapper == null || mapper.getListeners().isEmpty()) { - throw new TrustlyNoNotificationListenerException(String.format("There is no listener for incoming notification '%s' nor unknown", methodValue)); - } - } - - this.handleNotification(jsonString, mapper, onOK, onFailed); - } - - private void handleNotification( - String jsonString, - NotificationMeta meta, - NotificationOkHandler onOK, - NotificationFailHandler onFailed - ) throws IOException, TrustlyValidationException, TrustlySignatureException { - - JavaType javaRequestType = this.objectMapper.getTypeFactory().constructParametricType(NotificationRequest.class, meta.getDataClass()); - NotificationRequest rpcRequest = this.objectMapper.readValue(jsonString, javaRequestType); - - // Verify the notification (RpcRequest from Trustly) signature. - try { - this.signer.verify(rpcRequest); - } catch (TrustlySignatureException ex) { - throw new TrustlySignatureException( - "Could not validate signature of notification from Trustly. Is the public key for Trustly the correct one, for test or production?", - ex - ); - } - - // Validate the incoming request instance. - // Most likely this will do nothing, since we are lenient on things sent from Trustly server. - // But we do this in case anything is needed to be validated on the local domain classes in the future. - this.validator.validate(rpcRequest); - - NotificationArgs args = new NotificationArgs<>( - rpcRequest.getParams().getData(), - rpcRequest.getMethod(), - rpcRequest.getParams().getUuid(), - onOK, onFailed - ); - - try { - - for (NotificationEvent listener : meta.getListeners()) { - listener.onNotification(args); - } - } catch (Exception ex) { - String message = this.settings.isIncludeExceptionMessageInNotificationResponse() ? ex.getMessage() : null; - onFailed.handle(rpcRequest.getMethod(), rpcRequest.getParams().getUuid(), message); - } - } -} diff --git a/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java b/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java deleted file mode 100644 index f20abec..0000000 --- a/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.trustly.api.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.base.NotificationResponse; -import com.trustly.api.domain.exceptions.TrustlyDeprecatedException; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationClientException; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationListenerException; -import com.trustly.api.domain.exceptions.TrustlySignatureException; -import com.trustly.api.domain.exceptions.TrustlyValidationException; -import com.trustly.api.util.TrustlyStreamUtils; -import com.trustly.api.util.TrustlyStringUtils; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.concurrent.atomic.AtomicInteger; - -public class TrustlyApiClientExtensions { - - public interface NotificationResponder { - - void addHeader(String key, String value); - - void setStatus(int httpStatus); - - void writeBody(String value) throws IOException; - } - - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - - public static void handleNotificationRequest(InputStream incoming, NotificationResponder responder) - throws IOException, - TrustlyNoNotificationClientException, - TrustlyNoNotificationListenerException, - TrustlyValidationException, - TrustlySignatureException { - - String requestStringBody; - try (InputStreamReader sr = new InputStreamReader(incoming, StandardCharsets.UTF_8)) { - requestStringBody = TrustlyStreamUtils.readerToString(sr); - } - - final AtomicInteger responseCount = new AtomicInteger(0); - final AtomicInteger clientCount = new AtomicInteger(0); - for (TrustlyApiClient client : TrustlyApiClient.getRegisteredClients()) { - clientCount.incrementAndGet(); - client.handleNotification( - requestStringBody, - (method, uuid) -> { - responseCount.incrementAndGet(); - TrustlyApiClientExtensions.respond(client, responder, method, uuid, "OK", null, 200); - }, - (method, uuid, message) -> { - responseCount.incrementAndGet(); - TrustlyApiClientExtensions.respond(client, responder, method, uuid, "FAILED", message, 500); - } - ); - } - - if (clientCount.get() == 0) { - throw new TrustlyNoNotificationClientException("There are no registered Api Clients listening to notifications"); - } - - if (responseCount.get() == 0) { - throw new TrustlyNoNotificationClientException( - "None of your client's event listeners responded with OK or FAILED. That must be done."); - } - } - - /** - * @deprecated Use specific {@link TrustlyApiClientJakartaExtensions} or {@link TrustlyApiClientJavaxExtensions} depending on your need. - */ - @Deprecated - public static void handleNotificationRequest(Object request, Object response) throws TrustlyDeprecatedException { - throw new TrustlyDeprecatedException( - "Need to use the more specific TrustlyApiClientJakartaExtensions or TrustlyApiClientJavaxExtensions" - ); - } - - public static void respond( - TrustlyApiClient client, - NotificationResponder responder, - String method, - String uuid, - String status, - String message, - int httpStatusCode - ) throws IOException, TrustlyValidationException { - - NotificationResponse notificationResponse = NotificationResponse.builder() - .status(status) - .build(); - - JsonRpcResponse rpcResponse = client.createResponsePackage(method, uuid, notificationResponse); - - if (client.getSettings().isIncludeMessageInNotificationResponse() && !TrustlyStringUtils.isBlank(message)) { - - rpcResponse = rpcResponse.toBuilder() - .result( - rpcResponse.getResult().toBuilder() - .data( - rpcResponse.getResult().getData().toBuilder() - .any("message", message) - .build() - ) - .build() - ) - .build(); - } - - String rpcString = OBJECT_MAPPER.writeValueAsString(rpcResponse); - - String assemblyVersion = TrustlyApiClientExtensions.class.getPackage().getImplementationVersion(); - - responder.addHeader("Content-Type", "application/json"); - responder.addHeader("Accept", "application/json"); - responder.addHeader("User-Agent", "trustly-api-client-java/" + assemblyVersion); - responder.setStatus(httpStatusCode); - responder.writeBody(rpcString); - } -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractFromTrustlyRequestData.java b/src/main/java/com/trustly/api/domain/base/AbstractFromTrustlyRequestData.java deleted file mode 100644 index f60fd96..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractFromTrustlyRequestData.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.AllArgsConstructor; -import lombok.Value; -import lombok.experimental.NonFinal; -import lombok.experimental.SuperBuilder; - -@Value -@SuperBuilder -@NonFinal -@AllArgsConstructor -public class AbstractFromTrustlyRequestData - implements IFromTrustlyRequestData { - - public AbstractFromTrustlyRequestData() { - this.attributes = null; - } - - @JsonProperty(value = "attributes") - @JsonInclude(Include.NON_NULL) - @Valid - A attributes; -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractNotificationRequestData.java b/src/main/java/com/trustly/api/domain/base/AbstractNotificationRequestData.java deleted file mode 100644 index 85e3df6..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractNotificationRequestData.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@EqualsAndHashCode(callSuper = true) -@SuperBuilder -@AllArgsConstructor -@Jacksonized -public class AbstractNotificationRequestData - extends AbstractFromTrustlyRequestData { - - @JsonProperty("messageid") - String messageId; - @JsonProperty("notificationid") - String notificationId; - @JsonProperty("orderid") - String orderId; -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractRequestParamsDataAttributes.java b/src/main/java/com/trustly/api/domain/base/AbstractRequestParamsDataAttributes.java deleted file mode 100644 index 1d132d1..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractRequestParamsDataAttributes.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.Singular; -import lombok.experimental.SuperBuilder; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode -@RequiredArgsConstructor -@AllArgsConstructor -@JsonInclude(Include.NON_NULL) -public abstract class AbstractRequestParamsDataAttributes { - - @JsonAnySetter - @Singular("any") - private Map any; - - @JsonAnyGetter - public Map getAny() { - return this.any; - } -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractResponseResultData.java b/src/main/java/com/trustly/api/domain/base/AbstractResponseResultData.java deleted file mode 100644 index 901af92..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractResponseResultData.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import java.util.HashMap; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.Singular; -import lombok.Value; -import lombok.experimental.NonFinal; -import lombok.experimental.SuperBuilder; - -@Value -@SuperBuilder(toBuilder = true) -@NonFinal -@AllArgsConstructor -public abstract class AbstractResponseResultData implements IResponseResultData { - - @JsonAnySetter - @Singular("any") - Map any; - - @JsonAnyGetter - public Map getAny() { - return this.any; - } - - protected AbstractResponseResultData() { - this.any = new HashMap<>(); - } -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestData.java b/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestData.java deleted file mode 100644 index 661e214..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestData.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Data -@SuperBuilder(toBuilder = true) -@RequiredArgsConstructor -@AllArgsConstructor -public abstract class AbstractToTrustlyRequestData - implements IToTrustlyRequestParams { - - /** - * You do not have to set this property. It is set automatically by the API Client. - */ - @JsonProperty(value = "Username", required = true) - @NotBlank - String username; - - /** - * You do not have to set this property. It is set automatically by the API Client. - */ - @JsonProperty(value = "Password", required = true) - @NotBlank - String password; - - @JsonProperty(value = "Attributes", required = true) - @JsonInclude(Include.NON_NULL) - @Valid - A attributes; -} diff --git a/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestParams.java b/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestParams.java deleted file mode 100644 index c2129da..0000000 --- a/src/main/java/com/trustly/api/domain/base/AbstractToTrustlyRequestParams.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.trustly.api.domain.base; - -import jakarta.validation.Valid; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Data -@SuperBuilder(toBuilder = true) -@RequiredArgsConstructor -@AllArgsConstructor -public abstract class AbstractToTrustlyRequestParams implements IRequestParams { - - @Valid - D data; -} diff --git a/src/main/java/com/trustly/api/domain/base/EmptyRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/base/EmptyRequestDataAttributes.java deleted file mode 100644 index c8ceedf..0000000 --- a/src/main/java/com/trustly/api/domain/base/EmptyRequestDataAttributes.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.trustly.api.domain.base; - -public class EmptyRequestDataAttributes extends AbstractRequestParamsDataAttributes { - -} diff --git a/src/main/java/com/trustly/api/domain/base/IData.java b/src/main/java/com/trustly/api/domain/base/IData.java deleted file mode 100644 index 59d5e83..0000000 --- a/src/main/java/com/trustly/api/domain/base/IData.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IData { - -} diff --git a/src/main/java/com/trustly/api/domain/base/IFromTrustlyRequestData.java b/src/main/java/com/trustly/api/domain/base/IFromTrustlyRequestData.java deleted file mode 100644 index d0d2388..0000000 --- a/src/main/java/com/trustly/api/domain/base/IFromTrustlyRequestData.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IFromTrustlyRequestData extends IRequestParamsData { - -} diff --git a/src/main/java/com/trustly/api/domain/base/IRequest.java b/src/main/java/com/trustly/api/domain/base/IRequest.java deleted file mode 100644 index 64b4c95..0000000 --- a/src/main/java/com/trustly/api/domain/base/IRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IRequest

> { - - String getMethod(); - - double getVersion(); - - P getParams(); -} diff --git a/src/main/java/com/trustly/api/domain/base/IRequestParams.java b/src/main/java/com/trustly/api/domain/base/IRequestParams.java deleted file mode 100644 index 740c070..0000000 --- a/src/main/java/com/trustly/api/domain/base/IRequestParams.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IRequestParams { - - String getSignature(); - - String getUuid(); - - D getData(); - - IRequestParams withSignature(String value); -} diff --git a/src/main/java/com/trustly/api/domain/base/IRequestParamsData.java b/src/main/java/com/trustly/api/domain/base/IRequestParamsData.java deleted file mode 100644 index a174132..0000000 --- a/src/main/java/com/trustly/api/domain/base/IRequestParamsData.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.trustly.api.domain.base; - -/** - * Marker interface for restricting the generics through the project. We can use it to say that we want request params data, but not at all - * of what type. - */ -public interface IRequestParamsData extends IData { - -} diff --git a/src/main/java/com/trustly/api/domain/base/IResponseResultData.java b/src/main/java/com/trustly/api/domain/base/IResponseResultData.java deleted file mode 100644 index 1b4d670..0000000 --- a/src/main/java/com/trustly/api/domain/base/IResponseResultData.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.trustly.api.domain.base; - -import java.util.Map; - -public interface IResponseResultData extends IData { - - Map getAny(); -} diff --git a/src/main/java/com/trustly/api/domain/base/IToTrustlyRequestParams.java b/src/main/java/com/trustly/api/domain/base/IToTrustlyRequestParams.java deleted file mode 100644 index 49dce32..0000000 --- a/src/main/java/com/trustly/api/domain/base/IToTrustlyRequestParams.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IToTrustlyRequestParams extends IRequestParamsData { - - String getUsername(); - - void setUsername(String value); - - String getPassword(); - - void setPassword(String value); -} diff --git a/src/main/java/com/trustly/api/domain/base/IWithRejectionResult.java b/src/main/java/com/trustly/api/domain/base/IWithRejectionResult.java deleted file mode 100644 index 98b8267..0000000 --- a/src/main/java/com/trustly/api/domain/base/IWithRejectionResult.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.trustly.api.domain.base; - -public interface IWithRejectionResult { - - boolean isResult(); - - String getRejected(); -} diff --git a/src/main/java/com/trustly/api/domain/base/JsonRpcRequest.java b/src/main/java/com/trustly/api/domain/base/JsonRpcRequest.java deleted file mode 100644 index 90a69b7..0000000 --- a/src/main/java/com/trustly/api/domain/base/JsonRpcRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.Builder; -import lombok.Builder.Default; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder(toBuilder = true) -@RequiredArgsConstructor -@Jacksonized -public class JsonRpcRequest { - - @JsonProperty("method") - String method; - - @JsonProperty("params") - @Valid - IRequestParams params; - - @Default - @JsonProperty("version") - double version = 1.1; -} diff --git a/src/main/java/com/trustly/api/domain/base/JsonRpcResponse.java b/src/main/java/com/trustly/api/domain/base/JsonRpcResponse.java deleted file mode 100644 index ed209b3..0000000 --- a/src/main/java/com/trustly/api/domain/base/JsonRpcResponse.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.trustly.api.domain.base; - -import jakarta.validation.Valid; -import lombok.Builder; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder(toBuilder = true) -@RequiredArgsConstructor -@Jacksonized -public class JsonRpcResponse { - - String version; - - @Valid - ResponseResult result; - - @Valid - ResponseError error; - - public boolean isSuccessfulResult() { - return this.result != null && this.error == null; - } - - public String getUUID() { - return this.isSuccessfulResult() ? this.result.getUuid() : this.error.getError().getUuid(); - } - - public IData getData() { - if (this.isSuccessfulResult()) { - return this.result.getData(); - } else { - if (this.error != null && this.error.getError() != null) { - return this.error.getError().getData(); - } - } - - return null; - } - - public String getMethod() { - return this.isSuccessfulResult() ? this.result.getMethod() : this.error.getError().getMethod(); - } - - public String getSignature() { - return this.isSuccessfulResult() ? this.result.getSignature() : this.error.getError().getSignature(); - } -} diff --git a/src/main/java/com/trustly/api/domain/base/NotificationRequest.java b/src/main/java/com/trustly/api/domain/base/NotificationRequest.java deleted file mode 100644 index 4cde6d5..0000000 --- a/src/main/java/com/trustly/api/domain/base/NotificationRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.Builder; -import lombok.Builder.Default; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder(toBuilder = true) -@RequiredArgsConstructor -@Jacksonized -public class NotificationRequest implements IRequest> { - - @JsonProperty("method") - String method; - - @JsonProperty("params") - @Valid - NotificationRequestParams params; - - @Default - @JsonProperty("version") - double version = 1.1; -} diff --git a/src/main/java/com/trustly/api/domain/base/NotificationRequestParams.java b/src/main/java/com/trustly/api/domain/base/NotificationRequestParams.java deleted file mode 100644 index ca41e1a..0000000 --- a/src/main/java/com/trustly/api/domain/base/NotificationRequestParams.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.With; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@RequiredArgsConstructor -@SuperBuilder -@Jacksonized -public class NotificationRequestParams implements IRequestParams { - - @JsonProperty("signature") - @With - String signature; - - @JsonProperty("uuid") - String uuid; - - @JsonProperty("data") - @Valid - D data; -} diff --git a/src/main/java/com/trustly/api/domain/base/NotificationResponse.java b/src/main/java/com/trustly/api/domain/base/NotificationResponse.java deleted file mode 100644 index e140077..0000000 --- a/src/main/java/com/trustly/api/domain/base/NotificationResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.NonFinal; -import lombok.experimental.SuperBuilder; - -@SuperBuilder(toBuilder = true) -@Value -@EqualsAndHashCode(callSuper = true) -@NonFinal -@AllArgsConstructor -public class NotificationResponse extends AbstractResponseResultData { - - /** - * Valid values are: - * - *

- */ - @JsonProperty("status") - String status; -} diff --git a/src/main/java/com/trustly/api/domain/base/RequestParams.java b/src/main/java/com/trustly/api/domain/base/RequestParams.java deleted file mode 100644 index 0de6065..0000000 --- a/src/main/java/com/trustly/api/domain/base/RequestParams.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.Builder; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.With; -import lombok.experimental.NonFinal; - -@Value -@NonFinal -@Builder(toBuilder = true) -@RequiredArgsConstructor -public class RequestParams implements IRequestParams { - - @JsonProperty("Signature") - @With - String signature; - - @JsonProperty("UUID") - String uuid; - - @JsonProperty("Data") - @Valid - D data; -} diff --git a/src/main/java/com/trustly/api/domain/base/ResponseError.java b/src/main/java/com/trustly/api/domain/base/ResponseError.java deleted file mode 100644 index 28bbce0..0000000 --- a/src/main/java/com/trustly/api/domain/base/ResponseError.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.trustly.api.domain.base; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@EqualsAndHashCode(callSuper = true) -@SuperBuilder(toBuilder = true) -@AllArgsConstructor -@Jacksonized -public class ResponseError extends ResponseErrorData { - - String name; - - ResponseResult error; - - int code; - - String message; -} diff --git a/src/main/java/com/trustly/api/domain/base/ResponseErrorData.java b/src/main/java/com/trustly/api/domain/base/ResponseErrorData.java deleted file mode 100644 index d8f2da7..0000000 --- a/src/main/java/com/trustly/api/domain/base/ResponseErrorData.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.trustly.api.domain.base; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.NonFinal; -import lombok.experimental.SuperBuilder; - -@Value -@NonFinal -@EqualsAndHashCode(callSuper = true) -@SuperBuilder(toBuilder = true) -@AllArgsConstructor -public class ResponseErrorData extends AbstractResponseResultData { - - int code; - - String message; - - ResponseErrorData() { - this.code = -1; - this.message = null; - } -} diff --git a/src/main/java/com/trustly/api/domain/base/ResponseResult.java b/src/main/java/com/trustly/api/domain/base/ResponseResult.java deleted file mode 100644 index 8c20eec..0000000 --- a/src/main/java/com/trustly/api/domain/base/ResponseResult.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.trustly.api.domain.base; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder(toBuilder = true) -@AllArgsConstructor -@Jacksonized -public class ResponseResult { - - @JsonProperty(value = "signature") - String signature; - - @JsonProperty(value = "uuid") - String uuid; - - @JsonProperty(value = "method") - String method; - - @JsonProperty(value = "data") - @Valid - D data; -} diff --git a/src/main/java/com/trustly/api/domain/common/AbstractAccountDataAttributes.java b/src/main/java/com/trustly/api/domain/common/AbstractAccountDataAttributes.java deleted file mode 100644 index 7524a3c..0000000 --- a/src/main/java/com/trustly/api/domain/common/AbstractAccountDataAttributes.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.trustly.api.domain.common; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@JsonInclude(Include.NON_NULL) -public class AbstractAccountDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The end-user's first name. - */ - @JsonProperty(value = "Firstname", required = true) - @NotBlank - String firstname; - - /** - * The end-user's last name. - */ - @JsonProperty(value = "Lastname", required = true) - @NotBlank - String lastname; - - /** - * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. - * Note: This will only have an effect for new end-users.If an end-user has done a previous order(with the same EndUserID), the country - * that was last used will be pre-selected. - */ - @JsonProperty(value = "Country", required = true) - @NotBlank - @Pattern(regexp = "[A-Z]{2}") - String country; - - /** - * The end-users localization preference in the format[language[_territory]]. Language is the ISO 639-1 code and territory the ISO - * 3166-1-alpha-2 code. - */ - @JsonProperty(value = "Locale", required = true) - @Pattern(regexp = "[a-z]{2}_[A-Z]{2}") - @NotBlank - String locale; - - /** - * The text to show on the end-user's bank statement after Trustly's own 10 digit reference(which always will be displayed first). The - * reference must let the end user identify the merchant based on this value.So the ShopperStatement should contain either your brand - * name, website name, or company name. - */ - @JsonProperty(value = "ShopperStatement") - @NotBlank(groups = {DepositValidationGroup.class}) - String shopperStatement; - - /** - * The email address of the end user. - */ - @JsonProperty(value = "Email") - @NotBlank(groups = {DepositValidationGroup.class}) - @Email - String email; - - /** - * The mobile phone number of the end-user in international format. - */ - @JsonProperty(value = "MobilePhone") - @NotBlank(groups = {DepositValidationGroup.class}) - String mobilePhone; - - /** - * The IP-address of the end-user. - */ - @JsonProperty("IP") - String ip; - - /** - * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not - * guaranteed that the end-user will in fact visit it. - * - *
{@code https://example.com/thank_you.html}
- */ - @JsonProperty("SuccessURL") - @NotBlank - @URL - String successUrl; - - /** - * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed - * that the end-user will in fact visit it. - * - *
{@code https://trustly.com/error.html}
- */ - @JsonProperty(value = "FailURL") - @NotBlank - @URL - String failURL; - - /** - * The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your - * template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template - * page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will - * receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be iframed). - */ - @JsonProperty(value = "TemplateURL") - String templateURL; - - /** - * The html target/framename of the SuccessURL. Only _top, _self and _parent are suported. - */ - @JsonProperty(value = "URLTarget") - String urlTarget; - - /** - * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and - * KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. - */ - @JsonProperty(value = "NationalIdentificationNumber") - String nationalIdentificationNumber; - - /** - * This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank.If this - * attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only - * available for Swedish banks. - */ - @JsonProperty(value = "UnchangeableNationalIdentificationNumber") - String unchangeableNationalIdentificationNumber; - - /** - * If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your - * app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). - */ - @JsonProperty("URLScheme") - String urlScheme; -} diff --git a/src/main/java/com/trustly/api/domain/common/AbstractAmountConstrainedAccountDataAttributes.java b/src/main/java/com/trustly/api/domain/common/AbstractAmountConstrainedAccountDataAttributes.java deleted file mode 100644 index f32d324..0000000 --- a/src/main/java/com/trustly/api/domain/common/AbstractAmountConstrainedAccountDataAttributes.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.trustly.api.domain.common; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@JsonInclude(Include.NON_NULL) -public abstract class AbstractAmountConstrainedAccountDataAttributes extends AbstractAccountDataAttributes { - - /** - * The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal - * separator. - */ - @JsonProperty(value = "SuggestedMinAmount") - String suggestedMinAmount; - - /** - * The maximum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal - * separator. - */ - @JsonProperty(value = "SuggestedMaxAmount") - String suggestedMaxAmount; -} diff --git a/src/main/java/com/trustly/api/domain/common/RecipientOrSenderInformation.java b/src/main/java/com/trustly/api/domain/common/RecipientOrSenderInformation.java deleted file mode 100644 index adfa654..0000000 --- a/src/main/java/com/trustly/api/domain/common/RecipientOrSenderInformation.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.trustly.api.domain.common; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.Builder; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder(toBuilder = true) -@Jacksonized -@RequiredArgsConstructor -public class RecipientOrSenderInformation { - - /** - * Partytype can be "PERSON" or "ORGANISATION" (if the recipient or ultimate debtor is an organisation/company). - */ - @JsonProperty("Partytype") - @NotBlank - String partytype; - - /** - * First name of the person, or the name of the organisation. - */ - @JsonProperty("Firstname") - @NotBlank - String firstname; - - /** - * Last name of the person (NULL for organisation). - */ - @JsonProperty("Lastname") - @NotBlank - String lastname; - - /** - * The ISO 3166-1-alpha-2 code of the country that the recipient resides in. - */ - @JsonProperty("CountryCode") - @NotBlank - @Pattern(regexp = "[A-Z]{2}") - String countryCode; - - /** - * Payment account number or an alternative consistent unique identifier(e.g.customer number). Note: this is not a transaction ID or - * similar.This identifier must stay consistent across all transactions relating to this recipient (payee). - */ - @JsonProperty("CustomerID") - String customerID; - - /** - * Full address of the recipient, excluding the country. - */ - @JsonProperty("Address") - String address; - - /** - * Date of birth (YYYY-MM-DD) of the beneficiary, or organisational number for the organisation. - */ - @JsonProperty("DateOfBirth") - String dateOfBirth; -} diff --git a/src/main/java/com/trustly/api/domain/common/StringBooleanDeserializer.java b/src/main/java/com/trustly/api/domain/common/StringBooleanDeserializer.java deleted file mode 100644 index 5d68179..0000000 --- a/src/main/java/com/trustly/api/domain/common/StringBooleanDeserializer.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.trustly.api.domain.common; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.deser.std.StdDeserializer; -import java.io.IOException; - -public class StringBooleanDeserializer extends StdDeserializer { - - protected StringBooleanDeserializer() { - super(Boolean.class); - } - - @Override - public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { - String valueString = p.getValueAsString(""); - return "1".equals(valueString); - } -} diff --git a/src/main/java/com/trustly/api/domain/common/StringBooleanSerializer.java b/src/main/java/com/trustly/api/domain/common/StringBooleanSerializer.java deleted file mode 100644 index b819b37..0000000 --- a/src/main/java/com/trustly/api/domain/common/StringBooleanSerializer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.trustly.api.domain.common; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.ser.std.StdSerializer; -import java.io.IOException; - -public class StringBooleanSerializer extends StdSerializer { - - protected StringBooleanSerializer() { - super(Boolean.class); - } - - @Override - public void serialize(Boolean value, JsonGenerator gen, SerializerProvider provider) throws IOException { - gen.writeString(Boolean.TRUE.equals(value) ? "1" : "0"); - } -} diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyConnectionException.java b/src/main/java/com/trustly/api/domain/exceptions/TrustlyConnectionException.java deleted file mode 100644 index 5993436..0000000 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyConnectionException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.trustly.api.domain.exceptions; - -public class TrustlyConnectionException extends AbstractTrustlyApiException { - - public TrustlyConnectionException(String message) { - super(message); - } - - public TrustlyConnectionException(String message, Exception cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyDeprecatedException.java b/src/main/java/com/trustly/api/domain/exceptions/TrustlyDeprecatedException.java deleted file mode 100644 index ed686ed..0000000 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyDeprecatedException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.trustly.api.domain.exceptions; - -public class TrustlyDeprecatedException extends AbstractTrustlyApiException { - - public TrustlyDeprecatedException(String message) { - super(message); - } -} diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNotificationException.java b/src/main/java/com/trustly/api/domain/exceptions/TrustlyNotificationException.java deleted file mode 100644 index 0633c02..0000000 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNotificationException.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.trustly.api.domain.exceptions; - -public class TrustlyNotificationException extends AbstractTrustlyApiException { - - public TrustlyNotificationException(String message) { - super(message); - } - - public TrustlyNotificationException(String message, Exception cause) { - super(message, cause); - } -} diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyRejectionException.java b/src/main/java/com/trustly/api/domain/exceptions/TrustlyRejectionException.java deleted file mode 100644 index 0851200..0000000 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyRejectionException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.trustly.api.domain.exceptions; - -public class TrustlyRejectionException extends AbstractTrustlyApiException { - - private final String reason; - - public TrustlyRejectionException(String message, String reason) { - super(message); - this.reason = reason; - } - - public String getReason() { - return reason; - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerRequestData.java b/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerRequestData.java deleted file mode 100644 index c456622..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerRequestData.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.trustly.api.domain.methods.accountledger; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class AccountLedgerRequestData extends AbstractToTrustlyRequestData { - - @JsonProperty(value = "FromDate", required = true) - @NotBlank - String fromDate; - - @JsonProperty(value = "ToDate", required = true) - @NotBlank - String toDate; - - @JsonProperty(value = "Currency", required = true) - @Pattern(regexp = "[A-Z]{2,3}") - String currency; -} - - - diff --git a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseData.java b/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseData.java deleted file mode 100644 index 42e61ba..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.trustly.api.domain.methods.accountledger; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonValue; -import com.trustly.api.domain.base.IResponseResultData; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import lombok.Value; - -@Value -public class AccountLedgerResponseData implements IResponseResultData { - - @JsonValue - List entries; - - @JsonCreator - public AccountLedgerResponseData(List entries) { - this.entries = entries; - } - - @Override - @JsonIgnore - public Map getAny() { - return Collections.emptyMap(); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseDataEntry.java b/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseDataEntry.java deleted file mode 100644 index 37f0d4d..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountledger/AccountLedgerResponseDataEntry.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.trustly.api.domain.methods.accountledger; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder -@AllArgsConstructor -@Jacksonized -public class AccountLedgerResponseDataEntry { - - /** - * Your userid in our system. - */ - @JsonProperty("userid") - String userId; - - /** - * The datestamp for when this ledger row affected your balance in our system. - */ - @JsonProperty("datestamp") - String datestamp; - - /** - * The globally unique OrderID that resulted in this ledger record. - */ - @JsonProperty("orderid") - String orderId; - - /** - * The name of the bookkeeping account this ledger record belongs to. - */ - @JsonProperty("accountname") - String accountName; - - /** - * Your unique MessageID that you used to create the order that resulted in this ledger record. - */ - @JsonProperty("messageid") - String messageId; - - /** - * A human friendly description of this ledger record. - */ - @JsonProperty("transactiontype") - String transactionType; - - /** - * The currency of the amount in this ledger record. - */ - @JsonProperty("currency") - String currency; - - /** - * The amount your balance in our system was affected with due to this ledger record. May contain a lot of decimals. - */ - @JsonProperty("amount") - String amount; - - /** - * An ID meaning different things for different payment methods, you probably don't need this data. - */ - @JsonProperty("gluepayid") - String gluepayId; -} diff --git a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestData.java b/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestData.java deleted file mode 100644 index 0a64892..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestData.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.trustly.api.domain.methods.accountpayout; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class AccountPayoutRequestData extends AbstractToTrustlyRequestData { - - /** - * The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question - * mark"). - */ - @Pattern(regexp = "[^?]+") - @JsonProperty(value = "NotificationURL", required = true) - @NotBlank - String notificationURL; - - /** - * The AccountID received from an account notification to which the money shall be sent. - */ - @JsonProperty(value = "AccountID", required = true) - @NotBlank - String accountId; - - /** - * ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal, Preferably the same ID/username as used in - * the merchant's own backoffice in order to simplify for the merchant's support department. - */ - @JsonProperty(value = "EndUserID", required = true) - @NotBlank - String endUserId; - - /** - * Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order - * and the amount must be equal to or lower than the previously deposited amount. - */ - @JsonProperty(value = "MessageID", required = true) - @NotBlank - String messageId; - - /** - * The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the - * merchant's system then the amount must have been deducted from that balance before calling this method. - */ - @JsonProperty(value = "Amount", required = true) - @NotBlank - String amount; - - /** - * The currency of the end-user's account in the merchant's system. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestDataAttributes.java deleted file mode 100644 index 219c654..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutRequestDataAttributes.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.trustly.api.domain.methods.accountpayout; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import com.trustly.api.domain.common.RecipientOrSenderInformation; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class AccountPayoutRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The - * reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand - * name, website name, or company name. - *

- * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference - * field on the customer's bank since some banks allow only a limited number of characters. - */ - @JsonProperty(value = "ShopperStatement", required = true) - @NotBlank - String shopperStatement; - - /** - * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. The - * ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - */ - @JsonProperty(value = "ExternalReference") - String externalReference; - - /** - * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing - * account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to - * pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the - * e-money account of the payee ( "payment" stage). - */ - @JsonProperty(value = "pspMerchant") - String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing - * account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to - * pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the - * e-money account of the payee ( "payment" stage). - */ - @JsonProperty(value = "PSPMerchantURL") - String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing - * account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to - * pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the - * e-money account of the payee ( "payment" stage). - */ - @JsonProperty(value = "MerchantCategoryCode") - String merchantCategoryCode; - - /** - * Information about the Payer (ultimate debtor). This is required for some merchants and partners, see below. - *

- * SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid - * cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing - * account (other cases may also apply). - */ - @JsonProperty(value = "SenderInformation") - RecipientOrSenderInformation senderInformation; -} diff --git a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutResponseData.java b/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutResponseData.java deleted file mode 100644 index 3713f41..0000000 --- a/src/main/java/com/trustly/api/domain/methods/accountpayout/AccountPayoutResponseData.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.trustly.api.domain.methods.accountpayout; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class AccountPayoutResponseData extends AbstractResponseResultData { - - /** - * The globally unique OrderID the account payout order was assigned in our system. - */ - @JsonProperty("orderid") - long orderId; - - /** - * "1" if the payout could be accepted and "0" otherwise. - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; -} diff --git a/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalRequestData.java b/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalRequestData.java deleted file mode 100644 index 8c9817e..0000000 --- a/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalRequestData.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.methods.approvewithdrawal; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class ApproveWithdrawalRequestData extends AbstractToTrustlyRequestData { - - @JsonProperty(value = "OrderID", required = true) - long orderId; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalResponseData.java b/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalResponseData.java deleted file mode 100644 index ef5b03f..0000000 --- a/src/main/java/com/trustly/api/domain/methods/approvewithdrawal/ApproveWithdrawalResponseData.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.trustly.api.domain.methods.approvewithdrawal; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class ApproveWithdrawalResponseData extends AbstractResponseResultData { - - /** - * The OrderID specified when calling the method. - */ - @JsonProperty(value = "orderid", required = true) - long orderId; - - /** - * 1 if the withdrawal could be approved and 0 otherwise. - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; -} diff --git a/src/main/java/com/trustly/api/domain/methods/balance/BalanceRequestData.java b/src/main/java/com/trustly/api/domain/methods/balance/BalanceRequestData.java deleted file mode 100644 index 5896595..0000000 --- a/src/main/java/com/trustly/api/domain/methods/balance/BalanceRequestData.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.trustly.api.domain.methods.balance; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class BalanceRequestData extends AbstractToTrustlyRequestData { - -} - - diff --git a/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseData.java b/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseData.java deleted file mode 100644 index 8998ea4..0000000 --- a/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseData.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.trustly.api.domain.methods.balance; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonValue; -import com.trustly.api.domain.base.IResponseResultData; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import lombok.Value; - -@Value -public class BalanceResponseData implements IResponseResultData { - - @JsonValue - List entries; - - @JsonCreator - public BalanceResponseData(List entries) { - this.entries = entries; - } - - @Override - @JsonIgnore - public Map getAny() { - return Collections.emptyMap(); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseDataEntry.java b/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseDataEntry.java deleted file mode 100644 index 08a5ac9..0000000 --- a/src/main/java/com/trustly/api/domain/methods/balance/BalanceResponseDataEntry.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.trustly.api.domain.methods.balance; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@AllArgsConstructor -@Jacksonized -public class BalanceResponseDataEntry { - - /** - * The currency - */ - @JsonProperty("currency") - String currency; - - /** - * The balance with 2 decimals - */ - @JsonProperty("balance") - String balance; -} diff --git a/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeRequestData.java b/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeRequestData.java deleted file mode 100644 index b29a238..0000000 --- a/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeRequestData.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.trustly.api.domain.methods.cancelcharge; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class CancelChargeRequestData extends AbstractToTrustlyRequestData { - - /** - * The OrderID of the Charge request that should be canceled. - */ - @JsonProperty(value = "OrderID", required = true) - @NotBlank - String orderId; -} - - diff --git a/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeResponseData.java b/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeResponseData.java deleted file mode 100644 index cb51b5b..0000000 --- a/src/main/java/com/trustly/api/domain/methods/cancelcharge/CancelChargeResponseData.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.trustly.api.domain.methods.cancelcharge; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.base.IWithRejectionResult; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class CancelChargeResponseData extends AbstractResponseResultData implements IWithRejectionResult { - - /** - * {@code "1"} if the Charge could be canceled, and {@code "0"} otherwise. - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; - - /** - * If the CancelCharge was NOT accepted and result 0 is sent, a textual code describing the rejection reason will be sent here. - *

- * For a successful CancelCharge, this will be {@code null}. - */ - @JsonProperty("rejected") - @JsonInclude(Include.ALWAYS) - String rejected; -} diff --git a/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestData.java b/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestData.java deleted file mode 100644 index 02c6cd2..0000000 --- a/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestData.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.trustly.api.domain.methods.charge; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class ChargeRequestData extends AbstractToTrustlyRequestData { - - /** - * The AccountID received from an account notification which shall be charged. - */ - @JsonProperty(value = "AccountID", required = true) - @NotBlank - String accountId; - - /** - * The URL to which notifications for this payment should be sent to.This URL should be hard to guess and not contain a? ("question - * mark"). - */ - @JsonProperty(value = "NotificationURL", required = true) - @NotBlank - @URL - String notificationURL; - - /** - * ID, username, hash or anything uniquely identifying the end-user being charged. - *

- * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - */ - @JsonProperty(value = "EndUserID", required = true) - @NotBlank - String endUserId; - - /** - * Your unique ID for the charge. - */ - @JsonProperty(value = "MessageID", required = true) - @NotBlank - String messageId; - - /** - * The amount to charge with exactly two decimals.Only digits. Use dot (.) as decimal separator. - */ - @JsonProperty(value = "Amount", required = true) - @NotBlank - String amount; - - /** - * The currency of the amount to charge. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestDataAttributes.java deleted file mode 100644 index 51ebe71..0000000 --- a/src/main/java/com/trustly/api/domain/methods/charge/ChargeRequestDataAttributes.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.trustly.api.domain.methods.charge; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class ChargeRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The text to show on the end-user's bank statement as well as in end-user e-mail communication. On the bank statement, only the first - * seven characters (along with Trustly's reference) will be shown. - *

- * Allowed characters: - *

    - *
  • {@code A-Z} (both upper and lower case),
  • - *
  • {@code 0-9},
  • - *
  • {@code "."}, {@code "-"}, {@code "_"}, {@code " "} (dot, dash, underscore, space).
  • - *
- * - *

- * With {@code "Sport Shop"} set as ShopperStatement: - *

- *
In Bank Statement:
- *
{@code "T Sport S xyz"}
- * - *
In Email:
- *
{@code "Sport Shop"}
- *
- */ - @JsonProperty(value = "ShopperStatement", required = true) - @NotBlank - String shopperStatement; - - /** - * The email address of the end user. - */ - @JsonProperty(value = "Email", required = true) - @NotBlank - @Email - String email; - - /** - * The date when the funds will be charged from the end user's bank account. If this attribute is not sent, the charge will be attempted - * as soon as possible. - */ - @JsonProperty(value = "PaymentDate") - String paymentDate; - - /** - * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For - * example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the - * same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, - * ViewAutomaticSettlementDetailsCSV. - * - *
{@code 32423534523}
- */ - @JsonProperty(value = "ExternalReference") - String externalReference; - - /** - * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "pspMerchant") - String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "PSPMerchantURL") - String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "MerchantCategoryCode") - String merchantCategoryCode; -} diff --git a/src/main/java/com/trustly/api/domain/methods/charge/ChargeResponseData.java b/src/main/java/com/trustly/api/domain/methods/charge/ChargeResponseData.java deleted file mode 100644 index 48f75c9..0000000 --- a/src/main/java/com/trustly/api/domain/methods/charge/ChargeResponseData.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.trustly.api.domain.methods.charge; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.base.IWithRejectionResult; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class ChargeResponseData extends AbstractResponseResultData implements IWithRejectionResult { - - /** - * 1 if the charge was accepted for processing, 0 otherwise. Note that this is an acceptance of the order, no money has been charged from - * the account until you receive notifications thereof. - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; - - /** - * The globally unique OrderID the charge order was assigned in our system, or null if the charge was not accepted. The order has no - * end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. See section - * "Notifications" below for details. - */ - @JsonProperty("orderid") - String orderId; - - /** - * If the charge was NOT accepted, a textual code describing the rejection reason, null otherwise. - *

- * The possible rejected codes are: - *

- * ERROR_MANDATE_NOT_FOUND - the AccountID does not have an active mandate ERROR_DIRECT_DEBIT_NOT_ALLOWED - Trustly Direct Debit is not - * enabled on the merchant's account in Trustly's system. ERROR_ACCOUNT_NOT_FOUND - the specified AccountID does not exist. - */ - @JsonProperty("rejected") - String rejected; -} diff --git a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestData.java b/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestData.java deleted file mode 100644 index 909e434..0000000 --- a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestData.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.trustly.api.domain.methods.createaccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class CreateAccountRequestData extends AbstractToTrustlyRequestData { - - /** - * ID, username, hash or anything uniquely identifying the end-user holding this account. - *

- * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. - */ - @JsonProperty(value = "EndUserID", required = true) - @NotBlank - String endUserId; - - /** - * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See table* below. - */ - @JsonProperty(value = "ClearingHouse", required = true) - @NotBlank - String clearingHouse; - - /** - * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide - * an empty string (""). For non-IBAN format, see table* below. - */ - @JsonProperty(value = "BankNumber", required = true) - @NotBlank - String bankNumber; - - /** - * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table* below. - */ - @JsonProperty(value = "AccountNumber", required = true) - @NotBlank - String accountNumber; - /** - * First name of the account holder (or the name of the company/organization) - */ - @JsonProperty(value = "Firstname", required = true) - @NotBlank - String firstname; - - /** - * Last name of the account holder(empty for organizations/companies) - */ - @JsonProperty(value = "Lastname", required = true) - @NotBlank - String lastname; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestDataAttributes.java deleted file mode 100644 index c89edd2..0000000 --- a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountRequestDataAttributes.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.trustly.api.domain.methods.createaccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import jakarta.validation.constraints.Email; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class CreateAccountRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The date of birth of the account holder(ISO 8601). - */ - @JsonProperty(value = "DateOfBirth") - String dateOfBirth; - - /** - * The mobile phonenumber to the account holder in international format.This is used for KYC and AML routines. - */ - @JsonProperty(value = "MobilePhone") - String mobilePhone; - - /** - * The account holder's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions - * and KYC/AML. - */ - @JsonProperty(value = "NationalIdentificationNumber") - String nationalIdentificationNumber; - - /** - * The ISO 3166-1-alpha-2 code of the account holder's country. - */ - @JsonProperty(value = "AddressCountry") - String addressCountry; - - /** - * Postal code of the account holder. - */ - @JsonProperty(value = "AddressPostalCode") - String addressPostalCode; - - /** - * City of the account holder. - */ - @JsonProperty(value = "AddressCity") - String addressCity; - - /** - * Street address of the account holder. - */ - @JsonProperty(value = "AddressLine1") - String addressLine1; - - /** - * Additional address information of the account holder. - */ - @JsonProperty(value = "AddressLine2") - String addressLine2; - - /** - * The entire address of the account holder. This attribute should only be used if you are unable to provide the address information in - * the 5 separate attributes: - * - *

    - *
  • AddressCountry
  • - *
  • AddressPostalCode
  • - *
  • AddressCity
  • - *
  • AddressLine1
  • - *
  • AddressLine2
  • - *
- */ - @JsonProperty(value = "Address") - String address; - - /** - * The email address of the account holder. - */ - @JsonProperty(value = "Email") - @Email - String email; -} diff --git a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountResponseData.java b/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountResponseData.java deleted file mode 100644 index cad7109..0000000 --- a/src/main/java/com/trustly/api/domain/methods/createaccount/CreateAccountResponseData.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.trustly.api.domain.methods.createaccount; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class CreateAccountResponseData extends AbstractResponseResultData { - - /** - * The globally unique AccountID the account was assigned in our system. - */ - @JsonProperty("accountid") - String accountId; - - /** - * The clearinghouse for this account. - */ - @JsonProperty("clearinghouse") - String clearingHouse; - - /** - * The name of the bank for this account. - */ - @JsonProperty("bank") - String bank; - - /** - * A descriptor for this account that is safe to show to the end user. - */ - @JsonProperty("descriptor") - String descriptor; -} diff --git a/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalRequestData.java b/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalRequestData.java deleted file mode 100644 index abed571..0000000 --- a/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalRequestData.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.methods.denywithdrawal; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class DenyWithdrawalRequestData extends AbstractToTrustlyRequestData { - - @JsonProperty(value = "OrderID", required = true) - long orderId; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalResponseData.java b/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalResponseData.java deleted file mode 100644 index 25bf66c..0000000 --- a/src/main/java/com/trustly/api/domain/methods/denywithdrawal/DenyWithdrawalResponseData.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.trustly.api.domain.methods.denywithdrawal; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class DenyWithdrawalResponseData extends AbstractResponseResultData { - - /** - * The OrderID specified when calling the method. - */ - @JsonProperty("orderid") - long orderId; - - /** - * "1" if the refund request is accepted by Trustly's system. If the refund request is not accepted, you will get an error code back in - * the {@link JsonRpcResponse#getError()} - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; -} diff --git a/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestData.java b/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestData.java deleted file mode 100644 index b2c032f..0000000 --- a/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestData.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.trustly.api.domain.methods.deposit; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.common.DepositValidationGroup; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.groups.ConvertGroup; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class DepositRequestData extends AbstractToTrustlyRequestData { - - @JsonProperty("NotificationURL") - @NotBlank - @URL - private String notificationUrl; - - @JsonProperty("EndUserID") - @NotBlank - private String endUserId; - - @JsonProperty("MessageID") - @NotBlank - private String messageId; - - @JsonProperty(value = "Attributes", required = true) - @JsonInclude(Include.NON_NULL) - @Valid - @ConvertGroup(to = DepositValidationGroup.class) - @Override - public DepositRequestDataAttributes getAttributes() { - return super.getAttributes(); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestDataAttributes.java deleted file mode 100644 index a162bb0..0000000 --- a/src/main/java/com/trustly/api/domain/methods/deposit/DepositRequestDataAttributes.java +++ /dev/null @@ -1,184 +0,0 @@ -package com.trustly.api.domain.methods.deposit; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.common.AbstractAmountConstrainedAccountDataAttributes; -import com.trustly.api.domain.common.RecipientOrSenderInformation; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class DepositRequestDataAttributes extends AbstractAmountConstrainedAccountDataAttributes { - - /** - * iDeal. - *

- * The iDEAL integration offered by Trustly allows for both iDEAL and Trustly payments on a single integration with all transactions - * visible in the same AccountLedger. To initiate a new iDEAL payment, add Method = "deposit.bank.netherlands.ideal" to the Deposit - * attributes. - */ - @JsonProperty(value = "Method") - private String method; - - /** - * The currency of the end-user's account in the merchant's system. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - private String currency; - - /** - * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination with - * {@link DepositRequestDataAttributes#getSuggestedMinAmount()} and {@link DepositRequestDataAttributes#getSuggestedMaxAmount()}. Only - * digits. Use dot (.) as decimal separator. - */ - - @JsonProperty(value = "Amount") - private String amount; - - /** - * The ISO 3166-1-alpha-2 code of the shipping address country. - */ - @JsonProperty(value = "ShippingAddressCountry") - private String shippingAddressCountry; - - /** - * The postalcode of the shipping address. - */ - @JsonProperty(value = "ShippingAddressPostalCode") - private String shippingAddressPostalCode; - - /** - * The city of the shipping address. - */ - @JsonProperty(value = "ShippingAddressCity") - private String shippingAddressCity; - - /** - * Shipping address street - */ - @JsonProperty(value = "ShippingAddressLine1") - private String shippingAddressLine1; - - /** - * Additional shipping address information. - */ - @JsonProperty(value = "ShippingAddressLine2") - private String shippingAddressLine2; - - /** - * The entire shipping address. - *

- * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate attributes: - *

    - *
  • {@link DepositRequestDataAttributes#shippingAddressCountry}
  • - *
  • {@link DepositRequestDataAttributes#shippingAddressCity}
  • - *
  • {@link DepositRequestDataAttributes#shippingAddressPostalCode}
  • - *
  • {@link DepositRequestDataAttributes#shippingAddressLine1}
  • - *
  • {@link DepositRequestDataAttributes#shippingAddressLine2}
  • - *
- */ - @JsonProperty(value = "ShippingAddress") - private String shippingAddress; - - /** - * In addition to the deposit, request a direct debit mandate from the account used for the deposit. 1 enables, 0 disables. The default is - * disabled. If this attribute is set, additional account notifications might be sent. You can read more about Trustly Direct Debit here, - * under section 2.1 - */ - @JsonProperty(value = "RequestDirectDebitMandate") - private String requestDirectDebitMandate; - - /** - * The AccountID received from an account notification which shall be charged in a Trustly Direct Debit deposit. This attribute should - * only be sent in combination with "QuickDeposit" : 1 - */ - @JsonProperty("ChargeAccountID") - private String chargeAccountId; - - /** - * Set to 1 for Trustly Direct Debit deposits. QuickDeposit should be set set to 1 when the end user attempts a quick deposit, even if - * ChargeAccountID is not set. You can read more about QuickDeposits here, under section 1.1 and 1.2. - */ - @JsonProperty(value = "QuickDeposit") - private Integer quickDeposit; - - /** - * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. The - * ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - */ - @JsonProperty(value = "ExternalReference") - private String externalReference; - - /** - * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty("PSPMerchant") - private String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty("PSPMerchantURL") - private String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty(value = "MerchantCategoryCode") - private String merchantCategoryCode; - - /** - * The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. - */ - @JsonProperty(value = "AccountID") - private String accountId; - - /** - * Information about the Payee (ultimate creditor). The burden of identifying who the Payee for any given transaction is lies with the - * Trustly customer. - *

- * Required for some merchants and partners. - *

- * RecipientInformation is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, as - * well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other - * cases may also apply). - */ - @JsonProperty(value = "RecipientInformation") - private RecipientOrSenderInformation recipientInformation; - - /** - * Trustly will send a KYC notification to the merchant’s NotificationURL if the attribute "RequestKYC" : "1" is sent in a Deposit API call. - * The KYC notification should be expected after the end user has performed a successful login to their bank, and always before a deposit - * transfer is initiated. - */ - @JsonProperty(value = "RequestKYC") - private String requestKyc; -} diff --git a/src/main/java/com/trustly/api/domain/methods/deposit/DepositResponseData.java b/src/main/java/com/trustly/api/domain/methods/deposit/DepositResponseData.java deleted file mode 100644 index f56e914..0000000 --- a/src/main/java/com/trustly/api/domain/methods/deposit/DepositResponseData.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.trustly.api.domain.methods.deposit; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class DepositResponseData extends AbstractResponseResultData { - - /** - * The OrderID specified when calling the method. - */ - @JsonProperty("orderid") - String orderId; - - /** - * The URL that should be loaded so that the end-user can complete the deposit. - */ - @JsonProperty("url") - String url; -} diff --git a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsRequestData.java b/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsRequestData.java deleted file mode 100644 index 3c628a1..0000000 --- a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsRequestData.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.trustly.api.domain.methods.getwithdrawals; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class GetWithdrawalsRequestData extends AbstractToTrustlyRequestData { - - @JsonProperty(value = "OrderID") - String orderId; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseData.java b/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseData.java deleted file mode 100644 index f2604ff..0000000 --- a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseData.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.trustly.api.domain.methods.getwithdrawals; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; -import com.trustly.api.domain.base.IResponseResultData; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import lombok.Value; - -@Value -public class GetWithdrawalsResponseData implements IResponseResultData { - - @JsonValue - List entries; - - @JsonCreator - public GetWithdrawalsResponseData(List entries) { - this.entries = entries; - } - - @Override - public Map getAny() { - return Collections.emptyMap(); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseDataEntry.java b/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseDataEntry.java deleted file mode 100644 index 3e93dce..0000000 --- a/src/main/java/com/trustly/api/domain/methods/getwithdrawals/GetWithdrawalsResponseDataEntry.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.trustly.api.domain.methods.getwithdrawals; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.AllArgsConstructor; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@AllArgsConstructor -@Jacksonized -public class GetWithdrawalsResponseDataEntry { - - /** - * Reference code for the withdrawal generated by Trustly. - */ - @JsonProperty("reference") - String reference; - - /** - * Date and time when the withdrawal was last updated. - */ - @JsonProperty("modificationdate") - String modificationDate; - - /** - * OrderID of the withdrawal - */ - @JsonProperty("orderid") - String orderId; - - /** - * Date and time when the withdrawal request was received. - */ - @JsonProperty("datestamp") - String datestamp; - - /** - * The current state of the withdrawal. - *

- * Examples are: - *

    - *
  • EXECUTING
  • - *
  • EXECUTED
  • - *
  • PENDING
  • - *
  • QUEUED
  • - *
  • PREPARING
  • - *
  • PREPARED
  • - *
  • BOUNCED
  • - *
  • ERROR
  • - *
  • FAILED
  • - *
  • RETURNED
  • - *
  • CONFIRMED
  • - *
- * - *

- * It's important that no logic is built on the merchant side based on any specific transferState. - * New states can be added, and existing states can be changed or removed without notice. - */ - @JsonProperty("transferstate") - String transferState; - - /** - * The amount of the withdrawal. - */ - @JsonProperty("amount") - String amount; - - /** - * The accountid of the receiving account. - */ - @JsonProperty("accountid") - String accountid; - - /** - * The currency of the withdrawal. - */ - @JsonProperty("currency") - String currency; - - /** - * The estimated date and time for when the funds will be available on the receiving bank account.If this information is not available it - * will be null. - */ - @JsonProperty("eta") - String eta; -} diff --git a/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementRequestData.java b/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementRequestData.java deleted file mode 100644 index 2d8a05e..0000000 --- a/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementRequestData.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.trustly.api.domain.methods.merchantsettlement; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class MerchantSettlementRequestData extends AbstractToTrustlyRequestData { - - /** - * Your unique ID for the settlement transaction. - */ - @JsonProperty(value = "MessageID", required = true) - @NotBlank - String messageId; - - /** - * The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the - * merchant's system then the amount must have been deducted from that balance before calling this method. - */ - @JsonProperty(value = "Amount", required = true) - @NotBlank - String amount; - - /** - * The currency of the end-user's account in the merchant's system. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementResponseData.java b/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementResponseData.java deleted file mode 100644 index 9ccebf9..0000000 --- a/src/main/java/com/trustly/api/domain/methods/merchantsettlement/MerchantSettlementResponseData.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.trustly.api.domain.methods.merchantsettlement; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class MerchantSettlementResponseData extends AbstractResponseResultData { - - /** - * The globally unique reference ID for the settlement transaction. - */ - @JsonProperty("reference") - long reference; -} diff --git a/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestData.java b/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestData.java deleted file mode 100644 index fe305ac..0000000 --- a/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestData.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.trustly.api.domain.methods.refund; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RefundRequestData extends AbstractToTrustlyRequestData { - - /** - * The OrderID of the initial deposit. - */ - @JsonProperty(value = "OrderID", required = true) - @NotBlank - String orderId; - - /** - * The amount to refund the customer with exactly two decimals. Only digits. Use dot (.) as decimal separator. - */ - @JsonProperty(value = "Amount", required = true) - @NotBlank - String amount; - - /** - * The currency of the amount to refund the customer. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestDataAttributes.java deleted file mode 100644 index 8068758..0000000 --- a/src/main/java/com/trustly/api/domain/methods/refund/RefundRequestDataAttributes.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.trustly.api.domain.methods.refund; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RefundRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * This is a reference set by the merchant for any purpose and does not need to be unique for every API call. - *

- * This will be included in version {@code 1.2} of the settlement report, {@code ViewAutomaticSettlementDetailsCSV}. - */ - @JsonProperty(value = "ExternalReference") - String externalReference; -} diff --git a/src/main/java/com/trustly/api/domain/methods/refund/RefundResponseData.java b/src/main/java/com/trustly/api/domain/methods/refund/RefundResponseData.java deleted file mode 100644 index f7b46da..0000000 --- a/src/main/java/com/trustly/api/domain/methods/refund/RefundResponseData.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.trustly.api.domain.methods.refund; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class RefundResponseData extends AbstractResponseResultData { - - /** - * The OrderID specified when calling the method. - */ - @JsonProperty("orderid") - long orderId; - - /** - * "1" if the refund request is accepted by Trustly's system. - *

- * If the refund request is not accepted, you will get an error code back in {@link JsonRpcResponse#getError()}. - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; -} diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestData.java b/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestData.java deleted file mode 100644 index fa5cba9..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestData.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.trustly.api.domain.methods.registeraccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RegisterAccountRequestData extends AbstractToTrustlyRequestData { - - /** - * ID, username, hash or anything uniquely identifying the end-user to be identified. Preferably the same ID/username as used in the - * merchant's own backoffice in order to simplify for the merchant's support department - */ - @JsonProperty(value = "EndUserID") - @NotBlank - String endUserId; - - /** - * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See table - * here - *

{@code SWEDEN}
- */ - @JsonProperty(value = "ClearingHouse") - @NotBlank - String clearingHouse; - - /** - * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide - * an empty string (""). For non-IBAN format, see table here - */ - @JsonProperty(value = "BankNumber") - @NotBlank - String bankNumber; - - /** - * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table - * here - */ - @JsonProperty(value = "AccountNumber") - @NotBlank - String accountNumber; - - /** - * First name of the account holder (or the name of the company/organization) - */ - @JsonProperty(value = "Firstname") - @NotBlank - String firstname; - - /** - * Last name of the account holder (empty for organizations/companies) - */ - @JsonProperty(value = "Lastname") - @NotBlank - String lastname; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestDataAttributes.java deleted file mode 100644 index 334c364..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountRequestDataAttributes.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.trustly.api.domain.methods.registeraccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import jakarta.validation.constraints.Email; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RegisterAccountRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The end-user's date of birth. - * - *
{@code 1979-01-31}
- */ - @JsonProperty(value = "DateOfBirth") - String dateOfBirth; - - /** - * The mobile phonenumber to the account holder in international format. This is used for KYC and AML routines. - * - *
{@code +46709876543}
- */ - @JsonProperty(value = "MobilePhone") - String mobilePhone; - - /** - * The account holder's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions - * and KYC/AML. - * - *
{@code 790131-1234}
- */ - @JsonProperty(value = "NationalIdentificationNumber") - String nationalIdentificationNumber; - - /** - * The ISO 3166-1-alpha-2 code of the account holder's country. - * - *
{@code SE}
- */ - @JsonProperty(value = "AddressCountry") - String addressCountry; - - /** - * Postal code of the account holder. - * - *
{@code SE-11253}
- */ - @JsonProperty(value = "AddressPostalCode") - String addressPostalCode; - - /** - * City of the account holder. - * - *
{@code Stockholm}
- */ - @JsonProperty(value = "AddressCity") - String addressCity; - - /** - * Street address of the account holder. - * - *
{@code  Main street 1}
- */ - @JsonProperty(value = "AddressLine1") - String addressLine1; - - /** - * Additional address information of the account holder. - * - *
{@code Apartment 123, 2 stairs up}
- */ - @JsonProperty(value = "AddressLine2") - String addressLine2; - - /** - * The entire address of the account holder. This attribute should only be used if you are unable to provide the address information in - * the 5 separate attributes above (AddressCountry, AddressPostalCode, AddressCity, AddressLine1 and AddressLine2). - * - *
{@code Birgerstreet 14, SE-11411, Stockholm, Sweden}
- */ - @JsonProperty(value = "Address") - String address; - - /** - * The email address of the account holder. - * - *
{@code test@trustly.com}
- */ - @JsonProperty(value = "Email") - @Email - String email; - -} diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountResponseData.java b/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountResponseData.java deleted file mode 100644 index 1bdb84c..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccount/RegisterAccountResponseData.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.trustly.api.domain.methods.registeraccount; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class RegisterAccountResponseData extends AbstractResponseResultData { - - /** - * The globally unique AccountID the account was assigned in our system. - * - *
{@code 7653385737}
- */ - @JsonProperty(value = "accountid") - String accountId; - - /** - * The clearinghouse for this account. - * - *
{@code SWEDEN}
- */ - @JsonProperty(value = "clearinghouse") - String clearingHouse; - - /** - * The name of the bank for this account. - * - *
{@code Skandiabanken}
- */ - @JsonProperty(value = "bank") - String bank; - - /** - * A descriptor for this account that is safe to show to the end user. - * - *
{@code ***4057}
- */ - @JsonProperty(value = "descriptor") - String descriptor; -} diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestData.java b/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestData.java deleted file mode 100644 index 932a809..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestData.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.trustly.api.domain.methods.registeraccountpayout; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RegisterAccountPayoutRequestData extends AbstractToTrustlyRequestData { - - /** - * ID, username, hash or anything uniquely identifying the end-user to be identified. Preferably the same ID/username as used in the - * merchant's own backoffice in order to simplify for the merchant's support department - */ - @JsonProperty(value = "EndUserID") - String endUserId; - - /** - * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. - *

- * See table here. - * - *

{@code SWEDEN}
- */ - @JsonProperty(value = "ClearingHouse") - String clearingHouse; - - /** - * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide - * an empty string (""). For non-IBAN format, see table here - */ - @JsonProperty(value = "BankNumber") - String bankNumber; - - /** - * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see table - * here - */ - @JsonProperty(value = "AccountNumber") - String accountNumber; - - /** - * First name of the account holder (or the name of the company/organization) - */ - @JsonProperty(value = "Firstname") - String firstname; - - /** - * Last name of the account holder (empty for organizations/companies) - */ - @JsonProperty(value = "Lastname") - String lastname; - - /** - * The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question - * mark"). - */ - @JsonProperty(value = "NotificationURL", required = true) - @NotBlank - @URL - String notificationUrl; - - /** - * Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order - * and the amount must be equal to or lower than the previously deposited amount. - */ - @JsonProperty(value = "MessageID", required = true) - @NotBlank - String messageId; - - /** - * The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the - * merchant's system then the amount must have been deducted from that balance before calling this method. - */ - @JsonProperty(value = "Amount", required = true) - @NotBlank - String amount; - - /** - * The currency of the end-user's account in the merchant's system. - */ - @JsonProperty(value = "Currency", required = true) - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestDataAttributes.java deleted file mode 100644 index 3906420..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutRequestDataAttributes.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.trustly.api.domain.methods.registeraccountpayout; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import com.trustly.api.domain.common.RecipientOrSenderInformation; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class RegisterAccountPayoutRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The - * reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand - * name, website name, or company name. - *

- * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference - * field on the customer's bank since some banks allow only a limited number of characters. - */ - @JsonProperty(value = "ShopperStatement", required = true) - @NotBlank - String shopperStatement; - - /** - * *The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique *for every API call. The - * ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - */ - @JsonProperty(value = "ExternalReference") - String externalReference; - - /** - * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty(value = "PSPMerchant") - String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty(value = "PSPMerchantURL") - String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. - *

- */ - @JsonProperty(value = "MerchantCategoryCode") - String merchantCategoryCode; - - /** - * Information about the Payer (ultimate debtor). This is required for some merchants and partners, see below. - */ - @JsonProperty(value = "SenderInformation") - RecipientOrSenderInformation senderInformation; - - /** - * The end-user's date of birth. - * - *
{@code 1979-01-31}
- */ - @JsonProperty(value = "DateOfBirth") - String dateOfBirth; - - /** - * The mobile phonenumber to the account holder in international format. This is used for KYC and AML routines. - * - *
{@code +46709876543}
- */ - @JsonProperty(value = "MobilePhone") - String mobilePhone; - - /** - * The account holder's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions - * and KYC/AML. - * - *
{@code 790131-1234}
- */ - @JsonProperty(value = "NationalIdentificationNumber") - String nationalIdentificationNumber; - - /** - * The ISO 3166-1-alpha-2 code of the account holder's country. - * - *
{@code SE}
- */ - @JsonProperty(value = "AddressCountry") - String addressCountry; - - /** - * Postal code of the account holder. - * - *
{@code SE-11253}
- */ - @JsonProperty(value = "AddressPostalCode") - String addressPostalCode; - - /** - * City of the account holder. - * - *
{@code Stockholm}
- */ - @JsonProperty(value = "AddressCity") - String addressCity; - - /** - * Street address of the account holder. - * - *
{@code Main street 1}
- */ - @JsonProperty(value = "AddressLine1") - String addressLine1; - - /** - * Additional address information of the account holder. - * - *
{@code Apartment 123, 2 stairs up}
- */ - @JsonProperty(value = "AddressLine2") - String addressLine2; - - /** - * The entire address of the account holder. This attribute should only be used if you are unable to provide the address information in - * the 5 separate attributes above (AddressCountry, AddressPostalCode, AddressCity, AddressLine1 and AddressLine2). - * - *
{@code Birgerstreet 14, SE-11411 Stockholm, Sweden}
- */ - @JsonProperty(value = "Address") - String address; - - /** - * The email address of the account holder. - * - *
{@code test@trustly.com}
- */ - @JsonProperty(value = "Email") - @Email - String email; -} diff --git a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutResponseData.java b/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutResponseData.java deleted file mode 100644 index 37118db..0000000 --- a/src/main/java/com/trustly/api/domain/methods/registeraccountpayout/RegisterAccountPayoutResponseData.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.trustly.api.domain.methods.registeraccountpayout; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractResponseResultData; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class RegisterAccountPayoutResponseData extends AbstractResponseResultData { - - /** - * The globally unique OrderID the account payout order was assigned in our system . - */ - @JsonProperty("orderid") - long orderId; - - /** - * "1" if the payout could be accepted and "0" otherwise . - */ - @JsonProperty("result") - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean result; -} diff --git a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestData.java b/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestData.java deleted file mode 100644 index 61b580c..0000000 --- a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestData.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.trustly.api.domain.methods.selectaccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class SelectAccountRequestData extends AbstractToTrustlyRequestData { - - /** - * The URL to which notifications for this order should be sent to.This URL should be hard to guess and not contain a? ("question mark"). - * - *
{@code https://example.com/trustly/notification/a2b63j23dj23883jhfhfh}
- */ - @JsonProperty(value = "NotificationURL", required = true) - @NotBlank - @URL - String notificationUrl; - - /** - * ID, username, hash or anything uniquely identifying the end-user to be identified. Preferably the same ID/username as used in the - * merchant's own backoffice in order to simplify for the merchant's support department - */ - @JsonProperty(value = "EndUserID", required = true) - @NotBlank - String endUserId; - - /** - * Your unique ID for the account selection order. Each order you create must have an unique MessageID. - */ - @JsonProperty(value = "MessageID", required = true) - @NotBlank - String messageId; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestDataAttributes.java deleted file mode 100644 index b51e5bd..0000000 --- a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountRequestDataAttributes.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.trustly.api.domain.methods.selectaccount; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.common.AbstractAccountDataAttributes; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class SelectAccountRequestDataAttributes extends AbstractAccountDataAttributes { - - /** - * Only for Trustly Direct Debit. Request a direct debit mandate from the selected account. 1 or 0. See section "Direct Debit Mandates" - * below for details. - *

- * If this is set to 1, then {@link SelectAccountRequestDataAttributes#getEmail()} is required. - */ - @JsonProperty(value = "RequestDirectDebitMandate") - int requestDirectDebitMandate; - - /** - * The end-user's date of birth. - * - *

{@code 1979-01-31}
- */ - @JsonProperty(value = "DateOfBirth") - String dateOfBirth; - - /** - * Human-readable identifier of the consumer-facing merchant(e.g.legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding(EMO) and aggregate traffic under a master - * processing account. - *

- * - *
{@code Merchant Ltd.}
- */ - @JsonProperty(value = "pspMerchant") - String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding(EMO) and aggregate traffic under a master - * processing account. - *

- * - *
{@code www.merchant.com}
- */ - @JsonProperty(value = "PSPMerchantURL") - String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "MerchantCategoryCode") - String merchantCategoryCode; -} diff --git a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountResponseData.java b/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountResponseData.java deleted file mode 100644 index 00e2528..0000000 --- a/src/main/java/com/trustly/api/domain/methods/selectaccount/SelectAccountResponseData.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.trustly.api.domain.methods.selectaccount; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class SelectAccountResponseData extends AbstractResponseResultData { - - /** - * The globally unique OrderID the account selection order was assigned in our system. - * - *
{@code 7653345737}
- */ - @JsonProperty("orderid") - String orderId; - - /** - * The URL that should be loaded so that the end-user can complete the identification process. - * - *
{@code https://trustly.com/_/2f6b14fa-446a-4364-92f8-84b738d589ff}
- */ - @JsonProperty("url") - String url; -} diff --git a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportParser.java b/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportParser.java deleted file mode 100644 index 1be6825..0000000 --- a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportParser.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.trustly.api.domain.methods.settlementreport; - -import com.trustly.api.domain.methods.settlementreport.SettlementReportResponseDataEntry.SettlementReportResponseDataEntryBuilder; -import java.time.Instant; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; -import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public class SettlementReportParser { - - @FunctionalInterface - public interface Mapper { - - void map(SettlementReportResponseDataEntryBuilder row, String value); - } - - private static final Mapper NOOP_MAPPER = (row, value) -> { - }; - - private static final DateTimeFormatter[] DATE_TIME_FORMATTERS = new DateTimeFormatter[]{ - - new DateTimeFormatterBuilder() - .parseCaseInsensitive() - .append(DateTimeFormatter.ISO_LOCAL_DATE) - .appendLiteral(' ') - .append(DateTimeFormatter.ISO_LOCAL_TIME) - .appendOffsetId() - .toFormatter(Locale.ROOT), - - DateTimeFormatter.ISO_DATE_TIME, - DateTimeFormatter.ISO_INSTANT - }; - - private final Map mappers = new HashMap<>(); - - public SettlementReportParser() { - this.mappers.put("accountname", SettlementReportResponseDataEntryBuilder::accountName); - this.mappers.put("currency", SettlementReportResponseDataEntryBuilder::currency); - this.mappers.put("messageid", SettlementReportResponseDataEntryBuilder::messageId); - this.mappers.put("orderid", SettlementReportResponseDataEntryBuilder::orderId); - this.mappers.put("ordertype", SettlementReportResponseDataEntryBuilder::orderType); - this.mappers.put("username", SettlementReportResponseDataEntryBuilder::username); - this.mappers.put("fxpaymentcurrency", SettlementReportResponseDataEntryBuilder::fxPaymentCurrency); - this.mappers.put("settlementbankwithdrawalid", SettlementReportResponseDataEntryBuilder::settlementBankWithdrawalId); - this.mappers.put("externalreference", SettlementReportResponseDataEntryBuilder::externalReference); - - this.mappers.put("amount", (row, value) -> row.amount(Double.parseDouble(value))); - this.mappers.put("fxpaymentamount", (row, value) -> row.fxPaymentAmount(Double.parseDouble(value))); - this.mappers.put("total", (row, value) -> row.total(Double.parseDouble(value))); - - this.mappers.put("datestamp", (row, value) -> { - - List exceptions = new ArrayList<>(); - for (DateTimeFormatter formatter : DATE_TIME_FORMATTERS) { - try { - row.datestamp(formatter.parse(value, Instant::from)); - return; - } catch (DateTimeParseException ex) { - exceptions.add(ex); - } - } - - throw exceptions.stream().findFirst().orElseThrow(() -> new IllegalStateException("Unknown date format exception")); - }); - } - - public List parse(String csv) { - String[] lines = csv.replace("\r", "").trim().split("\n"); - List rows = new ArrayList<>(); - - if (lines.length == 0) { - return rows; - } - - String[] headers = lines[0].split(","); - - List localMappers = new ArrayList<>(); - for (String header : headers) { - String lowerCaseHeaderKey = header.toLowerCase(Locale.ROOT); - if (this.mappers.containsKey(lowerCaseHeaderKey)) { - localMappers.add(this.mappers.get(lowerCaseHeaderKey)); - } else { - // We do not recognize this new header key. - // This could count as an error, but we will let it go. - // The preferred way would perhaps be to log about the lost data, - // but we do not want to include a dependency on a logging library. - localMappers.add(NOOP_MAPPER); - } - } - - for (int i = 1; i < lines.length; i++) { - String line = lines[i]; - if (line == null || line.isEmpty()) { - continue; - } - - String[] fieldsValues = this.getFieldValues(line); - - SettlementReportResponseDataEntryBuilder rowBuilder = SettlementReportResponseDataEntry.builder(); - for (int columnIndex = 0; columnIndex < fieldsValues.length; columnIndex++) { - if (fieldsValues[columnIndex] != null && !fieldsValues[columnIndex].isEmpty()) { - localMappers.get(columnIndex).map(rowBuilder, fieldsValues[columnIndex]); - } - } - - rows.add(rowBuilder.build()); - } - - return rows; - } - - private String[] getFieldValues(String line) { - List tokens = new ArrayList<>(); - - StringBuilder buffer = new StringBuilder(); - boolean insideQuote = false; - - for (int i = 0; i < line.length(); i++) { - char c = line.charAt(i); - if (insideQuote) { - if (c == '"') { - insideQuote = false; - } else { - buffer.append(c); - } - } else { - if (c == '"') { - insideQuote = true; - } else if (c == ',') { - tokens.add(buffer.toString()); - buffer.setLength(0); - } else { - buffer.append(c); - } - } - } - - if (buffer.length() > 0) { - tokens.add(buffer.toString()); - buffer.setLength(0); - } - - return tokens.toArray(new String[0]); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestData.java b/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestData.java deleted file mode 100644 index 3466a80..0000000 --- a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestData.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.trustly.api.domain.methods.settlementreport; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class SettlementReportRequestData extends AbstractToTrustlyRequestData { - - /** - * If the value is specified (i.e. not "null"), the system will only search for a settlement executed in that particular currency. If - * unspecified, settlements executed in any currency are included in the report. - */ - @JsonProperty(value = "Currency") - String currency; - - /** - * The date when the settlement was processed. - * - *
{@code 2014-04-01}
- */ - @JsonProperty(value = "SettlementDate") - String settlementDate; -} - - diff --git a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestDataAttributes.java deleted file mode 100644 index 65e4c04..0000000 --- a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportRequestDataAttributes.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.trustly.api.domain.methods.settlementreport; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class SettlementReportRequestDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * Required. The APIVersion. - * - *

Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants.

- * - *
{@code 1.2}
- */ - @JsonProperty(value = "APIVersion", required = true) - @NotBlank - @Pattern(regexp = "1\\.2") - String apiVersion; -} diff --git a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseData.java b/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseData.java deleted file mode 100644 index a34288c..0000000 --- a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseData.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.trustly.api.domain.methods.settlementreport; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class SettlementReportResponseData extends AbstractResponseResultData { - - String csvContent; - - @JsonIgnore - List entries; - - @JsonCreator - public SettlementReportResponseData(@JsonProperty("view_automatic_settlement_details") String csvContent) { - this.csvContent = csvContent; - this.entries = new SettlementReportParser().parse(csvContent); - } -} diff --git a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseDataEntry.java b/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseDataEntry.java deleted file mode 100644 index f40f221..0000000 --- a/src/main/java/com/trustly/api/domain/methods/settlementreport/SettlementReportResponseDataEntry.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.trustly.api.domain.methods.settlementreport; - -import com.fasterxml.jackson.annotation.JsonAlias; -import java.time.Instant; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Value; -import lombok.extern.jackson.Jacksonized; - -@Value -@Builder -@AllArgsConstructor -@Jacksonized -public class SettlementReportResponseDataEntry { - - /** - * The account the money was transferred from(if the amount is positive), or the account the money was transferred to(if the amount is - * negative). - */ - String accountName; - - /** - * The monetary amount of the transaction, rounded down to two decimal places. - */ - Double amount; - - /** - * The three-letter currency code of the transaction. - */ - String currency; - - /** - * The timestamp of the transaction, including the UTC offset.As the timestamps are always in UTC, the offset is always +00 - * - *
{@code 2014-03-31 11:50:06.46106+00}
- */ - Instant datestamp; - - /** - * MessageID of the order associated with the transaction, if available. - */ - String messageId; - - /** - * OrderID of the order associated with the transaction, if available. - */ - String orderId; - - /** - * The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. - */ - String orderType; - - /** - * The sum of all amounts of the respective currency within the report. - */ - Double total; - - /** - * The username of the child merchant account. - */ - String username; - - /** - * The amount that the end user paid, if the currency is different from the requested deposit currency. For transactions where the payment - * currency is the same as the requested currency, this field will be empty. - */ - Double fxPaymentAmount; - - /** - * The currency that the user paid with, if the currency is different from the requested deposit currency. For transactions where the - * payment currency is the same as the requested currency, this field will be empty. - */ - String fxPaymentCurrency; - - /** - * The 10 digit reference that will show up on the merchant's bank statement for this automatic settlement batch. The same value will be - * sent on every row in the report. - */ - String settlementBankWithdrawalId; - - /** - * Contains the ExternalReference value for Deposit, Charge, and Refund transactions if provided.Otherwise empty. - */ - @JsonAlias("extraRef") - String externalReference; -} diff --git a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestData.java b/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestData.java deleted file mode 100644 index 9d08f65..0000000 --- a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestData.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.trustly.api.domain.methods.withdraw; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractToTrustlyRequestData; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; -import org.hibernate.validator.constraints.URL; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class WithdrawRequestData extends AbstractToTrustlyRequestData { - - /** - * The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question - * mark"). - */ - @JsonProperty(value = "NotificationURL") - @NotBlank - @URL - String notificationUrl; - - /** - * ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal, Preferably the same ID/username as used in - * the merchant's own backoffice in order to simplify for the merchant's support department. - */ - @JsonProperty(value = "EndUserID") - @NotBlank - String endUserId; - - /** - * Your unique ID for the withdrawal. - */ - @JsonProperty(value = "MessageID") - @NotBlank - String messageId; - - /** - * The currency of the end-user's account in the merchant's system. - */ - @JsonProperty(value = "Currency") - @NotBlank - String currency; -} - diff --git a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestDataAttributes.java b/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestDataAttributes.java deleted file mode 100644 index bcbc757..0000000 --- a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawRequestDataAttributes.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.trustly.api.domain.methods.withdraw; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.common.AbstractAmountConstrainedAccountDataAttributes; -import com.trustly.api.domain.common.RecipientOrSenderInformation; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Data -@SuperBuilder(toBuilder = true) -@EqualsAndHashCode(callSuper = true) -@RequiredArgsConstructor -@AllArgsConstructor -@Jacksonized -@JsonInclude(Include.NON_NULL) -public class WithdrawRequestDataAttributes extends AbstractAmountConstrainedAccountDataAttributes { - - /** - * Sets a fixed withdrawal amount which cannot be changed by the end-user in the Trustly iframe. If this attribute is not sent, the - * end-user will be asked to select the withdrawal amount in the Trustly iframe - *

- * Do not use in combination with {@link WithdrawRequestDataAttributes#getSuggestedMinAmount()} and - * {@link WithdrawRequestDataAttributes#getSuggestedMaxAmount()}. - *

- * Use dot(.) as decimal separator. - */ - @JsonProperty(value = "SuggestedAmount") - String suggestedAmount; - - /** - * The end-user's first name. - */ - @JsonProperty(value = "DateOfBirth") - String dateOfBirth; - - /** - * The ISO 3166-1-alpha-2 code of the shipping address country. - */ - @JsonProperty(value = "AddressCountry") - String addressCountry; - - /** - * The postalcode of the shipping address. - */ - @JsonProperty(value = "AddressPostalCode") - String addressPostalCode; - - /** - * The city of the shipping address. - */ - @JsonProperty(value = "AddressCity") - String addressCity; - - /** - * Shipping address street - */ - @JsonProperty(value = "AddressLine1") - String addressLine1; - - /** - * Additional shipping address information. - */ - @JsonProperty(value = "AddressLine2") - String addressLine2; - - /** - * The entire shipping address. - *

- * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: - *

    - *
  • {@link WithdrawRequestDataAttributes#getAddressCountry()}
  • - *
  • {@link WithdrawRequestDataAttributes#getAddressCity()}
  • - *
  • {@link WithdrawRequestDataAttributes#getAddressPostalCode()}
  • - *
  • {@link WithdrawRequestDataAttributes#getAddressLine1()}
  • - *
  • {@link WithdrawRequestDataAttributes#getAddressLine2()}
  • - *
- */ - @JsonProperty(value = "Address") - String address; - - /** - * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. The - * ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. - */ - @JsonProperty(value = "ExternalReference") - String externalReference; - - /** - * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - String pspMerchant; - - /** - * URL of the consumer-facing website where the order is initiated - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "PSPMerchantURL") - String pspMerchantUrl; - - /** - * VISA category codes describing the merchant's nature of business. - * - *

- * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master - * processing account. - *

- */ - @JsonProperty(value = "MerchantCategoryCode") - String merchantCategoryCode; - - /** - * Information about the Payer (ultimate debtor). - *

- * SenderInformation is mandatory for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for - * Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may - * also apply). - */ - @JsonProperty(value = "SenderInformation") - RecipientOrSenderInformation senderInformation; -} diff --git a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawResponseData.java b/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawResponseData.java deleted file mode 100644 index 59ebe7b..0000000 --- a/src/main/java/com/trustly/api/domain/methods/withdraw/WithdrawResponseData.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.trustly.api.domain.methods.withdraw; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractResponseResultData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class WithdrawResponseData extends AbstractResponseResultData { - - /** - * The globally unique OrderID the withdrawal was assigned in our system. - */ - @JsonProperty("orderid") - long orderId; - - /** - * The URL that should be loaded so that the end-user can complete the withdrawal. - */ - @JsonProperty("url") - String url; -} diff --git a/src/main/java/com/trustly/api/domain/notifications/AbstractCreditDebitPendingPayoutNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/AbstractCreditDebitPendingPayoutNotificationData.java deleted file mode 100644 index 595fead..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/AbstractCreditDebitPendingPayoutNotificationData.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractFromTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.EqualsAndHashCode; -import lombok.RequiredArgsConstructor; -import lombok.Value; -import lombok.experimental.NonFinal; -import lombok.experimental.SuperBuilder; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@NonFinal -@RequiredArgsConstructor -public class AbstractCreditDebitPendingPayoutNotificationData extends - AbstractFromTrustlyRequestData { - - @JsonProperty(value = "amount") - String amount; - - @JsonProperty(value = "currency") - String currency; - - @JsonProperty(value = "messageid") - String messageId; - - @JsonProperty(value = "orderid") - String orderId; - - @JsonProperty(value = "enduserid") - String endUserId; - - @JsonProperty(value = "notificationid") - String notificationId; - - @JsonProperty(value = "timestamp") - String timestamp; -} diff --git a/src/main/java/com/trustly/api/domain/notifications/AccountNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/AccountNotificationData.java deleted file mode 100644 index 6a9cd0e..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/AccountNotificationData.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.trustly.api.domain.base.AbstractFromTrustlyRequestData; -import com.trustly.api.domain.common.StringBooleanDeserializer; -import com.trustly.api.domain.common.StringBooleanSerializer; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class AccountNotificationData extends AbstractFromTrustlyRequestData { - - @JsonProperty("messageid") - String messageId; - - @JsonProperty("orderid") - String orderId; - - @JsonProperty("notificationid") - String notificationId; - - @JsonProperty("accountid") - String accountId; - - @JsonSerialize(using = StringBooleanSerializer.class) - @JsonDeserialize(using = StringBooleanDeserializer.class) - boolean verified; -} diff --git a/src/main/java/com/trustly/api/domain/notifications/AccountNotificationDataAttributes.java b/src/main/java/com/trustly/api/domain/notifications/AccountNotificationDataAttributes.java deleted file mode 100644 index 53fbb6a..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/AccountNotificationDataAttributes.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractRequestParamsDataAttributes; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class AccountNotificationDataAttributes extends AbstractRequestParamsDataAttributes { - - /** - * The clearinghouse for this account - */ - @JsonProperty("clearinghouse") - String clearinghouse; - - /** - * The bank for this account - */ - @JsonProperty("bank") - String bank; - - /** - * A text that is safe to show the enduser for identifying the account.Do not parse this text since it will be a different format for different accounts. - */ - @JsonProperty("descriptor") - String descriptor; - - /** - * The last digits of the bank account number.This can be used for matching against received KYC data from your manual routines. - */ - @JsonProperty("lastdigits") - String lastDigits; - - /** - * An ID that uniquely identifies the account holder.Note: The format of this field will for some countries look different than the example. - */ - @JsonProperty("personid") - String personId; - - /** - * The name of the account holder - */ - @JsonProperty("name") - String name; - - /** - * The address of the account holder - */ - @JsonProperty("address") - String address; - - /** - * The zipcode of the account holder - */ - @JsonProperty("zipcode") - String zipcode; - - /** - * The city of the account holder - */ - @JsonProperty("city") - String city; - - /** - * 1 if a direct debit mandate exists for this account, 0 otherwise - */ - @JsonProperty("directdebitmandate") - Integer directDebitMandate; -} diff --git a/src/main/java/com/trustly/api/domain/notifications/CancelNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/CancelNotificationData.java deleted file mode 100644 index d0a1bf0..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/CancelNotificationData.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.trustly.api.domain.base.AbstractFromTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class CancelNotificationData extends AbstractFromTrustlyRequestData { - - @JsonProperty("messageid") - String messageId; - - @JsonProperty("orderid") - String orderId; - - @JsonProperty("notificationid") - String notificationId; - - @JsonProperty("enduserid") - String endUserId; - - @JsonProperty("timestamp") - String timestamp; -} diff --git a/src/main/java/com/trustly/api/domain/notifications/CreditNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/CreditNotificationData.java deleted file mode 100644 index e17b4b4..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/CreditNotificationData.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.trustly.api.domain.notifications; - -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@Jacksonized -public class CreditNotificationData extends AbstractCreditDebitPendingPayoutNotificationData { - -} diff --git a/src/main/java/com/trustly/api/domain/notifications/DebitNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/DebitNotificationData.java deleted file mode 100644 index c7cfe69..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/DebitNotificationData.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.trustly.api.domain.notifications; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@Jacksonized -public class DebitNotificationData extends AbstractCreditDebitPendingPayoutNotificationData { - -} diff --git a/src/main/java/com/trustly/api/domain/notifications/PayoutConfirmationNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/PayoutConfirmationNotificationData.java deleted file mode 100644 index 461b97a..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/PayoutConfirmationNotificationData.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.trustly.api.client.TrustlyApiClient; -import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsRequestData; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -/** - * This is a notification that Trustly will send to the merchant's system in order to confirm that a payout has been sent. - *

- * This notification is not enabled by default. Please contact your Trustly integration manager in case you want to receive it. - * - *

- * Note: In many cases, the {@code payoutconfirmation} will be sent within minutes after the AccountPayout request has been received by - * Trustly. But in some cases there will be a delay of 1day or more,since Trustly relies on receiving statement files from banks. - *

- * If you have sent an AccountPayout request and haven’t received a {@code payoutconfirmation} within an hour or so, it does not necessarily - * mean that something is wrong. If you experience this and need to know the actual status of the payout, you can either use Trustly’s - * backoffice ({@code Transactions} > {@code Withdrawals}), or use the {@link TrustlyApiClient#getWithdrawals(GetWithdrawalsRequestData)} - * API method. - *

- * If you use the {@link TrustlyApiClient#getWithdrawals(GetWithdrawalsRequestData)} method and receive status {@code EXECUTING} or - * {@code EXECUTED}, it means that the withdrawal is currently being processed or has been processed, but is not confirmed yet. - *

- * The {@link TrustlyApiClient#getWithdrawals(GetWithdrawalsRequestData)} method must not be used more than once every 15 minutes per - * payout. - *

- * Please note that even if a {@code payoutconfirmation} has been sent,the payout can still fail afterwards. If that happens, Trustly will - * send a credit notification to the merchant’s {@code NotificationURL}. This can happen for example if the funds are sent to a bank account - * that is closed. - */ -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@Jacksonized -public class PayoutConfirmationNotificationData extends AbstractCreditDebitPendingPayoutNotificationData { - -} diff --git a/src/main/java/com/trustly/api/domain/notifications/PendingNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/PendingNotificationData.java deleted file mode 100644 index 69fb7e2..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/PendingNotificationData.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.trustly.api.domain.notifications; - -import lombok.EqualsAndHashCode; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@Jacksonized -public class PendingNotificationData extends AbstractCreditDebitPendingPayoutNotificationData { - -} diff --git a/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationData.java b/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationData.java deleted file mode 100644 index 4c74039..0000000 --- a/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationData.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.trustly.api.domain.notifications; - -import com.fasterxml.jackson.annotation.JsonAnyGetter; -import com.fasterxml.jackson.annotation.JsonAnySetter; -import com.trustly.api.domain.base.AbstractFromTrustlyRequestData; -import com.trustly.api.domain.base.EmptyRequestDataAttributes; -import java.util.HashMap; -import java.util.Map; -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Singular; -import lombok.Value; -import lombok.experimental.SuperBuilder; -import lombok.extern.jackson.Jacksonized; - -@Value -@SuperBuilder -@EqualsAndHashCode(callSuper = true) -@AllArgsConstructor -@Jacksonized -public class UnknownNotificationData extends AbstractFromTrustlyRequestData { - - @JsonAnySetter - @Singular("any") - Map any; - - @JsonAnyGetter - public Map getAny() { - return this.any; - } - - private UnknownNotificationData() { - this.any = new HashMap<>(); - } -} diff --git a/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java b/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java deleted file mode 100644 index ebfa3e7..0000000 --- a/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.trustly.api; - -import com.fasterxml.jackson.databind.JsonNode; -import com.trustly.api.client.JsonRpcSigner; -import com.trustly.api.domain.base.IRequest; -import com.trustly.api.domain.base.IRequestParams; -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.base.IResponseResultData; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.JsonRpcResponse; - -class NoOpJsonRpcSigner implements JsonRpcSigner { - - @Override - public JsonRpcRequest sign(JsonRpcRequest request) { - return request; - } - - @Override - public JsonRpcResponse sign(JsonRpcResponse response) { - return response; - } - - @Override - public > void verify(IRequest

request) { - - } - - @Override - public void verify(JsonRpcResponse response, JsonNode nodeResponse) { - - } -} diff --git a/src/test/java/com/trustly/api/NotificationsTest.java b/src/test/java/com/trustly/api/NotificationsTest.java deleted file mode 100644 index fcfe992..0000000 --- a/src/test/java/com/trustly/api/NotificationsTest.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.trustly.api; - -import com.trustly.api.client.TrustlyApiClient; -import com.trustly.api.client.TrustlyApiClientExtensions; -import com.trustly.api.client.TrustlyApiClientExtensions.NotificationResponder; -import com.trustly.api.client.TrustlyApiClientSettings; -import com.trustly.api.domain.base.IFromTrustlyRequestData; -import com.trustly.api.domain.notifications.AccountNotificationData; -import com.trustly.api.domain.notifications.CancelNotificationData; -import com.trustly.api.domain.notifications.CreditNotificationData; -import com.trustly.api.domain.notifications.DebitNotificationData; -import com.trustly.api.domain.notifications.PayoutConfirmationNotificationData; -import com.trustly.api.domain.notifications.PendingNotificationData; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Stream; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -class NotificationsTest { - - private final TrustlyApiClientSettings settings = TrustlyApiClientSettings.forTest() - .withCredentials("merchant_username", "merchant_password") - .withCertificatesFromStreams( - // We use the same certificates as those found at https://test.trustly.com/signaturetester/ - NotificationsTest.class.getResourceAsStream("/keys/merchant_public_key.pem"), - NotificationsTest.class.getResourceAsStream("/keys/merchant_private_key.pem") - ) - .andTrustlyCertificateFromStream( - // We pretend that Trustly is our own test certificate, so we can properly validate the signature. - NotificationsTest.class.getResourceAsStream("/keys/merchant_public_key.pem") - ); - - static Stream testNotificationsWithoutSignatureVerification() { - return Stream.of( - Arguments.of("account", AccountNotificationData.class), - Arguments.of("cancel", CancelNotificationData.class), - Arguments.of("credit", CreditNotificationData.class), - Arguments.of("debit", DebitNotificationData.class), - Arguments.of("payoutconfirmation", PayoutConfirmationNotificationData.class), - Arguments.of("pending", PendingNotificationData.class) - ); - } - - @ParameterizedTest - @MethodSource - void testNotificationsWithoutSignatureVerification(String method, Class dataType) throws Exception { - - try (TrustlyApiClient client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner())) { - - final AtomicInteger receivedNotificationDataCounter = new AtomicInteger(); - - client.addNotificationListener(method, dataType, args -> { - receivedNotificationDataCounter.incrementAndGet(); - args.respondWithOk(); - }); - - final InputStream is = this.getClass().getResourceAsStream(String.format("/notifications/incoming/%s.json", method)); - final Map headers = new HashMap<>(); - final AtomicInteger status = new AtomicInteger(); - final AtomicReference responseString = new AtomicReference<>(); - - final NotificationResponder responder = new NotificationResponder() { - @Override - public void addHeader(String key, String value) { - headers.put(key, value); - } - - @Override - public void setStatus(int httpStatus) { - status.set(httpStatus); - } - - @Override - public void writeBody(String value) { - responseString.set(value); - } - }; - - TrustlyApiClientExtensions.handleNotificationRequest(is, responder); - - Assertions.assertEquals(200, status.get()); - Assertions.assertNotNull(responseString.get()); - } - } - - @Test - void testUnknownNotification() throws Exception { - - try (TrustlyApiClient client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner())) { - - final AtomicReference receivedUnknownValue = new AtomicReference<>(); - - client.addOnUnknownNotification(args -> { - args.respondWithOk(); - receivedUnknownValue.set(args.getData().getAny().get("something")); - }); - - final InputStream is = this.getClass().getResourceAsStream("/notifications/incoming/_unknown.json"); - final Map headers = new HashMap<>(); - final AtomicInteger status = new AtomicInteger(); - final AtomicReference responseString = new AtomicReference<>(); - - final NotificationResponder responder = new NotificationResponder() { - @Override - public void addHeader(String key, String value) { - headers.put(key, value); - } - - @Override - public void setStatus(int httpStatus) { - status.set(httpStatus); - } - - @Override - public void writeBody(String value) { - responseString.set(value); - } - }; - - TrustlyApiClientExtensions.handleNotificationRequest(is, responder); - - Assertions.assertEquals(200, status.get()); - Assertions.assertEquals("application/json", headers.get("Content-Type")); - Assertions.assertNotNull(responseString.get()); - Assertions.assertEquals("abc", receivedUnknownValue.get()); - } - } - - @Test - void testCancelNotification() throws Exception { - - try (TrustlyApiClient client = new TrustlyApiClient(settings)) { - - final AtomicInteger receivedNotificationDataCounter = new AtomicInteger(); - - client.addOnCancelListener(args -> { - - receivedNotificationDataCounter.incrementAndGet(); - args.respondWithOk(); - }); - - final InputStream is = this.getClass().getResourceAsStream("/notifications/incoming/cancel.json"); - final Map headers = new HashMap<>(); - final AtomicInteger status = new AtomicInteger(); - final AtomicReference responseString = new AtomicReference<>(); - - final NotificationResponder responder = new NotificationResponder() { - @Override - public void addHeader(String key, String value) { - headers.put(key, value); - } - - @Override - public void setStatus(int httpStatus) { - status.set(httpStatus); - } - - @Override - public void writeBody(String value) { - responseString.set(value); - } - }; - - TrustlyApiClientExtensions.handleNotificationRequest(is, responder); - - Assertions.assertEquals(200, status.get()); - Assertions.assertNotNull(responseString.get()); - } - } - -} diff --git a/src/test/resources/notifications/incoming/cancel.json b/src/test/resources/notifications/incoming/cancel.json deleted file mode 100644 index ffa6f7d..0000000 --- a/src/test/resources/notifications/incoming/cancel.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "method": "cancel", - "params": { - "signature": "MWwF9r4AJ9uiI33qYwt/6xMnq5X7EM3DdxDpcbAh4jD7UQV4UUfAWW85+2ff+luWoN07P81x4WOVSi6GoLi2oK7fGXzy7alfIgN67TS1ixblKeuZHsAPZXR4CEqcRSD9IUKJDph2yblMakMAqeBtdUKrGzzFfyf0iHEeZFk6tO0wly0SfiyW4N0T8sp2AcEJPaAl+hdNSveKa6vBhr6mybnznDo0HeoMhyzR7NOKVEO1xLy3AM9XatwIdkmUO7DEEvqqcILNoBFuSpv6vkjxeKBcF80+tQ2RACYMnArMlJbRWVwdv3ZZfYTmvZ0iapVm2p+05HlajjawfXfGCaJsVQ==", - "uuid": "258a2184-9021-b874-21ca-293425152415", - "data": { - "messageid": "98348932", - "orderid": "87654567", - "enduserid": "32123", - "notificationid": "4876513450", - "timestamp": "2013-12-20 14:42:04.675645+01" - } - }, - "version": "1.1" -} diff --git a/trustly-java-client/pom.xml b/trustly-java-client/pom.xml new file mode 100644 index 0000000..b3bb282 --- /dev/null +++ b/trustly-java-client/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + + com.trustly.api + trustly-java + ${revision} + + + trustly-java-client + ${revision} + + + + + com.trustly.api + trustly-java-models + ${project.parent.version} + + + + com.trustly.api + trustly-java-util + ${project.parent.version} + + + + + + org.slf4j + slf4j-api + 2.0.6 + + + + + commons-httpclient + commons-httpclient + 3.1 + provided + + + org.apache.httpcomponents + httpclient + 4.5.14 + provided + + + org.apache.httpcomponents.client5 + httpclient5 + 5.2.1 + provided + + + + org.hibernate + hibernate-validator + 7.0.5.Final + provided + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + + jakarta.servlet + jakarta.servlet-api + 5.0.0 + provided + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + ${java.version} + ${java.version} + true + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.5.0 + + true + resolveCiFriendliesOnly + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + + + + + org.apache.maven.plugins + maven-release-plugin + ${maven.release.version} + + true + ProjectName-@{project.version} + + + + + + + diff --git a/trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcFactory.java b/trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcFactory.java new file mode 100644 index 0000000..aab5730 --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcFactory.java @@ -0,0 +1,22 @@ +package com.trustly.api.client; + +import static com.trustly.api.domain.Models.*; + +import java.util.Objects; +import java.util.UUID; + +public class JsonRpcFactory { + + public > JsonRpcRequest> create(TReqData requestData, String method, String uuid) { + + return JsonRpcRequest.>builder() + .method(method) + .params( + JsonRpcRequestParams.builder() + .uuid(Objects.requireNonNullElseGet(uuid, () -> UUID.randomUUID().toString())) + .data(requestData) + .build() + ) + .build(); + } +} diff --git a/src/main/java/com/trustly/api/client/JsonRpcValidator.java b/trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcValidator.java similarity index 95% rename from src/main/java/com/trustly/api/client/JsonRpcValidator.java rename to trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcValidator.java index e46d075..d82dded 100644 --- a/src/main/java/com/trustly/api/client/JsonRpcValidator.java +++ b/trustly-java-client/src/main/java/com/trustly/api/client/JsonRpcValidator.java @@ -1,6 +1,6 @@ package com.trustly.api.client; -import com.trustly.api.domain.exceptions.TrustlyValidationException; +import com.trustly.api.exceptions.TrustlyValidationException; import com.trustly.api.validation.AnnotationsValidator; import com.trustly.api.validation.AnnotationsValidatorLoader; import com.trustly.api.validation.HibernateDataAnnotationsValidatorLoader; diff --git a/trustly-java-client/src/main/java/com/trustly/api/client/NotificationArgs.java b/trustly-java-client/src/main/java/com/trustly/api/client/NotificationArgs.java new file mode 100644 index 0000000..80bfe4d --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/client/NotificationArgs.java @@ -0,0 +1,37 @@ +package com.trustly.api.client; + +import com.trustly.api.exceptions.TrustlyValidationException; +import jakarta.validation.Valid; +import java.io.IOException; + +public class NotificationArgs { + + @FunctionalInterface + public interface NotificationHandler { + void handle(String method, String uuid, TAckData result) throws IOException, TrustlyValidationException; + } + + @Valid + private final TCallbackData data; + + private final String method; + private final String uuid; + + private final NotificationHandler onOK; + + @Valid + public TCallbackData getData() { + return data; + } + + public NotificationArgs(TCallbackData data, String method, String uuid, NotificationHandler onOK) { + this.data = data; + this.method = method; + this.uuid = uuid; + this.onOK = onOK; + } + + public void respondWith(TAckData result) throws TrustlyValidationException, IOException { + this.onOK.handle(this.method, this.uuid, result); + } +} diff --git a/trustly-java-client/src/main/java/com/trustly/api/client/NotificationEvent.java b/trustly-java-client/src/main/java/com/trustly/api/client/NotificationEvent.java new file mode 100644 index 0000000..fca2cc1 --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/client/NotificationEvent.java @@ -0,0 +1,9 @@ +package com.trustly.api.client; + +import com.trustly.api.exceptions.TrustlyValidationException; +import java.io.IOException; + +@FunctionalInterface +public interface NotificationEvent { + void onNotification(NotificationArgs args) throws IOException, TrustlyValidationException; +} diff --git a/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClient.java b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClient.java new file mode 100644 index 0000000..bd588dd --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClient.java @@ -0,0 +1,587 @@ +package com.trustly.api.client; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.trustly.api.DefaultJsonRpcSigner; +import com.trustly.api.JsonRpcSigner; +import com.trustly.api.Serializer; +import com.trustly.api.TrustlyApiClientSettings; +import com.trustly.api.client.NotificationArgs.NotificationHandler; +import com.trustly.api.domain.Models; +import com.trustly.api.domain.notifications.UnknownNotification; +import com.trustly.api.domain.notifications.UnknownNotificationAckData; +import com.trustly.api.domain.notifications.UnknownNotificationResponse; +import com.trustly.api.exceptions.TrustlyErrorResponseException; +import com.trustly.api.exceptions.TrustlyNoNotificationListenerException; +import com.trustly.api.exceptions.TrustlyRejectionException; +import com.trustly.api.exceptions.TrustlyRequestException; +import com.trustly.api.exceptions.TrustlySignatureException; +import com.trustly.api.exceptions.TrustlyValidationException; +import com.trustly.api.request.ApacheHttpClient3HttpRequesterLoader; +import com.trustly.api.request.ApacheHttpClient4HttpRequesterLoader; +import com.trustly.api.request.ApacheHttpClient5HttpRequesterLoader; +import com.trustly.api.request.HttpRequester; +import com.trustly.api.request.HttpRequesterLoader; +import com.trustly.api.request.JavaUrlConnectionHttpRequesterLoader; +import com.trustly.api.util.TrustlyStringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; + +import static com.trustly.api.domain.Models.*; + +public class TrustlyApiClient implements Closeable { + + private static final Logger log = LoggerFactory.getLogger(TrustlyApiClient.class); + + private static final HttpRequesterLoader[] AVAILABLE_HTTP_REQUESTERS = new HttpRequesterLoader[]{ + new ApacheHttpClient5HttpRequesterLoader(), + new ApacheHttpClient4HttpRequesterLoader(), + new ApacheHttpClient3HttpRequesterLoader(), + new JavaUrlConnectionHttpRequesterLoader() + }; + + private static HttpRequester getFirstAvailableHttpRequester() { + + HttpRequester foundHttpRequester = null; + for (HttpRequesterLoader loader : AVAILABLE_HTTP_REQUESTERS) { + + foundHttpRequester = loader.create(); + if (foundHttpRequester != null) { + break; + } + } + + if (foundHttpRequester == null) { + throw new IllegalStateException("Could not find a suitable http requester factory"); + } + + return foundHttpRequester; + } + + private static class NotificationMeta< + TCallback extends JsonRpcNotification>, + TCallbackData, + + TAckData extends Models.NotificationResponseDataBase, + TAckStatus + > { + + private final Class clazz; + private final List> listeners = new ArrayList<>(); + + public Class getClazz() { + return clazz; + } + + public List> getListeners() { + return listeners; + } + + public NotificationMeta(Class dataClass) { + this.clazz = dataClass; + } + } + + private final TrustlyApiClientSettings settings; + + private final ObjectMapper objectMapper = TrustlyApiClientSettings.DEFAULT_OBJECT_MAPPER; + private final JsonRpcFactory objectFactory = new JsonRpcFactory(); + private final JsonRpcSigner signer; + private final JsonRpcValidator validator = new JsonRpcValidator(); + private final HttpRequester httpRequester; + + private final Map> onNotification = new HashMap<>(); + + public TrustlyApiClientSettings getSettings() { + return settings; + } + + public TrustlyApiClient(TrustlyApiClientSettings settings) { + this(settings, new DefaultJsonRpcSigner(new Serializer(), settings), TrustlyApiClient.getFirstAvailableHttpRequester()); + } + + public TrustlyApiClient(TrustlyApiClientSettings settings, JsonRpcSigner signer) { + this(settings, signer, TrustlyApiClient.getFirstAvailableHttpRequester()); + } + + public TrustlyApiClient(TrustlyApiClientSettings settings, HttpRequester httpRequester) { + this(settings, new DefaultJsonRpcSigner(new Serializer(), settings), httpRequester); + } + + public TrustlyApiClient(TrustlyApiClientSettings settings, JsonRpcSigner signer, HttpRequester httpRequester) { + this.settings = settings; + this.signer = signer; + this.httpRequester = httpRequester; + } + + @Override + public void close() { + + } + + + // Methods + + public List accountLedger(AccountLedgerRequestData data) throws TrustlyRequestException { + return this.sendRequest(new AccountLedgerRequest(), data, AccountLedgerResponse.class); + } + + public AccountPayoutResponseData accountPayout(AccountPayoutRequestData data) throws TrustlyRequestException { + return this.sendRequest(new AccountPayoutRequest(), data, AccountPayoutResponse.class); + } + + public ApproveWithdrawalResponseData approveWithdrawal(ApproveWithdrawalRequestData data) throws TrustlyRequestException { + return this.sendRequest(new ApproveWithdrawalRequest(), data, ApproveWithdrawalResponse.class); + } + + /** + * This method returns the current balance for all currencies available on the merchant's Trustly account. + *

+ * 🚧 Please do not use this method more than once every 15 minutes. + */ + public List balance(BalanceRequestData data) throws TrustlyRequestException { + return this.sendRequest(new BalanceRequest(), data, BalanceResponse.class); + } + + public CancelChargeResponseData cancelCharge(CancelChargeRequestData data) throws TrustlyRequestException { + return this.sendRequest(new CancelChargeRequest(), data, CancelChargeResponse.class); + } + + public ChargeResponseData charge(ChargeRequestData data) throws TrustlyRequestException { + return this.sendRequest(new ChargeRequest(), data, ChargeResponse.class); + } + + public DenyWithdrawalResponseData denyWithdrawal(DenyWithdrawalRequestData data) throws TrustlyRequestException { + return this.sendRequest(new DenyWithdrawalRequest(), data, DenyWithdrawalResponse.class); + } + + public DepositResponseData deposit(DepositRequestData data) throws TrustlyRequestException { + return this.sendRequest(new DepositRequest(), data, DepositResponse.class); + } + + public List getWithdrawals(GetWithdrawalsRequestData data) throws TrustlyRequestException { + return this.sendRequest(new GetWithdrawalsRequest(), data, GetWithdrawalsResponse.class); + } + + public RefundResponseData refund(RefundRequestData data) throws TrustlyRequestException { + return this.sendRequest(new RefundRequest(), data, RefundResponse.class); + } + + public CreateAccountResponseData createAccount(CreateAccountRequestData data) throws TrustlyRequestException { + return this.sendRequest(new CreateAccountRequest(), data, CreateAccountResponse.class); + } + + public SelectAccountResponseData selectAccount(SelectAccountRequestData data) throws TrustlyRequestException { + return this.sendRequest(new SelectAccountRequest(), data, SelectAccountResponse.class); + } + + public RegisterAccountResponseData registerAccount(RegisterAccountRequestData data) throws TrustlyRequestException { + return this.sendRequest(new RegisterAccountRequest(), data, RegisterAccountResponse.class); + } + + public RegisterAccountPayoutResponseData registerAccountPayout(RegisterAccountPayoutRequestData data) throws TrustlyRequestException { + return this.sendRequest(new RegisterAccountPayoutRequest(), data, RegisterAccountPayoutResponse.class); + } + + public MerchantSettlementResponseData merchantSettlement(MerchantSettlementRequestData data) throws TrustlyRequestException { + return this.sendRequest(new MerchantSettlementRequest(), data, MerchantSettlementResponse.class); + } + + public SettlementReportResponseData settlementReport(SettlementReportRequestData data) throws TrustlyRequestException { + return this.sendRequest(new SettlementReportRequest(), data, SettlementReportResponse.class); + } + + public WithdrawResponseData withdraw(WithdrawRequestData data) throws TrustlyRequestException { + return this.sendRequest(new WithdrawRequest(), data, WithdrawResponse.class); + } + + public DirectDebitMandateResponseData directDebitMandate(DirectDebitMandateRequestData data) throws TrustlyRequestException { + return this.sendRequest(new DirectDebitMandateRequest(), data, DirectDebitMandateResponse.class); + } + + public CancelDirectDebitMandateResponseData cancelDirectDebitMandate(CancelDirectDebitMandateRequestData data) throws TrustlyRequestException { + return this.sendRequest(new CancelDirectDebitMandateRequest(), data, CancelDirectDebitMandateResponse.class); + } + + public ImportDirectDebitMandateResponseData cancelDirectDebitMandate(ImportDirectDebitMandateRequestData data) throws TrustlyRequestException { + return this.sendRequest(new ImportDirectDebitMandateRequest(), data, ImportDirectDebitMandateResponse.class); + } + + public DirectDebitResponseData cancelDirectDebitMandate(CancelDirectDebitRequestData data) throws TrustlyRequestException { + return this.sendRequest(new CancelDirectDebitRequest(), data, DirectDebitResponse.class); + } + + public CancelDirectDebitResponseData cancelDirectDebit(CancelDirectDebitRequestData data) throws TrustlyRequestException { + return this.sendRequest(new CancelDirectDebitRequest(), data, CancelDirectDebitResponse.class); + } + + public DirectCreditResponseData directCredit(DirectCreditRequestData data) throws TrustlyRequestException { + return this.sendRequest(new DirectCreditRequest(), data, DirectCreditResponse.class); + } + + public RefundDirectDebitResponseData directCredit(RefundDirectDebitRequestData data) throws TrustlyRequestException { + return this.sendRequest(new RefundDirectDebitRequest(), data, RefundDirectDebitResponse.class); + } + + public DirectPaymentBatchResponseData directCredit(DirectPaymentBatchRequestData data) throws TrustlyRequestException { + return this.sendRequest(new DirectPaymentBatchRequest(), data, DirectPaymentBatchResponse.class); + } + + // Notifications + + /** + * Convenience method for adding a listener where the `TAckData` can be inferred from the given listener. + */ + public < + TCallbackData, + TCallback extends JsonRpcNotification>, + TAckData extends Models.NotificationResponseDataBase, + TAckStatus + > void addNotificationListener(String method, Class notificationClass, NotificationEvent listener) { + this.addNotificationListener(method, notificationClass, null, listener); + } + + /** + * Add a custom listener for a certain notification type. + *

+ * This method should only be used if there is no existing {@code addOnXyzListener} method for the notification you want. + */ + public < + TCallbackData, + TCallback extends JsonRpcNotification>, + TAck extends Models.JsonRpcResponse, + TAckRes extends Models.ResponseResult, + TAckData extends Models.NotificationResponseDataBase, + TAckStatus + > void addNotificationListener( + String method, + Class notificationClass, + Class ackClass, + NotificationEvent listener + ) { + + var meta = (NotificationMeta) this.onNotification.computeIfAbsent(method, k -> new NotificationMeta<>(notificationClass)); + if (!meta.getClazz().equals(notificationClass)) { + throw new IllegalArgumentException( + String.format("Each notification method must be registered with the same type (%s vs %s)", notificationClass, meta.getClazz())); + } + + meta.getListeners().add(listener); + } + + public void addOnAccountListener(NotificationEvent listener) { + this.addNotificationListener("account", AccountNotification.class, listener); + } + + public void addOnCancelListener(NotificationEvent listener) { + this.addNotificationListener("cancel", CancelNotification.class, listener); + } + + public void addOnCreditListener(NotificationEvent listener) { + this.addNotificationListener("credit", CreditNotification.class, listener); + } + + public void addOnDebitListener(NotificationEvent listener) { + this.addNotificationListener("debit", DebitNotification.class, listener); + } + + public void addOnPayoutConfirmation(NotificationEvent listener) { + this.addNotificationListener("payoutconfirmation", PayoutConfirmationNotification.class, listener); + } + + public void addOnPending(NotificationEvent listener) { + this.addNotificationListener("pending", PendingNotification.class, listener); + } + + public void addOnKYC(NotificationEvent listener) { + this.addNotificationListener("kyc", KYCNotification.class, listener); + } + + public void addOnUnknownNotification(NotificationEvent listener) { + this.addNotificationListener("", UnknownNotification.class, listener); + } + + // Base functionality + + /** + * Used internally to create a response package. + * + * @param method The method of the JsonRpc package + * @param uuid The UUID for the message, if null one will be generated for you + * @param responseData The response data that was received remotely + * @param The type of the response data + * @return A signed and validated JsonRpc response package + * @throws TrustlyValidationException Thrown if the response does not pass proper validations + */ + public JsonRpcResponse> createResponsePackage( + String method, + String uuid, + D responseData + ) throws TrustlyValidationException { + + var rpcResponse = JsonRpcResponse.>builder() + .result( + ResponseResult.builder() + .data(responseData) + .method(method) + .UUID(uuid) + .build() + ) + .build(); + + rpcResponse.getResult().setSignature(this.signer.sign( + rpcResponse.getResult().getData(), + rpcResponse.getResult().getMethod(), + rpcResponse.getResult().getUUID() + )); + + this.validator.validate(rpcResponse); + + return rpcResponse; + } + + public < + TReqData extends AbstractRequestData, + TReqAttributes extends AbstractRequestDataAttributes, + TReqParams extends JsonRpcRequestParams, + TReq extends JsonRpcRequest, + TResData, + TResResult extends ResponseResult, + TRes extends JsonRpcResponse + > + TResData sendRequest( + TReq rpcRequest, + Class resClass + ) throws TrustlyRequestException { + + Objects.requireNonNull(rpcRequest, "The request must not be null"); + Objects.requireNonNull(rpcRequest.getParams(), "If giving just the request, you have to set the params yourself"); + Objects.requireNonNull(rpcRequest.getParams().getData(), "If giving just the request, you have to set the data yourself"); + + return this.sendRequest(rpcRequest, rpcRequest.getParams().getData(), resClass); + } + + public < + TReqData extends AbstractRequestData, + TReqAttributes extends AbstractRequestDataAttributes, + TResData, + TResResult extends ResponseResult, + TRes extends JsonRpcResponse + > + TResData sendRequest( + TReqData data, + Class resClass, + String method, + String uuid + ) throws TrustlyRequestException { + + final var rpcRequest = this.objectFactory.create(data, method, uuid); + return this.sendRequest(rpcRequest, rpcRequest.getParams().getData(), resClass); + } + + /** + * Manually send a request to Trustly with the specified data and method and uuid. + *

+ * Should only be used if you need to call an undocumented/newly released method that is not yet added to this library. + */ + public < + TReqData extends AbstractRequestData, + TReqAttributes extends AbstractRequestDataAttributes, + TReqParams extends JsonRpcRequestParams, + TReq extends JsonRpcRequest, + TResData, + TResResult extends ResponseResult, + TRes extends JsonRpcResponse + > + TResData sendRequest( + TReq rpcRequest, + TReqData requestData, + Class resClass + ) throws TrustlyRequestException { + + if (rpcRequest.getParams() == null) { + rpcRequest.setParams((TReqParams) new JsonRpcRequestParams()); + } + + if (rpcRequest.getParams().getData() == null) { + rpcRequest.getParams().setData(requestData); + } + + if (TrustlyStringUtils.isBlank(rpcRequest.getParams().getUuid())) { + rpcRequest.getParams().setUuid(UUID.randomUUID().toString()); + } + + requestData = rpcRequest.getParams().getData(); + if (TrustlyStringUtils.isBlank(requestData.getUsername())) { + requestData.setUsername(this.settings.getUsername()); + requestData.setPassword(this.settings.getPassword()); + } + + rpcRequest.getParams().setSignature(this.signer.sign(requestData, rpcRequest.getMethod(), rpcRequest.getParams().getUuid())); + + try { + this.validator.validate(rpcRequest); + } catch (TrustlyValidationException ex) { + throw new TrustlyRequestException(ex); + } + + try { + var requestString = this.objectMapper.writeValueAsString(rpcRequest); + var responseString = this.httpRequester.request(this.settings, requestString); + + var rpcNodeResponse = this.objectMapper.readTree(responseString); + + if (rpcNodeResponse.has("error") || !rpcNodeResponse.has("result")) { + + var rpcErrorResponse = this.objectMapper.convertValue(rpcNodeResponse, JsonRpcErrorResponse.class); + + String message = null; + if (rpcErrorResponse.getError() != null) { + message = rpcErrorResponse.getError().getMessage(); + if (TrustlyStringUtils.isBlank(message)) { + message = rpcErrorResponse.getError().getName(); + if (TrustlyStringUtils.isBlank(message)) { + message = ("" + rpcErrorResponse.getError().getCode()); + } + } + } + + throw new TrustlyErrorResponseException(String.format("Received an error response from the Trustly API: %s", message), null, + rpcErrorResponse.getError() + ); + } + + TRes rpcResponse = this.objectMapper.convertValue(rpcNodeResponse, resClass); + + assertWithoutRejection(rpcResponse); + + this.signer.verify( + rpcResponse.getResult().getMethod(), + rpcResponse.getResult().getUUID(), + rpcNodeResponse.path("result").path("data"), + rpcResponse.getResult().getSignature() + ); + + final var responseResult = rpcResponse.getResult(); + final var requestParams = rpcRequest.getParams(); + + if (!Objects.equals(responseResult.getUUID(), requestParams.getUuid())) { + throw new TrustlyValidationException( + String.format("Incoming UUID is not valid. Expected %s but got back %s", rpcRequest.getParams().getUuid(), rpcResponse.getResult().getUUID()) + ); + } + + return rpcResponse.getResult().getData(); + } catch (Exception ex) { + throw new TrustlyRequestException(ex); + } + } + + private static > void assertWithoutRejection(JsonRpcResponse rpcResponse) + throws TrustlyRejectionException { + + if (rpcResponse.getResult().getData() instanceof WithRejection) { + WithRejection rejectionResult = (WithRejection) rpcResponse.getResult().getData(); + + if (rejectionResult.getRejected() != null) { + + String message = Objects.toString(rejectionResult.getRejected()); + if (TrustlyStringUtils.isBlank(message)) { + message = "The request was rejected for an unknown reason"; + } + + throw new TrustlyRejectionException( + "Received a rejection response from the Trustly API: " + message, + rejectionResult.getRejected() + ); + } + } + } + + public < + TAckData extends NotificationResponseDataBase, + TAckStatus + > + void handleNotification( + String jsonString, + NotificationHandler handler + ) throws IOException, TrustlyNoNotificationListenerException, TrustlyValidationException, TrustlySignatureException { + + var jsonToken = this.objectMapper.readTree(jsonString); + var methodValue = jsonToken.path("method").asText().toLowerCase(Locale.ROOT); + + // Should be typesafe enough, unless user has registered a listener very incorrectly. + var mapper = (NotificationMeta) this.onNotification.get(methodValue); + + if (mapper == null || mapper.getListeners().isEmpty()) { + log.warn("There is no listener for incoming notification '{}'. Will fallback on 'unknown' listener", methodValue); + mapper = this.onNotification.get(""); + if (mapper == null || mapper.getListeners().isEmpty()) { + throw new TrustlyNoNotificationListenerException(String.format("There is no listener for incoming notification '%s' nor unknown", methodValue)); + } + } + + this.handleNotification(jsonString, mapper, handler); + } + + private < + TCallback extends JsonRpcNotification>, + TCallbackData, + + TMeta extends NotificationMeta, + THandler extends NotificationHandler, + + TAckData extends NotificationResponseDataBase, + TAckStatus + > + void handleNotification( + String jsonString, + TMeta meta, + THandler handler + ) throws IOException, TrustlyValidationException, TrustlySignatureException { + + var requestNode = this.objectMapper.readTree(jsonString); + + // Verify the notification (RpcRequest from Trustly) signature. + try { + this.signer.verify( + requestNode.path("method").asText(), + requestNode.path("params").path("uuid").asText(), + requestNode.path("params").path("data"), + requestNode.path("params").path("signature").asText() + ); + } catch (TrustlySignatureException ex) { + throw new TrustlySignatureException( + "Could not validate signature of notification from Trustly. Is the public key for Trustly the correct one, for test or production?", + ex + ); + } + + var notificationRequest = this.objectMapper.treeToValue(requestNode, meta.getClazz()); + + // Validate the incoming request instance. + // Most likely this will do nothing, since we are lenient on things sent from Trustly server. + // But we do this in case anything is needed to be validated on the local domain classes in the future. + this.validator.validate(notificationRequest); + + var args = new NotificationArgs<>( + notificationRequest.getParams().getData(), + notificationRequest.getMethod(), + notificationRequest.getParams().getUUID(), + handler + ); + + for (var listener : meta.getListeners()) { + listener.onNotification(args); + } + } +} diff --git a/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java new file mode 100644 index 0000000..c8a40de --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientExtensions.java @@ -0,0 +1,105 @@ +package com.trustly.api.client; + +import com.trustly.api.TrustlyApiClientSettings; +import com.trustly.api.exceptions.TrustlyNoNotificationClientException; +import com.trustly.api.exceptions.TrustlyValidationException; +import com.trustly.api.util.TrustlyStreamUtils; +import com.trustly.api.util.TrustlyStringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.trustly.api.domain.Models.NotificationResponseDataBase; + +public class TrustlyApiClientExtensions { + + private static final Logger log = LoggerFactory.getLogger(TrustlyApiClientExtensions.class); + + public static final String GENERIC_ERROR_MESSAGE = "An exception occurred (error message given by trustly-api-client for Java)"; + + public interface NotificationResponder { + + default void addHeader(String key, String value) { + } + + void setStatus(int httpStatus); + + void writeBody(String value) throws IOException; + } + + public static void handleNotificationRequest(TrustlyApiClient client, InputStream incoming, NotificationResponder responder) + throws IOException, + TrustlyNoNotificationClientException { + + String requestStringBody; + try (var sr = new InputStreamReader(incoming, StandardCharsets.UTF_8)) { + requestStringBody = TrustlyStreamUtils.readerToString(sr); + } + + final var responseCount = new AtomicInteger(0); + try { + client.handleNotification( + requestStringBody, + (method, uuid, result) -> { + responseCount.incrementAndGet(); + TrustlyApiClientExtensions.respond(client, responder, method, uuid, result, null, 200); + } + ); + } catch (Exception ex) { + + log.error("Encountered an error trying to handle notification '" + requestStringBody + "'", ex); + + var assemblyVersion = TrustlyApiClientExtensions.class.getPackage().getImplementationVersion(); + + responder.addHeader("Content-Type", "application/json"); + responder.addHeader("Accept", "application/json"); + responder.addHeader("User-Agent", "trustly-api-client-java/" + assemblyVersion); + responder.setStatus(500); + + if (client.getSettings().isIncludeExceptionMessageInNotificationResponse()) { + responder.writeBody(ex.getMessage()); + } else { + responder.writeBody(GENERIC_ERROR_MESSAGE); + } + } + + if (responseCount.get() == 0) { + throw new TrustlyNoNotificationClientException( + "None of your client's event listeners responded with OK or FAILED. That must be done."); + } + } + + public static > void respond( + TrustlyApiClient client, + NotificationResponder responder, + String method, + String uuid, + D status, + String message, + int httpStatusCode + ) throws IOException, TrustlyValidationException { + + var rpcResponse = client.createResponsePackage(method, uuid, status); + + if (client.getSettings().isIncludeMessageInNotificationResponse() && !TrustlyStringUtils.isBlank(message)) { + rpcResponse.getResult().getData().setMessage(message); + } + + var rpcString = TrustlyApiClientSettings.DEFAULT_OBJECT_MAPPER.writeValueAsString(rpcResponse); + var assemblyVersion = TrustlyApiClientExtensions.class.getPackage().getImplementationVersion(); + if (assemblyVersion == null) { + assemblyVersion = "v1"; + } + + responder.addHeader("Content-Type", "application/json"); + responder.addHeader("Accept", "application/json"); + responder.addHeader("User-Agent", "trustly-api-client-java/" + assemblyVersion); + responder.setStatus(httpStatusCode); + responder.writeBody(rpcString); + } +} diff --git a/src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java similarity index 82% rename from src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java rename to trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java index 699be0d..68431bd 100644 --- a/src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java +++ b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJakartaExtensions.java @@ -1,9 +1,9 @@ package com.trustly.api.client; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationClientException; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationListenerException; -import com.trustly.api.domain.exceptions.TrustlySignatureException; -import com.trustly.api.domain.exceptions.TrustlyValidationException; +import com.trustly.api.exceptions.TrustlyNoNotificationClientException; +import com.trustly.api.exceptions.TrustlyNoNotificationListenerException; +import com.trustly.api.exceptions.TrustlySignatureException; +import com.trustly.api.exceptions.TrustlyValidationException; import java.io.IOException; import java.io.InputStream; @@ -55,6 +55,7 @@ public void writeBody(String value) throws IOException { * @throws TrustlySignatureException If the signature of the response could not be properly verified. */ public static void handleNotificationRequest( + TrustlyApiClient client, jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response ) throws @@ -64,10 +65,11 @@ public static void handleNotificationRequest( TrustlyValidationException, TrustlySignatureException { - TrustlyApiClientExtensions.handleNotificationRequest(request.getInputStream(), new JakartaNotificationResponder(response)); + TrustlyApiClientExtensions.handleNotificationRequest(client, request.getInputStream(), new JakartaNotificationResponder(response)); } public static void handleNotificationRequest( + TrustlyApiClient client, InputStream incoming, jakarta.servlet.http.HttpServletResponse response ) throws @@ -77,6 +79,6 @@ public static void handleNotificationRequest( TrustlyValidationException, TrustlySignatureException { - TrustlyApiClientExtensions.handleNotificationRequest(incoming, new JakartaNotificationResponder(response)); + TrustlyApiClientExtensions.handleNotificationRequest(client, incoming, new JakartaNotificationResponder(response)); } } diff --git a/src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java similarity index 82% rename from src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java rename to trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java index 3a42da5..2aad6bf 100644 --- a/src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java +++ b/trustly-java-client/src/main/java/com/trustly/api/client/TrustlyApiClientJavaxExtensions.java @@ -1,9 +1,9 @@ package com.trustly.api.client; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationClientException; -import com.trustly.api.domain.exceptions.TrustlyNoNotificationListenerException; -import com.trustly.api.domain.exceptions.TrustlySignatureException; -import com.trustly.api.domain.exceptions.TrustlyValidationException; +import com.trustly.api.exceptions.TrustlyNoNotificationClientException; +import com.trustly.api.exceptions.TrustlyNoNotificationListenerException; +import com.trustly.api.exceptions.TrustlySignatureException; +import com.trustly.api.exceptions.TrustlyValidationException; import java.io.IOException; import java.io.InputStream; @@ -55,6 +55,7 @@ public void writeBody(String value) throws IOException { * @throws TrustlySignatureException If the signature of the response could not be properly verified. */ public static void handleNotificationRequest( + TrustlyApiClient client, javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response ) throws @@ -64,10 +65,11 @@ public static void handleNotificationRequest( TrustlyValidationException, TrustlySignatureException { - TrustlyApiClientExtensions.handleNotificationRequest(request.getInputStream(), new JavaxNotificationResponder(response)); + TrustlyApiClientExtensions.handleNotificationRequest(client, request.getInputStream(), new JavaxNotificationResponder(response)); } public static void handleNotificationRequest( + TrustlyApiClient client, InputStream incoming, javax.servlet.http.HttpServletResponse response ) throws @@ -77,6 +79,6 @@ public static void handleNotificationRequest( TrustlyValidationException, TrustlySignatureException { - TrustlyApiClientExtensions.handleNotificationRequest(incoming, new JavaxNotificationResponder(response)); + TrustlyApiClientExtensions.handleNotificationRequest(client, incoming, new JavaxNotificationResponder(response)); } } diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyErrorResponseException.java b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyErrorResponseException.java similarity index 54% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlyErrorResponseException.java rename to trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyErrorResponseException.java index c136275..d68a1c3 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyErrorResponseException.java +++ b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyErrorResponseException.java @@ -1,17 +1,17 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; -import com.trustly.api.domain.base.ResponseError; +import static com.trustly.api.domain.Models.*; public class TrustlyErrorResponseException extends AbstractTrustlyApiException { - private final transient ResponseError responseError; + private final transient JsonRpcError responseError; - public TrustlyErrorResponseException(String message, Exception cause, ResponseError responseError) { + public TrustlyErrorResponseException(String message, Exception cause, JsonRpcError responseError) { super(message + " - " + responseError, cause); this.responseError = responseError; } - public ResponseError getResponseError() { + public JsonRpcError getResponseError() { return responseError; } } diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationClientException.java b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationClientException.java similarity index 87% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationClientException.java rename to trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationClientException.java index ee9ff76..4aa91b6 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationClientException.java +++ b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationClientException.java @@ -1,4 +1,4 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; public class TrustlyNoNotificationClientException extends AbstractTrustlyApiException { diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationListenerException.java b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationListenerException.java similarity index 53% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationListenerException.java rename to trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationListenerException.java index deeb959..6db130b 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyNoNotificationListenerException.java +++ b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyNoNotificationListenerException.java @@ -1,12 +1,8 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; public class TrustlyNoNotificationListenerException extends AbstractTrustlyApiException { public TrustlyNoNotificationListenerException(String message) { super(message); } - - public TrustlyNoNotificationListenerException(String message, Exception cause) { - super(message, cause); - } } diff --git a/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRejectionException.java b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRejectionException.java new file mode 100644 index 0000000..4f756c1 --- /dev/null +++ b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRejectionException.java @@ -0,0 +1,15 @@ +package com.trustly.api.exceptions; + +public class TrustlyRejectionException extends AbstractTrustlyApiException { + + private final Object reason; + + public TrustlyRejectionException(String message, Object reason) { + super(message); + this.reason = reason; + } + + public Object getReason() { + return reason; + } +} diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyRequestException.java b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRequestException.java similarity index 85% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlyRequestException.java rename to trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRequestException.java index a7f145f..77a5a80 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyRequestException.java +++ b/trustly-java-client/src/main/java/com/trustly/api/exceptions/TrustlyRequestException.java @@ -1,4 +1,4 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; /** * Wrapping exception for general error situations. Check the actual exception using {@link Exception#getCause()}. diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java similarity index 96% rename from src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java index 2d7b86b..6e84c31 100644 --- a/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java +++ b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequester.java @@ -1,6 +1,6 @@ package com.trustly.api.request; -import com.trustly.api.client.TrustlyApiClientSettings; +import com.trustly.api.TrustlyApiClientSettings; import com.trustly.api.util.TrustlyStreamUtils; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequesterLoader.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequesterLoader.java similarity index 100% rename from src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequesterLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient3HttpRequesterLoader.java diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java similarity index 95% rename from src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java index 92f27f1..f91e1f8 100644 --- a/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java +++ b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequester.java @@ -1,6 +1,6 @@ package com.trustly.api.request; -import com.trustly.api.client.TrustlyApiClientSettings; +import com.trustly.api.TrustlyApiClientSettings; import java.io.IOException; import java.nio.charset.StandardCharsets; import org.apache.http.HttpEntity; diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequesterLoader.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequesterLoader.java similarity index 100% rename from src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequesterLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient4HttpRequesterLoader.java diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java similarity index 94% rename from src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java index 7e6aacf..0010907 100644 --- a/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java +++ b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequester.java @@ -1,6 +1,6 @@ package com.trustly.api.request; -import com.trustly.api.client.TrustlyApiClientSettings; +import com.trustly.api.TrustlyApiClientSettings; import java.io.IOException; import org.apache.hc.client5.http.classic.HttpClient; import org.apache.hc.client5.http.classic.methods.HttpPost; diff --git a/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequesterLoader.java b/trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequesterLoader.java similarity index 100% rename from src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequesterLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/request/ApacheHttpClient5HttpRequesterLoader.java diff --git a/src/main/java/com/trustly/api/request/HttpRequester.java b/trustly-java-client/src/main/java/com/trustly/api/request/HttpRequester.java similarity index 76% rename from src/main/java/com/trustly/api/request/HttpRequester.java rename to trustly-java-client/src/main/java/com/trustly/api/request/HttpRequester.java index d3b5d8b..84d8524 100644 --- a/src/main/java/com/trustly/api/request/HttpRequester.java +++ b/trustly-java-client/src/main/java/com/trustly/api/request/HttpRequester.java @@ -1,6 +1,6 @@ package com.trustly.api.request; -import com.trustly.api.client.TrustlyApiClientSettings; +import com.trustly.api.TrustlyApiClientSettings; import java.io.IOException; public interface HttpRequester { diff --git a/src/main/java/com/trustly/api/request/HttpRequesterLoader.java b/trustly-java-client/src/main/java/com/trustly/api/request/HttpRequesterLoader.java similarity index 100% rename from src/main/java/com/trustly/api/request/HttpRequesterLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/request/HttpRequesterLoader.java diff --git a/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java b/trustly-java-client/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java similarity index 96% rename from src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java rename to trustly-java-client/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java index 7773ef6..8aa90ae 100644 --- a/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java +++ b/trustly-java-client/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequester.java @@ -1,6 +1,6 @@ package com.trustly.api.request; -import com.trustly.api.client.TrustlyApiClientSettings; +import com.trustly.api.TrustlyApiClientSettings; import com.trustly.api.util.TrustlyStreamUtils; import java.io.IOException; import java.io.InputStreamReader; diff --git a/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequesterLoader.java b/trustly-java-client/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequesterLoader.java similarity index 100% rename from src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequesterLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/request/JavaUrlConnectionHttpRequesterLoader.java diff --git a/src/main/java/com/trustly/api/validation/AnnotationsValidator.java b/trustly-java-client/src/main/java/com/trustly/api/validation/AnnotationsValidator.java similarity index 100% rename from src/main/java/com/trustly/api/validation/AnnotationsValidator.java rename to trustly-java-client/src/main/java/com/trustly/api/validation/AnnotationsValidator.java diff --git a/src/main/java/com/trustly/api/validation/AnnotationsValidatorLoader.java b/trustly-java-client/src/main/java/com/trustly/api/validation/AnnotationsValidatorLoader.java similarity index 100% rename from src/main/java/com/trustly/api/validation/AnnotationsValidatorLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/validation/AnnotationsValidatorLoader.java diff --git a/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java b/trustly-java-client/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java similarity index 85% rename from src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java rename to trustly-java-client/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java index 83e2b1a..261a023 100644 --- a/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java +++ b/trustly-java-client/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidator.java @@ -1,6 +1,5 @@ package com.trustly.api.validation; -import jakarta.validation.ConstraintViolation; import jakarta.validation.Validation; import jakarta.validation.Validator; import java.util.ArrayList; @@ -28,8 +27,10 @@ public List validate(T obj) { } List errorMessages = new ArrayList<>(); - for (ConstraintViolation validation : this.validator.validate(obj)) { - errorMessages.add(validation.getPropertyPath() + ": " + validation.getMessage()); + if (obj != null) { + for (var validation : this.validator.validate(obj)) { + errorMessages.add(validation.getPropertyPath() + ": " + validation.getMessage()); + } } if (!errorMessages.isEmpty()) { diff --git a/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidatorLoader.java b/trustly-java-client/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidatorLoader.java similarity index 100% rename from src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidatorLoader.java rename to trustly-java-client/src/main/java/com/trustly/api/validation/HibernateDataAnnotationsValidatorLoader.java diff --git a/src/main/java/com/trustly/api/validation/ValidationResult.java b/trustly-java-client/src/main/java/com/trustly/api/validation/ValidationResult.java similarity index 100% rename from src/main/java/com/trustly/api/validation/ValidationResult.java rename to trustly-java-client/src/main/java/com/trustly/api/validation/ValidationResult.java diff --git a/src/main/resources/keys/trustly_live_public.pem b/trustly-java-client/src/main/resources/keys/trustly_live_public.pem similarity index 100% rename from src/main/resources/keys/trustly_live_public.pem rename to trustly-java-client/src/main/resources/keys/trustly_live_public.pem diff --git a/src/main/resources/keys/trustly_test_public.pem b/trustly-java-client/src/main/resources/keys/trustly_test_public.pem similarity index 100% rename from src/main/resources/keys/trustly_test_public.pem rename to trustly-java-client/src/main/resources/keys/trustly_test_public.pem diff --git a/trustly-java-client/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java b/trustly-java-client/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java new file mode 100644 index 0000000..8646bd4 --- /dev/null +++ b/trustly-java-client/src/test/java/com/trustly/api/NoOpJsonRpcSigner.java @@ -0,0 +1,16 @@ +package com.trustly.api; + +import com.fasterxml.jackson.databind.JsonNode; + +class NoOpJsonRpcSigner implements JsonRpcSigner { + + @Override + public String sign(Object requestData, String method, String uuid) { + return String.format("<%s>", NoOpJsonRpcSigner.class.getName()); + } + + @Override + public void verify(String method, String uuid, JsonNode dataNode, String expectedSignature) { + + } +} diff --git a/trustly-java-client/src/test/java/com/trustly/api/NotificationsTest.java b/trustly-java-client/src/test/java/com/trustly/api/NotificationsTest.java new file mode 100644 index 0000000..9ad8a32 --- /dev/null +++ b/trustly-java-client/src/test/java/com/trustly/api/NotificationsTest.java @@ -0,0 +1,257 @@ +package com.trustly.api; + +import com.trustly.api.client.TrustlyApiClient; +import com.trustly.api.client.TrustlyApiClientExtensions; +import com.trustly.api.client.TrustlyApiClientExtensions.NotificationResponder; +import com.trustly.api.domain.Models; +import com.trustly.api.domain.notifications.UnknownNotificationAckData; +import com.trustly.api.exceptions.TrustlyNoNotificationClientException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; +import java.util.stream.Stream; + +import static com.trustly.api.domain.Models.*; + +@Execution(ExecutionMode.CONCURRENT) +class NotificationsTest { + + // We use the same certificates as those found at https://test.trustly.com/signaturetester/ + private final TrustlyApiClientSettings settings = TrustlyApiClientSettings.forTest() + .withCredentials("merchant_username", "merchant_password") + .withCertificatesFromStreams( + NotificationsTest.class.getResourceAsStream("/keys/merchant_public_key.pem"), + NotificationsTest.class.getResourceAsStream("/keys/merchant_private_key.pem") + ) + .andTrustlyCertificateFromStream( + NotificationsTest.class.getResourceAsStream("/keys/merchant_public_key.pem") + ); + + private static class Scenario< + TCallback extends JsonRpcNotification, + TCallbackParams extends JsonRpcNotificationParams, + TCallbackData, + + TAck extends Models.JsonRpcResponse, + TAckRes extends Models.ResponseResult, + TAckData extends Models.NotificationResponseDataBase, + TAckStatus + > { + + final String method; + final Class classNotification; + final Class classAck; + final Supplier dataSupplier; + + public Scenario(String method, Class classNotification, Class classAck, Supplier dataSupplier) { + this.method = method; + this.classNotification = classNotification; + this.classAck = classAck; + this.dataSupplier = dataSupplier; + } + } + + static Stream testNotificationsWithoutSignatureVerification() { + + var generalOk = AckData.builder().status(AckDataStatus.OK).build(); + var debitOk = DebitNotificationResponseData.builder().status(DebitNotificationResponseDataStatus.OK).build(); + + return Stream.of( + Arguments.of(new Scenario<>("account", AccountNotification.class, AccountNotificationResponse.class, () -> generalOk)), + Arguments.of(new Scenario<>("cancel", CancelNotification.class, CancelNotificationResponse.class, () -> generalOk)), + Arguments.of(new Scenario<>("credit", CreditNotification.class, CreditNotificationResponse.class, () -> generalOk)), + Arguments.of(new Scenario<>("debit", DebitNotification.class, DebitNotificationResponse.class, () -> debitOk)), + Arguments.of(new Scenario<>("payoutconfirmation", PayoutConfirmationNotification.class, PayoutConfirmationNotificationResponse.class, () -> generalOk)), + Arguments.of(new Scenario<>("pending", PendingNotification.class, PendingNotificationResponse.class, () -> generalOk)) + ); + } + + @ParameterizedTest + @MethodSource + < + TCallback extends JsonRpcNotification, + TCallbackParams extends JsonRpcNotificationParams, + TCallbackData, + + TAck extends Models.JsonRpcResponse, + TAckRes extends Models.ResponseResult, + TAckData extends Models.NotificationResponseDataBase, + TAckStatus + > + void testNotificationsWithoutSignatureVerification(Scenario scenario) throws Exception { + + try (var client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner())) { + + final var receivedNotificationDataCounter = new AtomicInteger(); + + client.addNotificationListener(scenario.method, scenario.classNotification, scenario.classAck, args -> { + receivedNotificationDataCounter.incrementAndGet(); + args.respondWith(scenario.dataSupplier.get()); + }); + + final var is = this.getClass().getResourceAsStream(String.format("/notifications/incoming/%s.json", scenario.method)); + final var status = new AtomicInteger(); + final var responseString = new AtomicReference(); + + final var responder = new NotificationResponder() { + + @Override + public void setStatus(int httpStatus) { + status.set(httpStatus); + } + + @Override + public void writeBody(String value) { + responseString.set(value); + } + }; + + TrustlyApiClientExtensions.handleNotificationRequest(client, is, responder); + + Assertions.assertEquals(200, status.get()); + Assertions.assertNotNull(responseString.get()); + } + } + + @Test + void testUnknownNotificationWithMissingProps() throws Exception { + + try (var client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner())) { + client.getSettings().setIncludeExceptionMessageInNotificationResponse(true); + + final AtomicReference receivedUnknownValue = new AtomicReference<>(); + + client.addOnUnknownNotification(args -> { + args.respondWith(new UnknownNotificationAckData()); + receivedUnknownValue.set(args.getData().getAdditionalProperties().get("something")); + }); + + final InputStream is = this.getClass().getResourceAsStream("/notifications/incoming/_unknown_missing_props.json"); + final Map headers = new HashMap<>(); + final AtomicInteger status = new AtomicInteger(); + final AtomicReference responseString = new AtomicReference<>(); + + final NotificationResponder responder = new NotificationResponder() { + @Override + public void addHeader(String key, String value) { + headers.put(key, value); + } + + @Override + public void setStatus(int httpStatus) { + status.set(httpStatus); + } + + @Override + public void writeBody(String value) { + responseString.set(value); + } + }; + + Assertions.assertThrowsExactly( + TrustlyNoNotificationClientException.class, + () -> TrustlyApiClientExtensions.handleNotificationRequest(client, is, responder) + ); + + Assertions.assertEquals(500, status.get(), "Http 500 was expected"); + Assertions.assertEquals("application/json", headers.get("Content-Type")); + Assertions.assertTrue(responseString.get().contains("params.data.orderID: must not be null")); + Assertions.assertTrue(responseString.get().contains("params.data.messageID: must not be null")); + Assertions.assertTrue(responseString.get().contains("params.data.notificationID: must not be null")); + Assertions.assertNull(receivedUnknownValue.get()); + } + } + + @Test + void testUnknownNotification() throws Exception { + + try (var client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner())) { + client.getSettings().setIncludeExceptionMessageInNotificationResponse(true); + + final AtomicReference receivedUnknownValue = new AtomicReference<>(); + + client.addOnUnknownNotification(args -> { + args.respondWith(new UnknownNotificationAckData()); + receivedUnknownValue.set(args.getData().getAdditionalProperties().get("something")); + }); + + final InputStream is = this.getClass().getResourceAsStream("/notifications/incoming/_unknown.json"); + final Map headers = new HashMap<>(); + final AtomicInteger status = new AtomicInteger(); + final AtomicReference responseString = new AtomicReference<>(); + + final NotificationResponder responder = new NotificationResponder() { + @Override + public void addHeader(String key, String value) { + headers.put(key, value); + } + + @Override + public void setStatus(int httpStatus) { + status.set(httpStatus); + } + + @Override + public void writeBody(String value) { + responseString.set(value); + } + }; + + TrustlyApiClientExtensions.handleNotificationRequest(client, is, responder); + + Assertions.assertEquals(200, status.get(), "Http 200 was expected, an error must have occurred: " + responseString.get()); + Assertions.assertEquals("application/json", headers.get("Content-Type")); + Assertions.assertNotNull(responseString.get()); + Assertions.assertEquals("abc", receivedUnknownValue.get()); + } + } + + @Test + void testCancelNotification() throws Exception { + + try (var client = new TrustlyApiClient(settings)) { + + final AtomicInteger receivedNotificationDataCounter = new AtomicInteger(); + + client.addOnCancelListener(args -> { + + receivedNotificationDataCounter.incrementAndGet(); + args.respondWith(AckData.builder().status(AckDataStatus.OK).build()); + }); + + final InputStream is = this.getClass().getResourceAsStream("/notifications/incoming/cancel.json"); + final AtomicInteger status = new AtomicInteger(); + final AtomicReference responseString = new AtomicReference<>(); + + final NotificationResponder responder = new NotificationResponder() { + + @Override + public void setStatus(int httpStatus) { + status.set(httpStatus); + } + + @Override + public void writeBody(String value) { + responseString.set(value); + } + }; + + TrustlyApiClientExtensions.handleNotificationRequest(client, is, responder); + + Assertions.assertEquals(200, status.get()); + Assertions.assertNotNull(responseString.get()); + } + } + +} diff --git a/src/test/java/com/trustly/api/RequestsTest.java b/trustly-java-client/src/test/java/com/trustly/api/RequestsTest.java similarity index 75% rename from src/test/java/com/trustly/api/RequestsTest.java rename to trustly-java-client/src/test/java/com/trustly/api/RequestsTest.java index 34a4dfb..b054b09 100644 --- a/src/test/java/com/trustly/api/RequestsTest.java +++ b/trustly-java-client/src/test/java/com/trustly/api/RequestsTest.java @@ -1,37 +1,16 @@ package com.trustly.api; import com.trustly.api.client.TrustlyApiClient; -import com.trustly.api.client.TrustlyApiClientSettings; -import com.trustly.api.domain.common.RecipientOrSenderInformation; -import com.trustly.api.domain.exceptions.TrustlyErrorResponseException; -import com.trustly.api.domain.exceptions.TrustlyRequestException; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutRequestData; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutRequestDataAttributes; -import com.trustly.api.domain.methods.cancelcharge.CancelChargeRequestData; -import com.trustly.api.domain.methods.charge.ChargeRequestData; -import com.trustly.api.domain.methods.charge.ChargeRequestDataAttributes; -import com.trustly.api.domain.methods.deposit.DepositRequestData; -import com.trustly.api.domain.methods.deposit.DepositRequestDataAttributes; -import com.trustly.api.domain.methods.deposit.DepositResponseData; -import com.trustly.api.domain.methods.merchantsettlement.MerchantSettlementRequestData; -import com.trustly.api.domain.methods.merchantsettlement.MerchantSettlementResponseData; -import com.trustly.api.domain.methods.refund.RefundRequestData; -import com.trustly.api.domain.methods.refund.RefundRequestDataAttributes; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountRequestData; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountRequestDataAttributes; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountResponseData; -import com.trustly.api.domain.methods.registeraccountpayout.RegisterAccountPayoutRequestData; -import com.trustly.api.domain.methods.registeraccountpayout.RegisterAccountPayoutRequestDataAttributes; -import com.trustly.api.domain.methods.registeraccountpayout.RegisterAccountPayoutResponseData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestDataAttributes; -import com.trustly.api.domain.methods.selectaccount.SelectAccountResponseData; -import com.trustly.api.domain.methods.withdraw.WithdrawRequestData; -import com.trustly.api.domain.methods.withdraw.WithdrawRequestDataAttributes; -import com.trustly.api.domain.methods.withdraw.WithdrawResponseData; -import java.util.UUID; +import com.trustly.api.exceptions.TrustlyErrorResponseException; +import com.trustly.api.exceptions.TrustlyRequestException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + +import static com.trustly.api.domain.Models.*; + +import java.util.UUID; /** * These test will only work if a local environment exists. At the USER_HOME root these files is needed: trustly_client_username.txt - your @@ -40,6 +19,7 @@ *

* If those files exist and are correct you are able to make requests to Trustly's test environment */ +@Execution(ExecutionMode.CONCURRENT) class RequestsTest { private final TrustlyApiClientSettings settings = TrustlyApiClientSettings.forTest() @@ -67,7 +47,7 @@ void testDeposit() throws Exception { .locale("sv_SE") .shopperStatement("Trustly Test Deposit") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .mobilePhone("0701234567") .build() ) @@ -76,7 +56,7 @@ void testDeposit() throws Exception { DepositResponseData response = client.deposit(request); Assertions.assertNotNull(response); - Assertions.assertNotNull(response.getUrl()); + Assertions.assertNotNull(response.getURL()); } } @@ -92,7 +72,7 @@ void testAccountPayout() { .messageId("MessageId") .amount("99.99") .currency("SEK") - .notificationURL("https://notify.me") + .notificationUrl("https://notify.me") .attributes( AccountPayoutRequestDataAttributes.builder() .pspMerchant("Merchant Ltd.") @@ -101,13 +81,13 @@ void testAccountPayout() { .merchantCategoryCode("5499") .pspMerchantUrl("www.merchant.com") .senderInformation( - RecipientOrSenderInformation.builder() - .partytype("PERSON") + SenderInformation.builder() + .partytype(PartyTypeKind.PERSON) .address("Street 1, 12345 Barcelona") .countryCode("SE") .firstname("Steve") .lastname("Smith") - .customerID("123456789") + .customerId("123456789") .dateOfBirth("1990-03-31") .build() ) @@ -157,7 +137,7 @@ void testCharge() { ChargeRequestData data = ChargeRequestData.builder() .accountId("accountId") - .notificationURL("https://notify.me") + .notificationUrl("https://notify.me") .endUserId("EndUserId") .messageId(UUID.randomUUID().toString()) .amount("99.90") @@ -242,7 +222,7 @@ void testRegisterAccount() throws Exception { ); Assertions.assertNotNull(registerAccountResponse); - Assertions.assertNotNull(registerAccountResponse.getAccountId()); +// Assertions.assertNotNull(registerAccountResponse.getAccountID()); } } @@ -267,7 +247,7 @@ void testSelectAccount() throws Exception { .merchantCategoryCode("5499") .pspMerchantUrl("www.merchant.com") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .build() ) .build() @@ -302,7 +282,7 @@ void testWithdraw() throws Exception { .locale("en_US") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .mobilePhone("0701234567") .build() @@ -311,8 +291,8 @@ void testWithdraw() throws Exception { WithdrawResponseData response = client.withdraw(data); - Assertions.assertNotNull(response.getUrl()); - Assertions.assertNotEquals(0, response.getOrderId()); + Assertions.assertNotNull(response.getURL()); + Assertions.assertNotEquals(0, response.getOrderID()); } } @@ -345,13 +325,13 @@ void testRegisterAccountPayout() throws Exception { .pspMerchantUrl("www.merchant.com") .merchantCategoryCode("5499") .senderInformation( - RecipientOrSenderInformation.builder() - .partytype("PERSON") + SenderInformation.builder() + .partytype(PartyTypeKind.PERSON) .address("Street 1, 12345 Barcelona") .countryCode("SE") .firstname("Steve") .lastname("Smith") - .customerID("123456789") + .customerId("123456789") .dateOfBirth("1990-03-31") .build() ) @@ -374,27 +354,19 @@ void testMerchantSettlement() { String uniqueMessageId = UUID.randomUUID().toString(); - MerchantSettlementResponseData merchantSettlementResponse = client.registerMerchantSettlement( + var ex = Assertions.assertThrows(TrustlyRequestException.class, () -> client.merchantSettlement( MerchantSettlementRequestData.builder() .messageId(uniqueMessageId) .amount("4.99") .currency("EUR") .build() - ); - - Assertions.assertNotNull(merchantSettlementResponse); - Assertions.assertNotEquals(0, merchantSettlementResponse.getReference()); - } catch (TrustlyRequestException ex) { + )); if (ex.getCause() instanceof TrustlyErrorResponseException) { - - final TrustlyErrorResponseException resEx = (TrustlyErrorResponseException) ex.getCause(); - if (resEx.getResponseError().getMessage().equals("ERROR_NO_SUITABLE_BANK_ACCOUNT_FOUND")) { - return; - } + Assertions.assertEquals("ERROR_NO_SUITABLE_BANK_ACCOUNT_FOUND", ((TrustlyErrorResponseException) ex.getCause()).getResponseError().getMessage()); + } else { + Assertions.fail("Should be a wrapped error response exception"); } - - Assertions.fail("Unexpected error: " + ex, ex); } } } diff --git a/src/test/java/com/trustly/api/SerializerTest.java b/trustly-java-client/src/test/java/com/trustly/api/SerializerTest.java similarity index 63% rename from src/test/java/com/trustly/api/SerializerTest.java rename to trustly-java-client/src/test/java/com/trustly/api/SerializerTest.java index f959a88..87c969f 100644 --- a/src/test/java/com/trustly/api/SerializerTest.java +++ b/trustly-java-client/src/test/java/com/trustly/api/SerializerTest.java @@ -1,27 +1,30 @@ package com.trustly.api; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; import com.fasterxml.jackson.databind.node.ObjectNode; -import com.trustly.api.client.DefaultJsonRpcSigner; import com.trustly.api.client.JsonRpcFactory; -import com.trustly.api.client.JsonRpcSigner; import com.trustly.api.client.JsonRpcValidator; -import com.trustly.api.client.Serializer; import com.trustly.api.client.TrustlyApiClient; -import com.trustly.api.client.TrustlyApiClientSettings; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.base.NotificationResponse; -import com.trustly.api.domain.exceptions.TrustlyValidationException; -import com.trustly.api.domain.methods.deposit.DepositRequestData; -import com.trustly.api.domain.methods.deposit.DepositRequestDataAttributes; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountResponseData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestDataAttributes; -import java.io.InputStream; +import com.trustly.api.domain.Models; +import com.trustly.api.domain.Models.AckData; +import com.trustly.api.domain.Models.DepositRequest; +import com.trustly.api.domain.Models.RegisterAccountResponse; +import com.trustly.api.domain.Models.SelectAccountRequest; +import com.trustly.api.exceptions.TrustlyValidationException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + +import java.io.InputStream; +import java.util.UUID; +import static com.trustly.api.domain.Models.*; + +@Execution(ExecutionMode.CONCURRENT) class SerializerTest { @Test @@ -44,22 +47,27 @@ void testSerializingDepositWithoutValidation() { attributes.setFirstname("John"); attributes.setLastname("Doe"); attributes.setNationalIdentificationNumber("790131-1234"); + attributes.setCountry("SE"); + attributes.setEmail("test@trustly.com"); + attributes.setSuccessUrl("http://www.google.com/q?success"); + attributes.setFailUrl("http://www.google.com/q?fail"); + attributes.setShopperStatement("Shop"); request.setAttributes(attributes); - JsonRpcRequest jsonRpc = factory.create(request, "Deposit"); + var jsonRpc = factory.create(request, "Deposit", UUID.randomUUID().toString()); String serialized = serializer.serializeData(jsonRpc.getParams().getData()); - String expected = "AttributesCurrencySEKFirstnameJohnIP123.123.123.123LastnameDoeLocalesv_SEMobilePhone+46709876543NationalIdentificationNumber790131-1234EndUserID12345MessageIDyour_unique_deposit_idNotificationURLURL_to_your_notification_servicePasswordmerchant_passwordUsernamemerchant_username"; + String expected = "AttributesCountrySECurrencySEKEmailtest@trustly.comFailURLhttp://www.google.com/q?failFirstnameJohnIP123.123.123.123LastnameDoeLocalesv_SEMobilePhone+46709876543NationalIdentificationNumber790131-1234ShopperStatementShopSuccessURLhttp://www.google.com/q?successEndUserID12345MessageIDyour_unique_deposit_idNotificationURLURL_to_your_notification_servicePasswordmerchant_passwordUsernamemerchant_username"; Assertions.assertEquals(expected, serialized); } @Test - void serializeResponseWithNonNullAnyMapAsPojo() throws Exception { + void serializeResponseWithNonNullAnyMapAsPojo() { RegisterAccountResponseData data = RegisterAccountResponseData.builder() - .accountId("123456789") + .accountID("123456789") .bank("BankA") .clearingHouse("SWEDEN") .build(); @@ -67,36 +75,36 @@ void serializeResponseWithNonNullAnyMapAsPojo() throws Exception { Serializer serializer = new Serializer(); String serialized = serializer.serializeData(data); - Assertions.assertEquals("accountid123456789bankBankAclearinghouseSWEDENdescriptor", serialized); + Assertions.assertEquals("accountid123456789bankBankAclearinghouseSWEDEN", serialized); } @Test - void serializeResponseWithNonEmptyAnyMapAsPOJO() throws Exception { + void serializeResponseWithNonEmptyAnyMapAsPOJO() { RegisterAccountResponseData data = RegisterAccountResponseData.builder() - .accountId("123456789") + .accountID("123456789") .bank("BankA") .clearingHouse("SWEDEN") - .any("key", "value") + .additionalProperty("key", "value") .build(); Serializer serializer = new Serializer(); String serialized = serializer.serializeData(data); - Assertions.assertEquals("accountid123456789bankBankAclearinghouseSWEDENdescriptorkeyvalue", serialized); + Assertions.assertEquals("accountid123456789bankBankAclearinghouseSWEDENkeyvalue", serialized); } @Test - void serializeResponseWithNonEmptyAnyMapAsNode() throws Exception { + void serializeResponseWithNonEmptyAnyMapAsNode() { RegisterAccountResponseData data = RegisterAccountResponseData.builder() - .accountId("123456789") + .accountID("123456789") .bank("BankA") .clearingHouse("SWEDEN") - .any("key", "value") + .additionalProperty("key", "value") .build(); - ObjectNode dataNode = new ObjectMapper().valueToTree(data); + ObjectNode dataNode = TrustlyApiClientSettings.DEFAULT_OBJECT_MAPPER.valueToTree(data); dataNode.remove("descriptor"); Serializer serializer = new Serializer(); @@ -123,23 +131,27 @@ void testNullProperties() throws Exception { try (TrustlyApiClient client = new TrustlyApiClient(settings)) { JsonRpcSigner signer = new DefaultJsonRpcSigner(serializer, settings); - JsonRpcResponse rpcResponse = client.createResponsePackage( + var rpcResponse = client.createResponsePackage( "account", "e76ffbe5-e0f9-4402-8689-f868ed2021f8", - NotificationResponse.builder() - .status("OK") + AckData.builder() + .status(AckDataStatus.OK) .build() ); - String serialized = serializer.serializeData(rpcResponse.getData()); + String serialized = serializer.serializeData(rpcResponse.getResult().getData()); Assertions.assertEquals("statusOK", serialized); - JsonRpcResponse signedResponse = signer.sign(rpcResponse); + var signature = signer.sign( + rpcResponse.getResult().getData(), + rpcResponse.getResult().getMethod(), + rpcResponse.getResult().getUUID() + ); Assertions.assertEquals( "J28IN0yXZN3dlV2ikg4nQKwnP98kso8lzpmuwBcfbXr8i3XeEyydRM4jRwsOOeF0ilGuXyr1Kyb3+1j4mVtgU0SwjVgBHWrYPMegNeykY3meto/aoATH0mvop4Ex1OKO7w/S/ktR2J0J5Npn/EuiKGiVy5GztHYTh9hWmZBCElYPZf4Rsd1CJQJAPlZeAuRcrb5dnbiGJvTEaL/7VLcPT27oqAUefSNb/zNt5yL+wH6BihlkpZ/mtE61lX5OpC46iql6hpsrlOBD3BroYfcwgk1t3YdcNOhVWrmkrlVptGQ/oy6T/LSIKbkG/tJsuV8sl6w1Z31IesK6MZDfSJbcXw==", - signedResponse.getSignature() + signature ); } } @@ -150,7 +162,7 @@ void testMissingDepositShopperStatement() { JsonRpcFactory factory = new JsonRpcFactory(); JsonRpcValidator validator = new JsonRpcValidator(); - JsonRpcRequest jsonRpc = factory.create( + var jsonRpc = factory.create( DepositRequestData.builder() .username("merchant_username") .password("merchant_password") @@ -168,15 +180,18 @@ void testMissingDepositShopperStatement() { .lastname("Doe") .nationalIdentificationNumber("790131-1234") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .mobilePhone("0701234567") .email("name@site.com") .build() ) .build(), - "Deposit" + "Deposit", + UUID.randomUUID().toString() ); + jsonRpc.getParams().setSignature(""); + try { validator.validate(jsonRpc); Assertions.fail("Expected an exception since ShopperStatement is not specified"); @@ -195,7 +210,7 @@ void testMissingDepositFirstName() { JsonRpcFactory factory = new JsonRpcFactory(); JsonRpcValidator validator = new JsonRpcValidator(); - JsonRpcRequest jsonRpc = factory.create( + var jsonRpc = factory.create( DepositRequestData.builder() .username("merchant_username") .password("merchant_password") @@ -213,14 +228,17 @@ void testMissingDepositFirstName() { .nationalIdentificationNumber("790131-1234") .shopperStatement("Shopper Statement") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .email("name@site.com") .build() ) .build(), - "Deposit" + "Deposit", + UUID.randomUUID().toString() ); + jsonRpc.getParams().setSignature(""); + Assertions.assertThrows( TrustlyValidationException.class, () -> validator.validate(jsonRpc), @@ -238,7 +256,7 @@ void testMissingNotDepositShopperStatement() throws Exception { JsonRpcFactory factory = new JsonRpcFactory(); JsonRpcValidator validator = new JsonRpcValidator(); - JsonRpcRequest jsonRpc = factory.create( + var jsonRpc = factory.create( SelectAccountRequestData.builder() .username("merchant_username") .password("merchant_password") @@ -255,15 +273,74 @@ void testMissingNotDepositShopperStatement() throws Exception { .lastname("Doe") .nationalIdentificationNumber("790131-1234") .successUrl("https://google.com") - .failURL("https://google.com") + .failUrl("https://google.com") .mobilePhone("0701234567") .build() ) .build(), - "SelectAccount" + "SelectAccount", + UUID.randomUUID().toString() ); + jsonRpc.getParams().setSignature(""); + // ShopperStatement is NOT specified -- but we should NOT throw exception, since that validation group is not specified. validator.validate(jsonRpc); } + + @Test + void testRequestData() throws Exception { + + var requestData = new RequestData( + new SenderInformation("2020-01-02") + ); + + final var om = new ObjectMapper(); + final var jsonString = om.writeValueAsString(requestData); + + Assertions.assertEquals("{\"senderInformation\":{\"DateOfBirth\":\"2020-01-02\"}}", jsonString); + + final var value1 = om.readValue("\"foo\"", SingleProp.class); + Assertions.assertEquals(value1.getKind(), "foo"); + + Assertions.assertThrowsExactly(MismatchedInputException.class, () -> om.readValue("{\"kind\": \"foo\"}", SingleProp.class)); + } + + private static class RequestData { + private final SenderInformation senderInformation; + + public RequestData(@JsonProperty(value = "senderInformation") SenderInformation senderInformation) { + this.senderInformation = senderInformation; + } + + public SenderInformation getSenderInformation() { + return this.senderInformation; + } + } + + private static class SenderInformation { + @JsonProperty(value = "DateOfBirth") + private final String dateOfBirth; + + public SenderInformation(@JsonProperty(value = "DateOfBirth") String dateOfBirth) { + this.dateOfBirth = dateOfBirth; + } + + public String getDateOfBirth() { + return this.dateOfBirth; + } + } + + private static class SingleProp { + private final String kind; + + @JsonCreator + public SingleProp(String kind) { + this.kind = kind; + } + + public String getKind() { + return this.kind; + } + } } diff --git a/src/test/java/com/trustly/api/TestExamplePayloads.java b/trustly-java-client/src/test/java/com/trustly/api/TestExamplePayloads.java similarity index 56% rename from src/test/java/com/trustly/api/TestExamplePayloads.java rename to trustly-java-client/src/test/java/com/trustly/api/TestExamplePayloads.java index 2ec59af..54ed57c 100644 --- a/src/test/java/com/trustly/api/TestExamplePayloads.java +++ b/trustly-java-client/src/test/java/com/trustly/api/TestExamplePayloads.java @@ -1,50 +1,23 @@ package com.trustly.api; -import com.fasterxml.jackson.databind.ObjectMapper; import com.trustly.api.client.TrustlyApiClient; -import com.trustly.api.client.TrustlyApiClientSettings; -import com.trustly.api.domain.base.IResponseResultData; -import com.trustly.api.domain.base.IToTrustlyRequestParams; -import com.trustly.api.domain.exceptions.TrustlyErrorResponseException; -import com.trustly.api.domain.exceptions.TrustlyRequestException; -import com.trustly.api.domain.methods.accountledger.AccountLedgerRequestData; -import com.trustly.api.domain.methods.accountledger.AccountLedgerResponseData; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutRequestData; -import com.trustly.api.domain.methods.accountpayout.AccountPayoutResponseData; -import com.trustly.api.domain.methods.approvewithdrawal.ApproveWithdrawalRequestData; -import com.trustly.api.domain.methods.approvewithdrawal.ApproveWithdrawalResponseData; -import com.trustly.api.domain.methods.balance.BalanceRequestData; -import com.trustly.api.domain.methods.balance.BalanceResponseData; -import com.trustly.api.domain.methods.cancelcharge.CancelChargeRequestData; -import com.trustly.api.domain.methods.cancelcharge.CancelChargeResponseData; -import com.trustly.api.domain.methods.charge.ChargeRequestData; -import com.trustly.api.domain.methods.charge.ChargeResponseData; -import com.trustly.api.domain.methods.denywithdrawal.DenyWithdrawalRequestData; -import com.trustly.api.domain.methods.denywithdrawal.DenyWithdrawalResponseData; -import com.trustly.api.domain.methods.deposit.DepositRequestData; -import com.trustly.api.domain.methods.deposit.DepositResponseData; -import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsRequestData; -import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsResponseData; -import com.trustly.api.domain.methods.refund.RefundRequestData; -import com.trustly.api.domain.methods.refund.RefundResponseData; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountRequestData; -import com.trustly.api.domain.methods.registeraccount.RegisterAccountResponseData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountRequestData; -import com.trustly.api.domain.methods.selectaccount.SelectAccountResponseData; -import com.trustly.api.domain.methods.settlementreport.SettlementReportRequestData; -import com.trustly.api.domain.methods.settlementreport.SettlementReportResponseData; -import com.trustly.api.domain.methods.withdraw.WithdrawRequestData; -import com.trustly.api.domain.methods.withdraw.WithdrawResponseData; +import com.trustly.api.exceptions.TrustlyErrorResponseException; +import com.trustly.api.exceptions.TrustlyRequestException; import com.trustly.api.request.HttpRequester; import com.trustly.api.util.TrustlyStreamUtils; -import java.io.IOException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; + import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.UUID; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; +import static com.trustly.api.domain.Models.*; + +@Execution(ExecutionMode.CONCURRENT) class TestExamplePayloads { private final TrustlyApiClientSettings settings = TrustlyApiClientSettings.forTest() @@ -62,7 +35,7 @@ void testInvalidParametersResponse() throws Exception { try { this.doRequestResponse( - WithdrawRequestData.class, WithdrawResponseData.class, + WithdrawRequestData.class, WithdrawResponse.class, "Withdraw", "/requests/withdraw.json", "/responses/error_invalid_parameters.json" ); @@ -81,140 +54,147 @@ void testInvalidParametersResponse() throws Exception { void testRequestAndResponsePayload() throws Exception { this.doRequestResponse( - AccountLedgerRequestData.class, AccountLedgerResponseData.class, + AccountLedgerRequestData.class, AccountLedgerResponse.class, "AccountLedger", "/requests/accountledger.json", "/responses/accountledger.json" ); // Same request, but this time we will respond with an Invalid Parameters error. Assertions.assertThrows(TrustlyRequestException.class, () -> this.doRequestResponse( - AccountLedgerRequestData.class, AccountLedgerResponseData.class, + AccountLedgerRequestData.class, AccountLedgerResponse.class, "AccountLedger", "/requests/accountledger.json", "/responses/error_invalid_parameters.json" )); this.doRequestResponse( - AccountPayoutRequestData.class, AccountPayoutResponseData.class, + AccountPayoutRequestData.class, AccountPayoutResponse.class, "AccountPayout", "/requests/accountpayout_1.json", "/responses/accountpayout.json" ); this.doRequestResponse( - AccountPayoutRequestData.class, AccountPayoutResponseData.class, + AccountPayoutRequestData.class, AccountPayoutResponse.class, "AccountPayout", "/requests/accountpayout_2.json", "/responses/accountpayout.json" ); this.doRequestResponse( - AccountPayoutRequestData.class, AccountPayoutResponseData.class, + AccountPayoutRequestData.class, AccountPayoutResponse.class, "AccountPayout", "/requests/accountpayout_3.json", "/responses/accountpayout.json" ); this.doRequestResponse( - ApproveWithdrawalRequestData.class, ApproveWithdrawalResponseData.class, + ApproveWithdrawalRequestData.class, ApproveWithdrawalResponse.class, "ApproveWithdrawal", "/requests/approvewithdrawal.json", "/responses/approvewithdrawal.json" ); this.doRequestResponse( - BalanceRequestData.class, BalanceResponseData.class, + BalanceRequestData.class, BalanceResponse.class, "Balance", "/requests/balance.json", "/responses/balance.json" ); Assertions.assertThrows(TrustlyRequestException.class, () -> this.doRequestResponse( - CancelChargeRequestData.class, CancelChargeResponseData.class, + CancelChargeRequestData.class, CancelChargeResponse.class, "CancelCharge", "/requests/cancelcharge.json", "/responses/cancelcharge_fail.json" )); this.doRequestResponse( - CancelChargeRequestData.class, CancelChargeResponseData.class, + CancelChargeRequestData.class, CancelChargeResponse.class, "CancelCharge", "/requests/cancelcharge.json", "/responses/cancelcharge_ok.json" ); this.doRequestResponse( - ChargeRequestData.class, ChargeResponseData.class, + ChargeRequestData.class, ChargeResponse.class, "Charge", "/requests/charge_1.json", "/responses/charge.json" ); this.doRequestResponse( - ChargeRequestData.class, ChargeResponseData.class, + ChargeRequestData.class, ChargeResponse.class, "Charge", "/requests/charge_2.json", "/responses/charge.json" ); this.doRequestResponse( - DenyWithdrawalRequestData.class, DenyWithdrawalResponseData.class, + DenyWithdrawalRequestData.class, DenyWithdrawalResponse.class, "DenyWithdrawal", "/requests/denywithdrawal.json", "/responses/denywithdrawal.json" ); this.doRequestResponse( - DepositRequestData.class, DepositResponseData.class, + DepositRequestData.class, DepositResponse.class, "Deposit", "/requests/deposit_1.json", "/responses/deposit.json" ); this.doRequestResponse( - DepositRequestData.class, DepositResponseData.class, + DepositRequestData.class, DepositResponse.class, "Deposit", "/requests/deposit_2.json", "/responses/deposit.json" ); this.doRequestResponse( - DepositRequestData.class, DepositResponseData.class, + DepositRequestData.class, DepositResponse.class, "Deposit", "/requests/deposit_3.json", "/responses/deposit.json" ); this.doRequestResponse( - DepositRequestData.class, DepositResponseData.class, + DepositRequestData.class, DepositResponse.class, "Deposit", "/requests/deposit_ideal.json", "/responses/deposit.json" ); this.doRequestResponse( - GetWithdrawalsRequestData.class, GetWithdrawalsResponseData.class, + GetWithdrawalsRequestData.class, GetWithdrawalsResponse.class, "GetWithdrawals", "/requests/getwithdrawals.json", "/responses/getwithdrawals.json" ); this.doRequestResponse( - RefundRequestData.class, RefundResponseData.class, + RefundRequestData.class, RefundResponse.class, "Refund", "/requests/refund.json", "/responses/refund.json" ); this.doRequestResponse( - RegisterAccountRequestData.class, RegisterAccountResponseData.class, + RegisterAccountRequestData.class, RegisterAccountResponse.class, "RegisterAccount", "/requests/registeraccount.json", "/responses/registeraccount.json" ); this.doRequestResponse( - RegisterAccountRequestData.class, RegisterAccountResponseData.class, + RegisterAccountRequestData.class, RegisterAccountResponse.class, "RegisterAccount", "/requests/registeraccount_2.json", "/responses/registeraccount.json" ); this.doRequestResponse( - SelectAccountRequestData.class, SelectAccountResponseData.class, + SelectAccountRequestData.class, SelectAccountResponse.class, "SelectAccount", "/requests/selectaccount.json", "/responses/selectaccount.json" ); this.doRequestResponse( - SettlementReportRequestData.class, SettlementReportResponseData.class, + SettlementReportRequestData.class, SettlementReportResponse.class, "ViewAutomaticSettlementDetailsCSV", "/requests/settlementreport.json", "/responses/settlementreport.json" ); this.doRequestResponse( - WithdrawRequestData.class, WithdrawResponseData.class, + WithdrawRequestData.class, WithdrawResponse.class, "Withdraw", "/requests/withdraw.json", "/responses/withdraw.json" ); } - private void doRequestResponse( - Class requestClass, - Class responseClass, + private < + TReqAttr extends AbstractRequestDataAttributes, + TReqData extends AbstractRequestData, + TResData, + TResResult extends ResponseResult, + TRes extends JsonRpcResponse + > + void doRequestResponse( + Class requestDataClass, + Class responseDataClass, String method, String requestClassPath, String responseClassPath @@ -232,8 +212,12 @@ private void try (TrustlyApiClient client = new TrustlyApiClient(settings, new NoOpJsonRpcSigner(), fakeHttpRequester)) { try (InputStream requestStream = TestExamplePayloads.class.getResourceAsStream(requestClassPath)) { - T requestData = new ObjectMapper().readValue(requestStream, requestClass); - client.sendRequest(requestData, responseClass, method, requestUuid); + Assertions.assertNotNull(client.sendRequest( + TrustlyApiClientSettings.DEFAULT_OBJECT_MAPPER.readValue(requestStream, requestDataClass), + responseDataClass, + method, + requestUuid + )); } } } diff --git a/trustly-java-client/src/test/resources/junit-platform.properties b/trustly-java-client/src/test/resources/junit-platform.properties new file mode 100644 index 0000000..83613f6 --- /dev/null +++ b/trustly-java-client/src/test/resources/junit-platform.properties @@ -0,0 +1,7 @@ +# Once we have reactive transactions, we should enable parallel testing + +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.config.strategy=dynamic +junit.jupiter.execution.parallel.mode.default=same_thread +junit.jupiter.execution.parallel.mode.classes.default=same_thread +junit.jupiter.execution.parallel.config.dynamic.factor=1 diff --git a/src/test/resources/keys/merchant_private_key.pem b/trustly-java-client/src/test/resources/keys/merchant_private_key.pem similarity index 100% rename from src/test/resources/keys/merchant_private_key.pem rename to trustly-java-client/src/test/resources/keys/merchant_private_key.pem diff --git a/src/test/resources/keys/merchant_public_key.pem b/trustly-java-client/src/test/resources/keys/merchant_public_key.pem similarity index 100% rename from src/test/resources/keys/merchant_public_key.pem rename to trustly-java-client/src/test/resources/keys/merchant_public_key.pem diff --git a/trustly-java-client/src/test/resources/notifications/incoming/_unknown.json b/trustly-java-client/src/test/resources/notifications/incoming/_unknown.json new file mode 100644 index 0000000..904a9b7 --- /dev/null +++ b/trustly-java-client/src/test/resources/notifications/incoming/_unknown.json @@ -0,0 +1,14 @@ +{ + "method": "qweasdzxc", + "params": { + "signature": "fVhjuMqbsH0Ku ... S16VbzRsw==", + "uuid": "258a2184-2842-b485-23ca-293425152415", + "data": { + "messageid": "98348932", + "orderid": "87654567", + "notificationid": "4876513450", + "something": "abc" + } + }, + "version": "1.1" +} diff --git a/src/test/resources/notifications/incoming/_unknown.json b/trustly-java-client/src/test/resources/notifications/incoming/_unknown_missing_props.json similarity index 100% rename from src/test/resources/notifications/incoming/_unknown.json rename to trustly-java-client/src/test/resources/notifications/incoming/_unknown_missing_props.json diff --git a/src/test/resources/notifications/incoming/account.json b/trustly-java-client/src/test/resources/notifications/incoming/account.json similarity index 100% rename from src/test/resources/notifications/incoming/account.json rename to trustly-java-client/src/test/resources/notifications/incoming/account.json diff --git a/trustly-java-client/src/test/resources/notifications/incoming/cancel.json b/trustly-java-client/src/test/resources/notifications/incoming/cancel.json new file mode 100644 index 0000000..44913e9 --- /dev/null +++ b/trustly-java-client/src/test/resources/notifications/incoming/cancel.json @@ -0,0 +1,15 @@ +{ + "method": "cancel", + "params": { + "signature": "LNo4v7Iyvje+PurM2HYy1zqkmQxAH5KJouH2wTzRz+og56eiWjLRa1U0ww9g/YoPbyEI1znBIq4Fogi/McMbOUwVy8sQhqutuqlnRR2rDPfGHpOkX5ctiTdvP/0CmUVNwTLJzo93QrGvx7bcRx9W/D6iuipKP8Sh08KIk9LIUxnnwQnyz82ckG7+5GYK8Q2sGMjQIM+F8AhkA+wax3gnmoQJN8FrdHGRLROGDozBx27uIHIUzZTRrQdpFgH9asivr3+zVI4gZLt8OBMkqP9v3/YECwiucyEY51FmQCpTwVXDVNJ4uP4nhUvZzxtPQIhWeEW9Imw7sBIQqz/H5tC0Aw==", + "uuid": "8f003dba-4f90-4afe-91e9-6c2e6ad0f8a9", + "data": { + "messageid": "98348932", + "orderid": "87654567", + "enduserid": "32123", + "notificationid": "4876513450", + "timestamp": "2013-12-20 14:42:04.675645+01" + } + }, + "version": "1.1" +} diff --git a/src/test/resources/notifications/incoming/credit.json b/trustly-java-client/src/test/resources/notifications/incoming/credit.json similarity index 100% rename from src/test/resources/notifications/incoming/credit.json rename to trustly-java-client/src/test/resources/notifications/incoming/credit.json diff --git a/src/test/resources/notifications/incoming/debit.json b/trustly-java-client/src/test/resources/notifications/incoming/debit.json similarity index 100% rename from src/test/resources/notifications/incoming/debit.json rename to trustly-java-client/src/test/resources/notifications/incoming/debit.json diff --git a/src/test/resources/notifications/incoming/payoutconfirmation.json b/trustly-java-client/src/test/resources/notifications/incoming/payoutconfirmation.json similarity index 100% rename from src/test/resources/notifications/incoming/payoutconfirmation.json rename to trustly-java-client/src/test/resources/notifications/incoming/payoutconfirmation.json diff --git a/src/test/resources/notifications/incoming/pending.json b/trustly-java-client/src/test/resources/notifications/incoming/pending.json similarity index 100% rename from src/test/resources/notifications/incoming/pending.json rename to trustly-java-client/src/test/resources/notifications/incoming/pending.json diff --git a/src/test/resources/requests/accountledger.json b/trustly-java-client/src/test/resources/requests/accountledger.json similarity index 84% rename from src/test/resources/requests/accountledger.json rename to trustly-java-client/src/test/resources/requests/accountledger.json index 5b9a2c2..9e38efc 100644 --- a/src/test/resources/requests/accountledger.json +++ b/trustly-java-client/src/test/resources/requests/accountledger.json @@ -3,5 +3,5 @@ "Password": "*******", "FromDate": "2014-01-01", "ToDate": "2014-01-31", - "Currency": null + "Currency": "SEK" } diff --git a/src/test/resources/requests/accountpayout_1.json b/trustly-java-client/src/test/resources/requests/accountpayout_1.json similarity index 100% rename from src/test/resources/requests/accountpayout_1.json rename to trustly-java-client/src/test/resources/requests/accountpayout_1.json diff --git a/src/test/resources/requests/accountpayout_2.json b/trustly-java-client/src/test/resources/requests/accountpayout_2.json similarity index 100% rename from src/test/resources/requests/accountpayout_2.json rename to trustly-java-client/src/test/resources/requests/accountpayout_2.json diff --git a/src/test/resources/requests/accountpayout_3.json b/trustly-java-client/src/test/resources/requests/accountpayout_3.json similarity index 100% rename from src/test/resources/requests/accountpayout_3.json rename to trustly-java-client/src/test/resources/requests/accountpayout_3.json diff --git a/src/test/resources/requests/approvewithdrawal.json b/trustly-java-client/src/test/resources/requests/approvewithdrawal.json similarity index 100% rename from src/test/resources/requests/approvewithdrawal.json rename to trustly-java-client/src/test/resources/requests/approvewithdrawal.json diff --git a/src/test/resources/requests/balance.json b/trustly-java-client/src/test/resources/requests/balance.json similarity index 100% rename from src/test/resources/requests/balance.json rename to trustly-java-client/src/test/resources/requests/balance.json diff --git a/src/test/resources/requests/cancelcharge.json b/trustly-java-client/src/test/resources/requests/cancelcharge.json similarity index 100% rename from src/test/resources/requests/cancelcharge.json rename to trustly-java-client/src/test/resources/requests/cancelcharge.json diff --git a/src/test/resources/requests/charge_1.json b/trustly-java-client/src/test/resources/requests/charge_1.json similarity index 100% rename from src/test/resources/requests/charge_1.json rename to trustly-java-client/src/test/resources/requests/charge_1.json diff --git a/src/test/resources/requests/charge_2.json b/trustly-java-client/src/test/resources/requests/charge_2.json similarity index 100% rename from src/test/resources/requests/charge_2.json rename to trustly-java-client/src/test/resources/requests/charge_2.json diff --git a/src/test/resources/requests/denywithdrawal.json b/trustly-java-client/src/test/resources/requests/denywithdrawal.json similarity index 100% rename from src/test/resources/requests/denywithdrawal.json rename to trustly-java-client/src/test/resources/requests/denywithdrawal.json diff --git a/src/test/resources/requests/deposit_1.json b/trustly-java-client/src/test/resources/requests/deposit_1.json similarity index 100% rename from src/test/resources/requests/deposit_1.json rename to trustly-java-client/src/test/resources/requests/deposit_1.json diff --git a/src/test/resources/requests/deposit_2.json b/trustly-java-client/src/test/resources/requests/deposit_2.json similarity index 100% rename from src/test/resources/requests/deposit_2.json rename to trustly-java-client/src/test/resources/requests/deposit_2.json diff --git a/src/test/resources/requests/deposit_3.json b/trustly-java-client/src/test/resources/requests/deposit_3.json similarity index 100% rename from src/test/resources/requests/deposit_3.json rename to trustly-java-client/src/test/resources/requests/deposit_3.json diff --git a/src/test/resources/requests/deposit_ideal.json b/trustly-java-client/src/test/resources/requests/deposit_ideal.json similarity index 100% rename from src/test/resources/requests/deposit_ideal.json rename to trustly-java-client/src/test/resources/requests/deposit_ideal.json diff --git a/src/test/resources/requests/getwithdrawals.json b/trustly-java-client/src/test/resources/requests/getwithdrawals.json similarity index 100% rename from src/test/resources/requests/getwithdrawals.json rename to trustly-java-client/src/test/resources/requests/getwithdrawals.json diff --git a/src/test/resources/requests/refund.json b/trustly-java-client/src/test/resources/requests/refund.json similarity index 100% rename from src/test/resources/requests/refund.json rename to trustly-java-client/src/test/resources/requests/refund.json diff --git a/src/test/resources/requests/registeraccount.json b/trustly-java-client/src/test/resources/requests/registeraccount.json similarity index 100% rename from src/test/resources/requests/registeraccount.json rename to trustly-java-client/src/test/resources/requests/registeraccount.json diff --git a/src/test/resources/requests/registeraccount_2.json b/trustly-java-client/src/test/resources/requests/registeraccount_2.json similarity index 100% rename from src/test/resources/requests/registeraccount_2.json rename to trustly-java-client/src/test/resources/requests/registeraccount_2.json diff --git a/src/test/resources/requests/selectaccount.json b/trustly-java-client/src/test/resources/requests/selectaccount.json similarity index 100% rename from src/test/resources/requests/selectaccount.json rename to trustly-java-client/src/test/resources/requests/selectaccount.json diff --git a/src/test/resources/requests/settlementreport.json b/trustly-java-client/src/test/resources/requests/settlementreport.json similarity index 100% rename from src/test/resources/requests/settlementreport.json rename to trustly-java-client/src/test/resources/requests/settlementreport.json diff --git a/src/test/resources/requests/withdraw.json b/trustly-java-client/src/test/resources/requests/withdraw.json similarity index 91% rename from src/test/resources/requests/withdraw.json rename to trustly-java-client/src/test/resources/requests/withdraw.json index 565bd90..c4d9e6d 100644 --- a/src/test/resources/requests/withdraw.json +++ b/trustly-java-client/src/test/resources/requests/withdraw.json @@ -20,6 +20,7 @@ "AddressCountry": "SE", "AddressPostalCode": "SE-11253", "AddressCity": "Stockholm", - "AddressLine1": "Main street 1" + "AddressLine1": "Main street 1", + "ShopperStatement": "Shop!" } } diff --git a/src/test/resources/responses/accountledger.json b/trustly-java-client/src/test/resources/responses/accountledger.json similarity index 100% rename from src/test/resources/responses/accountledger.json rename to trustly-java-client/src/test/resources/responses/accountledger.json diff --git a/src/test/resources/responses/accountpayout.json b/trustly-java-client/src/test/resources/responses/accountpayout.json similarity index 100% rename from src/test/resources/responses/accountpayout.json rename to trustly-java-client/src/test/resources/responses/accountpayout.json diff --git a/src/test/resources/responses/approvewithdrawal.json b/trustly-java-client/src/test/resources/responses/approvewithdrawal.json similarity index 100% rename from src/test/resources/responses/approvewithdrawal.json rename to trustly-java-client/src/test/resources/responses/approvewithdrawal.json diff --git a/src/test/resources/responses/balance.json b/trustly-java-client/src/test/resources/responses/balance.json similarity index 100% rename from src/test/resources/responses/balance.json rename to trustly-java-client/src/test/resources/responses/balance.json diff --git a/src/test/resources/responses/cancelcharge_fail.json b/trustly-java-client/src/test/resources/responses/cancelcharge_fail.json similarity index 100% rename from src/test/resources/responses/cancelcharge_fail.json rename to trustly-java-client/src/test/resources/responses/cancelcharge_fail.json diff --git a/src/test/resources/responses/cancelcharge_ok.json b/trustly-java-client/src/test/resources/responses/cancelcharge_ok.json similarity index 100% rename from src/test/resources/responses/cancelcharge_ok.json rename to trustly-java-client/src/test/resources/responses/cancelcharge_ok.json diff --git a/src/test/resources/responses/charge.json b/trustly-java-client/src/test/resources/responses/charge.json similarity index 100% rename from src/test/resources/responses/charge.json rename to trustly-java-client/src/test/resources/responses/charge.json diff --git a/src/test/resources/responses/denywithdrawal.json b/trustly-java-client/src/test/resources/responses/denywithdrawal.json similarity index 100% rename from src/test/resources/responses/denywithdrawal.json rename to trustly-java-client/src/test/resources/responses/denywithdrawal.json diff --git a/src/test/resources/responses/deposit.json b/trustly-java-client/src/test/resources/responses/deposit.json similarity index 100% rename from src/test/resources/responses/deposit.json rename to trustly-java-client/src/test/resources/responses/deposit.json diff --git a/src/test/resources/responses/error_invalid_parameters.json b/trustly-java-client/src/test/resources/responses/error_invalid_parameters.json similarity index 100% rename from src/test/resources/responses/error_invalid_parameters.json rename to trustly-java-client/src/test/resources/responses/error_invalid_parameters.json diff --git a/src/test/resources/responses/getwithdrawals.json b/trustly-java-client/src/test/resources/responses/getwithdrawals.json similarity index 100% rename from src/test/resources/responses/getwithdrawals.json rename to trustly-java-client/src/test/resources/responses/getwithdrawals.json diff --git a/src/test/resources/responses/refund.json b/trustly-java-client/src/test/resources/responses/refund.json similarity index 100% rename from src/test/resources/responses/refund.json rename to trustly-java-client/src/test/resources/responses/refund.json diff --git a/src/test/resources/responses/registeraccount.json b/trustly-java-client/src/test/resources/responses/registeraccount.json similarity index 100% rename from src/test/resources/responses/registeraccount.json rename to trustly-java-client/src/test/resources/responses/registeraccount.json diff --git a/src/test/resources/responses/selectaccount.json b/trustly-java-client/src/test/resources/responses/selectaccount.json similarity index 100% rename from src/test/resources/responses/selectaccount.json rename to trustly-java-client/src/test/resources/responses/selectaccount.json diff --git a/src/test/resources/responses/settlementreport.json b/trustly-java-client/src/test/resources/responses/settlementreport.json similarity index 100% rename from src/test/resources/responses/settlementreport.json rename to trustly-java-client/src/test/resources/responses/settlementreport.json diff --git a/src/test/resources/responses/withdraw.json b/trustly-java-client/src/test/resources/responses/withdraw.json similarity index 100% rename from src/test/resources/responses/withdraw.json rename to trustly-java-client/src/test/resources/responses/withdraw.json diff --git a/trustly-java-models/pom.xml b/trustly-java-models/pom.xml new file mode 100644 index 0000000..dac25ef --- /dev/null +++ b/trustly-java-models/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + + com.trustly.api + trustly-java + ${revision} + + + trustly-java-models + ${revision} + + + ${project.build.directory}/delombok + + + + + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + provided + + + + org.projectlombok + lombok + 1.18.32 + provided + + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.core + jackson-annotations + + + + jakarta.validation + jakarta.validation-api + provided + + + + + + + + + + org.projectlombok + lombok-maven-plugin + 1.18.20.0 + + + generate-sources + + delombok + + + + + src/main/java + ${delombok.output} + false + UTF-8 + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + generate-delomboked-sources-jar + package + + run + + + + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + attach-delomboked-sources-jar + package + + attach-artifact + + + + + ${project.build.directory}/${project.build.finalName}-sources.jar + jar + sources + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://s01.oss.sonatype.org/ + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + attach-javadoc + + jar + + + + + ${delombok.output} + all,-missing + + + + + + + + diff --git a/trustly-java-models/src/main/java/com/trustly/api/domain/Models.java b/trustly-java-models/src/main/java/com/trustly/api/domain/Models.java new file mode 100644 index 0000000..145cae4 --- /dev/null +++ b/trustly-java-models/src/main/java/com/trustly/api/domain/Models.java @@ -0,0 +1,8634 @@ +package com.trustly.api.domain; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Generated; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.Valid; +import java.util.List; +import java.util.Map; +import lombok.Builder.Default; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.Singular; + +@Generated(value = "omnigen", date = "2024-09-17T06:38:32.432Z") +@SuppressWarnings("unused") +public class Models { + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractAccountNotificationData extends AbstractNotificationRequestData { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid", required = true) + @JsonInclude + @NotNull + private String accountID; + /** + * Whether the account is verified or not. 0 for not verified, 1 for verified. + */ + @JsonProperty(value = "verified", required = true) + @JsonInclude + @NotNull + private StringBoolean verified; + @JsonProperty(value = "attributes") + @Valid + private T attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractAccountNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "clearinghouse") + private String clearingHouse; + /** + * The bank for this account + *

Examples

+ *
    + *
  • SEB
  • + *
  • Skandiabanken
  • + *
+ */ + @JsonProperty(value = "bank") + private String bank; + /** + * A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + *

Examples

+ *
    + *
  • ***4057
  • + *
+ */ + @JsonProperty(value = "descriptor") + private String descriptor; + /** + * The last digits of the bank account number.This can be used for matching against received KYC data from your manual routines. + */ + @JsonProperty(value = "lastdigits") + private String lastdigits; + /** + * An ID that uniquely identifies the account holder. Only present in markets where SSN is applicable. Note: The format of this field will for some countries look different than the example. + *

Examples

+ *
    + *
  • SE198201019876
  • + *
  • 19900501
  • + *
+ */ + @JsonProperty(value = "personid") + private String personID; + /** + * The name of the account holder + *

Examples

+ *
    + *
  • John Doe
  • + *
+ */ + @JsonProperty(value = "name") + private String name; + /** + * The address of the account holder + */ + @JsonProperty(value = "address") + private String address; + /** + * The zipcode of the account holder + *

Examples

+ *
    + *
  • 12345
  • + *
+ */ + @JsonProperty(value = "zipcode") + private String zipcode; + /** + * The city of the account holder + *

Examples

+ *
    + *
  • Examplecity
  • + *
+ */ + @JsonProperty(value = "city") + private String city; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractCancelNotificationData extends AbstractNotificationRequestData { + @JsonProperty(value = "attributes") + @Valid + private T attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractCreditNotificationData extends AbstractNotificationRequestData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + /** + * {@code 98.02} + */ + @JsonProperty(value = "amount") + private double amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "currency") + private String currency; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp") + private String timestamp; + @JsonProperty(value = "attributes") + @Valid + private T attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractCreditNotificationDataAttributes extends AbstractRequestDataAttributes { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractDebitNotificationData extends AbstractNotificationRequestData implements IAdditionalProperties { + /** + *

Examples

+ *
    + *
  • BGN: 100.00
  • + *
  • CZK: 100.00
  • + *
  • DKK: 100.00
  • + *
  • EUR: 100.00
  • + *
  • GBP: 100.00
  • + *
  • HRK: 100.00
  • + *
  • HUF: 100
  • + *
  • NOK: 100.00
  • + *
  • PLN: 100.00
  • + *
  • RON: 100.00
  • + *
  • SEK: 100.00
  • + *
+ */ + @JsonProperty(value = "amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "currency", required = true) + @JsonInclude + private String currency; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid", required = true) + @JsonInclude + @NotNull + private String endUserID; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp", required = true) + @JsonInclude + @NotNull + private String timestamp; + @Singular + @JsonAnySetter + private Map additionalProperties; + @JsonProperty(value = "attributes") + @Valid + private T attributes; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractKYCNotificationData extends AbstractNotificationRequestData { + /** + * Trustly generated unique identifier based on player’s bank account profile*. + * Can be used as an identifier when personid is not available. + *

+ * ***The identifier may change, hence our suggestion is to have a logic that does not include KYCEntityID + *

Examples

+ *
    + *
  • 29a750aa-0bad-4a28-a42d-ffb9a690d93a
  • + *
+ */ + @JsonProperty(value = "kycentityid", required = true) + @JsonInclude + @NotNull + private String kycentityid; + @JsonProperty(value = "attributes") + @Valid + private KYCNotificationDataAttributes attributes; + } + + @Getter + @RequiredArgsConstructor + @Setter + @SuperBuilder + public abstract static class AbstractNotificationRequest { + @JsonProperty(value = "method") + private String method; + } + + @Getter + @RequiredArgsConstructor + @Setter + @SuperBuilder + public abstract static class AbstractNotificationRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "messageid", required = true) + @JsonInclude + @NotNull + private String messageID; + /** + * Unique ID for this notification. Each notification must only be handled once in your system. + */ + @JsonProperty(value = "notificationid", required = true) + @JsonInclude + @NotNull + private String notificationID; + } + + @Getter + @RequiredArgsConstructor + @Setter + @SuperBuilder + public abstract static class AbstractNotificationResponse { + + } + + @Getter + @RequiredArgsConstructor + @Setter + @SuperBuilder + public abstract static class AbstractPendingNotificationData extends AbstractNotificationRequestData { + /** + * {@code 98.02} + */ + @JsonProperty(value = "amount", required = true) + @JsonInclude + @NotNull + private double amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "currency", required = true) + @JsonInclude + private String currency; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp", required = true) + @JsonInclude + @NotNull + private String timestamp; + @JsonProperty(value = "attributes") + @Valid + private AnyAttributes attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AbstractRequestData { + @JsonProperty(value = "Username", required = true) + @JsonInclude + @NotNull + private String username; + @JsonProperty(value = "Password", required = true) + @JsonInclude + @NotNull + private String password; + @JsonProperty(value = "Attributes") + @Valid + private T attributes; + } + + @Getter + @RequiredArgsConstructor + @Setter + @SuperBuilder + public abstract static class AbstractRequestDataAttributes implements IAdditionalProperties { + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountDefaultNotification extends JsonRpcNotification { + public AccountDefaultNotification() { + super("account"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountDefaultNotificationData extends AbstractAccountNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountDefaultNotificationDataAttributes extends AbstractAccountNotificationDataAttributes { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountDefaultNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountDefaultNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountDefaultNotificationResponseResult extends ResponseResult { + public AccountDefaultNotificationResponseResult() { + super.method = "account"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountLedgerRequest extends JsonRpcRequest { + public AccountLedgerRequest() { + super("AccountLedger"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountLedgerRequestData extends AbstractRequestData { + /** + * Date string in the ISO 8601 format (YYYY-MM-DD) + *

Examples

+ *
    + *
  • 2014-04-01
  • + *
+ */ + @JsonProperty(value = "FromDate", required = true) + @JsonInclude + @NotNull + private String fromDate; + /** + * Date string in the ISO 8601 format (YYYY-MM-DD) + *

Examples

+ *
    + *
  • 2014-04-01
  • + *
+ */ + @JsonProperty(value = "ToDate", required = true) + @JsonInclude + @NotNull + private String toDate; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountLedgerRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountLedgerResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountLedgerResponseDataEntry { + /** + * Your userid in our system. + */ + @JsonProperty(value = "userid") + private String userID; + /** + * The datestamp for when this ledger row affected your balance in our system. + */ + @JsonProperty(value = "datestamp") + private String datestamp; + /** + * The globally unique OrderID that resulted in this ledger record. + */ + @JsonProperty(value = "orderid") + private long orderID; + /** + * The name of the bookkeeping account this ledger record belongs to. + */ + @JsonProperty(value = "accountname") + private String accountname; + /** + * Your unique MessageID that you used to create the order that resulted in this ledger record. + */ + @JsonProperty(value = "messageid") + private String messageID; + /** + * A human friendly description of this ledger record. + *

Examples

+ *
    + *
  • CLIENT_FUNDS_SWEDEN_ESSE
  • + *
+ */ + @JsonProperty(value = "transactiontype") + private String transactiontype; + /** + * The currency of the amount in this ledger record. + */ + @JsonProperty(value = "currency") + private String currency; + /** + * The amount your balance in our system was affected with due to this ledger record. May contain a lot of decimals. + */ + @JsonProperty(value = "amount") + private String amount; + /** + * An ID meaning different things for different payment methods, you probably don't need this data. + *

Examples

+ *
    + *
  • 3209647863
  • + *
+ */ + @JsonProperty(value = "gluepayid") + private String gluepayid; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountLedgerResponseResult extends ResponseResult> { + public AccountLedgerResponseResult() { + super.method = "AccountLedger"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountMandateNotification extends JsonRpcNotification { + public AccountMandateNotification() { + super("account"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountMandateNotificationData extends AbstractAccountNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountMandateNotificationDataAttributes extends AbstractAccountNotificationDataAttributes { + /** + * Whether the direct debit mandate is active or not, 1 for active, 0 for non-active. + */ + @JsonProperty(value = "directdebitmandate") + private NumberBoolean directDebitMandate; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "country") + private String country; + /** + * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + *

+ * IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • Sweden: ^[0-9]{4,5}$
  • + *
  • United Kingdom: ^[0-9]{6}$
  • + *
+ */ + @JsonProperty(value = "bankcode") + private String bankcode; + /** + * Name of the account + *

Examples

+ *
    + *
  • Salary account
  • + *
+ */ + @JsonProperty(value = "accountname") + private String accountname; + @JsonProperty(value = "accountholders") + private List accountholders; + /** + * The branch identifier + *

Examples

+ *
    + *
  • 6160
  • + *
  • 6000
  • + *
  • bg
  • + *
  • 123123
  • + *
  • HANDSESS
  • + *
+ */ + @JsonProperty(value = "bankidentifier") + private String bankidentifier; + /** + * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • 6112
  • + *
  • 391124057
  • + *
  • AUSTRIA: ^AT[0-9]{18}$
  • + *
  • BELGIUM: ^BE[0-9]{14}$
  • + *
  • BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$
  • + *
  • CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$
  • + *
  • CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$
  • + *
  • CZECH_REPUBLIC: ^CZ[0-9]{22}$
  • + *
  • DENMARK: ^DK[0-9]{16}$
  • + *
  • ESTONIA: ^EE[0-9]{18}$
  • + *
  • FINLAND: ^FI[0-9]{16}$
  • + *
  • FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$
  • + *
  • GERMANY: ^DE[0-9]{20}$
  • + *
  • GREECE: ^GR[0-9]{25}$
  • + *
  • HUNGARY: ^HU[0-9]{26}$
  • + *
  • IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$
  • + *
  • ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$
  • + *
  • LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$
  • + *
  • LITHUANIA: ^LT[0-9]{18}$
  • + *
  • LUXEMBOURG: ^LU[0-9]{18}$
  • + *
  • MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$
  • + *
  • NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
  • + *
  • NORWAY: ^NO[0-9]{13}$
  • + *
  • POLAND: ^PL[0-9]{26}$
  • + *
  • PORTUGAL: ^PT[0-9]{23}$
  • + *
  • ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$
  • + *
  • SLOVAKIA: ^SK[0-9]{22}$
  • + *
  • SLOVENIA: ^SI56[0-9]{15}$
  • + *
  • SPAIN: ^ES[0-9]{22}$
  • + *
  • SWEDEN:* [0-9]{1,15}$
  • + *
  • UNITED_KINGDOM: ^[0-9]{8}$
  • + *
+ */ + @JsonProperty(value = "accountnumber") + private String accountnumber; + @JsonProperty(value = "accountsource") + private MandateAccountSource accountsource; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountMandateNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountMandateNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountMandateNotificationResponseResult extends ResponseResult { + public AccountMandateNotificationResponseResult() { + super.method = "account"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountNotification extends JsonRpcNotification { + public AccountNotification() { + super("account"); + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountNotificationData { + @JsonValue + private final JsonNode _raw; + @Valid + private AccountDefaultNotificationData _accountDefaultNotificationData; + @Valid + private AccountMandateNotificationData _accountMandateNotificationData; + + @JsonCreator + public AccountNotificationData(JsonNode raw) { + this._raw = raw; + } + + public AccountDefaultNotificationData getAccountDefaultNotificationData(ObjectMapper transformer) throws JsonProcessingException { + if (this._accountDefaultNotificationData != null) { + return this._accountDefaultNotificationData; + } + return this._accountDefaultNotificationData = transformer.treeToValue(this._raw, AccountDefaultNotificationData.class); + } + + public AccountMandateNotificationData getAccountMandateNotificationData(ObjectMapper transformer) throws JsonProcessingException { + if (this._accountMandateNotificationData != null) { + return this._accountMandateNotificationData; + } + return this._accountMandateNotificationData = transformer.treeToValue(this._raw, AccountMandateNotificationData.class); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountNotificationResponseResult extends ResponseResult { + public AccountNotificationResponseResult() { + super.method = "account"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountPayoutRequest extends JsonRpcRequest { + public AccountPayoutRequest() { + super("AccountPayout"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountPayoutRequestData extends AbstractRequestData { + /** + * The URL to which notifications for this payment should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * The AccountID received from an Account notification to which the money shall be sent. + */ + @JsonProperty(value = "AccountID", required = true) + @JsonInclude + @NotNull + private String accountId; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the withdrawal. Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The amount to send. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountPayoutRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement", required = true) + @JsonInclude + @NotNull + private String shopperStatement; + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + /** + * Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @JsonProperty(value = "SenderInformation") + @Valid + private SenderInformation senderInformation; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountPayoutRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountPayoutResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AccountPayoutResponseData { + /** + * The globally unique OrderID the account payout order was assigned in our system. + */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private long orderID; + /** + * "1" if the payout could be accepted and "0" otherwise. + */ + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + private StringBoolean result; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class AccountPayoutResponseResult extends ResponseResult { + public AccountPayoutResponseResult() { + super.method = "AccountPayout"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AckData extends NotificationResponseDataBase implements IAdditionalProperties { + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class AnyAttributes extends AbstractRequestDataAttributes { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ApproveWithdrawalRequest extends JsonRpcRequest { + public ApproveWithdrawalRequest() { + super("ApproveWithdrawal"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ApproveWithdrawalRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private long orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ApproveWithdrawalRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ApproveWithdrawalResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ApproveWithdrawalResponseData { + /** + * The OrderID specified when calling the method. + */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private long orderID; + /** + * 1 if the withdrawal could be approved and 0 otherwise. + */ + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + private StringBoolean result; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ApproveWithdrawalResponseResult extends ResponseResult { + public ApproveWithdrawalResponseResult() { + super.method = "ApproveWithdrawal"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class BalanceRequest extends JsonRpcRequest { + public BalanceRequest() { + super("Balance"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class BalanceRequestData extends AbstractRequestData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class BalanceRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class BalanceResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class BalanceResponseDataEntry { + /** + * The currency + */ + @JsonProperty(value = "currency") + private String currency; + /** + * The balance with 2 decimals + */ + @JsonProperty(value = "balance") + private String balance; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class BalanceResponseResult extends ResponseResult> { + public BalanceResponseResult() { + super.method = "Balance"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelChargeRequest extends JsonRpcRequest { + public CancelChargeRequest() { + super("CancelCharge"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelChargeRequestData extends AbstractRequestData { + /** + * The OrderID of the Charge request that should be canceled. + */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private String orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelChargeRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelChargeResponse extends JsonRpcResponse { + + } + + /** + * 1 if the Charge could be canceled, and 0 otherwise. + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelChargeResponseData extends WithRejection { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelChargeResponseResult extends ResponseResult { + public CancelChargeResponseResult() { + super.method = "CancelCharge"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectCreditNotification extends JsonRpcNotification { + public CancelDirectCreditNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectCreditNotificationData extends AbstractCancelNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectCreditNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * From CancelDirectCreditNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private DirectCreditCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectCreditNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectCreditNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectCreditNotificationResponseResult extends ResponseResult { + public CancelDirectCreditNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateRequest extends JsonRpcRequest { + public CancelDirectDebitMandateRequest() { + super("CancelDirectDebitMandate"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private String orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateResponseData extends WithRejection { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitMandateResponseResult extends ResponseResult { + public CancelDirectDebitMandateResponseResult() { + super.method = "CancelDirectDebitMandate"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitNotification extends JsonRpcNotification { + public CancelDirectDebitNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitNotificationData extends AbstractCancelNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * From CancelDirectDebitNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private DirectDebitCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitNotificationResponseResult extends ResponseResult { + public CancelDirectDebitNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitRequest extends JsonRpcRequest { + public CancelDirectDebitRequest() { + super("CancelDirectDebit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private String orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectDebitResponseData extends WithRejection { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectDebitResponseResult extends ResponseResult { + public CancelDirectDebitResponseResult() { + super.method = "CancelDirectDebit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectPaymentBatchNotification extends JsonRpcNotification { + public CancelDirectPaymentBatchNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectPaymentBatchNotificationData extends AbstractCancelNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectPaymentBatchNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelDirectPaymentBatchNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelDirectPaymentBatchNotificationResponseResult extends ResponseResult { + public CancelDirectPaymentBatchNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelMandateNotification extends JsonRpcNotification { + public CancelMandateNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelMandateNotificationData extends AbstractCancelNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelMandateNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * From CancelMandateNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private CancelMandateNotificationDataAttributesCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + *

Examples

+ *
    + *
  • 123ABC0123
  • + *
+ */ + @JsonProperty(value = "merchantreference") + private String merchantreference; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelMandateNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelMandateNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelMandateNotificationResponseResult extends ResponseResult { + public CancelMandateNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelNotification extends JsonRpcNotification { + public CancelNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelNotificationData extends AbstractCancelNotificationData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp") + private String timestamp; + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + * From CancelRefundDirectDebitNotificationData + *

+ * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + private String refund; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelNotificationResponseResult extends ResponseResult { + public CancelNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotification extends JsonRpcNotification { + public CancelRefundDirectDebitNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotificationData extends AbstractCancelNotificationData { + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + public String getRefund() { + return "1"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * From CancelRefundDirectDebitNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private RefundDirectDebitCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelRefundDirectDebitNotificationResponseResult extends ResponseResult { + public CancelRefundDirectDebitNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelSwishNotification extends JsonRpcNotification { + public CancelSwishNotification() { + super("cancel"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelSwishNotificationData extends AbstractCancelNotificationData { + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp") + private String timestamp; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelSwishNotificationDataAttributes extends AbstractRequestDataAttributes { + @JsonProperty(value = "reason") + private SwishCancelReason reason; + /** + * Description of reason + *

Examples

+ *
    + *
  • User Declined
  • + *
+ */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelSwishNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CancelSwishNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CancelSwishNotificationResponseResult extends ResponseResult { + public CancelSwishNotificationResponseResult() { + super.method = "cancel"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ChargeRequest extends JsonRpcRequest { + public ChargeRequest() { + super("Charge"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ChargeRequestData extends AbstractRequestData { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountID", required = true) + @JsonInclude + @NotNull + private String accountId; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + *

Examples

+ *
    + *
  • BGN: 100.00
  • + *
  • CZK: 100.00
  • + *
  • DKK: 100.00
  • + *
  • EUR: 100.00
  • + *
  • GBP: 100.00
  • + *
  • HRK: 100.00
  • + *
  • HUF: 100
  • + *
  • NOK: 100.00
  • + *
  • PLN: 100.00
  • + *
  • RON: 100.00
  • + *
  • SEK: 100.00
  • + *
+ */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ChargeRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement", required = true) + @JsonInclude + @NotNull + private String shopperStatement; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email", required = true) + @JsonInclude + @NotNull + private String email; + /** + * The date when the funds will be charged from the end user's bank account. If this attribute is not sent, the charge will be attempted as soon as possible. + */ + @JsonProperty(value = "PaymentDate") + private String paymentDate; + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ChargeRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ChargeResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ChargeResponseData extends WithRejection { + @JsonProperty(value = "orderid") + private String orderID; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ChargeResponseResult extends ResponseResult { + public ChargeResponseResult() { + super.method = "Charge"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreateAccountRequest extends JsonRpcRequest { + public CreateAccountRequest() { + super("CreateAccount"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreateAccountRequestData extends AbstractRequestData { + /** + * ID, username, hash or anything uniquely identifying the end-user holding this account. Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "ClearingHouse", required = true) + @JsonInclude + @NotNull + private String clearingHouse; + /** + * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + *

+ * IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • Sweden: ^[0-9]{4,5}$
  • + *
  • United Kingdom: ^[0-9]{6}$
  • + *
+ */ + @JsonProperty(value = "BankNumber", required = true) + @JsonInclude + @NotNull + private String bankNumber; + /** + * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • 6112
  • + *
  • 391124057
  • + *
  • AUSTRIA: ^AT[0-9]{18}$
  • + *
  • BELGIUM: ^BE[0-9]{14}$
  • + *
  • BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$
  • + *
  • CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$
  • + *
  • CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$
  • + *
  • CZECH_REPUBLIC: ^CZ[0-9]{22}$
  • + *
  • DENMARK: ^DK[0-9]{16}$
  • + *
  • ESTONIA: ^EE[0-9]{18}$
  • + *
  • FINLAND: ^FI[0-9]{16}$
  • + *
  • FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$
  • + *
  • GERMANY: ^DE[0-9]{20}$
  • + *
  • GREECE: ^GR[0-9]{25}$
  • + *
  • HUNGARY: ^HU[0-9]{26}$
  • + *
  • IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$
  • + *
  • ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$
  • + *
  • LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$
  • + *
  • LITHUANIA: ^LT[0-9]{18}$
  • + *
  • LUXEMBOURG: ^LU[0-9]{18}$
  • + *
  • MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$
  • + *
  • NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
  • + *
  • NORWAY: ^NO[0-9]{13}$
  • + *
  • POLAND: ^PL[0-9]{26}$
  • + *
  • PORTUGAL: ^PT[0-9]{23}$
  • + *
  • ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$
  • + *
  • SLOVAKIA: ^SK[0-9]{22}$
  • + *
  • SLOVENIA: ^SI56[0-9]{15}$
  • + *
  • SPAIN: ^ES[0-9]{22}$
  • + *
  • SWEDEN:* [0-9]{1,15}$
  • + *
  • UNITED_KINGDOM: ^[0-9]{8}$
  • + *
+ */ + @JsonProperty(value = "AccountNumber", required = true) + @JsonInclude + @NotNull + private String accountNumber; + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreateAccountRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * Recipient address street + *

Examples

+ *
    + *
  • Main Street 1
  • + *
+ */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * Additional address information of the recipient. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The entire shipping address. + * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + *

Examples

+ *
    + *
  • Birgerstreet 14, SE-11411, Stockholm, Sweden
  • + *
+ */ + @JsonProperty(value = "Address") + private String address; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email") + private String email; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreateAccountRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreateAccountResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreateAccountResponseData { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountId") + private int accountId; + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "clearingHouse") + private String clearingHouse; + /** + * The bank for this account + *

Examples

+ *
    + *
  • SEB
  • + *
  • Skandiabanken
  • + *
+ */ + @JsonProperty(value = "bank") + private String bank; + /** + * A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + *

Examples

+ *
    + *
  • ***4057
  • + *
+ */ + @JsonProperty(value = "descriptor") + private String descriptor; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreateAccountResponseResult extends ResponseResult { + public CreateAccountResponseResult() { + super.method = "CreateAccount"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditDirectCreditNotification extends JsonRpcNotification { + public CreditDirectCreditNotification() { + super("credit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectCreditNotificationData extends AbstractCreditNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectCreditNotificationDataAttributes extends AbstractCreditNotificationDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectCreditNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectCreditNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditDirectCreditNotificationResponseResult extends ResponseResult { + public CreditDirectCreditNotificationResponseResult() { + super.method = "credit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditDirectDebitNotification extends JsonRpcNotification { + public CreditDirectDebitNotification() { + super("credit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectDebitNotificationData extends AbstractCreditNotificationData { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectDebitNotificationDataAttributes extends AbstractCreditNotificationDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditDirectDebitNotificationResponseResult extends ResponseResult { + public CreditDirectDebitNotificationResponseResult() { + super.method = "credit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditNotification extends JsonRpcNotification { + public CreditNotification() { + super("credit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditNotificationData extends AbstractCreditNotificationData { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + * From CreditDirectDebitNotificationData + *

+ * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + * From CreditRefundDirectDebitNotificationData + *

+ * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + private String refund; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditNotificationDataAttributes extends AbstractCreditNotificationDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + /** + * From CreditRefundDirectDebitNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private CreditRefundDirectDebitCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + * From CreditRefundDirectDebitNotificationDataAttributes + *

+ * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + * From CreditSwishNotificationDataAttributes + *

+ * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 467123476
  • + *
+ */ + @JsonProperty(value = "payerAlias") + private String payerAlias; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditNotificationResponseResult extends ResponseResult { + public CreditNotificationResponseResult() { + super.method = "credit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotification extends JsonRpcNotification { + public CreditRefundDirectDebitNotification() { + super("credit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotificationData extends AbstractCreditNotificationData { + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + public String getRefund() { + return "1"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotificationDataAttributes extends AbstractCreditNotificationDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + /** + * From CreditRefundDirectDebitNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private CreditRefundDirectDebitCancelReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditRefundDirectDebitNotificationResponseResult extends ResponseResult { + public CreditRefundDirectDebitNotificationResponseResult() { + super.method = "credit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditSwishNotification extends JsonRpcNotification { + public CreditSwishNotification() { + super("credit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditSwishNotificationData extends AbstractCreditNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditSwishNotificationDataAttributes extends AbstractCreditNotificationDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 467123476
  • + *
+ */ + @JsonProperty(value = "payerAlias") + private String payerAlias; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditSwishNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class CreditSwishNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class CreditSwishNotificationResponseResult extends ResponseResult { + public CreditSwishNotificationResponseResult() { + super.method = "credit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitDirectCreditNotification extends JsonRpcNotification { + public DebitDirectCreditNotification() { + super("debit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectCreditNotificationData extends AbstractDebitNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectCreditNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + /** + * From DebitDirectCreditNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private DirectCreditDebitNotificationReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectCreditNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectCreditNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitDirectCreditNotificationResponseResult extends ResponseResult { + public DebitDirectCreditNotificationResponseResult() { + super.method = "debit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitDirectDebitNotification extends JsonRpcNotification { + public DebitDirectDebitNotification() { + super("debit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectDebitNotificationData extends AbstractDebitNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectDebitNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + @JsonProperty(value = "reason") + private DebitDirectDebitNotificationReason reason; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitDirectDebitNotificationResponseResult extends ResponseResult { + public DebitDirectDebitNotificationResponseResult() { + super.method = "debit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitNotification extends JsonRpcNotification { + public DebitNotification() { + super("debit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitNotificationData extends AbstractDebitNotificationData { + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + * From DebitRefundDirectDebitNotificationData + *

+ * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + private String refund; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitNotificationResponseData extends NotificationResponseDataBase { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitNotificationResponseResult extends ResponseResult { + public DebitNotificationResponseResult() { + super.method = "debit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotification extends JsonRpcNotification { + public DebitRefundDirectDebitNotification() { + super("debit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotificationData extends AbstractDebitNotificationData { + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + public String getRefund() { + return "1"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DebitRefundDirectDebitNotificationResponseResult extends ResponseResult { + public DebitRefundDirectDebitNotificationResponseResult() { + super.method = "debit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DenyWithdrawalRequest extends JsonRpcRequest { + public DenyWithdrawalRequest() { + super("DenyWithdrawal"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DenyWithdrawalRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private long orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DenyWithdrawalRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DenyWithdrawalResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DenyWithdrawalResponseData { + /** + * The OrderID specified when calling the method. + */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private long orderID; + /** + * '1' if the refund request is accepted by Trustly's system. If the refund request is not accepted, you will get an error code back in the JsonRpcResponse -> error + */ + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + private StringBoolean result; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DenyWithdrawalResponseResult extends ResponseResult { + public DenyWithdrawalResponseResult() { + super.method = "DenyWithdrawal"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DepositRequest extends JsonRpcRequest { + public DepositRequest() { + super("Deposit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DepositRequestData extends AbstractRequestData implements IAdditionalProperties { + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DepositRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "Country", required = true) + @JsonInclude + @NotNull + private String country; + /** + * The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + */ + @JsonProperty(value = "Locale", required = true) + @JsonInclude + @NotNull + private String locale; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement", required = true) + @JsonInclude + @NotNull + private String shopperStatement; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email", required = true) + @JsonInclude + @NotNull + private String email; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The IP-address of the end-user. + */ + @JsonProperty(value = "IP") + private String ip; + /** + * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "SuccessURL", required = true) + @JsonInclude + @NotNull + private String successUrl; + /** + * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "FailURL", required = true) + @JsonInclude + @NotNull + private String failUrl; + /** + * The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + */ + @JsonProperty(value = "TemplateURL") + private String templateUrl; + /** + * The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + */ + @JsonProperty(value = "URLTarget") + private UrlTarget urlTarget; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + */ + @JsonProperty(value = "UnchangeableNationalIdentificationNumber") + private String unchangeableNationalIdentificationNumber; + /** + * If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + */ + @JsonProperty(value = "URLScheme") + private String urlScheme; + /** + * When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + *

+ * NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + */ + @JsonProperty(value = "ReturnToAppURL") + private String returnToAppUrl; + /** + * iDeal. The iDEAL integration offered by Trustly allows for both iDEAL and Trustly payments on a single integration with all transactions visible in the same AccountLedger. To initiate a new iDEAL payment, add Method = "deposit.bank.netherlands.ideal" to the Deposit attributes. + *

Examples

+ *
    + *
  • deposit.bank.netherlands.ideal
  • + *
+ */ + @JsonProperty(value = "Method") + private String method; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + /** + * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount") + private String amount; + /** + * The ISO 3166-1-alpha-2 code of the shipping address country. + */ + @JsonProperty(value = "ShippingAddressCountry") + private String shippingAddressCountry; + /** + * The postal code of the shipping address. + */ + @JsonProperty(value = "ShippingAddressPostalCode") + private String shippingAddressPostalCode; + /** + * The city of the shipping address. + */ + @JsonProperty(value = "ShippingAddressCity") + private String shippingAddressCity; + /** + * Shipping address street + */ + @JsonProperty(value = "ShippingAddressLine1") + private String shippingAddressLine1; + /** + * Additional shipping address information. + */ + @JsonProperty(value = "ShippingAddressLine2") + private String shippingAddressLine2; + /** + * The entire shipping address. This attribute should only be used if you are unable to provide the shipping address information in the 5 separate attributes: ShippingAddressCountry, ShippingAddressCity, ShippingAddressPostalCode, ShippingAddressLine, ShippingAddressLine + */ + @JsonProperty(value = "ShippingAddress") + private String shippingAddress; + /** + * In addition to the deposit, request a direct debit mandate from the account used for the deposit. 1 enables, 0 disables. The default is disabled. If this attribute is set, additional account notifications might be sent. You can read more about Trustly Direct Debit here, under section 2.1 + */ + @JsonProperty(value = "RequestDirectDebitMandate") + private StringBoolean requestDirectDebitMandate; + /** + * The AccountID received from an account notification which shall be charged in a Trustly Direct Debit deposit. This attribute should only be sent in combination with {"QuickDeposit" : 1} + */ + @JsonProperty(value = "ChargeAccountId") + private String chargeAccountId; + /** + * Set to 1 for Trustly Direct Debit deposits. QuickDeposit should be set set to 1 when the end user attempts a quick deposit, even if ChargeAccountID is not set. You can read more about QuickDeposits here, under section 1.1 and 1.2. + */ + @JsonProperty(value = "QuickDeposit") + private StringBoolean quickDeposit; + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountId") + private String accountId; + /** + * Information about the Payee (ultimate creditor). The burden of identifying who the Payee for any given transaction is lies with the Trustly customer. Required for some merchants and partners. RecipientInformation is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @JsonProperty(value = "RecipientInformation") + @Valid + private RecipientInformation recipientInformation; + /** + * Trustly will send a KYC notification to the merchant’s NotificationURL if the attribute "RequestKYC" : "1" is sent in a Deposit API call. The KYC notification should be expected after the end user has performed a successful login to their bank, and always before a deposit transfer is initiated. + */ + @JsonProperty(value = "RequestKYC") + private StringBoolean requestKyc; + /** + * The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "SuggestedMinAmount") + private String suggestedMinAmount; + /** + * The maximum amount the end-user is allowed to deposit in the currency specified by Currency. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "SuggestedMaxAmount") + private String suggestedMaxAmount; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DepositRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DepositResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DepositResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid") + private String orderID; + /** + * The URL that should be loaded so that the end-user can complete the deposit. + */ + @JsonProperty(value = "url") + private String URL; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DepositResponseResult extends ResponseResult { + public DepositResponseResult() { + super.method = "Deposit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectCreditRequest extends JsonRpcRequest { + public DirectCreditRequest() { + super("DirectCredit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectCreditRequestData extends AbstractRequestData { + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountID", required = true) + @JsonInclude + @NotNull + private String accountId; + /** + * The branch identifier + *

Examples

+ *
    + *
  • 6160
  • + *
  • 6000
  • + *
  • bg
  • + *
  • 123123
  • + *
  • HANDSESS
  • + *
+ */ + @JsonProperty(value = "BankIdentifier") + private String bankIdentifier; + /** + * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • 6112
  • + *
  • 391124057
  • + *
  • AUSTRIA: ^AT[0-9]{18}$
  • + *
  • BELGIUM: ^BE[0-9]{14}$
  • + *
  • BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$
  • + *
  • CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$
  • + *
  • CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$
  • + *
  • CZECH_REPUBLIC: ^CZ[0-9]{22}$
  • + *
  • DENMARK: ^DK[0-9]{16}$
  • + *
  • ESTONIA: ^EE[0-9]{18}$
  • + *
  • FINLAND: ^FI[0-9]{16}$
  • + *
  • FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$
  • + *
  • GERMANY: ^DE[0-9]{20}$
  • + *
  • GREECE: ^GR[0-9]{25}$
  • + *
  • HUNGARY: ^HU[0-9]{26}$
  • + *
  • IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$
  • + *
  • ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$
  • + *
  • LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$
  • + *
  • LITHUANIA: ^LT[0-9]{18}$
  • + *
  • LUXEMBOURG: ^LU[0-9]{18}$
  • + *
  • MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$
  • + *
  • NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
  • + *
  • NORWAY: ^NO[0-9]{13}$
  • + *
  • POLAND: ^PL[0-9]{26}$
  • + *
  • PORTUGAL: ^PT[0-9]{23}$
  • + *
  • ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$
  • + *
  • SLOVAKIA: ^SK[0-9]{22}$
  • + *
  • SLOVENIA: ^SI56[0-9]{15}$
  • + *
  • SPAIN: ^ES[0-9]{22}$
  • + *
  • SWEDEN:* [0-9]{1,15}$
  • + *
  • UNITED_KINGDOM: ^[0-9]{8}$
  • + *
+ */ + @JsonProperty(value = "AccountNumber") + private String accountNumber; + /** + * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount") + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency") + private String currency; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "Country") + private String country; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectCreditRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectCreditResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectCreditResponseData extends WithRejection { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectCreditResponseResult extends ResponseResult { + public DirectCreditResponseResult() { + super.method = "DirectCredit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectDebitMandateRequest extends JsonRpcRequest { + public DirectDebitMandateRequest() { + super("DirectDebitMandate"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitMandateRequestData extends AbstractRequestData { + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitMandateRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountId") + private String accountId; + /** + * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + *

Examples

+ *
    + *
  • 123ABC0123
  • + *
+ */ + @JsonProperty(value = "MerchantReference", required = true) + @JsonInclude + @NotNull + private String merchantReference; + /** + * The country where the mandate is to be created. + */ + @JsonProperty(value = "Country", required = true) + @JsonInclude + @NotNull + private String country; + /** + * The first name of the end user. + * [BACS]: Only mandatory if manual entry should be enabled. + * [Bankgiro]: Mandatory + * [Sepa-DD]: Mandatory + */ + @JsonProperty(value = "Firstname") + private String firstname; + /** + * The last name of the end user. + * [BACS]: Only mandatory if manual entry should be enabled. + * [Bankgiro]: Mandatory + * [Sepa-DD]: Mandatory + */ + @JsonProperty(value = "Lastname") + private String lastname; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email", required = true) + @JsonInclude + @NotNull + private String email; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "SuccessURL", required = true) + @JsonInclude + @NotNull + private String successUrl; + /** + * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "FailURL", required = true) + @JsonInclude + @NotNull + private String failUrl; + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * The national identification number.Format is yyyyMMddxxxx. Only applicable for Bankgiro(SE) + *

+ * [Bankgiro]: To preset the nationalId to use for setting up the mandate. To make the end-user journey smooth, please use this parameter. + */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * Only applicable for Bankgiro(SE) + * [Bankgiro]If the nationalId should be locked to the value of NationalIdentificationNumber, then set this to 1 or omit the parameter (you may set it to 0 as well). + */ + @JsonProperty(value = "UnchangeableNationalIdentificationNumber") + private String unchangeableNationalIdentificationNumber; + /** + * If the payment plan is known in advance, this information is displayed when approving the mandate. + */ + @JsonProperty(value = "PaymentSchedule") + @Valid + private DirectDebitPaymentSchedule paymentSchedule; + /** + * Recipient address street + *

Examples

+ *
    + *
  • Main Street 1
  • + *
+ */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * Additional address information of the recipient. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + /** + * The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + */ + @JsonProperty(value = "Locale") + private String locale; + @JsonProperty(value = "Theme") + private DirectDebitTheme theme; + /** + * When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + *

+ * NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + */ + @JsonProperty(value = "ReturnToAppURL") + private String returnToAppUrl; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement") + private String shopperStatement; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitMandateRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitMandateResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitMandateResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + */ + @JsonProperty(value = "url", required = true) + @JsonInclude + @NotNull + private String URL; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectDebitMandateResponseResult extends ResponseResult { + public DirectDebitMandateResponseResult() { + super.method = "DirectDebitMandate"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. + *

Examples

+ *
    + *
  • 1E2FC19E5E5E4E18916609B7F8911C12
  • + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "reference") + private String reference; + /** + * Statement that appear on the end users bank account + *

Examples

+ *
    + *
  • TRLY80494-1001
  • + *
+ */ + @JsonProperty(value = "statement") + private String statement; + /** + * Description of reason. If Direct Debit Mandate, then this applies when reason is FAILED: BACS ADDACS_1(INSTRUCTION CANCELLED BY PAYER). See https://eu.developers.trustly.com/doc/reference/mdd#description-of-details-eg-failure-details + */ + @JsonProperty(value = "details") + private String details; + /** + * From DebitDirectCreditNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private DebitNotificationReason reason; + } + + /** + * If the payment plan is known in advance, this information is displayed when approving the mandate. + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitPaymentSchedule implements IAdditionalProperties { + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectDebitRequest extends JsonRpcRequest { + public DirectDebitRequest() { + super("DirectDebit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitRequestData extends AbstractRequestData implements IAdditionalProperties { + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountID", required = true) + @JsonInclude + @NotNull + private String accountId; + /** + * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + *

Examples

+ *
    + *
  • 123ABC0123
  • + *
+ */ + @JsonProperty(value = "MerchantReference") + private String merchantReference; + /** + * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitRequestDataAttributes extends AbstractRequestDataAttributes { + @JsonProperty(value = "CollectionType") + private DirectDebitCollectionType collectionType; + /** + * Date string in the ISO 8601 format (YYYY-MM-DD) + *

Examples

+ *
    + *
  • 2014-04-01
  • + *
+ */ + @JsonProperty(value = "PaymentDate") + private String paymentDate; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement") + private String shopperStatement; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectDebitResponseData extends WithRejection implements IAdditionalProperties { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectDebitResponseResult extends ResponseResult { + public DirectDebitResponseResult() { + super.method = "DirectDebit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectPaymentBatchRequest extends JsonRpcRequest { + public DirectPaymentBatchRequest() { + super("DirectPaymentBatch"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectPaymentBatchRequestData extends AbstractRequestData { + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency") + private String currency; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "Country") + private String country; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectPaymentBatchRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * Date string in the ISO 8601 format (YYYY-MM-DD) + *

Examples

+ *
    + *
  • 2014-04-01
  • + *
+ */ + @JsonProperty(value = "PaymentDate") + private String paymentDate; + /** + * The uploaded unique file name on the SFTP server containing the instructions. + *

Examples

+ *
    + *
  • unique-filename.csv
  • + *
+ */ + @JsonProperty(value = "BatchFile") + private String batchFile; + /** + * The MD5 checksum for the file + *

Examples

+ *
    + *
  • 0cdf0945096283b9ba94e42150ba84d8
  • + *
+ */ + @JsonProperty(value = "Checksum") + private String checksum; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectPaymentBatchRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectPaymentBatchResponse extends JsonRpcResponse { + + } + + /** + * 1 if the charge was accepted for processing, 0 otherwise. Note that this is an acceptance of the order, no money has been charged from the account until you receive notifications thereof. + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class DirectPaymentBatchResponseData extends WithRejection { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class DirectPaymentBatchResponseResult extends ResponseResult { + public DirectPaymentBatchResponseResult() { + super.method = "DirectPaymentBatch"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ErrorUnknown extends JsonRpcErrorResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ErrorUnknownError extends JsonRpcError { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class GetWithdrawalsRequest extends JsonRpcRequest { + public GetWithdrawalsRequest() { + super("GetWithdrawals"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class GetWithdrawalsRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private long orderId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class GetWithdrawalsRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class GetWithdrawalsResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class GetWithdrawalsResponseDataEntry { + /** + * Reference code for the withdrawal generated by Trustly. + */ + @JsonProperty(value = "reference", required = true) + @JsonInclude + @NotNull + private String reference; + /** + * Date and time when the withdrawal was last updated. + */ + @JsonProperty(value = "modificationdate", required = true) + @JsonInclude + @NotNull + private String modificationdate; + /** + * OrderID of the withdrawal + */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * Date and time when the withdrawal request was received. + */ + @JsonProperty(value = "datestamp", required = true) + @JsonInclude + @NotNull + private String datestamp; + /** + * The current state of the withdrawal. + * It's important that no logic is built on the merchant side based on any specific transferState. New states can be added, and existing states can be changed or removed without notice. + *

Examples

+ *
    + *
  • EXECUTING
  • + *
  • EXECUTED
  • + *
  • PENDING
  • + *
  • QUEUED
  • + *
  • PREPARING
  • + *
  • PREPARED
  • + *
  • BOUNCED
  • + *
  • ERROR
  • + *
  • FAILED
  • + *
  • RETURNED
  • + *
  • CONFIRMED
  • + *
+ */ + @JsonProperty(value = "transferstate", required = true) + @JsonInclude + @NotNull + private String transferstate; + /** + * The amount of the withdrawal. + */ + @JsonProperty(value = "amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid", required = true) + @JsonInclude + @NotNull + private String accountID; + /** + * The currency of the withdrawal. + */ + @JsonProperty(value = "currency", required = true) + @JsonInclude + @NotNull + private String currency; + /** + * The estimated date and time for when the funds will be available on the receiving bank account. If this information is not available it will be null. + */ + @JsonProperty(value = "eta") + private String eta; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class GetWithdrawalsResponseResult extends ResponseResult> { + public GetWithdrawalsResponseResult() { + super.method = "GetWithdrawals"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateRequest extends JsonRpcRequest { + public ImportDirectDebitMandateRequest() { + super("ImportDirectDebitMandate"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateRequestData extends AbstractRequestData { + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "AccountID") + private String accountId; + /** + * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + *

Examples

+ *
    + *
  • 123ABC0123
  • + *
+ */ + @JsonProperty(value = "MerchantReference", required = true) + @JsonInclude + @NotNull + private String merchantReference; + @JsonProperty(value = "ImportType", required = true) + @JsonInclude + @NotNull + private DirectDebitImportType importType; + /** + * The country where the mandate is to be created. + */ + @JsonProperty(value = "Country", required = true) + @JsonInclude + @NotNull + private String country; + /** + * The first name of the end user. + * [BACS]: Only mandatory if manual entry should be enabled. + * [Bankgiro]: Mandatory + * [Sepa-DD]: Mandatory + */ + @JsonProperty(value = "Firstname") + private String firstname; + /** + * The last name of the end user. + * [BACS]: Only mandatory if manual entry should be enabled. + * [Bankgiro]: Mandatory + * [Sepa-DD]: Mandatory + */ + @JsonProperty(value = "Lastname") + private String lastname; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email", required = true) + @JsonInclude + @NotNull + private String email; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement") + private String shopperStatement; + /** + * The national identification number.Format is yyyyMMddxxxx. Only applicable for Bankgiro(SE) + *

+ * [Bankgiro]: To preset the nationalId to use for setting up the mandate. To make the end-user journey smooth, please use this parameter. + */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * [BACS]:If flat and building is available, then use that for this field. If there's no flat/building at all, then use the street and number. Note that without AddressLine1, manual entry will be disabled. + * [Bankgiro]: Not mandatory + * [SepaDD]: Mandatory + */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * [BACS]:If there are flat and building information, then use addressLine2 for the street and number. Note that without AddressLine1, manual entry will be disabled. + * [Bankgiro]: Not mandatory + * [SepaDD]: Optional and depends on the country if needed. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateResponseData extends WithRejection { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class ImportDirectDebitMandateResponseResult extends ResponseResult { + public ImportDirectDebitMandateResponseResult() { + super.method = "ImportDirectDebitMandate"; + } + } + + /** + * Generic class to describe the JsonRpc error inside an error response + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcError { + @Default + @JsonProperty(value = "code") + private int code = -1; + @Default + @JsonProperty(value = "message") + private String message = "Unknown Error"; + @JsonProperty(value = "error") + @Valid + private JsonRpcErrorError error; + + @JsonProperty(value = "name") + public String getName() { + return "JSONRPCError"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcErrorError extends ResponseResult implements IAdditionalProperties { + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcErrorErrorData implements IAdditionalProperties { + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + /** + * Generic class to describe the JsonRpc error response package + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcErrorResponse { + @JsonProperty(value = "error", required = true) + @JsonInclude + @NotNull + @Valid + private ErrorUnknownError error; + + @JsonProperty(value = "version") + public String getVersion() { + return "1.1"; + } + } + + /** + * Generic class to describe the JsonRpc callback package + */ + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class JsonRpcNotification> { + @JsonProperty(value = "method", required = true) + @JsonInclude + @NotNull + private final String method; + @JsonProperty(value = "params") + @Valid + private TParams params; + + public JsonRpcNotification(@JsonProperty(value = "method", required = true) String method) { + this.method = method; + } + + @JsonProperty(value = "version") + public String getVersion() { + return "1.1"; + } + } + + /** + * Generic class to describe the JsonRpc callback params + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcNotificationParams { + /** + * The signature that the Trustly server generated, which you can verify against with our public key + */ + @JsonProperty(value = "signature", required = true) + @JsonInclude + @NotNull + private String signature; + /** + * The unique identifier for this request + */ + @JsonProperty(value = "uuid", required = true) + @JsonInclude + @NotNull + private String UUID; + @JsonProperty(value = "data", required = true) + @JsonInclude + @NotNull + @Valid + private T data; + } + + /** + * Generic class to describe the JsonRpc request package + */ + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class JsonRpcRequest>> { + @JsonProperty(value = "method", required = true) + @JsonInclude + @NotNull + private final String method; + @JsonProperty(value = "params") + @Valid + private TParams params; + + public JsonRpcRequest(@JsonProperty(value = "method", required = true) String method) { + this.method = method; + } + + @JsonProperty(value = "version") + public String getVersion() { + return "1.1"; + } + } + + /** + * Generic class to describe the JsonRpc request params + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcRequestParams> { + /** + * The signature which validates your request to the Trustly server + */ + @JsonProperty(value = "Signature", required = true) + @JsonInclude + @NotNull + private String signature; + /** + * The unique identifier for this request + */ + @JsonProperty(value = "UUID", required = true) + @JsonInclude + @NotNull + private String uuid; + @JsonProperty(value = "Data", required = true) + @JsonInclude + @NotNull + @Valid + private T data; + } + + /** + * Generic class to describe the JsonRpc response package + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class JsonRpcResponse> { + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + @Valid + private T result; + + @JsonProperty(value = "version") + public String getVersion() { + return "1.1"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCAbortNotificationData extends AbstractKYCNotificationData { + @JsonProperty(value = "abort", required = true) + @JsonInclude + @NotNull + private StringBoolean abort; + /** + *

Examples

+ *
    + *
  • unverified
  • + *
  • underage
  • + *
+ */ + @JsonProperty(value = "abortmessage", required = true) + @JsonInclude + @NotNull + private String abortmessage; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCDefaultNotificationData extends AbstractKYCNotificationData { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class KYCNotification extends JsonRpcNotification { + public KYCNotification() { + super("kyc"); + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class KYCNotificationData { + @JsonValue + private final JsonNode _raw; + @Valid + private KYCDefaultNotificationData _kycDefaultNotificationData; + @Valid + private KYCAbortNotificationData _kycAbortNotificationData; + + @JsonCreator + public KYCNotificationData(JsonNode raw) { + this._raw = raw; + } + + public KYCDefaultNotificationData getKycDefaultNotificationData(ObjectMapper transformer) throws JsonProcessingException { + if (this._kycDefaultNotificationData != null) { + return this._kycDefaultNotificationData; + } + return this._kycDefaultNotificationData = transformer.treeToValue(this._raw, KYCDefaultNotificationData.class); + } + + public KYCAbortNotificationData getKycAbortNotificationData(ObjectMapper transformer) throws JsonProcessingException { + if (this._kycAbortNotificationData != null) { + return this._kycAbortNotificationData; + } + return this._kycAbortNotificationData = transformer.treeToValue(this._raw, KYCAbortNotificationData.class); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCNotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * An ID that uniquely identifies the account holder. Only present in markets where SSN is applicable. Note: The format of this field will for some countries look different than the example. + *

Examples

+ *
    + *
  • SE198201019876
  • + *
  • 19900501
  • + *
+ */ + @JsonProperty(value = "personid", required = true) + @JsonInclude + @NotNull + private String personID; + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "lastname", required = true) + @JsonInclude + private String lastname; + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "dob", required = true) + @JsonInclude + @NotNull + private String dob; + /** + * Recipient address street + *

Examples

+ *
    + *
  • Main Street 1
  • + *
+ */ + @JsonProperty(value = "street", required = true) + @JsonInclude + @NotNull + private String street; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "zipcode", required = true) + @JsonInclude + @NotNull + private String zipcode; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "city", required = true) + @JsonInclude + @NotNull + private String city; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "country", required = true) + @JsonInclude + @NotNull + private String country; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class KYCNotificationResponseData extends NotificationResponseDataBase { + /** + *

Examples

+ *
    + *
  • BGN: 100.00
  • + *
  • CZK: 100.00
  • + *
  • DKK: 100.00
  • + *
  • EUR: 100.00
  • + *
  • GBP: 100.00
  • + *
  • HRK: 100.00
  • + *
  • HUF: 100
  • + *
  • NOK: 100.00
  • + *
  • PLN: 100.00
  • + *
  • RON: 100.00
  • + *
  • SEK: 100.00
  • + *
+ */ + @JsonProperty(value = "limit") + private String limit; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class KYCNotificationResponseResult extends ResponseResult { + public KYCNotificationResponseResult() { + super.method = "kyc"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class MerchantSettlementRequest extends JsonRpcRequest { + public MerchantSettlementRequest() { + super("MerchantSettlement"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class MerchantSettlementRequestData extends AbstractRequestData { + /** + * Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The amount to send. See format in Handling currencies. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The currency of the amount to send. + */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + @NotNull + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class MerchantSettlementRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class MerchantSettlementResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class MerchantSettlementResponseData implements IAdditionalProperties { + /** + * The unique reference generated for the settlement. + */ + @JsonProperty(value = "reference", required = true) + @JsonInclude + @NotNull + private String reference; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class MerchantSettlementResponseResult extends ResponseResult { + public MerchantSettlementResponseResult() { + super.method = "MerchantSettlement"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class NotificationDataAttributes extends AbstractRequestDataAttributes { + /** + * Description of reason + *

Examples

+ *
    + *
  • User Declined
  • + *
+ */ + @JsonProperty(value = "details") + private String details; + /** + * From CancelMandateNotificationDataAttributes + */ + @JsonProperty(value = "reason") + private CancelReason reason; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + * From CancelMandateNotificationDataAttributes + *

+ * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + * From CancelMandateNotificationDataAttributes + *

+ * This parameter in a way identifies the mandate you are to setup. If it's already used, you will receive an error, ERROR_MERCHANT_REFERENCE_ALREADY_EXISTS + * which basically informs you that there's already a mandate with that reference. + *

+ * [BACS]: The unique mandate reference. 6 - 10 characters consisting of A-Z and 0-9. Can not begin with DDIC and neither consists of the same characters, eg. AAAAAAA. + * [Bankgiro]: The unique mandate reference. This must be numeric and unique for the payer, eg nationalId or similar can be used. Format needs to follow regexp [1-9][0-9]{5-15} + * [SEPA-DD]: The unique mandate reference. This must be unique for the end-user for you as a merchant. Format needs to follow regexp [0-9,a-z,A-Z]{10-35} + *

Examples

+ *
    + *
  • 123ABC0123
  • + *
+ */ + @JsonProperty(value = "merchantreference") + private String merchantreference; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class NotificationResponseDataBase { + @JsonProperty(value = "message") + private String message; + @JsonProperty(value = "status", required = true) + @JsonInclude + @NotNull + @Valid + private T status; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PayoutConfirmationNotification extends JsonRpcNotification { + public PayoutConfirmationNotification() { + super("payoutconfirmation"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutConfirmationNotificationData extends AbstractNotificationRequestData { + /** + * {@code 98.02} + */ + @JsonProperty(value = "amount", required = true) + @JsonInclude + @NotNull + private double amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "currency", required = true) + @JsonInclude + private String currency; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid", required = true) + @JsonInclude + @NotNull + private String endUserID; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp", required = true) + @JsonInclude + @NotNull + private String timestamp; + @JsonProperty(value = "attributes") + @Valid + private AnyAttributes attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutConfirmationNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutConfirmationNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PayoutConfirmationNotificationResponseResult extends ResponseResult { + public PayoutConfirmationNotificationResponseResult() { + super.method = "payoutconfirmation"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PayoutFailedNotification extends JsonRpcNotification { + public PayoutFailedNotification() { + super("payoutfailed"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutFailedNotificationData extends AbstractNotificationRequestData { + /** + * {@code 98.02} + */ + @JsonProperty(value = "amount", required = true) + @JsonInclude + @NotNull + private double amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "currency", required = true) + @JsonInclude + private String currency; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid", required = true) + @JsonInclude + @NotNull + private String endUserID; + /** + * The time of the transaction and the GMT offset (+01 means GMT + 1 hours). + *

Examples

+ *
    + *
  • 2014-01-30 13:28:45.652299+01
  • + *
  • 2014-03-31 11:50:06.46106+00
  • + *
+ */ + @JsonProperty(value = "timestamp", required = true) + @JsonInclude + @NotNull + private String timestamp; + /** + * Short code of the error + *

Examples

+ *
    + *
  • incorrect_account_number
  • + *
+ */ + @JsonProperty(value = "errorcode") + private String errorcode; + /** + * Description of the error + *

Examples

+ *
    + *
  • Format of the account number specified is not correct
  • + *
+ */ + @JsonProperty(value = "errormessage") + private String errormessage; + @JsonProperty(value = "attributes") + @Valid + private AnyAttributes attributes; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutFailedNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PayoutFailedNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PayoutFailedNotificationResponseResult extends ResponseResult { + public PayoutFailedNotificationResponseResult() { + super.method = "payoutfailed"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectCreditNotification extends JsonRpcNotification { + public PendingDirectCreditNotification() { + super("pending"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectCreditNotificationData extends AbstractPendingNotificationData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectCreditNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectCreditNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectCreditNotificationResponseResult extends ResponseResult { + public PendingDirectCreditNotificationResponseResult() { + super.method = "pending"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectDebitNotification extends JsonRpcNotification { + public PendingDirectDebitNotification() { + super("pending"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectDebitNotificationData extends AbstractPendingNotificationData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * The expected payment date for the debit. Note that this gives you an indication if the paymentDate you submitted has been adjusted eg due to a bank holiday. + * From PendingDirectDebitNotificationData + *

+ * The expected payment date for the debit. Note that this gives you an indication if the paymentDate you submitted has been adjusted eg due to a bank holiday. + */ + @JsonProperty(value = "paymentdate") + private String paymentdate; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectDebitNotificationResponseResult extends ResponseResult { + public PendingDirectDebitNotificationResponseResult() { + super.method = "pending"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectPaymentBatchNotification extends JsonRpcNotification { + public PendingDirectPaymentBatchNotification() { + super("pending"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectPaymentBatchNotificationData extends AbstractPendingNotificationData { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectPaymentBatchNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingDirectPaymentBatchNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingDirectPaymentBatchNotificationResponseResult extends ResponseResult { + public PendingDirectPaymentBatchNotificationResponseResult() { + super.method = "pending"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingNotification extends JsonRpcNotification { + public PendingNotification() { + super("pending"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingNotificationData extends AbstractPendingNotificationData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + * From PendingDirectDebitNotificationData + *

+ * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * The expected payment date for the debit. Note that this gives you an indication if the paymentDate you submitted has been adjusted eg due to a bank holiday. + * From PendingDirectDebitNotificationData + *

+ * The expected payment date for the debit. Note that this gives you an indication if the paymentDate you submitted has been adjusted eg due to a bank holiday. + */ + @JsonProperty(value = "paymentdate") + private String paymentdate; + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + * From PendingRefundDirectDebitNotificationData + *

+ * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + private String refund; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingNotificationResponseResult extends ResponseResult { + public PendingNotificationResponseResult() { + super.method = "pending"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingRefundDirectDebitNotification extends JsonRpcNotification { + public PendingRefundDirectDebitNotification() { + super("pending"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingRefundDirectDebitNotificationData extends AbstractPendingNotificationData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "enduserid") + private String endUserID; + + /** + * Flag indicating that this is for Direct Debit refund. Note that this flag is not sent unless it's for a refund. Only value will be 1. + */ + @JsonProperty(value = "refund") + public String getRefund() { + return "1"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingRefundDirectDebitNotificationParams extends JsonRpcNotificationParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class PendingRefundDirectDebitNotificationResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class PendingRefundDirectDebitNotificationResponseResult extends ResponseResult { + public PendingRefundDirectDebitNotificationResponseResult() { + super.method = "pending"; + } + } + + /** + * Information about the Payee (ultimate creditor). The burden of identifying who the Payee for any given transaction is lies with the Trustly customer. Required for some merchants and partners. RecipientInformation is mandatory to send for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RecipientInformation extends RecipientOrSenderInformation { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RecipientOrSenderInformation { + /** + * Partytype can be PERSON or ORGANISATION (if the recipient or ultimate debtor is an organisation/company). + */ + @JsonProperty(value = "Partytype", required = true) + @JsonInclude + @NotNull + private PartyTypeKind partytype; + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + /** + * The ISO 3166-1-alpha-2 code of the country that the recipient resides in. + */ + @JsonProperty(value = "CountryCode", required = true) + @JsonInclude + @NotNull + private String countryCode; + /** + * Payment account number or an alternative consistent unique identifier (e.g.customer number). Note: this is not a transaction ID or similar. This identifier must stay consistent across all transactions relating to this recipient (payee). + */ + @JsonProperty(value = "CustomerID") + private String customerId; + /** + * Full address of the recipient, excluding the country. + */ + @JsonProperty(value = "Address") + private String address; + /** + * Date of birth (YYYY-MM-DD, ISO 8601) of the beneficiary, or organisational number for the organisation. + *

+ * Date string in the ISO 8601 format (YYYY-MM-DD) + *

Examples

+ *
    + *
  • 2014-04-01
  • + *
+ */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RefundDirectDebitRequest extends JsonRpcRequest { + public RefundDirectDebitRequest() { + super("RefundDirectDebit"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundDirectDebitRequestData extends AbstractRequestData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private long orderId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundDirectDebitRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundDirectDebitResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundDirectDebitResponseData extends WithRejection { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RefundDirectDebitResponseResult extends ResponseResult { + public RefundDirectDebitResponseResult() { + super.method = "RefundDirectDebit"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RefundRequest extends JsonRpcRequest { + public RefundRequest() { + super("Refund"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundRequestData extends AbstractRequestData implements IAdditionalProperties { + /** + * The OrderID of the initial deposit. + */ + @JsonProperty(value = "OrderID", required = true) + @JsonInclude + @NotNull + private String orderId; + /** + * The amount to refund the customer with exactly two decimals. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The currency of the amount to refund the customer. + */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + @NotNull + private String currency; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RefundResponseData { + /** + * The OrderID specified when calling the method. + */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * "1" if the refund request is accepted by Trustly's system. If the refund request is not accepted, you will get an error code back in JsonRpcResponse -> error. + */ + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + private StringBoolean result; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RefundResponseResult extends ResponseResult { + public RefundResponseResult() { + super.method = "Refund"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RegisterAccountPayoutRequest extends JsonRpcRequest { + public RegisterAccountPayoutRequest() { + super("RegisterAccountPayout"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountPayoutRequestData extends AbstractRequestData implements IAdditionalProperties { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "ClearingHouse", required = true) + @JsonInclude + @NotNull + private String clearingHouse; + /** + * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + *

+ * IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • Sweden: ^[0-9]{4,5}$
  • + *
  • United Kingdom: ^[0-9]{6}$
  • + *
+ */ + @JsonProperty(value = "BankNumber", required = true) + @JsonInclude + @NotNull + private String bankNumber; + /** + * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • 6112
  • + *
  • 391124057
  • + *
  • AUSTRIA: ^AT[0-9]{18}$
  • + *
  • BELGIUM: ^BE[0-9]{14}$
  • + *
  • BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$
  • + *
  • CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$
  • + *
  • CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$
  • + *
  • CZECH_REPUBLIC: ^CZ[0-9]{22}$
  • + *
  • DENMARK: ^DK[0-9]{16}$
  • + *
  • ESTONIA: ^EE[0-9]{18}$
  • + *
  • FINLAND: ^FI[0-9]{16}$
  • + *
  • FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$
  • + *
  • GERMANY: ^DE[0-9]{20}$
  • + *
  • GREECE: ^GR[0-9]{25}$
  • + *
  • HUNGARY: ^HU[0-9]{26}$
  • + *
  • IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$
  • + *
  • ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$
  • + *
  • LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$
  • + *
  • LITHUANIA: ^LT[0-9]{18}$
  • + *
  • LUXEMBOURG: ^LU[0-9]{18}$
  • + *
  • MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$
  • + *
  • NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
  • + *
  • NORWAY: ^NO[0-9]{13}$
  • + *
  • POLAND: ^PL[0-9]{26}$
  • + *
  • PORTUGAL: ^PT[0-9]{23}$
  • + *
  • ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$
  • + *
  • SLOVAKIA: ^SK[0-9]{22}$
  • + *
  • SLOVENIA: ^SI56[0-9]{15}$
  • + *
  • SPAIN: ^ES[0-9]{22}$
  • + *
  • SWEDEN:* [0-9]{1,15}$
  • + *
  • UNITED_KINGDOM: ^[0-9]{8}$
  • + *
+ */ + @JsonProperty(value = "AccountNumber", required = true) + @JsonInclude + @NotNull + private String accountNumber; + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * Your unique ID for the payout. If the MessageID is a previously initiated P2P order then the payout will be attached to that P2P order and the amount must be equal to or lower than the previously deposited amount. + */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The amount to send with exactly two decimals. Only digits. Use dot (.) as decimal separator. If the end-user holds a balance in the merchant's system then the amount must have been deducted from that balance before calling this method. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountPayoutRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement", required = true) + @JsonInclude + @NotNull + private String shopperStatement; + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + /** + * Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @JsonProperty(value = "SenderInformation") + @Valid + private SenderInformation senderInformation; + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * Recipient address street + *

Examples

+ *
    + *
  • Main Street 1
  • + *
+ */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * Additional address information of the recipient. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The entire shipping address. + * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + *

Examples

+ *
    + *
  • Birgerstreet 14, SE-11411, Stockholm, Sweden
  • + *
+ */ + @JsonProperty(value = "Address") + private String address; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email") + private String email; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountPayoutRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountPayoutResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountPayoutResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private long orderID; + /** + * 1 if the payout could be accepted and 0 otherwise. + */ + @JsonProperty(value = "result", required = true) + @JsonInclude + @NotNull + private NumberBoolean result; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RegisterAccountPayoutResponseResult extends ResponseResult { + public RegisterAccountPayoutResponseResult() { + super.method = "RegisterAccountPayout"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RegisterAccountRequest extends JsonRpcRequest { + public RegisterAccountRequest() { + super("RegisterAccount"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountRequestData extends AbstractRequestData { + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID") + private String endUserId; + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "ClearingHouse", required = true) + @JsonInclude + @NotNull + private String clearingHouse; + /** + * The bank number identifying the end-user's bank in the given clearing house. For bank accounts in IBAN format you should just provide an empty string (""). For non-IBAN format, see examples. The BankNumber for Swedish bank accounts should be the local "clearing number", and the AccountNumber parameter should contain the rest of the account number. Most Swedish banks have a 4-digit clearing number, but a 5-digit clearing number is used for Swedbank accounts when the clearing number starts with "8". Nordea accounts where the account number is the same as the person's national identification number always has "3300" as the clearing number. + *

+ * IBAN for Swedish bank accounts is supported upon request. When making API calls with Swedish IBAN, ensure to include the Clearinghouse attribute as "IBAN" instead of "SWEDEN". See more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • Sweden: ^[0-9]{4,5}$
  • + *
  • United Kingdom: ^[0-9]{6}$
  • + *
+ */ + @JsonProperty(value = "BankNumber", required = true) + @JsonInclude + @NotNull + private String bankNumber; + /** + * The account number, identifying the end-user's account in the bank. Can be either IBAN or country-specific format, see examples or read more at https://developers.trustly.com/emea/docs/registeraccount + *

Examples

+ *
    + *
  • 6112
  • + *
  • 391124057
  • + *
  • AUSTRIA: ^AT[0-9]{18}$
  • + *
  • BELGIUM: ^BE[0-9]{14}$
  • + *
  • BULGARIA: ^BG[0-9]{2}[A-Z]{4}[0-9]{4}[0-9]{2}[A-Z0-9]{8}$
  • + *
  • CROATIA: ^HR[0-9]{2}[0-9]{7}[0-9]{10}$
  • + *
  • CYPRUS: ^CY[0-9]{10}[0-9A-Z]{16}$
  • + *
  • CZECH_REPUBLIC: ^CZ[0-9]{22}$
  • + *
  • DENMARK: ^DK[0-9]{16}$
  • + *
  • ESTONIA: ^EE[0-9]{18}$
  • + *
  • FINLAND: ^FI[0-9]{16}$
  • + *
  • FRANCE: ^FR[0-9]{12}[0-9A-Z]{11}[0-9]{2}$
  • + *
  • GERMANY: ^DE[0-9]{20}$
  • + *
  • GREECE: ^GR[0-9]{25}$
  • + *
  • HUNGARY: ^HU[0-9]{26}$
  • + *
  • IRELAND: ^IE[0-9]{2}[A-Z]{4}[0-9]{14}$
  • + *
  • ITALY: ^IT[0-9]{2}[A-Z][0-9]{10}[0-9A-Z]{12}$
  • + *
  • LATVIA: ^LV[0-9]{2}[A-Z]{4}[0-9A-Z]{13}$
  • + *
  • LITHUANIA: ^LT[0-9]{18}$
  • + *
  • LUXEMBOURG: ^LU[0-9]{18}$
  • + *
  • MALTA: ^MT[0-9]{2}[A-Z]{4}[0-9]{5}[0-9A-Z]{18}$
  • + *
  • NETHERLANDS: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
  • + *
  • NORWAY: ^NO[0-9]{13}$
  • + *
  • POLAND: ^PL[0-9]{26}$
  • + *
  • PORTUGAL: ^PT[0-9]{23}$
  • + *
  • ROMANIA: ^RO[0-9]{2}[A-Z]{4}[0-9A-Z]{16}$
  • + *
  • SLOVAKIA: ^SK[0-9]{22}$
  • + *
  • SLOVENIA: ^SI56[0-9]{15}$
  • + *
  • SPAIN: ^ES[0-9]{22}$
  • + *
  • SWEDEN:* [0-9]{1,15}$
  • + *
  • UNITED_KINGDOM: ^[0-9]{8}$
  • + *
+ */ + @JsonProperty(value = "AccountNumber", required = true) + @JsonInclude + @NotNull + private String accountNumber; + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The entire shipping address. + * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + *

Examples

+ *
    + *
  • Birgerstreet 14, SE-11411, Stockholm, Sweden
  • + *
+ */ + @JsonProperty(value = "Address") + private String address; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email") + private String email; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class RegisterAccountResponseData implements IAdditionalProperties { + /** + * The globally unique AccountID the account was assigned in our system. The AccountID of a returning customer. Allows for a quicker payment experience in some markets, see Trustly Express. + *

Examples

+ *
    + *
  • 1234567890
  • + *
  • 7653385737
  • + *
+ */ + @JsonProperty(value = "accountid") + private String accountID; + /** + * The clearing house of the end-user's bank account. Typically the name of a country in uppercase letters. See examples or table at https://developers.trustly.com/emea/docs/registeraccount. + *

Examples

+ *
    + *
  • AUSTRIA
  • + *
  • BELGIUM
  • + *
  • BULGARIA
  • + *
  • CROATIA
  • + *
  • CYPRUS
  • + *
  • CZECH_REPUBLIC
  • + *
  • DENMARK
  • + *
  • ESTONIA
  • + *
  • FINLAND
  • + *
  • FRANCE
  • + *
  • GERMANY
  • + *
  • GREECE
  • + *
  • HUNGARY
  • + *
  • IRELAND
  • + *
  • ITALY
  • + *
  • LATVIA
  • + *
  • LITHUANIA
  • + *
  • LUXEMBOURG
  • + *
  • MALTA
  • + *
  • NETHERLANDS
  • + *
  • NORWAY
  • + *
  • POLAND
  • + *
  • PORTUGAL
  • + *
  • ROMANIA
  • + *
  • SLOVAKIA
  • + *
  • SLOVENIA
  • + *
  • SPAIN
  • + *
  • SWEDEN
  • + *
  • UNITED_KINGDOM
  • + *
+ */ + @JsonProperty(value = "clearinghouse") + private String clearingHouse; + /** + * The bank for this account + *

Examples

+ *
    + *
  • SEB
  • + *
  • Skandiabanken
  • + *
+ */ + @JsonProperty(value = "bank") + private String bank; + /** + * A text that is safe to show the enduser for identifying the account. Do not parse this text since it will be a different format for different accounts. + *

Examples

+ *
    + *
  • ***4057
  • + *
+ */ + @JsonProperty(value = "descriptor") + private String descriptor; + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class RegisterAccountResponseResult extends ResponseResult { + public RegisterAccountResponseResult() { + super.method = "RegisterAccount"; + } + } + + @SuperBuilder + @Jacksonized + @Getter + @RequiredArgsConstructor + @Setter + public static class ResponseResult { + @JsonProperty(value = "signature", required = true) + @JsonInclude + @NotNull + private String signature; + @JsonProperty(value = "uuid", required = true) + @JsonInclude + @NotNull + private String UUID; + @JsonProperty(value = "data", required = true) + @JsonInclude + @NotNull + @Valid + private TData data; + @JsonProperty(value = "method", required = true) + @JsonInclude + @NotNull + private String method; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SelectAccountRequest extends JsonRpcRequest { + public SelectAccountRequest() { + super("SelectAccount"); + } + } + + /** + * https://eu.developers.trustly.com/doc/reference/selectaccount + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SelectAccountRequestData extends AbstractRequestData { + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SelectAccountRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "Country", required = true) + @JsonInclude + @NotNull + private String country; + /** + * The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + */ + @JsonProperty(value = "Locale", required = true) + @JsonInclude + @NotNull + private String locale; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement") + private String shopperStatement; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email") + private String email; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The IP-address of the end-user. + */ + @JsonProperty(value = "IP") + private String ip; + /** + * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "SuccessURL", required = true) + @JsonInclude + @NotNull + private String successUrl; + /** + * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "FailURL", required = true) + @JsonInclude + @NotNull + private String failUrl; + /** + * The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + */ + @JsonProperty(value = "TemplateURL") + private String templateUrl; + /** + * The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + */ + @JsonProperty(value = "URLTarget") + private UrlTarget urlTarget; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + */ + @JsonProperty(value = "UnchangeableNationalIdentificationNumber") + private String unchangeableNationalIdentificationNumber; + /** + * If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + */ + @JsonProperty(value = "URLScheme") + private String urlScheme; + /** + * When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + *

+ * NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + */ + @JsonProperty(value = "ReturnToAppURL") + private String returnToAppUrl; + /** + * Only for Trustly Direct Debit. Request a direct debit mandate from the selected account. 1 or 0. See section "Direct Debit Mandates" for details. If this is set to 1, then email is required. + */ + @JsonProperty(value = "RequestDirectDebitMandate") + private NumberBoolean requestDirectDebitMandate; + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SelectAccountRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SelectAccountResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SelectAccountResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the charge. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid") + private long orderID; + /** + * The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + */ + @JsonProperty(value = "url") + private String URL; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SelectAccountResponseResult extends ResponseResult { + public SelectAccountResponseResult() { + super.method = "SelectAccount"; + } + } + + /** + * Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SenderInformation extends RecipientOrSenderInformation { + + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SettlementReportRequest extends JsonRpcRequest { + public SettlementReportRequest() { + super("SettlementReport"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportRequestData extends AbstractRequestData { + /** + * If the value is specified (i.e. not "null"), the system will only search for a settlement executed in that particular currency. If unspecified, settlements executed in any currency are included in the report. + *

+ * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + /** + * The date when the settlement was processed. + */ + @JsonProperty(value = "SettlementDate", required = true) + @JsonInclude + @NotNull + private String settlementDate; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * Required. The APIVersion. Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants. + */ + @JsonProperty(value = "APIVersion", required = true) + @JsonInclude + @NotNull + private SettlementReportRequestDataAttributesApiVersion apiVersion; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportResponseData { + @JsonProperty(value = "view_automatic_settlement_details", required = true) + @JsonInclude + @NotNull + private String viewAutomaticSettlementDetails; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SettlementReportResponseDataEntry { + /** + * The account the money was transferred from (if the amount is positive), or the account the money was transferred to (if the amount is negative). + */ + @JsonProperty(value = "accountName") + private String accountName; + /** + * The monetary amount of the transaction, rounded down to two decimal places. + */ + @JsonProperty(value = "amount") + private double amount; + /** + * The three-letter currency code of the transaction. + */ + @JsonProperty(value = "currency") + private String currency; + /** + * The timestamp of the transaction, including the UTC offset. As the timestamps are always in UTC, the offset is always +00 + */ + @JsonProperty(value = "datestamp") + private String datestamp; + /** + * MessageID of the order associated with the transaction, if available. + */ + @JsonProperty(value = "messageId") + private String messageId; + /** + * OrderID of the order associated with the transaction, if available. + */ + @JsonProperty(value = "orderid") + private String orderID; + /** + * The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. + */ + @JsonProperty(value = "orderType") + private OrderType orderType; + /** + * Can be used in case there is an unknown order type that was received + */ + @JsonProperty(value = "orderTypeString") + private String orderTypeString; + /** + * The sum of all amounts of the respective currency within the report. + */ + @JsonProperty(value = "total") + private double total; + /** + * The username of the child merchant account. + */ + @JsonProperty(value = "username") + private String username; + /** + * The amount that the end user paid, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. + */ + @JsonProperty(value = "fxPaymentAmount") + private double fxPaymentAmount; + /** + * The currency that the user paid with, if the currency is different from the requested deposit currency. For transactions where the payment currency is the same as the requested currency, this field will be empty. + */ + @JsonProperty(value = "fxPaymentCurrency") + private String fxPaymentCurrency; + /** + * The 10 digit reference that will show up on the merchant's bank statement for this automatic settlement batch. The same value will be sent on every row in the report. + */ + @JsonProperty(value = "settlementBankWithdrawalId") + private String settlementBankWithdrawalId; + /** + * Contains the ExternalReference value for Deposit, Charge, and Refund transactions if provided. Otherwise empty. + */ + @JsonProperty(value = "externalReference") + private String externalReference; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SettlementReportResponseResult extends ResponseResult { + public SettlementReportResponseResult() { + super.method = "SettlementReport"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SwishRequest extends JsonRpcRequest { + public SwishRequest() { + super("Swish"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SwishRequestData extends AbstractRequestData { + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL") + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID") + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID") + private String messageId; + } + + /** + * https://eu.developers.trustly.com/doc/reference/swish + */ + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SwishRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * The Swish number of the payee. + *

Examples

+ *
    + *
  • 1231181189
  • + *
+ */ + @JsonProperty(value = "MerchantSwishNumber", required = true) + @JsonInclude + @NotNull + private String merchantSwishNumber; + @JsonProperty(value = "UseMobile") + private StringBoolean useMobile; + /** + * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "SuccessURL") + private String successUrl; + /** + * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "FailURL") + private String failUrl; + /** + * The amount to deposit with exactly two decimals in the currency specified by Currency. Do not use this attribute in combination withsuggestedMinAmount and suggestedMaxAmount. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "Amount", required = true) + @JsonInclude + @NotNull + private String amount; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + /** + * Merchant supplies a message about the payment/order. Max 50 characters. Common allowed characters are the letters a-ö, A-Ö, the numbers 0-9, and special characters !?(),.-:; + *

Examples

+ *
    + *
  • Payment
  • + *
+ */ + @JsonProperty(value = "Message") + private String message; + /** + * The registered cellphone number of the person that makes the payment. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: country code + cell phone number (without leading zero). + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * Minimum age (in years) that the individual connected to the payerAlias has to be in order for the payment to be accepted. Value has to be in the range of 1 to 99. + */ + @JsonProperty(value = "AgeLimit") + private String ageLimit; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SwishRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SwishResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class SwishResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + */ + @JsonProperty(value = "url") + private String URL; + @JsonProperty(value = "qrcode") + private String qrcode; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class SwishResponseResult extends ResponseResult { + public SwishResponseResult() { + super.method = "Swish"; + } + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class WithdrawRequest extends JsonRpcRequest { + public WithdrawRequest() { + super("Withdraw"); + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithdrawRequestData extends AbstractRequestData { + /** + * The URL to which notifications for this should be sent to. This URL should be hard to guess and not contain a ? ("question mark"). + *

Examples

+ *
    + *
  • https://example.com/trustly/notification/a2b63j23dj23883jhfhfh
  • + *
+ */ + @JsonProperty(value = "NotificationURL", required = true) + @JsonInclude + @NotNull + private String notificationUrl; + /** + * ID, username, hash or anything uniquely identifying the end-user requesting the deposit. + * Preferably the same ID/username as used in the merchant's own backoffice in order to simplify for the merchant's support department. + */ + @JsonProperty(value = "EndUserID", required = true) + @JsonInclude + @NotNull + private String endUserId; + /** + * Your unique ID of the transaction. + *

Examples

+ *
    + *
  • 12345678
  • + *
+ */ + @JsonProperty(value = "MessageID", required = true) + @JsonInclude + @NotNull + private String messageId; + /** + * The ISO 4217 code of the currency. See documentation + *

Examples

+ *
    + *
  • BGN
  • + *
  • CZK
  • + *
  • DKK
  • + *
  • EUR
  • + *
  • GBP
  • + *
  • HRK
  • + *
  • HUF
  • + *
  • NOK
  • + *
  • PLN
  • + *
  • RON
  • + *
  • SEK
  • + *
+ */ + @JsonProperty(value = "Currency", required = true) + @JsonInclude + private String currency; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithdrawRequestDataAttributes extends AbstractRequestDataAttributes { + /** + * First name of the person, or the name of the organization/company. + */ + @JsonProperty(value = "Firstname", required = true) + @JsonInclude + @NotNull + private String firstname; + /** + * Last name of the person (NULL/empty for organization/company). + */ + @JsonProperty(value = "Lastname", required = true) + @JsonInclude + private String lastname; + /** + * The ISO 3166-1-alpha-2 code of the end-user's country. This will be used for pre-selecting the country for the end-user in the iframe. + * Note: This will only have an effect for new end-users. If an end-user has done a previous order (with the same EndUserID), the country that was last used will be pre-selected. + */ + @JsonProperty(value = "Country", required = true) + @JsonInclude + @NotNull + private String country; + /** + * The end-users localization preference in the format language[_territory]. Language is the ISO 639-1 code and territory the ISO 3166-1-alpha-2 code. + */ + @JsonProperty(value = "Locale", required = true) + @JsonInclude + @NotNull + private String locale; + /** + * The text to show on the end-user's bank statement after Trustly's own 10 digit reference (which always will be displayed first). The reference must let the end user identify the merchant based on this value. So the ShopperStatement should contain either your brand name, website name, or company name. + *

+ * If possible, try to keep this text as short as possible to maximise the chance that the full reference will fit into the reference field on the customer's bank since some banks allow only a limited number of characters. If the full ShopperStatement does not fit into the reference it will be truncated from the end. + */ + @JsonProperty(value = "ShopperStatement", required = true) + @JsonInclude + @NotNull + private String shopperStatement; + /** + * The email address of the end user. + *

Examples

+ *
    + *
  • test@trustly.com
  • + *
+ */ + @JsonProperty(value = "Email") + private String email; + /** + * The mobile phone number to the end-user in international format. This is used for KYC and AML routines. + */ + @JsonProperty(value = "MobilePhone") + private String mobilePhone; + /** + * The IP-address of the end-user. + */ + @JsonProperty(value = "IP") + private String ip; + /** + * The URL to which the end-user should be redirected after a successful deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "SuccessURL", required = true) + @JsonInclude + @NotNull + private String successUrl; + /** + * The URL to which the end-user should be redirected after a failed deposit. Do not put any logic on that page since it's not guaranteed that the end-user will in fact visit it. + */ + @JsonProperty(value = "FailURL", required = true) + @JsonInclude + @NotNull + private String failUrl; + /** + * The TemplateURL should be used if you want to design your own payment page but have it hosted on Trustly's side. The URL of your template page should be provided in this attribute in every Deposit API call. Our system will then fetch the content of your template page, insert the Trustly iframe into it and host the entire page on Trustly’s side. In the response to the Deposit request, you will receive a URL to the hosted template page which you should redirect the user to (the hosted page cannot be put inside an iframe). + */ + @JsonProperty(value = "TemplateURL") + private String templateUrl; + /** + * The html target/frame-name of the SuccessURL. Only _top, _self and _parent are supported. + */ + @JsonProperty(value = "URLTarget") + private UrlTarget urlTarget; + /** + * The end-user's social security number / personal number / birth number / etc. Useful for some banks for identifying transactions and KYC/AML. If a Swedish personid ("personnummer") is provided, it will be pre-filled when the user logs in to their bank. + *

Examples

+ *
    + *
  • 790131-1234
  • + *
+ */ + @JsonProperty(value = "NationalIdentificationNumber") + private String nationalIdentificationNumber; + /** + * This attribute disables the possibility to change/type in national identification number when logging in to a Swedish bank. If this attribute is sent, the attribute NationalIdentificationNumber needs to be correctly included in the request. Note: This is only available for Swedish banks. + */ + @JsonProperty(value = "UnchangeableNationalIdentificationNumber") + private String unchangeableNationalIdentificationNumber; + /** + * If you are using Trustly from within your native iOS app, this attribute should be sent so that we can redirect the users back to your app in case an external app is used for authentication (for example Mobile Bank ID in Sweden). + */ + @JsonProperty(value = "URLScheme") + private String urlScheme; + /** + * When rendering the Trustly Checkout in a native app you are required to pass your application's url as an attribute to the order initiation request. By doing so, Trustly can redirect users back to your app after using external identification apps such as Mobile BankID: Please visit documentation site for more information. It must not be included for transactions that are not originating from an app. + *

+ * NOTE! This value is only used for redirecting users back to the native app within the flows. See also SuccessURL and FailURL descriptions. + */ + @JsonProperty(value = "ReturnToAppURL") + private String returnToAppUrl; + /** + * The minimum amount the end-user is allowed to deposit in the currency specified by Currency.Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "SuggestedMinAmount") + private String suggestedMinAmount; + /** + * The maximum amount the end-user is allowed to deposit in the currency specified by Currency. Only digits. Use dot (.) as decimal separator. + */ + @JsonProperty(value = "SuggestedMaxAmount") + private String suggestedMaxAmount; + /** + * Sets a fixed withdrawal amount which cannot be changed by the end-user in the Trustly iframe. If this attribute is not sent, the end-user will be asked to select the withdrawal amount in the Trustly iframe. Do not use in combination with suggestedMinAmount and suggestedMaxAmount. Use dot(.) as decimal separator. + */ + @JsonProperty(value = "SuggestedAmount") + private String suggestedAmount; + /** + * The end-user's date of birth. + */ + @JsonProperty(value = "DateOfBirth") + private String dateOfBirth; + /** + * The ISO 3166-1-alpha-2 code of the recipient address country. + */ + @JsonProperty(value = "AddressCountry") + private String addressCountry; + /** + * The postalcode of the recipient address. + */ + @JsonProperty(value = "AddressPostalCode") + private String addressPostalCode; + /** + * The city of the recipient address. + */ + @JsonProperty(value = "AddressCity") + private String addressCity; + /** + * Recipient address street + *

Examples

+ *
    + *
  • Main Street 1
  • + *
+ */ + @JsonProperty(value = "AddressLine1") + private String addressLine1; + /** + * Additional address information of the recipient. + */ + @JsonProperty(value = "AddressLine2") + private String addressLine2; + /** + * The entire shipping address. + * This attribute should only be used if you are unable to provide the shipping address information in the 5 separate properties: AddressCountry, AddressCity, AddressPostalCode, AddressLine1, AddressLine2 + *

Examples

+ *
    + *
  • Birgerstreet 14, SE-11411, Stockholm, Sweden
  • + *
+ */ + @JsonProperty(value = "Address") + private String address; + /** + * The ExternalReference is a reference set by the merchant for any purpose and does not need to be unique for every API call. For example, it can be used for invoice references, OCR numbers and also for offering end users the option to part-pay an invoice using the same ExternalReference. The ExternalReference will be included in version 1.2 of the settlement report, ViewAutomaticSettlementDetailsCSV. + *

Examples

+ *
    + *
  • 32423534523
  • + *
+ */ + @JsonProperty(value = "ExternalReference") + private String externalReference; + /** + * Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name) + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchant") + private String pspMerchant; + /** + * URL of the consumer-facing website where the order is initiated + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "PSPMerchantURL") + private String pspMerchantUrl; + /** + * VISA category codes describing the merchant's nature of business. + * Note: Mandatory attribute for Trustly Partners that are using Express Merchant Onboarding (EMO) and aggregate traffic under a master processing account. It is also mandatory for E-wallets used directly in a merchant's checkout. + * Mandatory attributes for Trustly Partners that are using Express account. It is also mandatory for E-wallets used directly in a merchant's checkout, whereby the purpose of a Trustly transaction is to pay for goods/services by placing funds on the payer's e-money account ("funding stage") following an immediate transfer into the e-money account of the payee ( "payment" stage). + */ + @JsonProperty(value = "MerchantCategoryCode") + private String merchantCategoryCode; + /** + * Information about the Payer (ultimate debtor). This is required for some merchants and partners. SenderInformation is mandatory to send in Attributes{} for money transfer services (including remittance houses), e-wallets, prepaid cards, as well as for Trustly Partners that are using Express Merchant Onboarding and aggregate traffic under a master processing account (other cases may also apply). + */ + @JsonProperty(value = "SenderInformation") + @Valid + private SenderInformation senderInformation; + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithdrawRequestParams extends JsonRpcRequestParams { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithdrawResponse extends JsonRpcResponse { + + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithdrawResponseData { + /** + * The globally unique OrderID the charge order was assigned in our system. The order has no end-user interaction; it is merely used as a reference for the notifications delivered regarding the request. + *

Examples

+ *
    + *
  • 9594811343
  • + *
+ */ + @JsonProperty(value = "orderid", required = true) + @JsonInclude + @NotNull + private String orderID; + /** + * The URL that should be loaded so that the end-user can continue with the interactive process. Please see our general guidelines around iFraming, nativeApps etc for best usability. In general, never iFrame the url for mobile devices. + */ + @JsonProperty(value = "url", required = true) + @JsonInclude + @NotNull + private String URL; + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class WithdrawResponseResult extends ResponseResult { + public WithdrawResponseResult() { + super.method = "Withdraw"; + } + } + + @Getter + @Jacksonized + @RequiredArgsConstructor + @Setter + @SuperBuilder + public static class WithRejection { + @JsonProperty(value = "result") + @Valid + private TResult result; + @JsonProperty(value = "rejected") + @Valid + private TRejected rejected; + } + + public enum AckDataStatus { + OK("OK"); + + @JsonValue + private final String value; + + AckDataStatus(String value) { + this.value = value; + } + } + + /** + * If the cancel was NOT accepted, a textual code describing the rejection reason, null otherwise. + */ + public enum CancelDirectDebitMandateReject { + /** + * The mandate does not exist. + */ + ERROR_MANDATE_NOT_FOUND("ERROR_MANDATE_NOT_FOUND"); + + @JsonValue + private final String value; + + CancelDirectDebitMandateReject(String value) { + this.value = value; + } + } + + /** + * If the cancel was NOT accepted, a textual code describing the rejection reason, null otherwise. + */ + public enum CancelDirectDebitReject { + /** + * the OrderId does not exist. + */ + ERROR_CHARGE_NOT_FOUND("ERROR_CHARGE_NOT_FOUND"), + /** + * the charge has already been processed in the scheme (e.g. BACS) and can not be cancelled. + */ + ERROR_CHARGE_ALREADY_PROCESSED("ERROR_CHARGE_ALREADY_PROCESSED"); + + @JsonValue + private final String value; + + CancelDirectDebitReject(String value) { + this.value = value; + } + } + + public enum CancelMandateNotificationDataAttributesCancelReason { + /** + * The mandate already exists + */ + MANDATE_ALREADY_EXISTS("MANDATE_ALREADY_EXISTS"), + /** + * Either when the consumer cancels in the journey or if you call cancel mandate method. + */ + CANCELLED("CANCELLED"), + /** + * If the underlying scheme reports failure or cancellation of the mandate + */ + FAILED("FAILED"), + /** + * If the provided accountId was incorrect + */ + INVALID_ACCOUNT_ID("INVALID_ACCOUNT_ID"); + + @JsonValue + private final String value; + + CancelMandateNotificationDataAttributesCancelReason(String value) { + this.value = value; + } + } + + public enum CancelReason { + /** + * The mandate already exists + * From CancelMandateNotificationDataAttributesCancelReason + */ + MANDATE_ALREADY_EXISTS("MANDATE_ALREADY_EXISTS"), + /** + * Either when the consumer cancels in the journey or if you call cancel mandate method. + * From CancelMandateNotificationDataAttributesCancelReason + */ + CANCELLED("CANCELLED"), + /** + * If the underlying scheme reports failure or cancellation of the mandate + * From CancelMandateNotificationDataAttributesCancelReason + */ + FAILED("FAILED"), + /** + * If the provided accountId was incorrect + * From CancelMandateNotificationDataAttributesCancelReason + */ + INVALID_ACCOUNT_ID("INVALID_ACCOUNT_ID"), + /** + * The specified account is not valid, eg sending funds to it is not possible. + * From RefundDirectDebitCancelReason + */ + INVALID_ACCOUNT("INVALID_ACCOUNT"), + /** + * The mandate is invalid for some reason. + * From DirectDebitCancelReason + */ + ERROR_MANDATE_INVALID("ERROR_MANDATE_INVALID"), + /** + * Ie. missing funds or being canceled by the end-user. + * From DirectDebitCancelReason + */ + ERROR_CHARGE_NOT_APPROVED("ERROR_CHARGE_NOT_APPROVED"), + /** + * The request was declined + * From SwishCancelReason + */ + DECLINED("DECLINED"), + /** + * The request was cancelled + * From SwishCancelReason + */ + CANCELED("CANCELED"), + /** + * There was an error during the request + * From SwishCancelReason + */ + ERROR("ERROR"); + + @JsonValue + private final String value; + + CancelReason(String value) { + this.value = value; + } + } + + public enum CreditRefundDirectDebitCancelReason { + /** + * The request was declined + */ + DECLINED("DECLINED"), + /** + * The request was cancelled + */ + CANCELED("CANCELED"), + /** + * There was an error during the request + */ + ERROR("ERROR"), + /** + * Direct Debit Mandate: Either when the consumer cancels in the journey or if you call cancel mandate method, or the payment was canceled from the api. + */ + CANCELLED("CANCELLED"), + /** + * Direct Debit Mandate: If the underlying scheme reports failure or cancellation of the mandate + */ + FAILED("FAILED"), + /** + * Direct Debit Mandate: If the mandate already exist + */ + MANDATE_ALREADY_EXISTS("MANDATE_ALREADY_EXISTS"), + /** + * Direct Debit Mandate: If the provided accountId was incorrect + */ + INVALID_ACCOUNT_ID("INVALID_ACCOUNT_ID"), + /** + * The mandate is invalid for some reason. + */ + ERROR_MANDATE_INVALID("ERROR_MANDATE_INVALID"), + /** + * Ie. missing funds or being canceled by the end-user. + */ + ERROR_CHARGE_NOT_APPROVED("ERROR_CHARGE_NOT_APPROVED"), + /** + * The specified account is not valid, eg sending funds to it is not possible. + */ + INVALID_ACCOUNT("INVALID_ACCOUNT"); + + @JsonValue + private final String value; + + CreditRefundDirectDebitCancelReason(String value) { + this.value = value; + } + } + + public enum DebitDirectDebitNotificationReason { + /** + * The mandate is invalid for some reason. + */ + ERROR_MANDATE_INVALID("ERROR_MANDATE_INVALID"), + /** + * Ie. missing funds or being canceled by the end-user. + */ + ERROR_CHARGE_NOT_APPROVED("ERROR_CHARGE_NOT_APPROVED"), + /** + * If the payment was canceled from the api + */ + CANCELLED("CANCELLED"), + /** + * All other failures + */ + FAILED("FAILED"); + + @JsonValue + private final String value; + + DebitDirectDebitNotificationReason(String value) { + this.value = value; + } + } + + public enum DebitNotificationReason { + /** + * All other failures + * From DirectCreditDebitNotificationReason + * From DebitDirectDebitNotificationReason + */ + FAILED("FAILED"), + /** + * The mandate is invalid for some reason. + * From DebitDirectDebitNotificationReason + */ + ERROR_MANDATE_INVALID("ERROR_MANDATE_INVALID"), + /** + * Ie. missing funds or being canceled by the end-user. + * From DebitDirectDebitNotificationReason + */ + ERROR_CHARGE_NOT_APPROVED("ERROR_CHARGE_NOT_APPROVED"), + /** + * If the payment was canceled from the api + * From DebitDirectDebitNotificationReason + */ + CANCELLED("CANCELLED"); + + @JsonValue + private final String value; + + DebitNotificationReason(String value) { + this.value = value; + } + } + + public enum DebitNotificationResponseDataStatus { + OK("OK"), + FAILED("FAILED"); + + @JsonValue + private final String value; + + DebitNotificationResponseDataStatus(String value) { + this.value = value; + } + } + + public enum DirectCreditCancelReason { + /** + * The specified account is not valid, eg sending funds to it is not possible. + */ + INVALID_ACCOUNT("INVALID_ACCOUNT"), + /** + * If the payment was cancelled via the api + */ + CANCELLED("CANCELLED"), + /** + * All other failures + */ + FAILED("FAILED"); + + @JsonValue + private final String value; + + DirectCreditCancelReason(String value) { + this.value = value; + } + } + + public enum DirectCreditDebitNotificationReason { + /** + * All other failures + */ + FAILED("FAILED"); + + @JsonValue + private final String value; + + DirectCreditDebitNotificationReason(String value) { + this.value = value; + } + } + + public enum DirectCreditRejected { + /** + * No matching active accountId + */ + ERROR_MANDATE_NOT_FOUND("ERROR_MANDATE_NOT_FOUND"), + /** + * Account not properly configured + */ + ERROR_DIRECT_DEBIT_NOT_ALLOWED("ERROR_DIRECT_DEBIT_NOT_ALLOWED"), + /** + * Payment date is invalid + */ + ERROR_PAYMENT_DATE_FAILURE("ERROR_PAYMENT_DATE_FAILURE"), + /** + * Amount is invalid or not within the configured range + */ + ERROR_AMOUNT_FAILURE("ERROR_AMOUNT_FAILURE"), + /** + * The mandate doesn't support the currency + */ + ERROR_CURRENCY_FAILURE("ERROR_CURRENCY_FAILURE"); + + @JsonValue + private final String value; + + DirectCreditRejected(String value) { + this.value = value; + } + } + + public enum DirectDebitCancelReason { + /** + * The mandate is invalid for some reason. + */ + ERROR_MANDATE_INVALID("ERROR_MANDATE_INVALID"), + /** + * Ie. missing funds or being canceled by the end-user. + */ + ERROR_CHARGE_NOT_APPROVED("ERROR_CHARGE_NOT_APPROVED"), + /** + * If the payment was canceled from the api + */ + CANCELLED("CANCELLED"), + /** + * All other failures + */ + FAILED("FAILED"); + + @JsonValue + private final String value; + + DirectDebitCancelReason(String value) { + this.value = value; + } + } + + public enum DirectDebitCollectionType { + INITIAL("INITIAL"), + RECURRING("RECURRING"), + RE_SUBMITTED("RE_SUBMITTED"), + FINAL("FINAL"); + + @JsonValue + private final String value; + + DirectDebitCollectionType(String value) { + this.value = value; + } + } + + public enum DirectDebitImportType { + /** + * Does NOT register the mandate with the scheme (REGISTER does) + */ + CREATE("CREATE"), + /** + * Registers the mandate with the scheme + */ + REGISTER("REGISTER"); + + @JsonValue + private final String value; + + DirectDebitImportType(String value) { + this.value = value; + } + } + + public enum DirectDebitRejected { + /** + * No matching active accountId + */ + ERROR_MANDATE_NOT_FOUND("ERROR_MANDATE_NOT_FOUND"), + /** + * Account not properly configured + */ + ERROR_DIRECT_DEBIT_NOT_ALLOWED("ERROR_DIRECT_DEBIT_NOT_ALLOWED"), + /** + * Payment date is invalid + */ + ERROR_PAYMENT_DATE_FAILURE("ERROR_PAYMENT_DATE_FAILURE"), + /** + * Amount is invalid or not within the configured range + */ + ERROR_AMOUNT_FAILURE("ERROR_AMOUNT_FAILURE"), + /** + * The mandate doesn't support the currency + */ + ERROR_CURRENCY_FAILURE("ERROR_CURRENCY_FAILURE"), + /** + * Invalid collection type + */ + ERROR_COLLECTION_TYPE_FAILURE("ERROR_COLLECTION_TYPE_FAILURE"); + + @JsonValue + private final String value; + + DirectDebitRejected(String value) { + this.value = value; + } + } + + public enum DirectDebitTheme { + DARK("DARK"), + LIGHT("LIGHT"), + DEFAULT("DEFAULT"); + + @JsonValue + private final String value; + + DirectDebitTheme(String value) { + this.value = value; + } + } + + public enum DirectPaymentBatchRejected { + /** + * The account has not properly been configured. + */ + ERROR_DIRECT_DEBIT_NOT_ALLOWED("ERROR_DIRECT_DEBIT_NOT_ALLOWED"), + /** + * Invalid payment date. + */ + ERROR_PAYMENT_DATE_FAILURE("ERROR_PAYMENT_DATE_FAILURE"), + /** + * The file on the sftp server can't be interpreted. + */ + ERROR_UNABLE_TO_READ_BATCH_FILE("ERROR_UNABLE_TO_READ_BATCH_FILE"), + /** + * The file could not be found on the sftp server. + */ + ERROR_MISSING_BATCH_FILE("ERROR_MISSING_BATCH_FILE"), + /** + * The checksum for the file doesn't match. + */ + ERROR_INVALID_CHECKSUM("ERROR_INVALID_CHECKSUM"); + + @JsonValue + private final String value; + + DirectPaymentBatchRejected(String value) { + this.value = value; + } + } + + public interface IAdditionalProperties { + Map getAdditionalProperties(); + void addAdditionalProperty(String key, Object value); + } + + /** + * Reasons for not being able to import the mandate + */ + public enum ImportDirectDebitReject { + /** + * AccountID not found + */ + ERROR_ACCOUNT_NOT_FOUND("ERROR_ACCOUNT_NOT_FOUND"), + /** + * mandate is not allowed for this account + */ + ERROR_IMPORT_MANDATE_NOT_ALLOWED("ERROR_IMPORT_MANDATE_NOT_ALLOWED"), + /** + * account can't be imported as it's blocked. + */ + BANK_ACCOUNT_NUMBER_BLOCKED("BANK_ACCOUNT_NUMBER_BLOCKED"), + /** + * account is invalid + */ + ERROR_INVALID_ACCOUNT_NUMBER("ERROR_INVALID_ACCOUNT_NUMBER"), + /** + * other reasons + */ + ERROR_UNKNOWN("ERROR_UNKNOWN"); + + @JsonValue + private final String value; + + ImportDirectDebitReject(String value) { + this.value = value; + } + } + + public enum KYCNotificationResponseDataStatus { + OK("OK"), + FINISH("FINISH"), + CONTINUE("CONTINUE"); + + @JsonValue + private final String value; + + KYCNotificationResponseDataStatus(String value) { + this.value = value; + } + } + + public enum MandateAccountSource { + /** + * Account details from AIS + */ + AIS("AIS"), + /** + * Manually inputed account number + */ + MANUAL_ENTRY("MANUAL_ENTRY"), + /** + * AccountID provided when creating the order + */ + ACCOUNT_ID("ACCOUNT_ID"), + /** + * If the scheme notifies about a change of account, this only aplies to BACS. + */ + REGISTRATION_SCHEME("REGISTRATION_SCHEME"); + + @JsonValue + private final String value; + + MandateAccountSource(String value) { + this.value = value; + } + } + + public enum NumberBoolean { + /** + * 0 for false + */ + FALSE(0), + /** + * 1 for true + */ + TRUE(1); + + @JsonValue + private final int value; + + NumberBoolean(int value) { + this.value = value; + } + } + + /** + * The type of the order associated with the transaction, if available.Text See list of possible orderypes in the table below. + */ + public enum OrderType { + /** + * Order type for Deposit + */ + DEPOSIT("Deposit"), + REFUND("Refund"), + CHARGE("Charge"), + WITHDRAW("Withdraw"), + ACCOUNT_PAYOUT("AccountPayout"), + DEPOSIT_FEE("Deposit Fee"), + REFUND_FEE("Refund Fee"), + CHARGE_FEE("Charge Fee"), + WITHDRAW_FEE("Withdraw Fee"), + SETTLEMENT_FEE("Settlement Fee"), + ACCOUNT_PAYOUT_FEE("AccountPayout Fee"), + FAILED_REFUND("Failed Refund"), + FAILED_REFUND_FEE("Failed Refund Fee"), + FX("FX"), + FLOAT_ADJUSTMENT("Float Adjustment"), + AUTOMATIC_FLOAT_ADJUSTMENT("Automatic Float Adjustment"); + + @JsonValue + private final String value; + + OrderType(String value) { + this.value = value; + } + } + + public enum PartyTypeKind { + PERSON("PERSON"), + ORGANISATION("ORGANISATION"); + + @JsonValue + private final String value; + + PartyTypeKind(String value) { + this.value = value; + } + } + + public enum RefundDirectDebitCancelReason { + /** + * The specified account is not valid, eg sending funds to it is not possible. + */ + INVALID_ACCOUNT("INVALID_ACCOUNT"), + /** + * All other failures + */ + FAILED("FAILED"); + + @JsonValue + private final String value; + + RefundDirectDebitCancelReason(String value) { + this.value = value; + } + } + + public enum RefundDirectDebitRejected { + /** + * The debit order wasn't found. + */ + ERROR_CHARGE_NOT_FOUND("ERROR_CHARGE_NOT_FOUND"), + /** + * The debit order is not refundable + */ + ERROR_CHARGE_NOT_REFUNDABLE("ERROR_CHARGE_NOT_REFUNDABLE"), + /** + * The amount is not valid, eg could be bigger than the debit. + */ + ERROR_AMOUNT_FAILURE("ERROR_AMOUNT_FAILURE"), + /** + * The currency does not match the original debit order. + */ + ERROR_CURRENCY_FAILURE("ERROR_CURRENCY_FAILURE"); + + @JsonValue + private final String value; + + RefundDirectDebitRejected(String value) { + this.value = value; + } + } + + /** + * Required. The APIVersion. Must be "1.2". We also have older versions of the report, but those should not be implemented by new merchants. + */ + public enum SettlementReportRequestDataAttributesApiVersion { + _1_2("1.2"); + + @JsonValue + private final String value; + + SettlementReportRequestDataAttributesApiVersion(String value) { + this.value = value; + } + } + + public enum StringBoolean { + FALSE("0"), + TRUE("1"); + + @JsonValue + private final String value; + + StringBoolean(String value) { + this.value = value; + } + } + + public enum SwishCancelReason { + /** + * The request was declined + */ + DECLINED("DECLINED"), + /** + * The request was cancelled + */ + CANCELED("CANCELED"), + /** + * There was an error during the request + */ + ERROR("ERROR"); + + @JsonValue + private final String value; + + SwishCancelReason(String value) { + this.value = value; + } + } + + /** + * The html target/frame-name. Only _top, _self and _parent are supported. + */ + public enum UrlTarget { + TOP("_top"), + SELF("_self"), + PARENT("_parent"); + + @JsonValue + private final String value; + + UrlTarget(String value) { + this.value = value; + } + } +} diff --git a/src/main/java/com/trustly/api/domain/common/DepositValidationGroup.java b/trustly-java-models/src/main/java/com/trustly/api/domain/common/DepositValidationGroup.java similarity index 100% rename from src/main/java/com/trustly/api/domain/common/DepositValidationGroup.java rename to trustly-java-models/src/main/java/com/trustly/api/domain/common/DepositValidationGroup.java diff --git a/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotification.java b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotification.java new file mode 100644 index 0000000..2b91768 --- /dev/null +++ b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotification.java @@ -0,0 +1,50 @@ +package com.trustly.api.domain.notifications; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import lombok.Getter; +import lombok.Setter; +import lombok.Singular; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +import java.util.Map; + +import static com.trustly.api.domain.Models.*; + +@Getter +@Jacksonized +@Setter +@SuperBuilder +public class UnknownNotification extends JsonRpcNotification { + public UnknownNotification(String method) { + super(method); + } + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class Params extends JsonRpcNotificationParams { + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class Data extends AbstractNotificationRequestData { + + @Singular + @JsonAnySetter + private Map additionalProperties; + + public void addAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + } + } +} diff --git a/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationAckData.java b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationAckData.java new file mode 100644 index 0000000..c6692d8 --- /dev/null +++ b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationAckData.java @@ -0,0 +1,14 @@ +package com.trustly.api.domain.notifications; + +import com.trustly.api.domain.Models; + +public class UnknownNotificationAckData extends Models.NotificationResponseDataBase { + + public UnknownNotificationAckData() { + this("OK"); + } + + public UnknownNotificationAckData(String status) { + this.setStatus(status); + } +} diff --git a/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationResponse.java b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationResponse.java new file mode 100644 index 0000000..d5d4c1b --- /dev/null +++ b/trustly-java-models/src/main/java/com/trustly/api/domain/notifications/UnknownNotificationResponse.java @@ -0,0 +1,28 @@ +package com.trustly.api.domain.notifications; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.trustly.api.domain.Models; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import lombok.extern.jackson.Jacksonized; + +@Getter +@Jacksonized +@RequiredArgsConstructor +@Setter +@SuperBuilder +public class UnknownNotificationResponse extends Models.JsonRpcResponse { + + @Getter + @Jacksonized + @Setter + @SuperBuilder + public static class Result extends Models.ResponseResult { + + public Result(@JsonProperty(value = "method", required = true) String method) { + super.setMethod(method); + } + } +} diff --git a/trustly-java-util/pom.xml b/trustly-java-util/pom.xml new file mode 100644 index 0000000..81c7aad --- /dev/null +++ b/trustly-java-util/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + com.trustly.api + trustly-java + ${revision} + + + trustly-java-util + ${revision} + + + 11 + 11 + UTF-8 + + + + + + + org.bouncycastle + bcpkix-jdk15on + + + + com.fasterxml.jackson.core + jackson-databind + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/trustly/api/client/DefaultJsonRpcSigner.java b/trustly-java-util/src/main/java/com/trustly/api/DefaultJsonRpcSigner.java similarity index 55% rename from src/main/java/com/trustly/api/client/DefaultJsonRpcSigner.java rename to trustly-java-util/src/main/java/com/trustly/api/DefaultJsonRpcSigner.java index 61a34d6..ae2bab5 100644 --- a/src/main/java/com/trustly/api/client/DefaultJsonRpcSigner.java +++ b/trustly-java-util/src/main/java/com/trustly/api/DefaultJsonRpcSigner.java @@ -1,15 +1,10 @@ -package com.trustly.api.client; +package com.trustly.api; import com.fasterxml.jackson.databind.JsonNode; -import com.trustly.api.domain.base.IData; -import com.trustly.api.domain.base.IRequest; -import com.trustly.api.domain.base.IRequestParams; -import com.trustly.api.domain.base.IRequestParamsData; -import com.trustly.api.domain.base.IResponseResultData; -import com.trustly.api.domain.base.JsonRpcRequest; -import com.trustly.api.domain.base.JsonRpcResponse; -import com.trustly.api.domain.exceptions.TrustlySignatureException; +import com.trustly.api.exceptions.TrustlySignatureException; import com.trustly.api.util.TrustlyStringUtils; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; @@ -18,7 +13,6 @@ import java.security.Signature; import java.security.SignatureException; import java.util.Base64; -import org.bouncycastle.jce.provider.BouncyCastleProvider; public class DefaultJsonRpcSigner implements JsonRpcSigner { @@ -37,33 +31,9 @@ public String createPlaintext(String serializedData, String method, String uuid) } @Override - public JsonRpcRequest sign(JsonRpcRequest request) { - - String signature = this.createSignature(request.getMethod(), request.getParams().getUuid(), request.getParams().getData()); - - return request.toBuilder() - .params( - request.getParams().withSignature(signature) - ) - .build(); - } - - @Override - public JsonRpcResponse sign(JsonRpcResponse response) { - - String signature = this.createSignature(response.getMethod(), response.getUUID(), response.getData()); + public String sign(Object requestData, String method, String uuid) { - return response.toBuilder() - .result( - response.getResult().toBuilder() - .signature(signature) - .build() - ) - .build(); - } - - private String createSignature(String method, String uuid, T data) { - String serializedData = this.serializer.serializeData(data); + String serializedData = this.serializer.serializeData(requestData); String plainText = this.createPlaintext(serializedData, method, uuid); Signature signer; @@ -94,31 +64,7 @@ private String createSignature(String method, String uuid, T d return Base64.getEncoder().encodeToString(signedBytes); } - @Override - public > void verify(IRequest

request) throws TrustlySignatureException { - - String uuid = (request.getParams() == null) ? null : request.getParams().getUuid(); - String signature = (request.getParams() == null) ? null : request.getParams().getSignature(); - D data = (request.getParams() == null) ? null : request.getParams().getData(); - - this.verify(request.getMethod(), uuid, signature, data, null); - } - - @Override - public void verify(JsonRpcResponse response, JsonNode nodeResponse) throws TrustlySignatureException { - - JsonNode dataNode = null; - if (nodeResponse != null) { - dataNode = nodeResponse.at("/result/data"); - if (dataNode.isMissingNode()) { - dataNode = nodeResponse.at("/error/data"); - } - } - - this.verify(response.getMethod(), response.getUUID(), response.getSignature(), response.getData(), dataNode); - } - - private void verify(String method, String uuid, String expectedSignature, IData data, JsonNode dataNode) + public void verify(String method, String uuid, JsonNode dataNode, String expectedSignature) throws TrustlySignatureException { if (TrustlyStringUtils.isBlank(expectedSignature)) { @@ -128,14 +74,12 @@ private void verify(String method, String uuid, String expectedSignature, IData // If possible, we will serialize based on the actual data node instead of the data object. // This way we can differentiate between a field that has as null value and was not given at all. // This can happen with values given back from the Trustly remote server. - String serializedResponseData = (dataNode != null && !dataNode.isMissingNode() && !dataNode.isNull()) - ? this.serializer.serializeNode(dataNode) - : this.serializer.serializeData(data); + var serializedResponseData = this.serializer.serializeNode(dataNode); - String responsePlainText = this.createPlaintext(serializedResponseData, method, uuid); + var responsePlainText = this.createPlaintext(serializedResponseData, method, uuid); - byte[] responseBytes = responsePlainText.getBytes(StandardCharsets.UTF_8); - byte[] expectedSignatureBytes = Base64.getDecoder().decode(expectedSignature); + var responseBytes = responsePlainText.getBytes(StandardCharsets.UTF_8); + var expectedSignatureBytes = Base64.getDecoder().decode(expectedSignature); try { @@ -143,7 +87,7 @@ private void verify(String method, String uuid, String expectedSignature, IData Security.addProvider(new BouncyCastleProvider()); } - Signature signer = Signature.getInstance(SHA1_WITH_RSA, BouncyCastleProvider.PROVIDER_NAME); + var signer = Signature.getInstance(SHA1_WITH_RSA, BouncyCastleProvider.PROVIDER_NAME); signer.initVerify(this.settings.getTrustlyPublicKey()); signer.update(responseBytes); diff --git a/trustly-java-util/src/main/java/com/trustly/api/JsonRpcSigner.java b/trustly-java-util/src/main/java/com/trustly/api/JsonRpcSigner.java new file mode 100644 index 0000000..a72e3ee --- /dev/null +++ b/trustly-java-util/src/main/java/com/trustly/api/JsonRpcSigner.java @@ -0,0 +1,11 @@ +package com.trustly.api; + +import com.fasterxml.jackson.databind.JsonNode; +import com.trustly.api.exceptions.TrustlySignatureException; + +public interface JsonRpcSigner { + + String sign(Object requestData, String method, String uuid); + + void verify(String method, String uuid, JsonNode dataNode, String expectedSignature) throws TrustlySignatureException; +} diff --git a/src/main/java/com/trustly/api/client/Serializer.java b/trustly-java-util/src/main/java/com/trustly/api/Serializer.java similarity index 82% rename from src/main/java/com/trustly/api/client/Serializer.java rename to trustly-java-util/src/main/java/com/trustly/api/Serializer.java index b2a8a28..9900ac4 100644 --- a/src/main/java/com/trustly/api/client/Serializer.java +++ b/trustly-java-util/src/main/java/com/trustly/api/Serializer.java @@ -1,11 +1,9 @@ -package com.trustly.api.client; +package com.trustly.api; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ValueNode; -import com.trustly.api.domain.base.IData; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; @@ -13,16 +11,10 @@ public class Serializer { - private final ObjectMapper objectMapper = new ObjectMapper(); + public String serializeData(D data) { - public String serializeData(D data) { - - JsonNode jsonObject = this.objectMapper.valueToTree(data); - - StringBuilder sb = new StringBuilder(); - this.serializeNode(jsonObject, sb); - - return sb.toString(); + JsonNode jsonObject = TrustlyApiClientSettings.DEFAULT_OBJECT_MAPPER.valueToTree(data); + return this.serializeNode(jsonObject); } public String serializeNode(TreeNode node) { diff --git a/src/main/java/com/trustly/api/client/TrustlyApiClientSettings.java b/trustly-java-util/src/main/java/com/trustly/api/TrustlyApiClientSettings.java similarity index 96% rename from src/main/java/com/trustly/api/client/TrustlyApiClientSettings.java rename to trustly-java-util/src/main/java/com/trustly/api/TrustlyApiClientSettings.java index 487cea0..c3adeac 100644 --- a/src/main/java/com/trustly/api/client/TrustlyApiClientSettings.java +++ b/trustly-java-util/src/main/java/com/trustly/api/TrustlyApiClientSettings.java @@ -1,5 +1,10 @@ -package com.trustly.api.client; +package com.trustly.api; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; import com.trustly.api.util.TrustlyFileUtils; import com.trustly.api.util.TrustlyStringUtils; import java.io.ByteArrayInputStream; @@ -27,6 +32,13 @@ public class TrustlyApiClientSettings { + public static final ObjectMapper DEFAULT_OBJECT_MAPPER = JsonMapper.builder() + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .serializationInclusion(JsonInclude.Include.NON_EMPTY) + .build(); + static final String URL_TEST = "https://test.trustly.com/api/1"; static final String URL_PRODUCTION = "https://api.trustly.com/1"; diff --git a/src/main/java/com/trustly/api/domain/exceptions/AbstractTrustlyApiException.java b/trustly-java-util/src/main/java/com/trustly/api/exceptions/AbstractTrustlyApiException.java similarity index 85% rename from src/main/java/com/trustly/api/domain/exceptions/AbstractTrustlyApiException.java rename to trustly-java-util/src/main/java/com/trustly/api/exceptions/AbstractTrustlyApiException.java index f27daf1..dfe878f 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/AbstractTrustlyApiException.java +++ b/trustly-java-util/src/main/java/com/trustly/api/exceptions/AbstractTrustlyApiException.java @@ -1,4 +1,4 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; public abstract class AbstractTrustlyApiException extends Exception { diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlySignatureException.java b/trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlySignatureException.java similarity index 85% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlySignatureException.java rename to trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlySignatureException.java index 08b852a..59e63a6 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlySignatureException.java +++ b/trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlySignatureException.java @@ -1,4 +1,4 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; public class TrustlySignatureException extends AbstractTrustlyApiException { diff --git a/src/main/java/com/trustly/api/domain/exceptions/TrustlyValidationException.java b/trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlyValidationException.java similarity index 52% rename from src/main/java/com/trustly/api/domain/exceptions/TrustlyValidationException.java rename to trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlyValidationException.java index 5ee83df..de2f1a0 100644 --- a/src/main/java/com/trustly/api/domain/exceptions/TrustlyValidationException.java +++ b/trustly-java-util/src/main/java/com/trustly/api/exceptions/TrustlyValidationException.java @@ -1,12 +1,8 @@ -package com.trustly.api.domain.exceptions; +package com.trustly.api.exceptions; public class TrustlyValidationException extends AbstractTrustlyApiException { public TrustlyValidationException(String message) { super(message); } - - public TrustlyValidationException(String message, Exception cause) { - super(message, cause); - } } diff --git a/src/main/java/com/trustly/api/util/TrustlyFileUtils.java b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyFileUtils.java similarity index 65% rename from src/main/java/com/trustly/api/util/TrustlyFileUtils.java rename to trustly-java-util/src/main/java/com/trustly/api/util/TrustlyFileUtils.java index a26adf6..b337603 100644 --- a/src/main/java/com/trustly/api/util/TrustlyFileUtils.java +++ b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyFileUtils.java @@ -4,12 +4,13 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; -import lombok.experimental.UtilityClass; -@UtilityClass public class TrustlyFileUtils { + private TrustlyFileUtils() { + } + public static String readAllText(String path) throws IOException { - return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8); + return Files.readString(Paths.get(path), StandardCharsets.UTF_8); } } diff --git a/src/main/java/com/trustly/api/util/TrustlyStreamUtils.java b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStreamUtils.java similarity index 89% rename from src/main/java/com/trustly/api/util/TrustlyStreamUtils.java rename to trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStreamUtils.java index 918ac5b..4ab00ba 100644 --- a/src/main/java/com/trustly/api/util/TrustlyStreamUtils.java +++ b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStreamUtils.java @@ -3,11 +3,12 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; -import lombok.experimental.UtilityClass; -@UtilityClass public class TrustlyStreamUtils { + private TrustlyStreamUtils() { + } + public static String readerToString(Reader reader) throws IOException { BufferedReader in = new BufferedReader(reader); diff --git a/src/main/java/com/trustly/api/util/TrustlyStringUtils.java b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStringUtils.java similarity index 62% rename from src/main/java/com/trustly/api/util/TrustlyStringUtils.java rename to trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStringUtils.java index f3fc364..c4630fc 100644 --- a/src/main/java/com/trustly/api/util/TrustlyStringUtils.java +++ b/trustly-java-util/src/main/java/com/trustly/api/util/TrustlyStringUtils.java @@ -1,20 +1,20 @@ package com.trustly.api.util; -import lombok.experimental.UtilityClass; - -@UtilityClass public class TrustlyStringUtils { + private TrustlyStringUtils() { + } + public static boolean isBlank(String value) { if (value == null) { return true; } - if (value.equals("")) { + if (value.isEmpty()) { return true; } - return value.trim().equals(""); + return value.trim().isEmpty(); } } diff --git a/trustly-java-util/src/test/java/com/trustly/api/SimpleSerializerTest.java b/trustly-java-util/src/test/java/com/trustly/api/SimpleSerializerTest.java new file mode 100644 index 0000000..7012fd7 --- /dev/null +++ b/trustly-java-util/src/test/java/com/trustly/api/SimpleSerializerTest.java @@ -0,0 +1,26 @@ +package com.trustly.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SimpleSerializerTest { + + @Test + void testSerializer() { + + final var serializer = new Serializer(); + final var om = new ObjectMapper(); + + final var o = om.createObjectNode() + .put("q", "str") + .put("a", 1.2) + ; + + final var b = o.putObject("b") + .put("a", 3) + ; + + Assertions.assertEquals("a1.2ba3qstr", serializer.serializeNode(o)); + } +}