Quantities for Multiple Products
This code is to add quantities for multiple products using USAePay's line items. If you choose not to use the line items, you can use Custom Fields with Custom Receipts or you can add notes about the quantities for multiple line items in the UMdescription field. The advantage to using line items is that you don't need to modify the merchant receipt and you can use Reports to see which items were bought.
Note that the payment form does not make any changes to the product database and it does not deduct items from your inventory. If you use the product database, you will need to manually adjust the inventory and hard code the information from the product database into the payment form.
In this example we have two line items: Member Breakfast for $20 and Guest Breakfast for $30. We assume no modifications have been made to the payment form.
Log into your USAePay merchant gateway. Go to "Settings", then "Source Keys". Select the source key you are using and click "Edit". Click "Edit Customization to Epay Form".
Overview
The strategy with the javascript and html is to
- Create an array of objects with each object a line item.
- Assign the same name, "Line[]", to all the input tags for line items so that we can create an array in the javascript for the values of all the input tags.
- Match the array of values from "Line[]" input tags to the quantity property for each object in the array in 1.
- Inject hidden input tags only for line items with positive line items.
This makes it so that a) only one part of the javascript has to be modified to add, modify, or delete line items and b) it is up to the developer to make sure that the order of the input tags match the order of the line items in the html code. If we hard code the line items as hidden input tags in the form, then the receipts will show every single line item even if they have 0 quantity since the form will pass UMline*quantity=0 for every line item.
Adding Javascript
In the header of the document, add the following code:
<script type="text/javascript">
//lineitem object constructor
function lineitem (productrefnum, sku, name, description, cost, quantity, taxable, hiddeninputs, subtotal)
{
this.productrefnum=productrefnum;
this.sku=sku;
this.name=name;
this.description=description;
this.cost=cost;
this.quantity=quantity;
this.taxable=taxable;
this.hiddeninputs=hiddeninputs;
this.subtotal=subtotal;
this.newhiddeninputs=newhiddeninputs;
this.newsubtotal=newsubtotal;
}
//newhiddeninputs method for lineitem object
//UMline*qty values are hidden since the form does not directly modify that variable.
function newhiddeninputs(n)
{
var hidden_inputs="";
if (this.quantity > 0)
{
hidden_inputs=hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "productrefnum\" value=\"" + this.productrefnum + "\" />";
hidden_inputs=hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "sku\" value=\"" + this.sku + "\" />";
hidden_inputs = hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "name\" value=\"" + this.name + "\" />";
hidden_inputs = hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "description\" value=\"" + this.description + "\" />";
hidden_inputs = hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "cost\" value=\"" + this.cost + "\" />";
hidden_inputs = hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "qty\" value=\"" + this.quantity + "\" />";
hidden_inputs = hidden_inputs + "<input type=\"hidden\" name=\"UMline" + n + "taxable\" value=\"" + this.taxable + "\" />";
this.hiddeninputs=hidden_inputs;
}
}
//newsubtotal method for lineitem object
function newsubtotal()
{
this.subtotal=this.quantity*(this.cost*1.0);
}
//main function to update the amount. We match quantities of all the line items to
//the products. Then we change the hidden inputs using a
//<div id="hiddenvariables> </div> tag only if the quantity > 0 for the product.
function updateAmount()
{
//we pull all the elements of the form which are named "Line[]" so that we'll be able to
//cycle through the assigning product quantities with a for loop based on the number of
//input fields for the products on the form. Without the [] notation
//we'd have to have a separate declaration line for each product.quantity
var myForm = document.forms.epayform;
var lineItems = myForm.elements["Line[]"];
//assign quantities to lineqty
var lineqty = new Array(lineItems.length); //lineqty size needs to be explicitly defined
for (var q = 0; q < lineItems.length; q++) //must use < since arrays start index at 0
{
lineqty[q] = lineItems[q].value;
}
//create lineitem objects for each product.
//To ease future maintenance of code we use an array to house the objects
//It's possible we may not need every single property of the product members to be declared
//but it's done just to avoid any possible errors with undefined properties.
//It's merchant's choice how many properties they really want to pass through on their
//transaction details and/or receipts.
//We initialize .quantity=0, .subtotal=0, .hiddeninputs="".
var products = new Array();
products[1] = new lineitem();
products[1].productrefnum = "57"
products[1].sku = "breakfastmembers";
products[1].name = "Breakfast for Members";
products[1].description = "Breakfast for members";
products[1].cost = 20.00;
products[1].quantity = 0;
products[1].taxable = "N";
products[1].subtotal = 0;
products[1].hiddeninputs = "";
products[2] = new lineitem();
products[2].productrefnum = "59"
products[2].sku = "breakfastnonmembers";
products[2].name = "Breakfast for Non-Members";
products[2].description = "Breakfast for non-members";
products[2].cost = 30.00;
products[2].quantity = 0;
products[2].taxable = "N";
products[2].subtotal = 0;
products[2].hiddeninputs = "";
//assign quantities to the product objects
for (var l=1; l < lineqty.length; l++) //must use < since arrays start index at 0
{
if (lineqty.length > 0)
{
products[l].quantity = lineqty[l];
}
}
//calculate subtotals
var total=0;
for (var t=1; t < products.length; t++) //must use < since arrays start index at 0
{
if (products[t].quantity > 0)
{
products[t].newsubtotal();
total=total + products[t].subtotal;
}
}
//create hidden inputs for form
var hiddeninputscomplete= "";
for (var h=1; h < products.length; h++) //must use < since arrays start index at 0
{
if (products[h].quantity > 0)
{
products[h].newhiddeninputs(h);
hiddeninputscomplete = hiddeninputscomplete + products[h].hiddeninputs;
document.getElementById('hiddenvariables').innerHTML = hiddeninputscomplete;
}
}
//assign total to UMamount and modify form to send the amount to the gateway.
document.epayform.UMamount.value = total;
document.getElementByName('UMamount').innerHTML = total;
}
</script>
Find the part of the form with the hidden tags, which should look something like this:
<input type="hidden" name="UMsubmit" value="1">
<input type="hidden" name="UMkey" value="[UMkey]">
<input type="hidden" name="UMredirDeclined" value="[UMredirDeclined]">
<input type="hidden" name="UMredirApproved" value="[UMredirApproved]">
<input type="hidden" name="UMhash" value="[UMhash]">
<input type="hidden" name="UMcommand" value="[UMcommand]">
<input type="hidden" name="UMtax" value="[UMtax]">
<input type="hidden" name="UMinvoice" value="[UMinvoice]">
<input type="hidden" name="UMcustid" value="[UMcustid]">
<input type="hidden" name="UMrecurring" value="[UMrecurring]">
<input type="hidden" name="UMaddcustomer" value="[UMaddcustomer]">
<input type="hidden" name="UMbillamount" value="[UMbillamount]">
<input type="hidden" name="UMcustreceipt" value="yes">
<input type="hidden" name="UMschedule" value="[UMschedule]">
<input type="hidden" name="UMnumleft" value="[UMnumleft]">
<input type="hidden" name="UMstart" value="[UMstart]">
<input type="hidden" name="UMexpire" value="[UMexpire]">
<input type="hidden" name="UMdescription" value="[UMdescription]">
<input type="hidden" name="UMechofields" value="[UMechofields]">
<input type="hidden" name="UMformString" value="[UMformString]">
We'll create the place were we inject the hidden input tags for the line items. Below the part of the form which has the hidden tags add:
<div id="hiddenvariables"> </div>
Find where you want to add the line items. Most people add it between the Order Date row and the Amount Row. Place the following code:
<!-- LINE ITEMS -->
<tr> <!-- first Line[] input hidden so that we can start counting with 1 in our arrays -->
<td bgcolor="#F0F0F0" width="234" align="right"> </td>
<td bgcolor="#F0F0F0" width="450"><input type="hidden" name="Line[]" value="">
</td>
</tr>
<tr>
<td bgcolor="#F0F0F0" width="234" align="right"><font size="2" face="Verdana">Breakfast - Members - $20: </font></td>
<td bgcolor="#F0F0F0" width="450"><input type="text" name="Line[]" value="" size="4" onChange="updateAmount()">
</td>
</tr>
<tr>
<td bgcolor="#F0F0F0" width="234" align="right"><font size="2" face="Verdana">Breakfast - Guests - $30: </font></td>
<td bgcolor="#F0F0F0" width="450"><input type="text" name="Line[]" value="" size="4" onChange="updateAmount()">
</td>
</tr>
<!-- END OF LINE ITEMS -->
Find the spot in the form where the Amount is displayed to the customer. If you search for [UMamount] and find the second occurance, it should look like this:
<tr>
<td bgcolor="#F0F0F0" width="234" align="right"><font size="2" face="Verdana">Order Amount:</font></td>
<td bgcolor="#F0F0F0" width="450">[UMamount]
</td>
</tr>
Replace that code with:
<tr>
<td bgcolor="#F0F0F0" width="234" align="right"><font size="2" face="Verdana">Total Charge: </font></td>
<td bgcolor="#F0F0F0" width="450">$<input type="text" name="UMamount" value="[UMamount]" readonly="readonly" size="4"></td>
</tr>
Delete the hidden input tag for UMamount:
<input type="hidden" name="UMamount" value="[UMamount]">