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