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";
}
Related
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;
}
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'm trying to include a identifier in the transaction so I know which transaction is when it returns from Paypal. I've tried to use the reference_id as it's like the better option (because is a temporal identifier that I assign to the transaction).
The problem is that when I set it to the transaction, Paypal refuse to accept the json, it returns:
{
"name":"MALFORMED_REQUEST",
"message":"Incoming JSON request does not map to API request",
"information_link":"https://developer.paypal.com/webapps/developer/docs/api/#MALFORMED_REQUEST",
"debug_id":"6835f984b6735"
}
More or less I use the example code:
// Create new payer and method
$payer = new Payer();
$payer->setPaymentMethod("paypal");
// Set redirect urls
$redirectUrls = new RedirectUrls();
$redirectUrls->setReturnUrl($urlRetorno)
->setCancelUrl($urlCancelar);
// Set payment amount
$amount = new Amount();
$amount->setCurrency($moneda)
->setTotal($total);
// Set transaction object
$transaction = new Transaction();
$transaction->setAmount($amount)
->setDescription($descripcion);
// If I comment this line it runs ok.
$transaction->setReferenceId($referenceId);
// Create the full payment object
$payment = new Payment();
$payment->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions(array($transaction));
echo $payment->toJSON();
// Create payment with valid API context
try {
$payment->create($apiContext);
// Get PayPal redirect URL and redirect user
$approvalUrl = $payment->getApprovalLink();
// Finalmente le redirigimos a PayPal para que apruebe el pago
//redirige($approvalUrl, 'Intentando redirigir a PayPal.');
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode();
echo $ex->getData();
die($ex);
} catch (Exception $ex) {
die($ex);
}
And this is the result (calling toJSON()):
{
"intent":"sale",
"payer":{
"payment_method":"paypal"
},
"redirect_urls":{
"return_url":"https://example.com/return.php",
"cancel_url":"https://example.com/cancel.php"
},
"transactions":[
{
"amount":{
"currency":"MXN",
"total":"1515"
},
"description":"Suscripci\u00f3n c\u00f3digo PP-19119",
"reference_id":"304171757041"
}
]
}
I have found the reference_id in the API documentation so I supposed I could use it.
After posting on the GitHub repositories about it here is the conclusion.
reference_id is a read only value and you should use invoice_number to track it.
You can read about it in https://github.com/paypal/PayPal-PHP-SDK/issues/828 and currently tracked in https://github.com/paypal/PayPal-REST-API-issues/issues/69.
I know there are qiestions asked on this topic already, but i could not find a solution. I am absolutely new at paypal api and my task is to create a function to cancel billing agreement.
Do not even know how to form and make function call api. Tried to find and example, but everywhere i end up viewing technical reference page which does not help me as newbie...
Anyone could draft and example please?
So far i got to this stage, but still won't work.
if(!empty($agreement->paypal_agreement_id) && $agreement->paypal_agreement_state == 'Active')
{
/*
* Cancel a billing agreement
*/
$apiContext = new ApiContext(new OAuthTokenCredential($this->clientid, $this->clientsecret));
$createdAgreement = $agreement->paypal_agreement_id;
$patch = new Patch();
$patch->setOp('replace')
->setPath('/')
->setValue(json_decode('{
"billingagreementstatus": "Canceled"
}'));
$patchRequest = new PatchRequest();
$patchRequest->addPatch($patch);
try {
// Uzkomentinta testatimui - netrinti. Mindaugas
$createdAgreement->update($patchRequest, $apiContext);
$agreement = Agreement::get($createdAgreement, $apiContext);
} catch (Exception $ex) {
ResultPrinter::printError("Updated the Agreement with new Description and Updated Shipping Address", "Agreement", null, $patchRequest, $ex);
exit(1);
}
} else {
return ['.reportmsg' => 'Payment agreements do not exist.'];
}
Anyone can help?
Reference
Code
public function ShowPaymentWithPaypal()
{
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item_1 = new Item();
$item_1->setName('Item 1') /** item name **/
->setCurrency('USD')
->setQuantity(1)
->setPrice(2); /** unit price **/
$item_list = new ItemList();
$item_list->setItems(array($item_1));
$amount = new Amount();
$amount->setCurrency('USD')
->setTotal(2);
$transaction = new Transaction();
$transaction->setAmount($amount)
->setItemList($item_list)
->setDescription('Your transaction description');
$redirect_urls = new RedirectUrls();
$redirect_urls->setReturnUrl(\URL::route('ReturnedFromPaypal')) /** Specify return URL **/
->setCancelUrl(\URL::route('CancelledPaymentWithPaypal'));
$payment = new Payment();
$payment->setIntent('Sale')
->setPayer($payer)
->setRedirectUrls($redirect_urls)
->setTransactions(array($transaction));
/** dd($payment->create($this->_api_context));exit; **/
try {
$payment->create($this->_api_context);
} catch (\PayPal\Exception\PPConnectionException $ex) {
dd($ex);
if (\Config::get('app.debug')) {
\Session::put('error','Connection timeout');
return "Error occured";
/** echo "Exception: " . $ex->getMessage() . PHP_EOL; **/
/** $err_data = json_decode($ex->getData(), true); **/
/** exit; **/
} else {
\Session::put('error','Some error occur, sorry for inconvenient');
return "Error occured";
/** die('Some error occur, sorry for inconvenient'); **/
}
}
foreach($payment->getLinks() as $link) {
if($link->getRel() == 'approval_url') {
$redirect_url = $link->getHref();
break;
}
}
/** add payment ID to session **/
\Session::put('paypal_payment_id', $payment->getId());
if(isset($redirect_url)) {
/** redirect to paypal **/
return \Redirect::away($redirect_url);
}
\Session::put('error','Unknown error occurred');
return "Last line error";
}
What's the problem ?
When I try to do the login for doing payment using sandbox credentials, I get the below error.
We aren't able to process your payment using your PayPal account at
this time. Please go back to the merchant and try using a different
payment method.
I am following this to configure Paypal in Laravel 5.5
XHR Error Details
Am I missing something ?
It looks like a Paypal limitation.
In this link, for example, the support say that Russia laws limit paypal account to 100000 rub of transaction.
When you reach the limit, you must specify something on your activities to unlock the limit.
Maybe have you reached the limit of transactions' amount for your country?
Try to use low amount, as 0.01 and to delete old test transactions from the sandbox account (seller).
If you haven't a lot of transactions for the seller, maybe the problem is in the customer's account? Try to create a new account and use it.
I suppose in the sandbox will be a place to unlock the