Introduction
Empower your business with Yoyo Group's comprehensive API platform. Our suite of APIs enables you to seamlessly issue, manage, and redeem Vouchers, Coupons, and Gift Cards, transforming how you engage with customers through digital rewards and loyalty solutions.
Designed with developers in mind, Yoyo Group APIs offer a robust, intuitive integration that simplifies complex loyalty and payment ecosystems. We abstract away technical intricacies, providing you with powerful tools that let you focus on what matters most—growing your business and delighting your customers.
Need help? Our dedicated integration team is always ready to support you.
Key Features
🚀 Unlock the Full Potential of Yoyo Group APIs
Digital Rewards | Payment Processing | Loyalty Programs | Integration Capabilities |
---|---|---|---|
- Instant digital coupon and voucher issuance - Comprehensive gift card program management - Real-time redemption tracking |
- Seamless mobile payment integration - End-to-end transaction security - Omnichannel payment support |
- Intelligent points accumulation - Flexible reward distribution - Comprehensive member lifecycle management |
- Fully documented RESTful APIs - Intuitive Web Portal - Customizable webhook notifications |
Getting Started
📖 Your Integration Journey in 3 Straightforward Steps:
🔑 Secure Authentication
- Generate and manage API credentials
- Implement robust security protocols
- Validate and test initial connection
- Generate and manage API credentials
🚧 Streamlined Integration
- Provision a comprehensive test environment
- Implement core API endpoints
- Thoroughly validate transaction flows
- Provision a comprehensive test environment
🔍 Advanced Optimization
- Configure intelligent webhooks
- Establish comprehensive reporting
- Activate advanced analytics capabilities
- Configure intelligent webhooks
Platform Architecture
In the Yoyo Group ecosystem, three key entities collaborate to facilitate seamless transactions:
- Value Store Provider (VSP): Manages and stores redeemable customer value
- Retailer: The merchant conducting the transaction
- YoyoPlatform: The central orchestrator handling routing and settlement
Key Integration Principles
The YoyoPlatform provides a unified integration solution that: - Aggregates multiple Value Store Providers - Offers retailers a single technical integration point - Enables cross-platform value redemption - Simplifies complex transaction routing
Architectural Diagram
Transaction Flow Overview
The platform leverages a sophisticated, multi-step process to ensure secure and efficient transactions:
VSP Interaction
- Each VSP manages its own customer treasury system
- Provides mobile channels (app, USSD, mobisite) for customer access
- Maintains individual customer wallet interfaces
Platform Capabilities
- Centralized token management
- Multi-provider transaction routing
- Real-time transaction processing
- Secure settlement mechanisms
Transactional Process Flow
Transaction Steps
Customer Initiation
- Customer signs into their mobile wallet via VSP channel
- Prepares to make a payment at a store
Token Generation
- VSP requests a transactional token from YoyoGroup Token Manager
- Token displayed to customer through mobile channel
Point of Sale (POS) Integration
- Cashier selects mobile tender option
- Transaction routed through:
- Direct YoyoPlatform POS API integration
- Retail switch using standard card transaction protocol
Transaction Processing
- Transaction Engine receives POS request
- Identifies associated VSP via Token Manager
- Sends processing request to VSP POST API
- Includes critical transaction details:
- Token
- Basket value
- Basket Information
- Merchant information
Customer Confirmation
- Optional customer transaction confirmation
- VSP-managed interface
- Benchmark response time: 1.5 seconds
Transaction Authorization
- VSP validates transaction
- Checks fund sufficiency
- Responds within standard timeout (< 15s)
Finalization
- YoyoPlatform provides transaction response to POS
- Transaction advice sent to finalize
- Option for transaction reversal if needed
Performance Considerations
- Ultrafast token generation
- Rapid transaction confirmation
- Seamless multi-provider integration
- Robust error handling and reversal mechanisms
Dual Messaging Approach
Yoyo Group's platform architecture employs a dual messaging flow to ensure seamless and reliable transaction processing. This system coordinates interactions between the Point of Sale (POS) system, the Yoyo wiCode platform, and the Value Store Provider (VSP).
Key Transaction Phases
The platform supports two primary request types to manage transactions:
Transaction Request:
- Initiates a payment, deposit, or withdrawal request.
- The Yoyo Platform forwards the request to the designated VSP for authorization.
- The response reflects the VSP's authorization status or any encountered errors.
Advice Request:
- Confirms the final state of the transaction (e.g., successful or reversed).
- Sent after the initial transaction request to update the Yoyo Platform and VSP:
- Finalized: Indicates a successfully completed transaction.
- Reversed: Indicates a canceled or timed-out transaction.
Typical Transaction Flow
The diagram below demonstrates the interaction flow among the POS, Yoyo Platform, and VSP:
Important Note:
The YoyoPlatform and the VSP must record and act on the advice instruction, as it represents the final "real-world" state of the transaction. This state must be accurately reflected in all systems upstream from the POS, including the YoyoPlatform and the VSP system.The VSP cannot decline the advice based on its own business logic (e.g., insufficient funds or user restrictions) because the original transaction has already been approved.
Exception: If the VSP system is unable to log the advice message due to system downtime, the YoyoPlatform will retry sending the advice multiple times until it is successfully logged and processed. This includes cases where the advice is declined or not delivered to the VSP system successfully.
Flexible Integration Models
Yoyo Group's architecture accommodates various integration models tailored to specific VSP and retailer requirements. These models will be detailed in the subsequent section.
Transaction Types
The YoyoPlatform supports the following transaction types:
- Pay in Store
- Earn Loyalty
- Redeem Loyalty / Coupon / Voucher / Giftcard
- Cash Withdrawal
- Cash Deposit
Key Benefits
Unified Transaction Process:
All transactions, regardless of the value store provider, follow the same process at the point of sale. This eliminates the need for cashiers to learn specific procedures for each provider.Simplified Cashier Training:
Cashiers do not require additional training for each application accepted by the merchant, reducing onboarding time and operational overhead.Consolidated Recon and Settlement:
Recon and settlement are aggregated across all providers, allowing merchants to process them once, instead of per provider.- Detailed, low-level reporting is available for each transaction provider, ensuring merchants have access to all data necessary for business intelligence and analytics.
This seamless and standardized approach enhances efficiency and reduces complexity for both merchants and cashiers.
Quick Start for Retailer - Merchant Integration Guide
This is a quick start guide. For more detailed information on any of the requests, refer to the relevant sections below in this document.
A point-of-sale integration can be achieved with as few as two API requests.
Point of Sale - Transaction Request & Response
#Authentication Required on every request:
{
"id": "POS_ID_GOES_HERE",
"password": "POS_PASSWORD_GOES_HERE",
"apiServerVersion": "1.14",
"apiSClientVersion": "this will be your software version identifier",
"Content-Type": "application/json"
}
#Transaction Request Example:
{
"token": {
"id": "1234567",
"type": "WICODE"
},
"storeTrxDetails": {
"retailerId": 999,
"storeId": 1050,
"basketId": "basket1",
"cashierId": "cashier1",
"posId": "workstation1",
"trxId": 12345
},
"product": [
{
"id": "coffee1",
"pricePerUnit": 5000,
"units": 1
},
{
"id": "coffee2",
"pricePerUnit": 5000,
"units": 1
}
],
"type": "PAYMENT",
"basketAmount": 10000,
"billAmount": 10000,
"totalAmount": 10000
}
#Transaction Response Example:
{
"token": {
"id": "1234567",
"type": "WICODE"
},
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": 1050,
"remoteStoreId": "10501",
"retailerId": 999,
"basketId": "basket1",
"trxId": "12345",
"posId": "workstation1",
"cashierId": "cashier1"
},
"wiTrxId": 431711,
"totalAmountProcessed": 10000,
"basketAmountProcessed": 10000,
"cashbackAmountProcessed": 0,
"tipAmountProcessed": 0,
"amountToSettle": 0,
"billAmount": 10000,
"vsp": {
"id": 20016,
"name": "wiCoupon",
"trxId": "569023",
"responseCode": "-1",
"responseDesc": "Success",
"vspRef": "CVS_20230606150456819_Grant Test"
},
"discount": [
{
"name": "API Voucher Documentation",
"amount": 10000,
"product": []
}
],
"loyalty": [],
"balance": [],
"redemptions": [
{
"description": "API Voucher Documentation",
"processedAmount": 10000,
"settleAmount": 0,
"type": "VOUCHER",
"vspId": 20016,
"wiVspTrxId": 658779
}
],
"responseCode": "-1",
"responseDesc": "Success"
}
Step 1: Transaction Request
The merchant identifiers (storeId
and retailerId
) will be provided by Yoyo. The authentication details found in the header (id
and password
) will also be provided by Yoyo. The product array list is required for coupons. Please refer to the transaction details for more information.
Host URL: https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/transaction
HTTP Method: POST
All responses with a "responseCode": "-1" is considered successful. Anything other than "-1" is considered failed. Please refer to "responseDesc" for more information
Point of Sale - Advise Request & Response
Step 2: Advise Request
Please note that the same header details mentioned above apply to this request.
Host URL: https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/advise
HTTP Method: POST
All responses with a "responseCode": "-1" is considered successful. Anything other than "-1" is considered failed. Please refer to "responseDesc" for more information
#Authentication Required on every request:
{
"id": "POS_ID_GOES_HERE",
"password": "POS_PASSWORD_GOES_HERE",
"apiServerVersion": "1.14",
"apiSClientVersion": "this will be your software version identifier",
"Content-Type": "application/json"
}
#Advise Request Example:
{
"action": "FINALISE",
"originalTrx": {
"wiTrxId": 431342,
"type": "PAYMENT",
"storeTrxDetails": {
"retailerId": 999,
"storeId": 10501,
"basketId": "basket1",
"cashierId": "cashier1",
"posId": "workstation1",
"trxId": "12345"
}
}
}
Advise Response Example:
{
"originalTrx": {
"storeTrxDetails": {
"storeId": 10501,
"retailerId": 999,
"basketId": "basket1",
"trxId": "12345",
"posId": "workstation1",
"cashierId": "cashier1"
},
"wiTrxId": 431342,
"type": "PAYMENT"
},
"action": "FINALISE",
"wiTrxId": 431342,
"responseCode": "-1",
"responseDesc": "Success"
}
Quick Setup - eCommerce
Integrating eCommerce functionality into your application involves a straightforward process that mirrors the steps taken for point-of-sale (POS) integration, with one key addition: the tokenInfo
request. This request is essential for validating the wiCode entered by the user, ensuring it can be redeemed on the eCommerce platform.
Purpose of the tokenInfo
Request
The tokenInfo
request serves multiple purposes:
- Validation: It checks whether the provided wiCode is valid and eligible for redemption.
- Monetary Value Retrieval: The response typically includes the monetary value associated with the coupon, voucher, or gift card. This information is crucial for displaying potential discounts to users during their shopping experience.
- Special Cases: Note that if a coupon applies to specific items or offers a percentage discount, the response may differ from standard cases.
Host URL: https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/token-info
HTTP Method: POST
Point of Sale - Token Info Response
All responses with a "responseCode": "-1"
indicate a successful operation. Any other response code signifies a failure, and you should refer to the "responseDesc"
for further details.
Every request must include the following authentication details:
Authentication Required
{
"id": "POS_ID_GOES_HERE",
"password": "POS_PASSWORD_GOES_HERE",
"apiServerVersion": "1.14",
"apiSClientVersion": "this will be your software version identifier",
"Content-Type": "application/json"
}
Here’s an example of how to structure the tokenInfo
request:
Token Info Request Example
{
"token": {
"id": "1234567",
"type": "WICODE"
},
"storeTrxDetails": {
"storeId": 1050,
"basketId": "basket1",
"cashierId": "cashier1",
"posId": "workstation1",
"trxId": "1"
}
}
Response Examples
This response indicates the details of a coupon associated with the provided wiCode:
Coupon Response Example
{
"vsp": {
"id": 20016,
"name": "wiCoupon",
"coupons": {
"coupon": [
{
"product": [
{
"id": "coffee1"
},
{
"id": "coffee2"
},
{
"id": "coffee3"
}
],
"name": "API Coupon Documentation",
"discount": 1750
}
]
},
"hasVoucher": false,
"hasCoupon": true,
"hasWallet": false,
"hasGiftCard": false
},
"responseCode": "-1",
"responseDesc": "Success"
}
This response provides details about a voucher associated with the provided wiCode:
Voucher Response Example
{
"vsp": {
"id": 20016,
"name": "wiCoupon",
"coupons": {
"coupon": [
{
"name": "API Voucher Documentation",
"discount": 10000
}
]
},
"hasVoucher": true,
"hasCoupon": false,
"hasWallet": false,
"hasGiftCard": false
},
"responseCode": "-1",
"responseDesc": "Success"
}
This response outlines the details of a gift card associated with the provided wiCode:
Gift Card Response Example
{
"vsp": {
"id": 20016,
"name": "wiCoupon",
"balances": {
"balance": [
{
"name": "API Gift Card Documentation",
"type": "CENT",
"value": 50000
}
]
},
"hasVoucher": false,
"hasCoupon": false,
"hasWallet": true,
"hasGiftCard": false
},
"responseCode": "-1",
"responseDesc": "Success"
}
Error Handling
Here are some common error responses you might encounter:
Invalid wiCode Format
{
"responseCode": "2",
"responseDesc": "Invalid wiCode format"
}
Invalid Credentials
{
"responseCode": "3",
"responseDesc": "Invalid credentials"
}
wiCode Not Found
{
"responseCode": "4",
"responseDesc": "wiCode not found"
}
wiCode Already Used
{
"responseCode": "5",
"responseDesc": "wiCode has already been used"
}
wiCode Expired
{
"responseCode": "6",
"responseDesc": "wiCode has expired"
}
For a complete list of error codes and their descriptions, please contact wiGroup support.
Security Best Practices
When integrating with the wiGroup API, follow these security best practices:
Authentication
- Store your API credentials securely.
- Never expose credentials in client-side code.
- Rotate passwords periodically.
- Use environment variables for credential storage.
Request/Response Handling
- Always validate wiCodes before processing.
- Implement proper error handling.
- Log all transactions for audit purposes.
- Implement request timeouts.
- Use HTTPS for all API calls.
Data Protection
- Never store wiCodes permanently.
- Implement session timeouts.
- Clear sensitive data after use.
- Follow PCI compliance guidelines if handling payment data.
Integration Testing
- Test all error scenarios.
- Validate response codes.
- Test timeout scenarios.
- Use the test environment before going live.
For additional security guidelines or integration support, please contact wiGroup support.
Overview - Point of Sale Integration
The Yoyo Platform is an open, interoperable system that enables mobile and card-initiated transactions directly at point-of-sale. Through a single integration, merchants can: - Accept transactions from any integrated mobile application - Process multiple transaction types - Handle various payment methods - Manage loyalty programs
Transaction Flow
Token Validation
- Customer presents wiCode/QR code
- System validates token authenticity
- Checks expiry and status
Transaction Processing
- System processes payment
- Applies any discounts
- Calculates loyalty points
- Updates balances
Confirmation
- Sends confirmation to all parties
- Updates transaction records
- Issues digital receipt
Integration Benefits
Unified Integration
- One integration handles all transaction types
- Supports multiple payment providers
- Common API for all services
Enhanced Security
- Secure token generation
- Real-time validation
- Encrypted communication
Flexible Configuration
- Customizable transaction flows
- Configurable business rules
- Adaptable to merchant needs
Token Validation
{
"token": {
"id": "123456789",
"type": "WICODE"
},
"storeTrxDetails": {
"storeId": "STORE123",
"basketId": "BASKET001",
"cashierId": "CASHIER001",
"posId": "POS001",
"trxId": "TRX001"
}
}
Process Transaction
{
"token": {
"id": "123456789",
"type": "WICODE"
},
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": "STORE123",
"retailerId": "RETAIL001",
"basketId": "BASKET001",
"trxId": "TRX001",
"posId": "POS001",
"cashierId": "CASHIER001"
},
"billAmount": 10000,
"basketItems": [
{
"id": "PROD001",
"description": "Coffee",
"quantity": 2,
"unitPrice": 2500,
"totalAmount": 5000
},
{
"id": "PROD002",
"description": "Muffin",
"quantity": 1,
"unitPrice": 5000,
"totalAmount": 5000
}
]
}
Transaction Response
{
"wiTrxId": 431711,
"totalAmountProcessed": 10000,
"basketAmountProcessed": 10000,
"cashbackAmountProcessed": 0,
"tipAmountProcessed": 0,
"amountToSettle": 10000,
"billAmount": 10000,
"vsp": {
"id": 20016,
"name": "Example VSP",
"trxId": "569023",
"responseCode": "-1",
"responseDesc": "Success",
"vspRef": "VSP_REF_001"
},
"discount": [],
"loyalty": [
{
"points": 100,
"balance": 500
}
],
"balance": [],
"redemptions": [],
"responseCode": "-1",
"responseDesc": "Success"
}
Finalize Transaction
{
"action": "FINALISE",
"originalTrx": {
"wiTrxId": "exampleTransactionId123",
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": "store123",
"cashierId": "cashier456",
"timestamp": "2024-12-11T10:00:00Z",
"amount": 10000
}
},
"status": {
"code": "SUCCESS",
"message": "Transaction finalized successfully"
}
}
Error Handling
{
"responseCode": "001",
"responseDesc": "Invalid token",
"errors": [
{
"code": "TOKEN_001",
"message": "Token has expired"
}
]
}
Common error codes:
- TOKEN_001
: Invalid or expired token
- TRX_001
: Invalid transaction type
- TRX_002
: Invalid amount
- TRX_003
: Insufficient funds
- AUTH_001
: Invalid POS credentials
Best Practices
Token Validation
- Always validate tokens before processing
- Check expiry and status
- Verify store details match
Transaction Processing
- Include detailed basket information
- Handle discounts and loyalty properly
- Process in correct order (discounts → payment → loyalty)
Error Handling
- Implement proper error handling
- Show clear error messages to cashiers
- Log all errors for troubleshooting
Security
- Keep credentials secure
- Use HTTPS for all API calls
- Validate all input data
User Experience
- Clear interface for cashiers
- Quick error resolution
- Proper receipt printing
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 YoyoDetect.dll, or manually entering the wiCode on the POS software to process a mobile payment.
For access to the YoyoGroup Detect SDK, please contact YoyoGroup 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 Yoyo 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 API
This RPC API (also referred to as REST) enables the Point of Sale to communicate with the Yoyo Platform in order to process transactions. Each transaction at Point of Sale typically requires the POS to communicate with the Yoyo Platform twice:
- A Transaction Request - in order to authorise the transaction.
- An Advice Request with either finalise or reversal as the action - a finalise is to close off the transaction whereas a reversal is to cancel the transaction.
Header Parameters
The following table specifies the header parameters which are required in each web service call.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
id | String | Required | The application id. |
password | String | Required | The application password hashed by SHA1. |
apiClientVersion | String | Required | This field can be used by POS integrators to send the version of their implementation to the YoyoPlatform. |
apiServerVersion | String | Required | This field allows POS integrators to send the version of the Yoyo server in use as at their time of integration, ensuring strict backwards compatibility. |
HOST URL
The QA wiCode platform exposes REST service endpoints by utilizing the following host and path:
Monetary values
Monetary amounts are both accepted and returned in minor denominations.
Versioning
This API exposes two required versioning fields.
#HEADER
id: {{api_id}}
password: {{api_password}}
apiClientVersion: {{api_client_version}}
apiServerVersion: {{api_server_version}}
Content-Type: application/json
API server versions
The following API server versions are currently being supported:
apiServerVersion |
Description | Environment(s) |
---|---|---|
1.5 | Base | Integration, Production |
1.8 | Support added for loyalty on split tender. VSP Name included on Transaction History . |
Integration, Production |
1.9 | List Redemptions in transaction API. | Integration, Production |
1.10 | tokenInfo flags added. |
Integration, Production |
1.11 | getVasToken API call added. Enable main VSP for loyalty redemption. |
Integration, Production |
1.14 | Enables Over the Counter tipping, billAmount and Discount/Payment split. | Integration, Production |
Transaction API
Create Transaction
This endpoint handles the creation of new transactions.
{
"type": "PAYMENT",
"switchTrxId": "TRX123",
"totalAmount": 10000,
"basketAmount": 10000,
"cashbackAmount": 0,
"tipAmount": 0,
"billAmount": 10000,
"products": [
{
"id": "PROD001",
"units": 2,
"pricePerUnit": 5000
}
],
"token": {
"id": "1234567",
"type": "WICODE",
"payload": "SAMPLE_PAYLOAD"
},
"storeTrxDetails": {
"storeId": 1050,
"remoteStoreId": "STORE123",
"retailerId": 999,
"basketId": "BASKET123",
"trxId": "TRX123",
"posId": "POS001",
"cashierId": "CASH001",
"billId": 12345,
"posBillId": "BILL123"
}
}
Example request
curl -X POST "https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/transaction"
-H "Content-Type: application/json"
-H "id: <#apiId#>"
-H "password: <#apiPassword#>"
-H "apiClientVersion: <#version#>"
-H "apiServerVersion: <#version#>"
-d {
"type": "PAYMENT",
"switchTrxId": "TRX123",
"totalAmount": 10000,
"basketAmount": 10000,
"cashbackAmount": 0,
"tipAmount": 0,
"billAmount": 10000,
"products": [
{
"id": "PROD001",
"units": 2,
"pricePerUnit": 5000
}
],
"token": {
"id": "1234567",
"type": "WICODE",
"payload": "SAMPLE_PAYLOAD"
},
"storeTrxDetails": {
"storeId": 1050,
"remoteStoreId": "STORE123",
"retailerId": 999,
"basketId": "BASKET123",
"trxId": "TRX123",
"posId": "POS001",
"cashierId": "CASH001",
"billId": 12345,
"posBillId": "BILL123"
}
}
Example response
{
"responseCode": "-1",
"responseDesc": "Success",
"wiTrxId": 87153,
"totalAmountProcessed": 10000,
"basketAmountProcessed": 10000,
"tipAmountProcessed": 0,
"amountToSettle": 10000,
"vsp": {
"id": 50099,
"name": "Sample VSP",
"trxId": "TRX123",
"responseCode": "-1",
"responseDesc": "Transaction successful!"
},
"discount": [],
"loyalty": []
}
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
type | String | Yes | Transaction type (e.g., "PAYMENT", "REFUND") |
switchTrxId | String | Yes | Unique transaction identifier |
totalAmount | Integer | Yes | Total transaction amount in cents |
basketAmount | Integer | Yes | Total basket amount in cents |
products | Array | No | List of products in the transaction |
token | Object | Yes | Token information for the transaction |
storeTrxDetails | Object | Yes | Store and transaction details |
Response Parameters
Parameter | Type | Description |
---|---|---|
responseCode | String | "-1" for success, other codes indicate failure |
responseDesc | String | Human-readable response description |
wiTrxId | Integer | Unique transaction ID in the Yoyo system |
totalAmountProcessed | Integer | Total amount processed in cents |
vsp | Object | VSP-specific transaction details |
Advise request
#REQUEST
curl --location 'https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-provider/advise' \
--header 'id: <string>' \
--header 'password: <string>' \
--header 'apiClientVersion: <string>' \
--header 'apiServerVersion: <string>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"action": "<string>",
"originalTrx": {
"storeTrxDetails": {
"basketId": "<string>",
"cashierId": "<string>",
"posId": "<string>",
"trxId": "<string>",
"storeId": "<long>",
"remoteStoreId": "<string>",
"retailerId": "<long>",
"billId": "<long>",
"posBillId": "<string>"
},
"type": "<string>",
"wiTrxId": "<long>",
"token": {
"id": "<string>",
"type": "<string>",
"payload": "<string>"
},
"switchTrxId": "<string>",
"vspTrxId": "<string>",
"totalAmountProcessed": "<integer>",
"basketAmountProcessed": "<integer>",
"cashbackAmountProcessed": "<integer>",
"tipAmountProcessed": "<integer>"
},
"apiCredentials": "sunt consectetur"
}'
The advise request must be sent after the transaction has completed at POS (tender is completed). The advise 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 YoyoGroup platform.
The POS will receive a response from YoyoGroup 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 on the advise request in order to advise that transaction. The only time an advise will not included the wiTrxId
is when the advise 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 YoyoGroup. 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 advise. |
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
#RESPONSE
{
"responseCode": "<string>",
"responseDesc": "<string>",
"originalTrx": {
"storeTrxDetails": {
"basketId": "<string>",
"cashierId": "<string>",
"posId": "<string>",
"trxId": "<string>",
"storeId": "<long>",
"remoteStoreId": "<string>",
"retailerId": "<long>",
"billId": "<long>",
"posBillId": "<string>"
},
"type": "<string>",
"wiTrxId": "<long>",
"token": {
"id": "<string>",
"type": "<string>",
"payload": "<string>"
},
"switchTrxId": "<string>",
"vspTrxId": "<string>",
"totalAmountProcessed": "<integer>",
"basketAmountProcessed": "<integer>",
"cashbackAmountProcessed": "<integer>",
"tipAmountProcessed": "<integer>"
},
"action": "<string>",
"wiTrxId": "<long>"
}
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 Yoyo Platform transaction ID assigned to the transaction. |
Transaction History request
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.
#REQUEST
curl --location --globoff 'https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/transaction-history' \
--header 'id: {{api_id}}' \
--header 'password: {{api_password}}' \
--header 'apiClientVersion: {{api_client_version}}' \
--header 'apiServerVersion: {{api_server_version}}' \
--header 'Content-Type: application/json' \
--data '{
"storeTrxDetails": {
"storeId": "<long>",
"retailerId": "<long>",
"basketId": "<long>",
"trxId": "<long>",
"posId": "<string>",
"cashierId": "<string>"
},
"dateFrom": "<string>",
"dateTo": "<string>",
"pageSize": 10,
"pageOffset": 0
}'
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 YoyoGroup. |
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 YoyoGroup. 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
#RESPONSE
{
"storeTrxDetails": {
"storeId": "<long>",
"retailerId": "<long>",
"basketId": "<string>",
"trxId": "<string>",
"posId": "<string>",
"cashierId": "<string>"
},
"dateFrom": "2022-02-24 00:00:00",
"dateTo": "2022-02-26 00:00:00",
"pageSize": 10,
"pageOffset": 0,
"transactions": [
{
"id": "<long>",
"type": "<string>",
"state": "S",
"vspId": "<long>",
"vspName": "<string>",
"token": {
"id": "<string>",
"type": "WICODE"
},
"billAmount": "<integer>",
"totalAmountProcessed": "<integer>",
"basketAmountProcessed": "<integer>",
"cashbackAmountProcessed": "<integer>",
"tipAmountProcessed": "<integer>",
"amountToSettle": "<ingintegereter>",
"createDate": "2022-02-25 12:57:13.0",
"lastModifiedDate": "2022-10-19 09:55:43.0",
"responseCode": "-1",
"adviceResponseCode": "-1"
}
],
"responseCode": "-1",
"responseDesc": "Success"
}
Transaction History V2 request
The transaction history V2 request returns details on a single transaction that have been processed. Transaction history may be linked to a specific retail store and is used to request details of a specific transaction.
#REQUEST
curl --location --globoff 'https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/transaction-history/v2 \
--header 'id: {{api_id}}' \
--header 'password: {{api_password}}' \
--header 'apiClientVersion: {{api_client_version}}' \
--header 'apiServerVersion: {{api_server_version}}' \
--header 'Content-Type: application/json' \
--data '{
"storeTrxDetails": {
"storeId": "<long>",
"retailerId": "<long>",
"basketId": "<long>",
"trxId": "<long>",
"posId": "<string>",
"cashierId": "<string>"
},
"transactionId": "<long>"
}'
The transaction history request provides details of the transaction stecified by the transasctionId and associated with the storeTrxDetails provided. It is mandatory to provide the transasctionId as well as the storeID (or both the remoteStoreID and retailerID). 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 YoyoGroup. |
transactionId | Required | This is the primary key for the request |
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 YoyoGroup. 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. |
#RESPONSE
{
"responseCode": "<string>",
"responseDesc": "<string>",
"token": {
"id": "<string>",
"type": "<string>",
"payload": "<string>"
},
"type": "<string>",
"storeTrxDetails": {
"basketId": "<string>",
"cashierId": "<string>",
"posId": "<string>",
"trxId": "<string>",
"storeId": "<long>",
"remoteStoreId": "<string>",
"retailerId": "<long>",
"billId": "<long>",
"posBillId": "<string>"
},
"switchTrxId": "<string>",
"wiTrxId": "<long>",
"totalAmountProcessed": "<integer>",
"basketAmountProcessed": "<integer>",
"cashbackAmountProcessed": "<integer>",
"tipAmountProcessed": "<integer>",
"amountToSettle": "<integer>",
"billAmount": "<integer>",
"vsp": {
"id": "<long>",
"name": "<string>",
"message": "<string>",
"trxId": "<string>",
"responseCode": "<string>",
"responseDesc": "<string>",
"balances": {
"balance": [
{
"name": "<string>",
"type": "<string>",
"value": "<integer>"
},
{
"name": "<string>",
"type": "<string>",
"value": "<integer>"
}
]
},
"coupons": {
"coupon": [
{
"product": [
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
},
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
}
],
"name": "<string>",
"discount": "<integer>",
"id": "<string>"
},
{
"product": [
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
},
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
}
],
"name": "<string>",
"discount": "<integer>",
"id": "<string>"
}
]
},
"hasVoucher": "<boolean>",
"hasCoupon": "<boolean>",
"hasWallet": "<boolean>",
"hasGiftCard": "<boolean>",
"vspRef": "<string>"
},
"discount": [
{
"name": "<string>",
"amount": "<integer>",
"product": [
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
},
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
}
]
},
{
"name": "<string>",
"amount": "<integer>",
"product": [
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
},
{
"id": "<string>",
"units": "<integer>",
"discount": "<integer>"
}
]
}
],
"loyalty": [
{
"name": "<string>",
"type": "<string>",
"earned": "<integer>"
},
{
"name": "<string>",
"type": "<string>",
"earned": "<integer>"
}
],
"balance": [
{
"name": "<string>",
"type": "<string>",
"value": "<integer>"
},
{
"name": "<string>",
"type": "<string>",
"value": "<integer>"
}
],
"redemptions": [
{
"id": "<long>",
"description": "<string>",
"processedAmount": "<integer>",
"settleAmount": "<integer>",
"type": "GIFTCARD",
"products": [
{
"id": "<string>",
"units": "<integer>"
},
{
"id": "<string>",
"units": "<integer>"
}
],
"vspId": "<long>",
"wiVspTrxId": "<long>",
"thirdPartySettleAmount": "<integer>",
"thirdPartySettleReference": "<string>"
},
{
"id": "<long>",
"description": "<string>",
"processedAmount": "<integer>",
"settleAmount": "<integer>",
"type": "CARD",
"products": [
{
"id": "<string>",
"units": "<integer>"
},
{
"id": "<string>",
"units": "<integer>"
}
],
"vspId": "<long>",
"wiVspTrxId": "<long>",
"thirdPartySettleAmount": "<integer>",
"thirdPartySettleReference": "<string>"
}
]
}
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 Yoyo Platform transaction ID assigned to the transaction. This field is important for processing a subsequent ADVISE 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 YoyoGroup 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. |
Transaction callback
The transaction callback URL provides the Yoyo platform with a means of notifying third parties that a transaction has been completed. Whenever a transaction is completed, successfully or not, a callback can be POSTed to a provided URL. A callback address can be setup on a retailer level, this means that on one callback address can be set for a defined retailer on the Yoyo platform.
Use case
The transaction callback is intended for retailers that support SITDOWN payments and require a notification when payment for an open bill has been completed. This notification could trigger an action by the merchant to close the bill or in the case of a none successful transaction, assist the client with an alternative payment method. More details regarding the transaction can requested using the Transaction History V2 request.
Transaction Callback failure
To facilitate synchronisation, the Yoyo Platform has a built-in finite redemption callback retry policy. This is enables better state synchronisation by minimising the number of redemption callback failures. If, for some reason, no response is received across all redemption callback requests, a redemption fallback policy must be followed.
Webhook URL
The transaction callback should be built using RESTful JSON programming language.
# Example request
{
"transactionId": 1,
"basketId": "STRING",
"storeId": 1050,
"totalAmountProcessed":100,
"state":"STRING"
}
# Example response
HTTP 200 (OK)
Endpoint: {your_webhook_url}/
Parameter | Type | Description |
---|---|---|
transactionId | Integer | Unique identifier of the transaction on the Yoyo platform. |
basketId | String | Unique identifier of the basket. |
storeId | Integer | Unique identifier of a store. Once-off provided by Yoyo. |
totalAmountProcessed | Integer | Sum of the processedAmount across each redemption. |
state | String | The final transaction status. ENUM: ['S','R','F'] |
Status | Description |
---|---|
S | Success |
F | Failed |
R | Reverse |
Bills API
Create Bill
This endpoint creates a new bill in the system.
{
"amount": 2300,
"basketId": "9eebc2fd-0d26-4680-b54e-f1d66862569b",
"cashierId": "Cathrine",
"storeId": "1050",
"posId": "0672ceb2-5b00-440c-8060-512822a558bh",
"basket": [
{
"product": {
"sku": "9999",
"desc": "Espresso",
"qty": 1,
"price": 2300
}
},
{
"product": {
"sku": "9991",
"desc": "Espresso",
"qty": 2,
"price": 2300
}
}
]
}
Example request
curl --location 'https://rad2.wigroup.co:8181/wigroup-bill/bills' \
--header 'Content-Type: application/json' \
--data '{
"amount": 2300,
"basketId": "9eebc2fd-0d26-4680-b54e-f1d66862569b",
"cashierId": "Cathrine",
"storeId": "1050",
"posId": "0672ceb2-5b00-440c-8060-512822a558bh",
"basket": [
{
"product": {
"sku": "9999",
"desc": "Espresso",
"qty": 1,
"price": 2300
}
},
{
"product": {
"sku": "9991",
"desc": "Espresso",
"qty": 2,
"price": 2300
}
}
]
}'
Example response
{
"id": 44,
"amount": 2300,
"basketId": "9eebc2fd-0d26-4680-b54e-f1d66862569b",
"createDate": "2024-01-18T14:05:58.009Z",
"footer": "|Apps accepted:|Example App",
"header": "| |*** Scan the QR code below: ***| |",
"mobilePaymentUrl": "http://rad2.wigroup.co/bill/9999",
"posId": "0672ceb2-5b00-440c-8060-512822a558bh",
"qrData": "sampledata",
"qrImage": "",
"state": "A",
"storeId": "1050"
}
Request Parameters
Parameter | Type | Required | Description |
---|---|---|---|
amount | Integer | Yes | Total transaction amount in cents |
basketId | String | Yes | Unique identifier for the basket/cheque |
cashierId | String | Yes | ID of the cashier processing the transaction |
storeId | String | Yes | Store identifier provided by YoyoGroup |
posId | String | No | Point of sale terminal identifier |
basket | Array | Yes | List of products in the transaction |
Response Parameters
Parameter | Type | Description |
---|---|---|
id | Integer | Unique bill identifier |
amount | Integer | Total amount in cents |
basketId | String | Original basket identifier |
createDate | String | Creation timestamp (ISO 8601) |
footer | String | Text to print below QR code |
header | String | Text to print above QR code |
mobilePaymentUrl | String | URL for mobile payment |
qrData | String | Raw QR code data |
qrImage | String | Base64 encoded QR code image |
state | String | Bill state ('A' = Active) |
Get Bill
Retrieve a bill using store ID, POS ID, and basket ID.
Example request
curl --location 'https://rad2.wigroup.co:8181/wigroup-bill/bills?storeId=1050&posId=1&basketId=basket_123'
Example response
{
"id": 44,
"amount": 2300,
"basketId": "basket_123",
"createDate": "2024-01-18T14:05:58.009Z",
"footer": "|Apps accepted:|Example App",
"header": "| |*** Scan the QR code below: ***| |",
"mobilePaymentUrl": "http://rad2.wigroup.co/bill/9999",
"posId": "1",
"qrData": "sampledata",
"qrImage": "",
"state": "A",
"storeId": "1050"
}
Query Parameters
Parameter | Required | Description |
---|---|---|
storeId | Yes | Store identifier |
posId | No | Point of sale terminal identifier |
basketId | Yes | Basket/cheque identifier |
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 Yoyo Group platform for POS transactions:
- User Interface Guide, PDF document.
- POS Screen Flow Walkthrough, PDF document.
Objects
API credentials
<apiCredentials>
<apiClientVersion></apiClientVersion>
<apiServerVersion></apiServerVersion>
<id></id>
<password></password>
</apiCredentials>
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
apiClientVersion | String | Required | This field can be used by POS integrators to send the version of their implementation to the YoyoPlatform. |
apiServerVersion | String | Required | This field allows POS integrators to send the version of the Yoyo server in use as at their time of integration, ensuring strict backwards compatibility. |
id | String | Required | API id, issued to you by Yoyo. |
password | String | Required | API password, issued to you by Yoyo. |
Product
<product>
<id></id>
<pricePerUnit></pricePerUnit>
<units></units>
</product>
This object contains information about each product in a user's basket.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
id | String | Required | The SKU or Barcode of the product purchased. The id should be consistent in either always sending through the product SKU or product barcode. |
pricePerUnit | Integer | Required | The price per unit. |
units | Integer | Required | The number of units purchased of this product. |
Store transaction details
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<remoteStoreId></remoteStoreId>
<retailerId></retailerId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
This object contains information about the store in which the transaction took place.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
basketId | String | Required | This is the identifier for the basket as assigned by the POS. The POS system must ensure that it stays the same across multiple transactions of the same basket so that unique baskets can be tracked and identified. |
cashierId | String | Required | Identifies the cashier that processed the transaction. |
posId | String | Required | Identifies the POS terminal the transaction was processed on. |
remoteStoreId | Long | Optional | This is the store's own identifier. Can be used instead of the storeId. Must be used in combination with the retailerId. |
retailerId | Long | Optional | This is the unique Yoyo retailer identifier. Required if using the remoteStoreId field instead of the storeId field. |
storeId | Long | Optional | This is the unique Yoyo store identifier. |
trxId | String | Required | This identifies and groups multiple YoyoPlatform transactions together into a single POS transaction. The POS system must ensure that it stays the same across multiple transactions of the same basket so that unique baskets can be tracked and identified. |
Token
<token>
<id></id>
<type></type>
</token>
This object contains information about the YoyoPlatform token associated with this transaction.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
id | String | Required | The unique token which the YoyoPlatform uses to identify and route the transaction to the VSP to authorize. |
type | String | Required | The token type is derived from how the token is received at the POS and can be either WICODE, WIQR or BIN. |
VSP
<vsp>
<id></id>
<message></message>
<name></name>
<responseCode></responseCode>
<responseDesc></responseDesc>
<trxId></trxId>
</vsp>
This object contains information about the Value Store Provider associated with this transaction. This object will only be returned if the token is valid.
Fields | Data Type | Description |
---|---|---|
id | String | This is an unique VSP identifier. |
message | String | This is a message that can be printed on the user's till slip. Sent back from the VSP on successful transactions. |
name | String | This is the name of the VSP. |
responseCode | String | The responseCode returned by the VSP. This should not be used to determine whether the transaction was approved or not. This should only be used for logging and error reporting to VSP. |
responseDesc | String | The VSP’s response description. Should be displayed in addition to the transactionResponse.responseDesc if available elaborate on why the transaction failed. |
trxId | String | The VSP’s transaction ID for a transaction. This is optionally returned by the VSP in the transaction response. |
Discount
<discount>
<amount></amount>
<name></name>
<product>
<id></id>
<units></units>
</product>
</discount>
This object contains information about the discount associated with this transaction.
Fields | Data Type | Description |
---|---|---|
name | String | Discount name/description. |
amount | Integer | The total discount amount for all products in discount. |
product | String | The products on which the discounts are applied. Please find information about the discount product object here. |
Discount product
<product>
<id></id>
<units></units>
</product>
This object contains information about the products on which discounts are applied in this transaction.
Fields | Data Type | Description |
---|---|---|
id | String | The product id used. |
units | Integer | The number of units processed in the discount. |
discount | String | The discount per product. |
Loyalty
<loyalty>
<name></name>
<type></type>
<earned></earned>
</loyalty>
This object contains information about the loyalty earned on this transaction.
Fields | Data Type | Description |
---|---|---|
name | String | The name of the loyalty program earned against. |
type | String | The type of loyalty earned. Valid values are cent, points or count. |
earned | Integer | The loyalty amount earned. |
Original transaction details
<originalTrxDetails>
<wiTrxId></wiTrxId>
<type></type>
<storeTrxDetails>
<basketId></basketId>
<cashierId></cashierId>
<posId></posId>
<storeId></storeId>
<trxId></trxId>
</storeTrxDetails>
</originalTrxDetails>
This object contains information about the original transaction.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
wiTrxId | Long | Required | The YoyoPlatform unique transaction identifier. It is assigned to the transaction by TE and returned in the transaction response. It is then used, thereafter, in advises to identify the original transaction. |
type | String | Required | The transaction type.Value that are allowed: PAYMENT, DEPOSIT and WITHDRAWAL. |
storeTrxDetails | StoreTrxDetails | Required | This object contains information about the store in which the transaction took place. Find information about the StoreTrxDetails object here. |
Transactions
<transactions>
<basketAmountProcessed></basketAmountProcessed>
<cashbackAmountProcessed></cashbackAmountProcessed>
<amountToSettle></amountToSettle>
<createDate></createDate>
<id></id>
<lastModifiedDate></lastModifiedDate>
<state></state>
<tipAmountProcessed></tipAmountProcessed>
<token>
<id></id>
<type></type>
</token>
<totalAmountProcessed></totalAmountProcessed>
<type></type>
<vspId></vspId>
</transactions>
Fields | Data Type | Description |
---|---|---|
basketAmountProcessed | Long | This is the amount in the basket that was processed for this transaction. |
billAmount | Long | Requires Information. |
cashbackAmountProcessed | Long | This is the cashback amount that was processed for this transaction. |
tipAmountProcessed | Long | This is the tip amount that was processed for this transaction. |
totalAmountProcessed | Long | This is the total amount of the transaction that was processed. |
amountToSettle | Long | This is the amount, in minor denomination, of the total transaction amount that will be settled to the retailer. The difference between totalAmountProcessed and amountToSettle is regarded as the discount amount for non/partially-settled campaigns, and should be handled and displayed as such. This field is only displayed when using apiClientVersion 1.6 and above. |
createDate | String | This is the date and time for when transaction engine first received this transaction. The format is as follows: yyyy-MM-dd HH:mm:ss. |
id | Long | The unique identifier for the transaction in the transaction engine. |
lastModifiedDate | String | This is the date and time for when TE last did any process related to this transaction. The format is as follows: yyyy-MM-dd HH:mm:ss. |
state | String | This is the current status of the transaction. |
type | String | This is the type of transaction. It can be set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
vspId | Long | This is the identifier of the VSP where this transaction was sent to |
token | Token | This object contains information about the YoyoPlatform token associated with this transaction. Please find information about the Token object here. |
Basket
Fields | Data Type | Description |
---|---|---|
product | product | The collection of items being charged for in the containing bill. |
sku | String | Stock Keeping Unit - Identifies this type of product within a store. |
desc | String | Description of the product. |
qty | Integer | Number of units of this product within the containing Basket. |
price | Integer | Unit price of this product, in minor denomination. |
Response Codes
Below is a list of Transaction Engine and Bill Server Response Codes:
Transaction Engine
Response Code | Response Description |
---|---|
-1 | Successful |
00001 | General System Error. |
00002 | General System Error. System configuration incorrect. |
00003 | System Error. Request not found. |
00004 | General Database Error. |
00005 | Duplicate key found. |
00006 | Duplicate entry in DB. |
00007 | Could not process your request. We are experiencing connection problems to external service providers. |
00021 | Email address format invalid. |
00022 | Mobile number invalid. |
00023 | Required field missing or invalid type used. |
00024 | General Input Error. |
00025 | Date format is invalid. |
00026 | Time format is invalid. |
00027 | Integer format is invalid. |
00100 | Invalid request. API credentials missing. |
00300 | Interface does not exist. |
00301 | Interface not activated. |
00302 | Invalid interface credentials. |
00303 | Interface method does not exist. |
01000 | VSP Reference invalid. A valid VSP Reference must be specified. Max 255 characters. |
01001 | VSP invalid. Must specify a value > 0. |
01002 | The wiCode life is invalid. Must specify a value > 0. |
01003 | wiCode Pool depleted. |
01004 | wiCode is not reserved. |
01005 | wiCode reserved by another VSP. |
01006 | wiCode vspReference differs. Might be new transaction. |
01007 | wiCode cannot be refreshed. Either busy being processed or being expired. |
01008 | wiCode has expired. |
01009 | wiCode locked. Currently being used in a transaction. |
01010 | Lock type is invalid. Value must be either 'True' to lock or 'False' to unlock. |
01011 | The wiCode is invalid. A valid wiCode must be specified. |
01012 | The transaction type is not allowed for wiCode. |
01013 | Transaction type invalid. |
01014 | The wiCode life is invalid, it exceeds the maximum wicode length allowed for the pool. |
01501 | Invalid State supplied. |
01501 | Invalid State supplied. |
01502 | Invalid Country id supplied. |
01503 | Invalid POS id supplied. |
01504 | Invalid Retailer id supplied. |
01505 | Invalid Store Owner id supplied. |
01506 | Invalid Store Group id supplied. |
01507 | Invalid subdivision id supplied. |
01508 | Invalid Store id supplied. |
01509 | Invalid VSP id supplied. |
01510 | User Authentication failed. |
01511 | User Authentication failed. |
01512 | User Authentication failed. |
01513 | Bank account credentials invalid. |
01514 | Invalid id supplied. |
01515 | Invalid batch time format. |
01516 | Invalid recon time format. |
01517 | Invalid bank account type. |
01518 | Invalid Bank account supplied. |
02001 | Invalid transaction type supplied. |
02002 | Invalid token type supplied. |
02003 | Invalid advice type supplied. |
02101 | Invalid token id. |
02102 | Could not parse VSP transaction response to JSON. |
02103 | Could not parse Wiprofile lock response to JSON. |
02104 | Timeout while waiting for Wiprofile response. |
02105 | Transaction to VSP timed out. |
02106 | Timeout while waiting for VSP response. |
02107 | Transaction failed. |
02108 | VSP not found. |
02109 | Advice request failed. |
02110 | Failed to log transaction products. |
02111 | API POS not found. |
02112 | Store not found. |
02113 | Lock failed. |
02114 | Store does not support Deposits. |
02115 | Store does not support Payments. |
02116 | Store does not support Withdrawals. |
02117 | VSP does not support Deposits. |
02118 | VSP does not support Payments. |
02119 | VSP does not support Withdrawals. |
02120 | Invalid token. |
02121 | Cashback can only be processed on a Payment. |
02122 | The totalAmount does not match basketAmount + cashbackAmount. |
02123 | Connection to VSP could not be established. |
02124 | POS provider not active. |
02125 | Store is not active. |
02126 | Store is not linked to POS provider. |
02127 | Store does not support Cashbacks. |
02128 | VSP does not support Cashbacks. |
02129 | Store does not accept VSP. |
02130 | Store does not allow Deposits for VSP. |
02131 | Store does not allow Payments for VSP. |
02132 | Store does not allow Withdrawals for VSP. |
02133 | Store does not allow Cashback on Payments for VSP. |
02134 | Token Info request failed. |
02135 | Store Group not found |
02136 | Store Group is not active. |
02137 | Store Group does not support Deposits |
02138 | Store Group does not support Payments |
02139 | Store Group does not support Withdrawals |
02140 | Store Group does not support Cashbacks. |
02141 | Invalid response received from VSP. Required fields missing. |
02142 | Tip can only be processed on a Payment. |
02143 | The transaction amount exceeds maximum amount allowed on token. |
02144 | VSP does not support partial settlement. |
02145 | Original transaction not found. |
02146 | Refund can only be processed on a Payment. |
02147 | Refund can only be processed on a finalised transaction. |
02148 | Store does not support Refunds |
02149 | VSP does not support Refunds. |
02150 | Store does not allow Refunds for VSP. |
02151 | Store not linked to original transaction store. |
02151 | Store retailer not linked to original transaction retailer. |
02152 | The refundAmount exceeds the total amount processed minus previous refunds. |
02153 | The transaction is locked. Refund in progress. |
02154 | The transaction is locked. Refund in progress. |
02155 | Refund request failed |
02156 | Transaction limit exceeded. |
02157 | API VSP not found |
02158 | The amountToSettle exceeds the total amount settled minus previous amounts settled. |
02159 | The amountToSettle exceeds the totalAmount. |
02160 | The total amount processed by the VSP exceeds the total amount. |
02161 | Invalid apiServerVersion |
02170 | Invalid VAS type |
02171 | VAS type not configured for retailer |
03001 | Invalid request. User credentials missing. |
03002 | Invalid user credentials. |
03003 | User not activated. |
03004 | Invalid user credentials. |
03051 | Password invalid. A valid password must be specified. |
03052 | Invalid state. Available states are {A, D, P, RP}. |
03053 | Invalid delivery method. Available methods are {SMS, Email}. |
03054 | Invalid token type specified. |
03055 | Country code invalid. A valid country code must be specified. |
03056 | OTP invalid. A valid OTP must be specified. |
03057 | General OTP Error. |
03058 | OTP is expired. |
03059 | Id invalid. A valid id must be specified. |
03060 | Date invalid. Must have format YYYY-MM-DD HH:MM:SS. |
03101 | Name invalid. Max length allowed is 255 Characters. |
03102 | Surname invalid. Max length allowed is 255 Characters. |
03103 | Gender invalid. Available options are {M, F}. |
03104 | Date of birth invalid. Must have format yyyy-MM-dd. |
03105 | User registration request failed. |
03106 | WiTag is already linked to a user. |
03107 | Username invalid. A valid username must be specified. |
03108 | User already activated. |
03109 | User already linked to VSP. |
03110 | User not linked to wiTag. |
03111 | User already linked to a wiTag with the same description. |
03112 | User not linked to VSP. |
03113 | User and VSP linked state inactive. |
03114 | User in progress with a transaction. |
03115 | User already reserved wiCode for VSP with the same VSP reference. |
03116 | User not reserved by VSP. |
03117 | Another user with the same email is already registered. |
03118 | Another user with the same mobile number is already registered. |
03151 | VSP not activated. |
03152 | VSP registration request failed. VSP already exists. |
03153 | VSP description invalid. Max length allowed is 255 Characters. |
03154 | User cancelled. |
03155 | VSP is not a discount VSP. |
03156 | VSP is not a loyalty VSP. |
03157 | VSP is not linked to discount VSP. |
03158 | VSP is not linked to loyalty VSP. |
03201 | WiTag length invalid. |
03202 | WiTag description invalid. |
03203 | The WiTag life is invalid. Must specify a value > 0. |
03204 | WiTag not linked to a user. |
03205 | No session active for wiTag. |
03230 | WiQR invalid. |
03231 | WiQR is expired. |
03251 | VSP invalid. Must specify a value > 0. |
03252 | VSP Reference invalid. Max length allowed is 255 Characters. |
03253 | The token life is invalid. Must specify a value > 0. |
03254 | The WiCode is invalid. A valid WiCode must be specified. |
03255 | There is no wiCode Pool available for your request parameters. |
03256 | WiCode Pool not activated. |
03257 | WiCode Pool Connection Error. |
03258 | Invalid WiCode Pool interface credentials. |
03259 | General WiCode Pool Error. |
03260 | wiCode is expired. |
03261 | wiCode not reserved. |
03262 | wiCode already locked. |
03263 | wiCode not linked to a user. |
03264 | wiCode Pool depleted. |
03265 | wiCode linked to Discount/Loyalty wiCodes. |
03300 | Invalid BIN. |
04001 | Invalid date supplied. |
Bill Server
Response Code | Response Description |
---|---|
8000 | General server error, 500 |
8001 | No Bill found, 404 |
8002 | No unique Bill found, 404 |
8003 | Invalid parameters, 400 |
Overview - Value Store Provider
The Yoyo Platform is an open, interoperable platform that facilitates transactions between a Retailer, Customer and Value Store Provider (VSP) at a Point of Sale/eCommerce. A single integration with the Yoyo Platform enables a Point of Sale/eCommerce to interact with any Mobile Application and enable a Customer to transact using a wiCode (token) in store.
Dual Messaging Architecture
{
"transaction_flow": {
"phase1": {
"name": "Transaction Request",
"purpose": "Initial authorization",
"flow": [
"POS initiates transaction",
"Platform routes to VSP",
"VSP authorizes or declines"
]
},
"phase2": {
"name": "Advice Request",
"purpose": "Final transaction state",
"types": {
"FINALISE": "Confirms successful completion",
"REVERSE": "Cancels/voids transaction"
}
}
},
"important_rules": {
"advice_handling": {
"mandatory": true,
"cannot_decline": true,
"represents": "Real-world transaction outcome"
},
"retry_mechanism": {
"enabled": true,
"condition": "VSP system unavailable",
"action": "Platform retries until successful"
}
}
}
The Yoyo Platform implements a dual messaging architecture to ensure reliable transaction processing:
Transaction Request
- Initiates payment, deposit, or withdrawal
- Platform routes request to VSP for authorization
- VSP validates and responds with approval/decline
Advice Request
- Confirms final transaction state
- Types:
- FINALISE: Confirms successful completion
- REVERSE: Indicates cancellation or timeout
- Cannot be declined by VSP
- Represents real-world transaction outcome
Important Implementation Notes
VSP Responsibilities
- Must implement both message types
- Cannot decline advice requests
- Must handle retry attempts
- Should reserve funds on initial authorization
Timing Considerations
- Transaction timeout: 15 seconds
- Advice may be delayed up to 24+ hours
- Must maintain transaction state until advice received
Fund Management
- Reserve funds on successful authorization
- Deduct/add funds only on FINALISE
- Release reserved funds on REVERSE
Transaction Types
The platform facilitates various transaction types including: - Pay in store - Earn & Burn loyalty - Redeem coupon/voucher/gift card - Cash Withdrawal/Cashback - Cash Deposit
All transactions across different value store providers occur at point of sale through the exact same transaction process, ensuring: - Cashiers don't need special training per provider - Unified recon and settlement mechanisms - Detailed per-provider reporting for business intelligence
Platform Architecture
For any transaction to occur, there are three primary entities: 1. Value Store Provider (VSP): Manages and stores redeemable customer value 2. Retailer: The merchant conducting the transaction 3. YoyoPlatform: The central orchestrator handling routing and settlement
Key Integration Principles
The YoyoPlatform provides a unified integration solution that: - Aggregates multiple Value Store Providers - Offers retailers a single technical integration point - Enables cross-platform value redemption - Simplifies complex transaction routing
VSP Types
There are typically three types of VSPs that integrate with the platform:
1. Treasury / Value Store
These are typically 'wallets' where funds are allocated through: - Insurance payouts - Lotto winnings - Micro job earnings - Employee benefit rewards - Loyalty and coupon/voucher systems
2. Direct Bank
For direct integrations into Bank Accounts through a middleware API layer.
3. Payment Gateway
For payments in apps that store users' banking cards (credit or debit), routing payments through to relevant banks.
Integration Requirements
When integrating as a VSP with the Yoyo Platform, the following requirements must be met:
Environment Setup
- Maintain both test and production environments
- SSL certification with 128-bit encryption for production
- Connect to secure DNS endpoints provided by Yoyo Group
Technical Requirements
- All communication via HTTPS (TLS 1.2 minimum)
- Response time within 10 seconds
- Support for Dual Messaging
- Never reject advice calls
- Prevent transaction cancellation during processing
Implementation Guidelines
- Document and get approval for user journey
- Follow "Powered by Yoyo Group" guidelines
- Submit final implementation for QA testing
- No code changes during test cycles
- Recommended 15-minute wiCode validity period
Auto-Redeem Functionality
The platform supports linking multiple VSPs to enable auto-redeem functionality:
{
"auto_redeem_features": {
"discount_vouchers": {
"triggers": [
"First-time registration",
"First payment",
"Campaign-specific"
]
},
"loyalty_points": {
"earning_methods": [
"Specific product purchases",
"Total transaction amount",
"Payment or deposit amount"
]
}
}
}
This functionality allows: - Grouping multiple wiCodes into one - Reducing number of QR scans at POS - Enhancing user journey - Minimizing transaction time
Bills Request
# Request Example
{
"endpoint": "/vsp/bills",
"method": "GET",
"headers": {
"apiId": "<your_api_id>",
"apiPassword": "<your_api_password>",
"Content-Type": "application/json; charset=UTF-8"
},
"parameters": {
"qrCode": "<qr_data>"
}
}
# Response Example
{
"store": {
"id": 1050,
"name": "YoyoGroup Test Merchant"
},
"retailer": {
"id": 999,
"name": "YoyoGroup SA"
},
"amount": 5000,
"basketId": "basket01",
"responseCode": "-1",
"responseDesc": "Success"
}
The bills request accepts QR code data and returns a bill object containing transaction details. This enables: - QR code parsing and validation - Collection of transaction details - Population of transaction screens - Initiation of payment process
Transaction Models
The Yoyo Platform supports three distinct transaction models, each designed for specific use cases and environments.
Over-the-Counter (OTC)
There are only three main components involved during a transaction: the Retailer, the wiCode Platform and the VSP. The wiCode Platform connects the retailers and VSPs to enable a VSP's users to transact at retailers connected to the platform. The same transaction flow is applicable for Payment, Withdrawal and Deposits. In the over-the-counter model, the POS requests the value of the transaction into the VSP for authorisation. We encourage all apps to implement the over-the-counter model as well as the sit-down model as it increases access to a larger retail footprint.
Transaction flow
The OTC model involves three main components: 1. Retailer (POS) 2. Yoyo Platform 3. VSP System
- 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 Yoyo 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 YoyoPlatform, the transaction request will be sent to the Transaction Engine via the YoyoPlatform POS API. If the POS is integrated to the YoyoPlatform 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 YoyoPlatform BIN number). It is then routed by the switch to the YoyoPlatform.
- Optionally the VSP can have the ability to process a tokenInfo request, which is used to relay information about an active user token back to the POS. This is generally not required.
- 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's Transactional Gateway 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, deposit, refund 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).
- Optionally the customer can be prompted to accept or decline the transaction. This interface is provided by the VSP to the customer. The confirmation process should not materially increase the customer's time at till.
- 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 YoyoPlatform in [7]. This will need to occur within the standard transaction timeout range of less than 15 seconds.
- The YoyoPlatform will provide the response of the transaction to the POS.
- Once the tender has been received by the POS, a transaction advice is sent to the YoyoPlatform, to FINALISE the transaction with the VSP. Should the POS need to cancel the pending transaction, a REVERSE advice is sent to the YoyoPlatform, and to the VSP.
Important Notes
{
"timeout": {
"limit": "15 seconds",
"action": "Transaction reversed if exceeded"
},
"advice_handling": {
"finalize": "Confirms successful transaction",
"reverse": "Cancels pending transaction",
"rules": [
"Cannot be declined",
"Indicates final real-world outcome",
"May be delayed up to 24+ hours"
]
},
"fund_management": {
"on_request": "Reserve funds",
"on_finalize": "Deduct/add funds",
"on_reverse": "Release reserved funds"
}
}
Sit-down
In the sit-down model, the user begins a transaction by scanning a QR code off of a bill. Essentially, two steps are carried out to perform a transaction.
Step 1 - QR parsing
In the QR parsing stage the app sends the raw QR data to the VSP, the VSP in turn sends the raw QR data to the Transaction Engine VSP API via the GET /bills call. After the YoyoPlatform decodes the data, all relevant information about the bill is returned to the VSP.
Step 2 - Transaction
In the second stage the actual financial transaction begins. The VSP uses the bill information to initiate the transaction with the YoyoPlatform by doing the POST /transactions call to the Transaction Engine VSP API.
Once the transaction is initiated the YoyoPlatform will route the request to the VSP's Transactional Gateway for authorisation. Upon a successful transaction response form the VSP the YoyoPlatform will automatically send the FINALISE advice to the VSP's Transactional Gateway. Payment notification is sent to the app once the transaction outcome is known.
Transaction flow
This is what the transaction flow would look like for the sit-down model.
Example QR code
Informal merchant
If the merchant does not have a physical POS, they might employ a static QR code in the form of a wobbler at the place where they sell their goods/services. This is normally used in informal settings and typically means reduced functionality.
Transaction flow
This is what the transaction flow would look like for the informal model.
Example QR code
Implementation Notes
{
"qr_code": {
"type": "Static",
"placement": "Store wobbler/display",
"content": "Unique store identifier"
},
"limitations": {
"functionality": "Reduced compared to OTC",
"integration": "No POS system required",
"verification": "Manual amount entry"
}
}
Token Manager REST API
The Token Manager API is used by VSPs to reserve tokens (wiCodes) for specific time frames. Tokens automatically expire and return to the available pool. The wiCode length is determined by the token lifespan and availability.
Important Notes
- Date Format: Strict ISO 8601 format is required for dates. Example in Java:
- Monetary Format: All amounts are in cents.
API Credentials
This section provides interface definitions to allow for implementation on various platforms and in different programming languages. Note that:
- Our APIs were designed using the RESTful architectural style.
- Request and response bodies are formatted as JSON exclusively.
- Variables are indicated between angle brackets and the pound sign, e.g. <#variable#>.
- Different request -‐ response combinations are explored using 'Cases'.
Required in request headers:
apiId
: Your API IDapiPassword
: Your API PasswordContent-Type
: application/json
Token Types:
PAYMENT
: Standard payment tokenDEPOSIT
: For cash depositsWITHDRAWAL
: For cash withdrawals
Auto-Redeem Feature: Multiple VSP services can be linked:
- Discount wiCodes (from CVS)
- Loyalty wiCodes (from wiLoyalty)
- Both can be included in a single transaction
Test credentials
All calls to the wiCode platform must contain the issuing channel credentials in the header of the API call. This table contains a set of VSP-specific API credentials that may be used to authenticate all API calls made to CVS and YoyoPlatform.
API ID | API Password |
---|---|
<#apiID#> | <#apiPassword#> |
Linking multiple VSP's
The wiCode Platform has the ability to link multiple VSP’s to a main transactional VSP. This gives the main VSP access to other VSP services such as the Yoyo Coupon Voucher Service and the Yoyo Loyalty Service. This functionality is referred to auto-redeem whereby multiple wiCodes can be grouped or merged into single user token. This reduces the number of QR scans or wiCode entries for these scenarios at the point of sale, thus enhancing the user journey and reducing time at the till.
Use-cases
- A single discount voucher is issued per user for registering or paying with their app for the first time.
- A number of coupon campaigns linked to a channel for redemption against each purchase.
- Loyalty is earned on specific products purchased and vouchers or coupons are issued as rewards.
- Loyalty is earned on specific products purchased and vouchers or coupons are issued as rewards.
- Loyalty is earned on total amount of Payment or Deposit and vouchers or coupons are issued as rewards
Discount wiCode
In order to add a discount wiCode into a payment wiCode the VSP’s application server will need to make an Issue Coupon API call to the CVS API, once the response is received the VSP server must dynamically add the wiCode from CVS into the main Token Manager createToken request as a discountWicode.
When the User redeems the main Payment wiCode in store, the wiCode platform will route the discount wiCode to CVS for authorisation, if approved the discount will be passed back into the wiCode Platform against the basket amount before the total processed amount is sent into the VSP for authorisation.
Discount and Loyalty wiCodes
In order to add a Loyalty wiCode into a payment wiCode the VSP’s application server will need to make an Issue wiCode API call to the wiLoyalty API, once the response is received the VSP server must dynamically add the wiCode from wiLoyalty into the main Token Manager createToken request as a loyaltyWicode along with the discount wiCode.
When the User redeems the main Payment wiCode in store, the wiCode platform will route the discount wiCode to CVS for authorisation and the loyalty wiCode to wiLoyalty, if approved the discount will be passed back into the wiCode Platform against the basket amount before the total processed amount is sent into the VSP for authorisation, loyalty is earned against the total processed amount after the discount is processed. Loyalty auto redemption can be added to the payment and deposit transaction types without the discount wiCode if the business model requires it.
Common error codes:
TOKEN_001
: Invalid token typeTOKEN_002
: Invalid amountTOKEN_003
: Invalid expiry dateTOKEN_004
: Invalid discount wiCodeTOKEN_005
: Invalid loyalty wiCodeAUTH_001
: Invalid API credentials
Tokens request
# EXAMPLE REQUEST
curl "https://token-manager-api-int.wigroup.co/wigroup-tokenmanager/vsp/tokens" \
-H "apiId: <#apiId#>" \
-H "sha1Password: <#sha1Password#>" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"discountWicodes": "1234567,999999999",
"loyaltyWicodes": "7654321,999999999",
"maxTrxAmount": "15000",
"tokenLifeInMin": "15",
"transactionType": "PAYMENT",
"vspReference": "VSP_User_Id_001",
"tipAmount":"5000"
}'
# EXAMPLE RESPONSE without Tip
{
"token": {
"wiCode": "5286264",
"wiQR": "5286264",
},
"responseCode": "-1",
"responseDesc": "Success"
}
# EXAMPLE RESPONSE with Tip
{
"token": {
"wiCode": "5286264",
"wiQR": "5286264|5000",
},
"responseCode": "-1",
"responseDesc": "Success"
}
This resource can be used to issue new wiCodes. Two parameters must be supplied: tokenLifeInMin and vspReference.
Endpoint: {root}/tokens
Available methods: POST
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
vspReference | String | A reference which will be echoed back to the VSP during the transact call, documented in the Transaction Engine VSP POST API. | ✓ | |
tokenLifeInMin | Integer | The life of the token in minutes. This will determine the length of the wiCode returned. Longer time frames produce longer wiCodes. | ✓ | |
transactionType | String | Used to return only brands that have deals of this dealType. | ✓ | |
transactionType | String | This is the type of transaction. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. | ✓ | |
discountWicodes | String | A list of discount wicodes to link to wicode. | ✓ | |
loyaltyWicodes | String | A list of loyalty wicodes to link to wicode. | ✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
wiQR | String | The wiCode linked to the user token. If a tipAmount is specified, the wiQR field will contain a pipe and the tip amount in cents as per the example. | ✓ | |
tipAmount | Integer | The tip amount included with the token | ✓ |
Transaction Gateway
POST Transaction Request
Transactional Gateway (callback)
The wiCode Platform requires the VSP to implement a transactional API to which Transaction Engine can POST the transactional requests as JSON objects. This section describes the methods that need to be implemented by the VSP.
Authorisation
The YoyoPlatform will send the API id and password to the VSP for additional security.
Error handling
Test cases will be provided for negative tests, however we do request that the VSP provide us with a list of Errors and that they be as accurate and as informative as possible so that the Customer and the Merchant teller will understand what the errors mean. The more accurate the human readable error message is the less support requests the VSP will receive.
POST Transaction Request Callback
# Request Example
{
"token": {
"id": "1234567",
"type": "WICODE"
},
"storeTrxDetails": {
"storeId": 1050,
"basketId": "basket1",
"cashierId": "cashier1",
"posId": "workstation1",
"trxId": "1"
}
}
This call can be used to obtain information about a YoyoGroup Coupon or Voucher. The Coupon/Voucher ID is specified as a path parameter in this case.
- Requests authorisation of funds against the wiCode.
- The VSP is required to reserve the funds on a successful Transaction Request Response.
- A successful transaction Request will also put the wiCode into a SPR (success pending recon) state.
Endpoint: {your_endpoint}/<#your_context#>
Available methods: POST
Fields | Description |
---|---|
wiTrxId | The Yoyo Platform unique transaction identifier. |
token ID Type vspReference |
The ID is the unique token which the YoyoPlatform 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. vspReference is the VSP's reference linked to this token. |
type | This is the type of transaction. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
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 Yoyo. 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 |
totalAmount | This is the total transaction amount in cent. This is the sum of the basketAmount and the cashbackAmount. |
basketAmount | This is the total transaction amount in cent for all products in the basket. If the transaction type is DEPOSIT, this is the deposit amount. It the transaction type is WITHDRAWAL this is the amount to withdraw. |
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. |
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. |
vspCredentials | The VSP's API credentials are passed in the body of the message for authentication over and above SSL. |
Transaction Response
# Response Example
{
"responseCode": "-1",
"responseDesc": "Success",
"vspTrxId": "0001",
"totalAmountProcessed": 100,
"basketAmountProcessed": 100,
"cashbackAmountProcessed": 0,
"id": 1234,
"name": "vsp_name"
}
Fields | Description |
---|---|
responseCode | The authorization response code. ‐1 is Authorized. All other codes are treated as failed. |
responseDescription | Readable description of responseCode, typically used to give the user and cashier context of the transaction outcome. |
vspTrxId | The VSP's unique transaction id. It is required should the transaction on successful authorization. |
totalAmountProcessed | The basket amount that was used in processing the transaction. |
basketAmountProcessed | The basket amount that was used in processing the transaction. |
cashBackAmountProcessed | 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. |
id | The VSP id. |
name | The VSP name. |
POST Advise Request Callback
# EXAMPLE REQUEST
curl "{your_endpoint}/<#your_context#>" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"action": "FINALISE",
"originalTrx": {
"storeTrxDetails": {
"storeId": 1050,
"basketId": "Test VSP 09-05-2015 15:42:13",
"trxId": "1543",
"posId": "8",
"cashierId": "Sam"
},
"wiTrxId": 21752,
"type": "PAYMENT",
"vspTrxId": 4256
},
"vspCredentials": {
"id": "DummyVSP",
"password": "test"
}
}'
- The Advise request has two types of calls, a Finalise and a Reverse.
- The Advise Finalise indicates a completed transaction.
- The Advise Reverse is used to cancel a transaction and restore the funds balance in the user account.
- Once a transaction has been finalised it cannot be reversed.
- Once either the Finalise and a Reverse has taken place the wiCode then gets freed and returns to the wiCode pool.
Endpoint: {your_endpoint}/<#your_context#>
Available methods: POST
Fields | 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 YoyoGroup. 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 | 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. |
vspTrxId | The transaction ID supplied by the VSP. |
vspCredentials | Optional | The VSP's API credentials can be passed in the body of the message should it require authentication beyond SSL. |
Advice Response
# EXAMPLE RESPONSE
{
"responseCode": "-1",
"responseDesc": "Success"
}
Fields | Description |
---|---|
responseCode | The authorization response code. ‐1 is Authorized. All other codes are treated as failed. |
responseDescription | Readable description of responseCode, typically used to give the user and cashier context of the transaction outcome. |
POST Token Info Request
# EXAMPLE REQUEST
curl "{your_endpoint}/<#your_context#>" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"token": {
"id": "536598854",
"type": "WICODE",
},
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": 1050,
"basketId": "basket50",
"trxId": "trx1",
"posId": "pos1",
"cashierId": "admin"
}
}'
- Requests information and seeks validity of the wiCode from the VSP. Predominantly used in the "Over the Counter” transactional model.
Endpoint: {your_endpoint}/<#your_context#>
Available methods: POST
Fields | Description |
---|---|
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 YoyoGroup. If the StoreID is populated, this will be used. Alternatively, the RemoteStoreID and the RetailerID must be populated - these are used in combination. |
token ID Type |
The ID is the unique token which the YoyoPlatform 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. |
type | This is the type of transaction. It can set to either PAYMENT, DEPOSIT or WITHDRAWAL. |
Token Info Response
# EXAMPLE RESPONSE
{
"responseCode": "-1",
"responseDesc": "Success"
}
Fields | Description |
---|---|
responseCode | The authorization response code. ‐1 is Authorized. All other codes are treated as failed. |
responseDescription | Readable description of responseCode, typically used to give the user and cashier context of the transaction outcome. |
Transaction Engine VSP REST API
The TE VSP API (Scan Model API) is exposed off the wiCode Platform. This API exposes two methods: a GET method named bill, and a POST method named transactions.
API credentials
This section provides interface definitions to allow for implementation on various platforms and in different programming languages. Note that:
- Our APIs were designed using the RESTful architectural style.
- Request and response bodies are formatted as JSON exclusively.
- Variables are indicated between angle brackets and the pound sign, e.g. <#variable#>.
- Different request -‐ response combinations are explored using 'Cases'.
API references
The Token Manager VSP API RESTful web service endpoints may be accessed by utilising the following WADL (<#endpointURL#>):
Test credentials
All calls to the wiCode platform must contain the issuing channel credentials in the header of the API call. This table contains a set of VSP-specific API credentials that may be used to authenticate all API calls made to CVS and YoyoPlatform.
API ID | API Password |
---|---|
<#apiID#> | <#apiPassword#> |
Transactions request
# EXAMPLE REQUEST
curl "https://rad2.wigroup.co:8181/wigroup-transactionengine/vsp/transactions"
-H "apiId: <#apiId#>"
-H "apiPassword: <#apiPassword#>"
-H "Content-Type: application/json; charset=UTF-8"
-X POST
-d {
{
"basketAmount": "100",
"storeTrxDetails": {
"basketId": "180_63631826413",
"cashierId": "snappy",
"posId": "861074024300611",
"storeId": "1050",
"trxId": "1"
},
"token": {
"id": "7997560",
"type": "WICODE"
},
"totalAmount": "100",
"type": "PAYMENT"
}
}
Once the VSP has received the transaction from the mobile device (and created a Payment Token "wiCode" if needed), the VSP should initiate the transaction on the wiCode Platform. The Payment Token should form part of the request body.
The basic layout of the transaction request looks a follows:
Fields | Type | Required/Optional | Description | Request | Response |
---|---|---|---|---|---|
apiId | String | Required | A ID which the VSP authenticates that it is indeed the YoyoPlatform pushing the transaction. | ✓ | |
apiPassword | String | Required | The password hashed by SHA. | ✓ | |
apiClientVersion | String | Optional | This field can be used by VSP integrators to send the version of their implementation to the YoyoPlatform. | ||
apiServerVersion | String | Optional | This field allows VSP integrators to send the version of the YoyoGroup server in use as at their time of integration, ensuring strict backwards compatibility. | ||
basketAmount | Integer | Required | This is the total transaction amount (in cents) of all products in the basket. | ✓ | ✓ |
storeTrxDetails | StoreTrxDetails | Required | This object contains information about the store in which the transaction took place. Find information about the StoreTrxDetails object here. | ✓ | ✓ |
tipAmount | Integer | Optional | 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 | Token | Required | This object contains information about the token. Find information about token object here. | ✓ | ✓ |
totalAmount | Integer | Required | This is the total transaction amount in cent. This is the sum of the BasketAmount and TipAmount. | ✓ | ✓ |
type | String | Required | The type of transaction; either Payment, Deposit or Withdrawal. | ✓ | ✓ |
# EXAMPLE SUCCESS RESPONSE
{
"token": {
"id": "7997560",
"type": "WICODE"
},
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": 1050,
"remoteStoreId": "1234512345",
"retailerId": 999,
"basketId": "180_63631826413",
"trxId": "1",
"posId": "861074024300611",
"cashierId": "snappy"
},
"wiTrxId": 87153,
"totalAmountProcessed": 100,
"basketAmountProcessed": 100,
"tipAmountProcessed": 0,
"amountToSettle": 100,
"vsp": {
"id": 50099,
"name": "Eben VSP",
"trxId": "test_vsp_17-x",
"responseCode": "-1",
"responseDesc": "Redemption successful!"
},
"discount": [],
"loyalty": [],
"responseCode": "-1",
"responseDesc": "Success"
}
# EXAMPLE FAILURE RESPONSE
{
"token": {
"id": "7997560",
"type": "WICODE"
},
"type": "PAYMENT",
"storeTrxDetails": {
"storeId": 1050,
"remoteStoreId": "1234512345",
"retailerId": 999,
"basketId": "180_63631826413",
"trxId": "1",
"posId": "861074024300611",
"cashierId": "snappy"
},
"wiTrxId": 87154,
"totalAmountProcessed": 0,
"basketAmountProcessed": 0,
"responseCode": "02120",
"responseDesc": "Invalid token"
}
Each transaction type uses the XML in a (slightly) different manner.
Fields | Type | Description |
---|---|---|
token | Token | This object contains information about the token. Find information about products object here |
type | String | The type of transaction; either Payment, Deposit or Withdrawal. |
storeTrxDetails | storeTrxDetails | This object contains information about the store in which the transaction took place. Find information about the StoreTrxDetails object here. |
wiTrxId | Long | This is the unique Yoyo transaction ID assigned to the transaction. This field is important for processing a subsequent Advice call. |
totalAmountProcessed | Integer | This is the total transaction amount in cent. This is the sum of the BasketAmount and TipAmount. |
BasketAmountProcessed | Integer | The basket amount that was used in processing the transaction. |
tipAmountProcessed | Integer | 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. |
amountToSettle | Integer | This is the amount, in cent, of the total transaction amount that will be settled to the retailer. The deficit between amountToSettle and totalAmountProcessed is regarded as the discount amount for non/partially-settled campaigns and should be handled as such. |
vspDetails | VspDetails | This object contains information about the vsp. Find information about vsp object here. |
discountProductDetails | DiscountProductDetails | This object contains information about the products on which discounts are applied in this transaction. Find information about discount-product object here. |
loyaltyDetails | LoyaltyDetails | This object contains information about the loyalty earned on this transaction. Please find information about the Loyalty object here here. |
responseCode | Integer | The responseCode returned by the VSP. This should not be used to determine whether the transaction was approved or not. This should only be used for logging and error reporting to VSP. Find information about responseCode object here. |
responseDesc | String | The VSP’s response description. Can be displayed addition to the transactionResponse.responseDesc if available to give more information on why the transaction failed. Find information about responseDesc object here. |
Objects
Product
{
"id": [],
"pricePerUnit": [],
"units": []
}
This object contains information about each product in a user's basket.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
id | String | Required | The SKU/Barcode of product purchased. The id should be consistent in either always sending through the product SKU or product barcode. |
pricePerUnit | Integer | Required | The price per unit. |
units | Integer | Required | The number of units of this product purchased. |
Store transaction details
{
"basketId": [],
"cashierId": [],
"posId": [],
"remoteStoreId": [],
"retailerId": [],
"storeId": [],
"trxId": []
}
This object contains information about the store in which the transaction took place.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
basketId | String | Required | This is the identifier for the basket as assigned by the POS. The POS system must ensure that it stays the same across multiple transactions of the same basket so that unique baskets can be tracked and identified. |
cashierId | String | Required | Identifies the cashier that processed the transaction. |
posId | String | Required | Identifies the POS terminal the transaction was processed on. |
remoteStoreId | Long | Optional | This is the store's own identifier. Can be used instead of the storeId. Must be used in combination with the retailerId. |
retailerId | Long | Optional | This is the unique Yoyo retailer identifier. Required if using the remoteStoreId field instead of the storeId field. |
storeId | Long | Optional | This is the unique Yoyo store identifier. |
trxId | String | Required | This identifies and groups multiple YoyoPlatform transactions together into a single POS transaction. The POS system must ensure that it stays the same across multiple transactions of the same basket so that unique baskets can be tracked and identified. |
Token
{
"id": [],
"type": []
}
This object contains information about the YoyoPlatform token associated with this transaction.
Fields | Data Type | Required/Optional | Description |
---|---|---|---|
id | String | Required | The unique token which the YoyoPlatform uses to identify and route the transaction to the VSP to authorize. |
type | String | Required | The token type is derived from how the token is received at the POS and can be either WICODE, WIQR or BIN. |
VSP
{
"id": [],
"message": [],
"name": [],
"responseCode": [],
"responseDesc": [],
"trxId": []
}
This object contains information about the VSP associated with this transaction. This object will only be returned if the token is valid.
Fields | Data Type | Description |
---|---|---|
id | String | This is an unique VSP identifier. |
message | String | This is a message that can be printed on the user's till slip. Sent back from the VSP on successful transactions. |
name | String | This is the name of the VSP. |
responseCode | String | The responseCode returned by the VSP. This should not be used to determine whether the transaction was approved or not. This should only be used for logging and error reporting to VSP. |
responseDesc | String | The VSP’s response description. Can be displayed addition to the transactionResponse.responseDesc if available to give more information on why the transaction failed. |
trxId | String | The VSP’s transaction ID for a transaction. This is optionally returned by the VSP in the transaction response. |
Discount
{
"amount": [],
"name": [],
"product": {
"id": [],
"units": []
}
}
This object contains information about the discount associated with this transaction.
Fields | Data Type | Description |
---|---|---|
name | String | Discount name/description. |
amount | Integer | The total discount amount for all products in discount. |
product | String | The products on which the discounts are applied. Please find information about the discount product object here. |
Discount product
{
"id": [],
"units": []
}
This object contains information about the products on which discounts are applied in this transaction.
Fields | Data Type | Description |
---|---|---|
id | String | The product id used. |
units | Integer | The number of units processed in the discount. |
discount | String | The discount per product. |
Loyalty
{
"name": [],
"type": [],
"earned": []
}
This object contains information about the loyalty earned on this transaction.
Fields | Data Type | Description |
---|---|---|
name | String | The name of the loyalty program earned against. |
type | String | The type of loyalty earned. Valid values are cent, points or count. |
earned | Integer | The loyalty amount earned. |
Overview - Coupon, Voucher and Giftcard Service
The CVS platform enables enterprises to issue and manage digital rewards in the form of coupons, vouchers, and gift cards. These can be redeemed at integrated point-of-sale (POS) systems.
Issue a Coupon
{
"campaign": {
"id": "CAMP123",
"name": "Summer Promotion"
},
"customer": {
"reference": "CUST456",
"mobile": "+27820000000",
"email": "customer@example.com"
},
"coupon": {
"value": 5000, // 50.00 in cents
"expiryDate": "2024-12-31T23:59:59+0200",
"products": [
{
"id": "PROD001",
"name": "Coffee"
}
]
}
}
Issue a Voucher
{
"campaign": {
"id": "CAMP789",
"name": "Welcome Bonus"
},
"customer": {
"reference": "CUST456",
"mobile": "+27820000000"
},
"voucher": {
"value": 10000, // 100.00 in cents
"expiryDate": "2024-12-31T23:59:59+0200",
"type": "FIXED_VALUE"
}
}
Issue a Gift Card
{
"campaign": {
"id": "CAMP101",
"name": "Digital Gift Card"
},
"customer": {
"reference": "CUST456",
"mobile": "+27820000000",
"email": "customer@example.com"
},
"giftCard": {
"value": 50000, // 500.00 in cents
"expiryDate": "2025-12-31T23:59:59+0200",
"message": "Happy Birthday!",
"sender": {
"name": "John Doe",
"email": "john@example.com"
}
}
}
Response Examples
Success Response
{
"wicode": "123456789",
"type": "COUPON", // or "VOUCHER" or "GIFTCARD"
"value": 5000,
"expiryDate": "2024-12-31T23:59:59+0200",
"status": "ACTIVE",
"campaign": {
"id": "CAMP123",
"name": "Summer Promotion"
},
"customer": {
"reference": "CUST456"
}
}
Error Response
{
"error": {
"code": "CVS_001",
"message": "Invalid campaign ID",
"details": "The specified campaign does not exist or has expired"
}
}
Common Error Codes
CVS_001
: Invalid campaign IDCVS_002
: Invalid customer referenceCVS_003
: Invalid value amountCVS_004
: Campaign expiredCVS_005
: Campaign limit reachedAUTH_001
: Invalid API credentials
Best Practices
Campaign Setup
- Create campaigns via CVS Web Portal
- Define clear expiry dates
- Set appropriate value limits
- Configure product restrictions
Customer Management
- Use consistent customer references
- Validate mobile numbers
- Store customer preferences
Value Management
- Use cents for all monetary values
- Set reasonable expiry dates
- Monitor campaign limits
Security
- Keep API credentials secure
- Use HTTPS for all API calls
- Validate all input data
Error Handling
- Implement proper error handling
- Log all API responses
- Monitor failed issuances
CVS Issuer REST API
The CVS Issuer API is the underlying interface for all of YoyoGroup's Coupon, Voucher, and Gift card related integrations. It is the simplest and most direct way to issue Coupons, Vouchers and Gift cards from YoyoGroup.
Each CVS Issuer API method is accompanied by a table of fields.
- Each method tabulates the available HTTP verb along with the list of parameters that they accept.
- A bold field in the Request column indicates that it's mandatory.
- A ✓ in the Request column of an operation denotes a field available in the request message.
- A ✓ in the Response column of an operation denotes its presence in the response payload.
- GET methods never have a body. All parameters are sent through as part of the URL as query parameters, e.g. {root}/{resource}?parameter=value.
- POST/PUT methods always have a body. All request parameters are sent through as part of a JSON object in the body. There is one exception to this rule when issuing a coupon. The issueWiCode parameter must be sent through as a query parameter as it does not form part of the resource.
- DELETE methods don't have query parameters or a body. It only takes in a URL parameter which is the resource id to delete, e.g. {root}/{resource}/{id}
Date format
A strict ISO 8601 date format is followed for dates. In Java a date can be formatted in the ISO 8601 format with the following snippet:
Monetary format
Monetary amounts are both accepted and returned in cents.
Paginated collections
All of the RESTful Web Service calls that return collections accept the following query parameters:
Parameter | Type | Description |
---|---|---|
pageSize | Integer (Default 20) | The max number of items returned per page. |
pageOffset | Integer (Default 0) | Zero‐based page offset into the list of all results. |
orderBy | String | A field by which to order the list (when ordering on the collection is available). |
orderDirection | String (Default "ASC") | The order direction (when ordering on the list is available). |
The following fields are returned in a paging object in the response of collection requests:
Parameter | Type | Description |
---|---|---|
orderBy | String | The field by which the list was ordered. |
orderDirection | String | The order direction. |
pageSize | Integer | The max number of items returned per page. |
pageOffset | Integer | Zero‐based page offset into the list of all results. |
numItemsOnPage | Integer | The number of items returned on the current page. |
numItemsInTotal | Integer | Total number of items found for the current set of constraints. |
numPages | Integer | The total number of pages found. |
API credentials
This section provides interface definitions to allow for implementation on various platforms and in different programming languages. Note that:
- Our APIs were designed using the RESTful architectural style.
- Request and response bodies are formatted as JSON exclusively.
- Variables are indicated between angle brackets and the pound sign, e.g. {variable}.
- Different request -‐ response combinations are explored using 'Cases'.
Authentication All the request make use of the same authentication details and will be provided by the friendly integration team at Yoyo. Authentication detail are set in the header of each request and also serve as the authorisation to gain access to specific resources. Here is a snippet that show what the request header should look like.
{
"apiId":"API_ID_GOES_HERE",
"apiPassword":"API_PASSWORD_GOES_HERE",
"Content-Type":"application/json"
}
API references
Once the CVS campaigns have been created via the CVS Web Portal and signed-off, the CVS RESTful web service endpoints may be accessed by utilising the following WADL ({endpointURL}):
Test credentials
All calls to the wiCode platform or to CVS must contain the issuing channel credentials in the header of the API call. Table 2 contains a set of VSP-specific API credentials that may be used to authenticate all API calls made to CVS and YoyoPlatform.
API ID | API Password |
---|---|
{apiID} | {apiPassword} |
Test API credentials are provided by the Yoyo integration team, and can thereafter be accessed via the CVS Portal. CVS portal login credentials will also be provided by the Yoyo integration team.
Coupon Campaigns
This request returns a list of active campaigns which are linked to the specific channel (issuer interface). By default only campaigns which still have coupons left to issue will be returned.
GET /couponcampaigns
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
"issueFromDate": "2017-09-11T00:00:00+0200",
"issueToDate": "2017-09-12T23:59:59+0200",
"redeemFromDate": "2017-09-11T00:00:00+0200",
"redeemToDate": "2017-09-12T23:59:59+0200",
"minBasketValue": 0,
"maxBasketValue": 0,
"maxRedemptionsPerUserPerDay": 0,
"id": 48184,
"name": "% discount",
"description": "% discount",
"termsAndConditions": "% discount",
"createDate": "2017-09-11T11:31:43+0200",
"requireUserRef": false,
"allowedUsersRestricted": false,
"maxNumberPerUser": 1,
"maxLivePerUser": 0,
"campaignType": "VOUCHER",
"minRank": 11,
"categories": [ {
"name": "All",
"id": 782,
"rank": 11
}],
"maxAllowedToIssue": 10,
"maxAllowedToIssueDaily": 10,
"maxRedemptionRuleAmount": 100000,
"discountType": "Percentage",
"percentageDiscount": 20,
"totalLive": 0,
"totalRedeemed": 0,
"totalExpired": 0,
"totalIssued": 0,
"totalIssuedToday": 0,
"campaignInfo": [ {
"name": "Adword",
"value": "%,discount,% discount"
}],
"stateId": "A",
"allowExpiryDateOverride": false,
"expiryDays": 1096,
"campaignRedemptionRestrictions": {
"redeemabableOnSundays": true,
"redeemabableOnMondays": true,
"redeemabableOnTuesdays": true,
"redeemabableOnWednesdays": true,
"redeemabableOnThursdays": true,
"redeemabableOnFridays": true,
"redeemabableOnSaturdays": true,
"redemptionFromTime": "00:00",
"redemptionToTime": "00:00"
}
}
],
"paging": {
"pageSize": 20,
"pageOffset": 0,
"numItemsOnPage": 11,
"numItemsInTotal": 11,
"numPages": 1
},
"responseCode": "-1",
"responseDesc": "Success"
This request returns a list of active campaigns which are linked to the specific channel (issuer interface). By default only campaigns which still have coupons left to issue will be returned. If no user reference (userRef) is specified in the request it is possible that there are campaigns which the user has already reached the max allowed per user. When the user tries to issue another on the campaign they will be declined. For a better customer experience we recommend including the user reference in the request. This will hide campaigns which the user cannot issue on. A similar problem occurs when the user has reached the max allowed to be issued, but still has a coupon active for redemption. This campaign will not be included in the campaign list. To include these campaigns the includeRedeemableForUser parameter must be set to true.
Endpoint: {root}/couponcampaigns
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the campaign. | ✓ | ✓ |
allowExpiryDateOverride | Boolean | Whether the campaign allows the default expiry days to be overwritten on issue. | ✓ | |
expiryDays | Integer | The default number of days the coupon will be valid for from issue date. The expiry date will be set to midnight x days from issue date. | ✓ | |
adwords | List |
List of adwords linked to the campaign. Adwords are special search key words which when setup against a campaign can be used to filter the campaign. | ✓ | ✓ |
campaignPhase | String | The phase of the campaign.
|
✓ | |
campaignType | String | The campaign type.
|
✓ | ✓ |
categoryIds | List |
A list of category id's. It will return campaigns which match any of the categories supplied. | ✓ | |
merchantId | Integer | A merchant id to filter campaigns on. | ✓ | |
provinceId | Integer | A province id to filter campaigns on. | ✓ | |
countryId | Integer | A country id to filter campaigns on. | ✓ | |
retailerId | Integer | A retailer id to filter campaigns on. | ✓ | |
longitude | Double | A longitude position. Required for distance calculation. Both longitude and latitude need to be specified together. | ✓ | |
latitude | Double | A latitude position. Required for distance calculation. Both longitude and latitude need to be specified together. | ✓ | |
userRef | String | A unique user reference. When specified only campaigns on which the user can still be issued coupons will be returned. | ✓ | |
includeRedeemableForUser | Boolean | Whether to include campaigns which the user has unredeemed coupons/voucher, but cannot get anymore issued. Normally the campaign would drop off the list as soon as the user cannot be issued anymore. Must be used in conjunction with the userRef field. | ✓ | |
totalViewed | Integer | The total number viewed of the couponCampaign. | ✓ | |
issueFromDate | String | The date from which a couponCampaign is allowed to be issued. | ✓ | |
issueToDate | String | The date the couponCampaign is allowed to be issued to. | ✓ | |
redeemFromDate | String | The date the couponCampaign is allowed to be redeemed from. | ✓ | |
redeemToDate | String | The date the couponCampaign is allowed to be redeemed to. | ✓ | |
minBasketValue | Integer | The minimum value of the basket allowed to redeem. | ✓ | |
maxBasketValue | Integer | The maximum value of the basket allowed to redeem. | ✓ | |
name | String | The name of the couponCampaign. | ✓ | |
description | String | The description of the couponCampaign. | ✓ | |
termsAndConditions | String | The terms and conditions of the couponCampaign. | ✓ | |
imageUrl | String | The image url of the couponCampaign. | ✓ | |
createDate | String | The date the couponCampaign was created. | ✓ | |
requireUserRef | Boolean | True if a userRef is required for couponCampaign. | ✓ | |
allowedUsersRestricted | Boolean | Whether only the users linked to the campaigns are able to view the contents of the campaign. | ✓ | |
maxNumberPerUser | Integer | The maximum number allowed per user. | ✓ | |
maxRedemptionsPerUserPerDay | Integer | The maximum number of redemption's per user on the couponCampaign daily. | ✓ | |
maxLivePerUser | Integer | The maximum allowed live(issued and not redeemed/expired) per user. | ✓ | |
minRank | Integer | The minimum rank of the couponCampaign. | ✓ | |
categories | Object | List of category details. Each entry consists of a name (String), id (Long) and rank (Integer). | ✓ | |
distance | Double | The distance to the closest merchant. | ✓ | |
maxAllowedToIssue | Integer | The maximum allowed to be issued in total. | ✓ | |
maxAllowedToIssueDaily | Integer | The maximum allowed to be issued in total daily. | ✓ | |
maxRedemptionRuleAmount | Integer | The maximum redemption rule amount. | ✓ | |
discountType | String | Fixed value or percentage . |
✓ | |
percentageDiscount | Integer | This parameter is only available for vouchers. If a voucher campaign is a percentage discount, the value will be listed here. | ✓ | |
totalLive | Integer | The total live coupons/voucher on the couponCampaign. | ✓ | |
totalRedeemed | Integer | The total number redeemed of the couponCampaign. | ✓ | |
totalExpired | Integer | The total number expired of the couponCampaign. | ✓ | |
totalIssued | Integer | The total number issued (live + redeemed) of the couponCampaign. | ✓ | |
totalIssuedToday | Integer | The total number issued daily of the couponCampaign. | ✓ | |
campaignInfo | Object | List of campaign info details. Each entry consists of a campaign name (String) and a campaign info value (String). | ✓ | |
stateId | String | The current state of the coupon.
|
✓ | |
campaignRedemptionRestrictions | Long | This rule states on which days the reward can be redeemed. If restrictions exist for a specific day, the value of the parameter will be "FALSE" | ✓ |
GET /couponcampaigns/{campaignId}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns/{campaignId}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
"couponCampaigns": [ {
"allowExpiryDateOverride": false,
"expiryDays":0,
"totalViewed": 0,
"issueFromDate": "2015-05-21T00:00:00+0200",
"issueToDate": "2015-11-21T23:59:59+0200",
"redeemFromDate": "2015-05-21T00:00:00+0200",
"redeemToDate": "2015-11-21T23:59:59+0200",
"minBasketValue": 0,
"maxBasketValue": 0,
"maxRedemptionsPerUserPerDay": 0,
"id": 4449,
"name": "Coupon R5",
"description": "Coupon R5",
"termsAndConditions": "VSP T&Cs",
"imageURL": "http://goo.gl/Zodst9",
"createDate": "2015-05-21T07:14:01+0200",
"requireUserRef": false,
"allowedUsersRestricted": false,
"maxNumberPerUser": 0,
"maxLivePerUser": 0,
"campaignType": "COUPON",
"minRank": 3,
"categories": [ {
"name": "All",
"id": 807,
"rank": 3
}],
"maxAllowedToIssue": 100000,
"maxAllowedToIssueDaily": 100000,
"maxRedemptionRuleAmount": 500,
"discountType": "Percentage",
"percentageDiscount": 20,
"totalLive": 1,
"totalRedeemed": 37,
"totalExpired": 1,
"totalIssued": 38,
"totalIssuedToday": 4,
"campaignInfo": [ {
"name": "Adword",
"value": "Integration,Gift,Card,R5,Integration Gift Card R5"
}],
"stateId": "A"
}],
"paging":
{
"pageSize": 20,
"pageOffset": 0,
"numItemsOnPage": 1,
"numItemsInTotal": 1,
"numPages": 1
},
"responseCode": "-1",
"responseDesc": "Success"
}
When a specific campaign's details are required rather than pulling the entire campaign list down, this endpoint can be used to retrieve the single campaign's details.
Endpoint: {root}/couponcampaigns/{campaignId}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
campaignId | Integer | The id of the campaign. | ✓ | ✓ |
allowExpiryDateOverride | Boolean | Whether the campaign allows the default expiry days to be overwritten on issue. | ✓ | |
expiryDays | Integer | The default number of days the coupon will be valid for from issue date. The expiry date will be set to midnight x days from issue date. | ✓ | |
totalViewed | Integer | The total number viewed of the couponCampaign. | ✓ | |
issueFromDate | String | The date from which a couponCampaign is allowed to be issued. | ✓ | |
issueToDate | String | The date the couponCampaign is allowed to be issued to. | ✓ | |
redeemFromDate | String | The date the couponCampaign is allowed to be redeemed from. | ✓ | |
redeemToDate | String | The date the couponCampaign is allowed to be redeemed to. | ✓ | |
minBasketValue | Integer | The minimum value of the basket allowed to redeem. | ✓ | |
maxBasketValue | Integer | The maximum value of the basket allowed to redeem. | ✓ | |
name | String | The name of the couponCampaign. | ✓ | |
description | String | The description of the couponCampaign. | ✓ | |
termsAndConditions | String | The terms and conditions of the couponCampaign. | ✓ | |
imageUrl | String | The image url of the couponCampaign. | ✓ | |
createDate | String | The date the couponCampaign was created. | ✓ | |
requireUserRef | Boolean | True if a userRef is required for couponCampaign. | ✓ | |
allowedUsersRestricted | Boolean | Whether only the users linked to the campaigns are able to view the contents of the campaign. | ✓ | |
maxNumberPerUser | Integer | The maximum number allowed per user. | ✓ | |
maxRedemptionsPerUserPerDay | Integer | The maximum number of redemption's per user on the couponCampaign daily. | ✓ | |
maxLivePerUser | Integer | The maximum allowed live(issued and not redeemed/expired) per user. | ✓ | |
minRank | Integer | The minimum rank of the couponCampaign. | ✓ | |
categories | Object | List of category details. Each entry consists of a name (String), id (Long) and rank (Integer). | ✓ | |
distance | Double | The distance to the closest merchant. | ✓ | |
maxAllowedToIssue | Integer | The maximum allowed to be issued in total. | ✓ | |
maxAllowedToIssueDaily | Integer | The maximum allowed to be issued in total daily. | ✓ | |
maxRedemptionRuleAmount | Integer | The maximum redemption rule amount. | ✓ | |
discountType | String | Fixed value or percentage . |
✓ | |
percentageDiscount | Integer | This parameter is only available for vouchers. If a voucher campaign is a percentage discount, the value will be listed here. | ✓ | |
totalLive | Integer | The total live coupons/voucher on the couponCampaign. | ✓ | |
totalRedeemed | Integer | The total number redeemed of the couponCampaign. | ✓ | |
totalExpired | Integer | The total number expired of the couponCampaign. | ✓ | |
totalIssued | Integer | The total number issued (live + redeemed) of the couponCampaign. | ✓ | |
totalIssuedToday | Integer | The total number issued daily of the couponCampaign. | ✓ | |
campaignInfo | Object | List of campaign info details. Each entry consists of a campaign name (String) and a campaign info value (String). | ✓ | |
stateId | String | The current state of the coupon.
|
✓ |
GET /couponcampaigns/{campaignId}/skus
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns/{campaignId}/skus" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
"responseCode": "-1",
"responseDesc": "Success!",
"skus": [
{
"sku": "string",
"value": 0,
"brand": "string",
"product": "string",
"size": "string"
}
]
}
If the campaign type is COUPON, the campaign will have SKUs linked to it. This endpoint can be used to retrieve the list of SKUs linked to the campaign.
Endpoint: {root}/couponcampaigns/{campaignId}/skus
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
campaignId | Integer | The id of the campaign. | ✓ | ✓ |
skus | Array | List of skus. Each sku object in the array consists of a sku (string), the sku value (integer), the sku brand (string), the sku product (string) and the product size (string) | ✓ |
Coupons
The fundamental difference between a Yoyo Coupon and Voucher is that a Coupon is associated with a particular SKU (or set of SKUs) being in the basket, while a voucher is merely a fixed discount amount, or percentage discount amount off the total basket amount processed during tender.
The issuing and redemption of Yoyo Coupons and Vouchers are identical when utilising the CVS Issuer API.
POST /coupons
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons?issueWiCode=true" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"campaignId": "9000",
"userRef": "VSP_User_Id_001",
"mobileNumber": "string",
"smsMessage": "string",
"sendSMS": boolean
}'
# Example response
{
“coupon”: {
“id”: 20,
“userRef”: "VSP_User_Id_001",
“campaignId”: 9000,
“campaignName”: "VSPTestCouponCampaign",
“campaignType”: "COUPON",
“termsAndConditions”: "VSP T&Cs",
“createDate”: "2015-05-15T15:10:07+0200",
“description”: "R5.00 off SKU 1234",
“redeemFromDate”: "2015-05-15T15:10:07+0200",
“redeemToDate”: "2015-08-22T23:59:59+0200",
“wiCode”: 1234567,
“voucherAmount”: 500,
“wiQr”: 1234567
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
This resource can be used to issue new coupons (coupon/voucher). Issuing a Coupon or Voucher is a straight forward API call. Two parameters must be supplied: campaignID and userRef. Each time this API is called a Coupon or Voucher is issued against the userRef and the campaignID.
Endpoint: {root}/coupons
Available methods: POST
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
issueWiCode | Boolean (query parameter) | Whether to issue a wiCode linked to the coupon for single redemption. Default it is set to false. | ✓ | |
campaignId | Integer | The id of the campaign to issue against. | ✓ | ✓ |
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
mobileNumber | String | The mobile number. The mobile number must be presented in International format. | ✓ | ✓ |
smsMessage | String | The message to override original sms message with. Used in request only. The following hash-tag's can be used: #WICODE (The wiCode), #MOBISITE (Will add a link to a generic mobisite for QR display.), #BALANCE (The value in Rand.) and #EXPIRY (Expiry date yyyy/mm/dd). | ✓ | |
sendSMS | Boolean | Indicates whether an SMS must be sent on issue or not. | ✓ | ✓ |
additionalInfo | String | Any additional information the channel would like to store against the coupon can be placed in this list. It can then be retrieved by getting the coupon details when needed. | ✓ | |
serviceProviderId | Integer | If the campaign has an Airtime Reward linked to it the channel can provide the airtime service provider id. If no provider id specified, the system will try and issue against the most obvious airtime provider. If it fails it will try all others. Slightly slower than specifying the correct provider upfront. | ✓ | ✓ |
id | Integer | The id of the coupon. | ✓ | |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | |
termsAndConditions | String | The terms and conditions of the coupon. | ✓ | |
numExpiryDays | Integer | The number of expiry days. Used in request only. | ✓ | |
createDate | String | The date the couponCampaign was created. | ✓ | |
description | String | A description of the campaign. | ✓ | |
imageURL | String | The image url of the coupon. | ✓ | |
redeemFromDate | String | From which date the coupon can be redeemed. | ✓ | |
redeemToDate | String | Until when the coupon is redeemable. | ✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
voucherAmount | Integer | The possible coupon redemption amount. | ✓ | |
wiQR | String | The wiCode linked to the user token. | ✓ |
GET /coupons/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons/{id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“coupon“: {
“id“: 171117,
"userRef": "string",
"mobileNumber": "string",
“campaignId“: 4449,
“campaignName“: "Integration Coupon R5",
“campaignType“: "COUPON",
“termsAndConditions“: "Integration Coupon R5",
“createDate“: "2015-05-21T09:11:32+0200",
“description“: "Integration Coupon R5",
“imageUrl“: "http://qa.wigroup.co/wigroup/image_uploads/2015-05-21_071108.PNG",
“redeemFromDate“: "2015-05-21T00:00:00+0200",
“redeemToDate“: "2015-11-21T23:59:59+0200",
“wiCode“: "902430319",
"redeemedAmount": 100,
“voucherAmount“: 500,
“stateId“: "R",
“redeemedDate“: "2015-05-21T09:13:17+0200"
},
“responseCode": "-1",
“responseDesc“: "Success"
}
This call can be used to obtain information about a Yoyo Coupon or Voucher. The Coupon/Voucher ID is specified as a path parameter in this case.
Endpoint: {root}/coupons/{id}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the coupon. | ✓ | |
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | |
mobileNumber | String | The users mobile number, if available. | ✓ | |
campaignId | Integer | The id of the campaign to issue against. | ✓ | |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | |
termsAndConditions | String | The terms and conditions of the coupon. | ✓ | |
createDate | String | The date the couponCampaign was created. | ✓ | |
description | String | A description of the campaign. | ✓ | |
imageURL | String | The image url of the coupon. | ✓ | |
redeemFromDate | String | From which date the coupon can be redeemed. | ✓ | |
redeemToDate | String | Until when the coupon is redeemable. | ✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the coupon. | ✓ | |
voucherAmount | Integer | The possible coupon redemption amount. | ✓ | |
stateId | String | The current state of the coupon.
|
✓ | |
redeemedDate | String | The date on which the coupon was redeemed (if it was expired). | ✓ | |
expiredDate | String | The on which the coupon expired. | ✓ |
DELETE /coupons/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons/{id}" \
-H "id: {id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X DELETE
# Example response
{
“responseCode”: "-1",
“responseDesc”: "Success"
}
This call can be used to expire (delete) a Yoyo Coupon or Voucher. The Coupon/Voucher ID is specified as a header parameter in this case. The funds will be returned to the campaign.
Endpoint: {root}/coupons/{id}
Available methods: DELETE
Coupon Transactions
GET /coupontransactions
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupontransactions" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“couponTransactions“: [ {
“id“: 123499,
“transactionId“: 101694,
“couponId“: 183980,
“wiCode“: "528626479",
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "YourRetailer",
“processedAmount“: 2500,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "AAIssuer",
“issuerId“: 128,
“stateId“: "S"
}],
“paging“:
{
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This endpoint can be used to retrieve all coupon related transactions. If no filters are specified it will return all coupon transactions ordered by date.
Endpoint: {root}/coupontransactions
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
transactionId | Integer | The top level transaction id. All transactions are linked to a high level transaction. The high level transaction groups multiple coupon transactions as well as gift card transactions. | ✓ | ✓ |
userRef | String | If the user reference is specified on transactions linked to the user will be returned. | ✓ | ✓ |
couponId | Integer | To filter on specific coupon Id. | ✓ | ✓ |
wiCode | String | The wiCode linked to the user token. | ✓ | |
campaignId | Integer | Filter transactions for specific campaign. | ✓ | ✓ |
dateFrom | String | The date from which to return transactions. | ✓ | |
dateTo | String | The date to which to return transactions. | ✓ | |
id | Integer | The coupon transaction id. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The processed amount. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | String | The id of the interface issuer. | ✓ | |
issuerId | String | The id of the issuer. | ✓ | |
stateId | Integer | The current transaction state.
|
✓ |
GET /coupontransactions/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupontransactions/{id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“couponTransactions“: [ {
“id“: 123499,
“transactionId“: 101694,
“couponId“: 183980,
“wiCode“: "528626479",
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "YourRetailer",
“processedAmount“: 2500,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "AAIssuer",
“issuerId“: 128,
“stateId“: "S"
}],
“paging“:
{
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This resource returns a specific coupon transaction.
Endpoint: {root}/coupontransactions/{id}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The coupon transaction id. | ✓ | ✓ |
transactionId | Integer | The top level transaction id. All transactions are linked to a high level transaction. The high level transaction groups multiple coupon transactions as well as gift card transactions. | ✓ | |
couponId | Integer | To filter on specific coupon Id. | ✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
userRef | String | If the user reference is specified on transactions linked to the user will be returned. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The processed amount. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | String | The id of the interface issuer. | ✓ | |
issuerId | String | The id of the issuer. | ✓ | |
stateId | Integer | The current transaction state.
|
✓ |
Giftcard Campaigns
This request returns a list of active campaigns which are linked to the specific channel (issuer interface).
GET /giftcardcampaigns
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcardcampaigns" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcardCampaigns“: [ {
“minValueAllowedToIssue“: 500,
“maxValueAllowedToIssue“: 500,
“totalAmountIssued“: 500,
“totalAmountRedeemed“: 6000,
“id“: 4420,
“name“: "Gift Card R5",
“description“: "Gift Card R5",
“termsAndConditions“: "VSP T&Cs",
“imageURL”: "http://goo.gl/Zodst9",
“createDate“: "2015-05-21T07:14:01+0200",
“requireUserRef“: false,
“allowedUsersRestricted“: false,
“maxNumberPerUser“: 0,
“maxLivePerUser“: 0,
“campaignType“: "GIFTCARD",
“minRank“: 2,
“categories“: [ {
“name“: "All",
“id“: 807,
“rank“: 3
}],
“totalLive“: 1,
“totalRedeemed“: 6000,
“totalExpired“: 1,
“totalIssued“: 14,
“campaignInfo“: [{
“name“: "Adword",
“value“: "Integration,Gift,Card,R5,Integration Gift Card R5"
}],
“stateId“: "A",
"allowExpiryDateOverride": false,
"expiryDays": 1095
}],
“paging“: {
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This endpoint returns all the active Gift Card campaigns which can be issued against. A campaign can be issued against if it has the required min float and the user has not yet reached the max allowed per user limit.
Available methods: GET
All requested parameters, except the API credentials, are query parameters.
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the campaign. | ✓ | ✓ |
adwords | List |
List of adwords linked to the campaign. Adwords are special search key words which when setup against a campaign can be used to filter the campaign. | ✓ | |
categoryIds | List |
A list of category id's. It will return campaigns which match any of the categories supplied. | ✓ | |
merchantId | Integer | A merchant id to filter campaigns on. | ✓ | |
provinceId | Integer | A province id to filter campaigns on. | ✓ | |
countryId | Integer | A country id to filter campaigns on. | ✓ | |
retailerId | Integer | A retailer id to filter campaigns on. | ✓ | |
longitude | Double | A longitude position. Required for distance calculation. Both longitude and latitude need to be specified together. | ✓ | |
latitude | Double | A latitude position. Required for distance calculation. Both longitude and latitude need to be specified together. | ✓ | |
userRef | String | A unique user reference. When specified only campaigns on which the user can still be issued coupons will be returned. | ✓ | |
includeRedeemableForUser | Boolean | Whether to include campaigns which the user has unredeemed coupons/voucher, but cannot get anymore issued. Normally the campaign would drop off the list as soon as the user cannot be issued anymore. Must be used in conjunction with the userRef field | ✓ | |
minValueAllowedToIssue | Integer | The minimum value of a giftcard that can be issued. | ✓ | |
maxValueAllowedToIssue | Integer | The maximum value of a giftcard that can be issued. | ✓ | |
totalAmountIssued | Integer | The total amount(cents) issued to giftcards. | ✓ | |
totalAmountRedeemed | Integer | The total amount(cents) redeemed on campaign. | ✓ | |
allowedExpiryDateOverride | Boolean | Whether the expiry date may be overriden. | ✓ | |
name | String | The name of the giftcard campaign. | ✓ | |
description | String | The description of the giftcard campaign. | ✓ | |
termsAndConditions | String | The terms and conditions of the giftcard campaign. | ✓ | |
imageUrl | String | The image url of the giftcard campaign. | ✓ | |
createDate | String | The date the giftcard campaign was created. | ✓ | |
requireUserRef | Boolean | True if a userRef is required for giftcard campaign. | ✓ | |
allowedUsersRestricted | Boolean | Whether only the users linked to the campaigns are able to view the contents of the campaign. | ✓ | |
maxLivePerUser | Integer | The maximum allowed live(issued and not redeemed/expired) per user. | ✓ | |
maxNumberPerUser | Integer | The maximum number allowed per user. | ✓ | |
campaignType | String | The campaign type.
|
✓ | |
minRank | Integer | The minimum rank of the giftcard campaign. | ✓ | |
categories | Object | List of category details. Each entry consists of a name (String), id (Integer) and description (Long). | ✓ | |
distance | Double | The distance to the closest merchant. | ✓ | |
totalExpired | Integer | The total number of giftcards expired. | ✓ | |
totalIssued | Integer | The total number of giftcards issued (live + redeemed). | ✓ | |
totalLive | Integer | The total number of live (active) giftcards. | ✓ | |
totalRedeemed | Integer | The total number of giftcards redeemed. | ✓ | |
campaignInfo | Object | List of campaign info details. Each entry consists of a campaign name (String) and a campaign info value (String). | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ | |
allowExpiryDateOverride | Boolean | Whether the campaign allowes the default expiry days to be overwritten on issue. | ✓ | |
expiryDays | Integer | The default number of days the coupon will be valid for from issue date. The expiry date will be set to midnight x days from issue date. | ✓ |
GET /giftcardcampaigns/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcardcampaigns/{id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcardCampaigns“: [ {
“minValueAllowedToIssue“: 500,
“maxValueAllowedToIssue“: 500,
“totalAmountIssued“: 500,
“totalAmountRedeemed“: 6000,
“id“: 4420,
“name“: "Gift Card R5",
“description“: "Gift Card R5",
“termsAndConditions“: "VSP T&Cs",
“imageURL”: "http://goo.gl/Zodst9",
“createDate“: "2015-05-21T07:14:01+0200",
“requireUserRef“: false,
“allowedUsersRestricted“: false,
“maxNumberPerUser“: 0,
“maxLivePerUser“: 0,
“campaignType“: "GIFTCARD",
“minRank“: 2,
“categories“: [ {
“name“: "All",
“id“: 807,
“rank“: 3
}],
“totalLive“: 1,
“totalRedeemed“: 6000,
“totalExpired“: 1,
“totalIssued“: 14,
“campaignInfo“: [{
“name“: "Adword",
“value“: "Integration,Gift,Card,R5,Integration Gift Card R5"
}],
“stateId“: "A",
"allowExpiryDateOverride": false,
"expiryDays": 1095
}],
“paging“:
{
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This endpoint returns all the active Gift Card campaigns which can be issued against. A campaign can be issued against if it has the required min float and the user has not yet reached the max allowed per user limit.
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the campaign. | ✓ | ✓ |
minValueAllowedToIssue | Integer | The minimum value of a giftcard that can be issued. | ✓ | |
maxValueAllowedToIssue | Integer | The maximum value of a giftcard that can be issued. | ✓ | |
totalAmountIssued | Integer | The total amount(cents) issued to giftcards. | ✓ | |
totalAmountRedeemed | Integer | The total amount(cents) redeemed on campaign. | ✓ | |
allowedExpiryDateOverride | Boolean | Whether the expiry date may be override | ✓ | |
name | String | The name of the giftcard campaign. | ✓ | |
description | String | The description of the giftcard campaign. | ✓ | |
termsAndConditions | String | The terms and conditions of the giftcard campaign. | ✓ | |
imageUrl | String | The image url of the giftcard campaign. | ✓ | |
createDate | String | The date the giftcard campaign was created. | ✓ | |
requireUserRef | Boolean | True if a userRef is required for giftcard campaign. | ✓ | |
allowedUsersRestricted | Boolean | Whether only the users linked to the campaigns are able to view the contents of the campaign. | ✓ | |
maxLivePerUser | Integer | The maximum allowed live(issued and not redeemed/expired) per user. | ✓ | |
maxNumberPerUser | Integer | The maximum number allowed per user. | ✓ | |
campaignType | String | The campaign type.
|
✓ | |
minRank | Integer | The minimum rank of the giftcard campaign. | ✓ | |
categories | Object | List of category details. Each entry consists of a name (String), id (Integer) and description (Long). | ✓ | |
distance | Double | The distance to the closest merchant. | ✓ | |
totalExpired | Integer | The total number of giftcards expired. | ✓ | |
totalIssued | Integer | The total number of giftcards issued (live + redeemed). | ✓ | |
totalLive | Integer | The total number of live (active) giftcards. | ✓ | |
totalRedeemed | Integer | The total number of giftcards redeemed. | ✓ | |
campaignInfo | Object | List of campaign info details. Each entry consists of a campaign name (String) and a campaign info value (String). | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ | |
allowExpiryDateOverride | Boolean | Whether the campaign allows the default expiry days to be overwritten on issue. | ✓ | |
expiryDays | Integer | The default number of days the coupon will be valid for from issue date. The expiry date will be set to midnight x days from issue date. | ✓ |
Giftcards
This resource is used to issue a giftcard. Depending on how the campaign is setup by the campaign owner, the channel can set the balance and expiry date of the giftcard. A giftcard can be redeemed multiple times.
Create (issue) a Gift Card
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcards?issueWiCode=true" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"campaignId": "9000",
"balance": "2000"
"userRef": "VSP_User_Id_001",
"mobileNumber": "string",
"numExpiryDays": 3,
"smsMessage": "Dear Customer. You have #BALANCE value to spend. wiCode: #WICODE. Expires: #EXPIRY.",
"sendSMS": boolean,
"sendFollowUpSMS": boolean,
"stateId": "A"
}'
# Example response
{
“giftcard”: {
“id”: 20,
“campaignId”: 9000,
“interfaceIssuerId”: "TestChannel",
“issuerId”: 94,
“userRef”: "VSP_User_Id_001",
“mobileNumber”: "string",
“sendSMS”: boolean,
“sendFollowUpSMS”: boolean,
“issuedAmount”: 2000,
“redeemedAmount”: 0,
“expiredAmount”: 0,
“balance”: 2000,
“createDate”: "2015-03-13T15:10:07+0200",
“expiryDate”: "2018-03-12T23:59:59+0200",
“campaignName”: "VSPTestGiftCardCampaign",
“campaignType”: "GIFTCARD",
“description”: "Gift Card worth R20.00",
“imageURL”: "http://goo.gl/Zodst9",
“termsAndCondition: "VSP T&Cs",
“stateId”: "A",
“wicode”: "123456789999"
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
Issuing a Gift card is a simple API call. Three parameters must be supplied: campaignID, balance and userRef. Each time this API is called a Gift card is issued against the userRef and the campaignID. If issueWicode is set to true, a wiCode will be issued for the gift card right away. If not, a wiCode can be issued using the issueGiftCardWicode API call.
A Gift Card can be ISSUED in a De-Activated State, then activated later via the portal or API call.
Endpoint: {root}/giftcards
Available methods: POST
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
issueWiCode | Boolean (query) | True if to issue wicode, otherwise false. | ✓ | |
campaignId | Integer | The id of the campaign to issue against. | ✓ | ✓ |
balance | Integer | The amount to issue on giftcard. The balance needs to be within the min and max boundaries of the campaign and the campaign must have the required float available. | ✓ | ✓ |
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
mobileNumber | String | The mobile number. The mobile number must be presented in International format. | ✓ | ✓ |
smsMessage | String | The message to override original sms message with. Used in request only. The following hash-tag's can be used: #WICODE (The wiCode), #MOBISITE (Will add a link to a generic mobisite for QR display.), #BALANCE (The value in Rand.) and #EXPIRY (Expiry date yyyy/mm/dd). | ✓ | |
sendSMS | Boolean | Indicates whether an SMS must be sent on issue or not. | ✓ | ✓ |
sendFollowUpSMS | Boolean | Indicates whether a follow-up SMS must be sent if the user partially redeems their gift card. | ✓ | ✓ |
numExpiryDays | Integer | If allowed by campaign the channel can override the default expiry days. It will still be capped by the default campaign value. | ✓ | |
id | Integer | The id of the gift card. | ✓ | |
interfaceIssuerId | Integer | The interface issuer id. | ✓ | |
issuerId | Integer | The issuer id. | ✓ | |
issuedAmount | Integer | The issued amount. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the giftcard. | ✓ | |
expiredAmount | Integer | The amount expired on the giftcard. | ✓ | |
createDate | String | The create date of the giftcard. | ✓ | |
expiredDate | String | The on which the gift card expired. | ✓ | |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | |
description | String | A description of the campaign. | ✓ | |
imageUrl | String | The image url of the gift card. | ✓ | |
termsAndConditions | String | The terms and conditions of the gift card. | ✓ | |
stateId | String | The current state of the giftcard. You can issue a Gift Card in a de-activated state if you set the stateId to "D" in the Request.
|
✓ | ✓ |
Issue a wiCode / Token for a Gift Card
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcards/{id}/wicode" \
-H "id: {id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
# Example response
{
"token": {
"userRef": "string",
"wiCode": "123456789999",
"createDate": "2016-07-06T12:05:10+0200",
"validTillDate": "2019-07-06T23:59:59+0200",
"lastModifiedDate": "2016-07-06T12:05:10+0200",
"stateId": "A"
},
"responseCode": "-1",
"responseDesc": "Success"
}
This resource is used to issue a wicode against giftcard for length of giftcard expiry. A wicode will only be issued if no wicode is linked to giftcard.
Endpoint: {root}/giftcards/{id}/wicode
Available methods: POST
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | |
wiCode | String | The wiCode. | ✓ | |
createDate | String | The create date. | ✓ | |
validTillDate | String | The date the wicode is valid to. | ✓ | |
lastModifiedDate | String | The last modified date. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ |
Query Gift Card details
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcards/{id}" \
-H "id: {id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcard“: {
“id“: 615,
“campaignId“: 4455,
“interfaceIssuerId“: "SnapAndSaveIssuer",
“issuerId“: 146,
“userRef“: "string",
“mobileNumber“: "string",
“issuedAmount“: 500,
“redeemedAmount“: 500,
“expiredAmount“: 0,
“balance“: 0,
“createDate“: "2015-05-25T11:41:51+0200",
“expiryDate“: "2015-05-25T23:59:59+0200",
“campaignName“: "Snap and Save Gift Card",
“campaignType“: "GIFTCARD",
“description“: "Snap and Save Gift Card",
“termsAndConditions“: "Snap and Save Gift Card",
“stateId“: "R",
"wicode": "1234567"
},
“responseCode": "-1",
“responseDesc": "Success"
}
This call can be used to retrieve (get) a Yoyo Gift Card. The giftcard id is specified as a header parameter in this case.
Endpoint: {root}/giftcards/{id}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the gift card. | ✓ | ✓ |
campaignId | Integer | The id of the campaign to issue against. | ✓ | |
interfaceIssuerId | Integer | The interface issuer id. | ✓ | |
issuerId | Integer | The issuer id. | ✓ | |
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | |
mobileNumber | String | The users mobile number, if available. | ✓ | |
issuedAmount | Integer | The issued amount. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the giftcard. | ✓ | |
expiredAmount | Integer | The amount expired on the giftcard. | ✓ | |
balance | Integer | The amount to issue on giftcard. The balance needs to be within the min and max boundaries of the campaign and the campaign must have the required float available. | ✓ | |
createDate | String | The create date of the giftcard. | ✓ | |
expiredDate | String | The on which the gift card expired. | ✓ | |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | |
description | String | A description of the campaign. | ✓ | |
imageUrl | String | The image url of the gift card. | ✓ | |
termsAndConditions | String | The terms and conditions of the gift card. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ |
Expire a Gift Card
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcards/{id}" \
-H "id: {id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X DELETE
# Example response
{
“responseCode”: "-1",
“responseDesc”: "Success"
}
This call can be used to expire (delete) a Gift Card. The giftcard id is specified as a header parameter in this case.
Endpoint: {root}/giftcards/{id}
Available methods: DELETE
Update Gift Card mobile number
This call can be used to update the mobile number assigned to a Gift Card. The giftcard id is specified as a path parameter in this case.
Endpoint: {root}/giftcards/{id}/mobilenumber
Available methods: PUT
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The id of the gift card. | ✓ | |
mobileNumber | String | New mobile number. | ✓ |
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcards/{id}/mobilenumber" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'apiId: {apiId}' \
-H 'apiPassword: {apiPassword}' \
-X PUT
-d '{
"mobileNumber": "{mobileNumber}"
}'
# Example response
{
"responseCode": "-1",
"responseDesc": "Success",
"httpStatusCode": 200
}
Giftcard Transactions
GET /giftcardtransactions
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcardtransactions" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcardTransactions“: [ {
“id“: 123499,
“transactionId“: 101694,
“giftcardId“: 183980,
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "YourRetailer",
“processedAmount“: 2500,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "AAIssuer",
“issuerId“: 128,
“stateId“: "S"
}],
“paging“:
{
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This endpoint can be used to retrieve all giftcard related transactions. If no filters are specified it will return all giftcard transactions ordered by date.
Endpoint: {root}/giftcardtransactions
All request parameters, except the API credentials, are query parameters.
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
transactionId | Integer | The top level transaction id. All transactions are linked to a high level transaction. The high level transaction groups multiple giftcard transactions as well as gift card transactions. | ✓ | ✓ |
userRef | String | If the user reference is specified on transactions linked to the user will be returned. | ✓ | ✓ |
giftcardId | Integer | To filter on specific giftcard Id. | ✓ | ✓ |
campaignId | Integer | Filter transactions for specific campaign. | ✓ | ✓ |
dateFrom | String | The date from which to return transactions. | ✓ | |
dateTo | String | The date to which to return transactions. | ✓ | |
id | Integer | The giftcard transaction id. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The processed amount. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | String | The id of the interface issuer. | ✓ | |
issuerId | String | The id of the issuer. | ✓ | |
stateId | Integer | The current transaction state.
|
✓ |
GET /giftcardtransactions/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/giftcardtransactions/{id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcardTransactions“: [ {
“id“: 123499,
“transactionId“: 101694,
“giftcardId“: 183980,
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "YourRetailer",
“processedAmount“: 2500,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "AAIssuer",
“issuerId“: 128,
“stateId“: "S"
}],
“paging“:
{
“pageSize“: 20,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode“: "-1",
“responseDesc“: "Success"
}
This resource returns a specific the giftcard transaction.
Endpoint: {root}/giftcardtransactions/{id}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The top level transaction id. All transactions are linked to a high level transaction. The high level transaction groups multiple giftcard transactions as well as gift card transactions. | ✓ | ✓ |
userRef | String | If the user reference is specified on transactions linked to the user will be returned. | ✓ | |
giftcardId | Integer | To filter on specific giftcard Id. | ✓ | |
campaignId | Integer | Filter transactions for specific campaign. | ✓ | |
dateFrom | String | The date from which to return transactions. | ✓ | |
dateTo | String | The date to which to return transactions. | ✓ | |
id | Integer | The giftcard transaction id. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The processed amount. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | String | The id of the interface issuer. | ✓ | |
issuerId | String | The id of the issuer. | ✓ | |
stateId | Integer | The current transaction state.
|
✓ |
Physical Giftcards
A customer can purchase and redeem a physical Giftcard in a brick & mortar store. The integration will facilitate the activation and redemption of gift cards through the POS integration using specified APIs.
PAN Generation
- Process: YOYO will generate a 16-digit (PAN) and configure against the relevant campaign.
- Usage: The PAN number will serve as the wicode during transaction time.
- NB* - Physical Card Printing: To be confirmed if the PAN will be printed on the physical card or converted to a scannable QR code for input by the cashier.
Customer Journey
- User visits store where physical gift card is available for purchase
- Store displays gift cards near the checkout counter, or a dedicated gift card display area
- User wants to purchase a gift card and asks for specific denomination of value (based on their budget)
- Cashier scans the selected physical gift card or manually enters the gift card’s unique code (PAN) into the store’s point-of-sale (POS) system
- The POS system should then communicate with Yoyo to validate the gift card’s authenticity and the fact that it hasn’t been used
- If the gift card is valid and hasn’t been used previously, the POS system then loads the requested value onto the physical gift card
- The user then pays for the gift card’s value either in cash, by card or another payment method
- The POS system then generates a receipt for the gift card purchase, indicating the load value, PAN and any terms and conditions
- The physical gift card is now activated and ready for use
- The store cashier hands over the physical gift card and the receipt to the user
- The receipt should include any relevant redemption instructions, such as where users can check their gift card balance, and when the gift card will expire
- The user should be able to use the physical gift card at any affiliated retail location, online store or configured partner merchant
Giftcard Activation Process
- POS Requirement: The POS checks the validity of the PAN by means of the following APIs.
- PAN Utilization: The token.id in the API request must be set as the gift card PAN number inputted from POS.
- Token Info Request to validate the PAN: Point of Sale - token info request
Request
{
"token":{
"id":"8200000153333333",
"type":"wicode"
},
"storeTrxDetails":{
"storeId": 123268,
"basketId": "test",
"trxId": "123",
"posId": "test",
"cashierId": "test"
}
}
Token Info response
{
"vsp": {
"id": 20016,
"name": "Yoyo wiCoupon",
"balances": {
"balance": [
{
"name": "Instore giftcard test",
"type": "CENT",
"value": 5000
}
]
},
"hasVoucher": false,
"hasCoupon": false,
"hasWallet": true,
"hasGiftCard": false
},
"responseCode": "-1",
"responseDesc": "Success"
}
After successful validation. The transaction API of type DEPOSIT will be used to load funds onto the gift card. Transaction API Documentation referenced here - Transaction request
POST : https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/transaction
Request:
{
"type": "DEPOSIT",
"totalAmount": 5000,
"basketAmount": 5000,
"cashbackAmount": 0,
"tipAmount": 0,
"billAmount": 5000,
"token": {
"id": "8200000153333333",
"type": "WICODE"
},
"storeTrxDetails": {
"storeId": "12345",
"basketId": "test2",
"trxId": "test2",
"posId": "test2",
"cashierId": "test2"
}
Response:
{
"token": {
"id": "8200000153333333",
"type": "BIN"
},
"type": "DEPOSIT",
"storeTrxDetails": {
"storeId": 123268,
"retailerId": 70000858,
"basketId": "test2",
"trxId": "test2",
"posId": "test2",
"cashierId": "test2"
},
"wiTrxId": 478094,
"totalAmountProcessed": 5000,
"basketAmountProcessed": 5000,
"cashbackAmountProcessed": 0,
"tipAmountProcessed": 0,
"amountToSettle": 5000,
"billAmount": 5000,
"vsp": {
"id": 20016,
"name": "Yoyo wiCoupon",
"trxId": "500",
"responseCode": "-1",
"responseDesc": "Success"
},
"discount": [],
"loyalty": [],
"balance": [],
"redemptions": [
{
"description": "DEPOSIT",
"processedAmount": 5000,
"settleAmount": 5000,
"type": "WALLET",
"vspId": 20016,
"wiVspTrxId": 707442
}
],
"responseCode": "-1",
"responseDesc": "Success"
}
After a successful DEPOSIT transaction response with the response of the below fields:
"responseCode": "-1",
"responseDesc": "Success"
The POS must initiate the transaction finalization process by initiating the advice API call To finalize the transaction and activate the Giftcard for the customer to use for redemption.
The advice request and response are as follows.
Advice API documentation can be found here: Transaction advise request
POST : https://rad2.wigroup.co:8181/wigroup-transactionengine/pos-providers/advise
Request:
{
"action": "FINALISE",
"originalTrx": {
"storeTrxDetails": {
"storeId": "12345",
"basketId": "test2",
"trxId": "test2",
"posId": "test2",
"cashierId": "test2"
}
"wiTrxId": 478094,
"type": "DEPOSIT"
}
}
Response:
{
"originalTrx": {
"storeTrxDetails": {
"storeId": 123268,
"basketId": "test2",
"trxId": "test2",
"posId": "test2",
"cashierId": "test2"
},
"wiTrxId": 478094,
"type": "DEPOSIT"
},
"action": "FINALISE",
"wiTrxId": 478094, // wiTrxId retrieved from the transaction response
"responseCode": "-1",
"responseDesc": "Success"
}
Once the transaction has been finalized, the gift card is now activated for redemption. The redemption process must follow the current integrated redemption process. The PAN number must be utilized as the as the wicode during the redemption process.
Transaction Scenarios:
Basket Modifications: If any changes are made to the basket after the transaction request (items added or removed), the POS must send a REVERSE type of advice call, and the payment or redemption process must start again.
Abandoned Transactions: If the transaction is abandoned, the POS must reverse the transaction.
Partial Payment: During redemption, If the gift card covers the basket amount partially, the customer must pay the remaining balance using an alternate payment method. After successful alternate payment, the finalize advice API must be initiated to conclude the transaction.
API References.
Info request: Point of Sale - token info request
Transaction request: Transaction request
Advice request: Transaction advise request
Error Response Codes
Every response contains responseCode and responseDesc fields. These indicate whether the request was successful or failed. The only successful is denoted by a value of -1. All other response codes indicate failed requests. The table below denotes all possible response codes.
Response Code | Response Description | Notes |
---|---|---|
-1 | Successful | |
2313 | Invalid wiCode. | Deactivated Giftcard |
2314 | Invalid wiCode. | Expired Giftcard |
Campaigns
GET /campaigns/{campaignId}/metadata
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/campaigns/{campaignId}/metadata" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
"campaignsMetadata": [
{
"name": "Kauai",
"value": "Smoothie"
},
{
"name": "Kauai",
"value": "Food"
}],
"paging": {
"pageSize": 20,
"pageOffset": 0,
"numItemsOnPage": 2,
"numItemsInTotal": 2,
"numPages": 1
},
"responseCode": "-1",
"responseDesc": "Success",
"httpStatusCode": 200
}
This API call can be used to retrieve all metadata entries linked to the given campaign.
Meta-data is additional information stored against the campaign by the Campaign Owner. This is configured during campaign setup. Typical use cases would be to store an external system campaign identifier or to store additional tags against the campaign to help the application group campaigns.
Endpoint: {root}/campaigns
Available Methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
campaignId | Integer | Filter metadata for specific campaign. | ✓ | |
name | String | The name of the key value pair. | ✓ | |
value | String | The value of the key value pair. | ✓ |
Users
POST /user/{userRef}/token
Case 1 -- Single Gift Card and Two Vouchers:
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/user/{userRef}/token" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
-d '{
“giftcardIds”: [“20”],
“couponIds”: [“55”, “56”],
“campaignType”: “VOUCHER”,
"mobileNumber": "string"
}'
# Example response
{
token: {
“userRef”: "VSP_User_Id_001",
“mobileNumber”: "string",
“campaignType”: "VOUCHER",
“wiCode”: "1122345",
“wiQR”: "1122345",
“couponIds”:
[
55,
56
],
“giftcardIds”:
[
20
],
“createDate”: "2015-03-13T14:22:52+0200",
“validTillDate”: "2015-03-14T23:59:59+0200",
“lastModifiedDate”: "2015-03-13T14:27:08+0200",
“stateId”: "A"
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
Case 2 -- Set of Gift Cards, a Two Coupons and a Voucher:
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/user/{userRef}/token" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
-d '{
“giftcardIds”: [“20”, “21”, “22”],
“couponIds”: [“101”, “102”, “55”],
“campaignType”: “COUPONVOUCHER”,
"mobileNumber": "string"
}'
# Example response
{
token: {
“userRef”: "VSP_User_Id_001",
“mobileNumber”: "string"
“campaignType”: "COUPONVOUCHER",
“wiCode”: "6786789",
“wiQR”: "6786789",
“couponIds”:
[
55,
101,
102
],
“giftcardIds”:
[
20,
21,
22
],
“createDate”: "2015-03-13T14:22:52+0200",
“validTillDate”: "2015-03-14T23:59:59+0200",
“lastModifiedDate”: "2015-03-13T14:27:08+0200",
“stateId”: "A"
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
Case 3 -- Coupon (all Coupons across any campaigns available to the userRef):
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/user/{userRef}/token" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
-d '{
“couponCampaignIds”: [“-1”],
“campaignType”: “COUPON”,
"mobileNumber": "string"
}'
# Example response
{
token: {
“userRef”: "VSP_User_Id_001",
“mobileNumber”: "string"
“campaignType”: "COUPON",
“wiCode”: "3334567",
“wiQR”: "3335678",
“couponCampaignIds”:
[
-1
],
“createDate”: "2015-03-13T14:22:52+0200",
“validTillDate”: "2015-03-14T23:59:59+0200",
“lastModifiedDate”: "2015-03-13T14:27:08+0200",
“stateId”: "A"
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
To redeem coupons or giftcards not issued with their own wiCode a user token must be created. This token specifies what must be considered on redemption. The token will be valid for up to 48 hours (today and tomorrow). A token can only be used for one transaction. The data linked to the token can be changed at any stage by recreating the token. To create the token you need to specify what to redeem. There are three lists which define what to redeem (couponCampaignIds, couponIds, giftcardIds), at least one must be specified. During redemption the system will first redeem against the couponCampaignIds list, then the couponIds, and finally the giftcardIds list. This is so that discounts are redeemed first, then vouchers/coupons issued to the user and then finally it will deduct the remaining value from the giftcards. If the list is not specified the redemption step for that list will be skipped. If you want to redeem against anything in that list rather than specify specific Ids, you can specify the wildcard [‑1] as the only value in the list. If you want to limit the list, you must specify the specific ids to take into account.
The primary function of setUserToken is to reserve a Token against a specific user. Its secondary function is to associate the Token with a CVS item, i.e. Gift Card or Coupon. Depending on the body parameters provided, setUserToken allows a great deal of flexibility in the way discounts are redeemed. This adds internal complexity to CVS, but simplifies the redemption process for client applications.
It is assumed that when a user registers on the VSP they are assigned a unique identifier, e.g. “VSP_User_001”, this identifier should be sent across by the VSP application servers to CVS as the userRef parameter. When the setUserToken call is made a Token is issued against this userRef.
When a User Token is created the IDs must be specified of the Coupons, Vouchers and Gift Cards that is required to be processed. The Campaign IDs may alternatively also be specified. A single ID may be specified or multiple IDs may be provided in the form of an array consisting of the IDs in String format. In the case where all issued Coupons, Vouchers or Gift Cards are issued against the user must be redeemed, [“-1”], should be presented in the JSON body of the request.
Furthermore, a Campaign Type has to be provided, which must be either: “COUPON”, “VOUCHER” or “COUPONVOUCHER”. The Campaign Type COUPONVOUCHER captures both Coupons and Vouchers issued against the user. The Campaign Type will have no effect on the redemption of issued Gift Cards – it will only have an impact on Coupons and Vouchers.
Endpoint: {root}/users/{userRef}/token
Available methods: POST
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
mobileNumber | String | The mobile number. The mobile number must be presented in International format. | ✓ | ✓ |
couponCampaignIds | Array[String], null if none, ["-1"] if all campaigns | The list of coupon campaign id's which during redemption phase will be issued to the user and redeemed. | ✓ | ✓ |
couponIds | Array[String], null if none, ["-1"] if all campaigns | The list of coupon id's already issued to the user to redeem if possible. | ✓ | ✓ |
giftcardIds | Array[String], null if none, ["-1"] if all campaigns | The list of giftcard id's already issued to the user to redeem if possible. | ✓ | ✓ |
campaignType | String | The campaign type issued against for couponCampaignIds list or couponIds list.
|
✓ | ✓ |
wiCode | String | The wiCode linked to the user token. | ✓ | |
wiQR | String | The wiCode linked to the user token. | ✓ | |
createDate | String | The date token was created. | ✓ | |
validTillDate | String | The date the wiCode will be valid to. | ✓ | |
lastModifiedDate | String | The date last modified. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the coupon. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ |
GET /user/{userRef}/token
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/user/{userRef}/token" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
token: {
“userRef”: "VSP_User_Id_001",
"mobileNumber": "string",
“campaignType”: "VOUCHER",
“wiCode”: "1122345",
“wiQR”: "1122345",
“couponIds”:
[
55,
56
],
“giftcardIds”:
[
20
],
“createDate”: "2015-03-13T14:22:52+0200",
“validTillDate”: "2015-03-14T23:59:59+0200",
“lastModifiedDate”: "2015-03-13T14:27:08+0200",
“stateId”: "A"
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
A token can also be retrieved.
Endpoint: {root}/users/{userRef}/token
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
mobileNumber | String | The users mobile number, if available. | ✓ | |
couponCampaignIds | Array[String], null if none, ["-1"] if all campaigns | The list of coupon campaign id's which during redemption phase will be issued to the user and redeemed. | ✓ | |
couponIds | Array[String], null if none, ["-1"] if all campaigns | The list of coupon id's already issued to the user to redeem if possible. | ✓ | |
giftcardIds | Array[String], null if none, ["-1"] if all campaigns | The list of giftcard id's already issued to the user to redeem if possible. | ✓ | |
campaignType | String | The campaign type.
|
✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
wiQR | String | The wiCode linked to the user token. | ✓ | |
createDate | String | The date token was created. | ✓ | |
validTillDate | String | The date the wiCode will be valid to. | ✓ | |
lastModifiedDate | String | The date last modified. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the coupon. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ |
DELETE /user/{userRef}/token
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/user/{userRef}/token" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X DELETE
# Example response
{
“responseCode”: "-1",
“responseDesc”: "Success"
}
A token can also be expired for safety should the user no longer want to transact.
Endpoint: {root}/users/{userRef}/token
Available methods: DELETE
GET /users/{userRef}/transactions
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/users/{userRef}/transactions" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“transactions”: {[
“id“: 101694,
“wiCode“: "528626479",
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "Yoyo Retailer",
“processedAmount“: 2500,
“numberOfCoupons“: 1,
“numberOfGiftcards“: 0,
“totalCouponProcessedAmount“: 2500,
“totalGiftcardProcessedAmount“: 0,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "VSPIssuer",
“issuerId“: 128,
“stateId“: "S"
}]
,
“paging“: {
“pageSize“: 10,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
This resource denotes the top level transactions for a specific user. It will indicate how many coupon and giftcard transactions was processed on the transaction.
Endpoint: {root}/users/{userRef}/transactions
Available methods: GET
All request parameters, except the API credentials, are query parameters.
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | The user reference to filter on. | ✓ | ✓ |
wiCode | String | To filter transaction on specific wiCode. | ✓ | ✓ |
dateFrom | String | The date from which to return transactions. | ✓ | |
dateTo | String | The date to which to return transactions. | ✓ | |
id | Integer | The transaction id. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The total processed amount for all linked coupon and giftcard transactions. | ✓ | |
numberOfCoupons | Integer | The number of coupons redeemed on transaction. | ✓ | |
numberOfGiftcards | Integer | The number of giftcards redeemed on transaction. | ✓ | |
totalCouponProcessedAmount | Integer | The total processed amount from coupon redemptions. | ✓ | |
totalGiftcardProcessedAmount | Integer | The total processed amount from giftcard redemptions. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | Integer | The transaction id. | ✓ | |
issuerId | Integer | The id of the issuer. | ✓ | |
stateId | String | The current transaction state.
|
✓ |
GET /users/{userRef}/coupons
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/users/{userRef}/coupons" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“coupon“: [ {
“id“: 171117,
“userRef“: “VSP_User_Id_001“,
“campaignId“: 4449,
“campaignName“: "Integration Coupon R5",
“campaignType“: "COUPON",
“termsAndConditions“: "Integration Coupon R5",
“createDate“: "2015-05-21T09:11:32+0200",
“description“: "Integration Coupon R5",
“imageURL”: "http://goo.gl/Zodst9",
“redeemFromDate“: "2015-05-21T00:00:00+0200",
“redeemToDate“: "2015-11-21T23:59:59+0200",
“redeemFromTime”: "00:00",
“redeemToTime”: "00:00",
“isRedeemableOnSundays”: boolean,
“isRedeemableOnMondays”: boolean,
“isRedeemableOnTuesdays”: boolean,
“isRedeemableOnWednesdays”: boolean,
“isRedeemableOnThursdays”: boolean,
“isRedeemableOnFridays”: boolean,
“isRedeemableOnSaturdays”: boolean,
“wiCode“: "902430319",
“voucherAmount“: 500,
“stateId“: "E",
“expiredDate“: "2015-05-21T09:13:17+0200"
}],
“responseCode": "-1",
“responseDesc“: "Success"
}
This resource can be used to retrieve a list of coupons linked to a specific user.
Endpoint: {root}/users/{userRef}/coupons
Available methods: GET
All request parameters, except the API credentials, are query parameters.
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The transaction id. | ✓ | |
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
campaignId | Integer | The id of the campaign to issue against. | ✓ | ✓ |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | ✓ |
termsAndConditions | String | The terms and conditions of the coupon. | ✓ | |
createDate | String | The date the couponCampaign was created. | ✓ | |
description | String | A description of the campaign. | ✓ | |
imageUrl | String | The image url of the gift card. | ✓ | |
redeemFromDate | String | From which date the coupon can be redeemed. | ✓ | |
redeemToDate | String | Until when the coupon is redeemable. | ✓ | |
redeemFromTime | String | The time from which the gift card can be redeemed. | ✓ | |
redeemToTime | String | The time on which the gift card can be redeemed to. | ✓ | |
isRedeemableOnSundays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnMondays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnTuesdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnWednesdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnThursdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnFridays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnSaturdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
wiCode | String | The wiCode linked to the user token. | ✓ | |
voucherAmount | Integer | The possible coupon redemption amount. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ | ✓ |
expiredDate | String | The date on which the gift card expired. | ✓ |
GET /users/{userRef}/giftcards
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/users/{userRef}/giftcards" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
“giftcard”: {
“id”: 20,
“campaignId”: 9000,
“userRef”: "VSP_User_Id_001",
"mobileNumber": "string",
“issuedAmount”: 2000,
“redeemedAmount”: 0,
“expiredAmount”: 0,
“balance”: 2000,
“createDate”: "2015-03-13T15:10:07+0200",
“expiryDate”: "2018-03-12T23:59:59+0200",
“campaignName”: "VSPTestGiftCardCampaign",
“campaignType”: "GIFTCARD",
“description”: "Gift Card worth R20.00",
“termsAndCondition: "VSP T&Cs",
“stateId”: "A",
“wicode”: "112233445566",
“redeemFromTime”: "00:00",
“redeemToTime”: "00:00",
“isRedeemableOnSundays”: boolean,
“isRedeemableOnMondays”: boolean,
“isRedeemableOnTuesdays”: boolean,
“isRedeemableOnWednesdays”: boolean,
“isRedeemableOnThursdays”: boolean,
“isRedeemableOnFridays”: boolean,
“isRedeemableOnSaturdays”: boolean
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
This resource can be used to retrieve a list of giftcards linked to a specific user.
Endpoint: {root}/users/{userRef}/giftcards
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
campaignId | Integer | The id of the campaign to issue against. | ✓ | ✓ |
mobileNumber | String | The mobile number. The mobile number must be presented in International format. | ✓ | |
id | Integer | The id of the gift card. | ✓ | |
campaignId | Integer | The id of the campaign to issue against. | ✓ | |
issuedAmount | Integer | The issued amount. | ✓ | |
redeemedAmount | Integer | The amount redeemed on the giftcard. | ✓ | |
expiredAmount | Integer | The amount expired on the giftcard. | ✓ | |
balance | Integer | The amount to issue on giftcard. The balance needs to be within the min and max boundaries of the campaign and the campaign must have the required float available. | ✓ | |
createDate | String | The create date of the giftcard. | ✓ | |
expiryDate | String | The date on which the gift card expire. | ✓ | |
expiredDate | String | The date on which the gift card expired. | ✓ | |
campaignName | String | The name of the campaign. | ✓ | |
campaignType | String | The type of campaign.
|
✓ | |
description | String | A description of the campaign. | ✓ | |
termsAndConditions | String | The terms and conditions of the coupon. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ | ✓ |
wicode | String | The wiCode linked to the user token.. | ✓ | |
redeemFromTime | String | The time from which the gift card can be redeemed. | ✓ | |
redeemToTime | String | The time on which the gift card can be redeemed to. | ✓ | |
isRedeemableOnSundays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnMondays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnTuesdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnWednesdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnThursdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnFridays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ | |
isRedeemableOnSaturdays | Boolean | Indicates if the giftcard is redeemable on day speicfied. | ✓ |
GET /users/{userRef}/pans
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/users/{userRef}/pans" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
"responseCode": "string",
"responseDesc": "string",
"userGroupPan": {
"pan": "string",
"userRef": "string",
"interfaceIssuerGroupId": "string",
"interfaceIssuerId": "string",
"createDate": "2016-07-06T07:53:18.628Z",
"lastModifiedDate": "2016-07-06T07:53:18.628Z",
"interfaceGroupId": "string"
}
}
Get user pan.
Endpoint: {root}/users/{userRef}/pans
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | A unique user reference as on the issuer channel system. This reference will be used to restrict user limits on campaigns. | ✓ | ✓ |
pan | String | The pan. | ✓ | |
interfaceIssuerGroupId | String | The id of the interface issuer group. | ✓ | |
createDate | String | The create date of the pan. | ✓ | |
lastModifiedDate | String | The last modified date. | ✓ |
Retailers
GET /retailers
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/retailers" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
retailers: [ {
“createDate“: "2013-03-19T07:34:02+0200",
“id“: 1050,
“name“: "Test Retailer",
“description“: "The best tester",
“logoURL“: "www.testurl.com/image.png"
}],
“responseCode“: "-1",
“responseDesc“: "Success"
}
Returns a list of the retailers linked to active campaigns on the channel.
Endpoint: {root}/retailers
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
campaignId | Integer (query) | If specified it will return a list of retailers linked to the campaign. | ✓ | |
createDate | String | The date the retailer was created. | ✓ | |
id | Integer | The id of the retailer. | ✓ | |
name | String | The name of the retailer. | ✓ | |
description | String | A description of the retailer. | ✓ | |
logoURL | String | The retailer logo URL. | ✓ |
Merchants
GET /merchants
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/merchants" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X GET
# Example response
{
merchants: [ {
“createDate“: "2013-03-19T07:34:02+0200",
“id“: 1050,
“name“: "Test Merchant",
“provinceDesc“: "Eastern Cape",
“provinceId“: 1,
“stateId“: "A",
“retailerId“: 10,
“retailerName“: "Yoyo Retailer",
“latitude“: -33.932308,
“longitude“: 18.467464,
“distance“: 0
}
}],
“hasNextPage“: false,
“numOfPages“: 1,
“numItemsOnPage“: 2,
“numItemsInTotal“: 2,
“order“: {},
“pageSize“: 20,
“pageOffset“: 0,
“responseCode“: "-1",
“responseDesc“: "Success"
}
This resource denotes the collection of all merchants linked to active campaigns on the channel.
Endpoint: {root}/merchants
Available Methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
campaignId | Integer | Filter transactions for specific campaign. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | ✓ |
id | Integer | The id of the merchant. | ✓ | |
name | String | The name of the merchant. | ✓ | |
provinceDesc | String | Description of the merchant province. | ✓ | |
provinceId | Integer | The id of the merchant province. | ✓ | |
stateId | String | The current state of the giftcard.
|
✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
longitude | Double | A longitude position. Both longitude and latitude need to be specified together. | ✓ | |
latitude | Double | A latitude position. Both longitude and latitude need to be specified together. | ✓ | |
distance | Double | The distance to the closest merchant. | ✓ |
Transactions
Coupon, voucher and gift card transactions may be queried.
GET /transactions
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/transactions" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
# Example response
{
“transactions”: {[
“id“: 101694,
“wiCode“: "528626479",
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "Yoyo Retailer",
“processedAmount“: 2500,
“numberOfCoupons“: 1,
“numberOfGiftcards“: 0,
“totalCouponProcessedAmount“: 2500,
“totalGiftcardProcessedAmount“: 0,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "VSPIssuer",
“issuerId“: 128,
“stateId“: "S"
}]
,
“paging“: {
“pageSize“: 10,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
This resource denotes the top level transactions. It will indicate how many coupon and giftcard transactions was processed on the transaction.
Endpoint: {root}/transactions
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
userRef | String | The user reference to filter on. | ✓ | ✓ |
wiCode | String | To filter transaction on specific wiCode. | ✓ | ✓ |
dateFrom | String | The date from which to return transactions. | ✓ | |
dateTo | String | The date to which to return transactions. | ✓ | |
id | Integer | The transaction id. | ✓ | |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The total processed amount for all linked coupon and giftcard transactions. | ✓ | |
numberOfCoupons | Integer | The number of coupons redeemed on transaction. | ✓ | |
numberOfGiftcards | Integer | The number of giftcards redeemed on transaction. | ✓ | |
totalCouponProcessedAmount | Integer | The total processed amount from coupon redemptions. | ✓ | |
totalGiftcardProcessedAmount | Integer | The total processed amount from giftcard redemptions. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | Integer | The transaction id. | ✓ | |
issuerId | Integer | The id of the issuer. | ✓ | |
stateId | String | The current transaction state.
|
✓ |
GET /transactions/{id}
# Example request
curl "https://za-vsp-int.wigroup.co/cvs-issuer/rest/transactions/{id}" \
-H "apiId: {apiId}" \
-H "apiPassword: {apiPassword}" \
-H "Content-Type: application/json" \
-X POST
# Example response
{
“transactions”: {[
“id“: 101694,
“wiCode“: "528626479",
“userRef“: "VSP_User_Id_001",
“merchantId“: 1050,
“merchantName“: "Test Merchant",
“retailerId“: 10,
“retailerName“: "Yoyo Retailer",
“processedAmount“: 2500,
“numberOfCoupons“: 1,
“numberOfGiftcards“: 0,
“totalCouponProcessedAmount“: 2500,
“totalGiftcardProcessedAmount“: 0,
“transactionDate“: "2015-07-23T14:07:24+0200",
“interfaceIssuerId“: "VSPIssuer",
“issuerId“: 128,
“stateId“: "S"
}]
,
“paging“: {
“pageSize“: 10,
“pageOffset“: 0,
“numItemsOnPage“: 1,
“numItemsInTotal“: 1,
“numPages“: 1
},
“responseCode”: "-1",
“responseDesc”: "Success"
}
This endpoint will return a specific high level transaction's details.
Endpoint: {root}/transactions/{id}
Available methods: GET
Parameter | Type | Description | Request | Response |
---|---|---|---|---|
id | Integer | The transaction id. | ✓ | |
wiCode | String | To filter transaction on specific wiCode. | ✓ | ✓ |
userRef | String | The user reference to filter on. | ✓ | ✓ |
merchantId | Integer | The merchant id. | ✓ | |
merchantName | String | The merchant name. | ✓ | |
retailerId | Integer | The retailer id. | ✓ | |
retailerName | String | The retailer name. | ✓ | |
processedAmount | Integer | The total processed amount for all linked coupon and giftcard transactions. | ✓ | |
numberOfCoupons | Integer | The number of coupons redeemed on transaction. | ✓ | |
numberOfGiftcards | Integer | The number of giftcards redeemed on transaction. | ✓ | |
totalCouponProcessedAmount | Integer | The total processed amount from coupon redemptions. | ✓ | |
totalGiftcardProcessedAmount | Integer | The total processed amount from giftcard redemptions. | ✓ | |
transactionDate | String | The transaction date. | ✓ | |
interfaceIssuerId | Integer | The transaction id. | ✓ | |
issuerId | Integer | The id of the issuer. | ✓ | |
stateId | String | The current transaction state.
|
✓ |
Giftcard Response Codes
Below is a list of Giftcard Response Codes:
Response Code | Response Description |
---|---|
-1 | Successful |
2313 | Invalid wiCode |
2314 | Invalid wiCode |
Redemption callback
The redemption callback URL provides the YoyoPlatform with a means of notifying third parties that a redemption has occurred. Whenever a transaction containing a redemption request is successfully processed by the wiCode platform, a redemption callback will be POSTed to the configured callback URL.
Redemption Callback failure
To facilitate synchronization, the YoyoPlatform has a built-in finite redemption callback retry policy. This is enables better state synchronization by minimizing the number of redemption callback failures. If, for some reason, no response is received across all redemption callback requests, a redemption fallback policy must be followed.
Webhook URL
Each redemption notification will include three key parameters: itemId, processedAmount, and totalProcessed. The itemId corresponds to the ID of the coupon, or giftcard that was redeemed. The processedAmount corresponds to the monetary value of the redemption, i.e. the value of the coupon or the value of the giftcard that was spent. totalProcessedAmount is the sum of the processed amount across all redemptions in the transaction.
The redemption callback should be built using RESTful JSON programming language.
# Example request
{
"id" : 115796,
"userRef" : "0813584314",
"basketId" : "wiPOS--2016-07-06 08:34:18",
"storeId" : 1050,
"totalProcessedAmount" : 1200,
"createDate" : "2016-07-06T10:34:20+0200",
"wiCode" : "4461707",
"interfaceIssuerId" : "your_qa_channel",
"wiTrxId" : "48711",
"redemption" : [{
"id" : 173608,
"processedAmount" : 300,
"createDate" : "2016-07-06T10:34:20+0200",
"type" : "COUPON",
"itemId" : 219086,
"campaignId" : 5943,
"wiCode" : "4461707"
}, {
"id" : 173609,
"processedAmount" : 400
"createDate" : "2016-07-06T10:34:20+0200",
"type" : "COUPON",
"itemId" : 219087,
"campaignId" : 5915,
"wiCode" : "4461707"
}, {
"id" : 173610,
"processedAmount" : 500,
"createDate" : "2016-07-06T10:34:20+0200",
"type" : "COUPON",
"itemId" : 219088,
"campaignId" : 5905,
"wiCode" : "4461707"
}
]
}
# Example response
HTTP 200 (OK)
Endpoint: {your_webhook_url}/
Parameter | Type | Description |
---|---|---|
id | Integer | Unique identifier of the redemption callback. |
userRef | String | Unique identifier of the user (against which the Gift Card is issued). |
basketId | String | Unique identifier of the basket. |
storeId | Integer | Unique identifier of a store. Once-off provided by Yoyo. |
totalProcessedAmount | Integer | Sum of the processedAmount across each redemption. |
createDate | String | The date on which the transaction was created. |
wiCode | String | Number of digits for the desired wiCode. |
wiTrxId | String | Unique Transaction Identifier for wiCode platform. |
interfaceIssuerId | String | The channel which issued the wiCode for redemption. |
Redemption object
Parameter | Type | Description |
---|---|---|
id | Integer | Unique identifier of the redemption. |
processedAmount | Integer | Value of the redemption. |
createDate | String | The date of redemption of the item. |
type | String | COUPON, VOUCHER or GIFTCARD. |
itemId | Integer | Unique identifier of the item. E.g. Gift Card Id. |
campaignId | Integer | Campaign against which the item was issued. |
Issuer Response Codes
Every response contains responseCode and responseDesc fields. These indicate whether the request was successful or failed. The only successful is denoted by a value of -1. All other response codes indicate failed requests. The table below denotes all possible response codes.
Response Code | Response Description |
---|---|
-1 | Successful |
0000 | NOT YET IMPLEMENTED. |
0001 | General System Error. |
0002 | General System Error. System configuration. |
0003 | General Database Error. |
0004 | We are currently experiencing high traffic load and can therefore not currently service your request. |
0005 | Invalid wiCode generated. |
0006 | General System Error. |
0007 | Failed to send email. |
0008 | Could not process your request. We are experiencing connection problems to external service providers. |
0009 | The API call has been deprecated. |
0010 | The wiCode could not be issued. The expiry date is too far in the future for channel configuration. |
1000 | Interface Authentication Failed. Account does not exist. |
1001 | Interface Authentication Failed. Invalid password. |
1002 | Interface Authentication Failed. Interface account not activated. |
1003 | Interface Authentication Failed. Issuer account not activated. |
1004 | Issuer Webuser Authentication Failed. Account does not exist. |
1005 | Issuer Webuser Authentication Failed. Invalid password. |
1006 | Issuer Webuser Authentication Failed. Issuer webuser not activated. |
1007 | Issuer Webuser Authentication Failed. Issuer webuser not linked to interface issuer. |
1008 | Interface Authentication Failed. Credentials missing. |
1200 | Campaign does not exist. |
1201 | Campaign is not active. |
1202 | Campaign not yet active for issuing vouchers. |
1203 | Campaign issuing window closed. No more vouchers can be issued. |
1204 | Campaign has reached its max available. |
1205 | The campaign requires an user id to issue voucher to. |
1206 | Campaign not linked to channel. |
1207 | Campaign not linked to channel. |
1208 | No more coupons available. |
1209 | User has reached the maximum allowed live coupons per user on campaign. |
1210 | User has reached the maximum allowed coupons per user on campaign. |
1211 | Campaign is open to selected users only. |
1212 | There is no SMS account linked. Cannot issue SMS voucher. |
1213 | No more coupons available for today. |
1214 | This is not a coupon campaign. |
1215 | Transaction coupon does not exist. |
1216 | Coupon does not exist. |
1217 | Users are not restricted against the campaign. |
1218 | Invalid campaign type. Use the correct associated campaign api call. |
1219 | The length of the SMS message is more than 160 characters. |
1250 | Invalid voucher phase specified. Must be LIVE, REDEEMED, or EXPIRED. |
1251 | Invalid campaign type specified. |
1300 | No valid wiCodes found. |
1301 | Could not link voucher infos. |
1303 | Invalid wiCode. |
1304 | No vouchers found for User. |
1305 | Invalid campaign type specified. |
1306 | Another request issued at the same time. Failing call. |
1306 | Required field missing |
1307 | Required field in voucherInfo missing |
1308 | Coupon does not exist. |
1309 | Coupon cannot be expired as it has already been redeemed. |
1310 | Coupon already expired. |
1311 | You must specify something to redeem. |
1312 | User does not have a valid token. |
1313 | User group pan record not updated. |
1314 | User group pan record not created. User already has PAN linked. |
1315 | The campaign does not allow channel to specify expiry days. |
1316 | The campaign does not allow the requested expiry days. |
1317 | The requested expiry days exceeds the campaign's redemption date. |
1318 | There is no PAN linked to the user. |
1319 | There is no wicode linked to the coupon/voucher. |
1320 | The number of expiry days must be greater or equal to zero. |
1321 | The campaign owner does not allow cash withdrawal. |
1322 | The create campaign request cannot disallow both redemption and cash withdrawals. |
1323 | The create campaign request has a campaignTypeId that is not giftcard. |
1500 | Invalid campaign phase specified. Must be CURRENT, TODAY, PENDING. |
1501 | Invalid campaign type specified. |
1550 | Latitude and Longitude values are required in order to sort by distance. |
1600 | Invalid channel group id specified. |
1601 | Channel group not linked to channel owner |
1602 | Category already exist. |
1602 | Category does not exist. |
1603 | The All category cannot be removed. |
1604 | Channel not linked to channel owner |
1605 | Invalid state of channel. |
1606 | Invalid channel id specified. |
1607 | Campaign not linked to channel. |
1608 | Campaign not linked to category. |
1609 | Invalid rank specified. |
1610 | Campaign not linked to channel group. |
1611 | Campaign not linked to Channel Owner. |
1612 | The channel name is already in use. The name must be unique on the system. |
1613 | Invalid password. |
1614 | Another group with this name already exists. |
1615 | Please provide a category name. |
1616 | The percentage limit is invalid. Value must be greater than 0 and less than 100. |
2000 | Interface Authentication Failed. Account does not exist. |
2001 | Interface Authentication Failed. Invalid password. |
2002 | Interface Authentication Failed. Interface account not activated. |
2100 | Invalid wicode |
2101 | Voucher no longer valid. Campaign has been discontinued. |
2102 | Voucher cannot not be redeem yet. Please check voucher details for validity period. |
2103 | Voucher no longer valid. Campaign is no longer running. |
2104 | Merchant not registered for coupon/voucher service. |
2105 | Merchant not currently activated for coupon/voucher service. |
2106 | Voucher cannot be redeemed at current merchant. |
2107 | Voucher cannot be redeemed at current merchant. |
2108 | The basket amount is below the minimum amount to qualify for voucher. |
2109 | The basket amount exceeds the maximum allowed amount for the voucher. |
2110 | Coupon cannot be redeemed. Required product(s) not found in basket. |
2111 | Voucher cannot be redeemed. Campaign has reached it's max redemption amount. |
2112 | Transactions with both redemptions and withdrawals are not allowed. |
2113 | Transactions with neither redemptions or withdrawals are not allowed. |
2114 | There are insufficient funds for a cash withdrawal. Requested amount greater than available funds. |
2115 | The transaction type is not allowed for the current wiCode. |
2200 | Original transaction not found. |
2201 | Transaction could not be uniquely identified. Transactional reference not unique. |
2202 | Transaction originally failed and therefore cannot be reversed. |
2203 | Transaction already previously reversed. |
2204 | Transaction is still being processed. Cannot reverse until completed original transaction. |
2205 | Transaction cannot be reversed by merchant. Must be reversed by original merchant. |
2206 | Transactional reference does not correspond to transaction. |
2207 | Processed amount is incorrect. Transaction not reversed. |
2208 | Voucher cannot be reversed as campaign no longer active. |
2209 | Transaction reversal already being processed by another instance. |
2210 | Transaction cannot be reversed. Transactions can only be reversed directly after a transaction. |
2211 | Transaction cannot be reversed. Transaction already finalised. |
2212 | Transaction could not be found. |
2213 | Transaction originally failed and therefore cannot be finalised. |
2214 | Transaction is still being processed. Cannot finalise until completed original transaction. |
2300 | No discounts available for customer basket. |
2301 | Could not retrieve wiCode info. |
2303 | Mobile Number not Registered |
5000 | Interface Authentication Failed. Account does not exist. |
5001 | Interface Authentication Failed. Invalid password. |
5002 | Interface Authentication Failed. Interface account not activated. |
5003 | User not allowed to use service. |
5100 | User Authentication Failed. Account does not exist. |
5101 | User Authentication Failed. Invalid password. |
5102 | User Authentication Failed. User account not activated. |
5201 | Campaign state not valid. |
5202 | Campaign does not exist. |
5203 | Campaign not owned by campaign owner. |
5204 | Could not link merchants. |
5205 | User does not exist. |
5206 | User state not valid. |
5207 | Could not create user. |
5208 | User already exists. |
5209 | Could not link interface issuers. |
5210 | Could not link skus. |
5211 | Could not link rules. |
5212 | Error processing redemption and sku rules. |
5213 | Sku not linked to campaign. |
5214 | Float topup exceeds campaign owner balance. |
5215 | Cant link skus since campaign already has redemption rules. |
5216 | Could not add campaign info. |
5217 | Invalid timeframe specified. |
5218 | Invalid transaction type specified. |
5219 | Invalid Amount, must be positive. |
5220 | Amount exceeds campaign owner balance. |
5225 | Interface Issuer does not exist. |
5226 | Campaign Sms does not exist. |
5227 | Invalid paging Id. |
5228 | Required campaign Sign Offs are outstanding. |
5229 | User not allowed to set campaign state to active. |
5230 | The campaign can only be signed off if the campaign is in a Pending Activation state. |
5231 | Retail sign off required. |
5232 | Campaign Owner not found. |
5233 | Campaign not linked to user. |
5234 | Campaign Owner sign off required. |
5235 | Campaign has insufficient float. |
5236 | Campaign owner has insufficient funds. |
5237 | Could not link users. |
5238 | Invalid audit trail id. Must be larger than zero. |
5239 | Invalid audit trail table. |
5240 | Cannot change merchants on a campaign with campaign owner sign off. |
5241 | You need to link a bank account to your profile to be able to receive payouts. |
5242 | Bank account credentials invalid. |
5243 | Cannot flush an active campaign. |
5244 | Amount exceeds campaign available funds. |
5245 | Cannot deduct the campaign balance below minimum required amount. |
5246 | EFT reference not found. |
5248 | Unable to retrieve the bulk issue request record from the database. |
5249 | Campaign Owner ID or EFT ref required. |
5250 | Invalid paramter Id range. |
5351 | Campaign Sms must contain at least #WICODE or #MOBISITE variable. |
5352 | Campaign type cannot be changed. |
5353 | Invalid reward type. |
5354 | Reward does not exist. |
5355 | Could not add financial liability. |
5356 | The Min basket value must be less Max basket value, unless Max is set to unlimited (0. |
5357 | CampaignId required. |
5358 | The Min giftcard range must be less or equal to the Max value, unless Max is set to unlimited (0. |
5359 | Required field missing. |
5360 | numExpiryDays must be greater than or equal to 0, where 0 equals midnight tonight. |
5361 | Giftcard does not exist. |
5362 | Giftcard has already expired. |
5363 | Giftcard has already been fully redeemed. |
5364 | Invalid Wicode Type |
5365 | Invalid Campaign Type |
5366 | Campaign Sms must contain #MOBISITE variable. |
5367 | Campaign Sms may not contain #MOBISITE variable. |
5368 | At least one rule is not linked to the specified campaign. |
5369 | Could not update rules. |
5370 | Callback URL required. |
5371 | Sms message must contain text if provided in request. |
5372 | Campaign has no stores linked to it. Must add stores before signoff. |
5373 | The campaign is non-settled. You cannot add float to the campaign. |
5374 | The campaign owner has insufficient funds to perform the flush request. |
5375 | The campaignId is a required field and has not been set. |
5376 | The flush reasonId is a required field and has not been set. |
5376 | The campaignOwnerId is a required field and has not been set. |
5377 | The campaign owner flush amount is a required field and has not been set. |
5378 | The campaign owner load amount is a required field and has not been set. |
5379 | The campaign owner flush amount is negative. |
5380 | The campaign owner load amount is negative. |
5381 | The reward float reduction + the reward value of live coupons is more than the reward float balance. |
5382 | The reward float reduction is more than the reward float balance. |
6000 | Auto campaign topup failed due to insufficient campaign owner balance. |
7001 | User authentication failed. |
7002 | User not allowed to use request. |
7003 | User Authentication Failed. Account does not exist. |
7004 | User Authentication Failed. Invalid password. |
7005 | User Authentication Failed. Account not activated. |
7006 | Only allowed to update self with this call. |
7007 | Invalid email provided. |
7008 | Invalid password length. |
7009 | Invalid user id. |
7010 | User already exists. |
7012 | Invalid profile. |
7013 | User does not exist. |
7014 | May not update this user type. |
7015 | Invalid account name. |
7016 | Invalid username. |
7017 | Invalid password. |
7018 | Invalid mobile number. |
7019 | Invalid request. User reference may not be empty. |
7020 | Invalid request. User pan may not be empty. |
7100 | This is not a giftcard campaign. |
7101 | Amount to issue exceeds available float for campaign. |
7102 | Amount to issue exceeds maximum allowable amount to issue. |
7103 | Amount to issue is less than minimum allowable amount to issue. |
7104 | The campaign requires an user id to issue giftcard to. |
7105 | No more giftcard available. |
7106 | User has reached the maximum allowed giftcards per user on campaign. |
7107 | Giftcard does not exist. |
7108 | Giftcards cannot be issued with SMS. |
7109 | The campaign does not allow channel to specify expiry days. |
7110 | The campaign does not allow the requested expiry days. |
7111 | Amount to issue invalid. |
7112 | Giftcard already has a wicode linked. |
7113 | Giftcard can't be redeemed, redemption limit reached. |
7114 | Giftcard state cannot be changed. Already in final state. |
7115 | Giftcard cannot be set to the requested state. States allowed ACTIVE (A, DEACTIVATED (D. |
8000 | The FromLastVoucherId is required and must be 0 or greater. |
8001 | The FromLastTransactionId is required and must be 0 or greater. |
8002 | The CampaignId is required and must be 1 or greater. |
8003 | The ChannelGroupId is required and must be 1 or greater. |
8004 | The CampaignTypeId is required and must be 1 or greater. |
Issuer References
- YoyoGroup APIs CVS 2.9 RESTful, PDF document.
- YoyoGroup CVS Web Portal Guide, PDF document.
FAQ's
Where can I find my testing API credentials?
Log into the Web Portal as the Channel Owner, go the the Channels section. The Interface ID and password are your API ID and password. You can have multiple channels inside the same channel group.
Where do I get my Web Portal login credentials?
These are issued to you by the Yoyo integrations team. When your solution has passed integrations testing, and is promoted into the production environment, you will receive an email with your login credentials.
How do I get my campaigns signed-off in the QA environment?
Make sure your have signed off the campaign as the Campaign Owner via the Web Portal, and then Simply email your integrations specialist to sign it off.
What parameters get sent with the redemption callback?
Please refer to the redemption callback section.
How do I set the expiry time for a coupon/voucher on issue?
When making the POST /coupons call use the numExpiryDays parameter to set the number of expiry days. This option will only work if the option for a channel to override the coupon expiry was enable during campaign creation.
Why do I only see 20 giftcards on the GET /giftcards/{id} API call when I know the user has 50?
If you wish to see an extended list of gift cards set the pageSize parameter to a number that you want, default is 20.
What are the content parameters to use when created a custom SMS message with the API call?
When issuing a gift card with an sms message, you can include the following parameters in the message. #WICODE #BALANCE #EXPIRY #MOBISITE.
What is the deference between an Open and a Merged wiCodes.
An open wiCode is campaign specific, issuing the user coupons from all campaigns assigned to that channel. A merged wicode is coupons specific, a token will be created incorporating all tokens that have been issued to the user by the channel group.
I am issuing coupons but I am not receiving a wiCode with them.
You need need to set the issueWicode parameter to true when doing the POST /coupon call.
Earn Gateway
The Earn Gateway enables external parties to notify Yoyo when transactions or events occur that should earn loyalty points for a Yoyo Pro client's customer. The service identifies customers using various identifiers.
Customer ID Types
customer.type | Description |
---|---|
MOBILE_SHA512 | SHA512 hash of the customer's mobile number* |
MOBILE | Customer's mobile number* |
REFERENCE | CVS customer reference |
ALIAS | Ad hoc customer alias (can also be a PSP card token for card-linked loyalty) |
* Mobile numbers must be in MSISDN format with a leading '+' character (e.g., '+27820000000')
Store Reference Types
reference | Description |
---|---|
WIGROUP | Store ID as defined by Yoyo |
REMOTE | Remote store ID as configured in the Yoyo platform |
API Service
{
"reference": "transaction_123",
"amount": 10000,
"customer": {
"type": "MOBILE",
"reference": "customer_456",
"msisdn": "+27820000000"
},
"store": {
"type": "WIGROUP",
"reference": "store_789"
}
}
Response Examples
Success Response
{
"earnEventId": 21447,
"loyaltyEarnEventId": 18086,
"totalPointsEarned": 3,
"loyaltyPointsBalance": 103,
"applicationDTO": {
"id": 14,
"name": "Wimpy Integrations"
}
}
Error Response
{
"errors": [
{
"code": "0103",
"message": "Customer does not exist."
}
]
}
Response Codes
Code | Description |
---|---|
200 | Success - loyalty earned |
400 | No loyalty was earned, see errors.message for details |
404 | User not found |
Recon and Settlement
The Yoyo 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 process.
Reconciliation
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:
- Daily mark off file via SFTP (on request)
- Daily Recon summary (PDF) and transactional (csv) report via email (automated)
- Recon transactional report via Yoyo merchant portal (manual retrieval)
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, Yoyo will float the difference between what has been settled to the store owner and what has been debited from the VSP. Yoyo 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 YoyoPlatform, a retailer-maintained float is typically required.
Test Cases
To view the Over the Counter Test Cases we use during Certification, please click here
POS Test cases
A table of test cases is provided that should be completed to ensure that the POS implementation operates as expected.
Category | ID | Description | Expected Outcome |
---|---|---|---|
Payments | 1.1 | Redeem a payment wiCode to settle the basketAmount. Finalise the transaction. | Successful response, with the basketAmount processed. |
1.2 | Redeem a payment wiCode to settle the basketAmount. Reverse the transaction. | Successful response, with the basketAmount reversed. | |
1.3 | Redeem an invalid payment wiCode (you may use any random number -- e.g. use "1234567"). (The transaction request should fail.) | Error message: "Transaction failed - token not reserved by VSP." | |
1.4 | Redeem a payment wiCode to partially settle the bill. Finalise the transaction. Redeem another payment wiCode to settle the outstanding amount on the bill. Finalise the transaction. | Successful response, with a partial basket amount processed. Another successful response with the full basketAmount processed. | |
Deposit | 2.1 | Redeem a deposit wiCode to the value of the basketAmount. Finalise the transaction. | Successful response, with the basketAmount processed. |
2.2 | Redeem a deposit wiCode to the value of the basketAmount. Reverse the transaction. | Successful response, with the basketAmount reversed. | |
2.3 | Redeem an invalid deposit wiCode. | Error message: "Transaction failed - token not reserved by VSP." | |
Withdrawal | 3.1 | Redeem a withdrawal wiCode to the value of the basketAmount. Finalise the transaction. | Successful response, with the basketAmount processed. |
3.2 | Redeem a withdrawal wiCode to the value of the basketAmount. Reverse the transaction. | Successful response, with the basketAmount reversed. | |
3.3 | Redeem an invalid withdrawal wiCode. | Error message: "Transaction failed - token not reserved by VSP." | |
TipAmount | 4.1 | Redeem a payment wiCode with a positive tipAmount to settle the basketAmount. Finalise the transaction. (basketAmount + tipAmount = totalAmount) | Successful response, with the totalAmount processed. |
4.2 | Redeem a payment wiCode with a positive tipAmount to settle the basketAmount. Reverse the transaction. (basketAmount + tipAmount = totalAmount) | Successful response, with the totalAmount reversed. | |
CashbackAmount | 5.1 | Redeem a payment wiCode with a positive cashbackAmount to settle the basketAmount. Finalise the transaction. (basketAmount + cashbackAmount = totalAmount) | Successful response, with the totalAmount processed. |
5.2 | Redeem a payment wiCode with a positive cashbackAmount to settle the basketAmount. Reverse the transaction. (basketAmount + cashBackAmount = totalAmount) | Successful response, with the totalAmount reversed. | |
Voucher | 6.1 | Redeem a voucher. Finalise the voucher redemption. | Successful response, with the totalAmount processed. |
6.2 | Redeem a voucher. Reverse the voucher redemption. | Successful response, with the totalAmount reversed. | |
6.3 | Redeem an invalid voucher wiCode. | Error message: "Transaction failed - token not reserved by VSP." | |
6.4 | Redeem a voucher wiCode to partially settle the bill. Finalise the transaction. Redeem more wiCode(s) (payment, voucher, etc.) to settle the outstanding amount on the bill. Finalise the transaction. | Successful response, with a partial basket amount processed. Subsequent successful response(s) until the full basketAmount is processed. | |
Coupon | 7.1 | Open a bill and add an item with the SKU of a single coupon redemption. Redeem a single SKU coupon. Finalise the transaction. | Successful response, with the totalAmount processed. |
7.2 | Open a bill and add an item with the SKU of a single coupon redemption. Redeem a single SKU coupon. Reverse the transaction. | Successful response, with the totalAmount reversed. | |
7.3 | Open a bill, and add items that do not have the SKU number of a single SKU coupon. Redeem a single SKU coupon. (The transaction request should fail.) | Error message: "Coupon cannot be redeemed. Required product(s) not found in basket." | |
7.4 | Open a bill and add the two items with the SKU numbers of a multi SKU coupon. Redeem a multi SKU combo. Finalise the transaction. | Successful response, with the totalAmount processed. | |
7.5 | Open a bill and add the two items with the SKU numbers of a multi SKU coupon. Redeem a multi SKU combo. Reverse the transaction. | Successful response, with the totalAmount reversed. | |
7.6 | Open a bill and only add one of the items with a SKU number of a multi SKU coupon. Redeem a multi SKU combo. (The transaction request should fail.) | Error message: "Coupon cannot be redeemed. Required product(s) not found in basket." | |
7.7 | Redeem a coupon wiCode to partially settle the bill. Finalise the transaction. Redeem more wiCode(s) (payment, voucher, etc.) to settle the outstanding amount on the bill. Finalise the transaction. | Successful response, with a partial basket amount processed. Subsequent successful response(s) until the full basketAmount is processed. | |
Loyalty - to be completed | 8.1 | Tests for earn loaylty codes -> potentially no discounts processed | |
8.2 | Tests for reward redemption wiCodes. | ||
8.3 | Tests to display the correct information. | ||
Error handling | 9.1 | Whenever a transaction fails, a VSP object should be received if the appropriate required fields are specified in the transaction request call | Display responseDesc from the VSP object. |
9.2 | If incorrect information are sent in the transaction request call, or if the required fields are not sent in the transaction request call, a response object will be received which contains a responseDesc field. | Display responseDesc from the response object. | |
Sit-down | 10.1 | Is it possible to print the QR code on the slip? The QR code must consist of the QR Type, Bill ID, Store ID and the Basket Amount. | This is mandatory. The correct information should be contained in the QR code. |
10.2 | Perform a partial transaction with an activated sit-down model VSP. Perform the transaction history call on the basketId. | A single transactions is successfully displayed corresponding to the particular basketId provided. | |
10.3 | Perform a partial transaction with an activated sit-down model VSP. Perform another payment to settle the outstanding amount on the bill. Perform the transaction history call on the basketID. | A list of two transactions are successfully displayed corresponding to the particular basketId provided. | |
10.4 | Perform three partial transactions to settle the bill. If possible, use more than one VSP. Perform a transaction history call after each of the three payments and ensure that the outstanding amount on the POS is updated accordingly. | A list of three transactions are successfully displayed corresponding to the particular basketId provided. In total three transaction history calls should be made. | |
Over-the-counter | 11.1 | Is it possible to scan the QR code with with a relevant device? The QR code must consist of the QR Type and the Store ID. | This is mandatory. The correct information should be contained in the QR code. |
11.2 | Perform a payment with an activated informal enabled VSP. Perform the the transaction history call on the storeId. | The most recent transaction corresponding to the particular storeId is successfully displayed. | |
11.3 | Perform a partial transaction with an activated sit-down model VSP. Perform another payment to settle the outstanding amount on the bill. Perform the transaction history call on the basketID. | A list of two transactions are successfully displayed corresponding to the particular basketId provided. | |
11.4 | Perform three partial transactions to settle the bill. Perform a transaction history call after each of the three payments and ensure that the outstanding amount on the POS is updated accordingly. | In total three transaction history calls should be made. The correct mobile payment information should be displayed on the POS and on the till slip printed after the transaction is closed. | |
11.5 | Perform four partial transactions to settle the bill. Perform a transaction history call after the first two payments and another after the fourth payment. Ensure that the outstanding amount on the POS is updated accordingly. | In total four transaction history calls should be made. The correct mobile payment information should be displayed on the POS and on the till slip printed after the transaction is closed. | |
Combination testing | 12.1 | Create a bill. Perform a partial payment using a sit-down model VSP. Perform a further partial payment using a Voucher wiCode. Perform a final partial payment using an informal VSP. | One transaction history call should be made to process the sit-down model VSP payment. |
Voiding of items (Over-the-counter) | 13 | If any item (SKU) is removed from the basket, all mobile payment transactions (all mobile payment transactions excluding sit-down transactions) must be reversed. If the make-up of the products in a basket changes, an updated list of products (SKUs) must be provided with any mobile transaction request. | A note |
13.1 | Create a bill with two items. Perform a partial payment. Void an item. Proceed to tender again. Perform over-the-counter payments to settle the bill. | The initial partial payments must be reversed. An updated list (containing a single SKU) must be provided when new tenders are processed. | |
Webcam | 14.1 | Can the webcam be activated to scan a QR code, and then be deactivated? | This a a mandatory test. |
Buzzer | 15.1 | Does the buzzer beep upon a QR code scan? | This a a mandatory test. |
- All relevant tests have to be successfully completed to ensure that the POS integration has been successful.
- All coupon & voucher wiCode redemption and loyalty wiCode information will be supplied.
- Partial payments on a bill should only be finalised once the sum of the partial payment equal or exceed the value of the basket. This rule only excludes sit-down payments.
POS Go-live checklist
Security
- Once in production, a QA and live environment are both required
- All communication to Yoyo must be done via HTTPS
- You must connect to the secure DNS endpoint that will be provided by Yoyo
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 labeled "Mobile"
- POS must be able to process a full, partial or zero-value approval
- Discount transactions (Coupons/Vouchers/Gift cards) are processed as partial payment tenders
- The POS must allow split tender with mobile as a payment method
- If a customer has multiple wiCodes to be redeemed, codes associated with coupons or vouchers should be used first. Thereafter, codes 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
CVS test cases
A table of test cases is provided that should be completed to ensure that the CVS implementation operates as expected.
Category | ID | Call | Description | Expected Outcome |
---|---|---|---|---|
giftcards | 1.1 | issueGiftCard | Issue a Gift Card with by specifying the balance, campaignId and the userRef. | Successful response, giftcard object is returned. |
1.2 | getGiftCard | Retrieve an issued Gift Card by specifying the giftcardId in the path. | Successful response, giftcard object is returned. | |
1.3 | deleteGiftCard | Delete an issued Gift Card by specifying the giftcardId in the path. | Successful response, with a responseCode of "-1" | |
coupon (Coupons & Vouchers) | 2.1 | IssueCoupon | Issue a Coupon or Voucher with by specifying the balance, campaignId and the userRef. | Successful response, coupon object is returned. |
2.2 | getCoupon | Retrieve an issued Coupon or Voucher by specifying the couponId in the path. | Successful response, coupon object is returned. | |
2.3 | deleteCoupon | Delete an issued Coupon or Voucher by specifying the couponId in the path. | Successful response, with a responseCode of "-1" | |
users/{userRef}/token | 3.1 | setUserToken | Issue a Gift Card wiCode by specifying a single giftcardId | Successful response, a token object is returned. |
3.2 | setUserToken | Issue a Gift Card wiCode by specifying multiple giftcardIds | Successful response, a token object is returned. | |
3.3 | setUserToken | Issue a Gift Card wiCode by specifying all active giftcardIds (i.e. giftcardIds = ["-1"]) | Successful response, a token object is returned. | |
3.4 | setUserToken | Issue a Coupon wiCode by specifying a single couponIds | Successful response, a token object is returned. | |
3.5 | setUserToken | Issue a Coupon wiCode by specifying multiple couponIds | Successful response, a token object is returned. | |
3.6 | setUserToken | Issue a Coupon wiCode by specifying all active couponIds (i.e. couponIds = ["-1"]) | Successful response, a token object is returned. | |
3.7 | setUserToken | Issue a Voucher wiCode by specifying a single couponId | Successful response, a token object is returned. | |
3.8 | setUserToken | Issue a Voucher wiCode by specifying multiple couponIds | Successful response, a token object is returned. | |
3.9 | setUserToken | Issue a Voucher wiCode by specifying all active couponIds (i.e. couponIds = ["-1"]) | Successful response, a token object is returned. | |
3.10 | getUserToken | Retrieve an issued Coupon or Voucher by specifying the couponId in the path. | Successful response, a token object is returned. | |
3.11 | deleteUserToken | Delete an issued Coupon or Voucher by specifying the couponId in the path. | Successful response, with a responseCode of "-1" | |
giftcardtransactions | 4.1 | getGiftCardTransactions | Retrieve a list of Gift Card transactions linked to a specific campaign. The apiId and the apiPassword must be provided, while the other fields may be used as query parameters. | Successful response, a giftcardTransactionList object is returned. |
4.2 | getGiftCardTransactions | Retrieve the details of a particular Gift Card by specifying the id in the path of the call. | Successful response, a giftcardTransactionList object is returned containing the Gift Card specified in the id. | |
coupontransactions | 5.1 | getCouponTransactions | Retrieve a list of Coupon & Voucher transactions linked to a specific campaign. The apiId and the apiPassword must be provided, while the other fields may be used as query parameters. | Successful response, a couponTransactionList is returned. |
5.2 | getCouponTransactions | Retrieve the details of a particular Coupon or Voucher by specifying the id in the path of the call. | Successful response, a couponTransactionList object is returned containing the Coupon or Voucher specified in the id. | |
transactions | 6.1 | transactions | Retrieve a list of Coupon & Voucher and Gift Card transactions linked to a specific campaign. The apiId and the apiPassword must be provided. | Successful response, a transaction object is returned. |
giftcardcampaigns | 7.1 | getGiftCardCampaigns | Retrieve a list of Gift Card campaigns linked to a channel. The apiId and the apiPassword must be provided. | Successful response, a giftCardCampaigns object is returned. |
couponcampaigns | 8.1 | getCouponCampaigns | Retrieve a list of Coupon and Voucher campaigns linked to a channel. The apiId and the apiPassword must be provided. | Successful response, a couponCampaigns object is returned. |
- All relevant tests have to be successfully completed to ensure that the CVS integration has been successful.
- All coupon & voucher wiCode redemption and loyalty wiCode information will be supplied.