Skip to content

Commit

Permalink
Merge pull request #122 from Adyen/develop
Browse files Browse the repository at this point in the history
Release 5.0.0
  • Loading branch information
rkewlani authored Jul 2, 2019
2 parents d3293af + 075e03b commit f07c2d5
Show file tree
Hide file tree
Showing 47 changed files with 1,873 additions and 132 deletions.
28 changes: 18 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ Required for the checkout:
<extension dir="${HYBRIS_BIN_DIR}/custom/adyen-hybris/adyenv6b2ccheckoutaddon"/>
<extension dir="${HYBRIS_BIN_DIR}/custom/adyen-hybris/adyenv6backoffice"/>
```
Required for the notifications:
```
<extension dir="${HYBRIS_BIN_DIR}/custom/adyen-hybris/adyenv6notification"/>
```

Additionally, required when using yacceleratorordermanagement (b2c_acc_oms recipe):
```
Expand All @@ -33,9 +37,9 @@ Additionally, required when using yacceleratorfulfilment (b2c_acc recipe):
<extension dir="${HYBRIS_BIN_DIR}/custom/adyen-hybris/adyenv6fulfilmentprocess"/>
```

### 3. Modify local.properties
### 3. Modify local.properties

Modify config/local.properties file:
Modify config/local.properties file:
append ,/[^/]+(/[^?]*)+(adyen-response)$,/adyen(/[^?]*)+$ to the value of csrf.allowed.url.patterns

### 4. Build
Expand All @@ -56,12 +60,11 @@ Please make sure your merchant has Variant true in API and responses section so

### Credit Cards

Credit Card payments are supported using [Client Side Encryption](https://docs.adyen.com/support/payment-glossary/client-side-encryption-cse).
Credit Card payments are supported using Checkout Components.

### Klarna
### Ratepay

Klarna is supported via Adyen API.
Requires shopper data listed in: https://developers.klarna.com/en/se/kpm/test-credentials
Ratepay is supported via Adyen API.

### Boleto

Expand All @@ -79,7 +82,7 @@ More details can be found here: https://docs.adyen.com/developers/payment-method

### Other alternative payment methods

Supported via Adyen [Hosted Payment Pages](https://docs.adyen.com/developers/products-and-subscriptions/hosted-payment-pages).
Supported via Adyen Checkout.


## Usage with OCC
Expand Down Expand Up @@ -109,7 +112,7 @@ For Credit Card payments - it expects encrypted card holder data obtained from y
For Stored Cards payments - selected Adyen recurringReference of the card and encrypted cvc

For Boleto payments - social security number


3. OrderData authorisePayment(CartData cartData) throws Exception;

Expand All @@ -124,13 +127,18 @@ It returns an instance of OrderWSDTO obtained from OrderData of the placed order
For Boleto, it will contain the pdf url, the base64 encoded data, expiration date and due date
https://docs.adyen.com/developers/payment-methods/boleto-bancario/boleto-payment-request

## 3DS2 configuration
By default 3DS2 is disabled. If you want to enable 3DS2 in your system, please set following property in local.properties file, build your environment and restart the server.
```
is3DS2allowed = true
```

## Documentation
https://docs.adyen.com/developers/plugins/hybris

## Support
You can create issues on our Magento Repository. In case of specific problems with your account, please contact
[email protected].

## License
MIT license. For more information, see the LICENSE file.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public interface AdyenControllerConstants
{
String ADDON_PREFIX = "addon:/adyenv6b2ccheckoutaddon/";
String SUMMARY_CHECKOUT_PREFIX = "/checkout/multi/adyen/summary";
String NOTIFICATION_PREFIX = "/adyen/v6/notification";
String PAYPAL_ECS_PREFIX = "/adyen/paypal-ecs";

/**
Expand All @@ -42,6 +41,7 @@ interface MultiStepCheckout
String SelectPaymentMethod = ADDON_PREFIX + "pages/checkout/multi/selectPaymentMethodPage";
String Validate3DSecurePaymentPage = ADDON_PREFIX + "pages/checkout/multi/3d-secure-payment-validation";
String HppPaymentPage = ADDON_PREFIX + "pages/checkout/multi/hpp-payment";
String Validate3DS2PaymentPage = ADDON_PREFIX + "pages/checkout/multi/3ds2_payment";
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,24 @@
import de.hybris.platform.site.BaseSiteService;
import static com.adyen.constants.ApiConstants.Redirect.Data.MD;
import static com.adyen.constants.ApiConstants.Redirect.Data.PAREQ;
import static com.adyen.constants.ApiConstants.Redirect.Data.PAYMENT_DATA;
import static com.adyen.constants.ApiConstants.ThreeDS2Property.CHALLENGE_TOKEN;
import static com.adyen.constants.ApiConstants.ThreeDS2Property.FINGERPRINT_TOKEN;
import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_CHALLENGE_TOKEN;
import static com.adyen.constants.ApiConstants.ThreeDS2Property.THREEDS2_FINGERPRINT_TOKEN;
import static com.adyen.constants.BrandCodes.PAYPAL_ECS;
import static com.adyen.constants.HPPConstants.Response.SHOPPER_LOCALE;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.CHALLENGESHOPPER;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.IDENTIFYSHOPPER;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.REDIRECTSHOPPER;
import static com.adyen.model.checkout.PaymentsResponse.ResultCodeEnum.REFUSED;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_BOLETO;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_CC;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_ONECLICK;
import static com.adyen.v6.constants.Adyenv6coreConstants.RATEPAY;
import static com.adyen.v6.constants.Adyenv6coreConstants.PAYMENT_METHOD_MULTIBANCO;
import static com.adyen.v6.facades.DefaultAdyenCheckoutFacade.MODEL_CHECKOUT_SHOPPER_HOST;
import static com.adyen.v6.facades.DefaultAdyenCheckoutFacade.MODEL_ORIGIN_KEY;

@Controller
@RequestMapping(value = AdyenControllerConstants.SUMMARY_CHECKOUT_PREFIX)
Expand Down Expand Up @@ -173,9 +183,7 @@ public String placeOrder(@ModelAttribute("placeOrderForm") final PlaceOrderForm
//In case of Boleto, show link to pdf
if (PAYMENT_METHOD_BOLETO.equals(cartData.getAdyenPaymentMethod())) {
addBoletoMessage(redirectModel, orderData.getCode());
}

else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
} else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
addMultibancoMessage(redirectModel, orderData.getCode());
}

Expand All @@ -199,6 +207,26 @@ else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
if (REFUSED == paymentsResponse.getResultCode()) {
errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason());
}
if (IDENTIFYSHOPPER == paymentsResponse.getResultCode()) {
if (adyenPaymentMethod.equals(PAYMENT_METHOD_CC)|| adyenPaymentMethod.indexOf(PAYMENT_METHOD_ONECLICK) == 0) {
model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
model.addAttribute(FINGERPRINT_TOKEN, paymentsResponse.getAuthentication().get(THREEDS2_FINGERPRINT_TOKEN));
return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
}
}
if (CHALLENGESHOPPER == paymentsResponse.getResultCode()) {
if (adyenPaymentMethod.equals(PAYMENT_METHOD_CC)|| adyenPaymentMethod.indexOf(PAYMENT_METHOD_ONECLICK) == 0) {
model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
model.addAttribute(CHALLENGE_TOKEN, paymentsResponse.getAuthentication().get(THREEDS2_CHALLENGE_TOKEN));
return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
}
}
} catch (Exception e) {
LOGGER.error(ExceptionUtils.getStackTrace(e));
}
Expand All @@ -208,6 +236,38 @@ else if (PAYMENT_METHOD_MULTIBANCO.equals(cartData.getAdyenPaymentMethod())) {
return enterStep(model, redirectModel);
}

@RequestMapping(value = "/3ds2-adyen-response", method = RequestMethod.POST)
@RequireHardLogIn
public String authorise3DS2Payment(final Model model,
final RedirectAttributes redirectModel,
final HttpServletRequest request) throws CMSItemNotFoundException, CommerceCartModificationException, UnknownHostException {

String errorMessage = "checkout.error.authorization.failed";
try {
OrderData orderData = adyenCheckoutFacade.handle3DS2Response(request);
LOGGER.debug("Redirecting to confirmation");
return redirectToOrderConfirmationPage(orderData);
} catch (AdyenNonAuthorizedPaymentException e) {
PaymentsResponse paymentsResponse = e.getPaymentsResponse();
if (paymentsResponse != null && paymentsResponse.getResultCode() == CHALLENGESHOPPER) {
model.addAttribute(MODEL_CHECKOUT_SHOPPER_HOST, adyenCheckoutFacade.getCheckoutShopperHost());
model.addAttribute(SHOPPER_LOCALE, adyenCheckoutFacade.getShopperLocale());
model.addAttribute(MODEL_ORIGIN_KEY, adyenCheckoutFacade.getOriginKey());
model.addAttribute(PAYMENT_DATA, paymentsResponse.getPaymentData());
model.addAttribute(CHALLENGE_TOKEN, paymentsResponse.getAuthentication().get("threeds2.challengeToken"));
return AdyenControllerConstants.Views.Pages.MultiStepCheckout.Validate3DS2PaymentPage;
}
if (paymentsResponse != null && paymentsResponse.getResultCode() == PaymentsResponse.ResultCodeEnum.REFUSED) {
errorMessage = getErrorMessageByRefusalReason(paymentsResponse.getRefusalReason());
}
} catch (Exception e) {
LOGGER.debug("Redirecting to summary" + errorMessage);
return redirectToSummaryWithError(redirectModel, errorMessage);
}
LOGGER.debug("Redirecting to final step of checkout" +errorMessage);
return redirectToSummaryWithError(redirectModel, errorMessage);
}

@RequestMapping(value = AUTHORISE_3D_SECURE_PAYMENT_URL, method = RequestMethod.POST)
@RequireHardLogIn
public String authorise3DSecurePayment(final Model model,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

checkout.error.authorization.transaction.not.permitted=The transaction is not permitted.
checkout.error.authorization.cvc.declined=Declined due to the Card Security Code(CVC) being incorrect. Please check your CVC code!
checkout.error.authorization.cvc.declined=The payment is REFUSED. Please check your Card details.
checkout.error.authorization.restricted.card=The card is restricted.
checkout.error.authorization.payment.detail.not.found=The payment is REFUSED because the saved card is removed. Please try an other payment method.
checkout.error.authorization.payment.refused=The payment is REFUSED.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,6 @@
<div class="chckt-pm__details js-chckt-pm__details payment_method_details" id="dd_method_adyen_cc">
<div class="chckt-form chckt-form--max-width">
<div id="card-div"></div>

<c:if test="${showRememberTheseDetails}">
<label class="chckt-form-label chckt-form-label--full-width">
<input class="chckt-checkbox" checked="" type="checkbox" name="rememberTheseDetails" value="true">
<span class="chckt-form-label__text">
Save for my next payment
</span>
</label>
</c:if>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<%@ page trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>

<script type="text/javascript" src="https://${checkoutShopperHost}/checkoutshopper/sdk/2.5.0/adyen.js"></script>
<link rel="stylesheet" href="https://${checkoutShopperHost}/checkoutshopper/sdk/2.5.0/adyen.css"/>

<script type="text/javascript">
function initiateCheckout ( locale, loadingContext, originKey ) {
var configuration = {
locale: locale,// shopper's locale
loadingContext: loadingContext,
originKey: originKey,
risk: {
enabled: false
}
};
this.checkout = new AdyenCheckout( configuration );
}
function perform3DS2Operations () {
initiateCheckout( "${shopperLocale}", "https://${checkoutShopperHost}/checkoutshopper/", "${originKey}" );
var challengeToken = "${challengeToken}";
var fingerprintToken = "${fingerprintToken}";
if ( challengeToken ) {
initiate3DS2ChallengeShopper( challengeToken );
} else {
if ( fingerprintToken ) {
initiate3DS2IdentifyShopper( fingerprintToken );
}
}
}
function initiate3DS2IdentifyShopper ( fingerprintToken ) {
var threeDS2IdentifyShopperNode = document.getElementById( 'threeDS2' );
var identifyShopperComponent = this.checkout.create( 'threeDS2DeviceFingerprint', {
fingerprintToken: fingerprintToken,
onComplete: function ( fingerprintData ) {
fingerprintResult = fingerprintData.data.details[ "threeds2.fingerprint" ];
var fingerprintResultField = document.getElementById( 'fingerprintResult' );
fingerprintResultField.value = fingerprintResult;
document.getElementById( "3ds2-form" ).submit();
}, // Gets triggered whenever the ThreeDS2 component has a result
onError: function ( error ) {
//alert( "Payment Refused with error ["+ error.errorCode +"] and reason is "+ error.message );
console.log(JSON.stringify(error));
} // Gets triggered on error
} );
identifyShopperComponent.mount( threeDS2IdentifyShopperNode );
}
function initiate3DS2ChallengeShopper ( challengeToken ) {
var threeDS2ChallengeShopperNode = document.getElementById( 'threeDS2' );
var challengeShopperComponent = this.checkout
.create( 'threeDS2Challenge', {
challengeToken: challengeToken,
onComplete: function ( challengeData ) {
challengeResult = challengeData.data.details[ "threeds2.challengeResult" ];
var challengeResultField = document.getElementById( 'challengeResult' );
challengeResultField.value = challengeResult;
document.getElementById( "3ds2-form" ).submit();
},
onError: function ( error ) {
console.log(JSON.stringify(error));
// alert( "Payment Refused with error ["+ error.errorCode +"] and reason is "+ error.message );
}, // Gets triggered on error
size: '05' // Defaults to '01'
} );
challengeShopperComponent.mount( threeDS2ChallengeShopperNode );
}
</script>

</head>
<body onload=perform3DS2Operations()>
<form method="post"
class="create_update_payment_form"
id="3ds2-form"
action="3ds2-adyen-response">
<div class="row">
<div class="col-sm-6">
<div id="threeDS2"></div>
<input type="hidden" name="challengeToken" value="${challengeToken}"/>
<input type="hidden" name="fingerprintToken" value="${fingerprintToken}"/>
<input type="hidden" id="fingerprintResult" name="fingerprintResult"/>
<input type="hidden" id="challengeResult" name="challengeResult"/>
</div>
</div>
</form>
</body>
</html>
Loading

0 comments on commit f07c2d5

Please sign in to comment.