paypal支付,异步回调(php)

来源:博客园 分类: 文章浏览史 发布时间:2020-09-20 14:09:31 最后更新:2020-09-20 浏览:984
转载声明:
本文为摘录自“博客园”,版权归原作者所有。
温馨提示:
为了更好的体验,请点击原文链接进行浏览
摘录时间:
2020-09-20 14:09:31

PayPay支付

1.paypal回调,在商户平台上先加上回调地址,是https回调路径,网站如果不是https 要安装https  阿里云有免费的https

2.回调配置后,ios或安卓客户端支付成功后,paypal回发起回调通知

paypal支付的IPN文档: https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSimulator/#ipn-simulator-troubleshooting  ,异步通知代码地址:https://github.com/paypal/ipn-code-samples

然后拿到异步通知的代码之后并没有什么用。没有调试成功过,paypal服务异步过来的是post的json数据。直接放在demo里边校验通不过,如果demo校验通过了最好的方式。没办法那只能用看其他法了。查看palpay文档,支持paypal服务器上查询订单状态,根据这个我们服务器发起请求,来查看订单状态。判断单的支付是否成功。

要查询单的状态必须获取token,再根据token查询订单状态。请求token链接:https://api.paypal.com/v1/oauth2/token,查看订单链接:https://api.paypal.com/v1/payments/payment/orderid

 

 

二 php 代码实现

1.回调地址palpay_notice,接收paypal异步的数据。

public function palpay_notice(){

  $content=file_get_contents("php://input");

 // 这里可以写一个日志,看一下接收到的数据
  if (! empty ( $content )) {
   $log_file = 'public/data_log/pay' . date ( 'Ymd', time () ) . '.txt';
   $logs = "notice \r" . date ( "Y-m-d H:i:s", time () ) . "\r\n" . $content;
   file_put_contents ( $log_file, $logs, FILE_APPEND );
  }
  
  $verify = $this->verifyNotify($content);
  if ($verify) {
   header("HTTP/1.1 200 OK");
   echo  'success';
   exit;
  } else {
   echo  'fail';
   exit;
  }
 }

 

2.verifyNotify方法校验异步回调的数据

 
 /**
  * paypal 验证异步回调数据
  * @return bool
  */
 private function verifyNotify($post)
 {
  if(empty($post)){
   return false;
  }
  
  if(!empty($post)){
   
   $post2=json_decode($post,true);
   //completed 表示订单状态ok. 这里怕是伪造的数据。我们自己去paypal服务器上去查
   if($post2['resource']['state'] !='completed'){
    return false;
   }

 // invoice_number,再客户端(ios或安卓)发起支付的时候加入进去的。如果这个数据是空的,客户端配置有问题。【客户端请求服务器,自己生成的唯一订单号,给客户端,客户端再加入到palpal支付参数里边】 

   $order_sn = $post2['resource']['invoice_number']; //收取订单号
   $payment_id=$post2['resource']['parent_payment'];
   $pay_order=$post2['resource']['parent_payment'];
   $money=$post2['resource']['amount']['total'];
   //根据订单号和钱的金额,查看订单的状态是否为已支付,已支付返回成功,
     /* $wh = array (
     'money' => $money,
     'recharge_sn' => $order_sn
   );
   $row = $this->db->where ( $wh )->from ( 'recharge' )->select ( 'id,uid,money,status' )->get ()->row_array ();
  
   if (empty ( $row ['id'] )) {
    return false;
   }
   // 状态已改变,支付成功过
   if ($row ['status'] == '1') {
    return true;
   }   */


  }
  
  // 查询订单信息获取,token
  $tokens = $this->access_token(1);
  $token = $tokens['access_token'];
  
  //查询是否有订单
  $order = $this->get_curlOrder ($pay_order, $token,1);
  
  //$payment_id = $order ['id'];
  $state=$order['transactions'][0]['related_resources'][0]['sale']['state'];
  
  //$res=$this->verifyIPN($post);
  // state 为commpleted 表示确实支付了此单。不是伪装数据
  if ($state == 'completed') {
   //付款完成,这里修改订单状态,这里的业务逻辑你自己去写,根据系统后台。也就像修改订单的状态。没有加此方法
   // $rs=$this->pay_order($money,$order_sn,$payment_id);
   // if($rs!=true){
    // return false;
   // }
    return true;
   } else{
    //未通过认证,有可能是编码错误或非法的 POST 信息
    return false;
   }
  return false;
 }

 

3.获取token的方法,密码和clientid就用xxx表示

// 获取token
 public function access_token($type = '') {
  
  if ($type == 1) {
   $clientId = 'xxx';
   $secret = 'xxx';
   // 生产环境
   $url = "https://api.paypal.com/v1/oauth2/token";
  } else {
   $clientId = 'xxx';
   $secret = 'xxx';
   // 沙箱环境
   $url = "https://api.sandbox.paypal.com/v1/oauth2/token";
  }
  $ch = curl_init ();
  curl_setopt ( $ch, CURLOPT_URL, $url );
  curl_setopt ( $ch, CURLOPT_HEADER, false );
  curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
  curl_setopt ( $ch, CURLOPT_POST, true );
  curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
  curl_setopt ( $ch, CURLOPT_USERPWD, $clientId . ":" . $secret );
  curl_setopt ( $ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials" );
  $result = curl_exec ( $ch );
  curl_close ( $ch );
  if (empty ( $result )) {
   return false;
  } else {
   return json_decode ( $result, true );
  }
 }

 

4.根据token查询订单方法

 // 获取curl订单信息
 public function get_curlOrder($orderid, $token, $type = '') {
  if (empty ( $orderid ) || empty ( $token )) {
   return false;
  }
  
  if ($type == 1) {
   // 生产环境
   // $URL = "https://api.paypal.com/v1/checkout/orders/$orderid";
   // $URL = "https://api.paypal.com/v1/payments/orders/$orderid";
   $URL = "https://api.paypal.com/v1/payments/payment/$orderid";
  } else {
   // 沙箱环境
    // $URL = "https://api.sandbox.paypal.com/v1/checkout/orders/$orderid";
    // $URL = "https://api.sandbox.paypal.com/v1/payments/orders/$orderid";
   $URL = "https://api.sandbox.paypal.com/v1/payments/payment/$orderid";
  }
  $curl = curl_init ();
  curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, '0' );
  curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, '0' );
  
  curl_setopt_array ( $curl, array (
    CURLOPT_URL => $URL,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => array (
      "Authorization: Bearer {$token}",
      "Content-Type:application/json"
    )
  ) );
  $response = curl_exec ( $curl );
  curl_close ( $curl );
  return json_decode ( $response, true );
 }

 

php技术微信