In the example we are using a custom brewed e-commerce system built from scratch. Item data is retrieved from the database and stored in a session to be displayed on the item page.
- We can simply enter this snippet of code snippet right on the checkout page before the final payment page. In this example let’s say we insert this into a file called order-product-step-2.php. This will create a basic unstyled form onto a page with an Apply button posting to a file in a directory called /codeBookie/coupon_verify.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<?php /** * CodeBookie App * * This is * */ //Codebookie applet script will go here. ?> <form method="post" action="/codeBookie/coupon_verify.php"> <div id="order_box" class="codeBookieBox"> <h3>Have a coupon?</h3> <input type="text" id="couponCode" name="couponCode" class="codeBookieTextBox" placeholder="Enter coupon code"> <?php /** * * Until I figure out a better way to display the codeBookie message and/or better way to * integrate it into the checkout process, we're just going to do everything via * PHP Sessions */ if (isset($_SESSION['codeBookie'])): //if status is ok use the success css for the message if ($_SESSION['codeBookie']['status'] == "OK"): //if status is an error use the error css $css = 'codeBookieSuccess'; elseif ($_SESSION['codeBookie']['status'] == "ERROR"): $css = 'codeBookieError'; //error so it's safe to unset the codeBookie session endif; ?> <div id="codeBookieNotification" name="codeBookNotification" class="<?php echo $css;?>"> <?php echo $_SESSION['codeBookie']['message'];?> </div> <?php endif; ?> <button class="codeBookieSubmit">Apply</button> <div class="poweredByCodeBookie">Powered by CodeBookie All rights reserved 2017.</div> </div> </form> <?php //End Codebookie script ?> |
2. When the visitor types in the coupon code into the text box and hits apply, it will make a post call the coupon_verify.php file
Here is an example source of coupon_verify.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
<?php /** * * This script verifies the coupon that is provided by the client. * * 1. The script takes the coupon code inputted and sends it off to codeBookie's server to verify. * 2. If the coupon is verified, the discounted price is returned along with a checkout token that should be used later * verify the order and to confirm and finalize the order. * * If the coupon isn't verified return an error message and make sure nothing is discounted. * * 3. What happens after a code is verified is subjective to how your ecommerce platform is setup. Ideally you won't have to * modify any of the data in the database but just modify the session data. If everythign checks out create a new session data * storing all the coupon data to be used when redirected back to the order page. * * */ /** * * Start the Session * * For this retail site, data is transferred between the pages via sessions. Depending on how your ecommmerce * site is setup you may have your own way of retrieving the required data. * */ session_start(); //include the codeBookie api class require "codeBookie.php"; $codeBookie = new CodeBookie(); /** * * Get the couponCode provided by the visitor to the site. * */ $couponCode = $_POST['couponCode']; /** * /the session variable $_SESSION['orderinfo']['method_id'] is the unique product code that has been synced in CodeBookie * Depending on where you grab you SKU or unique product code that is synced with CodeBookie you would load it here. * */ $productCode = $_SESSION['orderinfo']['method_id']; /** * * Get the price of the item from the database or whereever your data source is. * In this example the price just happens to be loaded in $_SESSION['orderinfo']['price'] */ /** * Is $_SESSION['codeBookie'] exists and status is = OK, it means the discounted price has already been applied to * $_SESSION['orderinfo']['price']. In order to prevent the system from discounting the already discounted price we * have to set price back to the original price if they try to apply another coupon. */ if (isset($_SESSION['codeBookie'])): //set price from the codeBookie SESSION NOT $_SESSION['orderinfo']['price'] since the discount is already applied! $price = $_SESSION['codeBookie']['price']; else: //first time running or discount hasn't been applied yet so just grab it from the original session data. $price = $_SESSION['orderinfo']['price']; endif; /** * * now let's use included codeBookie class to make the API calls to the main CodeBookie API interface. */ $result = $codeBookie->getCoupon($couponCode,$productCode,$price); /** * * Depending on what the status is, set the session variables when we redirect back to the order page. */ switch ($result['status']) { /** * * Code is not valid */ case "NOT_VALID": $_SESSION['codeBookie']['status'] = "ERROR"; $_SESSION['codeBookie']['message'] = "Coupon Code has expired or no longer valid."; if (isset($_SESSION['codeBookie']['price'])): $_SESSION['orderinfo']['price'] = $_SESSION['codeBookie']['price']; endif; break; /** * * Coupon Code is invalid * */ case "ERROR": $_SESSION['codeBookie']['status'] = "ERROR"; $_SESSION['codeBookie']['message'] = "Coupon not found in system"; /** * if $_SESSION['codeBookie']['price'] is already set set the price back to the original price * since probably a invalid coupon got entered the second time */ if (isset($_SESSION['codeBookie']['price'])): $_SESSION['orderinfo']['price'] = $_SESSION['codeBookie']['price']; endif; break; /** * * Coupon is valid and information has been found! */ case "OK": $_SESSION['codeBookie']['status'] = "OK"; $_SESSION['codeBookie']['message'] = "Coupon verified and applied successfully."; $_SESSION['codeBookie']['checkout_token'] = $result['checkout_token']; $_SESSION['codeBookie']['discount_amount'] = $result['discountAmount']; $_SESSION['codeBookie']['new_price'] = $result['newPrice']; $_SESSION['codeBookie']['price'] = $result['price']; $_SESSION['codeBookie']['coupon_code'] = $result['coupon_code']; $_SESSION['codeBookie']['discount_type'] = $result['discount_type']; $_SESSION['codeBookie']['discount'] = $result['discount']; break; } /** * * This section where we change the pricing information in the cart before we redirect back to the main order page and final checkout. * Every ecommerce site is different so do what works best for you! */ ?> <script type="text/javascript"> window.location.href = "/order-product-step-2.php"; </script> |
3. Once this script has been called it will automatically redirect back to order-product-step-2.php. The file should contain a conditional statement to display the coupon information. We’ve done it like so beneath the rest of the order information on this particular website:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/** * * If codeBookie coupon is valid strikeout the original price * */ if ($_SESSION['codeBookie']['status'] == "OK"): $strikeout = 'codeBookieDiscounted'; else: $strikeout = null; endif; ?> <div id="device_info"> <span class="device_label">Your Price:</span><span class="price <?php echo $strikeout;?>">$<?php echo $_SESSION['orderinfo']['price'];?> <img id="help_price" src="graphics/help2.png" class="closed" /><span id="pricediv" style="text-align:left;"></span></span> </div> <?php if (isset($_SESSION['codeBookie']) && $_SESSION['codeBookie']['status'] == "OK"): ?> <div id="device_info"> <span class="device_label">Discount</span><span class="price"><?php echo $_SESSION['codeBookie']['discount'].$_SESSION['codeBookie']['discount_type'];?></span> </div> <div id="device_info"> <span class="device_label">Discounted Price</span><span class="price">$<?php echo $_SESSION['codeBookie']['new_price'];?> </span> </div> <div id="device_info"> <span class="device_label">You Save</span><span class="price">$<?php echo $_SESSION['codeBookie']['discount_amount'];?> </span> </div> <?php endif; ?> |
4. For this website we are using Paypal’s ExpressCheckout API to complete the payment. We need to send the codebookie checkout_token, coupon code and discount amount to Paypal to generate a token for checkout.
In our implementation we created a new condition to check if the codebookie session exists.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
/** * * CodeBookie verification. * If CodeBookie's coupon is valid, and a discount has been applied, * $_SESSION['codeBookie']['checkout_token'] should exist. We will create a new line on the payment page * and make it show as a discount coupon. Be sure to calculate the total discounted price if the coupon is valid! * */ if ($codeBookie != null): $codeBookie_checkoutToken = "::".$codeBookie['checkout_token']; $codeBookieNVP = "&L_PAYMENTREQUEST_0_NAME1=".urlencode("Coupon Code"). "&L_PAYMENTREQUEST_0_DESC1=".urlencode($codeBookie['coupon_code']). "&L_PAYMENTREQUEST_0_AMT1=".urlencode("-".$codeBookie['discount_amount']). "&L_PAYMENTREQUEST_0_QTY1=".urlencode("1"); $finalPrice = $codeBookie['new_price']; else: $codeBookieNVP = null; $codeBookie_checkoutToken = null; $finalPrice = $f['price']; endif; $fields = "USER=".urlencode($c['user']). "&PWD=".urlencode($c['pwd']). "&SIGNATURE=".urlencode($c['signature']). "&METHOD=".urlencode("DoExpressCheckoutPayment"). "&VERSION=".urlencode("124"). "&TOKEN=".urlencode($token). "&PAYERID=".urlencode($payerId). // "&L_PAYMENTREQUEST_0_NAME0=".urlencode($title). // "&L_PAYMENTREQUEST_0_DESC0=".urlencode($paypal_desc). "&L_PAYMENTREQUEST_0_NAME0=".urlencode($paypal_desc). "&L_PAYMENTREQUEST_0_AMT0=".urlencode($f['price']). "&L_PAYMENTREQUEST_0_QTY0=".urlencode("1"). "&PAYMENTREQUEST_0_PAYMENTACTION=".urlencode("Sale"). "&PAYMENTREQUEST_0_ITEMAMT=".urlencode($finalPrice). "&PAYMENTREQUEST_0_AMT=".urlencode($finalPrice). "&PAYMENTREQUEST_0_CURRENCYCODE=".urlencode("USD"). (LIVE ? "" : "&PAYMENTREQUEST_0_NOTIFYURL=".urlencode(self::get_paypal('ipn-url'))). "&PAYMENTREQUEST_0_CUSTOM=".urlencode( $f['imei']."::". $f['make']."::". $f['model']."::". $ci['email']."::". $f['saleID'].$codeBookie_checkoutToken). "&PAYMENTREQUEST_0_NOTETEXT=retail". $codeBookieNVP. // "&PAYMENTREQUEST_0_DESC=".urlencode($paypal_desc). "&PAYMENTREQUEST_0_INVNUM=".urlencode($f['saleID']); |
5. The codeBookieNVP variable can then get appended to the rest of the NVP values to be sent off to Paypal for payment. Please notice that we have $codeBookie_checkoutToken in the &PAYMENTREQUEST_0_CUSTOM so we can grab the checkout token later on when we post back to the IPN file.
6. Once the buyer has entered the payment information into Paypal, we have Paypal have the information send all the payment details back to our IPN file. The IPN file needs to be modified to check for the coupon details and information.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
//now check to see if the order has already been submitted into the system if ($codeBookieToken != null): //get the order information from codeBookie $cbResult = $codeBookie->getTokenInfo($codeBookieToken); //make sure the amount paid matches the discounted price that was stored on the codebookie server if ($cbResult['status'] == "OK"): if ($cbResult['discounted_price'] == $payment_amount): //looks good! $valid = true; $codeBookieOrder = true; endif; else: $valid = false; //something wrong. Uh oh. token is not valid //create a log here to log what went wrong! $output = print_r($cbResult,true); $handle = fopen(LOGS.'codeBookieOrderError','a'); fwrite($handle,$output."\n"); fclose($handle); $codeBookieOrder = false; endif; //CodeBookie is not set so just compare the payed amount to whatever is in the database else: //price matches if ($itemInfo['price'] == trim($payment_amount)): $valid = true; //price doesn't match. booo. else: $valid = false; endif; endif; |
7. If all the other logic checks out in the ipn file, such the transaction ID verification and it’s not a duplicate order then you can confirm the codebookie order to close this coupon and finalize it.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if ($codeBookieOrder == true): //confirm the codeBookie order $cbConfirm = $codeBookie->confirmOrder($codeBookieToken,$payer_email,$txn_id,$saleID,$itemInfo['ip_address']); //update the order with the confirmation ID $retailSales->confirmCodeBookie($saleID,$cbConfirm['confirmation_id']); //log the information it retail sales log $itemAudit->retailCouponUsed($saleID,$cbResult['original_price'],$cbResult['discount_amount'],$cbResult['coupon_code']); endif; |