Alipay notify_url issue | PHP - php

I have been trying to build a woocommerce plugin for Alipay from what I understand from their docs is:
I have request a payment through an url(consist of several params, like notify_url, return_url etc.)
Pay through their websit by loggin in.
Then they redirect me to the return_url submitted in the first step (with several new params along with old ones)
They send another request to notify_url with a notify_id and a notify_status and some other params.
After that I have to confirm I got the notification.
Now the issue here is, I am being redirected to return_url and getting expected values. But the code supposed to be triggered by notify_url is not being executed. But if I replace the return_url with notify_url, when alipay redirects me to return_url(in this case reuthn_url = notify_url) notification verification code executes properly.
I am using their demo code.
Here is the configuration:
$gateway = "https://openapi.alipaydev.com/gateway.do?";
$partner = "";
$security_code = "";
$_input_charset = "utf-8";
$sign_type = "MD5";
$transport= "http";
$notify_url = "http://localhost/code/notify_url.php";
$return_url = "http://localhost/code/return_url.php";
N.B. They say payment process is successful in thier website, before redirecting me to return_url.

Related

PHP incoming webhook handling

I have a 3rd party website that has webhooks that send to a specific url. I set it up to send to a blank page on my site (example: www.mysite.com/webhook.php)
I have a var_dump set up in the webhook.php that should display any information in the post or get.. I am new to webhooks and might just not understand how they work. I assume that i can have var_dump($_POST) in my php file to display an array of the HTTP request that is coming to my site.
I cannot see any requests on my site from the hook after sending test data.. any ideas?
I would do this to test the webhook.
<?php
$fWrite = fopen("log.txt","a");
$wrote = fwrite($fWrite, var_dump($_POST));
fclose($fWrite);
?>
This will return var_dump data in log.txt file, since as rickdenhaan said 36 mins ago, your current webhook.php return data to the webhook not your view.
You may need to create log.txt manually if you don't have right on directory (755)
I'm currently working with a payment API that use webhook. Webhook send data to X url then do action and return code to webhook. so webhook.php is the place where my order if ispaid or not is proceed or not... here what I did:
if ($payment->isPaid() == TRUE)
{
/*
* At this point you'd probably want to start the process of delivering the product to the customer.
*/
$con->query("UPDATE orders SET bankno = '$bankno', status = 'paid' WHERE ordertr = '$ids'");
}
elseif ($payment->isOpen() == FALSE)
{
/*
* The payment isn't paid and isn't open anymore. We can assume it was aborted.
*/
$con->query("UPDATE orders SET bankno = '$bankno', status = 'closed' WHERE ordertr = '$ids'");
}
So if order paid mark as paid in database if not mark as closed. This show webhook usage. Doing action according to what the webhook data send.
here is how i get content sent to my app:
$varname = json_decode(file_get_contents('php://input'));
well my content are JSON encoded, but I think this would be fine:
$varname = file_get_contents('php://input');

how to handle paypal notify url in our site?

I have paypal form which will have ipn notify url. i have setup notify url in my paypal ipn settings. but it doesn't return to my site. after analyzed for more than 2 days. i found that my controller construct itself i check for current user session exist or not? should i remove the session check in construct not to check for session. Please advise on this.
this is my code. i am using codeigniter application.
function __construct() {
parent::__construct();
$this->load->model('user_model');
// if (!isEmployee()) {
// redirect('information');
//
// }
}
function paypal_ipn(){
$txn_id = $_POST['txn_id'];
$data = array("paypal_transaction_id"=>$txn_id);
$this->db->insert("payments",$data);
}
I have commented out now
Notify url is part of the Instant Payment Notification (IPN) mechanism of PayPal. This URL is called by PayPal to notify about a payment. It is not part of the user session at all so do not check for it.
I recommend you to read the documentation and get the example from here:
documentation IPN

Verify POST data comes from PayPal

How to verify POST data comes from PayPal ?
I am working on a store that sells some products. The payment gateway is PayPal.
Initially I set up a custom PayPal form and used the IPN responses to validate the data that is sent to me from PayPal.
Now my client has bought PayPal Advance Payment that uses PayPal PayFlow. The responses are not sent anymore through IPN (or are they?) instead they are returned by SILENT POST, basically when a transaction is perfomed on their end it is sent to a link of my choice and I process data through that link.
How do I validate the source of the POST data, so I know it is coming from PayPal and not a bad intentions user. I can not find any documentation on this. Also I want the same think when a users clicks "Cancel" button on paypal page and it is redirected to cancelation page on my website. I want that POST data source also verified.
Any thoughts on this ?
First solution than I found, also some PayPal support guy has mentioned something similar but he could not offer details as he said he is not an expert.
Basically you have to run a TRANSACTION of type INQUIRY with the received PNREF from SILENT POST, if the response returns ORIGRESULT equal to 0 then the transaction exists in PayPal database under your account.
I also send the SECURE TOKEN ID and SECURE TOKEN with the inquiry, I do not know if it helps or not, I saw this as a solution somewhere and I tried sending just TOKEN and TOKEN ID without ORIGID and sometimes it worked sometimes not.
On the developer reference from PayPal is specified that on a TRXTYPE=I (INQUIRY TRANSACTION) the ORIGID must be specified.
Code below:
//GET POST DATA FROM SILENT POST
$data = $_POST;
$result = $data['RESULT'];
$pnref = $data['PNREF'];
$secure_token = $data['SECURETOKEN'];
$secure_token_id = $data['SECURETOKENID'];
$fee_amount = $data['AMT'];
if(!isset($result) || $result != '0'){
//DO TRANSACTION FAILED OPERATIONS
exit;
}
//CHECK IF PNREF ID EXISTS ON PAYPAL
$post_data = "PARTNER=yourpartnerid"
."&VENDOR=your_vendor"
."&USER=your_user"
."&PWD=your_password"
."&SECURETOKENID=" . $secure_token_id
."&SECURETOKEN=" . $secure_token
."&ORIGID=" . $pnref
."&TRXTYPE=I"
."&VERBOSITY=HIGH";
$ch = curl_init('https://payflowpro.paypal.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$resp = curl_exec($ch);
$inquiry = array();
parse_str($resp, $inquiry);
//IF ORIGRESULT is 0 then PNREF/transaction exists.
if($inquiry['ORIGRESULT'] == '0' && $inquiry['RESPMSG'] == 'Approved'){ $validated = true; }
else{ $validated = false; }
if($result != 0 || $amount != 'your_correct_fee' || $validated == false){
// DO TRANSACTION NOT VALID OR HAS FAILED OPERATIONS
exit;
}
//DO TRANSACTION SUCCESSFULL OPERATIONS
The response from a INQUIRY looks this way:
RESULT=0&PNREF=ETHPC0BBF5FB&TRANSSTATE=8&ORIGRESULT=0&ORIGPNREF=ELFPB0E766F5&RESPMSG=Approved&AVSADDR=N&AVSZIP=N&ORIGPPREF=8GT035513B296200N&CORRELATIONID=97306f6456378&SETTLE_DATE=2014-07-09 14:11:36&TRANSTIME=2014-07-09 14:11:36&FIRSTNAME=John&LASTNAME=doe&AMT=0.0
Another way of doing it is checking the IP from which the SILENT POST is coming.
I noticed all SILENT POST data comes from 173.0.81.65
$ip_address = $_SERVER['REMOTE_ADDR'];
if($ip_address != '173.0.81.65'){ exit; }
#Andrew Angel
SILENT POST and NotifyURL is not the same thing.
From the NotifyURL you can use IPN and data verification it is done very differently there because you receive different kind of post data string back.
I talked with PayPal support and they said NotifyURL and IPN is not available for PayPal Advanced Payments only for PayPal Payments Pro.
Indeed they both do the same function, but they are different things and source validation is done differently.
Hope this helps someone, waiting on opinions.

Paypal IPN receiving via simulator but not via my site

I have an odd problem, testing my IPN handler using the IPN simulator on the paypal website, it works (I've just got it emailing me the report), but when I do it through my site, I don't receive anything.
So I guess the problem must be with sending the pay request and setting the ipn url there
$payRequest = new PayRequest(new RequestEnvelope("en_US"), "PAY", $cancelURL, $currencyCode, $receiverList, $returnURL);
$payRequest->ipnNotificationUrl = $notifyURL;
$service = new AdaptivePaymentsService($config);
try {
/* wrap API method calls on the service object with a try catch */
$response = $service->Pay($payRequest);
}
I've double checked $notifyURL is the same as what i'm using in the simulator. Everything else is working, the user gets sent to the paypal website to complete the payment, it's just the IPN never gets sent afterwards.
I figured out that IPN has to be manually turned on in one of the accounts' profile.

pay pal returnurl to return users pay pal account email address

I'm using PHP.
Is it possible when paypal returns to my site after taken the payment that it could also pass me the email address (paypal username) so that I may use this to send them an email?
I'm trying to keep my site as simple as possible and I don't want to ask the customer for a load of information up front.
My ideal flow would be:
Take Payment > Add record to database > email customer with username and password
The customer can then log in and fill the rest in at their own leisure.
Is it possible to get this variable?
Thanks in advance.
Yes...see the receiver_email variable that was passed back.
Guide here: https://cms.paypal.com/cms_content/GB/en_GB/files/developer/IPNGuide.pdf
See Pages 42-43
This page shows the things you can get back from PayPal after they process a payment.
IPN and PDT Variables
Here is on example I made in Codeigniter.
/* Receives a form data from paypal that is processed after payment goes through.
* It will update the database entry with a transaction id.
*/
function epayment_notify(){
$this->load->model('pament_notice_model');
echo "Hi<br>";
$postvars = isset($_POST)? $_POST : array("no post");
/* echo "</pre>Post Vars:<br><pre>";
print_r($postvars);
echo "</pre>Refurl:<br><pre>";
Check for the transaction ID and put it in the pament_notice table if possible.
*/
if (isset($postvars['item_number']) && $postvars['item_number'] > 0 && isset($postvars['txn_id'])){
/* make sure that payment_number is empty on this row. */
log_message('info',"PayPal transaction received.");
if ($this->pament_notice_model->make_sure_payment_number_is_empty($postvars['item_number'])){
//writes the message to the local log file in CI
log_message('debug',"PayPal payment number is empty.");
/* set the txn_id in the slot */
$data = array('payment_number' => $postvars['txn_id']);
$this->db->where('entry_id',$postvars['item_number']);
$this->db->update('pament_notice',$data);
log_message('debug',"payment number updated. item:".$postvars['item_number']);
log_message('debug',"payment actual cost. payment_gross:".$postvars['payment_gross']);
} else {
log_message('error',"PayPal transaction attempted on non-empty payment number.");
if (isset($postvars['item_number']))
log_message('error',"failed request item_number :".$postvars['item_number']);
if (isset($postvars['txn_id']))
log_message('error',"failed request txn_id:". $postvars['txn_id']);
}
} else {
log_message('info',"PayPal payment transaction sent with invalid data.");
if (!isset($postvars['item_number']))
log_message('error',"item_number is not set");
if (isset($postvars['item_number']))
log_message('error',"failed request item_number :".$postvars['item_number']);
if (!isset($postvars['txn_id']))
log_message('error',"txn_id is not set\n");
if (isset($postvars['txn_id']))
log_message('error',"failed request txn_id:". $postvars['txn_id']);
}
}
There are a couple of way of handling this.
The easiest method is to collect that data prior to sending the user to paypal.
Store it in the users current session, and have paypal redirect the user back to your page automatically.
The second is to set up the Payment Data Transfer option. I haven't fully implemented this but there is Documentation on paypal's developer site. It basically sends a token back to your site when the user makes payment and you have to perform another HTTP post to retrieve the user data.

Categories