diff --git a/processout-sdk/src/main/java/com/processout/processout_sdk/AuthorizationRequest.java b/processout-sdk/src/main/java/com/processout/processout_sdk/AuthorizationRequest.java index 4f36c96d..c8151548 100644 --- a/processout-sdk/src/main/java/com/processout/processout_sdk/AuthorizationRequest.java +++ b/processout-sdk/src/main/java/com/processout/processout_sdk/AuthorizationRequest.java @@ -3,15 +3,22 @@ import com.google.gson.annotations.SerializedName; public class AuthorizationRequest { + @SerializedName("invoice_id") + private String invoiceID; @SerializedName("source") private String source; @SerializedName("incremental") private boolean incremental; @SerializedName("enable_three_d_s_2") - private boolean enableThreeDS2 = true; + private final boolean enableThreeDS2 = true; @SerializedName("third_party_sdk_version") private String thirdPartySDKVersion; + + + @SerializedName("preferred_scheme") + private String preferredScheme; + public AuthorizationRequest(String source, boolean incremental) { this.source = source; this.incremental = incremental; @@ -28,21 +35,51 @@ public AuthorizationRequest(String source) { this.incremental = false; } - public AuthorizationRequest(String source, String thirdPartySDKVersion) { + public AuthorizationRequest(String source, String invoiceID) { this.source = source; this.incremental = false; - this.thirdPartySDKVersion = thirdPartySDKVersion; + this.invoiceID = invoiceID; + } + + + public String getInvoiceID() { + return invoiceID; + } + + public void setInvoiceID(String invoiceID) { + this.invoiceID = invoiceID; } public String getSource() { return source; } - public boolean isEnableThreeDS2() { - return enableThreeDS2; + public void setSource(String source) { + this.source = source; + } + + public boolean isIncremental() { + return incremental; + } + public void setIncremental(boolean isIncremental) { + this.incremental = isIncremental; } + public String getThirdPartySDKVersion() { return thirdPartySDKVersion; } + + public void setThirdPartySDKVersion(String thirdPartySDKVersion) { + this.thirdPartySDKVersion = thirdPartySDKVersion; + } + + public String getPreferredScheme() { + return preferredScheme; + } + + public void setPreferredScheme(String preferredScheme) { + this.preferredScheme = preferredScheme; + } + } diff --git a/processout-sdk/src/main/java/com/processout/processout_sdk/ProcessOut.java b/processout-sdk/src/main/java/com/processout/processout_sdk/ProcessOut.java index 8176e716..a4748f84 100644 --- a/processout-sdk/src/main/java/com/processout/processout_sdk/ProcessOut.java +++ b/processout-sdk/src/main/java/com/processout/processout_sdk/ProcessOut.java @@ -4,6 +4,7 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; +import android.media.session.MediaSession; import android.net.Uri; import android.os.Build; import android.util.DisplayMetrics; @@ -38,7 +39,7 @@ public class ProcessOut { - public static final String SDK_VERSION = "v2.17.0"; + public static final String SDK_VERSION = "v2.18.0"; private String projectId; private Context context; @@ -299,7 +300,8 @@ public Uri makeAPMPayment(@NonNull GatewayConfiguration apm, @NonNull String inv public void makeCardPayment(@NonNull final String invoiceId, @NonNull final String source, final String thirdPartySDKVersion, @NonNull final ThreeDSHandler handler, @NonNull final Context with) { try { // Generate the authorization body and forces 3DS2 - AuthorizationRequest authRequest = new AuthorizationRequest(source, thirdPartySDKVersion); + AuthorizationRequest authRequest = new AuthorizationRequest(source, invoiceId); + authRequest.setThirdPartySDKVersion(thirdPartySDKVersion); final JSONObject body = new JSONObject(gson.toJson(authRequest)); requestAuthorization(invoiceId, body, new RequestAuthorizationCallback() { @@ -381,6 +383,55 @@ public void shouldContinue(String source) { } } + /** + * Allow card payments authorization (with 3DS2 support) + * + * @param AuthorizationRequest contains all the necessary fields to initiate an authorisation request. + * @param handler (Custom 3DS2 handler) + */ + public void makeCardPayment(@NonNull final AuthorizationRequest AuthorizationRequest, @NonNull final ThreeDSHandler handler, @NonNull final Context with) { + try { + // Handle empty source + if (AuthorizationRequest.getSource().isEmpty()) { + handler.onError(new ProcessOutException("Validation error, you must supply the source in the AuthorizationRequest!")); + } + + final JSONObject body = new JSONObject(gson.toJson(AuthorizationRequest)); + + requestAuthorization(AuthorizationRequest.getInvoiceID(), body, new RequestAuthorizationCallback() { + @Override + public void onError(Exception error) { + handler.onError(error); + } + + @Override + public void onSuccess(JSONObject json) { + // Handle the authorization result + AuthorizationResult result = gson.fromJson( + json.toString(), AuthorizationResult.class); + + CustomerAction cA = result.getCustomerAction(); + if (cA == null) { + // No customer action in the authorization result, we return the invoice id + handler.onSuccess(AuthorizationRequest.getInvoiceID()); + return; + } + + CustomerActionHandler customerActionHandler = new CustomerActionHandler(handler, new PaymentWebView(with), with, new CustomerActionHandler.CustomerActionCallback() { + @Override + public void shouldContinue(String source) { + makeCardPayment(AuthorizationRequest, handler, with); + } + }); + customerActionHandler.handleCustomerAction(cA); + } + }); + } catch (JSONException e) { + handler.onError(e); + } + } + + /** * Allow card payments authorization and marks the authorization as incremental (with 3DS2 support) * @@ -438,7 +489,8 @@ public void shouldContinue(String source) { public void makeIncrementalAuthorizationPayment(@NonNull final String invoiceId, @NonNull final String source, final String thirdPartySDKVersion, @NonNull final ThreeDSHandler handler, @NonNull final Context with) { try { // Generate the authorization body and forces 3DS2 - AuthorizationRequest authRequest = new AuthorizationRequest(source, true, thirdPartySDKVersion); + AuthorizationRequest authRequest = new AuthorizationRequest(source, true); + authRequest.setThirdPartySDKVersion(thirdPartySDKVersion); final JSONObject body = new JSONObject(gson.toJson(authRequest)); requestAuthorization(invoiceId, body, new RequestAuthorizationCallback() { @@ -474,6 +526,55 @@ public void shouldContinue(String source) { } } + /** + * Allow card payments authorization and marks the authorization as incremental (with 3DS2 support) + * + * @param AuthorizationRequest contains all the necessary fields to initiate an authorisation request. + * @param handler (Custom 3DS2 handler) + */ + public void makeIncrementalAuthorizationPayment(@NonNull final AuthorizationRequest AuthorizationRequest, @NonNull final ThreeDSHandler handler, @NonNull final Context with) { + try { + // Handle empty source + if (AuthorizationRequest.getSource().isEmpty()) { + handler.onError(new ProcessOutException("Validation error, you must supply the source in the AuthorizationRequest!")); + } + + final JSONObject body = new JSONObject(gson.toJson(AuthorizationRequest)); + AuthorizationRequest.setIncremental(true); + + requestAuthorization(AuthorizationRequest.getInvoiceID(), body, new RequestAuthorizationCallback() { + @Override + public void onError(Exception error) { + handler.onError(error); + } + + @Override + public void onSuccess(JSONObject json) { + // Handle the authorization result + AuthorizationResult result = gson.fromJson( + json.toString(), AuthorizationResult.class); + + CustomerAction cA = result.getCustomerAction(); + if (cA == null) { + // No customer action in the authorization result, we return the invoice id + handler.onSuccess(AuthorizationRequest.getInvoiceID()); + return; + } + + CustomerActionHandler customerActionHandler = new CustomerActionHandler(handler, new PaymentWebView(with), with, new CustomerActionHandler.CustomerActionCallback() { + @Override + public void shouldContinue(String source) { + makeIncrementalAuthorizationPayment(AuthorizationRequest, handler, with); + } + }); + customerActionHandler.handleCustomerAction(cA); + } + }); + } catch (JSONException e) { + handler.onError(e); + } + } + /** * Increments the authorization of an applicable invoice by a given amount * @@ -601,6 +702,57 @@ public void shouldContinue(String source) { } } + /** + * Create a customer token from a card ID + * + * @param TokenRequest contains all the fields necessary for the token request. + * @param handler 3DS2 handler + * @param with Activity to display webviews and perform fingerprinting + */ + public void makeCardToken(@NonNull final TokenRequest TokenRequest, @NonNull final ThreeDSHandler handler, @NonNull final Context with) { + try { + + // Handle empty fields + if (TokenRequest.getTokenID().isEmpty() || TokenRequest.getCustomerID().isEmpty() || TokenRequest.getSource().isEmpty()) { + handler.onError(new ProcessOutException("Validation error, you must supply the source, tokenID and customerID in the TokenRequest!")); + } + + final JSONObject body = new JSONObject(gson.toJson(TokenRequest)); + + Network.getInstance(this.context, this.projectId).CallProcessOut("/customers/" + TokenRequest.getCustomerID() + + "/tokens/" + TokenRequest.getTokenID(), Request.Method.PUT, body, new Network.NetworkResult() { + @Override + public void onError(Exception error) { + handler.onError(error); + } + + @Override + public void onSuccess(JSONObject json) { + // Handle the authorization result + AuthorizationResult result = gson.fromJson( + json.toString(), AuthorizationResult.class); + + CustomerAction cA = result.getCustomerAction(); + if (cA == null) { + // No customer action in the authorization result, we return the invoice id + handler.onSuccess(TokenRequest.getTokenID()); + return; + } + + CustomerActionHandler customerActionHandler = new CustomerActionHandler(handler, new CardTokenWebView(with), with, new CustomerActionHandler.CustomerActionCallback() { + @Override + public void shouldContinue(String source) { + makeCardToken(TokenRequest, handler, with); + } + }); + customerActionHandler.handleCustomerAction(cA); + } + }); + } catch (JSONException e) { + handler.onError(e); + } + } + /** * Parses a intent uri * diff --git a/processout-sdk/src/main/java/com/processout/processout_sdk/TokenRequest.java b/processout-sdk/src/main/java/com/processout/processout_sdk/TokenRequest.java index fde583d9..83a6f0ff 100644 --- a/processout-sdk/src/main/java/com/processout/processout_sdk/TokenRequest.java +++ b/processout-sdk/src/main/java/com/processout/processout_sdk/TokenRequest.java @@ -2,16 +2,23 @@ import com.google.gson.annotations.SerializedName; -class TokenRequest { +public class TokenRequest { + @SerializedName("customer_id") + private String customerID; + @SerializedName("token_id") + private String tokenID; @SerializedName("source") private String source; @SerializedName("verify") - private boolean verify = true; + private final boolean verify = true; @SerializedName("enable_three_d_s_2") - private boolean enableThreeDS2 = true; + private final boolean enableThreeDS2 = true; @SerializedName("third_party_sdk_version") private String thirdPartySDKVersion; + @SerializedName("preferred_scheme") + private String preferredScheme; + TokenRequest(String source) { this.source = source; } @@ -20,4 +27,48 @@ class TokenRequest { this.source = source; this.thirdPartySDKVersion = thirdPartySDKVersion; } + + TokenRequest(String tokenID, String customerID, String source) { + this.tokenID = tokenID; + this.customerID = customerID; + this.source = source; + } + + public String getCustomerID() { + return customerID; + } + public String getTokenID() { + return tokenID; + } + public String getSource() { + return source; + } + + public void setCustomerID(String customerID) { + this.customerID = customerID; + } + + public void setTokenID(String tokenID) { + this.tokenID = tokenID; + } + + public void setSource(String source) { + this.source = source; + } + + public String getThirdPartySDKVersion() { + return thirdPartySDKVersion; + } + + public void setThirdPartySDKVersion(String thirdPartySDKVersion) { + this.thirdPartySDKVersion = thirdPartySDKVersion; + } + + public String getPreferredScheme() { + return preferredScheme; + } + + public void setPreferredScheme(String preferredScheme) { + this.preferredScheme = preferredScheme; + } }