Overview - Point of Sale
The wiPlatform is an open, interoperable platform that facilitates mobile (or card) initiated transactions directly at point of sale. Through a single integration with the wiPlatform, any mobile application can interact with integrated point of sale solutions for numerous transaction types. Through a single integration, any point of sale system can accept transactions from any integrated mobile application.
Transaction types facilitated by the wiPlatform include:
- Pay in store
- Earn loyalty
- Redeem loyalty / coupon / voucher
- Cash withdrawal
- Cash deposit
All transactions across different value store providers occur at point of sale through the exact same transaction process, thus cashiers do not require special knowledge of each provider, and cashier training is not required per application that is accepted by a merchant. Similarly, recon and settlement mechanisms are aggregated across all providers so that the merchant need only process recon and settlement once. It should be noted that low-level reporting is provided per transaction provider, to ensure that the merchant has access to all data potentially useful for business intelligence activities.
Platform Architecture
For any transaction to occur, there are primarily three entities: a Value Store Provider (VSP), storing some redeemable value on behalf of a customer, the retailer themselves, and the WP, facilitating the routing (low-level) and settlement (high-level) legs of the transaction.
The diagram below shows how these various role-players interact. The VSP platform will be entirely responsible for communicating with the mobile device of the customer through whichever channel is applicable for that particular VSP (USSD, mobi-site, app, etc.). As shown in Figure 2, the WP aggregates a number of VSP’s, each containing their own customer treasury system.. The WP interacts with this VSP system on behalf of the retailer, and offers the retailer access to multiple VSP’s with one single technical integration.
Transactional Process Flow
- A customer has access to a mobile channel (i.e mobile application) which is provisioned to them by a VSP. The customer ‘signs in’ to their mobile wallet to make a payment at a store (does not specify which store).
- The VSP requests a transactional token from the wiGroup Token Manager via the Token Manager API.
- The token is displayed to the customer through the appropriate mobile channel.
- The cashier selects the “mobile” tender button. At this point; if the POS is integrated directly to WP, the transaction request will be sent to the Transaction Engine via the wiPlatform POS API. If the POS is integrated to the WP through a retail switch, a standard “card” transaction is sent through to the switch with the transactional token in the “PAN” field of the ISO message (prefixed with a standard WP BIN number). It is then routed by the switch to the WP.
- The Transaction Engine receives the request from POS to process a transaction and interfaces with the Token Manager in order to discover which VSP reserved the token.
- A transaction processing request is sent to the VSP via the VSP POST API, including transactional information such as the token, the basket value, and the merchant information, in order to execute a transaction (purchase, earn, load or withdrawal). At this point the VSP system can request a confirmation from the customer (i.e. Confirm R25 at Retailer X?), but this step is often skipped (especially for coupons/vouchers).
- Optional – The customer may accept or decline the transaction. This interface is provided by the VSP to the customer. The benchmark for this confirmation process for all VSP’s is 1.5s in order to ensure speed at checkout in retail.
- Should the customer confirm the transaction, and the VSP authorises the transaction based on other criteria (sufficient funds etc.), the VSP may respond to the transaction processing request from the WP in step (6). This will need to occur within the standard transaction timeout ranges (< 15s).
- The WP will provide the response of the transaction to the point of sale.
- Once the tender has been received by POS, a transaction advice is sent to the WP, finalising the transaction. Should the POS need to cancel the pending transaction, a reversal is sent to the WP, and the transaction is reversed.
Dual Messaging
wiGroup supports dual messaging architecture. Payments using the wiCode platform consists of interactions between the issuer (POS system) and the VSP. The wiCode platform serve as a guarantor of processing the resulting settlement. The wiCode platform utilizes two basic requests to process transactions:
- Transaction request
- Advice request
The transaction request pushes a transaction (payment, deposit or withdrawal) to the VSP for authorization. The transaction response will contain the result of this request, which can then be applied to the transaction appropriately.
The advice request should be made to the wiCode platform once the real-world transaction has been completed. This could either be a once the tender is received by the cashier or if a reversal is required. This call will either change the state of the transaction from pending to successful, or, reversed.
The typical interactions for processing a transaction is displayed in the figure below.
Integration models
There are generally two manners of performing mobile transactions, namely:
- Over the Counter model
- Sit-down model
Over the Counter Model
The over-the-counter model is built on the principle that the client provides a wiCode (usually in the form of a QR code) to the cashier at the POS. Ideally the POS has the capability of scanning a QR code and processing the wiCode contained in the QR by making use of the wiGroupDetect.dll, or manually entering the wiCode on the POS software to process a mobile payment.
For access to the wiGroup Detect SDK, please contact wiGroup integrations.
Sit Down Model
Sit-down payments requires the POS to print a unique QR code on each till slip. POS software providers can use the wiGroup Bill Service REST API to generate this QR code.
The clients may then scan the QR code (making use of a registered mobile application) and proceed to make partial payments on the bill. The POS software requires to be integrated to the transaction history call to retrieve payments made on the basket.
POS Provider SOAP API
This SOAP API enables the point of sale to communicate with the wiPlatform in order to process transactions Each transaction at point of sale typically requires the POS to communicate with the wiPlatform twice:
- A transaction request in order to authorise the transaction.
- A finalise or reversal, the finalise is to close off the transaction whereas the reversal is to cancel the transaction.
Header Parameters
The following table specifies the header parameters which are required in each web service call.
Fields | Type | Description |
---|---|---|
id | String | The application id. |
password | String | Required The application password hashed by SHA1. |
WSDL URL
The QA wiCode platform exposes SOAP web service endpoints by utilizing the following WSDL:
Monetary Values
Monetary amounts are both accepted and returned in cents.
Response codes
The most common response codes are:
Response Code | Response Description |
---|---|
-1 | Successful |
2107 | Transaction to VSP timed out. |
2108 | VSP not found. |
2112 | Store not found. |
2117 | VSP does not support Deposits. |
2118 | VSP does not support Payments. |
2119 | VSP does not support Withdrawals. |
2120 | Invalid token. |
2128 | VSP does not support Cashbacks. |
2129 | Store does not accept VSP. |
For a comprehensive list of response codes, please download our API Reference.
pos:transaction
Transaction request
The basic layout of the transaction request looks as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:pos="http://posprovider.te.wigroup.com/">
<soapenv:Header/>
<soapenv:Body>
<pos:transaction>
<request>
<apiCredentials>
<id></id>
<password></password>
</apiCredentials>
<basketAmount></basketAmount>
<cashbackAmount></cashbackAmount>
<!--Zero or more repetitions:-->
<product>
<id></id>
<pricePerUnit></pricePerUnit>
<units></units>
</product>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<remoteStoreId></remoteStoreId>
<retailerId></retailerId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<switchTrxId></switchTrxId>
<tipAmount></tipAmount>
<token>
<id></id>
<type></type>
</token>
<totalAmount></totalAmount>
<type></type>
</request>
</pos:transaction>
</soapenv:Body>
</soapenv:Envelope>
public class posIntegration{
// wiGroup Transaction Engine location
private static final String te_URI =
"http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
private static Long doTransaction(String wiCode, StoreTrxDetails storeTrxDetails, PosProviderWS_Service stub) throws MalformedURLException{
ApiCredentials apiCredentials = new ApiCredentials();
apiCredentials.setId(posApiId);
apiCredentials.setPassword(posApiPassword);
Token token = new Token();
token.setId(wiCode);
token.setType(posTokenType);
Product prod1 = new Product();
prod1.setId(prod1ID);
prod1.setPricePerUnit(prod1Price);
prod1.setUnits(prod1Price);
Product prod2 = new Product();
prod2.setId(prod2ID);
prod2.setPricePerUnit(prod2Price);
prod2.setUnits(prod2Price);
PosProviderTransactionRequest transactionRequest =
new PosProviderTransactionRequest();
transactionRequest.setApiCredentials(apiCredentials);
transactionRequest.setStoreTrxDetails(storeTrxDetails);
transactionRequest.setToken(token);
transactionRequest.setBasketAmount(basketAmount);
transactionRequest.setCashbackAmount(cashbackAmount);
transactionRequest.setTipAmount(tipAmount);
transactionRequest.setTotalAmount(totalAmount);
transactionRequest.setType(posType);
transactionRequest.getProduct().add(prod1);
transactionRequest.getProduct().add(prod2);
PosProviderTransactionResponse response =
stub.getPosProviderWSPort().transaction(transactionRequest);
System.out.println("\n\nSome important information on the Transaction\nwiCode: " + wiCode +
"\nResponse code: " + response.getResponseCode() +
"\nResponse description: " + response.getResponseDesc() +
"\nwiTrxId: "+ response.getWiTrxId() +
"\nDiscount: " );
for(int i = 0; i < response.getDiscount().size(); i++) {
System.out.println("\tamount: " + response.getDiscount().get(i).getAmount());
}
wiTrxId = response.getWiTrxId();
trxId= response.getVsp().getTrxId();
if("-1".equals(response.getResponseCode()))
return (long) -1;
else
return response.getWiTrxId();
}
public static void main(String[] args) throws MalformedURLException, IOException, JSONException {
// Creating the store details for the transaction
StoreTrxDetails storeTrxDetails = new StoreTrxDetails();
storeTrxDetails.setBasketId(posBasketId);
storeTrxDetails.setCashierId(posCashierID);
storeTrxDetails.setPosId(posPosId);
storeTrxDetails.setStoreId(posStoreId);
storeTrxDetails.setTrxId(posTrxId);
PosProviderWS_Service stub = new PosProviderWS_Service(new URL(te_URI));
// Performing the transaction
doTransaction(wiCode, storeTrxDetails, stub);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<?php
class apiCredentials {
function apiCredentials($id, $password)
{
$this->apiId = $id;
$this->apiPassword = $password;
}
}
class storeTrxDetails {
function storeTrxDetails($basket, $cashier, $pos, $store, $trx)
{
$this->basketId = $basket;
$this->cashierId = $cashier;
$this->posId = $pos;
$this->storeId = $store;
$this->trxId = $trx;
}
}
class token {
function token($id, $type)
{
$this->id = $id;
$this->type = $type;
}
}
class product {
function product($id, $pricePerUnit, $units)
{
$this->id = $id;
$this->pricePerUnit = $pricePerUnit;
$this->units = $units;
}
}
$url = "http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
$transactionRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:pos=\"http://posprovider.te.wigroup.com/\">
<soapenv:Header/>
<soapenv:Body>
<pos:transaction>
<request>
<apiCredentials>
<id>".$apiCredentials->apiId."</id>
<password>".$apiCredentials->apiPassword."</password>
</apiCredentials>
<product>
<id>".$prod1->id."</id>
<pricePerUnit>".$prod1->pricePerUnit."</pricePerUnit>
<units>".$prod1->units."</units>
</product>
<product>
<id>".$prod2->id."</id>
<pricePerUnit>".$prod2->pricePerUnit."</pricePerUnit>
<units>".$prod2->units."</units>
</product>
<storeTrxDetails>
<basketId>".$storeTrxDetails->basketId."</basketId>
<cashierId>".$storeTrxDetails->cashierId."</cashierId>
<posId>".$storeTrxDetails->posId."</posId>
<storeId>".$storeTrxDetails->storeId."</storeId>
<trxId>".$storeTrxDetails->trxId."</trxId>
</storeTrxDetails>
<basketAmount>".$basketAmount."</basketAmount>
<token>
<id>".$token->id."</id>
<type>".$token->type."</type>
</token>
<totalAmount>".$totalAmount."</totalAmount>
<type>".$type."</type>
</request>
</pos:transaction>
</soapenv:Body>";
$header = array(
"Content-type: text/xml;charset=\"utf-8\";application/xml",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($transactionRequest),
);
$soap_do = curl_init();
curl_setopt($soap_do, CURLOPT_URL, "http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl");
curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($soap_do, CURLOPT_TIMEOUT, 30);
curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, true);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($soap_do, CURLOPT_POST, true);
curl_setopt($soap_do, CURLOPT_POST, true);
curl_setopt($soap_do, CURLOPT_POSTFIELDS, $transactionRequest);
curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);
$result = curl_exec($soap_do);
$xml = simplexml_load_string($result);
$xml->registerXPathNamespace('S', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('ns2', 'http://posprovider.te.wigroup.com/');
$xml_resp = $xml->xpath('//ns2:transactionResponse');
$response = $xml_resp[0]->response;
echo "<h3>Some important information on the transaction:</h3>";
echo "<p>wiCode: ".$response->token->id."<br>";
echo "Response code: ".$response->responseCode."<br>";
echo "Response description: ".$response->responseDesc."<br>";
echo "wiTrxId: ".$response->wiTrxId."<br>";
echo "Discount: <br>";
$discounts = $response->discount;
foreach($discounts->amount as $amount){
echo "amount:".$amount."<br>";
}
?>
</html>
This call is performed when a transaction is logged in the transaction engine and routed to the relevant VSP. This call usually contains more information than the Advice calls. The basic layout of the transaction request looks a follows:
Fields | Required | Description |
---|---|---|
BasketAmount | ✓ | This is the total transaction amount (in cents) of all products in the basket. |
CashBackAmount | This is the amount of cash in cent being withdrawn as part of the transaction. It can either be used in conjunction with a basked payment or on its own. This is only for use with PAYMENT type. | |
Product (Products) ID PricePerUnit Units |
✓ | The ID refers to the actual SKU number of the product. The price per unit at the POS and the number of units. It is recommended that the POS provides a list of products for each transaction. |
storeTrxDetails BasketId CashierId PosID RemoteStoreID RetailerID StoreID TrxID |
✓ ✓ ✓ ✓ |
These are the internal retailer ID’s for the basket, cashier and POS. Store details: StoreID: is the store WID assigned to you by wiGroup. If the StoreID is populated, this will be used. Alternatively, the RemoteStoreID and the RetailerID must be populated - these are used in combination. TrxID: The internal retailers unique transaction ID |
switchTrxID | If applicable, the switch will assign their ID to the transaction. | |
tipAmount | The tip amount must be included in the total amount in order for the VSP to process the full amount. Not all VSP’s support tip amount. | |
token ID Type |
✓ | The ID is the unique token which the wiPlatform uses to identify and route the transaction to the VSP to authorize. The token type is derived from how the token is received at the POS and can be either WICODE, WIQR or BIN. |
totalAmount | ✓ | This is the total transaction amount in cent. This is the sum of the BasketAmount, the CashbackAmount, and TipAmount. |
type | ✓ | This is the type of transaction. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
Payment
The PAYMENT type transaction request is used most often. Transaction request of the type PAYMENT should be used for all payment related transactions as well as the redemption of wiGroup coupon and vouchers.
It is important to note that the field totalAmountProcessed in the transaction response is not necessarily equal to value set in the basketAmount in the transaction request. A simple explanation of this significance is to consider a customer attempting to settle a bill worth R30.00 with a wiCode voucher worth R25.00. The POS may specify the basketAmount to be 3000 in the transaction request. The response will then provide the totalAmountProcessed to be 2500. The POS will then have to ensure that another tender of R5.00 takes place in order to settle the bill. Therefore, the POS must allow for multi-tender and split tender for transactions on the wiCode platform.
Deposit
The DEPOSIT type transaction request is used to load funds into a mobile wallet. In the case of a deposit transaction, the basketAmount and totalAmount is equal the the amount to be deposited.
Withdrawal
The WITHDRAWAL type transaction request is used to withdraw funds from a mobile wallet. In the case of a withdrawal transaction, the basketAmount and totalAmount is equal the the amount to be withdrawn.
Transaction response
The basic layout of the transaction response looks as follows:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:transactionResponse xmlns:ns2="http://posprovider.te.wigroup.com/">
<response>
<responseCode></responseCode> |
<responseDesc></responseDesc>
<basketAmountProcessed></basketAmountProcessed>
<cashbackAmountProcessed></cashbackAmountProcessed>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<remoteStoreId></remoteStoreId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<tipAmountProcessed></tipAmountProcessed>
<token>
<id></id>
<type></type>
</token>
<totalAmountProcessed></totalAmountProcessed>
<type></type>
<vsp>
<id></id>
<message></message>
<name></name>
<responseCode></responseCode>
<responseDesc></responseDesc>
<trxId></trxId>
</vsp>
<wiTrxId></wiTrxId>
<discount>
<com.wigroup.te.common.pojo.Discount>
<amount></amount>
<product/>
</com.wigroup.te.common.pojo.Discount>
<com.wigroup.te.common.pojo.Discount>
<name></name>
<amount></amount>
<product>
<com.wigroup.te.common.pojo.DiscountProduct>
<id></id>
<units></units>
</com.wigroup.te.common.pojo.DiscountProduct>
</product>
</com.wigroup.te.common.pojo.Discount>
</discount>
</response>
</ns2:transactionResponse>
</S:Body>
</S:Envelope>
// Some important information on the transaction
wiCode: 1122345
Response code: -1
Response description: Success
wiTrxId: 11222
Discount:
amount: 500
amount: 1000
// Some important information on the transaction
wiCode: 1122345
Response code: -1
Response description: Success
wiTrxId: 11222
Discount:
amount: 500
amount: 1000
Each transaction type uses the XML in a (slightly) different manner.
Fields | Description |
---|---|
ResponseCode & ResponseDescription | Code and description of the code. Use the VSP response for further details to display to user. A code of “-1” will always be associated with a “Success” description. |
BasketAmountProcessed | The basket amount that was used in processing the transaction. |
CashBackAmount | This is the amount of cash in cents being withdrawn as part of the transaction. It can either be used in conjunction with a basket payment or on its own. |
StoreTrxDetails | Returning the same details that were sent up in the request |
Token ID, Type |
Returning the same details that were sent up in the request. |
TotalAmountProcessed | This is the total transaction amount in cent. This is the sum of the BasketAmount, the CashbackAmount, and TipAmount. |
Type | The transaction type that was processed. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
VSP ID Message ResponseCode ResponseDescription TrxID |
Details indicate what VSP was used to process the transaction and the VSP response code. The response description can be used to display to the user / customer. The unique VSP transaction ID for the requested transaction is presented by TrxID. |
wiTrxID | This is the unique wiGroup transaction ID assigned to the transaction. This field is important for processing a subsequent ADVICE call. |
Discount Amount Product Id Units |
All the items that was discounted on the transaction. This returned by a discount VSP and is usually from the wiGroup Coupon Voucher Server. When product information is provided, a coupon has been redeemed, and when no product information is present, a voucher has been redeemed. |
pos:advise
Advise request
The basic layout of the ADVICE request looks as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:pos="http://posprovider.te.wigroup.com/">
<soapenv:Header/>
<soapenv:Body>
<pos:advise>
<request>
<apiCredentials>
<id></id>
<password></password>
</apiCredentials>
<action></action>
<originalTrx>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<type></type>
<vspTrxId></vspTrxId>
<wiTrxId></wiTrxId>
</originalTrx>
</request>
</pos:advise>
</soapenv:Body>
</soapenv:Envelope>
public class posIntegration{
// wiGroup Transaction Engine location
private static final String te_URI =
"http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
private static void doAdvise(Long wiTrxId, StoreTrxDetails storeTrxDetails) throws MalformedURLException{
ApiCredentials apiCredentials = new ApiCredentials();
apiCredentials.setId("finaliseApiID");
apiCredentials.setPassword("finaliseApiPassword");
OriginalTrx adviceOriginalTrx = new OriginalTrx();
adviceOriginalTrx.setType("PAYMENT");
adviceOriginalTrx.setVspTrxId(862);
adviceOriginalTrx.setWiTrxId(wiTrxId);
adviceOriginalTrx.setStoreTrxDetails(storeTrxDetails);
PosProviderTransactionAdviceRequest adviceRequest = new PosProviderTransactionAdviceRequest();
adviceRequest.setApiCredentials(apiCredentials);
adviceRequest.setAction("FINALISE");
adviceRequest.setOriginalTrx(adviceOriginalTrx);
PosProviderWS_Service stub = new PosProviderWS_Service(new URL("http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl"));
PosProviderTransactionAdviceResponse response = stub.getPosProviderWSPort().advise(adviceRequest);
System.out.println("\n\nSome important information on the advise" +
"\nResponse code: " + response.getResponseCode() +
"\nResponse description: " + response.getResponseDesc() +
"\naction: "+ response.getAction());
}
public static void main(String[] args) throws MalformedURLException, IOException, JSONException {
// Store details for the transaction
StoreTrxDetails storeTrxDetails = new StoreTrxDetails();
storeTrxDetails.setBasketId("basket005");
storeTrxDetails.setCashierId("cashier005");
storeTrxDetails.setPosId("pos005");
storeTrxDetails.setStoreId(1050);
storeTrxDetails.setTrxId("trx005");
PosProviderWS_Service stub = new PosProviderWS_Service(new URL(te_URI));
// Performing the advice
doAdvise(17956, storeTrxDetails);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<?php
class apiCredentials {
function apiCredentials($id, $password)
{
$this->apiId = $id;
$this->apiPassword = $password;
}
}
class storeTrxDetails {
function storeTrxDetails($basket, $cashier, $pos, $store, $trx)
{
$this->basketId = $basket;
$this->cashierId = $cashier;
$this->posId = $pos;
$this->storeId = $store;
$this->trxId = $trx;
}
}
class token {
function token($id, $type)
{
$this->id = $id;
$this->type = $type;
}
}
class product {
function product($id, $pricePerUnit, $units)
{
$this->id = $id;
$this->pricePerUnit = $pricePerUnit;
$this->units = $units;
}
}
$apiCredentials = new apiCredentials("test", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3");
$storeTrxDetails = new storeTrxDetails("aa", "112aa2", "112aa2", "1050", "11aa22");
$token = new token("706313626", "WICODE");
$basketAmount = 3000;
$totalAmount = 3000;
$type = "PAYMENT";
$prod1 = new product(1111, 1000, 1);
$prod2 = new product(2222, 250, 2);
$url = "http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
$action = "FINALISE";
$adviseRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:pos=\"http://posprovider.te.wigroup.com/\">
<soapenv:Header/>
<soapenv:Body>
<pos:advise>
<request>
<apiCredentials>
<id>".$apiCredentials->apiId."</id>
<password>".$apiCredentials->apiPassword."</password>
</apiCredentials>
<action>".$action."</action>
<originalTrx>
<storeTrxDetails>
<basketId>".$storeTrxDetails->basketId."</basketId>
<cashierId>".$storeTrxDetails->cashierId."</cashierId>
<posId>".$storeTrxDetails->posId."</posId>
<storeId>".$storeTrxDetails->storeId."</storeId>
<trxId>".$storeTrxDetails->trxId."</trxId>
</storeTrxDetails>
<type>PAYMENT</type>
<vspTrxId>".$transactionResponse->vsp->id."</vspTrxId>
<wiTrxId>".$transactionResponse->wiTrxId."</wiTrxId>
</originalTrx>
</request>
</pos:advise>
</soapenv:Body>
</soapenv:Envelope>";
$adviseHeader = array(
"Content-type: text/xml;charset=\"utf-8\";application/xml",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($adviseRequest),
);
$performAdvise = curl_init();
curl_setopt($performAdvise, CURLOPT_URL, $url);
curl_setopt($performAdvise, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($performAdvise, CURLOPT_TIMEOUT, 30);
curl_setopt($performAdvise, CURLOPT_RETURNTRANSFER, true);
curl_setopt($performAdvise, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($performAdvise, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($performAdvise, CURLOPT_POST, true);
curl_setopt($performAdvise, CURLOPT_POST, true);
curl_setopt($performAdvise, CURLOPT_POSTFIELDS, $adviseRequest);
curl_setopt($performAdvise, CURLOPT_HTTPHEADER, $adviseHeader);
$adviseResult = curl_exec($performAdvise);
$adviseXml = simplexml_load_string($adviseResult);
$adviseXml->registerXPathNamespace('S', 'http://schemas.xmlsoap.org/soap/envelope/');
$adviseXml->registerXPathNamespace('ns2', 'http://posprovider.te.wigroup.com/');
$xml_resp1 = $adviseXml->xpath('//ns2:adviseResponse');
$adviseResponse = $xml_resp1[0]->response;
echo "<h3>Some important information on the advise:</h3>";
echo "<p>wiCode: ".$transactionResponse->token->id."<br>";
echo "Response code: ".$adviseResponse->responseCode."<br>";
echo "Response description: ".$adviseResponse->responseDesc."<br>";
echo "Action: ".$adviseResponse->action."</p>";
?>
</html>
The advice request must be sent after the transaction has completed at POS (tender is completed). The advice request determines whether the state of a pending transaction is set to either to complete the transaction or to cancel the entire bill. This is done by means of setting the action field to REVERSE or FINALISE. This will change the transaction from pending to finalised / reversed state on the wiGroup platform.
The POS will receive a response from wiGroup as the final leg of the transaction. It is important to note that the wiTrxId received in the transaction response should be carried over and used the advice request in order to advise that transaction. The only time an advice will not included the wiTrxId
is when the advice Type is a reversal.
Parameters:
Fields | Required | Description |
---|---|---|
action | ✓ | Must be either FINALISE or REVERSE. |
storeTrxDetails BasketId CashierId PosID RemoteStoreID RetailerID StoreID TrxID |
✓ ✓ ✓ ✓ |
These are the internal retailer ID’s for the basket, cashier and POS. Store details: StoreID: is the store WID assigned to you by wiGroup. If the StoreID is populated, this will be used. Alternatively, the remoteStoreID and the retailerID must be populated - these are used in combination. TrxID: The internal retailers unique transaction ID |
switchTrxID | If applicable, the switch will assign their ID to the transaction. | |
vspTrxId | The transaction ID supplied by the VSP. | |
wiTrxID | ✓ | The transaction ID supplied by the wiCode Platform. This field is returned in the transaction response. This links the transaction and the advice. |
type | ✓ | This is the type of transaction. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. It should correspond with the transaction it is trying to advise. |
Advise response
The basic layout of the ADVICE response looks as follows:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:adviseResponse xmlns:ns2="http://posprovider.te.wigroup.com/">
<response>
<responseCode></responseCode>
<responseDesc></responseDesc>
<action></action>
<originalTrx>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<type></type>
<vspTrxId></vspTrxId>
<wiTrxId></wiTrxId>
</originalTrx>
</response>
</ns2:adviseResponse>
</S:Body>
</S:Envelope>
// Some important information on the advise
Response code: -1
Response description: Success
action: FINALISE
// Some important information on the advise
Response code: -1
Response description: Success
action: FINALISE
Parameters:
Fields | Description |
---|---|
responseCode & responseDescription | Code and description of the code. Use the VSP response for further details to display to user. A code of “-1” will always be associated with a “Success” description. |
action | Will be either FINALISE or REVERSE. |
cashBackAmount | This is the amount of cash in cents being withdrawn as part of the transaction. It can either be used in conjunction with a basket payment or on its own. |
storeTrxDetails | Returning the same details that were sent up in the request |
type | The transaction type that was processed. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
vspTrxId | The unique VSP transaction ID. |
wiTrxID | This is the unique wiGroup transaction ID assigned to the transaction. |
pos:refund
Refund request
The basic layout of the refund request looks as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pos="http://posprovider.te.wigroup.com/">
<soapenv:Header/>
<soapenv:Body>
<pos:refund>
<request>
<apiCredentials>
<id></id>
<password></password>
</apiCredentials>
<originalTrxDetails>
<wiTrxId></wiTrxId>
<type></type>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
</originalTrxDetails>
<!--Zero or more repetitions:-->
<product>
<id></id>
<pricePerUnit></pricePerUnit>
<units></units>
</product>
<refundAmount></refundAmount>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<remoteStoreId></remoteStoreId>
<retailerId></retailerId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<switchTrxId></switchTrxId>
</request>
</pos:refund>
</soapenv:Body>
</soapenv:Envelope>
A refund transaction is logged in the transaction engine and routed to the relevant VSP. It can only be used with payment transactions.
Parameters:
Fields | Required | Description |
---|---|---|
refundAmount | ✓ | This is the refund amount (in cents). |
switchTrxId | Should there be a transaction switch involved in between the POS and the wiPlatform this must be the switch’s transaction reference. | |
storeTrxDetails BasketId CashierId PosID RemoteStoreID RetailerID StoreID TrxID |
✓ ✓ ✓ ✓ |
These are the internal retailer ID’s for the basket, cashier and POS. Store details: StoreID: is the store WID assigned to you by wiGroup. If the StoreID is populated, this will be used. Alternatively, the RemoteStoreID and the RetailerID must be populated - these are used in combination. TrxID: The internal retailers unique transaction ID. |
originalTrxDetails | ✓ | This object contains information about the originnal transaction. Please find information about the originalTrx object here. |
product (Products) ID PricePerUnit Units |
The ID refers to the actual SKU number of the product. The price per unit at the POS and the number of units. It is recommended that the POS provides a list of products for each transaction. |
Refund response
The basic layout of the refund response looks as follows:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:transactionResponse xmlns:ns2="http://posprovider.te.wigroup.com/">
<response>
<responseCode></responseCode>
<responseDesc></responseDesc>
<refundAmountProcessed></refundAmountProcessed>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<remoteStoreId></remoteStoreId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
<vsp>
<id></id>
<name></name>
<responseCode></responseCode>
<responseDesc></responseDesc>
<trxId></trxId>
</vsp>
<wiTrxId></wiTrxId>
<switchTrxId></switchTrxId>
</response>
</ns2:transactionResponse>
</S:Body>
</S:Envelope>
Each transaction type uses the XML in a (slightly) different manner.
Fields | Description |
---|---|
refundAmountProcessed | This is the total refund amount processed in cent. |
switchTrxId | Should there be a transaction switch involved in between the POS and the wiPlatform this must be the switch’s transaction reference. |
storeTrxDetails BasketId CashierId PosID RemoteStoreID RetailerID StoreID TrxID |
These are the internal retailer ID’s for the basket, cashier and POS. Store details: StoreID: is the store WID assigned to you by wiGroup. If the StoreID is populated, this will be used. Alternatively, the RemoteStoreID and the RetailerID must be populated - these are used in combination. TrxID: The internal retailers unique transaction ID. |
wiTrxID | This is the unique wiGroup transaction ID assigned to the transaction. This field is important for processing a subsequent ADVICE call. |
product (Products) ID PricePerUnit Units |
The ID refers to the actual SKU number of the product. The price per unit at the POS and the number of units. It is recommended that the POS provides a list of products for each transaction. |
VSP ID Message ResponseCode ResponseDescription TrxID |
Details indicate what VSP was used to process the transaction and the VSP response code. The response description can be used to display to the user / customer. The unique VSP transaction ID for the requested transaction is presented by TrxID. |
pos:transactionHistory
The transaction history request returns a list of transactions that have been processed. Transaction history may be linked to a specific retail store and is used to summarize a list of partial transactions associated with a particular basket or store (or even a combination of the two).
The typical interactions for processing a transaction and performing the transaction history call is displayed in the figure below.
Transaciton history request
The basic layout of the TRANSACTIONHISTORY request looks as follows:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:pos="http://posprovider.te.wigroup.com/">
<soapenv:Header/>
<soapenv:Body>
<pos:transactionHistory>
<request>
<apiCredentials>
<id>historyApiID</id>
<password>historyApiPassword</password>
</apiCredentials>
<dateFrom>2015-05-10 12:42:45</dateFrom>
<dateTo>2015-05-12 12:42:45</dateTo>
<pageOffset>0</pageOffset>
<pageSize>2</pageSize>
<storeTrxDetails>
<basketId>basket006</basketId>
<storeId>store006</storeId>
</storeTrxDetails>
</request>
</pos:transactionHistory>
</soapenv:Body>
</soapenv:Envelope>
public class posIntegration{
// wiGroup Transaction Engine location
private static final String te_URI =
"http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
private static void doTransactionHistory(StoreDetails storeTrxDetails) throws MalformedURLException{
ApiCredentials apiCredentials = new ApiCredentials();
apiCredentials.setId(posApiId);
apiCredentials.setPassword(posApiPassword);
PosProviderTransactionHistoryRequest historyRequest = new PosProviderTransactionHistoryRequest();
historyRequest.setApiCredentials(apiCredentials);
historyRequest.setStoreTrxDetails(storeTrxDetails);
PosProviderWS_Service stub = new PosProviderWS_Service(new URL(te_URI));
PosProviderTransactionHistoryResponse response = stub.getPosProviderWSPort().transactionHistory(historyRequest);
for(int i = 0; i < response.getTransactions().size(); i++) {
System.out.println("Transaction: "+ i);
System.out.println("\tID: " + response.getTransactions().get(i).getId());
System.out.println("\tTotalAmountProcessed: " + response.getTransactions().get(i).getTotalAmountProcessed());
System.out.println("\twiCode: " + response.getTransactions().get(i).getToken().getId());
System.out.println("\tState: " + response.getTransactions().get(i).getState());
}
}
public static void main(String[] args) throws MalformedURLException, IOException, JSONException {
// Creating the store details for the transaction
StoreDetails storeTrxDetails = new StoreDetails();
storeTrxDetails.setBasketId("llkkjjhh");
storeTrxDetails.setCashierId("cashier111");
storeTrxDetails.setPosId("pos111");
storeTrxDetails.setStoreId(Long.decode("1050"));
storeTrxDetails.setTrxId("trx111");
doTransactionHistory(storeTrxDetails);
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<?php
class apiCredentials {
function apiCredentials($id, $password)
{
$this->apiId = $id;
$this->apiPassword = $password;
}
}
class storeTrxDetails {
function storeTrxDetails($basket, $store)
{
$this->basketId = $basket;
$this->storeId = $store;
}
}
$apiCredentials = new apiCredentials("test", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3");
$storeTrxDetails = new storeTrxDetails("aa", "112aa2", "112aa2", "1050", "11aa22");
$url = "http://rad2.wigroup.co:8080/wigroup-te-za-rad/PosProviderWS?wsdl";
$historyRequest = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:pos=\"http://posprovider.te.wigroup.com/\">
<soapenv:Header/>
<soapenv:Body>
<pos:transactionHistory>
<request>
<apiCredentials>
<id>".$apiCredentials->apiId."</id>
<password>".$apiCredentials->apiPassword."</password>
</apiCredentials>
<storeTrxDetails>
<basketId>".$storeTrxDetails->basketId."</basketId>
<storeId>".$storeTrxDetails->storeId."</storeId>
</storeTrxDetails>
</request>
</pos:advise>
</soapenv:Body>
</soapenv:Envelope>";
$historyHeader = array(
"Content-type: text/xml;charset=\"utf-8\";application/xml",
"Accept: text/xml",
"Cache-Control: no-cache",
"Pragma: no-cache",
"SOAPAction: \"run\"",
"Content-length: ".strlen($historyRequest),
);
$performHistory = curl_init();
curl_setopt($performHistory, CURLOPT_URL, $url);
curl_setopt($performHistory, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($performHistory, CURLOPT_TIMEOUT, 30);
curl_setopt($performHistory, CURLOPT_RETURNTRANSFER, true);
curl_setopt($performHistory, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($performHistory, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($performHistory, CURLOPT_POST, true);
curl_setopt($performHistory, CURLOPT_POST, true);
curl_setopt($performHistory, CURLOPT_POSTFIELDS, $historyRequest);
curl_setopt($performHistory, CURLOPT_HTTPHEADER, $historyHeader);
$historyResult = curl_exec($performHistory);
$historyXml = simplexml_load_string($historyResult);
$historyXml->registerXPathNamespace('S', 'http://schemas.xmlsoap.org/soap/envelope/');
$historyXml->registerXPathNamespace('ns2', 'http://posprovider.te.wigroup.com/');
$xml_resp2 = $historyXml->xpath('//ns2:transactionHistoryResponse');
$historyResponse = $xml_resp2[0]->response;
echo "<h3>Some important information on the transaction history:</h3>";
$index = 0;
foreach($historyResponse->transactions as $transactions){
echo "<h5>Transaction $index:</h5>";
echo "ID: ".$transactions->id."<br>";
echo "TotalAmountProcessed: ".$transactions->totalAmountProcessed."<br>";
echo "wiCode: ".$transactions->token->id."<br>";
echo "State: ".$transactions->state."<br>";
$index++;
}
?>
</html>
The transaction history request provides a summary of the transactions associated with the storeTrxDetails provided. It is recommended that the storeID (or both the remoteStoreID and retailerID) as well as the basketID is provided in the transaction history request to find all the (partial) transactions associated with a particular basket. It is, however, required that the storeID (or both the remoteStoreID and retailerID) be provided at the very minimum. The basic layout of the transaction history request looks a follows:
Fields | Optional or Required | Description |
---|---|---|
API Credentials | Required | API credentials issued to you by wiGroup. |
dateFrom | Optional* | This is the start date for the transaction history search. It should be of the form: yyyy-MM-dd HH:mm:ss |
dateTo | Optional* | This is the end date for the transaction history search. It should be of the form: yyyy-MM-dd HH:mm:ss |
pageSize | Optional | The number of transactions returned per page from the transaction history result set. The default page size is 10. |
pageOffset | Optional | This is the page that should be returned from the transaction history result set. The first page starts at 0. |
StoreTrxDetails BasketId RemoteStoreID StoreID TrxID |
Required Required Required Optional Optional Optional Required |
These are the internal retailer ID’s for the basket, cashier and POS. Store details: StoreID: is the store WID assigned to you by wiGroup. If the StoreID is populated, this will be used. Alternatively, the RemoteStoreID and the RetailerID must be populated - these are used in combination. TrxID: The internal retailers unique transaction ID. |
* If no date range is specified, the call will default to returning the transaction history for the past 24 hours.
Transaction history response
The basic layout of the TRANSACTIONHISTORY response looks as follows:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:transactionHistoryResponse xmlns:ns2="http://posprovider.te.wigroup.com/">
<response>
<responseCode>-1</responseCode>
<responseDesc>Success</responseDesc>
<dateFrom>2015-05-10 12:42:45</dateFrom>
<dateTo>2015-05-12 12:42:45</dateTo>
<pageOffset>0</pageOffset>
<pageSize>3</pageSize>
<storeTrxDetails>
<basketId>basket006</basketId>
<storeId>store006</storeId>
</storeTrxDetails>
<transactions>
<basketAmountProcessed>2000</basketAmountProcessed>
<cashbackAmountProcessed>0</cashbackAmountProcessed>
<createDate>2015-05-11 12:42:45.0</createDate>
<id>19731</id>
<lastModifiedDate>2015-05-11 12:42:54.0</lastModifiedDate>
<state>SPR</state>
<tipAmountProcessed>0</tipAmountProcessed>
<token>
<id>4902378</id>
<type>WICODE</type>
</token>
<totalAmountProcessed>2000</totalAmountProcessed>
<type>PAYMENT</type>
<vspId>80032</vspId>
</transactions>
<transactions>
<basketAmountProcessed>1000</basketAmountProcessed>
<cashbackAmountProcessed>0</cashbackAmountProcessed>
<createDate>2015-05-11 12:42:15.0</createDate>
<id>19730</id>
<lastModifiedDate>2015-05-11 12:42:26.0</lastModifiedDate>
<state>S</state>
<tipAmountProcessed>0</tipAmountProcessed>
<token>
<id>6229377</id>
<type>WICODE</type>
</token>
<totalAmountProcessed>1000</totalAmountProcessed>
<type>PAYMENT</type>
<vspId>80032</vspId>
</transactions>
</response>
</ns2:transactionHistoryResponse>
</S:Body>
</S:Envelope>
// Some important information on the transaction history
Transaction 0:
ID: 23502
TotalAmountProcessed: 1000
wiCode: 8237662
State: S
Transaction 1:
ID: 23501
TotalAmountProcessed: 1000
wiCode: 3308640
State: S
// Some important information on the transaction history
Transaction 0:
ID: 23502
TotalAmountProcessed: 1000
wiCode: 8237662
State: S
Transaction 1:
ID: 23501
TotalAmountProcessed: 1000
wiCode: 3308640
State: S
Bill Service REST API
This REST API enables the point of sale to communicate with the wiPlatform in order to create bills and print a scannable QR code on the till slip.
WSDL URL
The QA wiCode platform exposes REST web service endpoints by utilizing the following WSDL:
Monetary Values
Monetary amounts are both accepted and returned in cents.
/bills
POST /bills
The basic layout of the BILL request looks as follows:
<bill>
<amount>100</amount>
<basketId>123</basketId>
<cashierId>cashier_1</cashierId>
<storeId>1050</storeId>
<posId>pos_1</posId>
<basket>
<product>
<sku>12345</sku>
<desc>Product_1</desc>
<qty>2</qty>
<price>100</price>
</product>
<product>
<sku>126</sku>
<desc>Product_2</desc>
<qty>1</qty>
<price>100</price>
</product>
</basket>
</bill>
Retrieves a bill based on the provided arguments and which was created during the configured time window.
Endpoint: {root}/bills
Available methods: POST, GET
Fields | Optional or Required | Description |
---|---|---|
amount | Required | The total financial amount associated with the bill. |
basketID | Required | The store’s identifier for a particular basket. Must be unique per store per day. |
storeID | Required | The wiGroup store ID as provided by wiGroup. |
posId | Optional | The store’s identifier for the POS / terminal from which the Bill was created. |
basket | Optional | Describes the set of goods or services outlined in the bill. |
product sku desc qty price |
Required Required Required Required |
These are the internal stock keeping unit ID’s. The description as per the tillslip of the product. The discrete quantity of products. The price in cents of the product. |
Bill response
The basic layout of the BILL response looks as follows:
<bill>
<amount>100</amount>
<basketId>basket_123</basketId>
<createDate>2016-10-18T14:05:58.009Z</createDate>
<footer>|Apps accepted:|Example App</footer>
<header>| |*** Scan the QR code below: ***| |</header>
<id>44</id>
<mobilePaymentUrl>http://rad2.wigroup.co/bill/9999</mobilePaymentUrl>
<posId>1</posId>
<qrData>sampledata</qrData>
<qrImage></qrImage>
<state>A</state>
<storeId>1050</storeId>
</bill>
The bill response contains the following information:
Fields | Description |
---|---|
amount | The amount in cents of the bill. |
basketId | The ‘cheque number’ of the bill in question. Must be unique per store per day. |
header | This is a text field that must be printed on the tillslip (above the transactional QR code). |
qrData | Raw data for generating the QR code if the |
qrImage | This is a base64 encoded monochrome bitmap of the QR code to be printed on the tillslip. |
footer | This is a text field that must be printed on the tillslip (below the transactional QR code). |
mobilePaymentUrl | The URL to retrieve the Bill for mobile payment applications. |
User Interface Guide
Although mobile transacting technology has existed for several years, transacting at point of sale using only your mobile device is still a relatively new concept for many consumers and cashiers alike. Furthermore, as more applications enter the market, consumers are being asked to transact in many different ways. Similarly, cashiers are being asked to understand many different payment processes, and as well as many different types of transactions (from pay to deposit to loyalty accumulation).
The following documentation can be viewed as guidelines for best practices when integration in to the wiGroup platform for POS transactions:
- User Interface Guide, PDF document.
- POS Screen Flow Walkthrough, PDF document.
Recon and Settlement
The wiCode platform settlement engine aggregates transactions at a merchant across many providers, and facilitates a settlement of the net amount due to the merchant. This section provides a high-level description of the recon process and the settlement proces.
Recon
To ensure the final transaction state is consistent throughout all the entities involved, the platform performs a recon process with both the retailer and the VSP Methods of recon supported include:
- Recon summary and transactional report via email (automated)
Depending on the capabilities of the retailer, the wiCode platform supports an automated recon and allows the status of transactions to be updated based on discrepancies identified by the retailer.
Settlement
Settlement (payment/debit order) occurs independently from the recon process Transactions will only be settled once finalised.
Due to the different recon times from retailers and daily deadlines for submitting debit orders and EFT payments to the banking systems, some transactions may only be settled the following day.
Settlement of the store owner and the VSP is processed independently and do not effect each other The store owner will be settled/debited for all transactions over all of its stores over all the VSPs in one single settlement batch. The VSP will be debited/settled for all transactions successfully authorized and finalised across all stores linked to the VSP in one single settlement batch.
Due to the timing differences between the store owner and VSP settlements, wiGroup will float the difference between what has been settled to the store owner and what has been debited from the VSP wiGroup cannot support a float over a certain amount, thus the VSP settlement (debits) are typically processed on a daily basis Additionally, when retailers accept deposits via the wiPlatform, a retailer-maintained float is typically required.
Specification
For a detailed specification of the contents of both the generic store owner Recon and Settlement files, please download the specification document.
Go-live checklist
Security
- Once in production, a QA and live environment are both required
- All communication to wiGroup need to be done via HTTPS
- You must connect to the secure DNS endpoint that will be provided by wiGroup
User journey
- The POS must allow for multiple tender types to be used to settle the entire outstanding amount on the basket. One or more of those tenders can be Mobile
- The mobile tender button must be called “Mobile͟”
- POS must be able to process a full, partial or zero-value approval
- Discount (Coupons/Vouchers/Gift cards) transactions get processed as partial payment tender
- The POS must allow split tender with mobile as a payment method
- If a customer has multiple wiCodes that is to be redeemed, wiCodes associated withcoupons or vouchers should preferably be used first. Thereafter wiCodes that hold no specific additional rewards may be processed, if necessary
Transaction messaging
- The wiCode platform supports a dual message architecture and as such a reversal message can be sent up in the event of a cancelled or voided transaction on the POS
- It is important to note that the finalise advice transaction request should not be sent until the basket has been tendered in full
- The reversal advice transaction request should be sent if the transaction/basket has been voided. All the mobile tenders processed on the same basket need to be reversed in case of a void or cancellation
- The transaction amount requested against a basket must include VAT