PayPal Billing REST Api Php issue - php

I have an issue with Paypal REST Api billing (recurring payments).
I did exactly as in paypal documentation but when I click payment button it opens blank page (no errors in the error log).
Here is what I do:
Front End Button
<form action="WEBSITE/subscribe/paypal/paypal_agreement.php" method="POST">
<button type="submit" style="margin-top:10px;border: 0; background: transparent">
<img src="WEBSITE/wp-content/uploads/2017/05/paypal.png" style = "width:170px;" alt="submit" />
</button>
</form>
paypal_agreement.php (copy/paste from paypal docs)
<?php
require_once("../../paypal/vendor/autoload.php");
$createdPlan = require 'paypal_createplan.php';
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
use PayPal\Api\ShippingAddress;
$ppstartdate = date('c', time()+210);
$agreement = new Agreement();
$agreement->setName('Title Agreement')
->setDescription('Description Agreement')
->setStartDate($ppstartdate);
// Add Plan ID
// Please note that the plan Id should be only set in this case.
$plan = new Plan();
$plan->setId($createdPlan->getId());
$agreement->setPlan($plan);
// Add Payer
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
// ### Create Agreement
try {
// Please note that as the agreement has not yet activated, we wont be receiving the ID just yet.
$agreement = $agreement->create($apiContext);
// ### Get redirect url
// The API response provides the url that you must redirect
// the buyer to. Retrieve the url from the $agreement->getApprovalLink()
// method
$approvalUrl = $agreement->getApprovalLink();
header("Location: ".$approvalUrl);
} catch (Exception $ex) {
exit(1);
}
return $agreement;
?>
paypal_createplan.php (copy/paste from paypal docs)
<?php
require_once("../../paypal/vendor/autoload.php");
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
// Create a new instance of Plan object
$plan = new Plan();
// # Basic Information
// Fill up the basic information that is required for the plan
$plan->setName('Title Plan')
->setDescription('Description Subscription Plan')
->setType('fixed');
// # Payment definitions for this billing plan.
$paymentDefinition = new PaymentDefinition();
// The possible values for such setters are mentioned in the setter method documentation.
// Just open the class file. e.g. lib/PayPal/Api/PaymentDefinition.php and look for setFrequency method.
// You should be able to see the acceptable values in the comments.
$paymentDefinition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency('Month')
->setFrequencyInterval("1")
->setCycles("6")
->setAmount(new Currency(array('value' => 94.99, 'currency' => 'USD')));
$merchantPreferences = new MerchantPreferences();
$baseUrl = "https://websitelink.com";
$merchantPreferences->setReturnUrl("$baseUrl/subscribe/paypal/execute.php?success=true")
->setCancelUrl("$baseUrl/subscribe/paypal/execute.php?success=false")
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new Currency(array('value' => 0, 'currency' => 'USD')));
// ### Create Plan
try {
$output = $plan->create($apiContext);
} catch (Exception $ex) {
exit(1);
}
return $output;
?>
execute.php (copy/paste from paypal docs)
<?php
// #Execute Agreement
// This is the second part of CreateAgreement Sample.
// Use this call to execute an agreement after the buyer approves it
require_once("../../paypal/vendor/autoload.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) {
exit(1);
}
// ## Get Agreement
// Make a get call to retrieve the executed agreement details
try {
$agreement = \PayPal\Api\Agreement::get($agreement->getId(), $apiContext);
//done
header('Location: https://websitelink.com/subscribe/subscribe.php');
} catch (Exception $ex) {
exit(1);
}
} else {
$_SESSION['pmsg'] = $_SESSION['pmsg'].'<h2>Subscription Failed</h2>';
}
But I couldn't find anything about authentication OAuth2 (as for example with express checkout), nothing in documentation. Maybe it doesn't work because of that?

Variable $apiContext should contain paypal app authentication & setConfig

Is this: "Variable $apiContext should contain paypal app authentication & setConfig"
the solution to this issue?: I have an issue with Paypal REST Api billing (recurring payments). I did exactly as in paypal documentation but when I click payment button it opens blank page (no errors in the error log).
I am having a similiar issue. Pls confirm. And how do we get the paypal app authentication & setConfig?

Related

Laravel PayPal agreement-execute error on return url

I have two questions, first about the error, Laravel 8.20.1 + Paypal SDK v1.
App Routes:
Route::get('/agreement/execute', [PaymentController::class, 'agreementExecute']);
Route::post('/agreement/create', [PaymentController::class, 'subscribeMonthly']);
Admin Routes:
Route::prefix('paypal')->name('plan.')->group(function () {
Route::get('/monthly/create', [PrivatePaypal::class, 'createMonthly'])
Route::get('/list', [PrivatePaypal::class, 'showPlans'])
Route::get('/plan/{plan}', [PrivatePaypal::class, 'plan'])
Route::get('/delete', [PrivatePaypal::class, 'deletePlan'])
});
Created plan:
Created plan image
Plan code:
public function createMonthly() {
$plan = new \PayPal\Api\Plan();
$plan->setName('Monthly')
->setDescription('Activate partnership for one month.')
->setType('INFINITE'); // or FIXED: The plan has a fixed number of payment cycles
$paymentDefinition = new \PayPal\Api\PaymentDefinition();
$paymentDefinition->setName('Monthly Payments')
->setType('REGULAR') // or TRIAL
->setFrequency('Month') // or WEEK, DAY, YEAR, MONTH
->setFrequencyInterval("1") // The interval at which the customer is charged. Value cannot be greater than 12 months
->setAmount(new \PayPal\Api\Currency(array('value' => 20, 'currency' => 'USD')));
// ->setCycles("12")
$merchantPreferences = new \PayPal\Api\MerchantPreferences();
$merchantPreferences->setReturnUrl(route('account.agreement',['success'=>'true']))
->setCancelUrl(route('account.agreement',['success'=>'false']))
->setAutoBillAmount("yes")
->setInitialFailAmountAction("CONTINUE")
->setMaxFailAttempts("0")
->setSetupFee(new \PayPal\Api\Currency(array('value' => config('settings.price_monthly'), 'currency' => 'USD')))
;
$plan->setPaymentDefinitions(array($paymentDefinition));
$plan->setMerchantPreferences($merchantPreferences);
try {
$createdPlan = $plan->create($this->apiContext);
} catch(\Exception $ex) {
print_r($ex->getMessage());
die();
}
// dd($createdPlan);
$this->activatePlan($createdPlan);
}
After I send data with the form
<form action="https://site.test/agreement/create" method="post">
<input type="hidden" name="_token" value="XSM2gxx0Cqs5dlloYScQfl2GdeGqrz4lkWLfm42a">
<input type="hidden" name="_method" value="POST">
<input type="hidden" name="id" value="P-0UV961714R317531UT5H72WI">
<button class="button compact">Activate</button>
</form>
After succesful redirect to paypal with all data, i click accept (sandbox) and after that i get succesfull rerict back, redirect functions:
if (!empty($request->input('success')))
{
$success = $request->input('success');
if ($success && !empty($request->input('token')))
{
$token = $request->input('token');
$agreement = new \PayPal\Api\Agreement();
try {
// Execute agreement
$agreement->execute($token, $this->apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
print_r($ex->getMessage());
echo $ex->getCode();
echo $ex->getData();
print_r($ex->getData());
die($ex);
} catch (Exception $ex) {
// die($ex);
}
And when $agreement->execute runs I get errors with no detailed information.
Form subscribe function:
public function subscribeMonthly(Request $request) {
$id = $request->id;
$agreement = new \PayPal\Api\Agreement();
$agreement->setName('Monthly subscription')
->setDescription('Activate partnership for one month.')
->setStartDate(Carbon::now()->addMonth()->toIso8601String());
$plan = new \PayPal\Api\Plan();
$plan->setId($id);
$agreement->setPlan($plan);
$payer = new \PayPal\Api\Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
try {
$agreement = $agreement->create($this->apiContext);
$approvalUrl = $agreement->getApprovalLink();
} catch(\Exception $ex) {
print_r($ex->getMessage());
die();
}
return redirect($approvalUrl);
}
Error is : PayPal\Exception\PayPalConnectionException
Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/billing-agreements/EC-1LE052463N345662M/agreement-execute.
https://am.test/account/agreement?ba_token=BA-9X735270PX851462W&success=true&token=EC-1LE052463N345662M
I reviewed a lot of tutorials, re-read the code in PayPal guides several times. I'm new to this and can't figure out what the reason is, it just doesn't work for me. I do everything one to one.
No subscriptions are created in the buyer account or by the administrator, everything is empty.
And the second question, Paypal writes that v1 is deprecated. How can I use the second version with a checkout v2 for subscriptions and where can I find detailed guides with the Laravel about this question.
It's hard for me to fully understand API and code not created by myself, I create a big project on my own, but stuck a few days with that PayPal error. Thank you for reading so much of what I have written, I hope for your support.
The PayPal-PHP-SDK is deprecated, and not compatible with the current version of PayPal Subscriptions. You should not be using it for anything.
Instead, integrate directly with the necessary Product, Plan, and subscription management API calls described in that Subscriptions documentation. (Plus webhooks, if desired--to be notified of future subscription events)
You can also manage Products and Plans manually in the receiver account:
Sandbox: https://www.sandbox.paypal.com/billing/plans
Live: https://www.paypal.com/billing/plans

trigger webhook without payment execute?

I'm building paypal subscription system and i'm using web-hooks for notifying system on subscription created, active, etc.
However, it's required that user must return to success url and site execute $agreement->execute($token, $apiContext)); to make it work.
Let's say for some reason user never get back to return url then you will never execute payment and user will never get their subscription.
I've looked around on paypal documentation and couldn't find any solution.
Here's my code:
Subscribe.php:
$agreement = new Agreement();
$agreement->setName('Basic Plan')
->setDescription('Some info')
->setStartDate($date);
$plan = new Plan();
$plan->setId('PLAN_ID');
$agreement->setPlan($plan);
// Add Payer
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
// Add Shipping Address
$shippingAddress = new ShippingAddress();
$shippingAddress->setLine1('111 First Street')
->setCity('Saratoga')
->setState('CA')
->setPostalCode('95070')
->setCountryCode('US');
$agreement->setShippingAddress($shippingAddress);
// ### Create Agreement
try {
$agreement = $agreement->create($apiContext);
$agreement->getApprovalLink()
// method
$approvalUrl = $agreement->getApprovalLink();
redirect($approvalUrl);
} catch (Exception $ex) {
print_r($ex->getData());
}
index.php
if (isset($_GET['status']) && $_GET['status'] == 'success') {
$token = $_GET['token'];
$agreement = new \PayPal\Api\Agreement();
try {
// ## Execute Agreement
// Execute the agreement by passing in the token
echo "<pre>";
print_r($agreement->execute($token, $apiContext));
} catch (Exception $ex) {
exit(1);
}
} else {
echo "User Cancelled the Approval";
}

Searching for Paypal records by paymentId at Paypal account

I have a site that uses the Paypal Rest API SDK and successfully capture the paymentId after the transaction.
I capture it from the return_url's $_SERVER['QUERY_STRING'] using PHP.
I was hoping my Client would be able to then go into their Paypal account and search for records using these PaymentID's. It doesn't seem the case. There is a TransactionID but it does not match the PaymentID.
Any idea how to either:
Search for the record in a Paypal Account using the PaymentID (using the Paypal Account interface record tools - not api programming)
Grab the transactionID after the transaction (the return URL only gives me PaymentID, Token, and PayerID.)
I've realized that I will need to take the PaymentID and use the SDK to retrieve more detailed payment information.
$apiContext = $this->getApiContext();
$payment = new Payment();
$payment = $payment->get( $paymentId, $apiContext );
$execution = new PaymentExecution();
$execution->setPayerId( $_GET['PayerID'] );
// ### Retrieve payment
// Retrieve the payment object by calling the
// static `get` method
// on the Payment class by passing a valid
// Payment ID
// (See bootstrap.php for more on `ApiContext`)
try {
$payment->execute( $execution, $apiContext );
if ( $payment ) {
$obj = json_decode( $payment );
//GET SOME STUFF
$paypal_payment_id = $obj->{'id'};
$status = $obj->{'state'};
//DO SOMETHING WITH IT
}
} catch ( Exception $ex ) {
// NOTE: PLEASE DO NOT USE RESULTPRINTER CLASS IN YOUR ORIGINAL CODE. FOR SAMPLE ONLY
//ResultPrinter::printError("Get Payment", "Payment", null, null, $ex);
log_message( 'error', 'error=' . $ex );
//exit(1);
}

PayPal PHP SDK - cancel invoice function does nothing

I am using the PayPal SDK for PHP, I am trying to cancel an invoice, the result returned is "true", there isn't exception returned, but the invoice is not canceled. Please could you tell me if there is an error in my code?
$Invoice = new Invoice();
try {
$invoice = $Invoice->get($id_invoice, $apiContext);
$notify = new CancelNotification();
$notify->setSubject("Past due")
->setNote("Canceling invoice")
->setSendToMerchant(true)
->setSendToPayer(true);
$result = $Invoice->cancel($notify, $apiContext);
} catch (Exception $ex) {
$result = self::getException($ex);
}
return $result;
First get an invoice object like this:
$invoice = Invoice::get($invoiceId, $apiContext);
Then, you could do the following to cancel it.
// ### Cancel Notification Object
// This would send a notification to both merchant as well
// the payer about the cancellation. The information of
// merchant and payer is retrieved from the invoice details
$notify = new CancelNotification();
$notify
->setSubject("Past due")
->setNote("Canceling invoice")
->setSendToMerchant(true)
->setSendToPayer(true);
// ### Cancel Invoice
// Cancel invoice object by calling the
// static `cancel` method
// on the Invoice class by passing a valid
// notification object
// (See bootstrap.php for more on `ApiContext`)
$cancelStatus = $invoice->cancel($notify, $apiContext);
Also, to test the code, you could always run the samples, and test it out yourself, by just clicking a button.
I ran the sample to cancel an invoice, and then use the similar information provided back on get response of invoice:
"metadata": {
"created_date": "2015-02-04 13:12:33 PST",
"first_sent_date": "2015-02-04 13:12:34 PST",
"last_sent_date": "2015-02-04 13:12:34 PST",
"payer_view_url": "https://www.sandbox.paypal.com/cgi_bin/webscr?cmd=_pay-inv&viewtype=altview&id=INV2-6S46-MLLN-3FEA-VLZE"
}
Opening the URL showed me that the invoice was cancelled as shown below:

Paypal PHP REST service - "access token does not have required scope"

I'm coding in PHP using the Paypal REST SDK. I've set up my Sandbox account to use AUD. I worked this out after realising that my initial transactions were in USD and the transactions were getting held.
Using my revised code I'm trying to create payment - I assume I'll get back a URL which will allow me to redirect the user to approve the payment.
I'm getting a message which says:
Exception: Got Http response code 403 when accessing https://api.sandbox.paypal.com/v1/payments/payment. Retried 0 times.
string(215) "{"name":"REQUIRED_SCOPE_MISSING","message":"Access token does not have required scope","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#REQUIRED_SCOPE_MISSING","debug_id":"34683601f5dcd"}"
My code is:
$apiContext = new ApiContext(new OAuthTokenCredential(
'xxxxxx',
'xxxxxx'));
//### FundingInstrument
// A resource representing a Payer's funding instrument.
// For direct credit card payments, set the CreditCard
// field on this object.
$fi = new FundingInstrument();
$creditCardToken = new CreditCardToken();
$creditCardToken->setCreditCardId($creditcard->cardToken);
$fi->setCreditCardToken($creditCardToken);
// ### Payer
// A resource representing a Payer that funds a payment
// For direct credit card payments, set payment method
// to 'credit_card' and add an array of funding instruments.
$payer = new Payer();
$payer->setPaymentMethod("credit_card")
->setFundingInstruments(array($fi));
// ### Itemized information
// (Optional) Lets you specify item wise
// information
$paymentItems=Yii::app()->session['paymentitems'];
$items=array();
$total=0;
foreach ($paymentItems as $item)
{
$pp_item = new Item();
$pp_item->setName("Donation to ".$item->organisation->organisationName)
->setCurrency('AUD')
->setQuantity(1)
->setPrice($item->amount);
array_push($items,$pp_item);
$total+=(float)$item->amount;
}
$itemList = new ItemList();
$itemList->setItems($items);
// ### Amount
// Lets you specify a payment amount.
// You can also specify additional details
// such as shipping, tax.
$amount = new Amount();
$amount->setCurrency("AUD")
->setTotal($total);
// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it.
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description");
// ### Payment
// A Payment Resource; create one using
// the above types and intent set to sale 'sale'
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setTransactions(array($transaction));
// ### Create Payment
// Create a payment by calling the payment->create() method
// with a valid ApiContext (See bootstrap.php for more on `ApiContext`) href
// The return object contains the state.
try {
$response=$payment->create($apiContext);
var_dump($response);
//$this->redirect($response->links[0]->href);
} catch (PayPal\Exception\PPConnectionException $ex) {
echo "Exception: " . $ex->getMessage() . PHP_EOL;
var_dump($ex->getData());
exit(1);
}
Any thoughts as to what this message means. It would seem that direct credit card payments are not supported by Paypal in Australia, but I don't think that's the problem.
In your Paypal developer account, under My Apps > [Your App], make sure the feature you are trying to use is enabled in the APP SETTINGS section.

Categories