1521400; #--------------------------------------------------------------- # # Generated by ISControlISConfigCtrl # #--------------------------------------------------------------- # my $bCompleteOnTechnicalFailures = $::FALSE; my $bCompleteOnFinancialFailures = $::FALSE; my $bAuthorize = $::FALSE; my $bTestMode = $::FALSE; my $sGTime = '1711132723'; my $sSanity = '150a307f75997ac8ad671a57cbfb98e1'; my $sProcessScriptURL = 'https://online.sellerdeckpayments.com/'; my $sADF01 = '25005946'; my $sADF02 = 'fkghD7cC'; my $sADF03 = '16 1444327dde6a85c28afb82ed464a655a'; my $sADF04 = '0'; my $sADF05 = '2'; my $sADF06 = '2'; my $sADF07 = '0'; my $sADF08 = '0'; my $sADF09 = ''; my $sADF10 = 'SellerDeck Payments'; my $sProcessAdditionalFiles = 'ADF09'; my $sADFDump = '02010280000000B8000000005127020A0A6FD509BE051FFCFBCC5DD76166494241F07AD8A6F74B3F22146FD2E21F97428B1FF30428E0C4C20DC3B93DEA2CDA489AE81A529FC3C2A45222BB84381FAF93EE5D5775574852973B1F853527CAEA73159750F6161C3CEA18ED80624FBB77324D9740E71F415D811596DA8A9FB1A265FA14C065AA0721FE2900E78BAA2B5CBEBB7DE99E5A6EF7A14F71B98ECFC806B2576B6349800FA9D02343DC0730DE7AA5EAFD5082CC8DF9967A4A9DA3B164AAF7287F04B9ADF509D8BD91DAC95DCBFD124569FCE238165821DEC7CD387316C4DE5725802DEE17B74A6A5FF38D1C01D6FB8E7B166DF19BDFBAB6035B3838165821DEC7CD3879D5E6329E510FD47464CBD6F7143830CEA235075D780E916A4147C9ACC5374A7FC0DD9DB624AC57F11D6CE64495E4DE54ACCC4EB3188DBB26B494214E7B3EAE'; # #--------------------------------------------------------------- # # OCCeKashuScriptTemplate.pl - code part of OCC script # # Parts Copyright (c) SellerDeck Limited 2001 All rights reserved # # *** Do not change this code unless you know what you are doing *** # # Adapted from OCCAuthorizeNetScriptTemplate.pl by Bill Birthisel # Written by Mike Purnell # # This script is called by an eval() function and it will already # have the following variables set up: # # Expects: $::sOrderNumber - the alphanumeric order number for this order # $::nOrderTotal - the total for this order (stored in based currency format e.g. 1000 = $10.00) # %::PriceFormatBlob - the price format data # %::InvoiceContact - customer invoice contact information # %::OCCShipData - customer invoice shipping information # $::sCallBackURLAuth - the URL of the authorization callback script # $::sCallBackURLBack - the URL of the backup script # $::sCallBackURLUser - the URL of the receipt script # $::sPath - the path to the Catalog directory # $::sWebSiteUrl - the Catalog web site URL # $::sContentUrl - the content URL # $::sCartID - the cart id # # Affects: $::eStatus - the status of the transaction: # $::FAILURE - Failure # $::ACCEPTED - Accepted # $::REJECTED - Rejected # $::PENDING - Pending # $::sErrorMessage - error message if any # $::sHTML - the HTML to display # $::sRedirectURL - (optional) data for logging or # for redirect if implemented someday # # $Revision: 1 $ # #--------------------------------------------------------------- use strict; use HTML::Entities; # # This block of code isolates the plug-in scripts from version specific code that they have historically used # BEGIN my $sCartID; if (defined $::EC_MAJOR_VERSION) # EC version 6 or greater { $sCartID = $::sCartID; # Use the value setup by OrderScript.pl } else # Pre-version 6 { $sCartID = $::g_sCartId; # copy the global value } # END # This block of code isolates the plug-in scripts from version specific code that they have historically used # # # The OCC plug-in runs in pending mode. This script does not # perform the transaction. Rather, it forwards the customer to # the OCC site for completion. # $::eStatus = $::PENDING; # # constants # my $ALWAYS = 1; my $OPTION = 0; my $NOENCODE = 0; my $ENCODE = 1; # encode both bounce and redirect my $REDIRECT = 2; # encode redirect only my %VarTable; # substitution hash for template my %hashcode_input; # post values in a hash used when generating the signature my @aPropertiesToHash = qw( ekashu_3d_secure_verify ekashu_amount ekashu_amount_format ekashu_auto_confirm ekashu_callback_failure_url ekashu_callback_include_post ekashu_callback_success_url ekashu_card_address_editable ekashu_card_address_required ekashu_card_address_verify ekashu_card_email_address_mandatory ekashu_card_phone_number_mandatory ekashu_card_title_mandatory ekashu_card_zip_code_verify ekashu_currency ekashu_delivery_address_editable ekashu_delivery_address_required ekashu_delivery_email_address_mandatory ekashu_delivery_phone_number_mandatory ekashu_delivery_title_mandatory ekashu_description ekashu_device ekashu_duplicate_check ekashu_duplicate_minutes ekashu_failure_return_text ekashu_failure_url ekashu_hash_code_format ekashu_hash_code_type ekashu_hash_code_version ekashu_include_post ekashu_invoice_address_editable ekashu_invoice_address_required ekashu_invoice_email_address_mandatory ekashu_invoice_phone_number_mandatory ekashu_invoice_title_mandatory ekashu_locale ekashu_payment_methods ekashu_reference ekashu_request_type ekashu_return_text ekashu_seller_address ekashu_seller_email_address ekashu_seller_id ekashu_seller_key ekashu_seller_name ekashu_shortcut_icon ekashu_style_sheet ekashu_success_url ekashu_title ekashu_verification_value_mask ekashu_verification_value_verify ekashu_viewport); # # insert the OCC web site URL into the HTML template # $VarTable{$::VARPREFIX . 'OCC_URL'} = $sProcessScriptURL; # # build up a string of all of the values that must be passed to OCC # my $sHiddenValues; my $sRedirectData = $sProcessScriptURL; # # sprintf template for data form sent to the OCC # my $OCC_template = ''."\n"; my $POST_template = '%s%s=%s'; my $sMerchantID = $sADF01; my $sMerchantName = $sADF02; # # Parameter translation for verify options # sub TranslateOption { my $sInOption = shift @_; if ($sInOption eq "0") { return "true" } if ($sInOption eq "1") { return "false" } if ($sInOption eq "2") { return "check" } if ($sInOption eq "3") { return "strict" } return ""; } # # AddPostValues ($sPostSeparator, $sPostName, $sPostValue, $bAlways, $bEncode, $bAddToHash) # # adds a name/value pair to $sHiddenValues and $sRedirectData # sub AddPostValues { my ($sDelim, $sName, $sValue, $bAlways, $eEncode, $bAddToHash) = @_; if (!defined $bAddToHash) { $bAddToHash = $::TRUE; } if ($sValue || $bAlways) { my $sEncValue = $sValue; if ($eEncode) { # We want to encode the text for an HTML post, not for use in a URL # so just replace characters that are unsafe for use in HTML #$sEncValue = ACTINIC::EncodeText2 ($sValue, $::FALSE); encode_entities($sEncValue); } if ($eEncode == $REDIRECT) { $sHiddenValues .= sprintf ($OCC_template, $sName, $sValue); } else { $sHiddenValues .= sprintf ($OCC_template, $sName, $sEncValue); } if ($bAddToHash) { $hashcode_input{$sName} = ($REDIRECT == $eEncode) ? $sValue : $sEncValue; } $sRedirectData .= sprintf ($POST_template, $sDelim, $sName, $sEncValue); } } sub encode_base64 ($;$) { if ($] >= 5.006) { require bytes; if (bytes::length($_[0]) > length($_[0]) || ($] >= 5.008 && $_[0] =~ /[^\0-\xFF]/)) { require Carp; Carp::croak("The Base64 encoding is only defined for bytes"); } } use integer; my $eol = $_[1]; $eol = "\n" unless defined $eol; my $res = pack("u", $_[0]); # # Remove first character of each line, remove newlines # $res =~ s/^.//mg; $res =~ s/\n//g; $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs # # fix padding at the end # my $padding = (3 - length($_[0]) % 3) % 3; $res =~ s/.{$padding}$/'=' x $padding/e if $padding; # # break encoded string into lines of no more than 76 characters each # if (length $eol) { $res =~ s/(.{1,76})/$1$eol/g; } return $res; } # # order details # # Calculate the conversion factor for the currency # my $nFactor = 100; my $nNumDigits = $::PriceFormatBlob{"ICURRDIGITS"}; # read the currency format values if(defined $nNumDigits) { $nFactor = (10 ** $nNumDigits); } my $sCurrencyFormat = sprintf('%%d.%%0%dd', $nNumDigits); my $sConvertedAmount .= sprintf($sCurrencyFormat, $::nOrderTotal / $nFactor, $::nOrderTotal % $nFactor); # # Add the upload data signature - this is a light signature - just an SHA hash of the order number, amount and # factor with a fixed semi-secret "secret" # my $sUserKey = $::g_sUserKey; if ($sUserKey) { $sUserKey =~ s/([A-Fa-f0-9]{2})/pack("C",hex($1))/ge; my @PrivateKey = unpack('C*',$sUserKey); my ($sLength, $sDetails) = split(/ /, $sADF03); $sDetails =~ s/([A-Fa-f0-9]{2})/pack("C",hex($1))/ge; ActinicEncrypt::InitEncrypt(@{$$::g_pSetupBlob{PUBLIC_KEY_128BIT}}); $sDetails = ActinicEncrypt::DecryptSafer($sDetails, @PrivateKey); $sADF03 = substr($sDetails, 0, $sLength); # restore it's size to the original length } # # Supply the mandatory account info # AddPostValues('?', 'ekashu_seller_id', $sMerchantID, $ALWAYS, $ENCODE); AddPostValues('&', 'ekashu_amount', $sConvertedAmount, $ALWAYS, $NOENCODE); AddPostValues('&', 'ekashu_currency', $::PriceFormatBlob{SINTLSYMBOLS}, $ALWAYS, $ENCODE); AddPostValues('&', 'ekashu_seller_key', substr($sMerchantName,0,8), $ALWAYS, $NOENCODE); AddPostValues('&', 'ekashu_reference', $::sOrderNumber, $ALWAYS, $ENCODE); AddPostValues('&', 'ekashu_hash_code_type', 'SHA256HMAC', $ALWAYS, $NOENCODE); AddPostValues('&', 'ekashu_hash_code_version', '2.0.0', $ALWAYS, $NOENCODE); if ($bAuthorize) { # If PSP is in pre-authorise mode, do not auto confirm transactions AddPostValues ('&', 'ekashu_auto_confirm', 'true', $ALWAYS, $NOENCODE); } else { # PSP is not in pre-authorise mode so auto confirm transactions AddPostValues ('&', 'ekashu_auto_confirm', 'false', $ALWAYS, $NOENCODE); } my ($sFirstName, $sLastName); $sLastName = $::InvoiceContact{NAME}; # Start with one field for both names if ($sLastName =~ /^(.+)\s+(\S+)/) # is there a space in there { $sFirstName = $1; $sLastName = $2; } if (ACTINIC::IsPromptRequired(0,0)) { # Shown and mandatory AddPostValues ('&', 'ekashu_card_title_mandatory', 'true', $ALWAYS, $NOENCODE); } else { # Not shown or shown but not mandatory AddPostValues ('&', 'ekashu_card_title_mandatory', 'false', $ALWAYS, $NOENCODE); } # # Company name # AddPostValues('&', 'ekashu_seller_name', $$::g_pSetupBlob{COMPANY_NAME}, $ALWAYS, $NOENCODE); # # Security checks # AddPostValues ('&', 'ekashu_verification_value_verify', TranslateOption($sADF04), $ALWAYS, $NOENCODE); AddPostValues ('&', 'ekashu_card_address_verify', TranslateOption($sADF05), $ALWAYS, $NOENCODE); AddPostValues ('&', 'ekashu_card_zip_code_verify', TranslateOption($sADF06), $ALWAYS, $NOENCODE); no strict 'vars'; if (defined $sADF07) { my $n3DSMask = 4 | 16; # Maestro and Amex are always on if ($sADF07 eq '0') { $n3DSMask |= 1; } if ($sADF08 eq '0') { $n3DSMask |= 2; } AddPostValues ('&', 'ekashu_3d_secure_verify', $n3DSMask, $ALWAYS, $NOENCODE); } else { AddPostValues ('&', 'ekashu_3d_secure_verify', 'false', $ALWAYS, $NOENCODE); } use strict; # # Card address # AddPostValues ('&', 'ekashu_card_address_editable', 'false', $ALWAYS, $NOENCODE); AddPostValues ('&', 'ekashu_card_address_required', 'true', $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_title', $::InvoiceContact{SALUTATION}, $OPTION, $ENCODE); AddPostValues ('&', 'ekashu_card_first_name', $sFirstName, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_last_name', $sLastName, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_address_1', $::InvoiceContact{ADDRESS1}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_address_2', $::InvoiceContact{ADDRESS2}, $OPTION, $ENCODE); AddPostValues ('&', 'ekashu_card_city', $::InvoiceContact{ADDRESS3}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_state', $::InvoiceContact{ADDRESS4}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_zip_code', substr($::InvoiceContact{POSTALCODE}, 0, 10), $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_country', $::InvoiceContact{COUNTRY}, $OPTION, $ENCODE); #OPTION? AddPostValues ('&', 'ekashu_card_phone_number', $::InvoiceContact{PHONE}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_phone_number_type', 'Other', $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_card_email_address', $::InvoiceContact{EMAIL}, $ALWAYS, $ENCODE); $sFirstName = ''; $sLastName = $::g_ShipContact{NAME}; if ($sLastName =~ /^(.+)\s+(\S+)/) # is there a space in there { $sFirstName = $1; $sLastName = $2; } if (ACTINIC::IsPromptRequired(1,0)) { # Shown and mandatory AddPostValues ('&', 'ekashu_delivery_title_mandatory', 'true', $ALWAYS, $NOENCODE); } else { # Not shown or shown but not mandatory AddPostValues ('&', 'ekashu_delivery_title_mandatory', 'false', $ALWAYS, $NOENCODE); } AddPostValues ('&', 'ekashu_delivery_address_editable', 'false', $ALWAYS, $NOENCODE); AddPostValues ('&', 'ekashu_delivery_address_required', 'true', $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_address_is_card_address', ($::g_LocationInfo{SEPARATESHIP} eq '' ? 'true' : 'false'), $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_title', $::g_ShipContact{SALUTATION}, $OPTION, $ENCODE); AddPostValues ('&', 'ekashu_delivery_first_name', $sFirstName, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_last_name', $sLastName, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_address_1', $::g_ShipContact{ADDRESS1}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_address_2', $::g_ShipContact{ADDRESS2}, $OPTION, $ENCODE); AddPostValues ('&', 'ekashu_delivery_city', $::g_ShipContact{ADDRESS3}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_state', $::g_ShipContact{ADDRESS4}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_zip_code', substr($::g_ShipContact{POSTALCODE}, 0, 10), $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_country', $::g_ShipContact{COUNTRY}, $ALWAYS, $ENCODE); #OPTION? AddPostValues ('&', 'ekashu_delivery_phone_number', $::g_ShipContact{PHONE}, $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_phone_number_type', 'Other', $ALWAYS, $ENCODE); AddPostValues ('&', 'ekashu_delivery_email_address', $::g_ShipContact{EMAIL}, $ALWAYS, $ENCODE); # # URLs: # # AUTH - the URL to create the authorization blob # BACK - the URL to return to the Catalog checkout process # USER - the URL to the receipt script # # Make sure we call the post process with the authorization URL for nochex APC # my $sAPCCallBackURLAuth = $::sCallBackURLAuth; # # Must pass in ordernumber for APC callback processing # The ordernumber is required for authorisation # $sAPCCallBackURLAuth .= "AM=" . $::nOrderTotal; $sAPCCallBackURLAuth .= "&TO_EMAIL=" .$sMerchantID; $sAPCCallBackURLAuth .= "&ACT_POSTPROCESS=1"; # if ($bTestMode) { $sAPCCallBackURLAuth .= "&TM=1"; } else { $sAPCCallBackURLAuth .= "&TM=0"; } if ($bAuthorize) { $sAPCCallBackURLAuth .= "&PA=0"; } else { $sAPCCallBackURLAuth .= "&PA=1"; } my $useredirect = $::sCallBackURLUser; $useredirect =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; my $sAuthURLSuccess = $sAPCCallBackURLAuth . "&NOAUTH=1"; my $sAuthURLFailure = $sAPCCallBackURLAuth . "&NOAUTH=1&ERROR=1"; AddPostValues ('&', 'ekashu_success_url', $::sCallBackURLUser, $ALWAYS, $REDIRECT); AddPostValues ('&', 'ekashu_failure_url', $sAuthURLFailure, $ALWAYS, $REDIRECT); AddPostValues ('&', 'ekashu_return_url', $::sCallBackURLBack, $ALWAYS, $REDIRECT); AddPostValues ('&', "ekashu_include_post", "false"); AddPostValues ('&', "ekashu_callback_success_url", $sAPCCallBackURLAuth); AddPostValues ('&', "ekashu_callback_failure_url", $sAPCCallBackURLAuth); AddPostValues ('&', "ekashu_callback_include_post", "true"); AddPostValues ('&', "ekashu_duplicate_check", "error"); # make sure no duplicated transactions by navigating back in checkout AddPostValues ('&', "ekashu_duplicate_minutes", "60"); # default if ($sADF09 ne '') # if they specified a custom stylesheet { AddPostValues ('&', "ekashu_style_sheet", $sADF09); # custom stylesheet URL } AddPostValues ('&', "ekashu_title", $sADF10); # page title # # Calculate the signature here as we need all post values # # # Create and add the signature if needed # if ($sADF03 ne "") { # # Get the SHA package # eval { require Digest::SHA; # Try loading the SHA library import Digest::SHA 'hmac_sha256'; }; if ($@) { require DigestSHAPurePerl; import Digest::SHA::PurePerl 'hmac_sha256'; } my $sStringToSign; my $sSignature; # # Build hash of posted values, it must be the array of values joined by &-s but first sorted by key # foreach (@aPropertiesToHash) { if (exists $hashcode_input{$_}) { $sStringToSign .= $hashcode_input{$_} . "&"; } else { $sStringToSign .= "&"; } } $sStringToSign =~ s/&$//; # remove trailing & my $sHmac = hmac_sha256($sStringToSign, $sADF03); $sSignature = encode_base64($sHmac); LogData("\$sSignature = $sSignature"); AddPostValues ('&', 'ekashu_hash_code', $sSignature, $OPTION, $NOENCODE, $::FALSE); # add the signature, no need for it in %hashcode_input } # # add the OCC values to the template # $VarTable{$::VARPREFIX . 'OCC_VALUES'} = $sHiddenValues; # Set the submission URL based on whether we are in a test mode or not my $sEKashuURL = $sProcessScriptURL; $VarTable{$::VARPREFIX . 'EKASHU_SUBMIT_URL'} = $sEKashuURL; my $sLinkHTML = 'occlink.html'; if(defined $::g_pPaymentList) { $sLinkHTML = $$::g_pPaymentList{ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'})}{BOUNCE_HTML}; } @Response = ACTINIC::TemplateFile($::sPath . $sLinkHTML, \%VarTable); # build the file if ($Response[0] != $::SUCCESS) { $::eStatus = $::FAILURE; # return a plug-in error $::sErrorMessage = $Response[1]; return ($::SUCCESS); # always return success if the script runs } @Response = ACTINIC::MakeLinksAbsolute($Response[2], $::sWebSiteUrl, $::sContentUrl); if ($Response[0] != $::SUCCESS) { $::eStatus = $::FAILURE; # return a plug-in error $::sErrorMessage = $Response[1]; return ($::SUCCESS); # always return success if the script runs } $::sHTML = $Response[2]; # grab the resulting HTML # # process the test mode warning # my ($sTestDelimiter) = $::DELPREFIX . 'TESTMODE'; my ($sLiveDelimiter) = $::DELPREFIX . 'LIVEMODE'; # only include the test mode block if we are in test mode if ($bTestMode) { # remove the delimiter text $::sHTML =~ s/$sTestDelimiter//g; # remove the test mode warning blob (/s removes the \n limitation of .) $::sHTML =~ s/$sLiveDelimiter(.*?)$sLiveDelimiter//gs; } else { # remove the test mode warning blob (/s removes the \n limitation of .) $::sHTML =~ s/$sTestDelimiter(.*?)$sTestDelimiter//gs; # remove the delimiter text $::sHTML =~ s/$sLiveDelimiter//g; } $::sRedirectURL = $sRedirectData; # data for log or redirect return ($::SUCCESS); # # End of OCCeKashuScriptTemplate.pl # # # End of File