Voucher Issuing
Issue vouchers via SMS, WhatsApp, or your own channels
Via SMS or WhatsApp
Quick StartYoyo handles delivery - just provide a mobile number
How it works
- 1Call the Issue Coupon API with campaign ID and mobile number
- 2Yoyo creates the voucher and generates a unique wiCode
- 3Yoyo automatically delivers the voucher via SMS or WhatsApp
- 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
}'{
"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
- 1Call the Issue Coupon API with userRef but without sendSMS
- 2Yoyo creates the voucher and returns the wiCode in the response
- 3Display the wiCode in your app, email, or any custom channel
- 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 codeid- Voucher IDstateId- 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}"{
"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}"{
"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}"{
"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}"{
"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}"{
"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}"{
"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}"{
"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.
{
"redemptionId": 1,
"campaignId": 123,
"userId": "user456",
"vspId": 20016,
"amount": 5000,
"type": "VOUCHER",
"state": "S",
"transactionId": 431711,
"createDate": "2024-01-18T14:05:58.009Z"
}| Field | Type | Description |
|---|---|---|
redemptionId | Integer | Unique identifier for the redemption event |
campaignId | Integer | Campaign the redemption belongs to |
userId | String | Customer identifier |
vspId | Integer | Value Store Provider identifier |
amount | Integer | Redemption amount in cents (5000 = R50.00) |
type | String | COUPON, VOUCHER, or GIFTCARD |
state | String | S (Success), F (Failed), or R (Reversed) |
transactionId | Integer | Related transaction identifier |
createDate | String | ISO 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.
