Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ private <T extends IData> String createSignature(String method, String uuid, T d
}

@Override
public <D extends IRequestParamsData, P extends IRequestParams<D>> void verify(IRequest<P> request) throws TrustlySignatureException {
public <D extends IRequestParamsData, P extends IRequestParams<D>> void verify(IRequest<P> request, JsonNode dataNode) 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);
this.verify(request.getMethod(), uuid, signature, data, dataNode);
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/trustly/api/client/JsonRpcSigner.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public interface JsonRpcSigner {

<T extends IResponseResultData> JsonRpcResponse<T> sign(JsonRpcResponse<T> response);

<D extends IRequestParamsData, P extends IRequestParams<D>> void verify(IRequest<P> request) throws TrustlySignatureException;
<D extends IRequestParamsData, P extends IRequestParams<D>> void verify(IRequest<P> request, JsonNode dataNode) throws TrustlySignatureException;

<T extends IResponseResultData> void verify(JsonRpcResponse<T> response, JsonNode nodeResponse) throws TrustlySignatureException;
}
3 changes: 3 additions & 0 deletions src/main/java/com/trustly/api/client/NotificationArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public interface NotificationFailHandler {
@Valid
private final D data;

@Getter
private final String method;

@Getter
private final String uuid;

private final NotificationOkHandler onOK;
Expand Down
27 changes: 26 additions & 1 deletion src/main/java/com/trustly/api/client/TrustlyApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
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.deposit.azura.AzuraDepositRequestData;
import com.trustly.api.domain.methods.deposit.azura.AzuraDepositResponseData;
import com.trustly.api.domain.methods.deposit.azura.AzuraRemoveAccountRequestData;
import com.trustly.api.domain.methods.deposit.azura.AzuraRemoveAccountResponseData;
import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsRequestData;
import com.trustly.api.domain.methods.getwithdrawals.GetWithdrawalsResponseData;
import com.trustly.api.domain.methods.merchantsettlement.MerchantSettlementRequestData;
Expand Down Expand Up @@ -441,6 +445,20 @@ public WithdrawResponseData withdraw(WithdrawRequestData request) throws Trustly
return this.sendRequest(request, WithdrawResponseData.class, "Withdraw", null);
}

/**
* TODO insert javadoc
*/
public AzuraDepositResponseData azuraDeposit(AzuraDepositRequestData request) throws TrustlyRequestException {
return this.sendRequest(request, AzuraDepositResponseData.class, "AzuraDeposit", null);
}

/**
* TODO insert javadoc
*/
public AzuraRemoveAccountResponseData azuraRemoveAccount(AzuraRemoveAccountRequestData request) throws TrustlyRequestException {
return this.sendRequest(request, AzuraRemoveAccountResponseData.class, "RemoveAzuraAccount", null);
}

// Notifications

/**
Expand Down Expand Up @@ -720,12 +738,19 @@ private <D extends IFromTrustlyRequestData> void handleNotification(
NotificationFailHandler onFailed
) throws IOException, TrustlyValidationException, TrustlySignatureException {

// Get the JsonNode for the data field for verifying later
JsonNode jsonToken = this.objectMapper.readTree(jsonString);
JsonNode dataToken = null;
if (jsonToken.at("/params/data") != null) {
dataToken = jsonToken.at("/params/data");
}

JavaType javaRequestType = this.objectMapper.getTypeFactory().constructParametricType(NotificationRequest.class, meta.getDataClass());
NotificationRequest<D> rpcRequest = this.objectMapper.readValue(jsonString, javaRequestType);

// Verify the notification (RpcRequest from Trustly) signature.
try {
this.signer.verify(rpcRequest);
this.signer.verify(rpcRequest, dataToken);
} 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?",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,21 @@ public class AbstractAccountDataAttributes extends AbstractRequestParamsDataAttr
String unchangeableNationalIdentificationNumber;

/**
* @deprecated (see ReturnToAppURL)
* 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).
*/
@Deprecated
@JsonProperty("URLScheme")
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 this link for more info. 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("ReturnToAppURL")
String returnToAppURL;
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,11 @@ public class DepositRequestDataAttributes extends AbstractAmountConstrainedAccou
*/
@JsonProperty(value = "RequestKYC")
private String requestKyc;

/**
* The Deposit request starts the deposit process at Trustly. It includes the same parameters as a standard deposit request,
* along with an additional Azura object containing attributes.
*/
@JsonProperty(value = "Azura")
private DepositRequestDataAzura azura;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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 jakarta.validation.constraints.NotBlank;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;

@Value
@Builder(toBuilder = true)
@Jacksonized
@RequiredArgsConstructor
@JsonInclude(Include.NON_NULL)
public class DepositRequestDataAzura {

/**
* Same value that was returned in the response to the initial call to AzuraDeposit.
*/
@JsonProperty(value = "AzuraSessionID", required = true)
@NotBlank
String azuraSessionId;

/**
* SELECT_ACCOUNT: Deposit will have specified account preselected.
* SELECT_BANK: Deposit will have specified bank preselected.
* NO_SELECTION: Deposit will not have a preselected account or bank.
*/
@JsonProperty(value = "Action", required = true)
@NotBlank
String action;

/**
* Id of the account that user wants to use. Should be the value from the field ‘accountid’ that is returned from the AzuraDeposit call.
* Note: Required if Action is SELECT_ACCOUNT
*/
@JsonProperty("AccountID")
String accountId;

/**
* Id of the bank to use. Should be the value from the field ‘bankid’ that is returned from the AzuraDeposit call.
* Note: Required if Action is SELECT_BANK
*/
@JsonProperty("BankID")
String bankId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.trustly.api.domain.methods.deposit.azura;

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.Valid;
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 AzuraDepositRequestData extends AbstractToTrustlyRequestData<AzuraDepositRequestDataAttributes> {

@JsonProperty(value = "MessageID", required = true)
@NotBlank
private String messageId;

@JsonProperty(value = "Attributes", required = true)
@JsonInclude(Include.NON_NULL)
@Valid
@Override
public AzuraDepositRequestDataAttributes getAttributes() {
return super.getAttributes();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.trustly.api.domain.methods.deposit.azura;

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;

@Data
@SuperBuilder(toBuilder = true)
@EqualsAndHashCode(callSuper = true)
@RequiredArgsConstructor
@AllArgsConstructor
@JsonInclude(Include.NON_NULL)
public class AzuraDepositRequestDataAttributes extends AbstractRequestParamsDataAttributes {

/**
* The email of the consumer.
*/
@JsonProperty(value = "Email")
@Email
String email;

/**
* The mobile phone number of the end-user in international format.
*/
@JsonProperty(value = "MobilePhone")
String mobilePhone;

/**
* 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")
String endUserID;

/**
* The ISO 3166-1-alpha-2 code of the end-user's country.
*/
@JsonProperty(value = "Country", required = true)
@NotBlank
@Pattern(regexp = "[A-Z]{2}")
String country;

/**
* The currency of the end-user's account in the merchant's system.
*/
@JsonProperty(value = "Currency", required = true)
@NotBlank
String currency;

/**
* Only for Gaming
* If it's set to 1, it means requiring KYC.
*/
@JsonProperty(value = "RequestKYC")
Integer requestKYC;

/**
* Only for Express Merchant Onboarding
* Human-readable identifier of the consumer-facing merchant (e.g. legal name or trade name).
*/
@JsonProperty(value = "PSPMerchant")
String pspMerchant;

/**
* 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.
*/
@JsonProperty(value = "RequestDirectDebitMandate")
String requestDirectDebitMandate;

/**
* Only for Trustly Direct Debit.
* In order to let the consumer choose to sign up for a recurring mandate,
* the attribute QuickDeposit with the value 1 shall be included in the call.
*/
@JsonProperty(value = "QuickDeposit")
Integer quickDeposit;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.trustly.api.domain.methods.deposit.azura;

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 AzuraDepositResponseData extends AbstractResponseResultData {

/**
* ID that you will send in the next call.
*/
@JsonProperty("azurasessionid")
String azuraSessionId;

/**
* Array of objects containing information about the found accounts, sorted with the best match listed first.
*/
@JsonProperty("accounts")
List<AzuraDepositResponseDataAccount> accounts;

/**
* Trustly assets.
*/
@JsonProperty("trustlyinfo")
AzuraDepositResponseDataTrustlyInfo trustlyInfo;

/**
* A list of countries and their banks, which can be utilized to display bank logos in the checkout.
*/
@JsonProperty("countries")
List<AzuraDepositResponseDataCountry> countries;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.trustly.api.domain.methods.deposit.azura;

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 AzuraDepositResponseDataAccount {

/**
* Identifies the suggested account.
* You will send this account id in the next call if the user chose to continue with this account.
*/
@JsonProperty("accountid")
String accountId;

/**
* A masked representation of the account number.
*/
@JsonProperty("accountnumbermasked")
String accountNumberMasked;

/**
* The last digits of the account number.
*/
@JsonProperty("accountnumberlastdigits")
String accountNumberLastDigits;

/**
* An object with bank data.
*/
@JsonProperty("bank")
AzuraDepositResponseDataBank bank;
}
Loading