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