How to create recurring payment with PayPal (Credit cards and PayPal)

I had project to implement subscription on Laravel website with PayPal. PayPal have 3 types of API right now, I tried all of them. And find out that PayPal Payments Pro suites best for client needs. So I implement subscription payment with Credit Cards and with PayPal express redirect to PayPal website. Here is code, maybe if you are stuck will help you.

Install via composer PayPal Merchant account https://github.com/paypal/merchant-sdk-php

In controller include this classes:

use PayPal\Service\PayPalAPIInterfaceServiceService;
use PayPal\EBLBaseComponents\PaymentDetailsType;
use PayPal\CoreComponentTypes\BasicAmountType;
use PayPal\EBLBaseComponents\SetExpressCheckoutRequestDetailsType;
use PayPal\EBLBaseComponents\BillingAgreementDetailsType;
use PayPal\PayPalAPI\SetExpressCheckoutRequestType;
use PayPal\PayPalAPI\SetExpressCheckoutReq;
use PayPal\EBLBaseComponents\RecurringPaymentsProfileDetailsType;
use PayPal\EBLBaseComponents\BillingPeriodDetailsType;
use PayPal\EBLBaseComponents\ScheduleDetailsType;
use PayPal\EBLBaseComponents\CreateRecurringPaymentsProfileRequestDetailsType;
use PayPal\PayPalAPI\CreateRecurringPaymentsProfileRequestType;
use PayPal\PayPalAPI\CreateRecurringPaymentsProfileReq;
use PayPal\EBLBaseComponents\ActivationDetailsType;
use PayPal\EBLBaseComponents\CreditCardDetailsType;

For implementing PayPal checkout that redirect to PayPal website use two functions in PaymentController

First call SetExpressCheckout and PayPal will redirect to ReturnURL you specified in it.

ReturnURL execute another function ConfirmPaymentWithExpress and use token from SetExpressCheckout

 /**
     * Create Payment via PayPal Express checkout
     * @return \Illuminate\Http\RedirectResponse
     */
    public function SetExpressCheckout()
    {
        $config = array(
            'mode' => 'sandbox',
            'acct1.UserName' => 'your username from sandbox',
            'acct1.Password' => 'your password',
            'acct1.Signature' => 'your signature'
        );
        $paypalService = new PayPalAPIInterfaceServiceService($config);
        $paymentDetails = new PaymentDetailsType();

        $orderTotal = new BasicAmountType();
        $orderTotal->currencyID = 'USD'; //change this
        $orderTotal->value = '3.00'; //change this

        $paymentDetails->OrderTotal = $orderTotal;
        $paymentDetails->PaymentAction = 'Sale';

        $setECReqDetails = new SetExpressCheckoutRequestDetailsType();
        $setECReqDetails->PaymentDetails[0] = $paymentDetails;
        $setECReqDetails->CancelURL = 'http://domain.com/paypal-cancel'; //change this 
        $setECReqDetails->ReturnURL = 'http://domain.com/paypal-confirm'; //change this

        $billingAgreementDetails = new BillingAgreementDetailsType('RecurringPayments');
        $billingAgreementDetails->BillingAgreementDescription = 'Recurring';
        $setECReqDetails->BillingAgreementDetails = array($billingAgreementDetails);

        $setECReqType = new SetExpressCheckoutRequestType();
        $setECReqType->Version = '106.0';
        $setECReqType->SetExpressCheckoutRequestDetails = $setECReqDetails;

        $setECReq = new SetExpressCheckoutReq();
        $setECReq->SetExpressCheckoutRequest = $setECReqType;

        $setECResponse = $paypalService->SetExpressCheckout($setECReq);

        if ($setECResponse->Ack == 'Success') {
            $token = $setECResponse->Token;
            //printr($token);
            return Redirect::to('https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $token);

        } else {
            return Redirect::to('error')->with('message', 'There is a problem in payment processing.');
        }

    }
    


    /**
     * Confirm payment with express checkout and create recurring payment
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function confirmPaymentWithExpress(Request $request)
    {
        $token = $request->get('token');

        $profileDetails = new RecurringPaymentsProfileDetailsType();
        $profileDetails->BillingStartDate = date(DATE_ISO8601, strtotime(date('Y-m-d') . ' +1 day'));

        $paymentBillingPeriod = new BillingPeriodDetailsType();
        $paymentBillingPeriod->BillingFrequency = 1;//your own value
        $paymentBillingPeriod->BillingPeriod = "Day";  //change this

        $paymentBillingPeriod->Amount = new BasicAmountType("USD", "5.00"); //change this

        $activationDetails = new ActivationDetailsType();
        $activationDetails->InitialAmount = new BasicAmountType('USD', '4.00');  //change this
        $activationDetails->FailedInitialAmountAction = 'ContinueOnFailure';  //change this

        $scheduleDetails = new ScheduleDetailsType();
        $scheduleDetails->Description = "Recurring";
        $scheduleDetails->PaymentPeriod = $paymentBillingPeriod;
        $scheduleDetails->ActivationDetails = $activationDetails;

        $createRPProfileRequestDetails = new CreateRecurringPaymentsProfileRequestDetailsType();
        $createRPProfileRequestDetails->Token = $token;

        $createRPProfileRequestDetails->ScheduleDetails = $scheduleDetails;
        $createRPProfileRequestDetails->RecurringPaymentsProfileDetails = $profileDetails;

        $createRPProfileRequest = new CreateRecurringPaymentsProfileRequestType();
        $createRPProfileRequest->CreateRecurringPaymentsProfileRequestDetails = $createRPProfileRequestDetails;

        $createRPProfileReq = new CreateRecurringPaymentsProfileReq();
        $createRPProfileReq->CreateRecurringPaymentsProfileRequest = $createRPProfileRequest;


        $config = array(
            'mode' => 'sandbox',
            'acct1.UserName' => 'your username from sandbox',
            'acct1.Password' => 'your password',
            'acct1.Signature' => 'your signature'
        );
        $paypalService = new PayPalAPIInterfaceServiceService($config);
        $createRPProfileResponse = $paypalService->CreateRecurringPaymentsProfile($createRPProfileReq);

        printr($createRPProfileResponse);

        //Now we have to check if the recurring profile successfully created.

        if ($createRPProfileResponse->Ack == 'Success') {
            $profileId = $createRPProfileResponse->CreateRecurringPaymentsProfileResponseDetails->ProfileID;
            //your own logic to save details in database.

            return view('pages.payment-success');

        } else {

            return Redirect::to('error')->with('message', 'There is a problem in payment processing . ');
        }

    }

For implementing payment with credit cards use this function in PaymentController

 /**
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function confirmPaymentWithCreditCard()
    {
        $profileDetails = new RecurringPaymentsProfileDetailsType();
        $profileDetails->BillingStartDate = date(DATE_ISO8601, strtotime(date('Y-m-d') . ' +1 day'));
        //Since date start should be greater than current date.

        $paymentBillingPeriod = new BillingPeriodDetailsType();
        $paymentBillingPeriod->BillingFrequency = 1;//your own value
        $paymentBillingPeriod->BillingPeriod = "Day";//your own value

        $paymentBillingPeriod->Amount = new BasicAmountType("USD", "2.00");//your own value

        $activationDetails = new ActivationDetailsType();
        $activationDetails->InitialAmount = new BasicAmountType('USD', '2.50');
        $activationDetails->FailedInitialAmountAction = 'ContinueOnFailure';

        $scheduleDetails = new ScheduleDetailsType();
        $scheduleDetails->Description = "Recurring";
        $scheduleDetails->PaymentPeriod = $paymentBillingPeriod;
        $scheduleDetails->ActivationDetails = $activationDetails;

        $createRPProfileRequestDetails = new CreateRecurringPaymentsProfileRequestDetailsType();

        $creditCard = new CreditCardDetailsType();
        $creditCard->CreditCardNumber = "5555555555554444";
        $creditCard->CreditCardType = "MasterCard";
        $creditCard->CVV2 = "962";
        $creditCard->ExpMonth = 002;
        $creditCard->ExpYear = 2021;
        $createRPProfileRequestDetails->CreditCard = $creditCard;

        $createRPProfileRequestDetails->ScheduleDetails = $scheduleDetails;
        $createRPProfileRequestDetails->RecurringPaymentsProfileDetails = $profileDetails;

        $createRPProfileRequest = new CreateRecurringPaymentsProfileRequestType();
        $createRPProfileRequest->CreateRecurringPaymentsProfileRequestDetails = $createRPProfileRequestDetails;

        $createRPProfileReq = new CreateRecurringPaymentsProfileReq();
        $createRPProfileReq->CreateRecurringPaymentsProfileRequest = $createRPProfileRequest;


        $config = array(
            'mode' => 'sandbox',
            'acct1.UserName' => 'your username from sandbox',
            'acct1.Password' => 'your password',
            'acct1.Signature' => 'your signature'
        );
        $paypalService = new PayPalAPIInterfaceServiceService($config);
        $createRPProfileResponse = $paypalService->CreateRecurringPaymentsProfile($createRPProfileReq);

        //printr($createRPProfileResponse);

        //Now we have to check if the recurring profile successfully created.

        if ($createRPProfileResponse->Ack == 'Success') {
            $profileId = $createRPProfileResponse->CreateRecurringPaymentsProfileResponseDetails->ProfileID;
            //your own logic to save details in database.
//            printr($profileId);
//            printr($activationDetails);
//            echo "success";
            return view('pages.payment-success');

        } else {
//            printr($createRPProfileResponse);
//            echo "greska";

            return Redirect::to('error')->with('message', 'There is a problem in payment processing . ');
        }

    }

 

Leave a Reply

Your email address will not be published. Required fields are marked *