Aurus Quick Start
Broadleaf Commerce offers an out-of-the-box Aurus solution that requires little configuration and is easily set up. The quick start solution implements the AurusPay E-Commerce Payment API (javascript + java) SDK model offered by the Aurus API.
This implementation should be useful for those with a simple checkout flow.
You must have completed the Aurus Environment Setup before continuing
Adding Aurus Checkout Support
These instructions assume integration with the default Heat Clinic Demo Site provided with the framework.
- In your core
applicationContext.xml
, replace the following block of text
<!-- Scan DemoSite Sample Payment Gateway Implementation -->
<context:component-scan base-package="com.mycompany.sample" />
<context:component-scan base-package="com.broadleafcommerce.demo"/>
with
<context:component-scan base-package="com.broadleafcommerce.vendor.aurus"/>
Add the following bean to your site applicationContext.xml
in your blVariableExpressions
list
<bean id="mySampleVariableExpressions" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<ref bean="blAurusVariableExpression"/>
</list>
</property>
</bean>
<bean class="org.broadleafcommerce.common.extensibility.context.merge.LateStageMergeBeanPostProcessor">
<property name="collectionRef" value="mySampleVariableExpressions"/>
<property name="targetRef" value="blVariableExpressions"/>
</bean>
- Create a Payment Form on your checkout page with the following fields:
<form method="POST" action="/checkout/aurus/complete" id="payment-form">
<span id="token-error"></span>
<iframe id="frame_carddetails" name="frame_carddetails"
style="height:550px;width:400px;border:0px; margin-top:15px;"
th:src="${#aurus.getIFrameUrl()}">
</iframe>
<br/>
<input type="hidden" name="CardToken" id="CardToken" value=""/>
<input type="hidden" name="CardType" id="CardType" value=""/>
<input type="hidden" name="CardExpiryDate" id="CardExpiryDate" value=""/>
<input type="hidden" name="CardHolderName" id="CardHolderName" value=""/>
<input type="hidden" name="MaskedCardNum" id="MaskedCardNum" value=""/>
<input type="hidden" name="OneTimeToken" id="OneTimeToken" value=""/>
<input type="hidden" name="RespCode" id="RespCode" value=""/>
<input type="hidden" name="RespTxt" id="RespTxt" value=""/>
<input type="hidden" th:name="${@blExploitProtectionService.getCsrfTokenParameter()}" th:value="${@blExploitProtectionService.getCSRFToken()}" />
<input type="button" id="buttonSubmit" value="Submit..." onclick="javascript: getCardToken();"/>
</form>
- Insert the following Javascript into your checkout html in order to generate the one time token:
<script>
// This method needs to be called on Submit button click present on Merchant's page.
function getCardToken() {
var $form = $('#payment-form');
$form.find('#buttonSubmit').prop('disabled', true);
var frame = document.getElementById('frame_carddetails');
frame.contentWindow.postMessage('aurus-token', "*");
}
function enablePlaceOrderBtn(flag) {
if (flag) {
$("#buttonSubmit").attr("disabled", false);
} else {
$("#buttonSubmit").attr("disabled", true);
}
}
//IE 11 does not support 'startsWith' with strings. Adding this prototype so that it supports the method.
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position) {
position = position || 0;
return this.indexOf(searchString, position) === position;
};
}
// This will get triggered when Aurus will post the OTT response on Merchant's page.
window.addEventListener("message", function (event) {
var data = event.data;
if (data.startsWith('response')) {
var splt = data.split('=');
var json = JSON.parse(splt[1]);
responseHandler(json);
} else if (data.startsWith('iframeLoaded')) {
var splt = data.split('=');
var json = splt[1];
var enableBtn = json == 'true' ? true : false;
enablePlaceOrderBtn(enableBtn);
} else if (data.startsWith('isValidInfo')) {
var splt = data.split('=');
var json = splt[1];
var isValidInfo = json == 'true' ? true : false;
enablePlaceOrderBtn(!isValidInfo);
}
});
function responseHandler(JSONdata) {
try {
var $msg = $('#token-error');
var respCode = JSONdata.response_code;
var respTxt = JSONdata.response_text;
var maskedCardNum = JSONdata.masked_card_num;
var cardToken = JSONdata.card_token;
var cardType = JSONdata.card_type;
var cardExpiry = JSONdata.card_expiry_date;
var ott = JSONdata.one_time_token;
var cardHolderName = JSONdata.card_holder_name;
var $form = $('#payment-form');
if (Number(JSONdata.response_code) > 0) { //Handle the Error Response here
$msg.text('ERROR: ' + JSONdata.response_code + ' - ' + JSONdata.response_text);
$('#buttonSubmit').prop('disabled', false);
} else {
//Handle the success response here like below:
$msg.text('SUCCESS');
$form.append($('#CardToken').val(cardToken));
$form.append($('#CardType').val(cardType));
$form.append($('#CardExpiryDate').val(cardExpiry));
$form.append($('#CardHolderName').val(cardHolderName));
$form.append($('#MaskedCardNum').val(maskedCardNum));
$form.append($('#OneTimeToken').val(ott));
$form.append($('#RespCode').val(respCode));
$form.append($('#RespTxt').val(respTxt));
$form.get(0).submit();
$form.find('#buttonSubmit').prop('disabled', false);
}
} catch (e) {
alert("ERROR: " + e);
}
}
</script>
- Create a Spring MVC Controller to handle the form you created above in order to process the payment token and confirm the transaction
@Controller
public class AurusCheckoutController extends BroadleafCheckoutController {
@RequestMapping("/checkout/aurus/complete")
public String completeAurusCheckout(Model model, HttpServletRequest request, RedirectAttributes redirectAttributes,
@PathVariable Map<String, String> pathVars) throws PaymentException, PricingException {
//Get Cart
Order cart = CartState.getCart();
//Create a new AurusPay Order Payment
OrderPayment paymentNonce = orderPaymentService.create();
paymentNonce.setType(AurusPaymentType.AURUSPAY);
paymentNonce.setPaymentGatewayType(AurusGatewayType.AURUS);
paymentNonce.setAmount(cart.getTotalAfterAppliedPayments());
paymentNonce.setOrder(cart);
// Create the UNCONFIRMED transaction for the payment
PaymentTransaction transaction = orderPaymentService.createTransaction();
transaction.setAmount(cart.getTotalAfterAppliedPayments());
transaction.setRawResponse("AurusPay Token");
transaction.setSuccess(true);
transaction.setType(PaymentTransactionType.UNCONFIRMED);
transaction.getAdditionalFields().put(MessageConstants.CARD_TOKEN, request.getParameter(MessageConstants.CARD_TOKEN));
transaction.getAdditionalFields().put(MessageConstants.CARD_EXPIRY_DATE, request.getParameter(MessageConstants.CARD_EXPIRY_DATE));
transaction.getAdditionalFields().put(MessageConstants.CARD_HOLDER_NAME, request.getParameter(MessageConstants.CARD_HOLDER_NAME));
transaction.getAdditionalFields().put(MessageConstants.ONE_TIME_TOKEN, request.getParameter(MessageConstants.ONE_TIME_TOKEN));
transaction.getAdditionalFields().put(MessageConstants.MASKED_CARD_NUM, request.getParameter(MessageConstants.MASKED_CARD_NUM));
transaction.getAdditionalFields().put(MessageConstants.RESPONSE_CODE, request.getParameter(MessageConstants.RESPONSE_CODE));
transaction.getAdditionalFields().put(MessageConstants.RESPONSE_TEXT, request.getParameter(MessageConstants.RESPONSE_TEXT));
transaction.setOrderPayment(paymentNonce);
paymentNonce.addTransaction(transaction);
orderService.addPaymentToOrder(cart, paymentNonce, null);
orderService.save(cart, true);
return processCompleteCheckoutOrderFinalized(redirectAttributes);
}
}
When processCompleteCheckoutOrderFinalized
is called, the checkout workflow is invoked and the ValidateAndConfirmPaymentActivity
is executed to confirm the payment token.
Done!
At this point, all the configuration should be complete and you are now ready to test your integration with Aurus. Add something to your cart and proceed with checkout.
Aurus requests extension
If you need to extend any Aurus request then you should follow these steps:
Create new class and extend it from ExternalCallAurusServiceImpl.class
public class ExampleExternalCallAurusServiceImpl extends ExternalCallAurusServiceImpl { @Override public JSONObject buildPreAuthTransactionRequest(PaymentRequestDTO paymentRequestDTO, String transactionType) { final JSONObject preAuthTransactionRequest = super.buildPreAuthTransactionRequest(paymentRequestDTO, transactionType); return preAuthTransactionRequest; } }
Add new bean to the Spring Context
<bean name="blExternalCallAurusService" class="com.mycompany.controller.checkout.ExampleExternalCallAurusServiceImpl"/>
Add, update or delete fields of the JSONObject.class
public class ExampleExternalCallAurusServiceImpl extends ExternalCallAurusServiceImpl { @Override public JSONObject buildPreAuthTransactionRequest(PaymentRequestDTO paymentRequestDTO, String transactionType) { final JSONObject preAuthTransactionRequest = super.buildPreAuthTransactionRequest(paymentRequestDTO, transactionType); // Put or update field to the TransRequest object final JSONObject transRequest = preAuthTransactionRequest.getJSONObject("TransRequest"); transRequest.put("POSType", 5); // Put or update field of the root object JSONObject eCommFingerPrintInfo = new JSONObject(); eCommFingerPrintInfo.put("IPAddress", "103.113.136.59"); eCommFingerPrintInfo.put("MerchantWebsite", "https://xxx.com"); transRequest.put("ECOMMFingerPrintInfo", eCommFingerPrintInfo); // Put or update field of the ShippingInfo object final JSONObject shippingInfo = transRequest.getJSONObject("ShippingInfo"); shippingInfo.put("MiddleName", "Test"); // Remove field transRequest.remove("ProcessorToken"); return preAuthTransactionRequest; } }
Note: All data in the JSON example is not valid and should be replaced with real values