PayPal IPN Example: Completed, Reversed, Canceled_Reversed and Refunded - paypal
I had troubles with handling PayPal IPN messages on the web app I'm developing. I asked PayPal Merchant Technical Support for info about handling Reversed, Canceled_Reversed and Refunded IPN messages. This code below is what I found useful from their answers. I hope it will use others too:
Payment:
{
"mc_gross":"5.00",
"protection_eligibility":"Ineligible",
"item_number1":"",
"payer_id":"2LMAK5CCRFC7Y",
"tax":"0.00",
"payment_date":"15:51:55 May 02, 2014 PDT",
"payment_status":"Completed",
"charset":"windows-1252",
"mc_shipping":"0.00",
"mc_handling":"0.00",
"first_name":"Roman",
"mc_fee":"0.45",
"notify_version":"3.8",
"custom":"",
"payer_status":"verified",
"num_cart_items":"1",
"mc_handling1":"0.00",
"verify_sign":"AhKjPyUAFwaeM5vZHwjU.0caZhHtAV.H1ZruV63s-yLcAYfGQU8WYTEX",
"payer_email":"XXXXXX",
"mc_shipping1":"0.00",
"tax1":"0.00",
"txn_id":"64M28299HV0955007",
"payment_type":"instant",
"last_name":"Arora",
"item_name1":"Air Pilots",
"receiver_email":"XXXXXX",
"payment_fee":"0.45",
"quantity1":"1",
"receiver_id":"XXXXXX",
"txn_type":"cart",
"mc_gross_1":"5.00",
"mc_currency":"USD",
"residence_country":"US",
"transaction_subject":"Air Pilots",
"payment_gross":"5.00",
"ipn_track_id":"dfa90ecb35b46"
}
When a dispute is filed with paypal resolution center: This IPN has the same txn_id of the initial payment
{
"txn_type":"new_case",
"payment_date":"15:51:55 May 02, 2014 PDT",
"case_id":"PP-003-125-383-356",
"case_type":"dispute",
"business":"XXXXXX",
"verify_sign":"AbFfRIjxGf8ulMoIvA2Jhdo84gY5Ahewo.T-JjKYBzZxoAYuDLiZf5oK",
"payer_email":"XXXXXX",
"txn_id":"64M28299HV0955007",
"case_creation_date":"14:46:47 May 05, 2014 PDT",
"receiver_email":"XXXXXX",
"payer_id":"2LMAK5CCRFC7Y",
"receiver_id":"XXXXXX",
"reason_code":"non_receipt",
"custom":"","charset":"windows-1252",
"notify_version":"3.8",
"ipn_track_id":"6b3a7ef61a303"
}
Amount on hold(payment_status is Reversed): The txn_id of initial payment is the parent_txn_id. It has a new txn_id.
{
"mc_gross":"-4.55",
"protection_eligibility":"Ineligible",
"item_number1":"",
"payer_id":"2LMAK5CCRFC7Y",
"payment_date":"14:47:45 May 05, 2014 PDT",
"payment_status":"Reversed",
"charset":"windows-1252",
"mc_shipping":"0.00",
"mc_handling":"0.00",
"first_name":"Roman",
"mc_fee":"-0.45",
"notify_version":"3.8",
"reason_code":"buyer_complaint",
"custom":"",
"business":"XXXXXX",
"mc_handling1":"0.00",
"verify_sign":"Aayt7rRv.9vczRke0KD5otSJgqTEA6ETzuIl3f7JWHiTh.q-Pp8Lh7QW",
"payer_email":"XXXXXX",
"mc_shipping1":"0.00",
"tax1":"0.00",
"parent_txn_id":"64M28299HV0955007",
"txn_id":"4RW75981SW305352R",
"payment_type":"instant",
"last_name":"Arora",
"item_name1":"Air Pilots",
"receiver_email":"XXXXXX",
"payment_fee":"-0.45",
"quantity1":"1",
"receiver_id":"XXXXXX",
"mc_gross_1":"5.00",
"mc_currency":"USD",
"residence_country":"US",
"transaction_subject":"Air Pilots",
"payment_gross":"-4.55",
"ipn_track_id":"ed496d8ef1d7d"
}
Amount released(payment_status is Canceled_Reversal) - Merchant won the dispute: The txn_id of initial payment is the parent_txn_id. It has same txn_id of the IPN - Amount on hold.
{
"mc_gross":"4.55",
"protection_eligibility":"Ineligible",
"item_number1":"",
"payer_id":"2LMAK5CCRFC7Y",
"payment_date":"14:47:45 May 05, 2014 PDT",
"payment_status":"Canceled_Reversal",
"charset":"windows-1252",
"mc_shipping":"0.00",
"mc_handling":"0.00",
"first_name":"Roman",
"mc_fee":"0.45",
"notify_version":"3.8",
"reason_code":"buyer_complaint",
"custom":"",
"business":"XXXXXX",
"mc_handling1":"0.00",
"verify_sign":"Auodxl0Yf.7io9Qqvln7PODrgOvjAbuOsf7PTpgdLQyLHk1uoYabZCsl",
"payer_email":"XXXXXX",
"mc_shipping1":"0.00",
"tax1":"0.00",
"parent_txn_id":"64M28299HV0955007",
"txn_id":"4RW75981SW305352R",
"payment_type":"instant",
"last_name":"Arora",
"item_name1":"Air Pilots",
"receiver_email":"XXXXXX",
"payment_fee":"0.45",
"quantity1":"1",
"receiver_id":"XXXXXX",
"mc_gross_1":"5.00",
"mc_currency":"USD",
"residence_country":"US",
"transaction_subject":"Air Pilots",
"payment_gross":"4.55",
"ipn_track_id":"72b0067375b5f"
}
Reversal(payment_status is Refunded) - Merchant lost the dispute: The txn_id of initial payment is the parent_txn_id. It has new txn_id.
{
"mc_gross":"-5.00",
"protection_eligibility":"Ineligible",
"item_number1":"",
"payer_id":"2LMAK5CCRFC7Y",
"payment_date":"10:45:49 May 06, 2014 PDT",
"payment_status":"Refunded",
"charset":"windows-1252",
"mc_shipping":"0.00",
"mc_handling":"0.00",
"first_name":"Roman",
"mc_fee":"-0.15",
"notify_version":"3.8",
"reason_code":"refund",
"custom":"",
"business":"XXXXXX",
"mc_handling1":"0.00",
"verify_sign":"AmmJ3Da6WMy0qcyvYpAIcfVWfBEgAJfGvFm8TK2MGOZV6Hc9Ll5axN.V",
"payer_email":"XXXXXX",
"mc_shipping1":"0.00",
"tax1":"0.00",
"parent_txn_id":"64M28299HV0955007",
"txn_id":"4CG08179BW957404H",
"payment_type":"instant",
"last_name":"Arora",
"item_name1":"Air Pilots",
"receiver_email":"XXXXXX",
"payment_fee":"-0.15",
"quantity1":"1",
"receiver_id":"XXXXXX",
"mc_gross_1":"5.00",
"mc_currency":"USD",
"residence_country":"US",
"transaction_subject":"Air Pilots",
"payment_gross":"-5.00",
"ipn_track_id":"54a6104f4cebb"
}
Related
unable to upload an image file to slack through hubot
I am trying to get an image of a web page using pageres package, And post the image to slack using hubot. I am able to get the image, but for some reason i am not able to post it to slack using slack upload api. Here is my code, can you tell me what could be wrong? (not a coffee lint issue) fs = require("fs") Pageres = require('pageres') util = require("util") request = require("request") module.exports = (robot) -> robot.respond /screenshot page (\S*)?( at )?(\S*)?/i, (msg) -> pageres = new Pageres({delay: 30}) domain = msg.match[1].replace("http://", "") if msg.match[3] == undefined size = '960x1024' else size = msg.match[3] dest = './screenshots' msg.send "Acquiring screenshot of #{domain}" pageres.src(domain, [size]).dest(dest) pageres.run (err) -> if err robot.logger.error err msg.send "Um..., you better check the log" else opts = { method: 'POST', uri: 'https://slack.com/api/files.upload', formData: { channels: process.env.HUBOT_SCREENSHOT_SLACK_CHANNEL, initial_comment: "Screenshot of #{domain}", token: process.env.HUBOT_SLACK_TOKEN, file: fs.createReadStream("#{dest}/#{domain}.png") } } request.post opts, (error, response, body) -> if error robot.logger.error error else robot.logger.debug 'screenshot posted to slack' return The bot is connected to slack, and receiving messages from slack, parsing them fine and getting the image back to the local destination, but not able to post it to slack, There are no errors as well in the log. [Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Received message: '#hubot screenshot page http://www.google.com' in channel: ****, from: ****** [Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Message '#hubot screenshot page http://www.google.com' matched regex //^\s*[#]?hubot[:,]?\s*(?:screenshot page (\S*)?( at )?(\S*)?)/i/; listener.options = { id: null } [Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Executing listener callback for Message '#hubot screenshot page http://www.google.com' [Wed Apr 11 2018 16:16:47 GMT+0000 (UTC)] DEBUG Sending to *****: Acquiring screenshot of www.google.com
You can use curl command which can be called using child_process to upload a file in the channel. curl -F file=#dramacat.gif -F channels=C024BE91L,#general -F token=xxxx-xxxxxxxxx-xxxx https://slack.com/api/files.upload
It seems the formData property in your opts variable should be slightly different like this: formData: { token: process.env.HUBOT_SLACK_TOKEN, title: "Screenshot of #{domain}", filename: "image.png", filetype: "auto", channels: channel_id, file: fs.createReadStream("path_to_your_image"), } The channel_id is your slack channel id which you can see in the browser address bar when you access the channel.
Failed to send event to MongoDb
I am using logstash to collect data from android device using http-poller as input plugin. I want to store the collected data in a NoSQL(mongodb) using mongodb as output plugin. I have successfully set up the configuration file but when I run my set-up, I get the following error: Failed to send event to MongoDB {:event=>#, #cancelled=false, #data={"error"=>501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "url"=>"http://127.0.0.1/web/app.php/api/addsmartlog"}, "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, #metadata={}, #accessors=#501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "url"=>"http://127.0.0.1/web/app.php/api/addsmartlog"}, "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, #lut={"http_poller_metadata"=>[{"error"=>501, "#version"=>"1", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=>{"method"=>"post", "#timestamp"=>"2016-10-03T18:02:11.337Z", "http_poller_metadata"=>{"name"=>"some_other_service", "host"=>"s18660276.domainepardefaut.fr", "request"=> "runtime_seconds"=>0.526, "code"=>200, "response_headers"=>{"date"=>"Mon, 03 Oct 2016 18:02:11 GMT", "server"=>"Apache/2.2.22 (Debian)", "x-powered-by"=>"PHP/5.5.30-1~dotdeb+7.1", "cache-control"=>"no-cache", "content-length"=>"13", "keep-alive"=>"timeout=5, max=100", "connection"=>"Keep-Alive", "content-type"=>"application/json"}, "response_message"=>"OK", "times_retried"=>0}}, "#timestamp"]}>>, :exception=>#"admin"}, #server_selection_timeout=30>>, :backtrace=>["/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/server_selector/selectable.rb:99:in select_server'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/cluster.rb:122:innext_primary'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/collection.rb:190:in insert_many'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/mongo-2.0.6/lib/mongo/collection.rb:175:ininsert_one'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-output-mongodb-2.0.5/lib/logstash/outputs/mongodb.rb:56:in receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/outputs/base.rb:109:inmulti_receive'", "org/jruby/RubyArray.java:1613:in each'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/outputs/base.rb:109:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/output_delegator.rb:130:in worker_multi_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/output_delegator.rb:114:inmulti_receive'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:301:in output_batch'", "org/jruby/RubyHash.java:1342:ineach'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:301:in output_batch'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:232:inworker_loop'", "/opt/logstash/vendor/bundle/jruby/1.9/gems/logstash-core-2.4.0-java/lib/logstash/pipeline.rb:201:in `start_workers'"], :level=>:warn} ^CSIGINT received. Shutting down the agent. {:level=>:warn} Can anyone help out?
Sorting a Meteor Cursor
I am using Ionic 2 with Meteor/Mongo. I am trying to sort a Cursor, but find it just keeps the original order which the items were inserted. model interface Chat { _id?: string; memberIds?: string[]; title?: string; subTitle?: string; picture?: string; lastMessage?: Message; lastMessageCreatedAt?: Date; receiverComp?: Tracker.Computation; lastMessageComp?: Tracker.Computation; } ts private sortLocalChats(): void { this.localChatCursor = this.localChatCollection.find({}, { sort: { lastMessageCreatedAt: -1 } }); this.localChatCursor.forEach((chat: Chat) => { console.log(chat.title+' '+chat.lastMessageCreatedAt); }); console.log('==> loaded sorted local chats: ' + this.localChatCollection.find().count()); output Ashton Marais Thu Oct 06 2016 16:50:36 GMT+0800 (CST) Ashton Marais Wed Oct 12 2016 21:20:18 GMT+0800 (CST) ghjghj ghjghg Wed Oct 05 2016 23:37:49 GMT+0800 (CST) Brett Simpson Thu Oct 06 2016 23:52:05 GMT+0800 (CST) ==> loaded sorted local chats: 4 I would have expected this to be sorted by lastMessageCreatedAt. Any help appreciated.
To get sorted results you probably need to call fetch() first. So in the above example this works: this.localChatCursor.fetch().forEach(...);
Is the IPN response for Payments Standard the same as for Express Checkout?
I am switching from Payments Standard to Express Checkout. Is the IPN response the same or different?
There is one IPN parameter which is different txn_type Check the IPN response for Website Payment Standard and express Checkout respectively. For WPS : txn_type=web_accept For EC : txn_type=express_checkout **IPN response for Payment Standard:** cmd=_notify-validate mc_gross=10.01 protection_eligibility=Eligible address_status=confirmed payer_id=ZK5AUW8MWY9CW tax=0.00 address_street=3585+Petunia+Way%0D%0Aaddress+222 payment_date=00%3A08%3A18+Apr+03%2C+2015+PDT payment_status=Completed charset=UTF-8 address_zip=35045 first_name=vimalbuyer mc_fee=0.59 address_country_code=US address_name=azlan+xxxxx notify_version=3.8 custom= payer_status=verified business=vimalnath53-facilitator%40gmail.com address_country=United+States address_city=Clanton quantity=1 verify_sign=AEkJZp5PlgClTn1mxfylgc2FBYMzALsU7xcwTTHxpgXCri8asnzueXPK payer_email=vimalbuyer%40gmail.com contact_phone=408-329-3451 txn_id=5GW24560KH817881A payment_type=instant last_name=ravichandran address_state=AL receiver_email=vimalnath53-facilitator%40gmail.com payment_fee=0.59 shipping_discount=0.00 insurance_amount=0.00 receiver_id=S4X5XW328WAYY txn_type=web_accept item_name=Test+Item discount=0.00 mc_currency=USD item_number= residence_country=US test_ipn=1 shipping_method=Express handling_amount=0.00 transaction_subject= payment_gross=10.01 shipping=10.00 ipn_track_id=97ef1f6957d55 **IPN response for Express Checkout:** cmd=_notify-validate mc_gross=0.01 protection_eligibility=Eligible address_status=confirmed payer_id=ZK5AUW8MWY9CW tax=0.00 address_street=3585+Petunia+Way%0D%0Aaddress+222 payment_date=00%3A00%3A44+Apr+03%2C+2015+PDT payment_status=Completed charset=UTF-8 address_zip=35045 first_name=vimalbuyer mc_fee=0.01 address_country_code=US address_name=azlan+xxxxx notify_version=3.8 custom= payer_status=verified address_country=United+States address_city=Clanton quantity=1 verify_sign=Au5ok3gYe0CeO2vF0KS59WJwgD0QAIljdpxKQfkvVQsbdbhT2o7SKMxQ payer_email=vimalbuyer%40gmail.com contact_phone=408-329-3451 txn_id=207564537Y419840U payment_type=instant last_name=ravichandran address_state=AL receiver_email=vimalnath53-facilitator%40gmail.com payment_fee=0.01 receiver_id=S4X5XW328WAYY txn_type=express_checkout item_name= mc_currency=USD item_number= residence_country=US test_ipn=1 handling_amount=0.00 transaction_subject= payment_gross=0.01 shipping=0.00 ipn_track_id=c50c795d8f17a Also, look at the IPN variables that would be returned for each transaction here
Testing Chargebacks/Dispute with IPN in the PayPal Sandbox
Is there any way to go to test Chargebacks/Disputes on the PayPal Sandbox test site? I try to use the resolution center to create new cases both through the normal method of disputing a charge and through the sandbox specific "Create or Resolve Case" section of the Resolution Center. Either way I do it, I can only ever get the disputes into a status of "Being Reviewed By PayPal". No IPN notifications are sent out. This support article details the expected steps I'm hoping to emulate in the sandbox environment: https://ppmts.custhelp.com/app/answers/detail/a_id/622/kw/Dispute
What you'll need to do is create your own IPN simulator to test this. You can make a basic HTML form with the action set to your IPN URL and hidden fields that match the names/values you expect to get from an IPN. This way you can load your test in a browser and submit it to your IPN listener. You'll be able to see the results on screen which can help with troubleshooting. Keep in mind that when testing this way the data is not coming from PayPal's server so the IPN will be unverified. You'll need to make sure your code logic handles that. Here are some samples of IPN's you'd get when a chargeback occurs so you can see what you should expect and setup your simulator accordingly. New Case txn_type = new_case payment_date = 13:40:52 Aug 05, 2013 PDT case_id = PP-002-576-509-683 receipt_id = 4674-2219-3481-3741 case_type = chargeback business = payments#domain.com verify_sign = AeD56uUedZzgp83xxTHMkZtMZ9FVAzvpMwl6OHUf9CNvlvgA2P0mbcwP payer_email = 9FE47613HE5558457#dcc.paypal.com txn_id = 0PC8014855508203X case_creation_date = 18:40:23 Sep 04, 2013 PDT receiver_email = payments#domain.com payer_id = RZ3LX555U646Q receiver_id = M5VRA555CSK6 reason_code = non_receipt custom = charset = windows-1252 notify_version = 3.7 ipn_track_id = 2842c24f40ac Reversal mc_gross = -1972.86 protection_eligibility = Ineligible payer_id = RZ3LX555U646Q address_street = N/A payment_date = 18:42:00 Sep 04, 2013 PDT payment_status = Reversed charset = windows-1252 address_zip = 00000 first_name = Tester mc_fee = -44.74 address_country_code = US address_name = Tester Testerson notify_version = 3.7 reason_code = chargeback custom = business = payments#usbswiper.com address_country = United States address_city = NA verify_sign = Ai1PaghZh5FmBLCDCTQpwG8jB264ABWpa3tbhFljkaPnVj1L9ip5EwyS parent_txn_id = 0PC8014555008203X txn_id = 0PC8014855508203X payment_type = instant last_name = Testerson address_state = NA receiver_email = payments#domain.com payment_fee = -44.74 receiver_id = M5VRA555CSK6 item_name = PayPal POS Web Order mc_currency = USD item_number = residence_country = US receipt_id = 4674-2219-3481-3741 handling_amount = 0.00 transaction_subject = payment_gross = -1972.86 shipping = 100.00 ipn_track_id = f456d076de1ff