Build Basic IPN Functionality

Issue #1 closed
Drew Angell repo owner created an issue

I have a PayPal IPN solution I built years ago that is a very simple, stand-alone PHP solution: https://github.com/angelleye/paypal-ipn-template

You can see what it provides or you here: http://sandbox.angelleye.com/paypal/ipn/admin

There is a general, raw log of the IPN data, and then you can also browse for specific things like orders, refunds, disputes, etc. and get a nicer looking details page for review.

We need to build this same sort of functionality into WordPress. I'd like to follow this plugin template for the structure of the plugin: https://github.com/tommcfarlin/WordPress-Plugin-Boilerplate

For the IPN processing, PayPal provides a basic template for the best way to handle it so that all types of IPN's will work: https://github.com/paypal/ipn-code-samples/blob/master/paypal_ipn.php

Comments (62)

  1. Drew Angell reporter

    I would like the angelleye_ namespace to be used for class names, CSS ruless, element ID's, etc, and the plugin name itself is: paypal-ipn-for-wordpress

  2. jignesh kaila

    Hello Andrew,

    Today I have started initial plugin skeleton development with naming convention and uploaded on development branch. Along with that I have reviewed "paypal-ipn-template" code.

    Thanks, Jignesh

  3. jignesh kaila

    Today I have reviewed your basic "paypal-ipn-template" code with more understanding. I have debug your code and understand code standard as you have follow in this.

    Monday I will start basic IPN class with member functions development in our development branch.

    Please let me know if any suggestion or thoughts for me.

  4. Drew Angell reporter

    The only thing I would say is that I know that IPN template solution I have is pretty rough. I built it a long time ago, and I never did any database normalization with it because I was just following a structure that PayPal had done with something similar. In this case I'd prefer a more normalized system (and I guess we'll just be using Custom Post Types anyway, so that'll take care of itself I think..??) Also, for example, there may be a better way to process all of the POST data. I was using that parse-data.php file to pull everything out individually.

    The point is, while I'd like the basic functionality of that tool to be applied here, I would expect this to be done "the WordPress way" and follow all standards accordingly.

    Just don't want you to try and copy that other thing so much that we follow bad standards or anything like that.

  5. jignesh kaila

    Perfect !

    According to WordPress standard best way to used Custom Post Types and Categories.

    I am going to create WordPress custom post type "Paypal IPN" name itself.

    WordPress generally used table like "prefix_posts" and "prefix_postmeta" two tables for managing all the post data, so I can follow same WordPress structure Is it fine? or Can we create custom tables with normalization?

    Let me know you suggestion for the same.

  6. Drew Angell reporter

    Yes, we're on the same page. Use WordPress structure. I want to avoid creating custom tables as much as possible. Thanks!

  7. jignesh kaila

    Thanks for the quick response !!

    Today I will work on create IPN Listener class and related member function and create Custom Post Types and Categories for store IPN response.

  8. jignesh kaila

    Today I have worked on below tasks:

    1. Custom Post Types and Categories register function.
    2. Create PayPal IPN helper class.
    3. Create Logger class for write log file(log.txt)

    I need your suggestion for ipn listener file name, Currently I have used file name "paypal-ipn-for-wordpress-ipn.php".

    Please Note: PayPal IPN helper class still in progress.

    Latest work uploaded to developer branch. Please review it and let me know, Can we are in right track?

  9. Drew Angell reporter

    I guess I'm a little confused why you need a separate file..?? The plugin template we started with should give you the majority of what you need doesn't it? I was thinking we would just have the paypal-ipn-for-wordpress.php be the primary plugin file, and that would be the name of the plugin: PayPal IPN for WordPress

  10. Drew Angell reporter

    I guess you're creating this extra file to be the file that PayPal's IPN would actually hit..?? I guess I was thinking we would end up registering a function within one of the existing classes to be used for the IPN handler.

    Either way, still not sure why we need this additional file a the root of the plugin..??

  11. Drew Angell reporter

    I'm not necessarily saying I won't accept it this way. If you feel it's best or easiest to keep it as its own separate class that's perfectly fine, but then maybe it would go into the includes folder to keep things consistent with all the other classes the plugin is using, and would be called from the main plugin file that's already there..??

  12. jignesh kaila

    Actually I am trying to get short ipn listener path which user will set on Paypal account. if we put ipn listener file in include folder so ipn listener file path become long.

    For ex. ipn listener path: wp-content/plugins/paypal-ipn-for-wordpress/paypal-ipn-for-wordpress-ipn.php if we put ipn listener file in include folder path will become wp-content/plugins/paypal-ipn-for-wordpress/includes/paypal-ipn-for-wordpress-ipn.php

    Can please suggest ipn listener path and file name? because it will become public url so file name and path should be valuable.

  13. jignesh kaila

    Thank you for explaining in detail.

    Okay i understand your concern and will work accordingly to you suggestion.

    I will follow "?AngellEYE_Paypal_Ipn_For_Wordpress_Paypal&action=ipn_handler" this pattern is it right?

  14. jignesh kaila

    Today I have worked on below tasks:

    1. Create custom post status in costume post type. It was required for handle IPN response payment_status type

    2. Validate and parse IPN data.

    3. Put hook and filter for specific place to make extendable function.

    4. Store IPN response on WordPress table.

    Please Note: Today I have not push development branch, because IPN storing process still in-progress.

    Do let us know if you have any query or question.

    Thanks.

  15. jignesh kaila

    Today I will worked on below task:

    1. Store IPN response with txn_type in different Categories.
    2. Store all the other IPN response variable to meta table.
    3. put hook and filter to specific place for extend function.
    4. finalize remain thing.

    Let me know you suggestion for the same.

  16. Drew Angell reporter

    Not sure I understand number 2, where you say store all "other" response variables to meta table..??

    All of the data for each IPN should be viewable as a "raw log" so that you can simply see all of the parameters and their values as a dump like this: http://sandbox.angelleye.com/paypal/ipn/admin/raw-log-detail.php?id=9086

    So that would be the data record in WordPress. Then the separate views for looking at orders, refunds, or any txn_type would basically just filter the records and display the data a little more pretty for browsing purposes.

    Is that what you're doing?

  17. jignesh kaila

    2) Store all the other IPN response variable to meta table.

    Actually, I store txn_id and payment_status two fields to prefix_posts table and remain all the IPN fields like residence_country, invoice, address_city.. fields to prefix_postmeta table. so all the IPN fields are visible to post edit interface from admin side.

    Regarding Costume post type admin interface will provide our demo side Url by today EOD.

    Yes, I will provide filter like payment_status and Transaction type for browsing purposes.

  18. Drew Angell reporter

    Ok, I'll just wait to see what you come up with and if we need to make adjustments then I'll let you know.

  19. jignesh kaila

    Today I have worked on below task:

    1) Store IPN response with txn_type in different Categories. 2) Store all the other IPN response variable to meta table. 3) put hook and filter to specific place for extend function.

    Please Note: payment_status and Transaction type filter is pending.

    Below are Demo site detail:

    http://paypalipn.projectsmd.in/wp-admin/edit.php?post_type=paypal_ipn

    Username: admin Password: thinker99

    Do let us know if you have any query or question.

  20. Drew Angell reporter

    Looking good so far! I have a few adjustments I would at this point, but I can save my feedback for later. Should be simple updates once this functionality is all done. Thanks!

  21. jignesh kaila

    Today I have worked on below tasks: 1. I have added filter like payment_status and Transaction type for browsing purposes. 2. Show txn_type count in categories listing column.

    Tomorrow will upload latest code to development branch.

  22. jignesh kaila

    Today I have worked on below tasks:

    1. Add meta_box for update transaction.
    2. Finalized the all the tasks and testing it.
    3. Testing real sandbox transactions, before I am testing using Paypal IPN simulator.
    4. Finalized developer log file so developer can see the paypal log data.

    I have uploaded latest code to our development branch. Along with that we have uploaded latest work to the demo server as I have sent earlier details with you.

    Please review plugin code, admin interface and let me know your suggestion/thoughts for the same.

  23. Drew Angell reporter

    Over all things look pretty good. I do have a few questions / comments.

    • We won't have any need to add IPN records or IPN types manually. This should only house the data that comes from PayPal IPN's. We really don't need the "Add PayPal IPN" and "PayPal IPN Types" screens. The types can be managed within the plugin directly, and we can add new types and release updates in the future if need be to match anything PayPal adds.

    • I notice the filters in the PayPal IPN section seem to be based on the "payment_status" field of IPN's. Is that dynamic? Will those filters be built over time as IPN's come through, or how exactly is that setup right now? My basic solution actually used the txn_type field instead of payment_status to create the different sections, so I may want to make an adjustment here. For example, at the top, we could have filters for the txn_types (and there are quite a few) and then things like the payment_status could go in columns on the list and could be sort-able. I think that's what I'd like to see here but I'm happy to hear out any objection you may have.

    • With a fresh install on my machine I'm left wondering what the URL for IPN is..?? I've created issue #9 to address this.

    • On the IPN list page, please change the "Title" column header to say "Transaction ID" since that's what we're displaying there. We can also remove the payment status from the end there because we'll be displaying that in its own column like I mentioned above.

    If we can address those few things I think I can close out this first issue. Thanks!

  24. jignesh kaila

    Please see my below inline commnets:

    We won't have any need to add IPN records or IPN types manually. This should only house the data that comes from PayPal IPN's. We really don't need the "Add PayPal IPN" and "PayPal IPN Types" screens. The types can be managed within the plugin directly, and we can add new types and release updates in the future if need be to match anything PayPal adds.

    [Yes, I have added this functionality if some one required to own ipn records. for now I will disable this features, if in feature required then I will enable this features. ]

    I notice the filters in the PayPal IPN section seem to be based on the "payment_status" field of IPN's. Is that dynamic? Will those filters be built over time as IPN's come through, or how exactly is that setup right now? My basic solution actually used the txn_type field instead of payment_status to create the different sections, so I may want to make an adjustment here. For example, at the top, we could have filters for the txn_types (and there are quite a few) and then things like the payment_status could go in columns on the list and could be sort-able. I think that's what I'd like to see here but I'm happy to hear out any objection you may have.

    [Yes, payment_status and txn_types are dynamic it will come from PayPal IPN response. At the top, I should have put filters txn_types(https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNandPDTVariables/#id08CTB0S055Z) insted of payment_status is this right? Also I will put new column payment_status on the list and could be sort-able.]

    With a fresh install on my machine I'm left wondering what the URL for IPN is..?? I've created issue #9 to address this.

    [Yes, you are right I still not provide any interface for this, I just thinking I will provide good interface for all ticket wise settings like WooCommerce setting. is it fine? otherwise please provide any suitable interface/more idea if you have in your mind. ]

    On the IPN list page, please change the "Title" column header to say "Transaction ID" since that's what we're displaying there. We can also remove the payment status from the end there because we'll be displaying that in its own column like I mentioned above.

    [Okay, will do.]

  25. jignesh kaila

    On the IPN list page, please change the "Title" column header to say "Transaction ID" since that's what we're displaying there. We can also remove the payment status from the end there because we'll be displaying that in its own column like I mentioned above.

    [I have change Title column header to say "Transaction ID" and add new column "Payment status". Regarding "Payment status" filter is more pretty good for browsing purposes. if you want to remove this then let me know.]

    PayPal IPN Transaction Type (txn_type), some txn_type is too long like "recurring_payment_suspended_due_to_max_failed_payment" So WordPress allow 20 character limit for post_status column in prefix_posts table. So I have created script to alter prefix_posts table and increased limit (post_status column varchar(20) to varchar(55)).

    For this case, some time WordPress database user not have table alter permission that time our plugin txn_type save only first 20 characters.

    Please review it and let me know your thought/suggestion for the same.

  26. Drew Angell reporter

    I wonder if it might be better to go ahead and create a new table of our own for this purpose..??

    For example, we could create our own table called "angelleye_paypal_ipn_transaction_types" or something like that. In this would be nothing but an ID and the txn_type values that PayPal may send.

    Then, in the other tables we can just add the ID of the txn_type from our table and that way we wouldn't have to alter any core tables.

    Do you think we would run into the same problem with creating a new table as opposed to altering it? I know lots of plugins create tables and I've never had any issues with plugins on all the different client sites I've worked on.

    I know I said I'd like to avoid creating our own tables as much as possible, but this may be an area where it's better to go ahead and do it. Your thoughts on that?

  27. Drew Angell reporter

    Yes, I was saying I would like the txn_types to be the filters across the top. There are quite a few, though, so I'm hoping we can do something similar to what I did in my basic IPN template solution.

    If you look at my ipn-listener.php starting at line 95 you'll see that I'm actually grouping txn_type's so there aren't so many. For example, new_case, reversed, canceled_reversal, and adjustment would all go under the "Disputes" section. So here, it would be nice to see "Disputes" at the top, and if I click on that I would get a list of all those txn_types that have occurred. Then we'd show columns with important data for the list and the list could be sortable by those columns.

    You tell me, though, if you feel like that should be split into a separate issue..?? Not sure how complicated that will make it.

  28. jignesh kaila

    I understand your concern base on that I really need some more brainstorming because it most important part of our plugin.

    Yes, I look into your ipn_listener.php file it work like grouping txn_type For example, new_case, reversed, canceled_reversal, and adjustment would all go under the "Disputes" section and recurring_payment_expired, recurring_payment_failed, recurring_payment_skipped, recurring_payment_suspended, recurring_payment_suspended_due_to_max_failed_payment go under "Recurring payment" section.

    So Disputes and Recurring payment section are display at the top. and when user click on "Disputes" section then all the transaction will display, also I will add new txn_type column it will display original txn_type like "canceled_reversal" and this column is sort-able like "Payment status" column.

    Regarding txt_type section name is it more the 20 character? If possible can we manage all the section name within 20 character? If yes, I will manage it programmatically without adding any new db table.

    Please let me know your suggestion/thought for the same.

  29. Drew Angell reporter

    Internally, I guess we could chop off the txn_type names or come up with our own unique values that would represent the actual values. When we display such values on screen, though, I'd like to make sure we're always using the actual name PayPal uses so we don't confuse anybody. Does that make sense? You think that'll work?

  30. jignesh kaila

    Yes, I understand you concern base on that I will used own section name like which you almost used on ipn_listener.php file. Also I will display actual txn_type name IPN Listing column so we don't confuse anybody.

  31. jignesh kaila

    Can you please suggest section name of txn_type (merch_pmt, mp_cancel, mp_signup, payout, pro_hosted) ?

    I have attached excel file with details in screencast.com site please download it using this link: http://www.screencast.com/t/q3vPdAMH6BWX

    Please find it and let me you suggestion for the same.

  32. jignesh kaila

    Today I have worked on below tasks: 1. Disable auto save post functionality. 2. Grouping txn_type section name like above attached excel file. 3. Finalize Transaction types and Payment status with filter.

    I have uploaded latest code to development branch and our demo server.

  33. Drew Angell reporter

    I've updated your spreadsheet to reflect what I was hoping to see for the labels across the top. You'll see I adjusted the labels so they read more like actual column headers instead of code-like labels with underscores.

    I've added you to the Google Doc so you can view it here.

  34. jignesh kaila

    I review Google Doc which you share with us base on that today I will apply changes.

    One more thing, I found txn_type "invoice_payment" Can you please suggest this txn_type name under which section? I have added this txn_type in Google spread sheet with red color.

    Also you have reviewed other stuffs which we have implemented if you have any suggestion then do let me know.

  35. Drew Angell reporter

    We can put invoice_payment under Orders. I've updated the spreadsheet.

    As for the other stuff, it looks ok on your server, but I still haven't been able to test thoroughly on my end because I don't know what the primary IPN URL is for this thing..??

  36. jignesh kaila

    I have apply all changes related to txn_type group section and upload latest code to demo server and development branch.

    Please review it and let me know you suggestion for the same.

    Now I am move to Issue #2 IPN Forwarding

  37. Drew Angell reporter

    I've been doing some quick tests on this, and I've discovered something odd.

    Using the PayPal IPN Simulator, I'm able to hit the plugin on my server and I get data saved, which looks good. However, when I choose a payment_status of "Pending" in the simulator, it gets saved in the WordPress site as "Completed" for some reason.

    Here's a link to the Simulator test hitting my original IPN template, and you can see it gets saved with a payment_status of Pending: http://sandbox.angelleye.com/paypal/ipn/admin/raw-log-detail.php?id=9314

    Here's a link to the same simulation hitting this plugin on my WordPress site, and it ends up with a Completed status for some reason: http://woo.angelleye.com/wp-admin/post.php?post=365&action=edit

    I was thinking maybe their simulator was doing something funny, but again, when I hit my original template it comes through just fine.

  38. jignesh kaila

    Actually it is from my end. I have play with "test_ipn" variable for simulator or sandbox testing purpose. Now, I have updated it and push to demo server and development branch.

    Tomorrow I will start working on Issue #2 IPN Forwarding OR If you have any suggestion then do let me know.

  39. Drew Angell reporter

    Ok, thanks. That's a good example of why I want to get a completely raw dump of the IPN data in here instead of the parsed values. I've created issue #11 for that, so I'm going to go ahead and close out this issue.

  40. Drew Angell reporter

    Now that this first issue is completed, I've locked the development branch so that only I can push updates to it. What I'd like from now on is for you to create separate issue branches for each issue that you're working on, but of course you'll need to make sure you always create new issue branches from the updated dev branch.

    As you complete an issue, I'll pull that branch down individually, test it for my approval, and once I'm happy with it that's when I will merge into the dev branch, push it back to BitBucket, and close that issue.

    I realize that sometimes the work done in one branch is required to complete another branch, so there will be times that more than 1 issue are included in a single branch, but I'd like to stick to a single issue in each branch as much as possible.

    Please let me know if you have any questions about that. Thanks!

  41. Drew Angell reporter

    I notice that we do have a create_tables() method in our activator class that seems to be creating a new table..?? What exactly are we doing there? If we could leave some good notes in the comments above functions like that explaining what they're doing and what they're for that would be great. Thanks!

  42. jignesh kaila

    Ok, I understand your concern base on that I follow your suggestion.

    Yes, I have created function like "create_tables" it for create or modified prefix_posts table, I just think few day ago but now it used less so I will remove it.

  43. Drew Angell reporter

    OK, thanks. Please try and remember to remove anything that's not getting used as we go. I'd like to keep this thing as clean as possible and don't want to be reviewing code that is obsolete. Thanks!

  44. jignesh kaila

    Can you please allow me access to development branch for only one day to remove create_tables function and some other stuff that I have added for simulator testing purpose.

  45. Drew Angell reporter

    It looks like you've already removed that in the Issue-10 branch didn't you? I see it in this commit. As soon as I'm able to see those changes (I left an update in that issue) then I'll merge it into the dev branch so it's all caught up. I'd really like to keep things that way if we can, because then I can think of the dev branch as a fully tested and ready to go branch. If I'm the only one merging into it that's a lot easier to accomplish.

    Is there some specific reason you're wanting to apply those changes directly in dev?

  46. jignesh kaila

    No there is no any reason.

    I asking because When create new branch first pull to development branch so every new branch we need to remove this code. So I think we have remove it on development branch so will not remove every new branch when we create. Hope you understand.

    I understand your concern, I will remove that code every new created branch from our end until you not merged issue-10 branch to development branch. Is it fine?

  47. Drew Angell reporter

    Well, in a situation like that, you could create the next issue branch from the previous issue branch, right? Then as I get each one merged into the dev branch I'll still just be looking at only that issue's changes.

    Does that make sense or am I missing something? I know I said previously I would always want to branch of the development branch to start a new one, but I guess this would be an exception to the rule where you need updates from previous branch in order to continue with your next one.

  48. jignesh kaila

    I have one suggestion. when I am done with one issue, I will let know for the review. after your review you will commit it to development branch.

    when I am done with second issue, I will get pull from development branch so all the latest code will merge to second issue branch and push to second issue branch.

    So, conflict should never occur because latest code already merged with new branch.

    In sort one day not more one branch merge to development branch.

    is it fine? let me know your thought for same.

  49. Drew Angell reporter

    That sounds like exactly what I've been saying, so I think we're on the same page. I'm really not sure why I ran into this conflict on the other issue, but we'll get it all worked out.

  50. Log in to comment