有没有办法使用 PayPal REST API 设置定期付款? [英] Is there a way to set up recurring payments with the PayPal REST API?

查看:22
本文介绍了有没有办法使用 PayPal REST API 设置定期付款?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阅读了 这个问题这个问题.他们都说(一年前)正在通过 REST API 进行定期付款.在我客户的网站上,客户需要能够付款

I read this question and this one. They both said (a year ago) that recurring payments via the REST API was in the works. On my client's website, customers need to be able to pay either

  1. 全款(一次性支付 - 例如,结账时支付 1200 美元)
  2. 分期付款(6 个月内 1200 美元,每月 200 美元)

在客户付款时通知他的网站至关重要.我目前已为选项 #1 进行了设置:

It is crucial that his website be notified when a customer pays. I have currently set this up for option #1:

app.get("/cart/checkout/paypal", isLoggedIn, isVerified, function (req, res) {
    var user = req.user;
    var paymentDetails = {
        "intent": "sale",
        "payer": { "payment_method": "paypal"},
        "redirect_urls": {
            "return_url": "http://localhost:5000/cart/checkout/success",
            "cancel_url": "http://localhost:5000/cart"
        },
        "transactions": [
            { "amount": { "total": user.cart.finalPrice.toFixed(2), "currency": "USD"},
            "description": "You are being billed for " + user.cart.finalPrice.toFixed(2)}
        ]
    };
    paypal.payment.create(paymentDetails, function (err, payment) {
        if (err) console.log(err);
        else {
            if (payment.payer.payment_method === "paypal") {
                req.session.paymentId = payment.id;
                var redirectURL;
                for (var i = 0; i < payment.links.length; i++) {
                    var link = payment.links[i];
                    if (link.method === "REDIRECT") redirectURL = link.href;
                }
                res.redirect(redirectURL);
            }
        }
    })
})

然后,"return_url" (/cart/checkout/success) 获取所有正确的会话信息,然后我的数据库处理它.

Then, the "return_url" (/cart/checkout/success) grabs all the correct session info and my database processes it.

app.get("/cart/checkout/success", isLoggedIn, isVerified, function (req, res) {
    var user = req.user,
        paymentId = req.session.paymentId,
        payerId = req.param("PayerID"),
        details = { "payer_id": payerId };
...

选项#2(定期付款)是否有类似的设置.如果没有,PayPal 是否可以在每次用户使用未结余额和已付金额/等支付分期付款时通知我的服务器?

Is there a similar setup for option #2 (recurring payments). If not, is there a way for PayPal to notify my server every time a user has paid an installment with the outstanding balance and amount paid/etc.?

推荐答案

是的,现在有一种方法可以在新的 REST API 中进行订阅.请参阅文档.

Yes, there is now a way to do subscriptions within the new REST API. See the documentation.

好的,首先您需要设置从 PayPal 获得的客户 ID 和密码.我有一个测试和现场环境

OK, first you need to set the Client ID and secret you get from PayPal. I have both a testing and live environment

所有 {xxx} 都是我的私有应用程序变量

All {xxx} are my private application variables

public function __construct()
{

    $this->sandbox = {sandbox};
    if($this->sandbox) 
    {
        $this->host = 'https://api.sandbox.paypal.com';
        $this->clientId = {clientIdSandbox};
        $this->clientSecret = {clientSecretSandbox};            
    }
    else 
    {
        $this->host = 'https://api.paypal.com';
        $this->clientId = {clientId};
        $this->clientSecret = {clientSecret};           
    }
    $this->get_access_token();
}

然后我去获取访问令牌

private function get_access_token() 
{
    $curl = curl_init($this->host.'/v1/oauth2/token'); 
    curl_setopt($curl, CURLOPT_POST, true); 
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_USERPWD, $this->clientId . ":" . $this->clientSecret);
    curl_setopt($curl, CURLOPT_HEADER, false); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($curl, CURLOPT_POSTFIELDS, 'grant_type=client_credentials'); 
    $response = curl_exec( $curl );
    if (empty($response)) 
    {
        echo "NO RESPONSE for $url for function ".__FUNCTION__;
        print_r(curl_getinfo($curl));
        die(curl_error($curl));
        curl_close($curl); // close cURL handler
    } 
    else 
    {
        $info = curl_getinfo($curl);
        curl_close($curl); // close cURL handler
        if($info['http_code'] != 200 && $info['http_code'] != 201 ) 
        {
            echo "Received error: " . $info['http_code']. "
";
            echo "Raw response:".$response."
";
            die();
        }
    }
    $jsonResponse = json_decode( $response );
    $this->token = $jsonResponse->access_token;
    $this->expires = time()+$jsonResponse->expires_in;
}

然后将访问数据存储在类属性中

This then stores the access data in the classes properties

然后您还需要三个部分.创建订阅模板,然后检索协议,然后为客户端创建协议.

You then need three more sections. Create the subscription template, then retrieve the agreement, then create the agreement for the client.

在这种方法中,我发送数据名称、描述、周期、间隔和价格.但是,您可以手动填写.这将创建您现在可以出售的订阅.

In this method I send over the data Name, Desc, Period, Interval and Price. However you can just fill in manually. This will create the subscription that you can now sell.

public function create_subscription($name, $desc, $period, $interval, $price)
{
    $data = array(
        'name' => $name,
        'description' => $desc,
        'type' => 'INFINITE',
        'payment_definitions' => array(
            0 => array (
                'name' => 'Payment Definition-1',
                'type' => 'REGULAR',
                'frequency' => $period,
                'frequency_interval' => $interval,
                'amount' => array(
                    'value' => $price,
                    'currency' => 'EUR',
                ),
                'cycles' => '0',
            ),
        ),
        'merchant_preferences' => array(
            'return_url'=>{return_url},
            'cancel_url'=>{cancel_url},
            'auto_bill_amount' => 'YES',
            'initial_fail_amount_action' => 'CONTINUE',
            'max_fail_attempts' => '0',
        ),
    );
    $data=json_encode($data);
    $url = $this->host.'/v1/payments/billing-plans';
    return $this->make_post_call($url, $data);  
}

从上面的方法你会得到一个id,在下面的方法中使用它来收集订阅的数据并存储

From the above method you will get in return an id, use that for the method below to collect the data of the subscription and store it

public function retrieve_agreement($id)
{
    $url = $this->host.'/v1/payments/billing-agreements/'.$id;
    return $this->make_get_call($url);      
}

此方法将允许您分配和同意客户.您将需要带有一些数据的协议 ID,以便您能够添加到描述中.

This method will allow you to allocate and agreement to a client. You will need the id of the aggreement with some data for you to be able add to the description.

public function create_agreement($subId, $data, $product)
{
    $paypalId = ($this->sandbox) ? $product->paypal_test_sub_id : $product->paypal_sub_id;
    $startDate = date('c', strtotime('+10 MINUTE'));
    $data = array (
        'name'=>'Subscription for subscription::'.$subId,
        'description'=>{company}.'  Subscription - ' . $data . ' - '.$product->name.' - '.$product->price .'€',
        'start_date'=>$startDate,
        'plan'=>array(
            'id'=>$paypalId,
        ),
        'payer'=>array(
            'payment_method'=>'paypal',
        ),
        'override_merchant_preferences'=>array(
            'return_url'=>{return_url}.$subId.'/',
            'cancel_url'=>{cancel_url}.$subId.'/',
        ),
    );  
    $data=json_encode($data);
    $url = $this->host.'/v1/payments/billing-agreements';
    $response = $this->make_post_call($url, $data);
    header("location:".$response['links'][0]['href']);      
    //return $response;
}

return_url 是最终用户将被发送到以完成协议的 URL.我比使用它传递给下面的方法

The return_url is the url that the end user will be sent to to complete the aggreement. I than use that to pass to the method below

public function execute_agreement($token)
{

    $data=json_encode('');
    $url = $this->host.'/v1/payments/billing-agreements/'.$token.'/agreement-execute';
    return $response = $this->make_post_call($url, $data);
}

然后您需要创建一个计划任务以使用retrieve_agreement 方法并查看订阅是否已取消.

You will then need to create a scheduled task to use the retrieve_agreement method and see if a subscription has been cancelled or not.

这是一个简短的解释.

如果您需要更多,请告诉我.

if you require more please let me know.

获取和发布

private function make_post_call($url, $postdata) 
{
    $curl = curl_init($url); 
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                'Authorization: Bearer '.$this->token,
                'Accept: application/json',
                'Content-Type: application/json'
                ));

    curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata); 
    $response = curl_exec( $curl );
    if (empty($response)) 
    {
        echo "NO RESPONSE for $url for function ".__FUNCTION__;
        print_r(curl_getinfo($curl));
        die(curl_error($curl));
        curl_close($curl); // close cURL handler
    } 
    else 
    {
        $info = curl_getinfo($curl);
        curl_close($curl); // close cURL handler
        if($info['http_code'] != 200 && $info['http_code'] != 201 ) 
        {
            echo "Received error: " . $info['http_code']. "
";
            echo "Raw response:".$response."
";
            die();
        }
    }
    $jsonResponse = json_decode($response, TRUE);
    return $jsonResponse;
}

private function make_get_call($url) 
{
    $curl = curl_init($url); 
    curl_setopt($curl, CURLOPT_POST, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                'Authorization: Bearer '.$this->token,
                'Accept: application/json',
                'Content-Type: application/json'
                ));
    $response = curl_exec( $curl );
    if (empty($response))
    {
        echo "NO RESPONSE for $url for function ".__FUNCTION__;
        print_r(curl_getinfo($curl));
        die(curl_error($curl));
        curl_close($curl); // close cURL handler
    } 
    else 
    {
        $info = curl_getinfo($curl);
        //echo "Time took: " . $info['total_time']*1000 . "ms
";
        curl_close($curl); // close cURL handler
        if($info['http_code'] != 200 && $info['http_code'] != 201 ) 
        {
            echo "Received error: " . $info['http_code']. "
";
            echo "Raw response:".$response."
";
            die();
        }
    }
    $jsonResponse = json_decode($response, TRUE);
    return $jsonResponse;
}

这篇关于有没有办法使用 PayPal REST API 设置定期付款?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆