Real World PayPal IPN Paypal’s Instant Payment Notifications are GREAT* *Once You Actually Get Them to Work Paul Croubalian First Edition The name, “PayPal” is owned by PayPal (Nasdaq: PYPL) and is used within this text solely for ilustration and indentification purposes PayPal neither endorses nor approved that which is written herein The author has taken care in the preparation of this book, but makes no expressed or implied warranty of any kind The author assumes no responsibility for errors or omissions No liability is assumed for incidental or consequential damages in connection with or arising out of the use of the information or programs contained herein For information about buying this title in bulk quantities or for special sales opportunities (which may include electronic, print, or audio versions, content particular to your business, training goals, marketing focus, branding interests, or consulting) contact the author at Paul@PaulTheGhost.com Copyright © 2017 Paul Croubalian This publication is protected by copyright and permission must be obtained from the author prior to any reproduction, storage in a retrieval system, or tansmission by any means, electronic, mechanical, photocopying, recording, or any other means Contact the author for information regarding permissions ISBN (eBook): 978-1-988406-02-2 ISBN (print): 978-1-988406-04-6 ISBN (audioBook , as narrated by the author): 978-1988406-03-9 Contents Conventions used in this book What you will learn Just how “instant” is Instant? IPN vs PDT The IPN System, How it works Why you’re “sort of” Good to Go Who can use IPN Lets go play in the sandbox Details about Test Accounts Creating Buy Buttons Ways to NOT Test Buttons Customizing a Hosted Button The REAL way to test Hosted Buttons How to build a button from scratch Stored vs Custom Buttons Creating your listener Dissecting Listener.php PayPal’s IPN Simulator Debugging the listener Appendix: Variables and Values Variables for special PayPal features Individual items variables Payment transaction variables Shopping cart variables Recurring payment variables Automatic Billing variables Installment Plan variables PayPal checkout page variables Auto-fill PayPal checkout variables Instant Update API variables Variables for dimensions of individual items Reader Promotions About the Author Conventions used in this book Most text is written in this font Code samples, or anything relating to code is written in this font ProTip: ProTips offer hacks or shortcuts or just things to be careful of Watch for these Tips They can save you a ton of headaches Note: Notes are used to point something out that I consider important Watch for these too Sometimes, they just repeat something in the text I know people like to skim ;-) Bookmark Navigation, No Table of Contents The eBook use Bookmark navigation You can access the bookmarks (which are easier to use) from the top left corner of your device, or from the Table of Contents Three versions: eBook, Book, & AudioBook The eBook version uses capabilities found in next-generation readers, tablets, smartphones, and computers That means you can zoom in and out using the pinch-and-zoom method I increased font sizes so that you shouldn’t need to that on every page The print version has extra stuff in the Appendices It’s tough to click a link on a printed page Well, it’s easy, but doesn’t take you anywhere Both are available on Amazon If you bought the print book, you can get the eBook at a heavily discounted price The audio book version should be ready in June of 2017 Cheers What you will learn After reading this book, you will be able to actually use PayPal’s Instant Payment Notification system That may not sound like a lot It is Once it gets going, it goes on forever on its own IPN will make your life easier Once you get it going You’ll see orders and deposits run automatically Once you get it going You can connect everything through your server back end to make things seamless, automatic, and effortless Once you get it going Getting the darned thing going is another story altogether I wasted three solid weeks six months apart trying I spent months invoicing manually! That’s not ideal Documentation isn’t the greatest Until now, I couldn’t find anything that set out a repeatable process, let alone set one out in simple English That’s why I decided to write this book It helps that I’m a ghostwriter who’s specialty is demystifying tech I save you the headaches, aggravation, and Tourette’s style outbursts that accompanied me on this journey Instant Payment Notification (IPN) does pretty much what its name implies IPN notifies you (nearly) instantly of any actions people make on, to, or with your account That’s the first gotcha! There are many more I’ll share the ones that kicked me in the teeth IPN notifies you of any action A notification that somebody added something to a shopping cart is not the same thing as the notification that somebody actually bought that stuff Don’t laugh! It took me hours before I figured out why I had so many repeating notifications They can come in one right after the other Just that warning alone is worth the price of this book No worries, once you understand that, you can deal with it It’s better to get too much info than not enough You will be able to verify that the order actually came from PayPal You will know who bought how much of what, for how much and when Then you can fill the order You will learn how to use PayPal’s sandbox feature to build and test your notification system You will also learn how to build custom buttons on the fly You will know how to have your system send you an email synopsis of every notification You’ll also know how to turn those emails off You’ll learn how to generate a log of all notifications, busted up by month and day You’ll Learn how to make your system read the incoming notifications, ask for verification, and then act on the ones you need to act on PayPal will send info They will even confirm that it came from them They won’t the work for you Just how “instant” is Instant? Paypal goes to great lengths to tell you the system is not really “instant.” Okay, so they’re right But VVFN, “very, very fast notifications” doesn’t sound as cool IPN is plenty fast enough for most purposes It’s even fast enough for situations where the buyer is waiting for a download link I ran 1000 test buys The slowest one was 32 seconds No other test even came close to that The next slowest was 21 seconds Most, over 700, worked in less than seconds That super slow one may have been due to the bad weather, busy servers, or maybe my ISP was running slow Isn’t it funny how nowadays, 32 seconds seems like an eternity? I also include links to my web site where you can download the code we talk about here Those files are the actual code but in RTF format with color-coded notes They make things very easy That’s a drawback common to books and eBooks It isn’t easy to get stuff like code from the book to your site Those links fix that They’re regular text files in rich text format (RTF) Just save them as PHP when ready If you’re ready, so am I Let’s get to it You’ll have it up and running before lunch Note: All the examples and scripts available for download are in PHP with mySQL as the database You can easily morph them to your preferred poison, sorry, language PHP and mySQL combine to drive the internet Even Facebook started out as a LAMP stack (Linux, Apache, MySQL, PHP) I figured that was the best place to focus IPN vs PDT PayPal has two notification systems, IPN and PDT PayPal loves its acronyms We already learned that IPN was Instant Payment Notifications PDT stands for Payment Data Transfer Both use the Name Value Pair system, or NPV Yeah, PayPal really loves its acronyms NPV is fancy-pants talk It just means a variable name has a value associated to it No poop, Sherlock They’d be pretty useless otherwise It’s like back in grade school when we learned X=3 That’s a name-value pair too “X” is the name is the value ProTip: The trick for making this stuff work is in knowing which variable names PayPal sends and which values those names have That can be complicated or easy I’m Constructively Lazy so I found the easy way I’ll show it to you soon Back to the two notification systems You would think that the “Instant” one would be faster, right? Nope PDT is the real Instant one PDT fires off a notification the very moment a buyer buys There is no lag Not even a tiny lag of a few seconds They click, “Buy,” and boom, you have a notification zipping over to you You might be saying, “Yeah! That’s what I want! To heck with this IPN stuff Gimme PDT!!!!” Hold your horses First of all, they both get set up the same way Second, neither is well-documented Second, yes, PDT is faster We’re only talking seconds faster, though That extra speed comes at a cost, a Big One Capitals intended PDT sends a notification instantly That’s the problem Did you catch it? No? I’ll repeat it This time I’ll add some emphasis PDT sends a notification instantly That’s the problem That’s right, it only sends one Ouch! Miss it and you have an irate customer on your hands It can happen easily Double Ouch! I wish for you to have so many orders your server can’t handle them all The ones it can’t handle will give you grief On a not so happy note, your server can be down for maintenance just when a bunch of orders pop in More grief Much as I love the whole idea of One-and-Done This is not the place for it IPN sends the notification and waits to hear you got it Don’t answer and it will resend it That’s when “instant” is not all that instant at all IPN will continue sending the notification periodically for four days Better late than never There’s another problem with PDT It only sends payment notifications That might not sound too bad at all But, there’s great value to being to automate everything not just payments IPN lets you know about: ¾¾ Payments received: That includes Express Checkout and Adaptive Payments ¾¾ Credit card authorizations: Handy if your Buyer doesn’t have a PayPal account or prefers to use a credit or debit card ¾¾ eCheck payments as well as pending, completed, or denied situations ¾¾ New subscriptions It will even automatically assign user names and id for you, if you like ¾¾ New sign-ups or carts ¾¾ Cancelled subscriptions or carts ¾¾ Recurring payments: Those are related to subscrip- tions and installment plans They’re great Payments continue until either you or the buyer stops them The buyer just needs to click once ¾¾ Chargebacks, disputes, reversals, and refunds Okay, so maybe we don’t really want those Still, they’re a fact of life Once you have the info, you can whatever you want with it ¾¾ You can email an order confirmation ¾¾ You can email an up-sell pitch ¾¾ You can add them to your email list for future mar- keting ¾¾ You can update their info with the info from PayPal ¾¾ Update your customer lists ¾¾ Segregate your lists based on buying habits ¾¾ Update inventory ¾¾ Prepare a picking and/or packing slip ¾¾ Cut an order if you drop ship ¾¾ Issue a refund (not often, I hope) ¾¾ Update your accounting ¾¾ You can notify sales people of purchases by their customers ¾¾ You can update and assign sales to affiliates You have the data You can whatever you need or want to with the data once you have it Want the Speed of PDT with the reliability of IPN? No problem Implement them both Really, go ahead custom OPTIONAL Max 256 char Strictly a pass-through variable that buyers not see and PayPal does nothing with I think of it like PayPal passing me a note Put whatever you want in there a1 OPTIONAL The price for the first Trial Period For a free trial, use 0, otherwise enter the amount without a currency symbol Currency is handled by currency_code Every period in a subscription needs an a, p, and t value for amount, period, and definition of period I remember it by saying, “Subscriptions are apt.” A1 and A2 are for trials A3 is the actual subscription A1 can be a free trial, but a2 must have an associated cost p1 REQUIRED if a1 is set The duration of the first Trial Period Allowed values are dependent on the value of t1 t1 REQUIRED if a1 is set The units of the duration of the first Trial Period Valid Values are: ¾¾ D for days Values for p1 are from to 90 ¾¾ W for weeks Values for p1 are from to 52 ¾¾ M for months Values for p1 are from to 24 ¾¾Y for years Values for p1 are from to a2 OPTIONAL The price for the second Trial Period Enter an amount without a currency symbol Second trials cannot be free Currency is handled by currency_code Every period in a subscription needs an a, p, and t value for amount, period, and definition of period I remember it by saying, “Subscriptions are apt.” A1 and a2 are for trials A3 is the actual subscription p2 REQUIRED if a2 is set The duration of the second Trial Period Allowed values are dependent on the value of t2 t2 REQUIRED if a2 is set The units of the duration of the second Trial Period Valid Values are: ¾¾ D for days Values for p2 are from to 90 ¾¾ W for weeks Values for p2 are from to 52 ¾¾ M for months Values for p2 are from to 24 ¾¾ Y for years Values for p2 are from to a3 REQUIRED The price for the actual subscription Enter an amount without a currency symbol Currency is handled by currency_code Every period in a subscription needs an a, p, and t value for amount, period, and definition of period I remember it by saying, “Subscriptions are apt.” A1 and a2 are for trials A3 is the actual subscription p3 REQUIRED The duration of the actual subscription Allowed values are dependent on the value of t3 t3 REQUIRED The units of the duration for the actual subscription Valid Values are: ¾¾ D for days Values for p3 are from to 90 ¾¾ W for weeks Values for p3 are from to 52 ¾¾ M for months Values for p3 are from to 24 ¾¾ Y for years Values for p3 are from to src OPTIONAL Recurring payments Subscription payments go on indefinitely unless subscribers cancel their subscriptions before the end of the current billing cycle or you limit the number of times that payments happen You that with the src and srt variables srt OPTIONAL Number of times subscription payments recur Specify an integer with a minimum value of and a maximum value of 52 Valid only if you specify src=”1” sra OPTIONAL Reattempt on failure If a recurring payment fails, PayPal attempts to collect the payment two more times before canceling the subscription Valid Values are: ¾¾ - Do not reattempt failed recurring payments ¾¾ - Reattempt failed recurring payments before can- celing Default is For more information, see https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/html_example_subscribe#reattempted-payments no_note REQUIRED Hides the text box and the prompt where buyers can add a note For Subscribe buttons, always set it to yes , i.e no_note=”1” It’s like a double-negative custom OPTIONAL Max 256 char Strictly a pass-through variable that buyers not see and PayPal does nothing with I think of it like PayPal passing me a note Put whatever you want in there invoice OPTIONAL Max 127 char WORKS DIFFERENTLY for Subscribe buttons! User-defined field which must be unique with each subscription The invoice number is shown to subscribers with the other details of their payments modify OPTIONAL Subscription modification behavior control Allowed Values are: ¾¾ – (Default) Subscribers ca only to sign up for new subscriptions., ¾¾ - Subscribers can sign up for new subscriptions and modify their current subscriptions ¾¾ - Subscribers can only modify a current subscrip- tion For more information see https://developer.paypal.com/docs/classic/paypal-payments-stan- dard/integration-guide/html_example_subscribe#modify-subscription-button Error on PayPal Documentation: Well, maybe it’s just misleading Modify is touted as a great way to upgrade subscriptions It is, but only in very limited circumstances Modify does not take term (p# & t#) into account The customer can only raise the price by 20% maximum Going from monthly to annual plans will not work usr_manage OPTIONAL Set as usr_manage=”1” to have PayPal generate user names and initial passwords for subscribers There’s more to to make that work See https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/user_ names_passwords/ Automatic Billing variables set_customer_limit REQUIRED Buyers can enter maximum billing limits in a text box or choose from a list of maximum billing limits that you specify Valid values are: ¾¾ max_limit_own - your button displays a text box for buyers to enter their own maximums above a minimum billing limit that you set with the min_amount variable ¾¾ max_limit_defined - Display a dropdown menu of product options with prices to let buyers choose their maximum billing limits min_amount OPTIONAL The minimum monthly billing limit, if you have one Valid only if set_customer_limit = max_limit_own Installment Plan variables disp_tot OPTIONAL Displays the total payment amount to buyers during checkout Valid Values are: Y - Display the total N - Do not display the total Default is N option_index REQUIRED If the button offers a single plan, use 0, or use a number not used for option fields without prices, such as size and color If the button offers plan options, use the cardinal number of the option field, on0 through on9, with plan payment options Include option_index if the number for the single plan or options field is not option_select# REQUIRED The value attributes of os and option_select elements must match In other words, and by example, os5 goes with option_select5 If the button offers plan options, the value attribute of the radio button for plan option # The value attributes of both elements must match option_select#_name REQUIRED The text to add with option # Ex if you want “Pay in installments ,” next to option_select3, use option_select3_name=”Pay in Installments” option_select#_type REQUIRED Sets how plan # is paid Valid Values are: F - Pay in full, at checkout, E - Pay in equal periods, beginning at checkout or sometime later V - Pay in variable periods, beginning at checkout option_select#_am REQUIRED The amount of payment m for plan # If option_select#_type is E, this value applies to all payments in the plan Nothing to with AM as in time option_select#_pm REQUIRED The duration of payment m for plan # If option_select#_type is E, this value applies to all payments in the plan Nothing to with PM as in time option_select#_tm REQUIRED The units of time for payment period p of payment m for plan # Valid Values are: ¾¾ D for days Values for option_select#_pm are from to 90 ¾¾ W for weeks Values for option_select#_pm are from to 52 ¾¾ M for months Values for option_select#_pm are from to 24 ¾¾ Y for years Values for option_select#_pm are from to option_select#_nm REQUIRED Number of payments that are the same, in amount and duration, as this one ¾¾ If option_select#_type is F, set this value to ¾¾ If option_select#_type is E, set this value to the number of payments in the plan ¾¾ If option_select#_type is F and no subsequent payments are the same as this one, set this value to PayPal checkout page variables These are the variables that set how the checkout page looks and acts image_url OPTIONAL Max 1024 char The link to the file that is the 150x50-pixel image displayed as your logo in the upper left corner of the PayPal checkout pages It defaults to your business name if you have a PayPal Business account, or to your email address if you have PayPal Premier or Personal lc OPTIONAL Sets the locale of the checkout login or sign-up page Accepts a 2-letter code PayPal provides localized checkout pages for some countries and languages See Appendix B or https://developer.paypal.com/docs/classic/api/locale_codes/ no_shipping OPTIONAL Do not prompt buyers to provide their shipping address Valid values are (default) Prompt for an address, but not require one ¾¾ ¾¾ Do not prompt for an address ¾¾ Prompt for an address make it required return OPTIONAL Max 1024 char The link where PayPal will send people after they paid By default, PayPal redirects the browser to a PayPal webpage rm OPTIONAL only works with return The FORM METHOD used to send data to the link you set in the return variable Valid values are ¾¾ 0 (default) All shopping cart payments returm by the GET method ¾¾ The buyer’s browser is redirected to the return URL by the GET method, but no payment variables are included ¾¾ The buyer’s browser is redirected to the return URL by the POST method, and all payment variables are included cancel_return OPTIONAL Max 1024 char The link where PayPal will send people if they cancel checkout before completing their payments By default, PayPal redirects the browser to a PayPal webpage Auto-fill PayPal checkout variables These HTML variables are for filling out PayPal checkout pages automatically.You can specify information about buyers PayPal suggests that you include automatic fill-out variables with all of your payment buttons It’s a good idea Being consistent with address handling improves the checkout experience for both you and your buyers To determine how the checkout experience varies if you not pass in automatic fill-out variables, see https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/Appx_BillingShippingAddress/ (U.S Merchants Only) Note: When you pass in address_override=1 or tax or shipping variables, PayPal displays the values in the payment widget Also, PayPal hides the calculation widget, regardless of setting up shipping and tax rates in your Account Profile address1 OPTIONAL Max 100 char Line of Street Address address2 OPTIONAL Max 40 char Line of Street Address city OPTIONAL Max 40 char Buyer’s city of residence country OPTIONAL Max char Buyer’s country of residence Accepts two-letter code For codes see Appendix B or https://developer.paypal.com/docs/classic/api/country_ codes/#CountryCodes_id083SG0U0OY4 email OPTIONAL Max 127 char The Buyer’s email address first_name OPTIONAL Max 32 char The Buyer’s first name last_name OPTIONAL Max 32 char The Buyer’s last name lc OPTIONAL Accepts a two-letter code The language used for the billing information/log-in page only Default is US For valid values, see Countries and Regions Supported by PayPal on PayPal’s Site, or Appendix B charset OPTIONAL Sets the character set and character encoding for the billing information/log-in page on the PayPal website Also sets the same value for stuff that you send to PayPal by HTML button code Default is the language encoding settings in your account profile For valid values, see Setting the Character Set on PayPal’s site night_phone_a OPTIONAL Pulls in the area code for U.S phone numbers, or the country code for phone numbers outside the U.S Use only if absolutely neccessary This one has a very high creepy-factor night_phone_b OPTIONAL Pulls in the the 3-digit prefix for U.S phone numbers, or the entire phone numbers for numbers outside the US Use only if absolutely neccessary This one has a very high creepy-factor night_phone_c OPTIONAL Pulls in the 4-digit balance for U.S phone numbers Use only if absolutely neccessary This one has a very high creepy-factor state OPTIONAL Pulls in the U.S state where the buyer lives or the state/ province/district for many other countries zip OPTIONAL Max 32 char Pulls in the buyer’s postal code It’s called zip, but the code returned will be that of the supported country Instant Update API variables These variables are used in the back-and-forth between PayPal and your server’s listener file(s) Set up a payment for the Instant Update API Some Instant Update variables set up the Cart Upload to use your callback server Some are Required some are Optional Use as appropriate callback_url REQUIRED Max 1024 char The link to your listener This one is listed on PayPal documentation as Required, although semi-required would make more sense It’s required for Cart Upload Otherwise, it defaults to the link you wrote when you set up your account to use IPN Play it safe Consider it a Required variable at all times callback_timeout REQUIRED Accepts a single digit from to PayPal recommends This is the timeout in seconds for callback responses from your Instant Update callback server If you go over the timeout, PayPal uses the fallback values on the Review Your Payment page for tax, shipping, and insurance Important: Use values other than only when PayPal Support tells you to callback_version REQUIRED The version of the Instant Update API that your callback server uses Look at your IPN server log or the email generated after your test IPN, for its value (if you need it) fallback_tax_amount OPTIONAL Tax amount to use as a fallback, if the callback response times out fallback_shipping_option_name_x REQUIRED Max 50 char Name and label of shipping option x as a fallback, if the callback response times out For example, “Express days” You can include a maximum of 10 shipping options as fallbacks Substitute x with ordinal numbers, starting with Include one instance of this variable, with its index (x) set to If you include just one instance, include fallback_ shipping_option_is_default_x parameter with its index, x, set to and its value set to Valid values for x is from to fallback_shipping_option_amount_x REQUIRED Shipping amount for option x (x is a placeholder for the actual index) as a fallback Only if the response times out Valid values for x are from to fallback_shipping_option_is_default_x REQUIRED Sets shipping option x (with x a placeholder for the option’s index number) as the default fallback shipping option Used if the response times out Make sure you only set one shipping option as the default like this fallback_shipping_option_is_default_x =”1” Set all others to fallback_shipping_option_is_default_x =”0” Valid values are (no) and (yes) fallback_insurance_option_offered OPTIONAL Shows that insurance is offered Buyers can opt in to the insurance during checkout PayPal ignores this variable if fallback_insurance_amount is not set, or if fallback_insurance_amount’s value is less than or equal to Valid values are: ¾¾ - Insurance is offered and consumers can opt in to during checkout ¾¾ - Insurance is applied along with the transaction, if applicable The consumer will NOT have a choice to remove the insurance from the transaction amount fallback_insurance_amount OPTIONAL Insurance amount to use if the callback response times out Include the fallback_insurance_option_offered variable if you specify an insurance amount The fallback insurance amount applies to all shipping options that you specify Variables for dimensions of individual items Sometimes, you need to calculate shipping charges by using the dimensions of individual items in the shopping cart These variables let you that height_x OPTIONAL Height of item x where x is a placehoder for the item’s index Accepts only positive integers height_unit OPTIONAL Unit of measure for the values specified by the height_x values Use any value that makes sense to you, even “cubit.” PayPal passes the value to your callback server in callback requests width_x OPTIONAL Width of item x where x is a placehoder for the item’s index Accepts only positive integers width_unit OPTIONAL Unit of measure for the value specified by width_x Use any value that makes sense to you, even “cubit.” PayPal passes the value to your callback server in callback requests length_x OPTIONAL Length of item x where x is a placehoder for the item’s index Accepts only positive integers length_unit OPTIONAL Unit of measure for the value specified by length_x Use any value that makes sense to you, even “cubit.” PayPal passes the value to your callback server in callback requests Reader Promotions About the Author ... special PayPal features Individual items variables Payment transaction variables Shopping cart variables Recurring payment variables Automatic Billing variables Installment Plan variables PayPal. .. stands for Payment Data Transfer Both use the Name Value Pair system, or NPV Yeah, PayPal really loves its acronyms NPV is fancy-pants talk It just means a variable name has a value associated to. .. had that fake transaction been real It’s more accurate, and more useful, to say that PayPal charges fake fees against fake accounts for fake buyers that buy fake stuff For real ProTip: Create