1
votes

I'm trying to create a PayPal recurring subscription (Credit Card) using REST APIs:

Create Billing Plans - https://developer.paypal.com/docs/api/quickstart/create-billing-plan/

Create Billing Agreements - https://developer.paypal.com/docs/api/quickstart/create-billing-agreement/

I'm testing and playing around with the APIs and so I created two files plan.php and agreement.php.

plan.php is where I generate the plan ID and pass it statically in the agreement.php.

plan.php

<?php

require 'vendor/autoload.php';

$apiContext = new \PayPal\Rest\ApiContext(
  new \PayPal\Auth\OAuthTokenCredential(
    'Application-ID',    
    'Secret-ID'  
  )
);

use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;

use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
use PayPal\Api\CreditCard;
use PayPal\Api\FundingInstrument;

    $plan = new Plan();
    $plan->setName('T-Shirt of the Month Club Plan')
      ->setDescription('Template creation.')
      ->setType('fixed');

    // Set billing plan definitions
    $paymentDefinition = new PaymentDefinition();
    $paymentDefinition->setName('Regular Payments')
      ->setType('REGULAR')
      ->setFrequency('Month')
      ->setFrequencyInterval('2')
      ->setCycles('12')
      ->setAmount(new Currency(array('value' => 100, 'currency' => 'USD')));

// Set charge models
$chargeModel = new ChargeModel();
$chargeModel->setType('SHIPPING')
  ->setAmount(new Currency(array('value' => 10, 'currency' => 'USD')));
$paymentDefinition->setChargeModels(array($chargeModel));

// Set merchant preferences
$merchantPreferences = new MerchantPreferences();
$merchantPreferences->setReturnUrl('http://localhost:3000/processagreement')
  ->setCancelUrl('http://localhost:3000/cancel')
  ->setAutoBillAmount('yes')
  ->setInitialFailAmountAction('CONTINUE')
  ->setMaxFailAttempts('0')
  ->setSetupFee(new Currency(array('value' => 1, 'currency' => 'USD')));

$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);




//create plan
try {
  $createdPlan = $plan->create($apiContext);

  try {
    $patch = new Patch();
    $value = new PayPalModel('{"state":"ACTIVE"}');
    $patch->setOp('replace')
      ->setPath('/')
      ->setValue($value);
    $patchRequest = new PatchRequest();
    $patchRequest->addPatch($patch);
    $createdPlan->update($patchRequest, $apiContext);
    $plan = Plan::get($createdPlan->getId(), $apiContext);

    // Output plan id
    echo $plan->getId();
  } catch (PayPal\Exception\PayPalConnectionException $ex) {
    echo $ex->getCode();
    echo $ex->getData();
    die($ex);
  } catch (Exception $ex) {
    die($ex);
  }
} catch (PayPal\Exception\PayPalConnectionException $ex) {
  echo $ex->getCode();
  echo $ex->getData();
  die($ex);
} catch (Exception $ex) {
  die($ex);
}

and agreement.php

// Autoload SDK package for composer based installations
require 'vendor/autoload.php';

$apiContext = new \PayPal\Rest\ApiContext(
  new \PayPal\Auth\OAuthTokenCredential(
    'Application-ID',    
    'Secret-ID'  
  )
);

use PayPal\Api\ChargeModel;
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Common\PayPalModel;

use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\ShippingAddress;
use PayPal\Api\CreditCard;
use PayPal\Api\FundingInstrument;


// Create new agreement
// $agreement = new Agreement();
// $agreement->setName('Base Agreement')
//   ->setDescription('Basic Agreement')
//   ->setStartDate('2017-02-17T9:45:04Z');

// // Set plan id
// $plan = new Plan();
// $plan->setId('P-1CD306827C2019339JKC6JDY');
// $agreement->setPlan($plan);

// // Add payer type
// $payer = new Payer();
// $payer->setPaymentMethod('paypal');
// $agreement->setPayer($payer);

// // Adding shipping details
// $shippingAddress = new ShippingAddress();
// $shippingAddress->setLine1('111 First Street')
//   ->setCity('Saratoga')
//   ->setState('CA')
//   ->setPostalCode('95070')
//   ->setCountryCode('US');
// $agreement->setShippingAddress($shippingAddress);




//create new agreement
$agreement = new Agreement();
$agreement->setName('Base Agreement')
  ->setDescription('Basic Agreement')
  ->setStartDate('2017-02-17T9:45:04Z');

// Set plan id
$plan = new Plan();
$plan->setId('P-1CD306827C2019339JKC6JDY');
$agreement->setPlan($plan);

// Create credit card object and set funding instrument
$card = new CreditCard();
$card->setType("visa")
  ->setNumber("4250448816997456")
  ->setExpireMonth("06")
  ->setExpireYear("2018")
  ->setCvv2("012")
  ->setFirstName("Joe")
  ->setLastName("Shopper");

$fi = new FundingInstrument();
$fi->setCreditCard($card);

// Set payer to process credit card
$payer = new Payer();
$payer->setPaymentMethod("credit_card")
  ->setFundingInstruments(array($fi));
$agreement->setPayer($payer);

// Adding shipping details
$shippingAddress = new ShippingAddress();
$shippingAddress->setLine1('111 First Street')
  ->setCity('Saratoga')
  ->setState('CA')
  ->setPostalCode('95070')
  ->setCountryCode('US');
$agreement->setShippingAddress($shippingAddress);

$agreement = $agreement->create($apiContext);
// print_r($agreement); exit();


if (isset($_GET['success']) && $_GET['success'] == 'true') {
  $token = $_GET['token'];
  $agreement = new \PayPal\Api\Agreement();

  try {
    // Execute agreement
    $agreement->execute($token, $apiContext);
  } catch (PayPal\Exception\PayPalConnectionException $ex) {
    echo $ex->getCode();
    echo $ex->getData();
    die($ex);
  } catch (Exception $ex) {
    die($ex);
  }
} else {
    echo "user canceled agreement";
}

However it didn't return a token and the success variable is not set. I have printed the $agreement variable and below is the response:

PayPal\Api\Agreement Object
(
    [_propMap:PayPal\Common\PayPalModel:private] => Array
        (
            [name] => Base Agreement
            [description] => Basic Agreement
            [start_date] => 2017-02-17T17:45:04Z
            [plan] => PayPal\Api\Plan Object
                (
                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                        (
                            [payment_definitions] => Array
                                (
                                    [0] => PayPal\Api\PaymentDefinition Object
                                        (
                                            [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                (
                                                    [type] => REGULAR
                                                    [frequency] => Month
                                                    [amount] => PayPal\Api\Currency Object
                                                        (
                                                            [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                (
                                                                    [value] => 100.00
                                                                )

                                                        )

                                                    [cycles] => 12
                                                    [charge_models] => Array
                                                        (
                                                            [0] => PayPal\Api\ChargeModel Object
                                                                (
                                                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                        (
                                                                            [type] => TAX
                                                                            [amount] => PayPal\Api\Currency Object
                                                                                (
                                                                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                                        (
                                                                                            [value] => 0.00
                                                                                        )

                                                                                )

                                                                        )

                                                                )

                                                            [1] => PayPal\Api\ChargeModel Object
                                                                (
                                                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                        (
                                                                            [type] => SHIPPING
                                                                            [amount] => PayPal\Api\Currency Object
                                                                                (
                                                                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                                        (
                                                                                            [value] => 10.00
                                                                                        )

                                                                                )

                                                                        )

                                                                )

                                                        )

                                                    [frequency_interval] => 2
                                                )

                                        )

                                )

                            [merchant_preferences] => PayPal\Api\MerchantPreferences Object
                                (
                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                        (
                                            [setup_fee] => PayPal\Api\Currency Object
                                                (
                                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                        (
                                                            [value] => 1.00
                                                        )

                                                )

                                            [max_fail_attempts] => 0
                                            [auto_bill_amount] => YES
                                        )

                                )

                            [links] => Array
                                (
                                )

                            [currency_code] => USD
                        )

                )

            [payer] => PayPal\Api\Payer Object
                (
                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                        (
                            [payment_method] => credit_card
                            [payer_info] => PayPal\Api\PayerInfo Object
                                (
                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                        (
                                        )

                                )

                            [funding_instruments] => Array
                                (
                                    [0] => PayPal\Api\FundingInstrument Object
                                        (
                                            [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                (
                                                    [credit_card] => PayPal\Api\CreditCard Object
                                                        (
                                                            [_propMap:PayPal\Common\PayPalModel:private] => Array
                                                                (
                                                                    [type] => visa
                                                                    [number] => 7456
                                                                    [expire_month] => 06
                                                                    [expire_year] => 2018
                                                                    [first_name] => Edford Patrick
                                                                    [last_name] => Bedia
                                                                )

                                                        )

                                                )

                                        )

                                )

                        )

                )

            [shipping_address] => PayPal\Api\ShippingAddress Object
                (
                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                        (
                            [line1] => 111 First Street
                            [city] => Saratoga
                            [state] => CA
                            [postal_code] => 95070
                            [country_code] => US
                        )

                )

            [id] => I-9107LMJ0351R
            [state] => Active
            [links] => Array
                (
                    [0] => PayPal\Api\Links Object
                        (
                            [_propMap:PayPal\Common\PayPalModel:private] => Array
                                (
                                    [href] => https://api.sandbox.paypal.com/v1/payments/billing-agreements/I-9107LMJ0351R
                                    [rel] => self
                                    [method] => GET
                                )

                        )

                )

            [agreement_details] => PayPal\Api\AgreementDetails Object
                (
                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                        (
                            [outstanding_balance] => PayPal\Api\Currency Object
                                (
                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                        (
                                            [value] => 0.00
                                        )

                                )

                            [cycles_remaining] => 12
                            [cycles_completed] => 0
                            [next_billing_date] => 2017-02-17T10:00:00Z
                            [last_payment_date] => 2017-02-17T05:46:56Z
                            [last_payment_amount] => PayPal\Api\Currency Object
                                (
                                    [_propMap:PayPal\Common\PayPalModel:private] => Array
                                        (
                                            [value] => 1.00
                                        )

                                )

                            [final_payment_date] => 2018-12-17T10:00:00Z
                            [failed_payment_count] => 0
                        )

                )

        )

)

Any ideas why I can't get a token?

Thanks in advance.

1
We are making our own PHP - PAYPAL - LIBRARY If you want to use here is the link. - Tejas Mehta

1 Answers

0
votes

Here is your solution

1) you need to give Return URL as Execute.php while creating Plan.

2) You pass that plan ID to Billing Agreement

3) Your agreement.php print_r($agreement->toArray());

4) While Buyer approves agreement it will redirect to the Execute.php that is return Url set while creating plan.

5) in execute.php you will get token and success true.

You are adding code of Execute agreement after agreement create. That's why you are not getting success is set, you can Executes a billing agreement, by ID, after buyer approval. check below link.

https://developer.paypal.com/docs/api/payments.billing-agreements

So now you should remove the execute code from agreement.php and add execute.php with this

<?php

// #Execute Agreement
// This is the second part of CreateAgreement Sample.
// Use this call to execute an agreement after the buyer approves it
require __DIR__ . '/../bootstrap.php';

// ## Approval Status
// Determine if the user accepted or denied the request
if (isset($_GET['success']) && $_GET['success'] == 'true') {
    $token = $_GET['token'];
    $agreement = new \PayPal\Api\Agreement();
    try {
        // ## Execute Agreement
        // Execute the agreement by passing in the token
        $agreement->execute($token, $apiContext);
    } catch (Exception $ex) {
        // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
        ResultPrinter::printError("Executed an Agreement", "Agreement", $agreement->getId(), $_GET['token'], $ex);
        exit(1);
    }

    // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
    ResultPrinter::printResult("Executed an Agreement", "Agreement", $agreement->getId(), $_GET['token'], $agreement);

    // ## Get Agreement
    // Make a get call to retrieve the executed agreement details
    try {
        $agreement = \PayPal\Api\Agreement::get($agreement->getId(), $apiContext);
    } catch (Exception $ex) {
        // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
        ResultPrinter::printError("Get Agreement", "Agreement", null, null, $ex);
        exit(1);
    }

    // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
    ResultPrinter::printResult("Get Agreement", "Agreement", $agreement->getId(), null, $agreement);
} else {
    // NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
    ResultPrinter::printResult("User Cancelled the Approval", null);
}