function run_transaction($vars)
 {
     global $db;
     $psi = new PsiGatePayment();
     // Not all fields below are required.  Consult manual for specifics.
     if ($vars['testmode']) {
         $psi->setGatewayURL('https://dev.psigate.com:7989/Messenger/XMLMessenger');
     } else {
         $psi->setGatewayURL('https://secure.psigate.com:7934/Messenger/XMLMessenger');
     }
     $psi->setStoreID($vars['storeid']);
     $psi->setPassPhrase($vars['passphrase']);
     $psi->setPaymentType('CC');
     $psi->setCardAction($vars['card-action']);
     // 0 – Sale, 1 – PreAuth, 2 – PostAuth, 3 – Credit, 4 – Forced PostAuth, 9 – Void
     //$psi->setOrderID($vars['order-id']); // For PostAuth, Credit, and Void transactions, OrderID is required and it must its value must be the same as the OrderID of the associated transaction request.
     $psi->setSubTotal($vars['card-amount']);
     // Amount
     $psi->setCardNumber($vars['card-number']);
     // Card Number
     $psi->setCardExpMonth(substr($vars['card-exp'], 0, 2));
     // Month in 2-digit format
     $psi->setCardExpYear(substr($vars['card-exp'], 2, 2));
     // Year in 2-digit format
     if ($vars['card-cvv']) {
         $psi->setCardIDCode('1');
         // Pass CVV code
         /*
                     Passes the status for Visa CVV2, MasterCard CVC2, and Amex CID.  
                     If unknown leave blank.
                     0 = Bypassed
                     1 = Value present
                     2 = Value illegible
                     9 = Card has no CVV2 value
         */
         $psi->setCardIDNumber($vars['card-cvv']);
         // Passes Visa CVV2, MasterCard CVC2, and Amex CID numbers
     }
     if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
         if (isset($_SERVER["HTTP_CLIENT_IP"])) {
             $proxy_ip = $_SERVER["HTTP_CLIENT_IP"];
         } else {
             $proxy_ip = $_SERVER["REMOTE_ADDR"];
         }
         $client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
         $forwarded_ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
     } else {
         if (isset($_SERVER["HTTP_CLIENT_IP"])) {
             $client_ip = $_SERVER["HTTP_CLIENT_IP"];
         } else {
             $client_ip = $_SERVER["REMOTE_ADDR"];
         }
         $proxy_ip = '0.0.0.0';
         $forwarded_ip = '';
     }
     $psi->setCustomerIP($client_ip);
     // Customer IP address, for fraud
     $psi->setUserID($vars['user-id']);
     // Unique customer identifier set by merchant.
     /**/
     $psi->setItemID($vars['item1']);
     $psi->setItemDescription($vars['description1']);
     $psi->setItemQty($vars['quantity1']);
     $psi->setItemPrice($vars['price1']);
     /**/
     $psi->setShiptotal($vars['shipping']);
     // shipping
     $psi->setTaxTotal1($vars['tax']);
     // Tax value 1, ex Sales Tax
     /*
         	$psi->setTaxTotal2('0.00'); // Tax value 2, ex VAT
         	$psi->setTaxTotal3('0.00'); // Tax value 3, ex GST
         	$psi->setTaxTotal4('0.00'); // Tax value 4, ex PST
         	$psi->setTaxTotal5('0.00'); // Tax value 5
     */
     $psi->setBname($vars['card-name']);
     // Billing Name
     $psi->setBcompany($vars['card-company']);
     // Company Name
     $psi->setBaddress1($vars['card-address']);
     // Billing Address 1
     $psi->setBaddress2('');
     // Billing Address 2
     $psi->setBcity($vars['card-city']);
     // Billing City
     $psi->setBprovince($vars['card-state']);
     // Billing state or province
     $psi->setBpostalCode($vars['card-zip']);
     // Billing Zip
     $psi->setBcountry($vars['card-country']);
     // Country Code - 2 alpha characters
     $psi->setPhone($vars['user-phone']);
     // Customer Phone
     $psi->setEmail($vars['user-email']);
     // Customer Email
     $psi->setComments('');
     // comments, whatever you'd like
     /*
         	$psi->setSname(''); // Shipping Name
         	$psi->setScompany(''); // Shipping Company
         	$psi->setSaddress1(''); // Shipping Address 1
         	$psi->setSaddress2(''); // Shipping Address 2
         	$psi->setScity(''); // Shipping City
         	$psi->setSprovince(''); // Shipping state or province
         	$psi->setSpostalCode(''); // Shipping Zip
         	$psi->setScountry(''); // Shipping country
     */
     //  $psi->setTestResult('A'); // Test result if you'd like to pass one.  See xml guide for more details
     /*
     TestResult may be set to simulate a response from the bank.
     A simulated transaction result shall be returned once the transaction request passes the fulfillment and fraud rule checks.  
     
     A – Simulates an approved response.
     D – Simulates a declined response.
     R – Randomly approves or declines orders.
     F – Simulates a fraud response.        
     */
     // Send transaction data to the gateway
     $psi_xml_error = !($psi->doPayment() == PSIGATE_TRANSACTION_OK);
     $return['RESULT'] = $psi->getTrxnApproved();
     $return['RESPMSG'] = $psi->getTrxnErrMsg();
     $return['PNREF'] = $psi->getTrxnTransRefNumber();
     $return['ORDERID'] = $psi->getTrxnOrderID();
     $return['AVS'] = $psi->getTrxnAVSResult();
     $return['CVV_VALID'] = $psi->getTrxnCardIDResult();
     $return['TAX_TOTAL'] = $psi->getTrxnTaxTotal();
     $return['SUB_TOTAL'] = $psi->getTrxnSubTotal();
     $return['FULL_TOTAL'] = $psi->getTrxnFullTotal();
     $err = '';
     if ($psi->getTrxnErrMsg()) {
         $err = "<br />PSiGate ERROR: " . $psi->getTrxnErrMsg();
     }
     $db->log_error("PSiGate RESPONSE: " . $psi->getTrxnReturnCode() . $err);
     return $return;
 }