PX : code

CyberCash Payment Script (cbsend.php3) by Flint Doungchak
Download this code


<?

##
# Net Solutions LLC - 9/21/99
#
# Flint Doungchak (flint@netsolutionsllc.com) & Patrick Shafer (pshafer@netsolutionsllc.com)
#
# This is our first go-around with a totally PHP cybercash processing script.
# This script was designed with an Win32 filestructure in mind so your might
# need to tweak it to get in to work with Linux, etc. 

# Of course I invite improvements, and hope someone will post their UNIX
# solution for everyone to see. Please send comments and suggestions to 
# flint@netsolutionsllc.com
#
# Warning: There isn't a lot of error checking yet so be carefull.

# I hope it serves a lot of people.

##

# Get the necessary files... YOU NEED cybercash.inc. It defines the 
# functions used
# in this script.

require("cybercash.inc");

# Turn off error reporting. For some reason, php still reports an 
# error when it on although everything work fine...

error_reporting("1");

# You'll want to query all of your ccstuff form the db for security...

mysql_connect("$DBHost","$DBUser","$DBPass");

# Your query string here...
$result = mysql("$database","SELECT * from db");

$oid = mysql_result ($result, 0, invoiceid);
$price = mysql_result ($result, 0, total);
$ccnumber = mysql_result ($result, 0, ccnumber);
$ccexp = mysql_result ($result, 0, ccexpire);
$name = mysql_result ($result, 0, shipname);
$address1 = mysql_result ($result, 0, address1);
$address2 = mysql_result ($result, 0, address2);
$city = mysql_result ($result, 0, city);
$state = mysql_result ($result, 0, state);
$zip = mysql_result ($result, 0, zip);


# Now format the variables for CyberCash...
# Replace all strings with spaces with pluses...
$name = ereg_replace(" ","+",$name);

if ($address2):
    $address = "$address1 $address2";
  else: 
    $address = "$address1";
endif;

$address = ereg_replace(" ","+",$address);
$city = ereg_replace(" ","+",$city);
$state = ereg_replace(" ","+",$state);

# I redefined my variables for clarity on this example. You don't really 
# need this step.
$oid = "$oid";

# Timestamp isn't required for some reason...

#$timestamp = "199908251358";
$price = "usd+$price";
$ccnum = "$ccnumber";
$ccexp = "$ccexp";
$name = "$name";
$address = "$address";
$city = "$city";
$state = "$state";
$zip = "$zip";
$country = "USA";

# generate the message that needs to be sent to cybercash (CPI)
$cpi = gencpi($ccnum,$ccexp,$name,$address,$city,$state,$zip,$country);
if (!$cpi) rpterror("Error from gencpi()");

# generate the msg that needs to be sent to cybercash (MO)
$mo = genmo($oid,$price,"%OA");
if (!$mo) rpterror("Error from genmo()");

# combine CPI & MO message blocks
$msg = "CPI=$cpi&MO=$mo";

if (!cryptmsg($msg)) rpterror("Error from cryptmsg()");

# retrieve the MAC, Sesion key, and the encrypted message
$fd = fopen($CRYPToutfile, "r");
while ($buffer = fgets($fd, 4096)) {
  if (!$mac) $mac = $buffer;
  else if (!$sessionkey) $sessionkey = $buffer;
  else if (!$encryptedmessage) $encryptedmessage = $buffer;
}
fclose($fd);

# Delete temp files.
unlink($CRYPTinfile);
unlink($CRYPToutfile);

#get some sorta msg
$args = genmsg($mac,$sessionkey,$encryptedmessage);
if (!$args) rpterror("Error from genmsg()");


# remote host definitions
$rhost = "cr.cybercash.com";
$prgm = "/cgi-bin/directcardpayment.cgi";
#$url = "$rhost";
#$url .= "$prgm";
#$url .= "/$merchant_id";

$length = strlen($args);

# generate another message that includes ($args) and wraps it in the headers
$msg = "POST $prgm/$merchant_id HTTP/1.0\n";
$msg .= "User-Agent: CCMCK-$MCKversion\n";
$msg .= "Content-type: application/x-www-form-urlencoded\n";
$msg .= "Content-length: $length\n";
$msg .= "\n";
$msg .= "$args";

# Ok, now that we have the message built, lets send it off to Cybercash.
#$cbnet = fsockopen($rhost,80, &$errno, &$errstr, 30);
$cbnet = fsockopen($rhost,80);
if (!$cbnet) {
  rpterror("CyberCash connection failure: $errstr ($errno)");
#  die;
}
else {
  fputs($cbnet, $msg);
  while(!feof($cbnet)) {
    for($i=1;$i<=9;$i++) {
      if ($i == 8) {
        $response = fgets($cbnet,4096);
      }
      else {
       fgets($cbnet,1024);
      }
    }


  fclose($cbnet);
  }
}

# $response = sndsocket($msg);
# mail ("flint@netsolutionsllc.com","Response from CC","$response","From:server@netsolutionsllc.com");
if (!$response) {
  rpterror("Error: no data recieved");
  die;
}


# remove white space from response
$response = chop($response);

# URL-decode the response
$response = urldecode($response);

# minor tweak, PHP doesn't like 'session-key'
$response=ereg_replace("session-key","sessionkey",$response);

# break up the message
parse_str($response);

# remove more white space
$sessionkey=chop($sessionkey);
$mac=chop($mac);
$message=chop($message);

$mac=ereg_replace(" ","+",$mac);
$message=ereg_replace(" ","+",$message);

# write out to a temp file
$DECRYPTinFD = fopen($DECRYPTinfile, "w");
fwrite($DECRYPTinFD,$merchant_key,strlen($merchant_key));
fwrite($DECRYPTinFD,"\r\n",strlen("\r\n"));
fwrite($DECRYPTinFD,$sessionkey,strlen($sessionkey));
fwrite($DECRYPTinFD,"\r\n",strlen("\r\n"));
fwrite($DECRYPTinFD,$mac,strlen($mac));
fwrite($DECRYPTinFD,"\r\n",strlen("\r\n"));
fwrite($DECRYPTinFD,$message,strlen($message));
fwrite($DECRYPTinFD,"\r\n",strlen("\r\n"));
fclose($DECRYPTinFD);

$DECRYPTcommand = "$DECRYPTexec -f $DECRYPTinfile > $DECRYPToutfile";

# attempt to decrypt the message
exec($DECRYPTcommand);

# grab results from the temp file
$fd = fopen($DECRYPToutfile, "r");

while ($buffer = fgets($fd, 4096)) {
#   echo $buffer;
  if (!$ccres) $ccres = $buffer;
  else $ccres .= $buffer;
}
# echo $ccres;

fclose($fd);

# delete temp files
unlink($DECRYPTinfile);
unlink($DECRYPToutfile);

parse_str($ccres);
#$response=ereg_replace("session-key","sessionkey",$response);
$POP = ereg_replace("pop.auth-code","authcode",$POP);
$POP = ereg_replace("pop.avs-code","avscode",$POP);
$POP = ereg_replace("pop.ref-code","refcode",$POP);
$POP = ereg_replace("pop.action-code","actcode",$POP);
parse_str($POP);

# This checks to see if it's approved or what. You can also add your
# AVS check here.
if ($MStatus == "success" OR $MStatus == "success-duplicate"):

# Tell it what to do here if it authorizes. This just forwards to a thank you message.

  Header("Location: ./complete.html");

else:

# If authrization fails, redirect to another page. Send the error codes with it
# for intepretation.

  Header("Location: ./error.html?errorcode=$MErrCode&avs=$avscode");
  
endif;

?>

Comments or questions?
PX is running PHP 5.2.17
Thanks to Miranda Productions for hosting and bandwidth.
Use of any code from PX is at your own risk.