官方文档
https://developer.paypal.com/docs/classic/api/
准备工作
参考REST API https://blog.csdn.net/rty426/article/details/88246867的准备工作。注册账号,记录下测试PERSONAL账号账号密码,然后点击BUSSINESS账号的profile-API Credentials,记录下username password signature。
NVP API和REST API的流程类似,先调用SetExpressCheckout
创建授权信息,生成token,使用token拼接并跳转到授权访问url,用户授权成功后调用GetExpressCheckoutDetails
去获取订单信息,核对后将信息传到DoExpressCheckoutPayment
完成付款。
和 REST API生成accesstoken的验证方式不同,NVP API接口调用时post的参数以键值对形式存在。参数1=值1&参数2=值2(值需要转换成url编码),需要把username password signature version加入到每次调用接口所传数据中作为验证身份。
事例
访问index.php,create_payment函数构造订单信息,调用SetExpressCheckout
获取token后跳转到授权页面,用户确认付款后,跳转到index.php?a=excute 并附带参数token和PayerID,excute函数通过GetExpressCheckoutDetails
获取订单信息(商户核对信息),将信息传到DoExpressCheckoutPayment
完成确认付款。
Paypal.php
<?php
class Paypal{
protected $username;
protected $password;
protected $signature;
protected $baseUrl='https://api-3t.sandbox.paypal.com/nvp';
//protected $baseUrl='https://api-3t.paypal.com/nvp';
function __construct($username,$password,$signature){
$this->username = $username;
$this->password = $password;
$this->signature = $signature;
}
/*转化键值对为数组形式
*param
* $array string 需要转化的字符串:参数1=值1&参数2=值2
* return array 转化后的数组
* */
protected function keyvalue2array($string)
{
parse_str(urldecode($string),$return);
return $return;
}
/*转化数组为键值对形式
*param
* $array array 需要转化的数组
* return string 转化后的字符串:参数1=值1&参数2=值2
* */
protected function array2keyvalue($array)
{
$res=[];
foreach($array as $k=>$v){
if(is_array($v)){
//现在只支持一维数组&二维数组
foreach($v as $kk=>$vv){
$res[]=$k.'['.$kk.']='.$vv;
}
}else{
$res[]=$k.'='.urlencode($v);
}
}
return implode('&',$res);
}
public function httpRequest($data,$method)
{
$data['METHOD']=$method;
$data['PWD']=urlencode($this->password);
$data['USER']=urlencode($this->username);
$data['SIGNATURE']=urlencode($this->signature);
$data['METHOD']=$method;
$data['VERSION']='80';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->baseUrl);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($curl, CURLOPT_POSTFIELDS,$this->array2keyvalue($data));
curl_setopt($curl, CURLOPT_POST,1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $this->keyvalue2array($output);
}
}
index.php
<?php
$username='账号';
$password='密码';
$signature='签名';
include('Paypal.php');
$a=$_GET['a']?$_GET['a']:'create_payment';
$paypal = new paypal($username, $password, $signature);
$a($paypal);
function create_payment($paypal)
{
$excuteUrl='https://www.sandbox.paypal.com/webscr&cmd=_express-checkout&token=';
//$excuteUrl='https://www.paypal.com/webscr&cmd=_express-checkout&token=';
$returnURL = 'http://localhost/paypalNVP/?a=excute';
$cancelURL = 'http://localhost?/paypalNVP/a=cancel';
$data['ADDRESSOVERRIDE'] = '1';
$data['RETURNURL'] = $returnURL;
$data['CANCELURL'] = $cancelURL;
/*多个产品时,PAYMENTREQUEST_0_AMT PAYMENTREQUEST_1_AMT 填充多个产品信息 最多0~9 10个
*/
$data['PAYMENTREQUEST_0_AMT'] = $amt;
//货币代码
$data['PAYMENTREQUEST_0_CURRENCYCODE'] ='USD';
$data['L_PAYMENTREQUEST_0_NAME0'] = ‘产品名称’;
$data['L_PAYMENTREQUEST_0_AMT0'] = 100;
$data['L_PAYMENTREQUEST_0_QTY0'] = '1';
$data['PAYMENTREQUEST_0_ITEMAMT'] = 100;
/*产品信息结束*/
$res = $paypal->httpRequest($data, 'SetExpressCheckout');
if (strtolower($res["ACK"]) == 'success') {
header('Location:' . $excuteUrl . urlencode($res['TOKEN']));
exit;
}
}
function excute($paypal)
{
$data['TOKEN'] = $_GET['token'];
$res = $paypal->httpRequest($data, 'GetExpressCheckoutDetails');
if (strtolower($res["ACK"]) == 'success'||strtolower($res["ACK"]) == 'successwithwarning') {
$data['PAYERID']=$_GET['PayerID'];
$data['PAYMENTREQUEST_0_AMT']=$res['PAYMENTREQUEST_0_AMT'];
$data['PAYMENTREQUEST_0_CURRENCYCODE']=$res['PAYMENTREQUEST_0_CURRENCYCODE'];
$data['PAYMENTINFO_0_PAYMENTACTION']='Sale';
$data['PAYMENTREQUEST_0_INVNUM']=time();
$res = $paypal->httpRequest($data, 'DoExpressCheckoutPayment');
if(strtolower($res["ACK"]) == 'success'||strtolower($res["ACK"]) == 'successwithwarning'){
echo '支付成功';
}
}
}
function cancel($paypal)
{
echo '用户取消';
}
报错
所使用的环境是win10+apache2.4+php7.1,如果是使用php7.1以下版本,需要把构造数组$res=[];
改成$res=array();
。
有的人curl_exec
执行报错,并且echo curl_no($curl);
为35,是因为curl扩展使用的openssl版本过低,不支持TLS 1.2。
解决方式:如果是linux编译php时使用新版的openssl,如果是windows暂时只能用新版的php。