Cybersource Secure Acceptance Web/Mobile Quick Start
Broadleaf Commerce offers an out-of-the-box Cybersource Secure Acceptance Web/Mobile solution that requires little configuration and is easily set up.
** You must have completed the [[Cybersource Secure Acceptance Web/Mobile Environment Setup]] before continuing **
Adding Cybersource Secure Acceptance SOP Checkout Support
- In your
applicationContext-servlet.xml
, add the component scan
<context:component-scan base-package="com.broadleafcommerce.vendor.cybersource"/>
- In your site
applicationContext.xml
, replace the block of text
<!-- Scan DemoSite Sample Payment Gateway Implementation -->
...
<!-- /End DemoSite NullPaymentGateway Config -->
with
<!-- Cybersource Secure Acceptance Web/Mobile -->
<context:component-scan base-package="com.broadleafcommerce.payment.service.gateway"/>
<context:component-scan base-package="com.broadleafcommerce.vendor.cybersource"/>
<bean class="com.broadleafcommerce.vendor.cybersource.service.payment.CybersourcePaymentGatewayType"/>
<bean class="org.broadleafcommerce.common.util.SpringAppContext"/>
<bean id="mySampleConfigurationServices" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<ref bean="blCybersourcePaymentConfigurationService"/>
</list>
</property>
</bean>
<bean class="org.broadleafcommerce.common.extensibility.context.merge.LateStageMergeBeanPostProcessor">
<property name="collectionRef" value="mySampleConfigurationServices"/>
<property name="targetRef" value="blPaymentGatewayConfigurationServices"/>
</bean>
- Exclude the cybersource URL from the CSRF token filter in your
applicationContext-security.xml
<bean id="blCsrfFilter" class="org.broadleafcommerce.common.security.handler.CsrfFilter" >
<property name="excludedRequestPatterns">
<list>
<value>/cybersource-payment/**</value>
</list>
</property>
</bean>
- Update the checkout payment form to redirect to the CyberSource Web/Mobile Hosted service: replace the block of text
<blc:transparent_credit_card_form paymentRequestDTO="${customerPaymentDto}"
action="#"
role="form"
method="POST">
...
</blc:transparent_credit_card_form>
with
<blc:cybersource_hosted_credit_card_form paymentRequestDTO="${paymentRequestDTO}"
action="#"
role="form"
method="POST">
<input type="submit" class="medium red" value="Checkout" />
</blc:cybersource_hosted_credit_card_form>
Done!
At this point, all the configuration should be complete and you are now ready to test your integration with CyberSource Secure Acceptance SOP. Add something to your cart and proceed with checkout.
Advanced Configuration: Embedding the CyberSource Secure Acceptance Web/Mobile form in the checkout page
Follow these steps to embed the CyberSource Secure Acceptance Web/Mobile form on the site instead of redirecting to it.
- Require HTTPS on the CyberSource return redirect urls in your
applicationContext-security.xml
<sec:http auto-config="false" authentication-manager-ref="blAuthenticationManager" disable-url-rewriting="true">
<sec:intercept-url pattern="/cybersource-payment/embedded-redirect/**" requires-channel="https"/>
</sec:http>
- Update the checkout payment form to include the iFrame for the embed and target it: replace the block of text from previous step 4
<blc:cybersource_hosted_credit_card_form paymentRequestDTO="${paymentRequestDTO}"
action="#"
role="form"
method="POST">
<input type="submit" class="medium red" value="Checkout" />
</blc:cybersource_hosted_credit_card_form>
with
<script type="text/javascript">
window.onload=function(){
document.getElementById("cybersource_hosted_credit_card_form").submit();
}
</script>
<blc:cybersource_hosted_credit_card_form paymentRequestDTO="${paymentRequestDTO}"
id="cybersource_hosted_credit_card_form"
action="#"
role="form"
method="POST"
target="cybersource_hosted_credit_card_frame">
</blc:cybersource_hosted_credit_card_form>
<iframe name="cybersource_hosted_credit_card_frame" src="" id="cybersource_hosted_credit_card_frame" width="100%" height="500"></iframe>
- Include a new template to perform a redirect to your confirmation or error page after the iFrame checkout is completed.
In
site/src/main/webapp/WEB-INF/default-theme/templates/
or wherever your templates are stored, create a file atcheckout/partials/cybersourceEmbeddedRedirect.html
with contents
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script th:inline="text">
//<![CDATA[
window.jQuery || document.write('<script src="[[@{/js/lib/jquery-1.9.1.js}]]"><\/script>');
//]]>
</script>
<script type="text/javascript" th:inline="javascript">
//<![CDATA[
$(document).ready(function() {
var $redirect = $('#top-redirect-url');
if ($redirect) {
var redirectUrl = $redirect.text();
if (redirectUrl != null && redirectUrl !== "") {
redirectUrl = redirectUrl.substr(redirectUrl.indexOf(":") + 1);
redirectUrl = window.top.location.origin + redirectUrl;
window.top.location.href = redirectUrl;
}
}
});
//]]>
</script>
<div id="top-redirect-url" style="display: none" th:utext="${redirectUrl}" th:if="${!#strings.isEmpty(redirectUrl)}"></div>
- Certain versions of Broadleaf include the
org.broadleafcommerce.common.web.filter.SecurityHeaderFilter
- if you wish to use the iFrame version of this implementation, it is recommended that the following response header is set "response.setHeader("X-Frame-Options", "SAMEORIGIN");" or the following boolean property set "security.header.x.frame.options=true" - note: this feature is only available on certain versions of the framework. If it is not available in your version, you can create your own security filter as below:
NOTE: this will disable any functionality where the site is displayed in an iFrame, such as viewing the site through an admin modal.
@Component("blCybersourceIFrameSecurityHeaderFilter")
public class CybersourceIFrameSecurityHeaderFilter extends OncePerRequestFilter {
@Resource(name = "blBaseUrlResolver")
BaseUrlResolver baseUrlResolver;
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
response.setHeader("X-Content-Type-Options", "nosniff");
response.setHeader("X-XSS-Protection", "1; mode=block");
response.setHeader("X-Frame-Options", "SAMEORIGIN");
response.setHeader("Content-Security-Policy", "frame-ancestors " + baseUrlResolver.getAdminBaseUrl() + " " + baseUrlResolver.getSiteBaseUrl());
filterChain.doFilter(request, response);
return;
}
}