Design Guide: Accepting Vouchers and Gift cards
Vouchers and Giftcards are held by customers and have monetary value. In order to accept these on a website or application you need to validate that the customer does indeed hold the card/voucher. This requires a process of:
- Collecting details of the voucher/card from the user
- Validating the details are still valid
- Applying as a payment on a sale
What is a Voucher or Giftcard?
The terms 'voucher' or 'giftcard' can be confusing and different retailers will sometimes use different terminology as well. This page is explainning how to redeem something that can be used as a payment.
Can of Drink | $2.50 | |
Less discount | -0.50 | A discount, or coupon, is applied against items and reduces the overall price. This page is not discussing how to process these. |
Total sale | 2.00 | |
Paid by | ||
Voucher | 2.00 | A voucher/giftcard/prepay is applied as payment to a sale. This page explains how to process these. |
Within Fieldpine, we use the following terminology
Voucher is used for a coupon, email code, text code or anything else that has a monetary value. A typical example would be a $5 off voucher. Vouchers tend to be anonymous and single use.
Prepay is used for a reuseable card that maintains a monetary value and can reduce and increase in value over time. These are also often called Giftcards or Stored Value Cards.
As both of these items can be considered cash equivalents, there is an extra degree of security when handling them.
Step 1. Collect card details
Add a form to your webpage to collect the card number and password. This is purely a design and style decision and you can use whatever technique you want.
- If the user is typing the card numbers in manually they need to enter the rightmost digits. A minimum of 5 digits is required, the more the better though. If the card number is 987654321012, then the number 21012 must be entered as a minimum. Some retailers may require more digits to be entered.
- If you are capturing from a barcode scanner or QR reader then you should capture and use all the digits.
- Card numbers will typically be numeric only for prepay/gift cards. Vouchers may be alphanumeric or numeric depending on retailer requirements.
- Passwords for vouchers and giftcards are typically alphanumeric, consisting of 0-9 and A-Z only. The user must enter the complete password. Password checking is case insensitive.
<table> <tr><td>Card Number</td><td><input size="10" id="cardnum" /></td></tr> <tr><td>Card Password</td><td><input size="10" id="cardpass" /></td></tr> <tr><td></td><td><input type="button" value="Check Card" onclick="CheckCard()" /><span id="checkcardstatus"></span></td></tr> </table>
Card Number | ||
Card Password | ||
Trial details. These are visible only for testing purposes. If you enter real values here a card will be checked | ||
Retailer RmSystem | 4 numbers seperated by a comma | |
X-Api-Key | The Api Key |
Step 2. Validate card details
Once the details are collected they can be validated. An example script (non production quality) is shown. This script validates from the client browser to the server directly. This means the client API key is exposed generally, so you should expect to change API keys often.
<script> function CheckCard() { var num = document.getElementById("cardnum").value; var pass = document.getElementById("cardpass").value; if ((num.length < 5) || (pass.length < 1)) { alert("Please enter card number and password"); return; } document.getElementById("checkcardstatus").innerHTML = "Checking..."; var req = null; if (window.XMLHttpRequest) req = new XMLHttpRequest(); else if (window.ActiveXObject) req = new ActiveXObject("Microsoft.XMLHTTP"); var Url = "https://a1.fieldpine.com/OpenApi2_"; Url += "1,2,3,4"; // ****** Insert Retailers RmSystem here Url += "/CardInquiry"; Url += "/" + num; Url += "?pass=" + pass; req.open("GET", Url, false); if (window.ActiveXObject) req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); // Dear hacker. We know this API key is visible here. // It is primarily a caller validation. It only has access to this single API req.setRequestHeader("X-Api-Key", "**** Your API Key here ****"); req.onreadystatechange = function () { if (req.readyState == 4) { document.getElementById("checkcardstatus").innerHTML = "Done"; if (req.status == 200) { var oo = null; if (!!window.JSON && !!window.JSON.parse) oo = JSON.parse(req.responseText); else oo = eval("(" + req.responseText + ')'); var bal = oo.data.Cards[0].Balance; var Status = oo.data.Cards[0].Status; // ******* Capture the Usage token, this will be need on a sale var Usage = oo.data.Cards[0].UsageToken; alert("Card status " + Status + " available balance " + bal); } } }; req.send(null); } </script>
Step 3. Apply to sale
Once a valid UsageToken is obtained, only this value needs to be sent as part of the sale.
POST /Sales { "ExternalId": "123414", "CompletedDt": "2019-10-06T21:35", "CallerHandling": "none", "LINE": [ { "Pid": 1234, "Qty": 1, "TotalPrice": 19.95 } ], "PAYM": [ { "UsageToken": "1|50|ABC|AAABCC|BBBAAA", // **** Value returned from Cardinquiry "Amount": 19.95 } ] }
A usage token does not guarantee that the payment will be accepted. The token only says that a card/voucher was validated and funds were available. While this might seem counter intuative at first, consider the following sequence:
- Customer creates a shopping cart and enters a card/pass, obtaining a usage token "A"
- Customer uses a second computer, creates a sale, enters a card/pass, obtaining a usage token "B". Fieldpine will issue a new token even though the first is still outstanding as this could be a correct sequence of events. Fieldpine does not know if cart "A" is active or abandoned, trying make a decision around that would lead to possible confusion for the shopper
- Customer finally attempts to complete both sales. One will succeed, the other will receive an error and not process.
Fieldpine Processing of Sales - When balances change
If a sale is completed on a web site using a voucher, then the actual voucher balance is reduced when the sale is finalised within Fieldpine, not when the web site transfers the sale. The logic is:
- A website completes a sale. This sale has a UsageToken to say the card/password was validated and that funds where available when the card was entered
- The website uploads the sale to Fieldpine. This sale will have a status of "picking" and is not formally a completed sale yet. The sale might be voided or placed on back order by the dispatch team.
- When the sale is ready to ship, the picking screen displays the voucher payment and the current balance. If the balance is too small, then the sale cannot be completed and the dispatch team should not ship the goods. If the balance is enough, the sale completes, goods can be shipped and the voucher balance is reduced.
What does this mean in practical terms?
- Customer has voucher for $100
- Customer purchases online for $80. This sale is transferred to Fieldpine and is ready for picking
- Dispatch team, pick goods, complete the sale and ship the goods
- Customer voucher is reduced to $20 (where applicable)
- Customer has voucher for $100
- Customer purchases online for $80. This sale is transferred to Fieldpine and is ready for picking
- Customer purchases again online for $50. This sale is transferred to Fieldpine and is ready for picking.
- Both of the above sales are valid.
- Dispatch team, pick goods, completes one of the sales and ship the goods
- Customer voucher is reduced to $20 or $50, depending on which sale was dispatched
- The other sale will not complete on the picking screen, and the dispatch team can manually handle it
- Customer has voucher for $100
- Customer purchases online for $80. This sale is transferred to Fieldpine and is ready for picking
- Customer visits and store and uses the voucher for $100. This is permitted to complete as the picking sale has not yet been finalised
- Dispatch team, pick goods, but cannot complete the sale as the balance remaining is too small.