Implement Payum/Laravel recurring payment - php

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 this example.
Now, my problem is that in Laravel you cannot simply put some random files, so I'm trying to do it in the correct way, sadly, there is no documentation of the classes and methods including on the library.
I've created some functions within controllers (I don't know if this the right way) the problem I'm facing now is trying to createRecurringPayment() to apply the desired amount of the recurring payment, is the final step I guess.
Thanks for yout help.
app/controllers/PaypalController.php
public function prepareExpressCheckout(){
$storage = $this->getPayum()->getStorage('Payum\Core\Model\ArrayObject');
$details = $storage->createModel();
$details['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD';
$details['PAYMENTREQUEST_0_AMT'] = 1.23;
$storage->updateModel($details);
$captureToken = $this->getTokenFactory()->createCaptureToken('paypal_es', $details, 'payment_done');
$details['RETURNURL'] = $captureToken->getTargetUrl();
$details['CANCELURL'] = $captureToken->getTargetUrl();
$storage->updateModel($details);
return \Redirect::to($captureToken->getTargetUrl());
}
public function prepareSubscribe(){
$storage = $this->getPayum()->getStorage('Payum\Core\Model\ArrayObject');
$details = $storage->createModel();
$details['PAYMENTREQUEST_0_AMT'] = 0;
$details['L_BILLINGTYPE0'] = Api::BILLINGTYPE_RECURRING_PAYMENTS;
$details['L_BILLINGAGREEMENTDESCRIPTION0'] = "Suscripción por X meses";
$details['NOSHIPPING'] = 1;
$storage->updateModel($details);
$captureToken = $this->getTokenFactory()->createCaptureToken('paypal_es', $details, 'payment_done');
$storage->updateModel($details);
return \Redirect::to($captureToken->getTargetUrl());
}
public function createRecurringPayment(){
$payum_token = Input::get('payum_token');
$request = \App::make('request');
$request->attributes->set('payum_token', $payum_token);
$token = ($request);
//$this->invalidate($token);
$agreementStatus = new GetHumanStatus($token);
$payment->execute($agreementStatus);
if (!$agreementStatus->isSuccess()) {
header('HTTP/1.1 400 Bad Request', true, 400);
exit;
}
$agreementDetails = $agreementStatus->getModel();
$storage = $this->getPayum()->getStorage('Payum\Core\Model\ArrayObject');
$recurringPaymentDetails = $storage->createModel();
$recurringPaymentDetails['TOKEN'] = $agreementDetails['TOKEN'];
$recurringPaymentDetails['DESC'] = 'Subscribe to weather forecast for a week. It is 0.05$ per day.';
$recurringPaymentDetails['EMAIL'] = $agreementDetails['EMAIL'];
$recurringPaymentDetails['AMT'] = 0.05;
$recurringPaymentDetails['CURRENCYCODE'] = 'USD';
$recurringPaymentDetails['BILLINGFREQUENCY'] = 7;
$recurringPaymentDetails['PROFILESTARTDATE'] = date(DATE_ATOM);
$recurringPaymentDetails['BILLINGPERIOD'] = Api::BILLINGPERIOD_DAY;
$payment->execute(new CreateRecurringPaymentProfile($recurringPaymentDetails));
$payment->execute(new Sync($recurringPaymentDetails));
$doneToken = $this->createToken('paypal_es', $recurringPaymentDetails, 'payment_done');
return \Redirect::to($doneToken->getTargetUrl());
}
app/routes.php
Route::get('/payment', array('as' => 'payment', 'uses' => 'PaymentController#payment'));
Route::get('/payment/done', array('as' => 'payment_done', 'uses' => 'PaymentController#done'));
Route::get('/payment/paypal/express-checkout/prepare', array('as' => 'paypal_es_prepare', 'uses' => 'PaypalController#prepareExpressCheckout'));
Route::get('/payment/paypal/subscribe/prepare', array('as' => 'paypal_re_prepare', 'uses' => 'PaypalController#prepareSubscribe'));
Route::get('/payment/paypal/subscribe/create', array('as' => 'payment_create', 'uses' => 'PaypalController#createRecurringPayment'));

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:
Easy to install - Just one file
Library is implemented as PHP class
It supports Recurring Payments It supports ExpressCheckout payments
All available PayPal API methods are wrapped in belonging methods
Well documented

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.

Related

database is not updating the values after successful transaction through payment gateway

My website's framework is in CodeIgniter. I have integrated instamojo payment gateway in it. The query inserting the payment id but after successful payment not updating the column value of status to 1 from 0,
This is the block code of paymentcontroller.php
public static function userDataUpdate($trx)
{
$general = getGeneral();
$data = Deposit::where('trx', $trx)->first();
if ($data->status == 0) {
$data->status = 1;
$data->save();
$user = User::find($data->user_id);
$wallet = $user->wallet;
$wallet->balance += $data->amount;
$wallet->save();
$transaction = new Transaction();
$transaction->user_id = $data->user_id;
$transaction->amount = $data->amount;
$transaction->post_balance = $wallet->balance;
$transaction->charge = $data->charge;
$transaction->trx_type = '+';
$transaction->details = 'Deposited via ' . $data->gatewayCurrency()->name;
$transaction->trx = $data->trx;
$transaction->save();
$adminNotification = new AdminNotification();
$adminNotification->user_id = $user->id;
$adminNotification->title = 'Deposit succeeded via '.$data->gatewayCurrency()->name;
$adminNotification->click_url = urlPath('admin.deposit.successful');
$adminNotification->save();
notify($user, 'DEPOSIT_COMPLETE', [
'method_name' => $data->gatewayCurrency()->name,
'method_currency' => $data->method_currency,
'method_amount' => showAmount($data->final_amo),
'amount' => showAmount($data->amount),
'charge' => showAmount($data->charge),
'currency' => $general->cur_text,
'rate' => showAmount($data->rate),
'trx' => $data->trx,
'post_balance' => showAmount($wallet->balance)
]);
}
}
This is the code of processcontroller.php
<?php
namespace App\Http\Controllers\Gateway\Instamojo;
use App\Models\Deposit;
use App\Http\Controllers\Gateway\PaymentController;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class ProcessController extends Controller
{
/*
* Instamojo Gateway
*/
public static function process($deposit)
{
$basic = getGeneral();
$instaMojoAcc = json_decode($deposit->gatewayCurrency()->gateway_parameter);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://test.instamojo.com/api/1.1/payment-requests/');
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
"X-Api-Key:$instaMojoAcc->api_key",
"X-Auth-Token:$instaMojoAcc->auth_token"
)
);
$payload = array(
'purpose' => 'Payment to ' . $basic->sitename,
'amount' => round($deposit->final_amo,2),
'buyer_name' => $deposit->user->username,
'redirect_url' => route('user.deposit.history'),
'webhook' => route('ipn.'.$deposit->gateway->alias),
'email' => $deposit->user->email,
'btc_wallet' => $deposit->trx,
'send_email' => true,
'allow_repeated_payments' => false
);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload));
$response = curl_exec($ch);
curl_close($ch);
$res = json_decode($response);
if (#$res->success) {
if(!#$res->payment_request->id){
$send['error'] = true;
$send['message'] = "Response not given from API. Please re-check the API credentials.";
}else{
$deposit->btc_wallet = $res->payment_request->id;
$deposit->save();
$send['redirect'] = true;
$send['redirect_url'] = $res->payment_request->longurl;
$send['btc_wallet'] = $deposit->trx;
}
} else {
$send['error'] = true;
$send['message'] = "Credentials mismatch. Please contact with admin";
}
return json_encode($send);
}
public function ipn(Request $request)
{
//$this->customLog($request->all(),'Instamojo',true);
$deposit = Deposit::where('btc_wallet', $_POST['payment_request_id'])->orderBy('id', 'DESC')->first();
$instaMojoAcc = json_decode($deposit->gatewayCurrency()->gateway_parameter);
$deposit->detail = $request->all();
$deposit->save();
$imData = $_POST;
$macSent = $imData['mac'];
unset($imData['mac']);
ksort($imData, SORT_STRING | SORT_FLAG_CASE);
$mac = hash_hmac("sha1", implode("|", $imData), $instaMojoAcc->salt);
if ($macSent == $mac && $imData['status'] == "Credit" && $deposit->status == '0') {
PaymentController::userDataUpdate($deposit->trx);
}
}
}
I am unable to find out why the query is not updating the status of the transaction in mysqli.

Error in creating record in zohocrm contacts using php 7.1

I am trying to create a record in zohocrm. i am using API version2 code.
i recieve this following error which i stated below. I tried stackoverflow for solutions but can't find relevant solution. I tried this Stackoverflow answer Zoho API V2 Update Record. It doesn't work for me. Help me with some solution. i use php version
7.1
Here's the Code i used:
public function createRecord($module, $module_fields)
{
global $HelperObj;
$WPCapture_includes_helper_Obj = new WPCapture_includes_helper_PRO();
$activateplugin = $WPCapture_includes_helper_Obj->ActivatedPlugin;
$moduleslug = $this->ModuleSlug = rtrim(strtolower($module), "s");
$zohoapi = new SmackZohoApi();
$module_field['data'] = array($module_fields);
$module_field['Owner']['id'] = $module_fields['SMOWNERID'];
$fields_to_skip = ['Digital_Interaction_s', 'Solution'];
foreach ($module_fields as $fieldname => $fieldvalue) {
if (!in_array($fieldname, $fields_to_skip)) {
continue;
}
$module_fields[$fieldname] = array();
if (is_string($fieldvalue)) {
array_push($module_fields[$fieldname], $fieldvalue);
} else if (is_array($fieldvalue)) {
array_push($module_fields[$fieldname], $fieldvalue);
}
}
//$fields = json_encode($module_fields);
$attachments = $module_fields['attachments'];
$body_json = array();
$body_json["data"] = array();
array_push($body_json["data"], $module_fields);
$record = $zohoapi->Zoho_CreateRecord($module, $body_json, $attachments);
if ($record['code'] == 'INVALID_TOKEN' || $record['code'] == 'AUTHENTICATION_FAILURE') {
$get_access_token = $zohoapi->refresh_token();
if (isset($get_access_token['error'])) {
if ($get_access_token['error'] == 'access_denied') {
$data['result'] = "failure";
$data['failure'] = 1;
$data['reason'] = "Access Denied to get the refresh token";
return $data;
}
}
$exist_config = get_option("wp_wpzohopro_settings");
$config['access_token'] = $get_access_token['access_token'];
$config['api_domain'] = $get_access_token['api_domain'];
$config['key'] = $exist_config['key'];
$config['secret'] = $exist_config['secret'];
$config['callback'] = $exist_config['callback'];
$config['refresh_token'] = $exist_config['refresh_token'];
update_option("wp_wpzohopro_settings", $config);
$this->createRecord($module, $module_fields);
} elseif ($record['data'][0]['code'] == 'SUCCESS') {
$data['result'] = "success";
$data['failure'] = 0;
} else {
$data['result'] = "failure";
$data['failure'] = 1;
$data['reason'] = "failed adding entry";
}
return $data;
}
API Call Code:
public function Zoho_CreateRecord($module = "Lead",$data_array,$extraParams) {
try{
$apiUrl = "https://www.zohoapis.com/crm/v2/$module";
$fields = json_encode($data_array);
$headers = array(
'Content-Type: application/json',
'Content-Length: ' . strlen($fields),
sprintf('Authorization: Zoho-oauthtoken %s', $this->access_token),
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
$result = curl_exec($ch);
curl_close($ch);
$result_array = json_decode($result,true);
if($extraParams != "")
{
foreach($extraParams as $field => $path){
$this->insertattachment($result_array,$path,$module);
}
}
}catch(\Exception $exception){
// TODO - handle the error in log
}
return $result_array;
}
error i got:
Array
(
[data] => Array
(
[0] => Array
(
[code] => INVALID_DATA
[details] => Array
(
[expected_data_type] => jsonarray
[api_name] => Solution_Interest
)
[message] => invalid data
[status] => error
)
)
)
By the details which you gave ,
(1)you said you wish to create "Contacts" , but the url you are using to create contact doesn't seems to create "Contacts" either by
**converting leads to account and contact , or
**directly creating contact
(2)you mentioned module name as "Lead" , try changing it to "Leads".
(3)variables $data_array & $extraParams , doesn't seems to hold any value , they seems to be null.
(4)Here is a help doc. for you
Create Contact
If that still doesn't solve your problem ,you could ask your queries at zoho crm community , people will definitely solve your queries Ask here

Sandbox Paypal Checkout (PHP, Laravel)

I'm trying to implement Paypal's checkout to my Laravel Api (connected to an Ionic app) and it gets stuck when in the app I press the button to checkout and it goes to Paypal (so far so good) in the login screen. I found it weird because it wouldn't let me login with my sandbox account or even my real account, the error is the same: "Some of your info isn't correct. Please try again." By opening developer tools, those are the errors I get (see screenshots). I really couldn't find where I'm making a mistake here. Maybe you can help me. Below are the screenshots and the code that makes takes the checkout to Paypal. Let me know if I should add any extra info here! Thanks a lot!
error 1: ,
investigating one of the console errors:
Route::middleware('auth:api')->post('/paypal', function (Request $request) {
$user = $request->user();
$data = $request->all();
$list_products_id = $data;
$products = [];
$total = 0;
$titles = '';
foreach($list_products_id as $key => $value) {
$product = Product::find($value);
if($product){
$products[$key] = $product;
$total += $product->price;
$titles .= $product->title." ";
}
}
if($total){
$paypal = config('app.paypal', "sandbox");
if($paypal == "sandbox"){
$userProvider = 'In my app I have the sandbox business credentials here';
$pwdProvider = 'In my app I have the sandbox business credentials here';
$signProvider = 'In my app I have the sandbox business credentials here';
$url = 'https://api-3t.sandbox.paypal.com/nvp';
$url2 = 'https://www.sandbox.paypal.com/cgi-bin/webscr?%s';
} else {
$userProvider = '';
$pwdProvider = '';
$signProvider = '';
$url = 'https://api-3t.paypal.com/nvp';
$url2 = 'https://www.paypal.com/cgi-bin/webscr?%s';
}
$data = [];
$data['USER'] = $userProvider;
$data['PWD'] = $pwdProvider;
$data['SIGNATURE'] = $signProvider;
$data['METHOD'] = 'SetExpressCheckout';
$data['VERSION'] = '108';
$data['LOCALECODE'] = 'en_US';
$data['L_PAYMENTREQUEST_0_NAME0'] = "Products Orders";
$data['L_PAYMENTREQUEST_0_DESC0'] = $titles;
$data['PAYMENTREQUEST_0_AMT'] = number_format($total, 2).'';
$data['PAYMENTREQUEST_0_CURRENCYCODE'] = 'EUR';
$data['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Sale';
$data['L_PAYMENTREQUEST_0_QTY0'] = '1'; //number of the same product the user is ordering
$data['L_PAYMENTREQUEST_0_AMT0'] = number_format($total, 2).'';
$data['L_BILLINGAGREEMENTDESCRIPTION0'] = $titles;
$data['CANCELURL'] = url('/');
$data['RETURNURL'] = url('/');
// curl
$data = http_build_query($data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
$nvp = array();
if (preg_match_all('/(?<name>[^\=]+)\=(?<value>[^&]+)&?/', $response, $matches)) {
foreach ($matches['name'] as $offset => $name) {
$nvp[$name] = urldecode($matches['value'][$offset]);
}
}
if(isset($nvp['ACK']) && $nvp['ACK'] == "Success" ){
$query = array(
'cmd' => '_express-checkout',
'token' => $nvp['TOKEN']
);
$redirectURL = sprintf($url2, http_build_query($query));
return ['date'=>$redirectURL];
}else{
return ['status'=>'error purchasing! - 1'];
}
}
echo "total: " . $total;
return ['status'=>'error purchasing! - 2'];
});
so I did a password reset on my sandboxes account and it worked!

WordPress - Issues with referencing custom PHP class in functions.php

I apologize if this is really dumb/obvious but this is my first experience working with classes in WordPress.
I made a class called SharpSpringService.php inside my custom plugin sharpspring-form. I placed the class within a classes folder within that custom plugin for organization purposes.
I'm referencing the SharpSpringService class within a function in functions.php but am getting an error. When I declare a new instance of SharpSpringService and place the account ID and secret key as parameters, I get a message: "Expected SharpSpring, got string". I also see an Internal Server 500 Error in the Chrome dev consoles that seems to be a result of creating an instance of this class.
I'm not sure why the parameters are expected to be "SharpSpring" as they should be accountID and secretkey.
Here is the SharpSpringService class:
private $authError = false;
private $accountID = null;
private $secretKey = null;
/**
* SharpSpringService constructor.
* #param $accountID SharpSpring Account ID
* #param $secretKey SharpSpring Secret Key
*/
public function __construct($accountID, $secretKey)
{
$this->accountID = $accountID;
$this->secretKey = $secretKey;
}
public function hasAuthError() {
return $this->authError;
}
public function makeCall($method, $params = []) {
$requestID = session_id();
$accountID = $this->accountID;
$secretKey = $this->secretKey;
$data = array(
'method' => $method,
'params' => $params,
'id' => $requestID,
);
$queryString = http_build_query([
'accountID' => $accountID,
'secretKey' => $secretKey
]);
$url = "http://api.sharpspring.com/pubapi/v1/?$queryString";
$data = json_encode($data);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
));
$result = curl_exec($ch);
curl_close($ch);
$resultObj = json_decode($result);
if ($resultObj->error != null) {
throw new \Exception($result->error);
}
return $resultObj;
}
}
And here is the function in functions.php that is referencing the class:
function get_memberships_callback(){
$newsListID = 550280195;
$listName = "NewsList";
$contactEmail = $_POST['contactemail'];
$sharpSpringService = new SharpSpringService('[redacted]', '[redacted]'); //this is where the code chokes
$return = [];
if($contactEmail != null && $contactEmail !=""){
$lists = $sharpSpringService->makeCall('getListMemberships', [
'emailAddress' => $contactEmail,
]);
if (count($lists) > 0) {
$listArray = json_decode(json_encode($lists), true);
$inNewsList = false;
foreach($listArray as $list){
if($list = $newsListID){
//the user is subscribed to the news list
$inNewsList = true;
$converted_result = ($inNewsList) ? 'true' : 'false';
}
}
}
$return[] = array(
"status" => $converted_result,
"list" => $listName
);
return json_encode($return);
}
else{
return $return;
}
die();
}
For calling numerous files, it is sometimes convenient to define a constant:
define( 'MY_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
include( MY_PLUGIN_PATH . 'includes/admin-page.php');
include( MY_PLUGIN_PATH . 'includes/classes.php');

Telegram bot Inline keyboards sends too many callbacks PHP

So problem is I am using inline keyboard in my bot. And when I am trying to push this keyboard it gives me 3-5 callbacks. I don't know where is my mistake.
EDIT
I don't know why but it causes this error when i working with mysqli->fetch_assoc();
There is not full code just peace where I use inline keyboard
if ($callback_data!=Null){
checkJSON(3124,$order_id);
$message_id = $update['callback_query']['message']['message_id'];
$callback_data = json_decode($callback_data,true);
checkJSON(3125,$callback_data["order_id"]);
$order_id = $callback_data["order_id"];
checkJSON(3126,$order_id);
$rs = $mysqli->query("SELECT manager_id FROM orders WHERE id=".$order_id);
$row = $rs->fetch_assoc();
$manager = $row['manager_id'];
if ($manager!=Null){
$rs = $mysqli->query("SELECT telegram_id FROM managers WHERE id=".$manager);
$row = $rs->fetch_assoc();
$manager_telegram_id = $row['telegram_id'];
if ($chatID==$manager_telegram_id){
$callback_data = json_decode($callback_data);
$order_id = $callback_data["order_id"];
$status = $callback_data["status"];
checkJSON(1231234,$callback_data);
if($status == '3'){
editMessage($chatID,$message_id,"Заказ N".$order_id." подтвержден");
}
else{
editMessage($chatID,$message_id,"Заказ N".$order_id." отклонен");
}
$mysqli->query("UPDATE orders SET status=".$status." WHERE id=".$order_id);
}
sendMessage($chatID,$update['callback_query']['message']['message_id']);
editMessage($chatID,$message_id,
"Данный заказ уже в оброботке");
}
else{
$get_manager_query = $mysqli->query("SELECT id FROM managers WHERE telegram_id=".$chatID);
$row = $get_manager_query->fetch_assoc();
$manager = $row['id'];
$data1 = json_encode(array("order_id"=>$order_id,"status"=>3));
$data2 = json_encode(array("order_id"=>$order_id,"status"=>4));
$inline_button1 = array("text"=>"Принять","callback_data"=>$data1);
$inline_button2 = array("text"=>"Отказать","callback_data"=>$data2);
$inline_keyboard = [[$inline_button1,$inline_button2]];
$keyboard=json_encode(array("inline_keyboard"=>$inline_keyboard));
editMessage($chatID,$message_id,
"Вы приняли данный заказ",$keyboard);
$rs = $mysqli->query("UPDATE orders SET status=1, manager_id=".$manager." WHERE id=".$order_id);
}
}
function sendMessage($chatID,$text){
$sendto =API_URL."sendmessage?chat_id=".$chatID."&text=".urlencode($text);
file_get_contents($sendto);
}
function editMessage($chatId, $messageId, $message,$replyMarkup=Null) {
$url = API_URL."editMessageText?chat_id=".$chatId."&message_id=".$messageId.
"&text=".urlencode($message)."&reply_markup=".$replyMarkup;
file_get_contents($url);
}
It's Not your mistake!
Telegram Server is send callbacks for every changes in inline query.
You can setting that to off in BotFatherwith /setinlinefeedback command.
For more information visit this
Set your data by some separator After, get that data by $update['callback_query']['data'] and split by seted separator.
$botToken = "(your token)";
$website = "https://(site_url)/bot" . $botToken;
$order_id = '44423'; //my additional data
$keyboard = ["inline_keyboard" => [
[
[
"text" => "Доставлено",
"callback_data" => "delivered_".$order_id, // set few data by '_' separator Like ("delivered_443423_phone12345667_...)
],
[
"text" => "Затримуюсь",
"callback_data" => "delaying_".$order_id,
]
],
]
];
$params = [
'chat_id' => $chat_id,
'text' => $msg,
'parse_mode' => 'html',
'reply_markup' => json_encode($keyboard),
];
$ch = curl_init($website . '/sendMessage');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
Update processing. For get update you need set webhook on file where bot is placed. https://api.telegram.org/bot(your token)/setWebhook?url=https://example.com/bot_directory/bot.php Site must have SSL (https).
$update = json_decode(file_get_contents('php://input'), TRUE);
$botToken = "(your token)";
$botAPI = "https://api.telegram.org/bot" . $botToken;
$msg = $update['message']['text'];
$user_id = $update['message']['from']['id'];
if (isset($update['callback_query'])) {
$update_multiple = explode('_', $update['callback_query']['data']); //split data
if ($update_multiple[0] == 'delivered') {
$data1 = $update_multiple[1]; // get some data
// ......
}
}

Categories