Friday 15 May 2015

Paypal Rest API Integration with Zend Framework

Paypal vault API with Do Direct Payment: It use the paypal REST API.
In this process, website process the credit card at their end and stored the credit card at paypal end. When we save credit card at paypal then credit_card_id is return for same credit card.

Now, when we need to charge the customer from their account. we need not to ask for same credit card details. Just use the credit_card_id to charge them.


Please get clientId and secretKey from https://developer.paypal.com/developer/applications, If you have not.

Paypal Rest API Integration with Zend Framework


How to Store a credit card with vault API (Zend Framework)
For this you need to two API call.
1. Get the Access token from paypal (In REST API, for every call you need to get a valid Access token).
2. Store the Credit card in paypal and save the returned credit_card_id in your database. (returned credit_card_id will be used to charge the money from customer credit cards).

class PaypalController extends Zend_Controller_Action {
    protected $_clientId='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
    protected $_secretKey='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; 


    /** Get Access Token Valut API **/
    protected function _getAccessKey($clientId, $clientSecret) {
        $accessToken = '';
        $url = "https://api.sandbox.paypal.com/v1/oauth2/token";
        try {

            $config = array(
                'adapter' => 'Zend_Http_Client_Adapter_Curl',
                'curloptions' => array(
                    CURLOPT_FOLLOWLOCATION => TRUE,
                    CURLOPT_SSL_VERIFYPEER => FALSE,
                    CURLOPT_USERPWD => "{$clientId}:{$clientSecret}"
                ),
            );
            $client = new Zend_Http_Client($url, $config);
            $postArray = array('grant_type' => 'client_credentials');
            $client->setParameterPost($postArray);

            $response = $client->request('POST');
            $response = json_decode($response->getBody());
            $accessToken = $response->access_token;
        } catch (Exception $e) {
            $e->getMessage();
            die;
        }
        return $accessToken;
    }


    protected function _storedCCDetails($clientId, $clientSecret,$accessToken,$creditCardDtls){
        $url = "https://api.sandbox.paypal.com/v1/vault/credit-cards";
        $config = array(
            'adapter' => 'Zend_Http_Client_Adapter_Curl',
            'curloptions' => array(
                CURLOPT_FOLLOWLOCATION => TRUE,
                CURLOPT_SSL_VERIFYPEER => FALSE,
                CURLOPT_USERPWD => "{$clientId}:{$clientSecret}"
            ),
        );
        $client = new Zend_Http_Client($url, $config);
        
        
        $client->setHeaders('Content-Type', 'application/json');
        $client->setHeaders('Authorization', "Bearer $accessToken");
        $response = $client->setRawData(json_encode($creditCardDtls), 'application/json')->request('POST');
        $data = json_decode($response->getBody());
        return $data;
    }

    function storecreditcardAction(){
        /** Get Access Token **/
        $accessToken = $this->_getAccessKey($this->clientId, $this->secretKey);
        /** Get Access Token **/

        //store credit card details
        $creditCardDtls = array(
        "payer_id" => "user1234567",
        "type" => "visa",
        "number" => "4417119669820331",
        "expire_month" => "11",
        "expire_year" => "2018",
        "first_name" => "Betsy",
        "last_name" => "Buyer",
        "billing_address" => array(
            "line1" => "111 First Street",
            "city" => "Mohali",
            "country_code" => "IN",
            "state" => "punjab",
            "postal_code" => "4252"
        )
        );

        $details = $this->_storedCCDetails($this->clientId, $this->secretKey,$accessToken, $creditCardDtls);

        //This is payer Account ID
        echo $payerId = $details->payer_id; echo '\n';
        //this is credit card Id used for pyament
        echo $creditCardId= $details->id;die;
    }

}

When we call /paypal/store-storecreditcard It will save the credit card detail and return the credit_card_id and payer_id.
Both (credit_card_id and payer_id) will be used for charge the payment from customer Account.

If we print_r the variable of $details, It will return following output.
 stdClass Object
(
    [id] => CARD-1FV197973J134115GKVKZMYQ //This is credit card Id
    [state] => ok
    [payer_id] => user12345 //This is userId
    [type] => visa
    [number] => xxxxxxxxxxxx0331
    [expire_month] => 11
    [expire_year] => 2018
    [first_name] => Betsy
    [last_name] => Buyer
    [billing_address] => stdClass Object
        (
            [line1] => 111 First Street
            [city] => Mohali
            [state] => punjab
            [postal_code] => 4252
            [country_code] => IN
        )

    [valid_until] => 2018-05-14T00:00:00Z
    [create_time] => 2015-05-15T06:46:58Z
    [update_time] => 2015-05-15T06:46:58Z
    [links] => Array
        (
            [0] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-1FV197973J134115GKVKZMYQ
                    [rel] => self
                    [method] => GET
                )

            [1] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-1FV197973J134115GKVKZMYQ
                    [rel] => delete
                    [method] => DELETE
                )

            [2] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-1FV197973J134115GKVKZMYQ
                    [rel] => patch
                    [method] => PATCH
                )

        )

) 




To charge the money from customer, you need to add below function in about class.
    function restSaleAction(){

        /** Get Access Token **/
        $accessToken = $this->_getAccessKey($this->clientId, $this->secretKey);
        /** Get Access Token **/
        
        
        $postData = new stdClass();
        $postData->intent ='sale';
        $postData->payer->payment_method ='credit_card';
        $postData->payer->funding_instruments[0]->credit_card_token->credit_card_id='CREDIT_CARD_ID_STORED_IN_PAYPAL';
        $postData->payer->funding_instruments[0]->credit_card_token->payer_id ='PAYER_ID';        
        $postData->transactions[0]->amount->total='15';
        $postData->transactions[0]->amount->currency='USD';
        $postData->transactions[0]->description='15 dollar Payment';
        $json = json_encode($postData); 

        $url = "https://api.sandbox.paypal.com/v1/payments/payment";
        $config = array(
            'adapter' => 'Zend_Http_Client_Adapter_Curl',
            'curloptions' => array(
                CURLOPT_FOLLOWLOCATION => TRUE,
                CURLOPT_SSL_VERIFYPEER => FALSE,
                CURLOPT_USERPWD => "{$this->clientId}:{$this->secretKey}"
            ),
        );
        $client = new Zend_Http_Client($url, $config);
     
        
        $client->setHeaders('Content-Type', 'application/json');
        $client->setHeaders('Authorization', "Bearer $accessToken");
        $response = $client->setRawData($json, 'application/json')->request('POST');
        $data = json_decode($response->getBody());
        print_r($data ); 
    }

To charge the payment from customer account,call below URL /payment/rest-sale
If we print_r($data), It will give following details.
stdClass Object
(
    [id] => PAY-199381315V473173TKVKZW2Q
    [create_time] => 2015-05-15T07:08:26Z
    [update_time] => 2015-05-15T07:08:55Z
    [state] => approved
    [intent] => sale
    [payer] => stdClass Object
        (
            [payment_method] => credit_card
            [funding_instruments] => Array
                (
                    [0] => stdClass Object
                        (
                            [credit_card_token] => stdClass Object
                                (
                                    [credit_card_id] => CARD-1FV197973J134115GKVKZMYQ
                                    [payer_id] => user12345
                                    [last4] => 0331
                                    [type] => visa
                                    [expire_month] => 11
                                    [expire_year] => 2018
                                )

                        )

                )

        )

    [transactions] => Array
        (
            [0] => stdClass Object
                (
                    [amount] => stdClass Object
                        (
                            [total] => 6.70
                            [currency] => USD
                            [details] => stdClass Object
                                (
                                    [subtotal] => 6.70
                                )

                        )

                    [description] => This is the payment transaction description.
                    [related_resources] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [sale] => stdClass Object
                                        (
                                            [id] => 13S217192H4845408
                                            [create_time] => 2015-05-15T07:08:26Z
                                            [update_time] => 2015-05-15T07:08:55Z
                                            [amount] => stdClass Object
                                                (
                                                    [total] => 6.70
                                                    [currency] => USD
                                                )

                                            [state] => completed
                                            [parent_payment] => PAY-199381315V473173TKVKZW2Q
                                            [links] => Array
                                                (
                                                    [0] => stdClass Object
                                                        (
                                                            [href] => https://api.sandbox.paypal.com/v1/payments/sale/13S217192H4845408
                                                            [rel] => self
                                                            [method] => GET
                                                        )

                                                    [1] => stdClass Object
                                                        (
                                                            [href] => https://api.sandbox.paypal.com/v1/payments/sale/13S217192H4845408/refund
                                                            [rel] => refund
                                                            [method] => POST
                                                        )

                                                    [2] => stdClass Object
                                                        (
                                                            [href] => https://api.sandbox.paypal.com/v1/payments/payment/PAY-199381315V473173TKVKZW2Q
                                                            [rel] => parent_payment
                                                            [method] => GET
                                                        )

                                                )

                                        )

                                )

                        )

                )

        )

    [links] => Array
        (
            [0] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/payments/payment/PAY-199381315V473173TKVKZW2Q
                    [rel] => self
                    [method] => GET
                )

        )

)

Look up a stored credit card This API is used to look up details of a credit card.
    function lookupAction(){
        /** Test Account **/         
        $clientId = 'ATuptMp3UudN3gLlbnBlZU3WTCecGskG6igWX1BhqNT-J4u333fIorUupt4QFHWsgeFdTGbO9oYMMU0f';
        $clientSecret = 'EGmdEqOEE2Xv6OH9fEfNw_OTg-0Zx72PqDab8y3JvGjx9TBY1KyeHN_V2CMX5WVmaeoKnwEvLykta-4v';
        /** Test Account **/ 
        
        /** Get Access Token **/
        $accessToken = $this->_getAccessKey($clientId, $clientSecret);
        /** Get Access Token **/
        
        $creditCardId='CARD-7P651358M81515745KVOB4MY';
        $url = "https://api.sandbox.paypal.com/v1/vault/credit-cards/".$creditCardId;
        
        
        
        $config = array(
            'adapter' => 'Zend_Http_Client_Adapter_Curl',
            'curloptions' => array(
                CURLOPT_FOLLOWLOCATION => TRUE,
                CURLOPT_SSL_VERIFYPEER => FALSE,
                CURLOPT_USERPWD => "{$clientId}:{$clientSecret}"
            ),
        );
        $client = new Zend_Http_Client($url, $config);
        
        
        $client->setHeaders('Content-Type', 'application/json');
        $client->setHeaders('Authorization', "Bearer $accessToken");
        $response = $client->setRawData(json_encode(array()), 'application/json')->request('GET');
        $body= $response->getBody();
        pr(json_decode($body));        die;
        // 
    }

When we call paypal/lookup, it will give following output:
stdClass Object
(
    [id] => CARD-7P651358M81515745KVOB4MY
    [state] => ok
    [payer_id] => arunkumar10
    [type] => visa
    [number] => xxxxxxxxxxxx0331
    [expire_month] => 11
    [expire_year] => 2018
    [first_name] => Arun
    [last_name] => Kumar
    [billing_address] => stdClass Object
        (
            [line1] => Sector 70
            [city] => Mohali
            [state] => punjab
            [postal_code] => 160055
            [country_code] => IN
        )

    [valid_until] => 2018-05-19T00:00:00Z
    [create_time] => 2015-05-20T05:40:03Z
    [update_time] => 2015-05-20T05:40:03Z
    [links] => Array
        (
            [0] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-7P651358M81515745KVOB4MY
                    [rel] => self
                    [method] => GET
                )

            [1] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-7P651358M81515745KVOB4MY
                    [rel] => delete
                    [method] => DELETE
                )

            [2] => stdClass Object
                (
                    [href] => https://api.sandbox.paypal.com/v1/vault/credit-cards/CARD-7P651358M81515745KVOB4MY
                    [rel] => patch
                    [method] => PATCH
                )

        )

)



Delete the credit card from paypal which is stored with vault API.
Use DELETE method to delete the credit card from paypal, for this you need only credit card_id
    function deleteAction(){
        /** Test Account **/ 
        $clientId = 'ATuptMp3UudN3gLlbnBlZU3WTCecGskG6igWX1BhqNT-J4u333fIorUupt4QFHWsgeFdTGbO9oYMMU0f';
        $clientSecret = 'EGmdEqOEE2Xv6OH9fEfNw_OTg-0Zx72PqDab8y3JvGjx9TBY1KyeHN_V2CMX5WVmaeoKnwEvLykta-4v';
        /** Test Account **/ 
         
        
        /** Get Access Token **/
        $accessToken = $this->_getAccessKey($clientId, $clientSecret);
        /** Get Access Token **/
        
       $creditCardId='CARD-7P651358M81515745KVOB4MY';
        $url = "https://api.sandbox.paypal.com/v1/vault/credit-cards/".$creditCardId;
        $config = array(
            'adapter' => 'Zend_Http_Client_Adapter_Curl',
            'curloptions' => array(
                CURLOPT_FOLLOWLOCATION => TRUE,
                CURLOPT_SSL_VERIFYPEER => FALSE,
                CURLOPT_USERPWD => "{$clientId}:{$clientSecret}"
            ),
        );
        $client = new Zend_Http_Client($url, $config); 
        
        $client->setHeaders('Content-Type', 'application/json');
        $client->setHeaders('Authorization', "Bearer $accessToken");
        $response = $client->setRawData(json_encode(array()), 'application/json')->request('DELETE');
        echo $response->getBody();die; 
    }


Note:
1. I have test with paypal sandbox account .
2. For vault API, you need an business account. (No need for Business Pro Account)
2. As you are processing credit card in your website, you must apply for PCI compliance.