Miva Merchant: E-commerce Solutions to Grow Online
spacer gif

17. Internet Commerce


<MvCOMMERCE> Tag

The <MvCOMMERCE> tag is the point of communications between a Miva Script application and a commerce library.

The <MvCOMMERCE> block is made up of the following:

  1. a start tag (<MvCOMMERCE>)
  2. three attributes
    ACTION
    The URL for the destination server. (optional)
    METHOD
    Identifies the method you are using to contact the server (that is, the type of service you are requesting). Define the METHOD to match the one you have (or will) registered in the Miva Engine.
    FIELDS
    List of variables that contains the data to be sent to the commerce library.

  1. An end-tag </MvCOMMERCE>
    <MvCOMMERCE> can loop more than one time. It will continue to loop until it no longer receives data, or until it is explicitly halted with the <MvCOMMERCESTOP> tag.
    The basic format of <MvCOMMERCE> looks like:
    <MvCOMMERCE ACTION="url_to_commerce_server"
    METHOD ="access_method"
    FIELDS="value1,value2,..."> ...
    ...<MvCOMMERCESTOP>...
    </MvCOMMERCE>

The commerce library performs its functions and passes the data back to the Miva Script application.

The output from the commerce library is a binary tree that allows the library to make results available to a Miva Script application.

Commerce Library Exported Functions

A commerce library communicates with a Miva Script application through the Miva Engine. When the Miva Engine encounters the <MvCOMMERCE> tag in a Miva Script application, it consults its list of registered commerce libraries. If a matching commerce library is found, the Miva Engine loads the corresponding DLL.

To develop a commerce library for a Miva Script application, the DLL must export the following four functions:

miva_commerce_init
miva_commerce_loop
miva_commerce_cleanup
miva_commerce_error

All communication from a Miva commerce library to the Miva Script application is through these four exported functions.

miva_commerce_init

This function is called when the Miva Engine encounters a <MvCOMMERCE> block. Its purpose is to initialize any data that will be used inside the <MvCOMMERCE> block. The DLL can store any application-specific values in the "data" parameter. This parameter is passed to the other exported functions.

Syntax:
Miva_Commerce_Status miva_commerce_init ( Miva_Context context,
void **data,
const char *method,
const char *action,
Miva_VariableList input,
Miva_VariableTree output );
Parameters
context
a handle to Miva_Context.
data
a placeholder that allows a commerce library to allocate and store instance-specific data. Any value, which you assign to the data parameter, is passed to any subsequent calls to the commerce library.
method
the value of the METHOD attribute that was specified in the <MvCOMMERCE> tag.
action
the value of the ACTION attribute that was specified in the <MvCOMMERCE> tag.
input
a handle to a Miva_VariableList containing all the variables specified in the FIELDS parameter of the <MvCOMMERCE> tag.
output
a handle to a Miva_VariableTree which is used by the commerce library to return values to the module. All variables added to this tree are made available to the module in the form of system variables, which are available only inside the <MvCOMMERCE> block.
Return Value
MIVA_COMMERCE_OK
successful, then proceeds with executing the code inside the <MvCOMMERCE> block.
MIVA_COMMERCE_ERROR
one of more errors were encountered and the Miva Engine calls miva_commerce_error.

miva_commerce_loop

When miva_commerce_init returns MIVA_COMMERCE_OK, the Miva Engine calls the miva_commerce_loop function.

This function is called once per iteration of a <MvCOMMERCE> block. The parameter "iteration" indicates the number of times that miva_commerce_loop has been called.

Syntax:
Miva_Commerce_Status miva_commerce_loop ( Miva_Context context,
void **data,
const char *method,
const char *action,
Miva_VariableList input,
Miva_VariableTree output,
int iteration );
Parameters
context
a handle to Miva_Context
data
a placeholder that was passed to miva_commerce_init. If you assigned a value to it there, it will have the same value here.
method
the value of the METHOD attribute that was specified in the <MvCOMMERCE> tag.
action
the value of the ACTION attribute that was specified in the <MvCOMMERCE> tag.
input
a handle to a Miva_VariableList containing all the variables specified in the FIELDS parameter of the <MvCOMMERCE> tag.
output
a handle to a Miva_VariableTree which is used by the commerce library to return values to the module. All variables added to this tree are made available to the module in the form of system variables only inside the <MvCOMMERCE> block.
iteration
the number of times Miva has executed the code inside the <MvCOMMERCE> block. The first time miva_commerce_loop is called, iteration has a value of 0.
Return Value

The action that the Miva Engine takes is dependent on the return value of the miva_commerce_loop.
MIVA_COMMERCE_OK
the engine will proceed to execute the code inside the <MvCOMMERCE> block.
MIVA_COMMERCE_ERROR
one of more errors were encountered and the Miva Engine calls miva_commerce_error.
MIVA_COMMERCE_END
the engine will exit the commerce block normally (you would normally return MIVA_COMMERCE_END when your commerce library functions are complete and should stop).

miva_commerce_cleanup

Whenever the Miva Engine has completed using the commerce library, regardless of the return value, it calls miva_commerce_cleanup.

Syntax:
void miva_commerce_cleanup (
Miva_Context context,
void **data,
const char *method,
const char *action,
Miva_VariableList input );
Parameters
context
a handle to Miva_Context. Your commerce library will need this handle to use the networking and file functions provided by the Commerce API.
data
a placeholder that was passed to miva_commerce_init. If you assigned a value to it there, it will have the same value here.
method
the value of the METHOD attribute that was specified in the <MvCOMMERCE> tag.
action
the value of the ACTION attribute that was specified in the <MvCOMMERCE> tag.
input
a handle to a Miva_VariableList containing all the variables specified in the FIELDS parameter of the <MvCOMMERCE> tag.
Return Value

No return value.

miva_commerce_error

If either miva_commerce_init or miva_commerce_loop returns MIVA_COMMERCE_ERROR, the Miva Engine calls miva_commerce_error to receive a description of the error. It makes this call prior to calling miva_commerce_cleanup.

This function is called by the Miva Engine to receive a description of an error. It is called prior to calling miva_commerce_cleanup.

Syntax
const char *miva_commerce_error (
Miva_Context context,
void **data,
const char *method,
const char *action,
Miva_VariableList input );
Parameters
context
a handle to Miva_Context. Your commerce library will need this handle to use the networking and file functions provided by the Commerce API.
data
a placeholder that was passed to miva_commerce_init. If you assigned a value to it there, it will have the same value here.
method
the value of the METHOD attribute that was specified in the <MvCOMMERCE> tag.
action
the value of the ACTION attribute that was specified in the <MvCOMMERCE> tag.
input
a handle to a Miva_VariableList containing all the variables specified in the FIELDS parameter of the <MvCOMMERCE> tag.
Return Value

The text for the error is returned.

Using UPS Quick Cost

<MvCOMMERCE> supports the 'UPSRSS' METHOD. This enables your program to submit information about a shipment (weight, origin, destination, etc.) to UPS's Quick Cost calculator and receive back the shipping cost and other information. <MvCOMMERCE> provides a convenient way to do pre- and post-processing of UPS shipping information without having to prepare your own CGI scripts to do so. UPS's documentation on Quick Cost is available from http://www.ups.com/tools/tools.html.

Quick Cost can calculate costs only for shipments that originate in the United States.

The basic format of <MvCOMMERCE> is as follows:

<MvCOMMERCE
METHOD = "UPSRSS"
ACTION = "http://www.ups.com/using/services/rave/qcost_dss.cgi"
FIELDS="var1, var2,...">

The values of ACTION and METHOD must be exactly as indicated. The value of the FIELDS attribute is a series of input variables giving information about the shipment. These variables will generally get their values from a form in your document. There are specific variable names (listed below) that must be used; these variables are case-sensitive.

To set up UPS processing, follow these steps:

  1. Create a form that contains fields for each input variable (that is, each type of information) that you want to send to the Quick Cost calculator. Some variables are required; others are optional.
    1. The name (NAME attribute) of each field must be the same as the corresponding variable name.
    2. Choose form objects that are appropriate to the type of data: for example, check boxes for yes/no choices, text boxes for text, and radio buttons or drop-down lists for choices from a defined group.
    3. Set the form's ACTION attribute to point to the Miva Script program containing the <MvCOMMERCE> tag. If it's the same as the script containing the form, just use the macro &[documenturl]; as the value of ACTION.
    4. Set the form's METHOD attribute to 'POST'.
  2. Include each of the input variables from the form in the FIELDS attribute of <MvCOMMERCE>. The order is unimportant, and you need include only those variables that actually appear in the form.
  3. Between the <MvCOMMERCE> and </MvCOMMERCE> tags, insert code that processes the information sent back by the Quick Cost calculator. The information is sent back in the output variables listed below. You don't have to use all of these variables in your code, just the ones you need. The processing that you do can be as simple as just displaying values of certain variables, or you can do more complex processing as desired. As a minimum, you should probably display the cost (totalchrg), or an error message (errmsg) if there is one.

UPS Input Variables

The table below displays the input variables that you can use in a form and pass to the Quick Cost calculator using the FIELDS attribute. The Description column identifies the type(s) of value that each variable must have. Required variables are bold and in red. Contact UPS or consult their online documentation for detailed definitions and service descriptions.

Field
Description
AppVersion
Set to 1.2.
AcceptUPSLicenseAgreement
Must have the value 'yes' when the form is submitted.
ResponseType
Data stream format to be used in response message.
ActionCode
3 - Show rate for selected UPS service.
4 - Show rates for all available UPS services
Defines the level of service required in the response. services.
ServiceLevelCode
Define type of UPS shipping
UPS Service___________UPS Product Code
Next Day Air Early_______1DM
Next Day Air____________1DA
Next Day Air Intra________1DAPI
(Puerto Rico)
Next Day Air Saver_______1DP
2nd Day Air A M_________2DM
2nd Day Air_____________2DA
3 Day Select____________3DS
Ground ________________GRD
Canada Standard ________STD
Worldwide Express_______XPR
Worldwide Express_______XDM
Worldwide Expedited ____XPD
RateChart
Determines which rate chart is used to calculate the rate.
Valid Codes are:
- Customer+Counter
- Letter+Center
- On+Call+Air
- One+Time+Pickup
- Regular+Daily+Pickup
ShipperPostalCode
Postal code for origin of package.
ConsigneePostalCode
One to six alphanumeric postal code of the destination country.
ConsigneeCountry
Country code
PackageActualWeight
Weight of package. If UPS letter, no weight required. If fraction included, will be rounded to next whole value.
DeclaredValueInsurance
All packages automatically insured for $100. Additional insurance $.35/$100 of value or fraction thereof. Max value for insurance $50,000.
Length
Length of package in inches. Default = 0.
Width
Width of package in inches. Default = 0.
Height
Weight of package in inches. Default = 0.
OversizeInd
0 = Not Oversized
1 = Package Oversized
CODInd
0 = Not COD
1 = Shipment is COD
HazMat
0 = No hazardous material
1 = Package contains a hazardous material
AdditionalHandlingInd
0 = No special handling
1 = Package requires additional handling
CallTagARDInd
0 = for none
1 = for basic call tag service
2 = for electronic
SatDeliveryInd
0 = No Saturday delivery
1 = Saturday delivery
SatPickupInd
0 = No Saturday pickup
1 = Saturday pickup
DCISInd
0 = None
1 = Basic
2 = Signature Required
3 = Alternative Return Address
4 = All Available Information
VerbalConfirmationInd
0 = No verbal confirmation; Default
1 = Verbal confirmation
SNDestinationInd1
0 = None; Default
1 = Domestic
2 = International
SNDestinationInd2
0 = None; Default
1 = Domestic
2 = International
ReturnLabelInd
0 = No return label; Default
1 = Return label
ResidentialInd
0 = Commercial
1 = Residential
PackagingType
00 = Shipper Supplied Packaging
01 = UPS Letter Envelope
03 = UPS Tube
21 = International UPS 25KG Box
25 = International UPS 10KG Box

Return Fields

The following fields are returned inside the <MvCOMMERCE>...</MvCOMMERCE>:

<MvCOMMERCE
METHOD = "UPSRSS"
ACTION = "http://www.ups.com/using/services/rave/qcost_dss.cgi"
FIELDS = "{ l.fields }">
Returned Fields

AcceptUPSLicenseAgreement = <MvEVAL EXPR = "{ g.AcceptUPSLicenseAgreement}"

UPSOnLine = <MvEVAL EXPR = "{ s.UPSOnLine }">

AppVersion = <MvEVAL EXPR = "{ s.AppVersion }">

ReturnCode = <MvEVAL EXPR = "{ s.ReturnCode }">

MessageText = <MvEVAL EXPR = "{ s.MessageText }">

ActionCode = <MvEVAL EXPR = "{ s.ActionCode }">

ServiceLevelCode = <MvEVAL EXPR = "{ s.ServiceLevelCode }">

ShipperPostalCode = <MvEVAL EXPR = "{ s.ShipperPostalCode }">

ShipperCountry = <MvEVAL EXPR = "{ s.ShipperCountry }">

ConsigneePostalCode = <MvEVAL EXPR = "{ s.ConsigneePostalCode }">

ConsigneeCountry = <MvEVAL EXPR = "{ s.ConsigneeCountry }">

DeliveryZone = <MvEVAL EXPR = "{ s.DeliveryZone }">

PackageActualWeight = <MvEVAL EXPR = "{ s.PackageActualWeight }">

ProductCharge = <MvEVAL EXPR = "{ s.ProductCharge }">

AccessorySurcharge = <MvEVAL EXPR = "{ s.AccessorySurcharge }">

TotalCharge = <MvEVAL EXPR = "{ s.TotalCharge }">

CommitTime = <MvEVAL EXPR = "{ s.CommitTime }">

Example

The file http://www.miva.com/products/engine/mia/templates/frame-ups.html gives an example of using UPSCost. Here is a shorter example that uses only required fields.

<HTML><HEAD><TITLE>UPS Cost Calculator</TITLE></HEAD>
<BODY BGCOLOR = "#ffffff">
<MvIF EXPR = "{ g.AcceptUPSLicenseAgreement EQ 'yes' }">
<MvCOMMENT> This branch is expected if the form has been submitted.</MvCOMMENT>
<TABLE BORDER = 0 WIDTH = "100%">
<TR><TD>
<B>Product</B>
</TD>
<TD WIDTH = "100%">
<B>Name</B>
</TD><TD>
<B>Price</B>
</TD></TR>
<TR><TD COLSPAN = 3>
<HR>
</TD></TR>
<MIVA MvCOMMERCE_Error = "nonfatal, nodisplay">
<MvCOMMERCE METHOD = "UPSRSS"
ACTION = "http://www.ups.com/using/services/rave/qcost_dss.cgi"
FIELDS ="AcceptUPSLicenseAgreement,
ActionCode,
ServiceLevelCode,
RateChart,
ShipperPostalCode,
ConsigneePostalCode,
ConsigneeCountry,
PackageActualWeight,
ResidentialInd,
PackagingType">
<MvIF EXPR = "{ s.ReturnCode NE '0000' }">
<MvASSIGN NAME = "g.Error" VALUE = "{ s.MessageText }">
<MvCOMMERCESTOP>
<MvELSE>
<TR><TD>
<MvEVAL EXPR = "{ s.ServiceLevelCode }">
</TD><TD>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '1DM' }">
Next Day Early AM
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '1DA' }">
Next Day Air
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '1DAPI' }">
Next Day Air Intra (Puerto Rico)
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '1DP' }">
Next Day Air Saver
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '2DM' }">
2nd Day Air AM
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '2DA' }">
2nd Day Air
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ '3DS' }">
3 Day Select
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ 'GND' }">
Ground
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ 'STD' }">
Canada Standard
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ 'XPR' }">
Worldwide Express
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ 'XDM' }">
Worldwide Express Plus
</MvIF>
<MvIF EXPR = "{ s.ServiceLevelCode EQ 'XPD' }">
Worldwide Expedited
</MvIF>
</TD><TD>
<MvEVAL EXPR = "{ s.TotalCharge }">
</TD></TR>
</MvIF>
</MvCOMMERCE>
</TABLE>
<MvIF EXPR = "{ MvCOMMERCE_Error }">
<P><B><MvEVAL EXPR = "{ MvCOMMERCE_Error }"></B></P>
<MvELSE>
<MvIF EXPR = "{ g.Error }">
<P><B><MvEVAL EXPR = "{ g.Error }"></B></P>
</MvIF>
</MvIF>
<P><A HREF = "&[s.documenturl];">Calculate shipping for another package.</A></P>
<MvELSE>
<FORM METHOD = "post" ACTION = "&[s.documenturl];">
<TABLE BORDER = 0>
<TR><TD>&nbsp;
</TD><TD>
<B>AcceptUPSLicenseAgreement</B>
<INPUT TYPE = "checkbox" NAME = "AcceptUPSLicenseAgreement" VALUE = "yes" CHECKED>
</TD></TR>
<TR><TD>
<B>ActionCode:</B>
</TD><TD>
<INPUT TYPE = "radio" NAME = "ActionCode" VALUE = 4 CHECKED> All Services<BR>
<INPUT TYPE = "radio" NAME = "ActionCode" VALUE = 3> Specified Service Only<BR>
</TD></TR>
<TR><TD>
<B>ServiceLevelCode:</B>
</TD><TD>
<SELECT NAME = "ServiceLevelCode">
<OPTION VALUE = "1DM">Next Day Early AM
<OPTION VALUE = "1DA">Next Day Air
<OPTION VALUE = "1DAPI">Next Day Air Intra (Puerto Rico)
<OPTION VALUE = "1DP">Next Day Air Saver
<OPTION VALUE = "2DM">2nd Day Air AM
<OPTION VALUE = "2DA">2nd Day Air
<OPTION VALUE = "3DS">3 Day Select
<OPTION VALUE = "GND">Ground
<OPTION VALUE = "STD">Canada Standard
<OPTION VALUE = "XPR">Worldwide Express
<OPTION VALUE = "XDM">Worldwide Express Plus
<OPTION VALUE = "XPD">Worldwide Expedited
</SELECT>
</TD></TR>
<TR><TD>
<B>RateChart:</B>
</TD><TD>
<SELECT NAME = "RateChart">
<OPTION VALUE = "Customer Counter" SELECTED>Customer Counter</OPTION>
<OPTION VALUE = "Letter Center">Letter Center</OPTION>
<OPTION VALUE = "On Call Air">On Call Air</OPTION>
<OPTION VALUE = "One Time Pickup">One Time Pickup</OPTION>
<OPTION VALUE = "Regular Daily Pickup">Regular Daily Pickup</OPTION>
</SELECT>
</TD></TR>
<TR><TD>
<B>ShipperPostalCode:</B>
</TD><TD>
<INPUT TYPE = "text" NAME = "ShipperPostalCode" SIZE = 10 VALUE = "92117">
</TD></TR>
<TR><TD ALIGN = "left">
<B>ConsigneePostalCode:</B>
</TD><TD ALIGN ="left">
<INPUT TYPE = "text" NAME = "ConsigneePostalCode" SIZE = 10 VALUE = "44145">
</TD></TR>
<TR><TD ALIGN = "left">
<B>ConsigneeCountry:</B>
</TD><TD ALIGN = "left">
<INPUT TYPE = "text" NAME = "ConsigneeCountry" SIZE = 4 VALUE = "US">
</TD></TR>
<TR><TD ALIGN = "left">
<B>PackageActualWeight:</B>
</TD><TD ALIGN = "left">
<INPUT TYPE = "text" NAME = "PackageActualWeight" SIZE = 10 VALUE = "5">
</TD></TR>
<TR><TD>
<B>ResidentialInd:</B>
</TD><TD ALIGN = "left">
<SELECT NAME = "ResidentialInd">
<OPTION VALUE = "0" SELECTED>Commercial</OPTION>
<OPTION VALUE = "1">Residential</OPTION>
</SELECT>
</TD></TR>
<TR><TD>
<B>PackagingType:</B>
</TD><TD ALIGN = "left">
<SELECT NAME = "PackagingType">
<OPTION VALUE = "00" SELECTED>Shipper Supplied Packaging</OPTION>
<OPTION VALUE = "01">UPS Letter Envelope</OPTION>
<OPTION VALUE = "03">UPS Tube</OPTION>
<OPTION VALUE = "21">UPS Express Box</OPTION>
<OPTION VALUE = "24">International UPS 25KG Box</OPTION>
<OPTION VALUE = "25">International UPS 10KG Box</OPTION>
</SELECT>
</TD></TR>
<TR><TD>&nbsp;
</TD><TD ALIGN = "left">
<INPUT TYPE = "submit" VALUE = "Calculate">
</TD></TR>
</TABLE>
</FORM>
</MvIF>
</BODY>
</HTML>