Skip to main content

GCash Payment Integration

Overview

This document will guide you through integrating GCash a payment service

What You Will Learn

  • Configuring Web Service endpoints
  • Background Application Process execution
  • Calling a resfull service
  • Updating a given TenderItem (BasketItem) to then be added to the transaction

Pre-requisites

In order to continue with this document, you need to have completed - Custom Payment Service

Appropriate Keys private and public are required to continue with this document

Configuration

Ensure you have started you Estate Manager

From the WorkspaceSetup\TrainingResources\CustomPaymentService\Configuration directory, import all available configuration files

Keys

Ensure you place both your private and public pem files into the following directory WorkspaceSetup\EnactorHome\pos\keys

info

The keys directory is referenced from the previously improted Account Credencials

Service Messages

Create a new java package named com.enactor.training

From the WorkspaceSetup\TrainingResources\CustomPaymentService\GCash\PackageInfo directory, copy the PackageInfo.java java class into your newly created package

Create a new java package named com.enactor.training.paymentService.service.messages.gcash From the WorkspaceSetup\TrainingResources\CustomPaymentService\GCash\Service Messages Classes directory, copy the entire contents your newly created package

Create a new java package named com.enactor.training.paymentService.service.actions.gcash From the WorkspaceSetup\TrainingResources\CustomPaymentService\GCash\Service Actions directory, copy the entire contents your newly created package

Open the Package.xml file of the Training Pos project

select the Source tab

Copy the following code block in anywhere within the <core:package>

<core:packageEntitiesDef defaultNamespace="http://www.enactor.com/retail">
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.StatusDetail" baseNamespace="http://www.enactor.com/retail" baseName="statusDetail" typeName="StatusDetail" name="statusDetail"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.TimeDetail" baseNamespace="http://www.enactor.com/retail" baseName="timeDetail" typeName="TimeDetail" name="timeDetail"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.ResultInfo" baseNamespace="http://www.enactor.com/retail" baseName="resultInfo" typeName="ResultInfo" name="resultInfo"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.CurrencyAmount" baseNamespace="http://www.enactor.com/retail" baseName="currencyAmount" typeName="CurrencyAmount" name="currencyAmount"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.PayOptionInfo" baseNamespace="http://www.enactor.com/retail" baseName="payOptionInfo" typeName="PayOptionInfo" name="payOptionInfo"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.PaymentView" baseNamespace="http://www.enactor.com/retail" baseName="paymentView" typeName="PaymentView" name="paymentView"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.User" baseNamespace="http://www.enactor.com/retail" baseName="user" typeName="User" name="user"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.AmountDetail" baseNamespace="http://www.enactor.com/retail" baseName="amountDetail" typeName="AmountDetail" name="amountDetail"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.MessageBody" baseNamespace="http://www.enactor.com/retail" baseName="messageBody" typeName="MessageBody" name="messageBody"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.MessageHead" baseNamespace="http://www.enactor.com/retail" baseName="messageHead" typeName="MessageHead" name="messageHead"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.MessageContent" baseNamespace="http://www.enactor.com/retail" baseName="messageContent" typeName="MessageContent" name="messageContent"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.ResponseMessage" baseNamespace="http://www.enactor.com/retail" baseName="responseMessage" typeName="ResponseMessage" name="responseMessage"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.EnvInfo" baseNamespace="http://www.enactor.com/retail" baseName="envInfo" typeName="EnvInfo" name="envInfo"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.Order" baseNamespace="http://www.enactor.com/retail" baseName="order" typeName="Order" name="order"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.ScannerInfo" baseNamespace="http://www.enactor.com/retail" baseName="scannerInfo" typeName="ScannerInfo" name="scannerInfo"/>
<core:packageEntityDef abstract="false" class="com.enactor.training.paymentService.service.messages.gcash.ShopInfo" baseNamespace="http://www.enactor.com/retail" baseName="shopInfo" typeName="ShopInfo" name="shopInfo"/>
</core:packageEntitiesDef>

Entity Wizard

Right click on the java package com.enactor.training.paymentService.service.messages.gcash and select New → Other

From the Enactor Development Group, select Entity and click Next

Form the Entity Wizard dialog, ensure Generate from scratch is selected

Click Next

Select Java Entity

Click Next

For the Entity Name enter RequestMessage

Deselect the Derive names from entity name check box

For the Entity Namespace Constant field, enter com.enactor.training.PackageInfo.NSURI_TRAINING

For the Entity Namespace, enter http://www.enactor.com/retail

For the XML Prefix Constant, enter com.enactor.training.PackageInfo.PREFIX_TRAINING

Dismiss the Added Property dialog

Deselect the Keyed and Timestamped options

Click Next

info

The Keyed and Timestamped properties are used when you want to map an Entity to the persistence layer. As we are only generating message entities, these are therefore not required at this time

The wizard will then display the files it will generate, ensure they match the image shown to the right.

Click Next

Add two new properties

  • request
  • signature

Click Next

Select the Request property

From the Data Type drop down, select complex

From the Component Type drop down, select Type...

In the search field enter com.enactor.training.paymentService.service.messages.gcash.MessageContent

Click Finish

When prompted with the Files have been modified dialog, click OK

Open the newly create RequestMessage class and place the following annotation above the request variable

@XmlElement(type=MessageContent.class)

XML Annotation

Connected Process

Bring up the Resource Library View and search for and open the Connection Diagram TrainingPosEstateManager

From the Palette, Add a new Application (Connected Process)

Select to view the properties of the Connected Process

For the Process ID, enter GCash

Edit the Outputs and add a new Output named Pay

From the Palette, add a new Web Service Group along side the GCash Connected Process

Select to view the properties of the Web Service Group

For the Name, enter GCashWebService

For the Service ID, enter GCashWebService

GCash Connected Process

Select the Unnamed Service from within the Web Services section

Set the Endpoint Reference Type to Rest Endpoint

info

A new new set of properties should appear

Re Select the Unnamed Service from within the GCashWebService section

For the Account Credencials Id, enter GCASH_RETAIL_PAY

For the Dynamic Endpoint, select true from the drop down

For the HTTP Method, select POST from the drop down

For the Connection Provider ID, enter GCashWebService

Add a link from the Pay output of the GCash connected process the Pay web service of the GCashWebService web service group

GCash Web Service

Connected Process Extension

Open the Packages.xml located with the Training - Common Data Project (same project as the Process Connection Diagram)

Select Pacakges

Selected the Connected Processes Tab

Expand the Connected Process Extensions

For the Extending Connected Process, enter StandardPosEstateManager

Extending Connected Process

Payment Service Call

Create a new Application Process with an ID of PaymentServiceCall in the Tender folder

From the Palette, expand the States group, select and drag on a new State, placing it under the Process figure

For the State ID property, enter Start

For the Events property, enter StateEntered

Bring up the Resource Library View and search for and open the Action LoadAccountCredentialsAction

Select the LoadAccountCredentialsAction action and select to edit the Parameters property

Add the following entries

  • Name : enactor.commonUI.AccountCredentialsId
    • Value : GCASH_CREDS
  • Name : enactor.commonUI.AccountCredentialsId
    • Value : com.enactor.mfc.accountCredentials.AccountCredentialsProvider

Select the process figure and add the following State Data entry

  • Name : enactor.commonUI.UserPrincipal
    • Type : com.enactor.core.signOn.IUserPrincipal

Select the process figure and add the following Inputs

  • Name : enactor.mfc.Device
    • Type : com.enactor.mfc.device.IDevice
  • Name : enactor.mfc.Location
    • Type : com.enactor.mfc.location.ILocation

Add a link form the StateEntered event of Start state connecting to the LoadAccountCredentialsAction process

Righ click the LoadAccountCredentialsAction action and select Mappings -> Edit Action-State Mappings -> For State Start

Add a link from the Location Process State variable to the LocationId input of LoadAccountCredentialsAction

Selecte the newly added link and select to edit its expression

Expand the location variable and double click the locationId property

The resualting expression should be location.locationId

Locationid Expresion

Add a link from the Device Process State variable to the DeviceId input of LoadAccountCredentialsAction

Selecte the newly added link and select to edit its expression

Expand the device variable and double click the deviceId property

The resualting expression should be device.deviceId

Device Id Expresion

Click OK

Load Account Credencials Mappings

From the Palette expand the Actions group, add an End Process Action placing above the LoadAccountCredentialsAction State

Set the Action ID to End Process Fail

Set the Process Outcome to Fail

Add a link from the Fail outcome of the LoadAccountCredentialsAction Action connecting to the newly created Action End Process Fail

Load Account Credencials

Bring up the Resource Library View and search for and open the Action CreateAndSignRequestAction

Add a link from the Success outcome of the LoadAccountCredentialsAction Action connecting to the newly added Action CreateAndSignRequestAction

Select the process figure and add the following Inputs

  • Name : enactor.gcash.CustomerCode
    • Type : java.lang.String
  • Name : enactor.mfc.PosTerminal
    • Type : com.enactor.mfc.posTerminal.IPOSTerminal
  • Name : enactor.mfc.TransactionHandler
    • Type : com.enactor.mfc.retail.transaction.IRetailTransactionHandler
  • Name : enactor.training.paymentService.service.messages.gcash.RequestMessage
    • Type : com.enactor.training.paymentService.service.messages.gcash.IRequestMessage

Create And Sign Request Action

From the WorkspaceSetup\TrainingResources\CustomPaymentService\Application Process directory, copy the InvokeBackgroundRestService_1.0.xml Application Process into your Tender folder

Right click the InvokeBackgroundRestService_1.0.xml file select Enactor -> Register in Packages

Click Register

From the WorkspaceSetup\TrainingResources\CustomPaymentService\Application Process directory, copy the InvokeRestService_1.0.xml Application Process into your Tender folder

Right click the InvokeRestService_1.0.xml file select Enactor -> Register in Packages

Click Register

Bring up the Resource Library View and search for and open the Action InvokeBackgroundRestService

Add a link from the Success outcome of the CreateAndSignRequestAction Action connecting to the newly added Action InvokeBackgroundRestService

Select the InvokeBackgroundRestService process call and select to edit the Parameters property

Add the following entries

  • Name : enactor.coreUI.ConnectedProcessId
    • Value : GCash
  • Name : enactor.coreUI.ConnectionPointId
    • Value : Pay
  • Name : enactor.service.ResponseObjectClassName
    • Value : com.enactor.training.paymentService.service.messages.gcash.ResponseMessage

Select the process figure and add the following State Data

  • Name : enactor.gcash.messages.ResponseMessage
    • Type : com.enactor.training.paymentService.service.messages.gcash.IResponseMessage

Righ click the InvokeBackgroundRestService process call and select Mappings -> Edit Action-State Mappings -> For State Start

Add a link from the RequestMessage Process State variable to the Request input of InvokeBackgroundRestService

Add a link from the ResponseMessage Process State variable to the Response output of InvokeBackgroundRestService

Invoke Background Rest Service Mapping

Click OK

Add a link form the Fail, Cancel and Empty outcome of InvokeBackgroundRestService connecting them to the End Process Fail action

Invoke Background Rest Service

From the Palette select and drag on a new Action

Double click the action and select to create a New Action

New Action

For the package enter to com.enactor.training.paymentService.service.actions.gcash

For the Name enter VerifySignatureAction

New Verify Signature Action

For the Input annotations add the following annotations

@Input(name = ResponseMessage.ENTITY_DATA_TYPE_NAME, type = IResponseMessage.class, required = true),
@Input(name = CommonUIDataTypesBase.USER_PRINCIPAL_NAME, type = IUserPrincipal.class, required = true)true)

For the Outcome annotations add the following

CoreUIOutcomes.FAIL_OUTCOME_NAME,
CoreUIOutcomes.SUCCESS_OUTCOME_NAME

Replace the execute method with the following code snippet

    private static Logger logger = Logger.getLogger(VerifySignatureAction.class.getName());

@Override
public IApplicationProcessOutcome execute(IApplicationProcessData inputData, IApplicationProcessData outputData)
throws UIProcessException, ApplicationProcessException {

IResponseMessage responseMessage = UIActionFunctions.getRequiredDataItem(inputData, ResponseMessage.ENTITY_DATA_TYPE);

IUserPrincipal userPrincipal = UIActionFunctions.getRequiredDataItem(inputData, CommonUIDataTypesBase.USER_PRINCIPAL);

String keyPath = userPrincipal.getCredentialProperties().get(GCashFunctions.CREDENTIAL_PROPERTY_PUBLIC_KEY);

IJsonSerializerUtil jsonSerializerUtil = JsonSerializerUtil.getInstance(com.enactor.core.json.serializer.JsonSerializerUtil.Format.ENACTOR);

boolean isValid = false;

try {
String payloadJson = jsonSerializerUtil.getUnformattedJSON(responseMessage.getResponse());

if (logger.isDebugEnabled()) {
logger.log(Logger.LOG_DEBUG, "Response: \n\r" + payloadJson + "\n\r");
logger.log(Logger.LOG_DEBUG, "Signature:\n\r" + responseMessage.getSignature() + "\n\r");
}

isValid = validateResponse(payloadJson, responseMessage, keyPath);

} catch (JsonParseException e) {
throw new ApplicationProcessException(e);
}

isValid = isValid && responseMessage.getResponse().getBody().getResultInfo().getResultCode().equals("SUCCESS");

return (isValid) ? CoreUIOutcomes.SUCCESS_OUTCOME : CoreUIOutcomes.FAIL_OUTCOME;
}

protected boolean validateResponse(String payloadJson, IResponseMessage responseMessage, String keyPath) {
try {
return GCashFunctions.validateSignatureString(payloadJson, responseMessage.getSignature(), keyPath);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

Return to the PaymentServiceCall Process

Right click the VerifySignatureAction and select Select Synchronise → With Class Annotations

For the Action ID property, enter VerifySignatureAction

Add a link form the Success outcome of InvokeBackgroundRestService process connecting to the VerifySignatureAction action

From the Palette expand the Actions group, add an End Process Action placing above the VerifySignatureAction State

Add a link form the Success outcome of VerifySignatureAction action connecting to the End Process Success action

Add a link form the Success outcome of VerifySignatureAction action connecting to the End Process Success action

Add a link form the Fail outcome of VerifySignatureAction action connecting to the End Process Fail action

Save the Process

Payment Service Call Complete

Open the Process CustomPaymentService

Bring up the Resource Library View and search for and open the process PaymentServiceCall

Select and drag to place it bellow the MakePayment State

Add a link form the StateEntered event of MakePayment state connecting to the PaymentServiceCall call process

Add a link form the Fail out of PaymentServiceCall Call Process connecting to the End Process Cancel call process

Add a link form the Success outcome of the PaymentServiceCall Call Process to the AddToBasket state

Add Payment Service Call

Answers

The completed solution can be found InvokingARestfulService Project located at /WorkspaceSetup/Solutions/CustomPaymentServiceGCash

To run the solution, import the project as a maven project to your workspace

Select the Training Solution - Custom Payment Service GCash Java launch