有没有办法用PayPal REST API设置定期付款?

我读了这个问题和这个 。 他们都表示(一年前)通过REST API进行的经常性支付正在进行中。 在我客户的网站上,客户需要能够支付

  1. (全部一次 – 例如,在退房1200美元)
  2. 分期付款(1200美元超过6个月,每月200美元)

客户付款时通知他的网站至关重要。 我目前已经设置了选项#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 )抓取所有正确的会话信息,我的数据库处理它。

 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有没有办法通知我的服务器每次用户支付未付余额和支付的金额/等的分期付款?

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

好的,首先您需要设置您从PayPal获得的客户端ID和密码。 我有一个testing和生活环境

所有{xxx}都是我的私有应用程序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; } 

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

然后你需要三个部分。 创build订阅模板,然后检索协议,然后为客户端创build协议。

在这种方法中,我发送数据名称,说明,时间段,时间间隔和价格。 但是,你可以手动填写。 这将创build您现在可以销售的订阅。

 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,使用下面的方法来收集订阅的数据并存储它

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

这个方法将允许你分配和同意一个客户端。 您将需要与您的一些数据的协议的id可以添加到说明。

 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。 我比使用它传递给下面的方法

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

然后,您将需要创build一个计划任务来使用retrieve_agreement方法,并查看订阅是否已被取消。

这是一个简单的解释。

如果你需要更多,请让我知道。

获取和发布

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

我现在build议远离REST API。 它只是不完整,经典的API给你更多的灵活性。

我会使用快速结账与循环付款,然后您将要使用即时付款通知(IPN)来处理处理付款,取消configuration文件等。

IPN通知实际上会触发任何有史以来最好的交易,所以你可以自动处理付款,退款,纠纷,订阅等。你可以更新你的数据库,发送电子邮件通知,或任何你需要自动化的基础在这些交易types上。

IPN是PayPal提供的最有价值的工具之一,但它也是利用率最低的工具之一。