'; echo 'ChurchMapped - Returns and Order'; echo ''; echo ''; echo ''; echo ''; echo ' '; echo ' '; echo ' '; echo ''; echo ''; echo ''; echo ''; #We have deliberately left the Facebook icon as ChurchMapped Marketplace Advert banner as this is similarly appropriate for the Returns and Orders page. echo ''; echo ' '; echo ''; echo ' '; #We have deliberately left the Twitter icon as ChurchMapped Marketplace Advert banner as this is similarly appropriate for the Returns and Orders page. echo ''; echo ''; echo ''; echo ''; #This ends the section. # This begins the BODY section. echo ''; include('/home/churchma/includes/churchmappedadverts.php'); }else{ #If there are indeed GET parameters, then we simply display the relevant information about the order that was just made. # The actual code begins below. echo ''; # This begins the section. echo ''; echo 'ChurchMapped - Returns and Order'; echo ''; echo ''; echo ''; echo ''; echo ' '; echo ' '; echo ' '; echo ''; echo ''; echo ''; echo ''; #We have deliberately left the Facebook icon as ChurchMapped Marketplace Advert banner as this is similarly appropriate for the Returns and Orders page. echo ''; echo ' '; echo ''; echo ' '; #We have deliberately left the Twitter icon as ChurchMapped Marketplace Advert banner as this is similarly appropriate for the Returns and Orders page. echo ''; echo ''; echo ''; echo ''; #This ends the section. # This begins the BODY section. echo ''; include('/home/churchma/includes/churchmappedadverts.php'); #This is used for the ChurchMapped adverts #We obtain the SHASIGN as we need this value to compare with our own sha1() calculation before granting the item. Note that where we change the hashing algorithm in the Barclays ePDQ back office (e.g. using SHA-512, &c), then we have to change this code as well. #It's worth recalling what STATUS means before proceeding with the rest of the code: # 5 - The authorisation has been accepted (this will be the case where the user has defined "Authorisation" in the Barclays Back Office). # 9 - Payment accepted (this will be the case where the merchant has defined "Sale" in the Barclays Back Office) # 0 - Invalid or incomplete payment method # 2 - Authorisation refused (this is the case where the financial institution has refused the payment). # 1 - This means the customer has pressed "CANCEL", and this is therefore a CANCEL/DENY order # 51 - This means the authorisation will be processed offline (Authorisation waiting). # 91 - This means the payment is currently processing and the data capture will be processed offline. # 52 - Authorisation not known (a technical problem arose during the authorisation process) # 92 - Payment is uncertain (a technical problem arose during the authorisation process) $_GET_upper_case = array_change_key_case($_GET, CASE_UPPER); #We use the method array_change_key_case to transform all the $_GET parameters to upper case. The reason we need to do this is two-fold. Firstly, because according to the documentation set out by Barclays ePDQ, Barclays have stated that sometimes they send the parameters back to us in lower case. Having experimented with this myself, it is actually worse than what they say - Barclays sometimes sends the parameters in mixed case (in my experience, this was usually with ORDERID which they sent to me as "orderID". Secondly, we create a copy of all the $_GET parameters (i.e. $_GET_upper_case instead of simply $_GET) because we might very well want to use the original $_GET parameters in their original form and case for other purposes. $SHASIGNTOCOMPARE = $_GET_upper_case['SHASIGN']; $SHAOUTPHRASE = "EasterEgg!!!2021"; #The SHAOUTPHRASE is the keyword we've elected to use to concatenate together with each parameter sent to us from Barclays. #We first arrange the $_GET parameters in alphabetical order, according to the requirements laid out by Barclays in their ePDQ documentation. $arrangedGetParameters = array(); #We create an array of the $_GET parameters that we are currently seeking. As of 20th May 2021, the parameters we have set to be returned to us in Barclays ePDQ system are as follows: #ORDERID #STATUS #PAYID #NCERROR #AAVADDRESS #In alpahbetical order, these are: #AAVADDRESS #NCERROR #ORDERID #PAYID #STATUS #Because PHP arrays bear some similarity to a hashmap in other languages, we can arrange the various GET parameters sequentially with the confidence that the order will be maintained. In doing this, we can also be assured that the parameters will be listed in alphabetical order, which is necessary to ensure the integrity of the order and that it was not tampered with. if($_GET_upper_case['STATUS'] == 9){ #This is the case where the payment has been accepted $arrangedGetParameters[] = $_GET_upper_case['AAVADDRESS'] . "="; $arrangedGetParameters[] = $_GET_upper_case['NCERROR'] . "="; $arrangedGetParameters[] = $_GET_upper_case['ORDERID'] . "="; $arrangedGetParameters[] = $_GET_upper_case['PAYID'] . "="; $arrangedGetParameters[] = $_GET_upper_case['STATUS'] . "="; #We list the $_GET parameters in alphabetical order because it is necessary to compare the SHASIGN sent to us from Barclays. $SHAOUTSIGN = 'AAVADDRESS=' . $_GET_upper_case['AAVADDRESS'] . $SHAOUTPHRASE . 'NCERROR=' . $_GET_upper_case['NCERROR'] . $SHAOUTPHRASE . 'ORDERID=' . $_GET_upper_case['ORDERID'] . $SHAOUTPHRASE . 'PAYID=' . $_GET_upper_case['PAYID'] . $SHAOUTPHRASE . 'STATUS=' . $_GET_upper_case['STATUS'] . $SHAOUTPHRASE; $SHAOUTSIGNHASHED = sha1($SHAOUTSIGN); $SHAOUTSIGNHASHEDANDCAPITALISED = strtoupper($SHAOUTSIGNHASHED); #The following line of code - namely, the "echo "echo SHA-SIGNS ARE EQUAL AND THEREFORE TRANSACTION IS VALID" and $SHAOUTSIGNHASHEDANDCAPITALISED" - is just for testing purposes. We should remove it in production code. if($SHAOUTSIGNHASHEDANDCAPITALISED == $SHASIGNTOCOMPARE){ #We use the sha1() function on the SHAOUT sign we create. *** Note that where we change the hashing algorithm, we need to change this too ***. #Commented out as of 19th JULY 2021. During testing we can uncomment it. echo "SHA-SIGNS ARE EQUAL AND THEREFORE TRANSACTION IS VALID"; # Commented out as of 19th JULY 2021. During testing we can uncomment it. echo $SHAOUTSIGNHASHEDANDCAPITALISED; echo 'VAT amount is: ' . $_SESSION['sessionVATAMOUNT']; echo 'Total amount is: ' . $_SESSION['sessionTOTALAMOUNT']; echo 'ChurchMapped is based at: ' . $_SESSION['sessionAddressOfSupplier']; echo 'Our registration number is: ' . $_SESSION['sessionVATRegistrationNumberOfSupplier']; #This is the VAT registration number of the Company, ChurchMapped Limited. echo 'The description of the items is:' . $_SESSION['sessionDescriptionOfItems']; #We use this section to obtain a value of $descriptionoftransactiontoinsert for later, as our aim is to insert one value into the row for description_of_transaction_in_array_format. The variable $descriptionoftransactiontoinsertforlater is taken from combining the values in the *table* basket_of_items_user_intends_to_buy: we combine the columns product_id_in_basket as well as price_of_product_in_basket. Because we are combining multiple columns, we need to use CONCAT_WS function. Because a user might have multiple items in their basket, we need a way of grouping multiple rows into one field. One way to do this is to use the GROUP_CONCAT function. Our function on MYSQL therefore looks like this: # SELECT CONCAT_WS('|', CONCAT('Product: ', product_id_in_basket), CONCAT("Price: ", GROUP_CONCAT(price_of_product_in_basket SEPARATOR ';'))) FROM basket_of_items_user_intends_to_buy WHERE personal_churchmapped_user_id_in_basket = X GROUP BY product_id_in_basket # We should store this in a stored procedure, using personal_churchmapped_user_id as the variable to use. We will call this stored procedure, PRICEANDPRODUCTIDTRANSACTIONDETAILSFORPERSONALUSER(). #Note that "X" is the ID of the ChurchMapped user. But what happens if this is business account rather than personal account? We can use an additional if(){} statement (in PHP, not MySQL) that determines whether this user is on a personal account or business account. If they are on a personal account, we call PRICEANDPRODUCTIDTRANSACTIONDETAILSFORPERSONALUSER(). If the user is on a business account, we use PRICEANDPRODUCTIDTRANSACTIONDETAILSFORBUSINESSUSER(). #Because this stored procedure (either PRICEANDPRODUCTIDTRANSACTIONDETAILSFORPERSONALUSER() or PRICEANDPRODUCTIDTRANSACTIONDETAILSFORBUSINESSUSER()) can return multiple rows (due to the fact a user might have multiple items in their basket), we are confronted with a question: we want to insert the transaction details into just one field, namely, description_of_transaction_in_array_format. Yet, the stored procedures might return multiple rows. Is there a way to get around this? Yes, there is. What we should do is that in the while(){} loop, we should concatenate the row with the already existing variable. Something like (psuedo-code): while($row = mysqli_fetch_assoc(result)){ $descriptionofrowtoinsert = $descriptionofrowtoinsert . ";" . $row['items_with_price_purchased_by_personal_churchmapped_user']} . Note that if the user is on a business account, the alias is items_with_price_purchased_by_business_churchmapped_user. Note that this could equivalent be rendered: while($row = mysqli_fetch_assoc(result)){ $descriptionofrowtoinsert .= ";" . $row['items_with_price_purchased_by_personal_churchmapped_user']} (emphasis on ".=") # This has the advantage of just being one line, e.g. "Product: 10|Price: 250;Product: 30|Price: 100". We can then insert it into the column description_of_transaction_in_array_format. The semi-colon is extremely helpful because it means if we want to retrieve the information later for the user, all we have to do is just explode the transaction with the semi-colon. However, it is possible for it to appear as ";Product: 10|Price: 250;Product: 30|Price: 100", the first character being a semi-colon. This is because of how the while loop operates. Whilst this may appear problematic, it is trivial to use a function such as substring() or ltrim() in PHP to remove this. Currently, as of 24th June 2021, we would prefer using ltrim. We can do something like ltrim(";", $descriptionoftransactiontoinsert). #UPDATE (19th JULY 2021): I've decided it might be best to store this in JSON format using PHP's json_encode() function. Therefore, we can do something like (psuedocode), while($row = mysqli_fetch_assoc(result)){ $detailsOfTransactionInArray[] = $row; } json_encode($detailsOfTransactionInArray); # Once again, don't forget to call mysqli_next_result() after each stored procedure. # Important note: Where a user purchases multiple items, this stored procedure returns one row with the product ID and the price of the item by the number of items the item was bought. For example, if a person bought product with ID 10 twice which has a price of 400, the row would appear as: "Product: 10|Price: 400;400". This is something to bear in mind. #UPDATE (23rd AUGUST 2021): We initially wanted to encode this all as a JSON array. However, it might just be best to simply add
between each using the implode() function, and then on retrieving the file, we use PHP's explode() function. mysqli_select_db($conn, "churchma_HISTORY_OF_TRANSACTIONS"); if($_SESSION['sessionTYPEOFUSER'] == "PERSONAL" && is_int($_SESSION['sessionCHURCHMAPPEDUSERID'])){ #We use the second qualifier of is_int($_SESSION['sessionCHURCHMAPPEDUSERID']) just in case to protect against SQL injection attacks. #Don't forget to sanitise user ID which is obtained from sessionCHURCHMAPPEDUSERID by ensuring it's a number. mysqli_next_result($conn); #We need this line of code to ensure that the stored procedure continues to work. $sessionVariableForChurchmappedUserId = $_SESSION['sessionCHURCHMAPPEDUSERID']; #We create a variable called $sessionVariableForChurchmappedUserId as it is easier to process for parsing (compare CALL PRICEANDPRODUCTIDTRANSACTIONDETAILSFORPERSONALUSER('$sessionVariableForChurchmappedUserId') to CALL PRICEANDPRODUCTIDTRANSACTIONDETAILSFORPERSONALUSER('$_SESSION['sessionCHURCHMAPPEDUSERID']') - you can see we run into issues regarding the quotation marks. NOTE (24th August 2021) - we no longer use this stored procedure. We instead use either RETRIEVEITEMSOFPERSONALUSER or RETRIEVEITEMSOFBUSINESSUSER. $queryForTransactionsDetails = "CALL RETRIEVEITEMSOFPERSONALUSER('$sessionVariableForChurchmappedUserId')"; #IMPORTANT NOTE: 24th August 2021 - The code below refers to $row['product_price']. Whilst this works for now and is suitable for 95%+ purposes, we might need to review this code in the situation where we allow merchants to charge personalised prices. One possible way of getting around this is to have a merchant add two items (or however many there is, corresponding to the number of discrimination points, i.e. n + 1, where n is at least 1 and represents the number of "rules" the merchant would like on their item) that are the same but charge different prices. We include() a short script (most likely using a switch statement) that first checks if the item retrieved from the database has a corresponding rule and then we use a regular expression to change the productid so that it instead shows the item with the affected rule, not the original item with no rule to whom would presumably be shown to the majority of users. $resultOfQueryForTransactionDetails = mysqli_query($conn, $queryForTransactionsDetails); $descriptionOfTransactionDetailsAsArray = array(); while($row = mysqli_fetch_array($resultOfQueryForTransactionDetails, MYSQLI_ASSOC)){ if($_SESSION['sessionOWNERCTY'] == "United Kingdom of Great Britain and Northern Ireland"){ #We use this section to determine if the user paid VAT. If they did, we need to store this in the database too. $descriptionOfTransactionDetailsAsArray[] = $row['product_name_english'] . ':' . number_format(($row['product_price']/100) * 1.2, 2) . " " . "sold by Merchant with ID" . " " . $row['merchant_id'] . "." . " " . "VAT charged on this item was:" . " " . number_format((($row['product_price']/100) * 1.2) - number_format(($row['product_price']/100) , 2), 2) . "." . "Total VAT charged was:" . " " . $_SESSION['sessionVATAMOUNT']; }else{ #This else clause concerns where the user is deemed as not living in the UK. In such instances, we do not charge VAT. Of course, we need to periodically review our code if our policy on VAT changes. $descriptionOfTransactionDetailsAsArray[] = $row['product_name_english'] . ':' . number_format(($row['product_price']/100) * 1.2, 2) . " " . "sold by Merchant with ID" . " " . $row['merchant_id'] . "." . " " . "VAT was not charged on this transaction. This could be because we deemed the customer as not living in the UK."; } } mysqli_next_result($conn); #We need this line of code to ensure that the stored procedure continues to work. $descriptionOfTransactionDetailsAsArray = implode("
", $descriptionOfTransactionDetailsAsArray); } elseif($_SESSION['sessionTYPEOFUSER'] == "BUSINESS" && is_int($_SESSION['sessionCHURCHMAPPEDUSERID'])){ #We use the second qualifier of is_int($_SESSION['sessionCHURCHMAPPEDUSERID']) just in case to protect against SQL injection attacks. mysqli_next_result($conn); #We need this line of code to ensure that the stored procedure continues to work. $sessionVariableForChurchmappedUserId = $_SESSION['sessionCHURCHMAPPEDUSERID']; $queryForTransactionsDetails = "CALL RETRIEVEITEMSOFBUSINESSUSER('$sessionVariableForChurchmappedUserId')"; $resultOfQueryForTransactionDetails = mysqli_query($conn, $queryForTransactionsDetails); while($row = mysqli_fetch_array($resultOfQueryForTransactionDetails, MYSQLI_ASSOC)){ if($_SESSION['sessionOWNERCTY'] == "United Kingdom of Great Britain and Northern Ireland"){ #We use this section to determine if the user paid VAT. If they did, we need to store this in the database too. $descriptionOfTransactionDetailsAsArray[] = $row['product_name_english'] . ':' . number_format(($row['product_price']/100) * 1.2, 2) . " " . "sold by Merchant with ID" . " " . $row['merchant_id'] . "." . " " . "VAT charged on this item was:" . " " . number_format((($row['product_price']/100) * 1.2) - number_format(($row['product_price']/100) , 2), 2) . "." . "Total VAT charged was:" . " " . $_SESSION['sessionVATAMOUNT']; }else{ #This else clause concerns where the user is deemed as not living in the UK. In such instances, we do not charge VAT. Of course, we need to periodically review our code if our policy on VAT changes. $descriptionOfTransactionDetailsAsArray[] = $row['product_name_english'] . ':' . number_format(($row['product_price']/100) * 1.2, 2) . " " . "sold by Merchant with ID" . " " . $row['merchant_id'] . "." . " " . "VAT was not charged on this transaction. This could be because we deemed the customer as not living in the UK."; } } } mysqli_next_result($conn); #We need this line of code to ensure that the stored procedure continues to work. $descriptionOfTransactionDetailsAsArray = implode("
", $descriptionOfTransactionDetailsAsArray); #Upon successful transaction, we insert the order into the table list_of_transactions, which is in the database HISTORY_OF_TRANSACTIONS. We also store the date of the transaction in the "YYYY-MM-DD" format, which we can do using the PHP date("Y-m-d H:i:s") function. mysqli_select_db($conn, "churchma_HISTORY_OF_TRANSACTIONS"); $stmt = $conn->prepare("INSERT INTO list_of_transactions(order_id, churchmapped_personal_user_id_if_available, status_of_transaction, ip_address_of_user, description_of_transaction_in_array_format, churchmapped_business_user_id_if_available, order_transaction_date_and_time) VALUES(?, ?, ?, ?, ?, ?, ?)"); #07:21 - Don't forget to include personal or business ID (whichever the case might be) $stmt->bind_param("siissis", $orderidtoinsert, $churchmappedpersonaluseridifavailabletoinsert, $statusoftransactiontoinsert, $ipaddressofusertoinsert, $descriptionoftransactiontoinsert, $churchmappedbusinessuseridifavailabletoinsert, $ordertransactiondateandtimetoinsert); #siissis stands for "string, integer, integer, string, string, integer, string" according to the format of MYSQLI prepared statements. To clarify: # string (s) - $orderidtoinsert # integer (i) - $churchmappedpersonaluseridifavailabletoinsert # integer (i) - $statusoftransactiontoinsert # string (s) - $ipaddressofusertoinsert # string (s) - $descriptionoftransactiontoinsert # integer (i) - $churchmappedbusinessuseridifavailabletoinsert # string (s) - $ordertransactiondateandtimetoinsert $orderidtoinsert = $_SESSION['sessionOrderID']; #We use $_SESSION['sessionOrderID'] rather than $orderidtoinsert = $_GET_upper_case['ORDERID']; because if we used $_GET_upper_case['ORDERID'], a person could add fictitious order IDs to the HISTORY_OF_TRANSACTIONS database by manipulating the URL/URI. A session variable goes some way into preventing this. if($_SESSION['sessionTYPEOFUSER'] == "PERSONAL"){ #If the user is on a personal account, we use $churchmappedpersonaluseridifavailabletoinsert and set $churchmappedbusinessuseridifavailabletoinsert to NULL $churchmappedpersonaluseridifavailabletoinsert = $_SESSION['sessionCHURCHMAPPEDUSERID']; $churchmappedbusinessuseridifavailabletoinsert = NULL; }elseif($_SESSION['sessionTYPEOFUSER'] == "BUSINESS"){ #If the user is on a business account, we use $churchmappedbusinessuseridifavailabletoinsert and set $churchmappedpersonaluseridifavailabletoinsert to NULL $churchmappedbusinessuseridifavailabletoinsert = $_SESSION['sessionCHURCHMAPPEDUSERID']; $churchmappedpersonaluseridifavailabletoinsert = NULL; } $statusoftransactiontoinsert = "2"; $ipaddressofusertoinsert = $_SESSION['sessionIPAddress']; $descriptionoftransactiontoinsert = $descriptionOfTransactionDetailsAsArray; #We just need to state the variable here. The full equation is: $descriptionoftransactiontoinsert = json_encode($descriptionOfTransactionDetailsAsArray); UPDATE (24th August 2021) - We are no longer using json_encode. Instead, we join elements of the array together and concatenate it with "
". $ordertransactiondateandtimetoinsert = date("Y-m-d H:i:s"); $stmt->execute(); #We use this section to briefly create human-readable information about the transaction that will be included in the e-mail. We will do this with the aid of our stored procedure functions - CALL RETRIEVEITEMSOFPERSONALUSER and CALL RETRIEVEITEMSOFBUSINESSUSER (using whichever is applicable in the particular case) the implode() function, using

to combine the array into one so that it can be directly plonked into the e-mail. Don't forget to account for VAT and we do this with an if(){} statement that checks for $_SESSION['sessionOWNERCTY'] == "United Kingdom of Great Britain and Northern Ireland". $descriptionOfTransactionInHumanReadableFormat = array(); #We create an array called $descriptionOfTransactionInHumanReadableFormat. How this will work is that we iterate through each row and add each row to this array. Then later we implode this with "

" and this will be included in the e-mail itself. The

has the effect of creating a space within each row in the e-mail, reflecting different items. #We have to account for the different kinds of user - PERSONAL or BUSINESS. if($_SESSION['sessionTYPEOFUSER'] == "PERSONAL"){ #This is for the situation where the user is on a PERSONAL account. $queryForHumanReadableInformationAboutTransaction = 'CALL RETRIEVEITEMSOFPERSONALUSER(' . $_SESSION['sessionCHURCHMAPPEDUSERID'] . ')'; #We call RETRIEVEITEMSOFPERSONALUSER in the case of a PERSONAL user. We can be assured that this is secure because we have already cast this to an integer above. $resultOfQueryForHumanReadableInformationAboutTransaction = mysqli_query($conn, $queryForHumanReadableInformationAboutTransaction); #Here we execute the MySQL statement relating to wanting to obtain human-readable information to be included in the e-mail. if($_SESSION['sessionOWNERCTY'] == "United Kingdom of Great Britain and Northern Ireland"){ #This if(){} statement determines the situation where the user is found to be living in the UK. In this case, we calculate VAT on each row by dividing the row price by 100 (because on the database it is stored as a multiple of 100, per the requirements of Barclays) and then multiplying by 1.2 (the 1.2 is the standard VAT rate). However, in future editions, we will likely have to amend this code because some items might be zero-rated for VAT purposes. while($row = mysqli_fetch_array($resultOfQueryForHumanReadableInformationAboutTransaction ,MYSQLI_ASSOC)){ $descriptionOfTransactionInHumanReadableFormat[] = $row['product_name_english'] . ":" . " " . "£" . number_format(($row['product_price']/100) * 1.2, 2) . " " . "VAT charged:" . number_format((($row['product_price']/100) * 1.2) - number_format(($row['product_price']/100) , 2), 2); #We grab the name of the product (in English) and the product price and we multiply by 1.2 because this is the standard VAT rate and we assume that this applies to all items. However, note that in a future revision of our code, we might have to amend this. Furthermore, in the event we allow multiple currencies, we might have to amend this code further. Currently, we only allow transactions in British Pound Sterling (GBP). } }else{ #This section is for where a user is not living in the UK - we do not charge VAT in such instances. while($row = mysqli_fetch_array($resultOfQueryForHumanReadableInformationAboutTransaction ,MYSQLI_ASSOC)){ $descriptionOfTransactionInHumanReadableFormat[] = $row['product_name_english'] . ":" . " " . "£" . number_format(($row['product_price']/100) , 2) . " " . "VAT charged: " . "£0.00"; #We grab the name of the product (in English) and the product price and we do not multiply by 100 because we determine that they are not based in the United Kingdom based on sessionOWNERCTY not being equal to United Kingdom of Great Britain and Northern Ireland. However, note that in a future revision of our code, we might have to amend this. Furthermore, in the event we allow multiple currencies, we might have to amend this code further. Currently, we only allow transactions in British Pound Sterling (GBP). } } } elseif($_SESSION['sessionTYPEOFUSER'] == "BUSINESS"){ #This is for the situation where the user is on a BUSINESS account. $queryForHumanReadableInformationAboutTransaction = 'CALL RETRIEVEITEMSOFBUSINESSUSER(' . $_SESSION['sessionCHURCHMAPPEDUSERID'] . ')'; # We call RETRIEVEITEMSOFBUSINESSUSER() in the case of a BUSINESS user. We can be assured that this is secure because we have already cast this to an integer above. $resultOfQueryForHumanReadableInformationAboutTransaction = mysqli_query($conn, $queryForHumanReadableInformationAboutTransaction); #Here we execute the MySQL statement relating to wanting to obtain human-readable information to be included in the e-mail. if($_SESSION['sessionOWNERCTY'] == "United Kingdom of Great Britain and Northern Ireland"){ #This if(){} statement determines the situation where the user is found to be living in the UK. In this case, we calculate VAT on each row by dividing the row price by 100 (because on the database it is stored as a multiple of 100, per the requirements of Barclays) and then multiplying by 1.2 (the 1.2 is the standard VAT rate). However, in future editions, we will likely have to amend this code because some items might be zero-rated for VAT purposes. while($row = mysqli_fetch_array($resultOfQueryForHumanReadableInformationAboutTransaction ,MYSQLI_ASSOC)){ $descriptionOfTransactionInHumanReadableFormat[] = $row['product_name_english'] . ":" . " " . "£" . number_format(($row['product_price']/100) * 1.2, 2) . " " . "VAT charged:" . number_format((($row['product_price']/100) * 1.2) - number_format(($row['product_price']/100) , 2), 2); #We grab the name of the product (in English) and the product price and we multiply by 1.2 because this is the standard VAT rate and we assume that this applies to all items. However, note that in a future revision of our code, we might have to amend this. Furthermore, in the event we allow multiple currencies, we might have to amend this code further. Currently, we only allow transactions in British Pound Sterling (GBP). } }else{ while($row = mysqli_fetch_array($resultOfQueryForHumanReadableInformationAboutTransaction ,MYSQLI_ASSOC)){ $descriptionOfTransactionInHumanReadableFormat[] = $row['product_name_english'] . ":" . " " . "£" . number_format(($row['product_price']/100) , 2) . " " . "VAT charged: " . "£0.00"; #We grab the name of the product (in English) and the product price and we do not multiply by 100 because we determine that they are not based in the United Kingdom based on sessionOWNERCTY not being equal to United Kingdom of Great Britain and Northern Ireland. However, note that in a future revision of our code, we might have to amend this. Furthermore, in the event we allow multiple currencies, we might have to amend this code further. Currently, we only allow transactions in British Pound Sterling (GBP). } } } #In the e-mail message down below, we do: $descriptionOfTransactionInHumanReadableFormat = implode("
", $descriptionOfTransactionInHumanReadableFormat). This creates a list of each transaction together with the price. Immediately below, we should refer to the total amount of the purchase, which we can get from referencing $_SESSION['sessionTOTALAMOUNT'], and total VAT charged, which we can get simply from referencing $_SESSION['sessionVATAMOUNT'] $descriptionOfTransactionInHumanReadableFormat = implode("

", $descriptionOfTransactionInHumanReadableFormat); if(mysqli_affected_rows($conn) > 0){ #Be sure to echo a statement here to inform the user that they should check their junk mail for correspondence from us following this transaction. require('/home/churchma/entitlements/grantentitlements.php'); #This include file manages providing the user with what they are entitled to after paying. Note that because we are calling this file mid-way through this file, we cannot use any header() function within grantentitlements.php. We use require as opposed to include because the user is absolutely entitled to what they have purchased. We use die() to handle any unusual errors and ask the user to inform us their order ID. If we look into the database and see that an order was indeed made, we will seek to manually provide them their entitlement. $ordertoinsert is *not* user-generated content. $to = $_SESSION['sessionVisibleEMAIL']; #In the production server, we must always try to filter the email to ensure it is in fact a genuine email. This is because, as David Powers notes, any form of user-input is a security risk. We therefore use the FILTER_VALIDATE_EMAIL() function in PHP. An example of using this function is seen below: # $email = "$_SESSION['sessionVisibleEMAIL']"; # if (filter_var($email, FILTER_VALIDATE_EMAIL)) { # echo("$email is a valid email address"); # } else { # echo("$email is not a valid email address"); # } if(filter_var($to, FILTER_VALIDATE_EMAIL)){ $to; #If $to, which is equated to the session variable $_SESSION['sessionVisibleEMAIL'], is an email, we simply state it here and proceed. } else{ unset($to); #If we find that $_SESSION['sessionVisibleEMAIL'] is not an email, we unset $to (effectively destroying the variable), thereby preventing the mail() function from being abused. } $subject = "Thank you for your custom on ChurchMapped!" . " " . "Order ID:" . " " . $_SESSION['sessionOrderID']; #The session variables to be included in the body of the email sent in the mail() function are: $_SESSION['sessionVisibleCIVILITY'] (Civility), $_SESSION['sessionVisibleFIRSTNAME'] (First Name), $_SESSION['sessionVisibleSURNAME'] (Surname), $_SESSION['sessionVisibleEMAIL'] (Email address), $_SESSION['sessionTOTALAMOUNT'] (Total amount), $_SESSION['sessionVATAMOUNT'] (VAT amount), $_SESSION['sessionOrderID'] (Order ID). #For testing purposes, we use the variable $_GET_upper_case['ORDERID']. However, in production-code we should use $_SESSION['sessionOrderID'] because it is slightly more secure (in other words, because $_GET_upper_case['ORDERID'] is taken from the address bar, it is susceptible to user tampering). #We use this for the logo to be included later in the HTML email (yes, quite extensive code just for an image, eh?). $path_of_the_logo = "https://www.churchmapped.com/churchmappedlogo.png"; $type = pathinfo($path_of_the_logo, PATHINFO_EXTENSION); $contentofimage = file_get_contents($path_of_the_logo); $image64 = "data:image/" . $type . ';base64,' . base64_encode($contentofimage); #UPDATE (19th JULY 2021): The picture doesn't seem to be included for some reason. #Remove $_GET_upper_case['ORDERID'] later. In production, we should use $_SESSION['sessionOrderID'] in its place. # Don't forget to show all items in the user's basket in the email, together with amount spent and VAT. Refer to grantentitlements.php . UPDATE: This has been done as of 24th August 2021 $message = '
' . '
' . '


'. 'Dear' . ' ' . '' . $_SESSION['sessionVisibleCIVILITY'] . ' ' . $_SESSION['sessionVisibleFIRSTNAME'] . ' ' . $_SESSION['sessionVisibleSURNAME'] . ',' . '' . '

' . 'Thank you so much for your order with the reference ' . ' ' . $_SESSION['sessionOrderID'] . '

These were the items you ordered, together with the VAT charged if applicable:' . $descriptionOfTransactionInHumanReadableFormat . '

' . 'The total amount of VAT paid is:'. $_SESSION['sessionVATAMOUNT'] . '
' . 'The total amount of your order is:' . ' ' . $_SESSION['sessionTOTALAMOUNT'] . '
' . ' ' . 'Please keep this information for your records and when consulting us if needed. We\'re grateful for your custom and we hope you enjoy your purchase!' . '


' . 'Kind regards,' . '
'.' ChurchMapped Team.' . '
The social network that aspires to do better ❤
' . '
See our terms and conditions here.| See our privacy policy here.| Visit ChurchMapped here.
' . 'ChurchMapped® Limited is a registered company in England and Wales. Our company number is 12329590 and our registered office is at 27 Old Gloucester Street, London, WC1N 3AX, United Kingdom. We are on the register of data fee payers courtesy of the Information Commissioner\'s Office (ICO) and our data protection registration number is ZA603587. Our VAT number is 340128834.
'; $headers = array(); #This array contains the headers for the email. $headers[] = "Content-Type: text/html; charset=utf-8"; $headers[] = "From: Sales - ChurchMapped Team "; $headers[] = "Cc: Billings - ChurchMapped Team "; $headers = implode("\r\n", $headers); #This adds a \r\n to each line, which we need when sending mail. mail($to, $subject, $message, $headers);#The mail() function takes the following arguments, in this order: the address(es) of the recipient, the subject line, the message body, a list of other email headers (optional) and additional parameters (optional). David Powers notes that you should never incorporate user input into the fifth argument because it can be used to execute arbitrary script on the web server. #On 24th June 2021, we asked WebHostingUK to enable the mail() function on our server. This was granted the same day. Some web hosting companies disable the mail() function for many reasons, not least because it can enable spamming. #Warning from David Powers in his book PHP 7 Solutions - "Although email fields are the prime target for attackers, the destination address and subject line are both vulnerable if you let users change the value. User input should always be regarded as suspect. Always hard-code the destination address and subject line. Alternatively, provide a drop-down menu of acceptable values and check the submitted value against an array of the same values. # We also need to send an email to the seller, including instances where ChurchMapped Limited sells something. If there are multiple sellers, then we need to account for this in our code. # One way to do this is to declare an array, $listOfMerchantsUserHasBoughtFrom. We first try to determine if this is a personal account or business account. We then call either of the following two stored procedures - RETRIEVEITEMSOFPERSONALUSER() or RETRIEVEITEMSOFBUSINESSUSER() - depending on what the case might be. In the while(){} loop, we store the merchant id in the array $listOfMerchantsUserHasBoughtFrom. We also store the name of the product from the column product_name_english in the array $listOfProductsSoldByMerchant. We have to be really careful we get the organisation right but we can be relatively assured they will be safe because of how PHP handles arrays. Outside of this while(){} loop, we then use a foreach() loop and a SELECT query for the table business_user_details_on_churchmapped. The query would look something like this: "SELECT business_primary_email_address, business_email_address_where_transactions_are_sent_to FROM churchma_USERS_ON_CHURCHMAPPED.business_user_details_on_churchmapped WHERE business_churchmapped_user_id=" . $particularMerchant. We then run *another* while(){} loop and then use each email in the row in the "to" header in PHP's mail() function informing the merchant that a person has purchased one of their items. Because we are calling a stored procedure, don't forget to use mysqli_next_result($conn). #We should explicitly choose the database given the nature of our query mysqli_select_db($conn, "churchma_USER_DETAILS_ON_CHURCHMAPPED"); $listOfMerchantsUserHasBoughtFrom = array(); $listOfProductsSoldByMerchant = array(); $listOfPricesOfItems = array(); $amountDueToMerchant = array(); $amountTakenByChurchMappedLimitedAsTransactionFee = array(); #This is the amount taken by us in the form of a transaction fee. We currently charge a 5% transaction fee on all transactions. $transactionFee = 0.05; #We currently charge a 5% transaction fee. Where this changes, we need to change this too. if($_SESSION['sessionTYPEOFUSER'] == "PERSONAL"){ $queryToObtainDetailsOfPurchase = 'CALL RETRIEVEITEMSOFPERSONALUSER(' . $_SESSION['sessionCHURCHMAPPEDUSERID'] . ')'; $resultOfQueryToObtainDetailsOfPurchase = mysqli_query($conn, $queryToObtainDetailsOfPurchase); mysqli_next_result($conn); #We need to use this to ensure that the stored procedure does not cause strange behaviour. while($row = mysqli_fetch_array($resultOfQueryToObtainDetailsOfPurchase, MYSQLI_ASSOC)){ #Because of the way PHP manages arrays, we can be assured that the positions will be fixed and won't be moved. Don't forget to concatenate the "��" sign in the actual email. $listOfMerchantsUserHasBoughtFrom[] = $row['merchant_id']; $listOfProductsSoldByMerchant[] = $row['product_name_english']; $listOfPricesOfItems[] = number_format($row['price_of_product_in_basket']/100, 2); #We use the number_format() function to give the price on the database - stored in multiples of 100 because this is how Barclays ePDQ wants it - in a human-readable format in the form of (for example) "1.20" and "4.68" rather than "120" and "468" as it is in the database respectively. We show this to the merchant. $amountDueToMerchant[] = number_format(($row['price_of_product_in_basket']/100) - (($row['price_of_product_in_basket']/100)*$transactionFee), 2); #The amount due to the merchant is defined as the amount the merchant sold their item at minus the transaction fee we have charged. For example, if the price of the item is ��1.00 and we charge a 5% transaction fee, the amount the merchant receives is ��0.95 (defined by ��1.00 minus 5% of ��1.00 which is 0.05, giving ��0.95). $amountTakenByChurchMappedLimitedAsTransactionFee[] = number_format(($row['price_of_product_in_basket']/100)*$transactionFee, 2); #This line reflects the actual amount we as a company (CHURCHMAPPED LIMITED) have taken as a transaction fee. For example, if the merchant has charged ��1.00 on their item and we have a 5% transaction fee, the actual amount taken by us is ��0.05. $dateOfLastLoginByMerchant = $row['date_and_time_of_last_login_of_business']; #We need this line on each email to communicate to the merchant that this is a genuine email from ChurchMapped Limited and not a phishing email. } }elseif($_SESSION['sessionTYPEOFUSER'] == "BUSINESS"){ $queryToObtainDetailsOfPurchase = 'CALL RETRIEVEITEMSOFBUSINESSUSER(' . $_SESSION['sessionCHURCHMAPPEDUSERID'] . ')'; $resultOfQueryToObtainDetailsOfPurchase = mysqli_query($conn, $queryToObtainDetailsOfPurchase); mysqli_next_result($conn); #We need to use this to ensure that the stored procedure does not cause strange behaviour. while($row = mysqli_fetch_array($resultOfQueryToObtainDetailsOfPurchase, MYSQLI_ASSOC)){ #Because of the way PHP manages arrays, we can be assured that the positions will be fixed and won't be moved. Don't forget to concatenate the "��" sign in the actual email. $listOfMerchantsUserHasBoughtFrom[] = $row['merchant_id']; $listOfProductsSoldByMerchant[] = $row['product_name_english']; $listOfPricesOfItems[] = number_format($row['price_of_product_in_basket']/100, 2); #We use the number_format() function to give the price on the database - stored in multiples of 100 because this is how Barclays ePDQ wants it - in a human-readable format in the form of (for example) "1.20" and "4.68" rather than "120" and "468" as it is in the database respectively. We show this to the merchant. $amountDueToMerchant[] = number_format(($row['price_of_product_in_basket']/100) - (($row['price_of_product_in_basket']/100)*$transactionFee), 2); #The amount due to the merchant is defined as the amount the merchant sold their item at minus the transaction fee we have charged. For example, if the price of the item is ��1.00 and we charge a 5% transaction fee, the amount the merchant receives is ��0.95 (defined by ��1.00 minus 5% of ��1.00 which is 0.05, giving ��0.95). $amountTakenByChurchMappedLimitedAsTransactionFee[] = number_format(($row['price_of_product_in_basket']/100)*$transactionFee, 2); #This line reflects the actual amount we as a company (CHURCHMAPPED LIMITED) have taken as a transaction fee. For example, if the merchant has charged ��1.00 on their item and we have a 5% transaction fee, the actual amount taken by us is ��0.05. $dateOfLastLoginByMerchant = $row['date_and_time_of_last_login_of_business']; #We need this line on each email to communicate to the merchant that this is a genuine email from ChurchMapped Limited and not a phishing email. } } #We then use this area to finally email the merchant in question. $indexOfForEachLoop = 0; #We set an index outside of the foreach loop in order to get an idea of the current position of the foreach() loop. It will be incremented down below. foreach($listOfMerchantsUserHasBoughtFrom as $particularmerchant){ $queryToObtainMerchantEmail = "SELECT * FROM churchma_USERS_ON_CHURCHMAPPED.business_user_details WHERE business_churchmapped_user_id =" . $particularmerchant; $resultOfQueryToObtainMerchantEmail = mysqli_query($conn, $queryToObtainMerchantEmail); while($row = mysqli_fetch_array($resultOfQueryToObtainMerchantEmail, MYSQLI_ASSOC)){ #In this while(){} loop, we email the merchant notifying the user of the item that has been bought. In my view, we do not need to further validate whether the email address is in fact an email because this was already done at registration. We can safely set $to = $row['business_primary_email_address'] or $to = $row['business_email_address_where_transactions_are_sent_to']. By default, we set $to = $row['business_email_address_where_transactions_are_sent_to']. This is because in cases where a merchant gets a lot of transactions, they might want a dedicated email address or area where such emails are sent to so that they aren't flooded with emails from us. This is an optional measure. Therefore, we have to first detect if $row['business_email_address_where_transactions_are_sent_to'] is null. If it is, then we set $row['business_primary_email_address']. if($row['business_email_address_where_transactions_are_sent_to'] != NULL){ $to = $row['business_email_address_where_transactions_are_sent_to']; }else{ $to = $row['business_primary_email_address']; } $subjectOfEmailForMerchant = "Congratulations! Someone has made a purchase of one of your items/services:" . " " . $_SESSION['sessionOrderID']; #It is debatable whether the merchant should in fact be informed about the OrderID rather than just the customer knowing it. I've taken the view that the merchant should also be told, just in case they have any questions about their order. There isn't any other way, unless we have to create a new ID system, which is more complicated than it is worth. #We use this for the logo to be included later in the HTML email (yes, quite extensive code just for an image, eh?). $path_of_the_logo = "https://www.churchmapped.com/churchmappedlogo.png"; $type = pathinfo($path_of_the_logo, PATHINFO_EXTENSION); $contentofimage = file_get_contents($path_of_the_logo); $image64 = "data:image/" . $type . ';base64,' . base64_encode($contentofimage); #UPDATE (19th JULY 2021): The picture doesn't seem to be included for some reason. #Remove $_GET_upper_case['ORDERID'] later. In production, we should use $_SESSION['sessionOrderID'] in its place. # Don't forget to show all items in the user's basket in the email, together with amount spent and VAT. Refer to grantentitlements.php . $messageForMerchant = '
' . '
' . '


'. 'Dear' . ' ' . '' . $row['business_official_name'] . ',' . '' . '

' . 'Congratulations! Someone has made a purchase of one of your items, namely ' . ' ' . $listOfProductsSoldByMerchant[$indexOfForEachLoop] . ', which was sold for' . ' ' . '��' . $listOfPricesOfItems[$indexOfForEachLoop] . ' ' . 'excluding any applicable taxes such as VAT.' . ' ' . 'We have charged you/your organisation a transaction fee of' . ' ' . '��' . $transactionfee . ' ' . 'meaning the amount due to CHURCHMAPPED LIMITED is' . ' '. '��' . $amountTakenByChurchMappedLimitedAsTransactionFee[$indexOfForEachLoop] . ' ' . 'and the amount due to you/your organisation is:' . ' ' . '��' . $amountDueToMerchant[$indexOfForEachLoop] . '. Kindly note that we reserve the right to amend this information in the event a mistake is found, as stated in our Terms & Conditions.' . 'Please keep this information for your records and when consulting us if needed. Please promptly reply to this email to finances@churchmapped.com with the following information so that we can process transferring the funds to you/your organisation: Name of cardholder on card, account number, sort code and bank. As stated in our Terms & Conditions, which you agreed to, payments can take up to the end of one calendar month from the date you provide us with payment information/purchase is made by customer. For example, if a purchase is made/you reply to our email with the requested information on the 15th June, the latest you should expect payment is 31st July 2021. Please do not query us about payment until this time has passed. For cybersecurity reasons, we can only respond to emails we have of a business/organisation that we have on our database. We reserve the right to undertake additional security checks as well as steps to prevent money laundering. You can be assured this is a genuine email from CHURCHMAPPED LIMITED and not a phishing email because the last time you logged into our website was:' . ' ' . $dateOfLastLoginByMerchant . ' ' . 'Only ChurchMapped and you/your organisation will know this information. If this seems inaccurate, please ignore this email as it is possibly a phishing scam.' . ' ' . 'We\'re grateful for your presence on the ChurchMapped platform!' . '


' . 'Kind regards,' . '
'.' ChurchMapped Team.' . '
The social network that aspires to do better ❤
' . '
See our terms and conditions here.| See our privacy policy here.| Visit ChurchMapped here.
' . 'ChurchMapped��� Limited is a registered company in England and Wales. Our company number is 12329590 and our registered office is at 27 Old Gloucester Street, London, WC1N 3AX, United Kingdom. We are on the register of data fee payers courtesy of the Information Commissioner\'s Office (ICO) and our data protection registration number is ZA603587. Our VAT number is 340128834.
'; $headers = array(); $headers[] = "Content-Type: text/html; charset=utf-8"; $headers[] = "From: Finances - ChurchMapped Team "; $headers[] = "Cc: Billings - ChurchMapped Team "; $headers = implode("\r\n", $headers); #This adds a \r\n to each line, which we need when sending mail. mail($to, $subjectOfEmailForMerchant, $messageForMerchant, $headers); } $indexOfForEachLoop++; } #We finally clear the basket. We use a stored procedure to delete the items from the basket called EMPTYBASKETFORPERSONALUSER() or EMPTYBASKETFORBUSINESSUSER() (whichever the case may be depending on the type of the user). Don't forget the WHERE clause is important! Don't forget to call mysqli_next_result() too to ensure that stored procedures don't behave erratically. if($_SESSION['sessionTYPEOFUSER'] == "PERSONAL"){ #This is where the user is on a personal account. $sessionVariableForChurchmappedUserId = (int)$_SESSION['sessionCHURCHMAPPEDUSERID']; $queryToEmptyBasketForPersonalUser = "CALL EMPTYBASKETFORPERSONALUSER('$sessionVariableForChurchmappedUserId')"; mysqli_query($conn, $queryToEmptyBasketForPersonalUser); #This empties the basket for the personal user on ChurchMapped and concludes the transaction mysqli_next_result($conn); #We include this line to ensure the script continues to work, because there are issues with how MYSQL manages multiple stored procedures in one script. }elseif($_SESSION['sessionTYPEOFUSER'] == "BUSINESS"){ #This is where the user is on a business account. $sessionVariableForChurchmappedUserId = (int)$_SESSION['sessionCHURCHMAPPEDUSERID']; $queryToEmptyBasketForBusinessUser = "CALL EMPTYBASKETFORBUSINESSUSER('$sessionVariableForChurchmappedUserId')"; mysqli_query($conn, $queryToEmptyBasketForBusinessUser); #This empties the basket for the business user and concludes the transaction. mysqli_next_result($conn); #We include this line to ensure the script continues to work, because there are issues with how MYSQL manages multiple stored procedures in one script. } } elseif(mysqli_affected_rows($conn) == 0){ #We have to catch when a user refreshes the page. When they refresh the page, the order won't be repeated. If they have accidentally refreshed the page, then a download link (for example) won't appear. We therefore take the opportunity to communicate to the user that they should quote $orderidtoinsert so that we can look into the matter. echo "Something wrong appears to have happened. If you have ordered an item but it does not appear here - likely due to refreshing the page - please contact support@churchmapped.com so that the item or order can be sent to you. Please cite $orderidtoinsert in any such correspondence so that we can look into this matter"; } $stmt->close(); #This closes the connection. }else{ #This segment concerns where a transaction is successful but the SHASIGN does not match for whatever reason. This could be because of a sophisticated scam (e.g. a man-in-the-middle-attack) or merely because a user is just tampering with the URL/URI in the browser's address bar. In any event, each time it happens we should investigate this. #We will probably want to send an email to support@churchmapped.com upon every transaction is invalid incident just to be sure nothing is wrong. If the user is trying to scam us, we get their IP address and ban them :) $to = "support@churchmapped.com"; #We do not need to sanitise this email address as it is hardcoded. In the event that the SHASIGN doesn't match, we send an email to here. $subject = "Something seems to be wrong with:" . " " . "Order ID:" . " " . $_SESSION['sessionOrderID']; $message = "Dear ChurchMapped Team\r\nWe have noticed a suspicious order based on the SHASIGN not equating. Please look into this. Note: that they do not equate does not necessarily mean malicious activity - it could be due to innocent tampering with the address in the address bar. If it is malicious, it is likely a man-in-the-middle cyber attack. \r\n\r\n The order to look into is:" . " " . $_SESSION['sessionOrderID'] . "\r\n"; #In production code, we should address each user by their salutation, first name and surname, which we can retrieve from session variables. $headers = array(); #We send this in plain text to save on bandwidth - we are not communicating with the outside world but employees here at ChurchMapped. $headers[] = "Content-Type: text/plain; charset=utf-8"; $headers[] = "From: Sales - ChurchMapped Team "; $headers[] = "Cc: Billings - ChurchMapped Team "; $headers = implode("\r\n", $headers); #This adds a \r\n to each line, which we need when sending mail. mail($to, $subject, $message, $headers); # We also need to communicate something to the user (but not by mail because it would mean any time a URI is changed for innocent reasons, their inbox will be spammed with emails by us, which could also lead to suspicions of us being a spammer by a web hosting company we are with. echo "
Something seems to be wrong. Please contact support@churchmapped.com for assistance, citing" . " " . $_SESSION['sessionOrderID'] . " " . ": UNEQUAL" . "
"; } } elseif($_GET_upper_case['STATUS'] == 1){ #This is where the user has cancelled their order. echo 'We\'re sorry you cancelled your order! This is just a heads up that you still have the items in your basket in case you change your mind.'; # Note that because the user has cancelled their order, in my view, we do not need to check for the SHASIGN. #In a future version of this code, we should consider looking to incorporate abandoned cart analytics, so this is still useful. } elseif($_GET_upper_case['STATUS'] == 5){ #This is the situation where the merchant has defined "Authorisation" as the default operation code. # In my view, *we do* need to check for the SHASIGN in this section. } elseif($_GET_upper_case['STATUS'] == 2){ #This is the situation where the authorisation has been refused by the financial institution (e.g. insufficient funds, etc). The customer can retry the authorisation process after selecting another card or payment method. #Note that because the financial institution has rejected their order, in my view, we do not need to check for the SHASIGN. We will inform the user that they still have their items in their basket, otherwise, we give them the option of emptying their basket. #In my view, the customer should receive an email informing them the transaction did not go through. We should also insert a value into HISTORY_OF_TRANSACTIONS and insert a value of 1 (a reference to the primary key 0), which indicates rejected. #Note that because the financial institution has rejected their order, in my view, we do not need to check for the SHASIGN. echo "Your payment sadly did not go through. Not to worry! Your items are still in your basket. Please try again."; } elseif($_GET_upper_case['STATUS'] == 51){ #This is the situation where the online acquiring system is unavailable and the merchant has selected "Online but switch to offline in intervals when the online acquiring system is unavailable" (which we have currently done in the Barclays Back Office) . There is also another situation outlined in the Barclays ePDQ documentation - although not applicable to our current situation - which is where the merchant has selected that payments should always be processed offline (scheduled). Important note: although Barclays state that the option "Online but switch to offline in intervals when the online acquiring system is unavailable" is not suitable for merchants who only sell digital goods/services (which is mostly applied to us), we have nevertheless selected this option in the Back Office so as to not miss out on potential transactions. In this elseif() statement, we should notify the user that their transaction is currently processing and we will email them with further information when it arises. # We check for the SHASIGN if this is the STATUS code. } elseif($_GET_upper_case['STATUS'] == 52 || $_GET_upper_case['STATUS'] == 91){ # 52 is the situation where the Authorisation is not known. 92 is the situation where payment is uncertain. In both scenarios, a technical problem has arisen in either the authorisation or payment process, giving an unpredictable result. According to the documentation laid out by Barclays, "The merchant can contact the acquirer helpdesk to know the exact status of the payment or can wait until we have updated the status in our system. The customer should not retry the authorisation process since the authorisation/payment might have already been accepted". # In this situation, we should communicate to the user that they should contact support@churchmapped.com citing error code B52 or B91, as the case may be according to the relevant STATUS code ("B" is shorthand for Barclays). We do not check for the SHASIGN if this is the status code. } elseif($_GET_upper_case['STATUS'] == 92){ #This is the situation where payment is uncertain. We do not check for SHASIGN if this is the status code. echo 'Something wrong has happened. Your order was not made. Please contact ChurchMapped for assistance at support@churchmapped.com'; } elseif($_GET_upper_case['STATUS'] == 93){ #This is the situation where payment has been refused. In other words, a technical problem arose. In this section, we should probably echo/print a message to the user asking them to contact support@churchmapped.com for assistance. } } ?>