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 );
}