标签归档:paypal

Paypal API

Paypal提供了两套API,REST API和NVP/SOAP API。REST API没有完全覆盖NVP API的功能,NVP API历史久远,未来应该会被REST API替换。

REST API使用OAuth2标准,首先需要有一个开发者账户,然后在开发者账户中创建APP(产生client_id, client_secret),Paypal账户授权给这个APP。

开发者网站:http://developer.paypal.com,然后需要注册一个真实的Paypal账户(可以个人,也可以商用),拿这个账户作为开发者账户去登录,然后就可以创建APP,分两个环境:正式和测试。如何创建一个测试APP,那么会自动给你创建一个测试商家账户,还有一个买家账户。当然也可以自己建多个测试账户。

——————————————————————-
在REST API之前,只有NVP API。为了可以使用NVP API,需要到自己的Paypal中的API设置中取到相关API签名(API用户名和密码,以及签名),只要暴露了这三个信息,就相当于是开放了自己的账户。

每个Paypal可以作为一个第三方,其它的Paypal账户如果把某些权限赋给了它,它就可以扮演第一方的身份去获取信息。关于权限赋予的流程,官方文档有详细描述。而Paypal后台的第三方许可,实际对应这个操作,最终都是赋予第三方权限。

这里需要输入的就是第三方Paypal账户的API的用户名(每个账户中的API签名部分),点击查找后会让你选择哪些权限赋予这个第三方:

结论:Paypal可以通过API签名开放账户,也可以把权限授予其它账户,由其它账户(第三方)代理访问。

<?php

namespace Paypal;

class Api
{
    protected $username = '';

    protected $password = '';

    protected $signature = '';

    protected $version = '95.0';

    protected $endPoint = 'https://api-3t.paypal.com/nvp';

    protected $subject = '';

    public function __construct($username, $password, $signature, $subject = '', $sandbox = false)
    {
        $this->username = $username;
        $this->password = $password;
        $this->signature = $signature;
        if (!empty($subject)) {
            $this->subject = trim($subject);
        }
        if ($sandbox) {
            $this->endPoint = 'https://api-3t.sandbox.paypal.com/nvp';
        }
    }

    // 作为第三方访问Paypal
    public function setSubject($email)
    {
        $this->subject = trim($email);
    }

    // 取回交易列表
    //$params = [
    //    'STARTDATE' => $startTime,
    //    'ENDDATE' => $endTime,
    //    'RECEIVER' => '',
    //    'TRANSACTIONCLASS' => 'All'
    //];
    public function getTransactions(array $params)
    {
        $return = ['success' => 0, 'message' => '', 'data' => []];
        if (empty($params['STARTDATE']) || empty($params['ENDDATE'])) {
            $return['message'] = '参数不合法';
            return $return;
        }

        $result = $this->post('TransactionSearch', $params);
        if (false === $result) {
            $return['message'] = 'CURL请求异常';
            return $return;
        }

        $tarr = explode('&', $result);
        $data = [];
        foreach ($tarr as $item) {
            $tmp = explode('=', rawurldecode($item));

            preg_match('/^L_([a-zA-Z\_]+)([0-9]+)/', $tmp[0], $m);
            if (isset($m[0]) && isset($m[1]) && isset($m[2])) {
                $data[$m[1]][$m[2]] = trim($tmp[1]);
            } else {
                $data[$tmp[0]] = trim($tmp[1]);
            }
        }

        // ACK 等于 Warming时,数据返回不齐全(Paypal每次查询最多返回100条)
        if (empty($data['ACK']) || ($data['ACK'] == 'Failure')) {
            $return['message'] = "API调用ACK返回Failure";
        } else {
            $return['success'] = 1;
            $return['data'] = $data;
        }

        return $return;
    }
 
    // 通用封装
    protected function post($api, array $params)
    {
        $global = [
            'METHOD' => $api,
            'VERSION' => $this->version,
            'USER' => $this->username,
            'PWD' => $this->password,
            'SIGNATURE' => $this->signature
        ];
        if (!empty($this->subject)) {
            $global['SUBJECT'] = $this->subject;
        }

        return $this->doRequest($this->endPoint, array_merge($global, $params));
    }

    // CURL请求
    protected function doRequest($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER, '');
        curl_setopt($ch, CURLOPT_URL, trim($url));
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 90);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
        if (!empty($data)) {
            if (is_array($data)) {
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            } elseif (is_string($data)) {
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            }
        }
        if (\PHP_OS === 'WINNT') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0");
        $result = curl_exec($ch);
        $error = curl_errno($ch);
        curl_close($ch);
        if ((int)$error == 0) {
            return $result;
        }
        return false;
    }
}