It's for couple of days, I'm using php sdk. It was working before, but now they are not executing my subscription and charge payment. I only get PAYMENT.SALE.PENDING event whenever a payment has made.
Please help, this is driving me crazy.
I get the payment status "approved", but I'm not getting the 'PAYMENT.SALE.COMPLETED' webhook, I don't know what's wrong.
Here is my code:
create:
public function doPayPalCharge($returnUrl, $cancelUrl)
{
$apiContext = $this->apiContext;
$money = $this->getAmount();
$customData = $this->getMetadata();
// Create new payer and method
$payer = new Payer();
$payer->setPaymentMethod("paypal");
// Set redirect urls
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl($returnUrl)
->setCancelUrl($cancelUrl);
// Set payment amount
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal($money);
// Set transaction object
$transaction = new Transaction();
$transaction->setAmount($amount)
//can not use json_encode here, because can not decode data from web hook
->setCustom(base64_encode(serialize($customData->all)))
->setDescription("Payment description");
// Create the full payment object
$payment = new Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions([$transaction]);
$request = clone $payment;
// Create payment with valid API context
try
{
$payment->create($apiContext);
$token = $this->getPayPalTokenFromUrl($payment->getApprovalLink());
} catch (PayPalConnectionException $e)
{
self::payPalLog($e, '[PayPalConnectionException]', (array)$request);
} catch (\Exception $e)
{
self::payPalLog($e, '[Create Payment Failed]', (array)$request);
}
return isset($token) ? $token : '';
}
execute:
public function confirmPayPalCharge($payment_id, $payer_id)
{
$apiContext = $this->apiContext;
// Get payment object by passing paymentId
$payment = Payment::get($payment_id, $apiContext);
// Execute payment with payer id
$execution = new PaymentExecution();
$execution->setPayerId($payer_id);
try
{
// Execute payment
$payment = $payment->execute($execution, $apiContext);
} catch (PayPalConnectionException $e)
{
self::payPalLog($e, '[PayPalConnectionException]');
} catch (\Exception $e)
{
self::payPalLog($e);
}
return isset($payment) ? $payment : null;
}
Related
I am implementing a functionality where admin pays the sellers on their PAYPAL email accounts. but for some reason I am getting this error while implementing the following code.
I believe the error comes when the function processPaymentInvoiceViaCheckout returns redirect($approvalUrl)
Argument 1 passed to Symfony\Component\HttpFoundation\Response::setContent() must be of the type string or null, object given, called in
Routes
//create payment object
Route::get('/invoices/process-payment','PaypalController#processPaymentInvoiceViaCheckout');
//when payment object is created then get its details and execute payment to send money.
Route::get('/invoices/response-success','PaypalController#paypalResponseSuccess');
//when cancel to pay
Route::get('/invoices/response-cancel','PaypalController#paypalResponseCancel');
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayPal\Api\Amount;
use PayPal\Api\Details;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Payee;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Rest\ApiContext;
use PHPUnit\TextUI\ResultPrinter;
class PaypalController extends Controller
{
private $api_context;
public function __construct()
{
$this->api_context = new ApiContext(
new OAuthTokenCredential(config('paypal.client_id'), config('paypal.secret'))
);
$this->api_context->setConfig(config('paypal.settings'));
}
public function processPaymentInvoiceViaCheckout(){
$payer = new Payer();
$payer->setPaymentMethod("paypal");
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
// ->setSku("123123") // Similar to `item_number` in Classic API
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
// ->setSku("321321") // Similar to `item_number` in Classic API
->setPrice(2);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
$details = new Details();
$details->setShipping(1.2)
->setTax(1.3)
->setSubtotal(17.50);
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(20)
->setDetails($details);
$payee = new Payee();
//this is the email id of the seller who will receive this amount
$payee->setEmail("seller-paypal-businness-account-email#business.example.com");
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setPayee($payee)
->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(url('/invoices/response-success'))
->setCancelUrl(url('/invoices/response-cancel'));
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
$request = clone $payment;
try {
//create payment object
$createdPayment = $payment->create($this->api_context);
//get payment details to get payer id so that payment can be executed and transferred to seller.
$paymentDetails = Payment::get($createdPayment->getId(), $this->api_context);
$execution = new PaymentExecution();
$execution->setPayerId($paymentDetails->getPayer());
$paymentResult = $paymentDetails->execute($execution,$this->api_context);
} catch (\Exception $ex) {
//handle exception here
}
//Get redirect url
//The API response provides the url that you must redirect the buyer to. Retrieve the url from the $payment->getApprovalLink() method
$approvalUrl = $payment->getApprovalLink();
return redirect($approvalUrl);
}
public function paypalResponseCancel(Request $request)
{
//normally you will just redirect back customer to platform
return redirect('invoices')->with('error','You can cancelled payment');
}
public function paypalResponseSuccess(Request $request)
{
if (empty($request->query('paymentId')) || empty($request->query('PayerID')) || empty($request->query('token'))){
//payment was unsuccessful
//send failure response to customer
}
$payment = Payment::get($request->query('paymentId'), $this->api_context);
$execution = new PaymentExecution();
$execution->setPayerId($request->query('PayerID'));
// Then we execute the payment.
$result = $payment->execute($execution, $this->api_context);
dd($request->all(),$result);
//payment is received, send response to customer that payment is made.
}
}
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";
}
My code is successfully processing payments to paypal and then return to success page, buy business account amount does not updating.
I am trying paypal sdk in laravel and below is my script which I am using it, but on front side it is successfully going to paypal page where I login using buyer account then pay and then paypal return to success page. But in seller account the amount does not showing and nor deducting from buyer account.
public function createpayment(){
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'Ac.................asd', // ClientID
'Ac.................sdf' // ClientSecret
)
);
$payer = new Payer();
$payer->setPaymentMethod("paypal");
$item1 = new Item();
$item1->setName('Ground Coffee 40 oz')
->setCurrency('USD')
->setQuantity(1)
->setSku("123123") // Similar to `item_number` in Classic API
->setPrice(7.5);
$item2 = new Item();
$item2->setName('Granola bars')
->setCurrency('USD')
->setQuantity(5)
->setSku("321321") // Similar to `item_number` in Classic API
->setPrice(2);
$itemList = new ItemList();
$itemList->setItems(array($item1, $item2));
$details = new Details();
$details->setShipping(1.2)
->setTax(1.3)
->setSubtotal(17.50);
$amount = new Amount();
$amount->setCurrency("USD")
->setTotal(20)
->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription("Payment description")
->setInvoiceNumber(uniqid());
/* $baseUrl = getBaseUrl(); */
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(route('success'))
->setCancelUrl(route('cancel'));
$payment = new Payment();
$payment->setIntent("sale")
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
/* $payment->create($apiContext);
return redirect($payment->getApprovalLink()); */
try {
$payment->create($apiContext);
} catch (Exception $ex) {
ResultPrinter::printError("Created Payment Using PayPal. Please visit the URL to Approve.", "Payment", null, $request, $ex);
exit(1);
}
$approvalUrl = $payment->getApprovalLink();
echo $payment, $approvalUrl;
}
public function success(){
$apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
'Ac.................asd', // ClientID
'Ac.................sdf' // ClientSecret // ClientSecret
)
);
return request();
}
I want this code to be transfer money from buyer to seller account and then return success page with response. Can someone kindly guide me about I would like to appreciate.
On the success page you need to execute the payment in order to actually finish the transaction.
https://github.com/paypal/PayPal-PHP-SDK/blob/master/sample/payments/ExecutePayment.php
I am using PayPal paypal/rest-api-sdk-php for payment gateway for my laravel application.
But when the link is click for confirmation, I get Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/payments/payment.
Following is my method of implementation in Laravel 5.1 and AngularJS:
angular.module('MyApp')
.factory('Account', function($http){
return {
buyNow: function(pid){
console.log(pid)
return $http.put('/api/buynow',pid);
}
}
});
public function buyNowAPI(Request $request)
{
$pid = $request->input('pid');
$product = Product::find($pid);
$baseUrl = url().'/#/app/product?orderId=$pid';
$payment = $this->makePaymentUsingPayPal($product->price,'MYR',$product->title,"$baseUrl&success=true", "$baseUrl&success=false");
dd($payment->getLinks());
return response()->json($pid);
}
public function makePaymentUsingPayPal($total, $currency, $paymentDesc, $returnUrl, $cancelUrl)
{
$payer = new Payer();
$payer->setPaymentMethod("paypal");
// Specify the payment amount.
$amount = new Amount();
$amount->setCurrency($currency);
$amount->setTotal($total);
$transaction = new Transaction();
$transaction->setAmount($amount);
$transaction->setDescription($paymentDesc);
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl($returnUrl);
$redirectUrls->setCancelUrl($cancelUrl);
$payment = new Payment();
$payment->setRedirectUrls($redirectUrls);
$payment->setIntent("sale");
$payment->setPayer($payer);
$payment->setTransactions(array($transaction));
$payment->create($this->getApiContext());
return $payment;
}
The laravel code implementation is based on example that available in git for paypal/rest-api-sdk-php based example called The Pizza App rest-api-sample-app .
Thanks!!
You need to follow the instructions mentioned here:
https://github.com/paypal/PayPal-PHP-SDK/wiki/exception-%27PayPal%5CException%5CPayPalConnectionException%27-with-message-%27Got-Http-response-code-400-when-accessing
try {
$payment->create($apiContext);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode(); // Prints the Error Code
echo $ex->getData(); // Prints the detailed error message
die($ex);
} catch (Exception $ex) {
die($ex);
}
I'm trying to create and execute a payment with PayPal REST API through PHP SDK (sandbox environment) like showing below. The payment creation ($payment->create) work fine but the payment execution ($payment->execute) return "Incoming JSON request does not map to API request".
The JSON request is created by the SDK, then what can be the problem?
Thanks in advance.
$payer = new Payer();
$payer->setPaymentMethod("paypal");
$item = new Item();
$item->setName('Any name')
->setCurrency('EUR')
->setQuantity(1)
->setPrice(0.99);
$itemList = new ItemList();
$itemList->setItems(array($item));
$details = new Details();
$details->setTax(0)
->setSubtotal(0.99);
$amount = new Amount();
$amount->setCurrency('EUR')
->setTotal(0.99)
->setDetails($details);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($itemList)
->setDescription('Any description')
->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl(BASE_URL.'/payment/?success=true')
->setCancelUrl(BASE_URL.'/payment/?success=false');
$payment = new Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
try {
$payment->create($apiContext);
$execution = new PaymentExecution();
$result = $payment->execute($execution, $apiContext);
} catch (Exception $ex) {
//Function for extract the error message,
//the error message can be showing with
//a simple var_dump($ex)
$exception = self::getException($ex);
}
Am not a PHP dev (.Net), so based on reading the above, check into this section in your code:
$execution = new PaymentExecution();
$result = $payment->execute($execution, $apiContext);
You are sending a new PaymentExecution without the payer_id and the Payment.Id which you would obtain after the user approves your paypal Payment request that you created.
That said, I don't see that part (though as above, not a PHP dev) so I could be wrong. The steps are:
Create the Payment
Go into the Approval Flow -> user is redirected to Paypal and approves the Payment you created in #1 -> and is redirected back to your site (the returnUrl)
a. the PayerID will be in the querystring in this process
b. the paymentId will also be in the querystring in this process
After the user is redirected back to your site from PayPal (your returnUrl) - Execute a new Payment, set it's id to the one you obtained (#2b), sending the PaymentExecution with its PayerID set to the what you you obtained (#2a)
In c# (you'll need to convert this to PHP):
var _payment = new Payment { id = the_payment_id_you_obtained };
var _payExec = new PaymentExecution { payer_id = the_payer_id_you_obtained };
var _response = _payment.Execute(context, _payExec);
Hth...
It was enough put
$payment->setIntent('authorize')
instead of
$payment->setIntent('sale')
and eliminate the execution
$execution = new PaymentExecution(); $result = $payment->execute($execution, $apiContext);
Then, after
$payment->create
I used the "href" from
$payment->links
to do the redirect. Everything went perfectly. Thank you all.