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

查看:87
本文介绍了有没有办法使用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']. "\n";
            echo "Raw response:".$response."\n";
            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是最终用户将被发送到的网址,以完成aggreement。我用它来传递给下面的方法

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']. "\n";
            echo "Raw response:".$response."\n";
            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\n";
        curl_close($curl); // close cURL handler
        if($info['http_code'] != 200 && $info['http_code'] != 201 ) 
        {
            echo "Received error: " . $info['http_code']. "\n";
            echo "Raw response:".$response."\n";
            die();
        }
    }
    $jsonResponse = json_decode($response, TRUE);
    return $jsonResponse;
}

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

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