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

Javascript 有没有办法使用PayPal REST API设置定期付款?,javascript,node.js,paypal,paypal-rest-sdk,Javascript,Node.js,Paypal,Paypal Rest Sdk,我阅读和阅读。他们两人(一年前)都表示,通过RESTAPI进行的定期付款正在进行中。在我客户的网站上,客户需要能够支付 全额(一次付清-例如,退房时为1200美元) 分期付款(6个月1200美元,每月200美元) 当客户付款时,通知他的网站是至关重要的。我目前已为选项1设置了此选项: 选项2(定期付款)是否有类似的设置。如果没有,PayPal是否有办法在用户每次用未付余额和已支付金额支付分期付款时通知我的服务器?我建议暂时不要使用REST API。它还没有完成,而经典的API给了你更多的灵活性

我阅读和阅读。他们两人(一年前)都表示,通过RESTAPI进行的定期付款正在进行中。在我客户的网站上,客户需要能够支付

  • 全额(一次付清-例如,退房时为1200美元)
  • 分期付款(6个月1200美元,每月200美元)
  • 当客户付款时,通知他的网站是至关重要的。我目前已为选项1设置了此选项:


    选项2(定期付款)是否有类似的设置。如果没有,PayPal是否有办法在用户每次用未付余额和已支付金额支付分期付款时通知我的服务器?

    我建议暂时不要使用REST API。它还没有完成,而经典的API给了你更多的灵活性

    我会使用定期付款的快速结账,然后您会希望使用来处理付款、取消的配置文件等

    IPN通知实际上会针对任何涉及您帐户的交易触发,因此您可以自动处理付款、退款、争议、订阅等。您可以根据这些交易类型更新数据库、发送电子邮件通知或任何其他需要自动处理的事项


    IPN是贝宝提供的最有价值的工具之一,但它也是利用率最高的工具之一

    我建议暂时不要使用RESTAPI。它还没有完成,而经典的API给了你更多的灵活性

    我会使用定期付款的快速结账,然后您会希望使用来处理付款、取消的配置文件等

    IPN通知实际上会针对任何涉及您帐户的交易触发,因此您可以自动处理付款、退款、争议、订阅等。您可以根据这些交易类型更新数据库、发送电子邮件通知或任何其他需要自动处理的事项


    IPN是贝宝提供的最有价值的工具之一,但它也是利用率最高的工具之一

    是的,现在有一种方法可以在新的RESTAPI中进行订阅。看

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

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

    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;
    }
    
    然后将访问数据存储在类属性中

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

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

    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);      
    }
    
    此方法将允许您分配并同意客户。 您需要aggreement的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);
    }
    
    然后,您需要创建一个计划任务来使用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;
    }
    

    是的,现在有一种方法可以在新的RESTAPI中进行订阅。看

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

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

    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;
    }
    
    然后将访问数据存储在类属性中

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

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

    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);      
    }
    
    此方法将允许您分配并同意客户。 您需要aggreement的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);
    }
    
    然后,您需要创建一个计划任务来使用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;
    }
    

    表示您应该调用
    GetTransactionDetails
    获取定期付款信息。由于您还可以从
    GetRecurringPaymentsProfileDetails
    获取下一个计划的计费日期,因此您可以将下一个计划的计费日期存储在数据库中,然后在此时间之后调用
    GetTransactionProfile
    ,检查是否已付款。表示您应该调用
    GetTransactionDetails
    获取定期付款信息。由于您还可以从<代码> GETCurrrPayPrimsPrimeDebug < /C>中获得下一个预定的计费日期,然后您可以将下一个预定的计费日期存储在您的数据库中,然后在该时间之后调用<代码> GETTraceActudioPrime>代码,以检查支付是否已生效。您是否认为利亚姆的回答仍然是不推荐的?我需要实现一个简单的定期支付,不需要任何
    IPN
    s之类的东西。我认为RESTAPI的支持非常好。只有文档非常复杂,它包含了与支付有关的大部分基本内容,但如果