
com.riskified.RiskifiedClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of riskified-sdk Show documentation
Show all versions of riskified-sdk Show documentation
Risikified rest api SDK for java
The newest version!
package com.riskified;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.riskified.models.*;
import com.riskified.validations.FieldBadFormatException;
import com.riskified.validations.IValidated;
import com.riskified.validations.Validation;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AUTH;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.ProxyAuthenticationStrategy;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
/**
* Riskified API Client
* The client implements the API for Riskified as described in:
* http://apiref.riskified.com/
*/
public class RiskifiedClient {
private Validation validation = Validation.ALL;
private Environment environment = Environment.SANDBOX;
private String baseUrl;
private String baseUrlSyncAnalyze;
private String decoBaseUrl;
private String accountBaseUrl;
private String shopUrl;
private SHA256Handler sha256Handler;
private int requestTimeout = 10000;
private int connectionTimeout = 5000;
private String authKey;
private String proxyUrl;
private int proxyPort;
private String proxyUsername;
private String proxyPassword;
private HttpClientContext context;
/**
* Riskified API client
* use configuration file: "src/main/resources/riskified_sdk.properties"
* uses the keys: shopUrl, authKey, environment, debugRiskifiedHostUrl
* see full doc on GitHub
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient() throws RiskifiedError {
Properties properties = new Properties();
try {
properties.load(getClass().getClassLoader().getResourceAsStream("riskified_sdk.properties"));
} catch (IOException e) {
throw new RiskifiedError("There was an error reading the config file in: src/main/resources/riskified_sdk.properties");
}
String shopUrl = properties.getProperty("shopUrl");
String authKey = properties.getProperty("authKey");
String environmentType = properties.getProperty("environment");
String validationType = properties.getProperty("validation");
String proxyUrl = properties.getProperty("proxyUrl");
String proxyPort = properties.getProperty("proxyPort");
String proxyUserName = properties.getProperty("proxyUsername");
String proxyPassword = properties.getProperty("proxyPassword");
if (validationType.equals("NONE")) {
validation = Validation.NONE;
} else if (validationType.equals("IGNORE_MISSING")) {
validation = Validation.IGNORE_MISSING;
} else if(validationType.equals("ALL")) {
validation = Validation.ALL;
}
if (environmentType.equals("DEBUG")) {
environment = Environment.DEBUG;
} else if (environmentType.equals("PRODUCTION")) {
environment = Environment.PRODUCTION;
} else if (environmentType.equals("SANDBOX")) {
environment = Environment.SANDBOX;
}
init(shopUrl, authKey, Utils.getBaseUrlFromEnvironment(environment), Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment), Utils.getDecoBaseFromEnvironment(environment), Utils.getAccountBaseFromEnvironment(environment), validation);
if (proxyUrl != null) {
initProxy(proxyUrl, proxyPort, proxyUserName, proxyPassword);
}
}
/**
* Riskified API client
* don't use config file
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param environment The Riskified environment (SANDBOX / PRODUCTION)
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient(String shopUrl, String authKey, Environment environment) throws RiskifiedError {
init(shopUrl, authKey, Utils.getBaseUrlFromEnvironment(environment), Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment), Utils.getDecoBaseFromEnvironment(environment), Utils.getAccountBaseFromEnvironment(environment), Validation.ALL);
}
/**
* Riskified API client (with proxy)
* don't use config file
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param environment The Riskified environment (SANDBOX / PRODUCTION)
* @param proxyClientDetails proxy details
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient(String shopUrl, String authKey, Environment environment, ProxyClientDetails proxyClientDetails) throws RiskifiedError {
init(shopUrl, authKey, Utils.getBaseUrlFromEnvironment(environment), Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment), Utils.getDecoBaseFromEnvironment(environment), Utils.getAccountBaseFromEnvironment(environment), Validation.ALL);
initProxy(proxyClientDetails);
}
/**
* Riskified API client
* don't use config file
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param environment The Riskified environment (SANDBOX / PRODUCTION)
* @param validation The sdk's validation strategy
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient(String shopUrl, String authKey, Environment environment, Validation validation) throws RiskifiedError {
init(shopUrl, authKey, Utils.getBaseUrlFromEnvironment(environment), Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment), Utils.getDecoBaseFromEnvironment(environment), Utils.getAccountBaseFromEnvironment(environment), validation);
}
/**
* Riskified API client (with proxy)
* don't use config file
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param environment The Riskifed environment (SANDBOX / PRODUCTION)
* @param validation The sdk's validation strategy
* @param proxyClientDetails proxy details
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient(String shopUrl, String authKey, Environment environment, Validation validation, ProxyClientDetails proxyClientDetails) throws RiskifiedError {
init(shopUrl, authKey, Utils.getBaseUrlFromEnvironment(environment), Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment), Utils.getDecoBaseFromEnvironment(environment), Utils.getAccountBaseFromEnvironment(environment), validation);
initProxy(proxyClientDetails);
}
/**
* Riskified API client
* don't use config file
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param validation The sdk's validation strategy
* @param baseUrl base riskified host
* @param baseUrlSyncAnalyze base riskified sync-api host
* @param decoBaseUrl deco host
* @param accountBaseUrl account host
* @throws RiskifiedError When there was a critical error, look at the exception to see more data
*/
public RiskifiedClient(String shopUrl, String authKey, Validation validation, String baseUrl, String baseUrlSyncAnalyze, String decoBaseUrl, String accountBaseUrl) throws RiskifiedError {
init(shopUrl, authKey, baseUrl, baseUrlSyncAnalyze, decoBaseUrl, accountBaseUrl, validation);
}
private void init(String shopUrl, String authKey, String baseUrl, String baseUrlSyncAnalyze, String decoBaseUrl, String accountBaseUrl, Validation validationType) throws RiskifiedError {
this.baseUrl = baseUrl;
this.baseUrlSyncAnalyze = baseUrlSyncAnalyze;
this.decoBaseUrl = decoBaseUrl;
this.accountBaseUrl = accountBaseUrl;
this.shopUrl = shopUrl;
this.sha256Handler = new SHA256Handler(authKey);
this.validation = validationType;
}
private void initProxy(String proxyUrl, String proxyPort, String proxyUsername, String proxyPassword) {
this.proxyUrl = proxyUrl;
this.proxyPort = Integer.parseInt(proxyPort);
this.proxyUsername = proxyUsername;
this.proxyPassword = proxyPassword;
}
private void initProxy(ProxyClientDetails proxyClientDetails) {
this.proxyUrl = proxyClientDetails.getProxyUrl();
this.proxyPort = proxyClientDetails.getProxyPort();
this.proxyUsername = proxyClientDetails.getProxyUsername();
this.proxyPassword = proxyClientDetails.getProxyPassword();
}
/**
* Send a new checkout order to Riskified
* @param order The checkout order to create (Checkout order has the same fields like Order but ALL fields are optional)
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response checkoutOrder(CheckoutOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/checkout_create";
// Validation.ALL is not relevant when checkout.
if(validation != validation.NONE) {
validate(order, Validation.IGNORE_MISSING);
}
return postCheckoutOrder(new CheckoutOrderWrapper(order), url);
}
// TODO add other paramaters Riskified server will return
/**
* Send a new advise order to Riskified
* @param order The advise order to create
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response adviseOrder(CheckoutOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/advise";
// Validation.ALL is not relevant when checkout.
if(validation != validation.NONE) {
validate(order, Validation.IGNORE_MISSING);
}
return postCheckoutOrder(new CheckoutOrderWrapper(order), url);
}
/**
* Send a new checkout order to Riskified
* @param order The checkout order to create (Checkout order has the same fields like Order but ALL fields are optional)
* @param validation Determines what type of validation will take place
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response checkoutOrder(CheckoutOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/checkout_create";
validate(order, validation);
return postCheckoutOrder(new CheckoutOrderWrapper(order), url);
}
/**
* Mark a previously checkout order has been denied.
* @param order The checkout denied order details, mark as denied and also can specify why it was denied.
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response checkoutDeniedOrder(CheckoutDeniedOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/checkout_denied";
validate(order);
return postCheckoutOrder(new CheckoutOrderWrapper(order), url);
}
/**
* Mark a previously checkout order has been denied.
* @param order The checkout denied order details, mark as denied and also can specify why it was denied.
* @param validation Determines what type of validation will take place
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response checkoutDeniedOrder(CheckoutDeniedOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/checkout_denied";
validate(order, validation);
return postCheckoutOrder(new CheckoutOrderWrapper(order), url);
}
/**
* Send a new order to Riskified
* Depending on your current plan, the newly created order might not be submitted automatically for review.
* @param order An order to create
* Any missing fields (such as BIN number or AVS result code) that are unavailable during the time of the request should be skipped or passed as null
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response createOrder(Order order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/create";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Send a new order to Riskified
* Depending on your current plan, the newly created order might not be submitted automatically for review.
* @param order An order to create
* @param validation Determines what type of validation will take place
* Any missing fields (such as BIN number or AVS result code) that are unavailable during the time of the request should be skipped or passed as null
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response createOrder(Order order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/create";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Submit a new or existing order to Riskified for review
* Forces the order to be submitted for review, regardless of your current plan.
* @param order An order to submit for review.
* Any missing fields (such as BIN number or AVS result code) that are unavailable during the time of the request should be skipped or passed as null.
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response submitOrder(Order order) throws IOException, FieldBadFormatException {
return submitOrder(order, validation);
}
/**
* Submit a new or existing order to Riskified for review
* Forces the order to be submitted for review, regardless of your current plan.
* @param order An order to submit for review.
* Any missing fields (such as BIN number or AVS result code) that are unavailable during the time of the request should be skipped or passed as null.
* @param validation Determines what type of validation will take place
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response submitOrder(Order order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/submit";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Update details of an existing order.
* Orders are differentiated by their id field. To update an existing order, include its id and any up-to-date data.
* @param order A (possibly incomplete) order to update
* The order must have an id field referencing an existing order and at least one additional field to update.
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response updateOrder(Order order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/update";
// Validation.ALL is not relevant when updating.
if(validation != validation.NONE) {
validate(order, Validation.IGNORE_MISSING);
}
return postOrder(new OrderWrapper(order), url);
}
/**
* Update details of an existing order.
* Orders are differentiated by their id field. To update an existing order, include its id and any up-to-date data.
* @param order A (possibly incomplete) order to update
* The order must have an id field referencing an existing order and at least one additional field to update.
* @param validation Determines what type of validation will take place
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response updateOrder(Order order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/update";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Mark a previously submitted order as cancelled.
* If the order has not yet been reviewed, it is excluded from future review.
* If the order has already been reviewed and approved, canceling it will also trigger a full refund on any associated charges.
* An order can only be cancelled during a relatively short time window after its creation.
* @param order The order to cancel
* @see CancelOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response cancelOrder(CancelOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/cancel";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Mark a previously submitted order as cancelled.
* If the order has not yet been reviewed, it is excluded from future review.
* If the order has already been reviewed and approved, canceling it will also trigger a full refund on any associated charges.
* An order can only be cancelled during a relatively short time window after its creation.
* @param order The order to cancel
* @param validation Determines what type of validation will take place
* @see CancelOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response cancelOrder(CancelOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/cancel";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Issue a partial refund for an existing order.
* Any associated charges will be updated to reflect the new order total amount.
* @param order The refund Order
* @see RefundOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response refundOrder(RefundOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/refund";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Issue a partial refund for an existing order.
* Any associated charges will be updated to reflect the new order total amount.
* @param order The refund Order
* @param validation Determines what type of validation will take place
* @see RefundOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response refundOrder(RefundOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/refund";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Mark a previously submitted order that is was fulfilled.
* @param order The fulfillment order details
* @see FulfillmentOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response fulfillOrder(FulfillmentOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/fulfill";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Mark a previously submitted order that is was fulfilled.
* @param order The fulfillment order details
* @param validation Determines what type of validation will take place
* @see FulfillmentOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response fulfillOrder(FulfillmentOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/fulfill";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Set the decision made for order that was not submitted.
* @param order The decision order details
* @see DecisionOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response decisionOrder(DecisionOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/decision";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Set the decision made for order that was not submitted.
* @param order The decision order details
* @param validation Determines what type of validation will take place
* @see DecisionOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response decisionOrder(DecisionOrder order, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/decision";
validate(order, validation);
return postOrder(new OrderWrapper(order), url);
}
/**
* Send and analyze a new order to Riskified
* Analyzes the order synchronicly, the returned status is Riskified's analysis review result.
* @param order An order to create and analyze
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response analyzeOrder(Order order) throws IOException, FieldBadFormatException {
String url = baseUrlSyncAnalyze + "/api/decide";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Check eligibility for Deco
* After checkout_denied, Inquiry if order is eligible for Deco.
* @param order An order to check Deco eligibility (only the order id is needed)
* @see Response
* @return Response object, including the status from the Deco server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response eligible(Order order) throws IOException, FieldBadFormatException {
String url = decoBaseUrl + "/api/eligible";
return postOrder(new OrderWrapper(order), url);
}
/**
* Opt-in to Deco
* Notifies Deco the customer has chosen to utilize Deco’s service
* @param order An order to opt-in to Deco payment (only the order id is needed)
* @see Response
* @return Response object, including the status from the Deco server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response opt_in(Order order) throws IOException, FieldBadFormatException {
String url = decoBaseUrl + "/api/opt_in";
return postOrder(new OrderWrapper(order), url);
}
/**
* The chargeback API will allow merchants to request a fraud-related chargeback reimbursement.
* The submitted request will be processed within 48 hours.
* Eligible requests will trigger an automatic credit refund by Riskified.
* An eligible chargeback reimbursement request must match the details provided originally within the order JSON
* and contain a fraudulent chargeback reason code. For tangible goods,
* Riskified uses the tracking number provided in the fulfillment parameter to ensure the parcel was delivered
* to the address provided within the order JSON. Riskified reserves the right to request additional documentation
* pertaining to submitted chargebacks as part of the eligibility review process.
* @param order The order to mark as chargeback
* @see ChargebackOrder
* @see Response
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response chargebackOrder(ChargebackOrder order) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/chargeback";
validate(order);
return postOrder(new OrderWrapper(order), url);
}
/**
* Send an array (batch) of existing/historical orders to Riskified.
* Use the decision field to provide information regarding each order status.
*
* Orders sent will be used to build analysis models to better analyze newly received orders.
*
* @param orders A list of historical orders to send
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response historicalOrders(ArrayOrders orders) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/historical";
validate(orders);
return postOrder(orders, url);
}
/**
* Send an array (batch) of existing/historical orders to Riskified.
* Use the financial_status field to provide information regarding each order status:
* * 'approved' - approved orders
* * 'declined-fraud' - declined orders (refunded or voided) as suspected fraud
* * 'declined' - declined orders (refunded or voided) without connection to fraud
* * 'chargeback' - orders that received a chargeback
*
* Orders sent will be used to build analysis models to better analyze newly received orders.
*
* @param orders A list of historical orders to send
* @param validation Determines what type of validation will take place
* @return Response object, including the status from Riskified server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response historicalOrders(ArrayOrders orders, Validation validation) throws IOException, FieldBadFormatException {
String url = baseUrl + "/api/historical";
validate(orders, validation);
return postOrder(orders, url);
}
/**
* Login Account Action
* Notifies Riskified that there has been a login account action
* @param login A login object
* @see Response
* @return Response object, including the status from the Deco server
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response login(Login login) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/login";
validate(login, validation);
return postOrder(login, url);
}
/**
* Customer Create Account Action
* Notifies Riskified that there has been a customer create account action
* @param customerCreate A customer create object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response customerCreate(CustomerCreate customerCreate) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/customer_create";
validate(customerCreate, validation);
return postOrder(customerCreate, url);
}
/**
* Customer Update Account Action
* Notifies Riskified that there has been a customer update account action
* @param customerUpdate A customer create object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response customerUpdate(CustomerUpdate customerUpdate) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/customer_update";
validate(customerUpdate, validation);
return postOrder(customerUpdate, url);
}
/**
* Logout Account Action
* Notifies Riskified that there has been a logout account action
* @param logout A logout object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response logout(Logout logout) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/logout";
validate(logout, validation);
return postOrder(logout, url);
}
/**
* ResetPassword Account Action
* Notifies Riskified that there has been a reset password account action
* @param resetPassword A resetPassword object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response resetPassword(ResetPassword resetPassword) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/reset_password";
validate(resetPassword, validation);
return postOrder(resetPassword, url);
}
/**
* Wishlist Account Action
* Notifies Riskified that there has been a wishlist account action
* @param wishlist A Wishlist object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response wishlist(Wishlist wishlist) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/wishlist";
validate(wishlist, validation);
return postOrder(wishlist, url);
}
/**
* Redeem Account Action
* Notifies Riskified that there has been a redeem account action
* @param redeem A Redeem object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response redeem(Redeem redeem) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/redeem";
validate(redeem, validation);
return postOrder(redeem, url);
}
/**
* Contact Account Action
* Notifies Riskified that there has been a contact account action
* @param contact A Contact object
* @see Response
* @return OK if good, object with error if bad request
* @throws ClientProtocolException in case of a problem or the connection was aborted
* @throws IOException in case of an http protocol error
* @throws HttpResponseException The server respond status wasn't 200
* @throws FieldBadFormatException bad format found on field
*/
public Response contact(Contact contact) throws IOException, FieldBadFormatException {
String url = accountBaseUrl + "/customers/contact";
validate(contact, validation);
return postOrder(contact, url);
}
private Response postCheckoutOrder(Object data, String url) throws IOException, FieldBadFormatException {
HttpPost request = createPostRequest(url);
addDataToRequest(data, request);
HttpResponse response;
HttpClient client = constructHttpClient();
response = executeClient(client, request);
String postBody = EntityUtils.toString(response.getEntity(), "UTF-8");
int status = response.getStatusLine().getStatusCode();
Response responseObject = getCheckoutResponseObject(postBody);
switch (status) {
case 200:
return responseObject;
case 400:
throw new HttpResponseException(status, responseObject.getError().getMessage());
case 401:
throw new HttpResponseException(status, responseObject.getError().getMessage());
case 404:
throw new HttpResponseException(status, responseObject.getError().getMessage());
case 504:
throw new HttpResponseException(status, "Temporary error, please retry");
default:
throw new HttpResponseException(500, "Contact Riskified support");
}
}
private HttpClient constructHttpClient() {
RequestConfig.Builder requestBuilder = RequestConfig.custom()
.setConnectTimeout(connectionTimeout)
.setConnectionRequestTimeout(requestTimeout);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setDefaultRequestConfig(requestBuilder.build());
if (this.proxyUrl != null) {
setProxyWithAuth(builder);
}
return builder.build();
}
private HttpResponse executeClient(HttpClient client, HttpPost request)
throws IOException {
HttpResponse response;
if (context != null) {
response = client.execute(request, context);
} else {
response = client.execute(request);
}
return response;
}
private CredentialsProvider getHttpProxyCredentials() {
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(new HttpHost(this.proxyUrl, this.proxyPort)),
new UsernamePasswordCredentials(this.proxyUsername, this.proxyPassword));
return credsProvider;
}
private void setProxyWithAuth(HttpClientBuilder builder) {
builder.setProxy(new HttpHost(proxyUrl, proxyPort));
builder.setDefaultCredentialsProvider(getHttpProxyCredentials());
builder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
if (this.context == null) {
try {
setProxyContext();
} catch (MalformedChallengeException e) {
System.out.println("Error: failed to process challenge for proxy");
}
}
}
private void setProxyContext() throws MalformedChallengeException {
BasicScheme proxyAuth = new BasicScheme();
proxyAuth.processChallenge(new BasicHeader(AUTH.PROXY_AUTH,
"BASIC realm=default"));
BasicAuthCache authCache = new BasicAuthCache();
authCache.put(new HttpHost(this.proxyUrl, this.proxyPort), proxyAuth);
HttpClientContext context = HttpClientContext.create();
context.setAuthCache(authCache);
context.setCredentialsProvider(getHttpProxyCredentials());
this.context = context;
}
private Response postOrder(Object data, String url) throws IOException {
HttpPost request = createPostRequest(url);
addDataToRequest(data, request);
HttpResponse response;
HttpClient client = constructHttpClient();
response = executeClient(client, request);
String postBody = EntityUtils.toString(response.getEntity());
int status = response.getStatusLine().getStatusCode();
Response responseObject = getResponseObject(postBody);
switch (status) {
case 200:
return responseObject;
case 400:
throw new HttpResponseException(status, postBody);
case 401:
throw new HttpResponseException(status, postBody);
case 404:
throw new HttpResponseException(status, postBody);
case 504:
throw new HttpResponseException(status, "Temporary error, please retry");
default:
throw new HttpResponseException(500, "Contact Riskified support");
}
}
private Response getResponseObject(String postBody) throws IOException {
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Response res = gson.fromJson(postBody, Response.class);
return res;
}
private CheckoutResponse getCheckoutResponseObject(String postBody) throws IOException {
Gson gson = new Gson();
CheckoutResponse res = gson.fromJson(postBody, CheckoutResponse.class);
res.setOrder(res.getCheckout());
return res;
}
private void addDataToRequest(Object data, HttpPost postRequest) throws IllegalStateException, UnsupportedEncodingException {
String jsonData = JSONFormater.toJson(data);
byte[] body = jsonData.getBytes("UTF-8");
String hmac = sha256Handler.createSHA256(body);
postRequest.setHeader("X-RISKIFIED-HMAC-SHA256", hmac);
ByteArrayEntity input;
input = new ByteArrayEntity(body, ContentType.APPLICATION_JSON);
postRequest.setEntity(input);
}
private HttpPost createPostRequest(String url) {
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HttpHeaders.ACCEPT, "application/vnd.riskified.com; version=2");
postRequest.setHeader("X-RISKIFIED-SHOP-DOMAIN", shopUrl);
postRequest.setHeader("User-Agent","riskified_java_sdk/1.2.7"); // TODO: take the version automatically
return postRequest;
}
private void validate(IValidated objToValidated) throws FieldBadFormatException {
if (this.validation != Validation.NONE) {
objToValidated.validate(this.validation);
}
}
private void validate(IValidated objToValidated, Validation validationType) throws FieldBadFormatException {
if (validationType != Validation.NONE) {
objToValidated.validate(validationType);
}
}
public String getShopUrl() {
return shopUrl;
}
public int getRequestTimeout() {
return requestTimeout;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public Environment getEnvironment() {
return environment;
}
public String getBaseUrl() {
return baseUrl;
}
public String getAuthKey() {
return authKey;
}
/**
* Change the Riskified server url
* You shouldn't use this regular
* @param url the new server url
*/
public void setBaseUrl(String url) {
this.baseUrl = url;
}
public Validation getValidation() {
return validation;
}
public void setValidation(Validation validation) {
this.validation = validation;
}
public static class RiskifiedClientBuilder {
private String shopUrl;
private String authKey;
private Environment environment;
private Integer requestTimeout;
private Integer connectionTimeout;
private Validation validation;
/**
* Required arguments to build a RiskifiedClient
* @param shopUrl The shop URL as registered in Riskified
* @param authKey From the advance settings in Riskified web site
* @param environment The Riskified environment (SANDBOX / PRODUCTION)
*/
public RiskifiedClientBuilder(String shopUrl, String authKey, Environment environment) {
this.shopUrl = shopUrl;
this.authKey = authKey;
this.environment = environment;
}
public RiskifiedClientBuilder setRequestTimeout(Integer requestTimeout) {
this.requestTimeout = requestTimeout;
return this;
}
public RiskifiedClientBuilder setConnectionTimeout(Integer connectionTimeout) {
this.connectionTimeout = connectionTimeout;
return this;
}
public RiskifiedClientBuilder setValidation(Validation validation) {
this.validation = validation;
return this;
}
public RiskifiedClient build() throws RiskifiedError {
return new RiskifiedClient(this);
}
}
public RiskifiedClient(RiskifiedClientBuilder riskifiedClientBuilder) throws RiskifiedError {
this.shopUrl = riskifiedClientBuilder.shopUrl;
this.authKey = riskifiedClientBuilder.authKey;
this.environment = riskifiedClientBuilder.environment;
if (riskifiedClientBuilder.validation != null) {
this.validation = riskifiedClientBuilder.validation;
}
if (riskifiedClientBuilder.requestTimeout != null) {
this.requestTimeout = riskifiedClientBuilder.requestTimeout;
}
if (riskifiedClientBuilder.connectionTimeout != null) {
this.connectionTimeout = riskifiedClientBuilder.connectionTimeout;
}
this.sha256Handler = new SHA256Handler(authKey);
this.baseUrl = Utils.getBaseUrlFromEnvironment(environment);
this.baseUrlSyncAnalyze = Utils.getBaseUrlSyncAnalyzeFromEnvironment(environment);
this.decoBaseUrl = Utils.getDecoBaseFromEnvironment(environment);
this.accountBaseUrl = Utils.getAccountBaseFromEnvironment(environment);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy