Send order confirmation email after paypal order and issue refund

Posted on 2008-11-07
Last Modified: 2013-11-29
What I'm looking to  do is send a confirmation email after a paypal purchase has been made.  I'm looking at using paypal NVP for this.

I also need the ability to issue a refund to a customer after they have purchased it.

How can I determine the user successully completed the payment on paypal?  Please provide code samples.
Question by:AngryLoop
    LVL 34

    Expert Comment

    by:Beverley Portlock
    There is a lot of documentation over at PayPal about this, but in essence for Web Payments (Standard)...

    1. You need a database table that stores a transaction number and the customer's details

    2. You need to generate a button to allow the purchase to be made at paypal

    3. You need a "callback" script that paypal will use to contact you. This script uses the transaction number to look up details in the database or to send emails as appropriate. It will need 3 urls - one for paypal to got to for a successful transaction, one for a failed transaction and an address for a callback to pass transaction NVP stuff to. I'm assuming that the account is set up at paypal.

    The following code will generate a "Buy now" button. You need to pass a description, a cost and a transaction number to it. It returns a small form that you embed in your webpage.

         // Generates the code necessary to make a tiny form for paypal payments
         // This is a single payment button containing one cost
         function makeButton( $descrip, $value, $email="", $imagePath = "", $transNum="", $partNumber=0 ) {

              $ppBusinessEmail = "your paypal login";
              $ppReturnUrl = "http://where to come back to after paypal finishes OK";
              $ppCancelUrl = "http://where to come back to after paypal rejects the transaction";
              $ppReturnUrl = "http://the location of your call back script";

              $des = addslashes( $descrip );
              $val = floatval($value );
              $img = ( $imagePath != "" ) ? $imagePath : "";

              if ( $this->testMode )
                   $txt  = noEcho("<form action='' method='post' />");
                   $txt  = noEcho("<form action='' method='post' />");

              if ( $transNum != "" )
                   $txt .= noEcho("<input type='hidden' name='invoice' value='$trans' />");

              $txt .= noEcho("<input type='hidden' name='cbt' value='Return to website' />");
              $txt .= noEcho("<input type='hidden' name='cmd' value='_xclick' />");
              $txt .= noEcho("<input type='hidden' name='business' value='$ppBusinessEmail' />");
              $txt .= noEcho("<input type='hidden' name='undefined_quantity' value='1' />");
              $txt .= noEcho("<input type='hidden' name='item_name' value='$des' />");
              $txt .= noEcho("<input type='hidden' name='item_number' value='$transNum' />");
              $txt .= noEcho("<input type='hidden' name='amount' value='$val' />");
              $txt .= noEcho("<input type='hidden' name='currency_code' value='GBP' />");
              $txt .= noEcho("<input type='hidden' name='country' value='GB' />");
              $txt .= noEcho("<input type='hidden' name='email' value='$email' />");
              $txt .= noEcho("<input type='hidden' name='return' value='$ppReturnUrl' />");
              $txt .= noEcho("<input type='hidden' name='cancel_return' value='$ppCancelUrl' />");
              $txt .= noEcho("<input type='hidden' name='notify_url' value='$ppNotifyUrl' />");
              $txt .= noEcho("<input type='image' border='0' name='submit' src='$img' alt='Buy $des' title='Buy $des' />");
              $txt .= noEcho("</form />");

              return $txt;


    Your call back script will need to extract the transaction ID and the amount and pass it to the following function which returns TRUE or FALSE. Based on this you can then send appropriate emails

         function verifyTransaction( $transId, $amount ) {
              $verified = false;

              $ppBusinessEmail = "your paypal login";

              $req = 'cmd=_notify-validate';

              foreach ($_POST as $key => $value) {
                   $value = urlencode(stripslashes($value));
                   $req .= "&$key=$value";

              // post back to PayPal system to validate
              $errstr = "";
              $errno  = 0;
              $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
              $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
              $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
              $fp = fsockopen ('ssl://', 443, $errno, $errstr, 30);

              // Typical return values from an IPN transaction
              // ---------------------------------------------
              // Key 'business'          value ''
              // Key 'payment_status'    value 'Completed'
              // Key 'mc_currency'       value 'GBP'
              // Key 'mc_gross'          value '12.34'
              // Key 'txn_type'          value 'web_accept'
              // Key 'txn_id'            value '119281018'
              // Key 'invoice'           value '98a56995d224db00f88e948f93a97a1b'
              // Key 'item_name'         value 'something'

              // assign posted variables to local variables
              $item_name        = $_POST['item_name'];
              $item_number      = $_POST['item_number'];
              $payment_status   = $_POST['payment_status'];
              $payment_amount   = $_POST['mc_gross'];
              $payment_currency = $_POST['mc_currency'];
              $txn_id           = $_POST['txn_id'];
              $receiver_email   = $_POST['receiver_email'];
              $payer_email      = $_POST['payer_email'];
              $invoice          = $_POST['invoice'];

              // Check the return values against known values
              if ($fp) {
                   fputs ($fp, $header . $req);
                   while (!feof($fp)) {
                        $res = fgets ($fp, 1024);
                        if (strcmp ($res, "VERIFIED") == 0) {

                             // check that txn_id has not been previously processed
                             // check the payment_status is Completed
                             // check that receiver_email is your Primary PayPal email
                             // check that payment_amount/payment_currency are correct
                             if ( $payment_status == "Completed" )
                                  if ( $payment_amount == $amount )
                                       if ( $payment_currency = "GBP" )
                                            if ( $receiver_email== $ppBusinessEmail )
                                                 if ( $item_number == $transId) {
                                                      $verified = true;
                             if (strcmp ($res, "INVALID") == 0) {
                                  // log for manual investigation

                   fclose ($fp);

              return $verified;

    In both of these functions there are variables that you will need to change. They all begin $pp

    Finally, here are typical values returned by PayPal

       Typical IPN Return Values from Paypal
        Info needed for typical storage and mail generation
        Key 'business'          value ''
        Key 'payment_status'    value 'Completed'
        Key 'mc_currency'       value 'GBP'
        Key 'mc_gross'          value '12.34'
        Key 'txn_type'          value 'web_accept'
        Key 'txn_id'            value '119281018'
        Key 'invoice'           value '98a56995d224db00f88e948f93a97a1b'
        Key 'item_name'         value 'something'
        Additional stuff
        Key 'test_ipn'          value '1'
        Key 'payment_type'      value 'instant'
        Key 'payment_date'      value '03:18:11 Sep. 28, 2008 PDT'
        Key 'address_status'    value 'confirmed'
        Key 'payer_status'      value 'verified'
        Key 'first_name'        value 'John'
        Key 'last_name'         value 'Smith'
        Key 'payer_email'       value ''
        Key 'payer_id'          value 'TESTBUYERID01'
        Key 'address_name'      value 'John Smith'
        Key 'address_country'   value 'United States'
        Key 'address_zip'       value '95131'
        Key 'address_state'     value 'CA'
        Key 'address_city'      value 'San Jose'
        Key 'address_street'    value '123, any street'
        Key 'receiver_email'    value ''
        Key 'receiver_id'       value 'TESTSELLERID1'
        Key 'residence_country' value 'US'
        Key 'item_number'       value 'AK-1234'
        Key 'quantity'          value '1'
        Key 'shipping'          value '3.04'
        Key 'tax'               value '2.02'
        Key 'mc_fee'            value '0.44'
        Key 'mc_gross1'         value '9.34'
        Key 'notify_version'    value '2.1'
        Key 'custom'            value 'xyz123'
        Key 'charset'           value 'windows-1252'
        Key 'verify_sign'       value 'AAOvSOENhhF2j-reEp5Iawri8OtSA8eSBN3Bg9CSXgWfaQKO4asFCWqI'
        Key 'address_country_code'   value 'US'

    Open in new window


    Author Comment

    What about issuing a refund?
    LVL 34

    Accepted Solution

    I don't have any code handy for that, but you create a transaction similar to the payment one but with an additional parameter parent_txn_id set to the transaction ID of the original transaction. I cannot recall if the amount has to be negative.

    Your callback will have additional variables (Search for "refund" on the following page)

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    Introduction HTML checkboxes provide the perfect way for a web developer to receive client input when the client's options might be none, one or many.  But the PHP code for processing the checkboxes can be confusing at first.  What if a checkbox is…
    Generating table dynamically is the most common issue faced by php developers.... So it seems there is a need of an article that explains the basic concept of generating tables dynamically. It just requires a basic knowledge of html and little maths…
    Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
    The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

    730 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now