How to use Paypal adaptive payments with IPN?

lazydaemon picture lazydaemon · Apr 24, 2012 · Viewed 8.2k times · Source

I am using the adaptive payment system from Paypal. Using a sandbox account, I was able to make a PayRequest and get forwarded to Paypal to do the payment. It's then looking like:

Request=

Apr 24, 2012 10:35:46 PM com.paypal.adaptive.api.requests.PayRequest execute INFO: Sending PayRequest with: requestEnvelope.errorLanguage=en_US&actionType=PAY&receiverList.receiver(0).email=seller_1334320690_biz%40email.org&receiverList.receiver(0).amount=5.0&currencyCode=EUR&feesPayer=SENDER&cancelUrl=https%3A%2F%2Flocalhost%3A8443&returnUrl=http%3A%2F%2Flocalhost%2F&ipnNotificationUrl=http%3A%2F%2Flocalhostu%2Ffinishdeposit&

Response=

Apr 24, 2012 10:35:48 PM com.paypal.adaptive.api.requests.PayPalBaseRequest makeRequest INFO: Received Response: responseEnvelope.timestamp=2012-04-24T13%3A35%3A48.587-07%3A00&responseEnvelope.ack=Success&responseEnvelope.correlationId=c8dee8023cca6&responseEnvelope.build=2756816&payKey=AP-1UF57245CJ360523K&paymentExecStatus=CREATED

I'm now trying to figure out, how i can check, the payment was successfully completed. So I tried to implement the ipn system, which works using the sandbox tools. However, I don't know how to connect the 2 together. i.e. when a payment is made, I am assuming I need to create a record in a database that this user has made a payment, probably as pending/created? Then wait for the ipn to return to notify me that the payment is made, and update the database table to say complete? How can i correlate the PayRequest to the IPN-Notification, i'll get from paypal? Paypal is only sending a few information with the IPN-Notification like:

  • item_number=AK-1234
  • residence_country=US
  • verify_sign=ArcmaOINNZx08uC3iQY0zhEQN3IZAz70ynRk93Or8ixRi23bb4rGNIrd
  • address_country=United States
  • address_city=San Jose
  • address_status=unconfirmed
  • payment_status=Completed
  • [email protected]
  • payer_id=TESTBUYERID01
  • first_name=John
  • shipping=3.04
  • [email protected]
  • mc_fee=0.44
  • txn_id=484221854
  • quantity=1
  • [email protected]
  • notify_version=2.1
  • txn_type=web_accept
  • test_ipn=1
  • payer_status=verified
  • mc_currency=USD
  • mc_gross=12.34
  • custom=xyz123
  • mc_gross_1=9.34
  • payment_date=11:54:48 Apr 22, 2012 PDT
  • charset=windows-1252
  • address_country_code=US
  • address_zip=95131
  • address_state=CA
  • tax=2.02
  • item_name=something
  • address_name=John Smith
  • last_name=Smith
  • payment_type=instant
  • address_street=123, any street
  • receiver_id=TESTSELLERID1

I cant find something usable in that IPN-Notifcation. The best would be if i could get the same correlation-id with the IPN-Notification i already got with the pay-response. So i could save the response-correlation-id on my database and then check against it if i receive the IPN-Notification with the same correlation-id.

Answer

Sai picture Sai · Jun 24, 2012

The test IPN they give you in the sandbox is terrible. Look at a real one triggered to your actual callback (even a test), and you'll see it has the payKey defined; this is what you use to look it up.

Note that they require port 80 for the IPN callback (though that's not documented anywhere).

Here's a real IPN notification (translated to JSON, info specific to my app redacted):

{"payment_request_date":"Sun Jun 24 06:12:20 PDT 2012",
"return_url":"http://redacted/paypal/transactions/3?status=completed",
"fees_payer":"EACHRECEIVER",
"ipn_notification_url":"http://redacted/paypal/notifications",
"sender_email":"redacted",
"verify_sign":"AFcWxVredacted",
"test_ipn":"1",
"transaction[0].id_for_sender_txn":"redacted",
"transaction[0].receiver":"redacted",
"cancel_url":"http://redacted/paypal/transactions/3?status=canceled",
"transaction[0].is_primary_receiver":"false",
"pay_key":"AP-redacted",
"action_type":"PAY",
"transaction[0].id":"redacted",
"transaction[0].status":"Completed",
"transaction[0].paymentType":"SERVICE",
"transaction[0].status_for_sender_txn":"Completed",
"transaction[0].pending_reason":"NONE",
"transaction_type":"Adaptive Payment PAY",
"transaction[0].amount":"USD 1.00",
"status":"COMPLETED",
"log_default_shipping_address_in_transaction":"false",
"charset":"windows-1252",
"notify_version":"UNVERSIONED",
"reverse_all_parallel_payments_on_error":"true"}

Note that you have to set reverse_all_parallel_payments_on_error in the PAY request manually. Even though they recommend doing so (and it'll probably save you angst) it's false by default.

Also, you can use PaymentDetails to get all the same info directly if you miss the IPN.

I don't know what @swade1987 was looking at, but my IPNs don't include any info about the fee amount. (That's actually how I found this post; trying to figure out why. The PP API documentation is horrid.)

Additional documentation can be found here https://developer.paypal.com/docs/classic/adaptive-payments/integration-guide/APIPN/