I have some issues trying to get this working, I\'ve implemented the checkout express (or seems to be) successfully, but also my system needs subscription option, following
I have found the problem. It is with the parameters we pass to the create recurring payment function. Here are functions for agreement and payment creation. It should work fine.
<?php
namespace App\Http\Controllers;
use Payum\Core\Request\GetHumanStatus;
use Payum\LaravelPackage\Controller\PayumController;
use Payum\Paypal\ExpressCheckout\Nvp\Api;
use Payum\Core\Request\Sync;
use Payum\Paypal\ExpressCheckout\Nvp\Request\Api\CreateRecurringPaymentProfile;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class PayPalController extends PayumController {
public function prepareSubscribeAgreement() {
$storage = $this->getPayum()->getStorage('Payum\Core\Model\ArrayObject');
$details = $storage->create();
$details['PAYMENTREQUEST_0_AMT'] = 0;
$details['L_BILLINGTYPE0'] = Api::BILLINGTYPE_RECURRING_PAYMENTS;
$details['L_BILLINGAGREEMENTDESCRIPTION0'] = "Weather subscription";
//$details['NOSHIPPING'] = 1;
$storage->update($details);
$captureToken = $this->getPayum()->getTokenFactory()->createCaptureToken('paypal_ec', $details, 'paypal_subscribe');
return \Redirect::to($captureToken->getTargetUrl());
}
public function createSubscribePayment(Request $request) {
$request->attributes->set('payum_token', $request->input('payum_token'));
$token = $this->getPayum()->getHttpRequestVerifier()->verify($request);
$gateway = $this->getPayum()->getGateway($token->getGatewayName());
$agreementStatus = new GetHumanStatus($token);
$gateway->execute($agreementStatus);
if (!$agreementStatus->isCaptured()) {
header('HTTP/1.1 400 Bad Request', true, 400);
exit;
}
$agreement = $agreementStatus->getModel();
$storage = $this->getPayum()->getStorage('Payum\Core\Model\ArrayObject');
$recurringPayment = $storage->create();
$recurringPayment['TOKEN'] = $agreement['TOKEN'];
$recurringPayment['PAYERID'] = $agreement['PAYERID'];
$recurringPayment['PROFILESTARTDATE'] = date(DATE_ATOM);
$recurringPayment['DESC'] = $agreement['L_BILLINGAGREEMENTDESCRIPTION0'];
$recurringPayment['BILLINGPERIOD'] = Api::BILLINGPERIOD_DAY;
$recurringPayment['BILLINGFREQUENCY'] = 7;
$recurringPayment['AMT'] = 0.05;
$recurringPayment['CURRENCYCODE'] = 'USD';
$recurringPayment['COUNTRYCODE'] = 'US';
$recurringPayment['MAXFAILEDPAYMENTS'] = 3;
$gateway->execute(new CreateRecurringPaymentProfile($recurringPayment));
$gateway->execute(new Sync($recurringPayment));
$captureToken = $this->getPayum()->getTokenFactory()->createCaptureToken('paypal_ec', $recurringPayment, 'payment_done');
return \Redirect::to($captureToken->getTargetUrl());
}
public function done(Request $request) {
/** @var Request $request */
//$request = \App::make('request');
$request->attributes->set('payum_token', $request->input('payum_token'));
$token = $this->getPayum()->getHttpRequestVerifier()->verify($request);
$gateway = $this->getPayum()->getGateway($token->getGatewayName());
$gateway->execute($status = new GetHumanStatus($token));
return \Response::json(array(
'status' => $status->getValue(),
'details' => iterator_to_array($status->getFirstModel())
));
}
}
The routes:
Route::get('paypal/agreement', 'PayPalController@prepareSubscribeAgreement');
Route::get('paypal/subscribe', [
'as' => 'paypal_subscribe',
'uses' => 'PayPalController@createSubscribePayment'
]);
Route::get('paydone', [
'as' => 'payment_done',
'uses' => 'PayPalController@done'
]);
Simply open www.example.com/paypal/agreement and it should take you to PayPal
In my project I used the following library and it helped me alot:
https://github.com/amirduran/duranius-paypal-rest-api-php-library
Here are some features:
Here is my Pay Pal REST API code.
//Request Perms
$cardtype = $request->cardtype;
$account_number = $request->cardnumber;
$expire_date =$request->expire_date;
$cvv = $request->cvv;
$plan_id =$request->plan_id;
$amount = $request->amount;
$userid = $request->user_id;
$payment_type = $request->plan_type;
//Genrate tokens
$ch = curl_init();
$clientId ='Your Client ID';
$clientSecret= 'Your Secret ID';
//you get Clientid and clientSecret
https://developer.paypal.com/developer/applications
curl_setopt($ch, CURLOPT_URL, "https://api.sandbox.paypal.com/v1/oauth2/token");
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $clientId.":".$clientSecret);
curl_setopt($ch, CURLOPT_POSTFIELDS, "grant_type=client_credentials");
$result = curl_exec($ch);
if(empty($result))die("Error: No response.");
else
{
$json = json_decode($result);
}
curl_close($ch);
$product_id = '';
//you can create payment plan this link
https://www.sandbox.paypal.com/billing/plans
if ($plan_id == 1) {
$product_id = 'your plan id';
}elseif ($plan_id == 2) {
$product_id = 'your plan id';
}
$ch = curl_init();
$payment_data = '{
"plan_id":"'.$product_id.'",
"start_time":"'.gmdate("Y-m-d\TH:i:s\Z",strtotime("+1 day")).'",
"shipping_amount":{
"currency_code":"USD",
"value":"'.$amount.'"
},
"subscriber":{
"name":{
"given_name":"",
"surname":""
},
"email_address":"'.$users->email.'",
"shipping_address":{
"name":{
"full_name":""
},
"address":{
"address_line_1":"",
"address_line_2":"",
"admin_area_2":"",
"admin_area_1":"",
"postal_code":"",
"country_code":"US"
}
},
"payment_source":{
"card":{
"number":"'.$account_number.'",
"expiry":"'. $expiry_date.'",
"security_code":"'.$cvv.'",
"name":"",
"billing_address":{
"address_line_1":"",
"address_line_2":"",
"admin_area_1":"",
"admin_area_2":"",
"postal_code":"",
"country_code":"US"
}
}
}
}
}';
curl_setopt($ch, CURLOPT_URL, 'https://api.sandbox.paypal.com/v1/billing/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payment_data);
$headers = array();
$headers[] = 'Accept: application/json';
$headers[] = 'Authorization: Bearer '.$json->access_token.'';
$headers[] = 'Paypal-Request-Id: SUBSCRIPTION-'. rand() .'';
$headers[] = 'Prefer: return=representation';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
$payment_id = json_decode($result);
$data =$headers[2];
$subid = substr($data, strpos($data, ":") + 2);
//save data in database
$payment = new Subscription();
$payment->userid=$userid;
$payment->plan_id=$plan_id;
$payment->price=$amount;
$payment->sub_id=$subid;
$payment->transaction_id=$payment_id->id;
$payment->payment_type='Paypal';
$payment->charge=$paypal_charge;
$payment->plan_type=$plan_type;
$payment->subscription_startdate= $subscription_startdate;
$payment->subscription_enddate= $subscription_enddate;
$payment->subscription_status= 'active';
$payment->save();
return response()->json(['status' => true,'message'=>'Payment has been successfully Done','data'=>$payment]);
It's working fine for me.