PayPal IPN unique identifier - paypal

I always assumed that txn_id sent with IPN message is unique. PayPal guidelines seem to support this idea - https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro
Avoid duplicate IPN messages. Check that you have not already processed the transaction identified by the transaction ID returned in the IPN message. You may need to store transaction IDs returned by IPN messages in a file or database so that you can check for duplicates. If the transaction ID sent by PayPal is a duplicate, you should not process it again.
However I found that PayPal's eCheck payment IPN is sent twice with the same transaction ID. Once during initial payment with payment_status as "Pending" and again after couple days when eCheck is actually processes with payment_status as "Completed".
I want to store both transactions, but still would like to avoid storing duplicates. There is another field in IPN called ipn_track_id and it's different for both transactions, but I can't find documentation for it, except this vague description:
Internal; only for use by MTS and DTS
Anyone else is using ipn_track_id to uniquely identify IPN messages?

ipn_track_id shouldn't be used; mainly because this is for internal use only as stated, and because it's unique for every IPN message.
The txn_id is unique for each transaction, not each IPN message.
What this means is; one transaction can have multiple IPN messages. eCheck, for example, where it will go in a 'Pending' state by default, and 'Complete' once the eCheck has cleared.
But you may also see reversals, canceled reversals, cases opened and refunds against the same txn_id.
Pseudo code:
If not empty txn_id and txn_type = web_accept and payment_status = Completed
// New payment received; completed. May have been a transaction which was pending earlier.
Update database set payment_status = Completed and txn_id = $_POST['txn_id']
If not empty txn_id and txn_type = web_accept and payment_status = Pending
// New payment received; completed
Update database set payment_status = Pending and payment_reason = $_POST['pending_reason'] and txn_id = $_POST['txn_id']
You can find a lot more IPN variables listed on https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_IPNandPDTVariables#id08CTB0S055Z
Basically; PayPal will generate a unique seller transaction ID. This tranaction ID may go through various stages before it's 'Completed', so you'll need to be able to handle these exceptions.
As for PayPal's note in the documentation: PayPal may resend individual IPN mesages if it encounters errors during delivery. For example, it's required for your script to return a proper HTTP/1.1 200 OK HTTP status response whenever PayPal POST's the IPN data to it.
If you don't return a HTTP/1.1 200 OK response, PayPal will reattempt sending the same data up to 16 times per indiviudal IPN message.
Note: A seller's transaction ID is different from a buyer's transction ID, since they're two different actions (one debit, one credit).

ipn_track_id is not unique for recurring payments. At least for installment plan it's not.
When customer create the installment plan and if your plan have a first payment at checkout you will receive 2 IPN messages with the same ipn_track_id (Example bellow).
First notification "recurring_payment_profile_created" the the first payment "recurring_payment"
Plan created IPN
[txn_type] => recurring_payment_profile_created
[recurring_payment_id] => I-57UAPHFJ3SBY
[product_name] => Risk-Free Trial
[time_created] => 06:24:39 Aug 15, 2013 PDT
[ipn_track_id] => bdd94fdee935a
First Payment IPN
[txn_type] => recurring_payment
[mc_gross] => 10.95
[shipping] => 0.00
[product_type] => 1
[time_created] => 06:24:39 Aug 15, 2013 PDT
[ipn_track_id] => bdd94fdee935a

Not all IPN messages contain a $_POST['txn_id'], so if you solely check for a txn_id, you may intermittently not log IPN messages where they don't contain this key.

In my PHP API call, i use these fields and store them in my database:
custom=xxxx
(or invoice=ZZZZZZ)
then, when your page receives IPN, it should check (from database) if the custom=xxxx or etc...

IPN transactions are unique, also and transactions that change the payment will generate a new txn_id. For example refunds, so its a good idea to store all txn_id related to a single purchase. As of yet I don't know what transactions other than refunds generate a new txn_id, possibly reversals do too.

Related

How does PayPal calculate and assign parallel payment transaction fees?

My question involves parallel (aka split) payments in PayPal's Adaptive Payments API.
I have been trawling various forums for the last hour (doesn't help that all the www.x.com pages are gone), and am unable to find a clear answer to a seemingly simple question about how PayPal's fixed transaction fee is applied in a parallel payment.
I can boil it down to two scenarios, but which is correct: Scenario A or Scenario B?
Many thanks,
Ollie
Scenario A:
Buyer pays $100 (buyer does not pay transaction fees)
Transaction fees for receivers to split = $100 x 3.4% (variable) + $0.45 (fixed) = $3.85
Seller #1 receives $90, less 90% of PayPal's transaction fees (90% x $3.85 = $3.47) = $86.53
Seller #2 receives $10, less 10% of PayPal's transaction fees (10% x $3.85= $0.39) = $9.61
PayPal transaction fees total = $3.85
Scenario B:
Buyer pays $100 (buyer does not pay transaction fees)
Transaction fee for receivers to split = $100 x 3.4% (variable) = $3.40
Seller #1 receives $90, less 90% of PayPal's transaction fee (90% x $3.40 = $3.06 + $0.45 (fixed) = $3.51) = $86.49
Seller #2 receives $10, less 10% of PayPal's transaction fee (10% x $3.40= $0.34 + $0.45 (fixed) = $0.79) = $9.21
PayPal transaction fees total = $4.30
If I recall correctly, the fee is calculated as Scenario A and then split amongst the receivers. You could always test this out on sandbox to determine which method is used.
So after a few inane form letters being sent to me, someone from PayPal responded to my query with the following:
Thank you for contacting PayPal.
From the two scenarios that you have sent Scenario B would apply for the fees on your Adaptive Payment
Scenario B:
Buyer pays $100 (does not pay transaction fees)
Transaction fee for receivers to split = $100 x 3.4% = $3.40
Seller #1 receives $90, less 90% of PayPal's transaction fee (90% x $3.40 = $3.06 + $0.45 fixed charge = $3.51)
Seller #2 receives $10, less 10% of PayPal's transaction fee (10% x $3.40= $0.34 + $0.45 fixed charge = $0.79)
PayPal transaction fees total = $4.30
Thank you for choosing PayPal.
If this is true, I've advised them to make this clearer in their documentation, i.e. that a parallel payment is treated like a series of completely separate transactions, and therefore a full fixed transaction fee applies to each.
If anyone thinks that my advisor from PayPal has it wrong (it's been known to happen...), please speak!

Paypal ExpressCheckout "constant values" to validate a successful transaction

In SetExpressCheckout I have the following values set
'PAYMENTREQUEST_0_ALLOWEDPAYMENTMETHOD' => 'InstantPaymentOnly',
'PAYMENTREQUEST_0_PAYMENTACTION'=> 'Sale'
After a successful DoExpressCheckout, this is some of what is returned
ACK => Success
PAYMENTINFO_0_TRANSACTIONTYPE => expresscheckout
PAYMENTINFO_0_PAYMENTTYPE => instant
PAYMENTINFO_0_PAYMENTSTATUS => Completed
PAYMENTINFO_0_ERRORCODE => 0
PAYMENTINFO_0_ACK => Success
PAYMENTINFO_0_PAYMENTSTATUS -- With InstantPaymentOnly set, will DoExpressCheckout ever return a PAYMENTINFO_0_PAYMENTSTATUS of In-Progress, Pending, Processed or something other than a clear yes or no as to the success?
Basically, since only instant payments are allowed, the only payments that will ever complete will have a PAYMENTINFO_0_PAYMENTSTATUS of Completed the first time around?
ACK and PAYMENTINFO_0_ACK -- Are they linked? Paypal states that ACK "Indicates the Success or Failure status of the transaction and whether any warnings were returned."
Both ACK values will either be Success or Failure? Does that refer explicitly to whether or not the transaction was or will be completed?
Much appreciated,
InstantPaymentOnly blocks non-instant funding sources in buyer accounts (such as echeck payments). This means that you will not get transactions that are waiting on buyer funds movements to complete. But there are other factors which could cause a payment to be pending rather than complete. These other factors may or may not apply to your specific use case, but examples include payments made to you in a new currency which would be held until you decide whether to open a balance in that currency or auto-convert them to your primary currency, or certain fraud filter/fraud detection scenarios.
As for ACK/ACK_PAYMENTINFO_0_ACK, for cases where you are only requesting the one payment (and no additional things like billing agreement signup) I would guess the two statuses will always be equal, but I would advise you to verify with the official documentation.

How should I send scheduled e-mails?

My question is theoretical.
I have a database with e-mails. For each email I store the desired sending time (as an UNIX timestamp) and the contents of the e-mail (sender, receiver, subject, body, etc.). There's a large number of e-mails scheduled.
This's how I wanted to send the e-mails so far:
I would have a worker process or server which periodically queries the database for "overdue" e-mails based on the timestamps. Then it sends those e-mails, and in the end it deletes them from the DB.
I started to think about two things:
What if the worker dies when it has sent the e-mail but hasn't
deleted it from the database? If I restart the worker, the e-mail
will be sent again.
How do I do it if I have a really large number of
e-mails and therefore I run multiple workers? I can mark an e-mail in
the database as "being sent", but how do I re-initiate sending if the
responsible worker dies? I mean I won't know if a worker has died or
it's just so slow that it's still sending the messages. I'm assuming I cannot get notified about a worker has died, so I can't re-send the e-mails that it failed to send.
I know that e-mail sending is not a so serious thing like bank transactions, but I think there must be a good solution for this.
How is this used to be done?
I would actually use a flag on each email record in the database:
Your worker (or multiples) update the oldest record with their unique worker ID (e.g. a PID or IP/PID combination).
Example for Oracle SQL:
update email set workerid = 'my-unqiue-worker-id' where emailid in (
select emailid from email where
rownum <= 1 and
duetime < sysdate and
workerid = null
order by duetime
)
This would just take 1 not yet processed record (ordered by duetime, which has to be in the past) and set the worker ID. This procedure would be synchronized by the normal database locking mechanism (so only one thread writes at the same time).
Then you select all records with:
select * from email where workerid = 'my-unique-worker-id'
which will be either 0 or 1 record. If it is 0, there is no due mail.
If you have finished sending the email you set the workerid = 'some-invalid-value' (or you use another flag-column to mark the progress. That way it doesn't get picked up by the next worker.
You probably won't be able to find out if the email really has been sent. If the worker dies after sending and before updating the record, there's not much you can do. To be a bit more self-sufficient the worker could create a process file locally (e.g. an empty file with the emailid as the file name. This could at least detect if the crash was just a database connection issue..
If the worker is started and before updating any record already finds a message, which has its ID as the workerid then I would raise an alert / error which should be handled manually (by checking the SMTP server log and manually updating the record).

Reccuring payments ambiguity

I have a class for recurring payments for subscriptions and there is a thing that is not 100% clear for me.
If I initialize an order with following params:
Amount: 25$
Initial amount: 0
Period: month
Freq: 3
Does this mean that the user is paying 25$ three months from now or does he pay 25 now with no extra charge (initial amount)?
In other words, what I am asking is - is the initial payment some extra charge or can it be used as a advanced payments for the first cycle subscription, in which case, the params I would need would be:
Amount: 25$
Initial amount: 25$
Period: month
Freq: 3
My understanding is that the initial amount is requested immediately, the reoccurring amount is taken depending on the billing cycle and the start date
this guide might help explain
If the initial amount request fails then the default is to not activate the reoccurring payments.

What does NOTIFY=&SYSUID mean?

What does NOTIFY=&SYSUID mean on the first line of a JCL? For example in the below declaration:
//DEV1000D JOB (0998,DEV,000,US),'TEST',
// CLASS=D,MSGCLASS=V,NOTIFY=&SYSUID
NOTIFY=&SYSUID indicates that the user who submitted the job should be notified when it completes.
From the MVS JCL manual:
NOTIFY:
In a non-APPC scheduling environment, requests that the system send a message to a
userid when this background job completes.
&SYSUID
The system replaces &SYSUID with the user ID under whose authority the job will run, which is normally one of the following:
The USER parameter from the JOB statement, if specified, or
The user ID from which the job was submitted.
Let me explain what is NOTIFY
NOTIFY statement is to direct the system ,where it has to send the success failure message after completing the job.
syntax :NOTIFY=userid/&SYSUID
Simply it says to which user the notification has to be send &SYSID is the userid from which the jcl is submitted
eg: NOTIFY=TRC033 will send success/failure message to trc033
NOTIFY=&SYSUID will send send/failure message to user submitting the job