Yoyo Logo

Voucher Issuing

Issue vouchers via SMS, WhatsApp, or your own channels

Via SMS or WhatsApp

Quick Start

Yoyo handles delivery - just provide a mobile number

How it works

  1. 1Call the Issue Coupon API with campaign ID and mobile number
  2. 2Yoyo creates the voucher and generates a unique wiCode
  3. 3Yoyo automatically delivers the voucher via SMS or WhatsApp
  4. 4Customer receives the wiCode and can redeem at any integrated merchant
# Issue voucher and send via configured channel (SMS or WhatsApp)
curl -X POST "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons?issueWiCode=true" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "1234",
    "userRef": "your_customer_ref",
    "mobileNumber": "+27821234567",
    "smsMessage": "Your voucher code is ready!",
    "sendSMS": true
}'
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"
}

Note: The communication channel (SMS or WhatsApp) is configured at the system level, not per-request. Set sendSMS: true to trigger delivery via your configured channel. WhatsApp requires additional META configuration. The userRef field is mandatory for tracking.

Distribute in Your Own App or Channel

Get the wiCode and display it however you want

How it works

  1. 1Call the Issue Coupon API with userRef but without sendSMS
  2. 2Yoyo creates the voucher and returns the wiCode in the response
  3. 3Display the wiCode in your app, email, or any custom channel
  4. 4Customer uses the wiCode to redeem at any integrated merchant
# Issue wiCode only — no message sent
curl --location -X POST "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons?issueWiCode=true" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "1234",
    "userRef": "your_customer_reference"
}'
Use Cases
  • Display in your mobile app
  • Send via your own email system
  • Print on receipts or marketing materials
Response Fields
  • wiCode - The redemption code
  • id - Voucher ID
  • stateId - A = Active

Get Available Campaigns

Retrieve a list of active coupon/voucher campaigns available to your channel. Filter by user to exclude campaigns where they've reached their limit.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
Example Response
{
  "couponCampaigns": [{
    "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,
    "stateId": "A",
    "allowExpiryDateOverride": false,
    "expiryDays": 1096
  }],
  "paging": {
    "pageSize": 20,
    "pageOffset": 0,
    "numItemsOnPage": 11,
    "numItemsInTotal": 11,
    "numPages": 1
  },
  "responseCode": "-1",
  "responseDesc": "Success"
}

Get Campaign Details

Retrieve details of a specific campaign including issue dates, redemption dates, and restrictions.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns/{campaignId}" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
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,
    "stateId": "A"
  }],
  "paging": {
    "pageSize": 20,
    "pageOffset": 0,
    "numItemsOnPage": 1,
    "numItemsInTotal": 1,
    "numPages": 1
  },
  "responseCode": "-1",
  "responseDesc": "Success"
}

Get Campaign SKUs (Product-Specific Coupons)

For coupon campaigns that are product-specific, retrieve the list of eligible SKUs/barcodes.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/couponcampaigns/{campaignId}/skus" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
Example Response
{
  "responseCode": "-1",
  "responseDesc": "Success!",
  "skus": [
    {
      "sku": "string",
      "value": 0,
      "brand": "string",
      "product": "string",
      "size": "string"
    }
  ]
}

Get Voucher Details

Retrieve details of a specific issued voucher including state and expiry information.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons/{couponId}" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
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"
}

Get User's Vouchers

Retrieve all vouchers/coupons linked to a specific user reference.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/users/{userRef}/coupons" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
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": true,
    "isRedeemableOnMondays": true,
    "isRedeemableOnTuesdays": true,
    "isRedeemableOnWednesdays": true,
    "isRedeemableOnThursdays": true,
    "isRedeemableOnFridays": true,
    "isRedeemableOnSaturdays": true,
    "wiCode": "902430319",
    "voucherAmount": 500,
    "stateId": "E",
    "expiredDate": "2015-05-21T09:13:17+0200"
  }],
  "responseCode": "-1",
  "responseDesc": "Success"
}

Get Transaction History

Retrieve all transactions related to coupons/vouchers for reporting and reconciliation.

curl -X GET "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupontransactions?couponId={id}" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
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"
}

Expire/Delete Voucher

Expire a voucher and return any value to the campaign float.

curl -X DELETE "https://za-vsp-int.wigroup.co/cvs-issuer/rest/coupons/{couponId}" \
  -H "apiId: {apiId}" \
  -H "apiPassword: {apiPassword}"
Example Response
{
  "responseCode": "-1",
  "responseDesc": "Success"
}

Redemption Callback

Yoyo sends a POST to your webhook URL whenever a redemption completes — successfully or not. This is an outbound notification from Yoyo, not an endpoint you call. Use it to keep your own records in sync without polling.

Webhook URL: One callback URL is configured per VSP. Contact your Yoyo integration manager to set or change it.

POST to your webhook URL
{
  "redemptionId": 1,
  "campaignId": 123,
  "userId": "user456",
  "vspId": 20016,
  "amount": 5000,
  "type": "VOUCHER",
  "state": "S",
  "transactionId": 431711,
  "createDate": "2024-01-18T14:05:58.009Z"
}
Redemption callback payload fields
FieldTypeDescription
redemptionIdIntegerUnique identifier for the redemption event
campaignIdIntegerCampaign the redemption belongs to
userIdStringCustomer identifier
vspIdIntegerValue Store Provider identifier
amountIntegerRedemption amount in cents (5000 = R50.00)
typeStringCOUPON, VOUCHER, or GIFTCARD
stateStringS (Success), F (Failed), or R (Reversed)
transactionIdIntegerRelated transaction identifier
createDateStringISO 8601 timestamp of the redemption

Acknowledge every callback: Respond with 200 OK. If no response is received, Yoyo retries up to 10 times before giving up — after that the notification is not resent, so reconcile any gaps from your own transaction records.

Failed and reversed redemptions are delivered too, so check state before treating a callback as a completed redemption.