I'm trying to integrate payment gateway (paypal) with laravel 5.1. I found some solutions for laravel 4, but none for laravel 5.0 and above.
I have been following all the steps mentioned in this link. xroot/laravel-paypalpayment
But I am getting FatalErrorException in PaypalPaymentController.php line 10:
I've attached my Paypal ntegration code, and a screen shot of the error.
Router.php
resource('payment','PaymentController');
app.php
Anouar\Paypalpayment\PaypalpaymentServiceProvider::class,
'Paypalpayment' => Anouar\Paypalpayment\Facades\PaypalPayment::class,
PaypalPaymentController.php
<?php
namespace my_app\Http\Controllers;
use Illuminate\Support\Facades\Cache;
use Illuminate\Http\Request;
use my_app\Http\Requests;
use my_app\Http\Controllers\Controller;
use Paypalpayment;
class PaypalPaymentController extends Facades {
private $_apiContext;
private $_ClientId=''/* ... */;
private $_ClientSecret=''/* ... */;
public function __construct(){
// ### Api Context
// Pass in a `ApiContext` object to authenticate
// the call. You can also send a unique request id
// (that ensures idempotency). The SDK generates
// a request id if you do not pass one explicitly.
$this->_apiContext = Paypalpayment:: ApiContext(
Paypalpayment::OAuthTokenCredential(
$this->_ClientId,
$this->_ClientSecret
)
);
// dynamic configuration instead of using sdk_config.ini
$this->_apiContext->setConfig(array(
'mode' => 'sandbox',
'http.ConnectionTimeOut' => 30,
'log.LogEnabled' => true,
'log.FileName' => __DIR__.'/../PayPal.log',
'log.LogLevel' => 'FINE'
));
}
/*
* Create payment using credit card
* url:payment/create
*/
public function create(){
// ### Address
// Base Address object used as shipping or billing
// address in a payment. [Optional]
$addr= Paypalpayment::Address();
$addr->setLine1(/* ... */);
$addr->setLine2(/* ... */);
$addr->setCity(/* ... */);
$addr->setState(/* ... */);
$addr->setPostal_code(/* ... */);
$addr->setCountry_code(/* ... */);
$addr->setPhone(/* ... */);
// ### CreditCard
// A resource representing a credit card that can be
// used to fund a payment.
$card = Paypalpayment::CreditCard();
$card->setType(/* ... */);
$card->setNumber(/* ... */);
$card->setExpire_month(/* ... */);
$card->setExpire_year(/* ... */);
$card->setCvv2(/* ... */);
$card->setFirst_name(/* ... */);
$card->setLast_name(/* ... */);
$card->setBilling_address($addr);
// ### FundingInstrument
// A resource representing a Payer's funding instrument.
// Use a Payer ID (A unique identifier of the payer generated
// and provided by the facilitator. This is required when
// creating or using a tokenized funding instrument)
// and the `CreditCardDetails`
$fi = Paypalpayment::FundingInstrument();
$fi->setCredit_card($card);
// ### Payer
// A resource representing a Payer that funds a payment
// Use the List of `FundingInstrument` and the Payment Method
// as 'credit_card'
$payer = Paypalpayment::Payer();
$payer->setPayment_method("credit_card");
$payer->setFunding_instruments(array($fi));
// ### Amount
// Let's you specify a payment amount.
$amount = Paypalpayment:: Amount();
$amount->setCurrency("USD");
$amount->setTotal("1.00");
// ### Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it. Transaction is created with
// a `Payee` and `Amount` types
$transaction = Paypalpayment:: Transaction();
$transaction->setAmount($amount);
$transaction->setDescription("This is the payment description.");
// ### Payment
// A Payment Resource; create one using
// the above types and intent as 'sale'
$payment = Paypalpayment:: Payment();
$payment->setIntent("sale");
$payment->setPayer($payer);
$payment->setTransactions(array($transaction));
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
try {
$payment->create($this->_apiContext);
} catch (\PPConnectionException $ex) {
return "Exception: " . $ex->getMessage() . PHP_EOL;
var_dump($ex->getData());
exit(1);
}
$response=$payment->toArray();
echo"<pre>";
print_r($response);
//var_dump($payment->getId());
//print_r($payment->toArray());//$payment->toJson();
}
/*
Use this call to get a list of payments.
url:payment/
*/
public function index(){
echo "<pre>";
$payments = Paypalpayment::all(array('count' => 1, 'start_index' => 0),$this->_apiContext);
print_r($payments);
}
}
The error I am getting:
I do not know your codebase, but if your class is a controller, why are you extending a Facades class? The issue is that your code is looking for the Facades class in your my_app\Http\Controllers namespace.
Removing that line or correctly importing the class will resolve your issue. However, I think you may need to rethink your design here.
Related
My problem is that billing agreements are successfully executed even if the setup fee is not paid. Looking at the logs, the IPN event notifiying that the setup fee failed and the agreement is cancelled typically takes 5-10 minutes to arrive, which is an insane amount of delay.
I am using the official PayPal PHP SDK at https://github.com/paypal/PayPal-PHP-SDK. It was deprecated a month ago, but its replacement is marked "not ready for production".
Billing plan details, with the intent to charge a $29.99/yr subscription. Setup fee is used to guarantee initial payment.
Per the 2 step process documented in https://paypal.github.io/PayPal-PHP-SDK/sample/, with the wrapping try/catch blocks removed for legibility:
// Step 1: https://paypal.github.io/PayPal-PHP-SDK/sample/doc/billing/CreateBillingAgreementWithPayPal.html
use PayPal\Api\Agreement;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
/**
* #var \PayPal\Rest\ApiContext $apiContext
*/
$plan = Plan::get('EXAMPLE-PLAN-ID', $apiContext);
$agreement = new Agreement();
date_default_timezone_set('America/Los_Angeles');
$agreement->setName($plan->getName())
->setDescription($plan->getDescription())
// I'm not sure why +1 hour is used here, but that's how it is in the codebase.
->setStartDate(date('c', strtotime("+1 hour", time())));
$agreement->setPlan($plan);
/**
* ------------------------------------------------------------------------------------------
* I think overriding should be optional since they currently precisely match the given
* plan's data. So for this particular plan, if I deleted everything between these comment
* blocks, nothing bad should happen.
* ------------------------------------------------------------------------------------------
*/
$preferences = new MerchantPreferences();
$preferences->setReturnUrl("https://www.example.com/actually-a-valid-site")
->setCancelUrl("https://www.example.com/actually-a-valid-site")
->setAutoBillAmount('no')
->setInitialFailAmountAction('CANCEL');
$agreement->setOverrideMerchantPreferences($preferences);
/**
* ------------------------------------------------------------------------------------------
* ------------------------------------------------------------------------------------------
*/
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
$agreement = $agreement->create($apiContext);
$approvalUrl = $agreement->getApprovalLink();
// This takes us to PayPal to login and confirm payment.
header("Location: ".$approvalUrl);
// Step 2: https://paypal.github.io/PayPal-PHP-SDK/sample/doc/billing/ExecuteAgreement.html
use PayPal\Api\Agreement;
/**
* #var \PayPal\Rest\ApiContext $apiContext
*/
try {
$agreement = new Agreement();
$agreement->execute($_GET['token'], $apiContext);
$agreement = Agreement::get($agreement->getId(), $apiContext);
/**
* I assume at this point the agreement is executed successfully. Yet, the setup fee does not
* have to be paid for us to get here. This behavior is verified on live.
*/
} catch (\Exception $e) {
// Do something.
}
I'm at a loss for what I'm doing wrong that would cause the billing agreement to execute even without the setup fee being paid. Help would be appreciated!
Here's how to create the Plan that was used:
use PayPal\Api\Currency;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Common\PayPalModel;
$plan = new Plan();
$plan->setName('Test Name')
->setDescription('Test Description')
->setType('INFINITE');
$payment_definition = new PaymentDefinition();
$payment_definition->setName('Regular Payments')
->setType('REGULAR')
->setFrequency('YEAR')
->setFrequencyInterval(1)
->setCycles('0')
->setAmount(new Currency(['value' => '29.99', 'currency' => 'USD']));
$merchant_preferences = new MerchantPreferences();
$merchant_preferences->setReturnUrl'https://insert.actual.url.here')
->setCancelUrl('https://insert.actual.url.here')
->setAutoBillAmount('NO')
->setInitialFailAmountAction('CANCEL')
->setMaxFailAttempts('1')
->setSetupFee(new Currency(['value' => '29.99', 'currency' => 'USD']));
$plan->setPaymentDefinitions([$payment_definition]);
$plan->setMerchantPreferences($merchant_preferences);
$request = clone $plan;
try {
/**
* #var \Paypal\Rest\ApiContext $apiContext
*/
$plan->create($apiContext);
$patch = new Patch();
$value = new PayPalModel(['state' => 'ACTIVE']);
$patch->setOp('replace')
->setPath('/')
->setValue($value);
$patchRequest = new PatchRequest();
$patchRequest->addPatch($patch);
if (!$plan->update($patchRequest, $apiContext)) {
throw new \Exception("Failed to apply patch to plan.");
}
// Done.
} catch (\Exception $e) {
// Some error handling.
exit;
}
The replacement SDK is https://github.com/paypal/Checkout-PHP-SDK , which does not include any billing agreement or subscription use cases. For use cases not covered by that SDK , you should use a direct HTTPS integration. This is documented here: https://developer.paypal.com/docs/api/rest-sdks/
The code you are trying to use is for an obsolete SDK for an obsolete API (old version of billing agreements, not compatible with new subscriptions).
Here is the API you should integrate, with no SDK: https://developer.paypal.com/docs/subscriptions/
Turns out an exception is not supposed to be thrown for usual agreement execution. To check whether the setup was paid, check the value of $agreement->getState() after executing the agreement.
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?
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);
}
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:
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.