Basket coding questions

Hi there,

I am looking to design a basket. I am using some code I have found but I have a couple questions!

This code is suggested:

<INPUT TYPE=HIDDEN NAME='cartId' VALUE='live'>
<INPUT TYPE=HIDDEN NAME='testMode' VALUE='0'>

It looks like this code suggests using both a LIVE basket and a TESTMODE basket. Would it not be best to code it as a TESTMODE first of all. Test it with test transactions. Then change the code to LIVE and delete the TESTMODE? Or is it standard practice to keep both LIVE and TESTMODE in the coding?!?

Secondly, CRYPT is encrypted. You may need to see this code first:

//** Build the crypt string plaintext **
$stuff = "VendorTxCode=" . $ThisVendorTxCode . "&";
$stuff .= "Amount=" . $ThisAmount . "&";
$stuff .= "Currency=" . $ThisCurrency . "&";
$stuff .= "Description=" . $ThisDescription . "&";
$stuff .= "SuccessURL=" . $MyServer . "completed.php&";
$stuff .= "FailureURL=" . $MyServer . "notcompleted.php&";

if ($ThisCustomerEmail) {
  $stuff .= "CustomerEmail=" . $ThisCustomerEmail . "&";
}
if ($ThisCustomerName) {
  $stuff .= "CustomerName=" . $ThisCustomerName . "&";
}
if ($ThisDeliveryAddress) {
  $stuff .= "DeliveryAddress=" . $ThisDeliveryAddress . "&";
}
if ($ThisDeliveryPostCode) {
  $stuff .= "DeliveryPostCode=" . $ThisDeliveryPostCode . "&";
}
if ($ThisBillingAddress) {
  $stuff .= "BillingAddress=" . $ThisDeliveryAddress . "&";
}
if ($ThisBillingPostCode) {
  $stuff .= "BillingPostCode=" . $ThisDeliveryPostCode . "&";
}
// new 2.22 fields
if ($ThisContactNumber) {
  $stuff .= "ContactNumber=" . $ThisContactNumber . "&";
}


	$stuff .= "ApplyAVSCV2=" . $ThisApplyAVSCV2 . "&";
	$stuff .= "Apply3DSecure=" . $ThisApply3DSecure . "&";
	$stuff .= "eMailMessage=Thankyou for your order from activegps.co.uk, we will dispatch your goods shortly&";
	$stuff .= "Basket=$pdBasket";

//print ($stuff);

Then stuff is encrypted:

 // ** Encrypt the plaintext string for inclusion in the hidden field **
$crypt = base64Encode(SimpleXor($stuff,$EncryptionPassword));

and then it is used to submit to the card transaction processing company:

<INPUT TYPE="hidden" NAME="Crypt" VALUE="<? echo($crypt); ?>"

What does this crypt do? Why is it encrypted? I am sure it is needed but what and why am I encrypting?!? Does it encrypt every field in the above code? Does it just supply a password to the card processing company? I have no idea what it does! And how do the card processing company decrypt it!?

Thanks for your help,

Matt.

  1. Seems rather silly to have two variables for the same purpose (live/test)… are you certain that’s what both of them do?

  2. SimpleXor isnt a default function, so we cant answer this question for you. It may be xor’ing the two strings bit by bit, and then base64 encoding them. Which… isnt really much of an encryption, tbh.

  1. I think that is what they do.

  2. I have found the function - so may be you could have a quick look:


/*  The SimpleXor encryption algorithm                                                                                **
**  NOTE: This is a placeholder really.  Future releases of VSP Form will use AES or TwoFish.  Proper encryption      **
**       This simple function and the Base64 will deter script kiddies and prevent the "View Source" type tampering    **
**      It won't stop a half decent hacker though, but the most they could do is change the amount field to something **
**      else, so provided the vendor checks the reports and compares amounts, there is no harm done.  It's still      **
**      more secure than the other PSPs who don't both encrypting their forms at all                                  */

function simpleXor($InString, $Key) {
  // Initialise key array
  $KeyList = array();
  // Initialise out variable
  $output = "";
  
  // Convert $Key into array of ASCII values
  for($i = 0; $i < strlen($Key); $i++){
    $KeyList[$i] = ord(substr($Key, $i, 1));
  }

  // Step through string a character at a time
  for($i = 0; $i < strlen($InString); $i++) {
    // Get ASCII code from string, get ASCII code from key (loop through with MOD), XOR the two, get the character from the result
    // % is MOD (modulus), ^ is XOR
    $output.= chr(ord(substr($InString, $i, 1)) ^ ($KeyList[$i % strlen($Key)]));
  }

  // Return the result
  return $output;
}

/* The getToken function.                                                                                         **
** NOTE: A function of convenience that extracts the value from the "name=value&name2=value2..." VSP reply string **
**     Works even if one of the values is a URL containing the & or = signs.                                      */

Matt.

I like how the coder couldnt decide if a string was an array of characters or not. (that was sarcasm, folks.)

that… is a strange way to do encrypting, though i suppose it works. Kind of. If you had a big enough key filled with random non repeating characters.
As for what it’s doing, it’d most likely just confuse you if i tried to explain what it was doing. Suffice it to say it’s hiding the values represented.

When you say:

“it’s hiding the values represented.”

do you mean all values with “stuff” in front of them?

So thats all the values in this code:


$stuff = "VendorTxCode=" . $ThisVendorTxCode . "&";
$stuff .= "Amount=" . $ThisAmount . "&";
$stuff .= "Currency=" . $ThisCurrency . "&";
$stuff .= "Description=" . $ThisDescription . "&";
$stuff .= "SuccessURL=" . $MyServer . "completed.php&";
$stuff .= "FailureURL=" . $MyServer . "notcompleted.php&";

if ($ThisCustomerEmail) {
  $stuff .= "CustomerEmail=" . $ThisCustomerEmail . "&";
}
if ($ThisCustomerName) {
  $stuff .= "CustomerName=" . $ThisCustomerName . "&";
}
if ($ThisDeliveryAddress) {
  $stuff .= "DeliveryAddress=" . $ThisDeliveryAddress . "&";
}
if ($ThisDeliveryPostCode) {
  $stuff .= "DeliveryPostCode=" . $ThisDeliveryPostCode . "&";
}
if ($ThisBillingAddress) {
  $stuff .= "BillingAddress=" . $ThisDeliveryAddress . "&";
}
if ($ThisBillingPostCode) {
  $stuff .= "BillingPostCode=" . $ThisDeliveryPostCode . "&";
}
// new 2.22 fields
if ($ThisContactNumber) {
  $stuff .= "ContactNumber=" . $ThisContactNumber . "&";
}


    $stuff .= "ApplyAVSCV2=" . $ThisApplyAVSCV2 . "&";
    $stuff .= "Apply3DSecure=" . $ThisApply3DSecure . "&";
    $stuff .= "eMailMessage=Thankyou for your order from activegps.co.uk, we will dispatch your goods shortly&";
    $stuff .= "Basket=$pdBasket";

Is this correct?

Would it not be better to encrypt each one individually?

Matt.

no, because that changes the value.

Let’s say you’re doing a simple replacement.

You want to encrypt “Smelly”, and “Cheese”
Your replacement index is “123456789”, and represents the number of letters a character should be shifted, repeating back on itself when needed.

So:
Encrypting them seperately, Smelly becomes Tohpqe, and Cheese becomes Djhixk.

Encrypting them together, “SmellyCheese” becomes TohpqeJpnfrh

Note that Cheese did not have the same hash.

ok - i get that - but what i was thinking was that

$crypt = base64Encode(SimpleXor($stuff,$EncryptionPassword));  

this seems to be encrypting $stuff

so this would suggest that
“VendorTxCode=” . $ThisVendorTxCode . “&”;
“VendorTxCode=” . $ThisVendorTxCode . “&”;
“Currency=” . $ThisCurrency . “&”;
“Description=” . $ThisDescription . “&”;
“SuccessURL=” . $MyServer . “completed.php&”;

etc.
etc.

are all encrypted. Since they all have:

$stuff =

and

$stuff .=

etc.

before them.

This suggests the encryption refers to about 20 odd encryptions!?

Do you understand my reasoning!? Is this wrong?

Matt

Yes, it’s wrong.

$a .= $b is one of PHP’s condensed operators, and reads as “Append to $a the string value of $b.”

Basically, the script takes all the variables to be sent, stuffs them into one big long string, and encrypts it.

oh - i see - how does the decrypter know where each string value starts and ends?

I will use this code to encrypt, thanks for your explanation.

Matt.

because of the delimiter - & - between each entry.

Encryptor slaps all values together with &'s between them, encodes the entire shebang.
Decryptor decrypts it, then segments it again on the &'s.

OK - thanks for that.

I have another question I have asked at SitePoint.com before but I have never received an answer. You seem like you ‘know your coding’… so, the problem is if all customer information is passed to the card processing company (customer name, telephone number, delivery address, email address, etc.).

then how do I post it to a MySQL database? The problem, which you might be aware of, is in the post you choose where which page to load next. All web baskets link direct to the card processing company which is on their server (like worldpay or sagepay) - but if you do this to my knowledge you cannot add anything to their card processing page coding it to add the customer details to a MySQL database!

So how do company’s get around this problem? I do not want to use JavaScript.

I need some code to say post this to this page (so I can add details to MySQL table) and go to that page (card processing web page on their server). Is this possible?

Matt.

Well #1: Never store CC data on your site. Ever. The legal implications of this are so vast you do not want to even come close to touching that - think about how many lawyers paypal or sagepay have on staff to handle privacy complaints and disputes.

#2: Easiest answer is “Store it before they click the checkout button”. Second easiest answer is have your checkout button pass the user to a page that stores the data, then constructs a hidden form and auto-submits it, Third easiest (though i might swap it with second) is use the pay-processing company’s API’s to catch the information as it comes back from them. Most pay processors have this ability (Paypal’s IPN, for example).

You don’t store the credit card locally. You send that information to the card processing company using [fphp]cURL[/fphp]. As I pointed out in your other thread, even if you do not intend to use ZenCart or Magento it would help you enormously to read their code - the answers to these questions are right there in their code.

And implying that most of the people here don’t know what they are doing is uncalled for. Many of us do. Many of us however aren’t willing to help someone who can’t be troubled to do some basic research but instead seems to want to be spoon fed answers. That may not be what you want but you starting to give off that vibe.

This checkout thing you keep asking questions about - that problem has been solved a few times already and the answers have been posted online for free. Read up on those answers and either use them or modify them to suit your specific needs. No one is going to type up and test a few hundred lines of code in a forum post though.

I know people cannot spend their time explaining detail. Pointing me to software packages is not a great response! I am designing it myself…half way through getting it done…just need some advice.

Cheers StarLion,

Matt.