i am using express checkout with this package :
https://github.com/srmklive/laravel-paypal
exactly as example repository one change i made is that the price and item info was hard coded but i passed a model to that function called event because i want to sell events . so it looks like below now :
protected function getCheckoutData($recurring = false,$event = null)
{
$data = [];
$order_id = Invoice::all()->count() + 1;
if ($recurring === true) {
$data['items'] = [
[
'name' => 'Monthly Subscription '.config('paypal.invoice_prefix').' #'.$order_id,
'price' => 12222,
'qty' => 1,
],
];
$data['return_url'] = url('/paypal/ec-checkout-success?mode=recurring');
$data['subscription_desc'] = 'Monthly Subscription '.config('paypal.invoice_prefix').' #'.$order_id;
} else {
$data['items'] = [
[
'name' => $event->title,
'price' => $event->price,
'qty' => 1,
'event_id' => $event->id,
]
];
$data['return_url'] = url('/paypal/ec-checkout-success');
}
$data['invoice_id'] = config('paypal.invoice_prefix').'_'.$order_id;
$data['invoice_description'] = $event->title;
$data['cancel_url'] = url('/');
$total = 0;
foreach ($data['items'] as $item) {
$total += $item['price'] * $item['qty'];
}
$data['total'] = $total;
return $data;
}
now on getExpressCheckoutSuccess function after payment it calls the getCheckoutData again but this time there is no model event on that like below :
public function getExpressCheckoutSuccess(Request $request)
{
$recurring = ($request->get('mode') === 'recurring') ? true : false;
$token = $request->get('token');
$PayerID = $request->get('PayerID');
$cart = $this->getCheckoutData($recurring);
// Verify Express Checkout Token
$response = $this->provider->getExpressCheckoutDetails($token);
.
.
.
so my question is that how can pass the paypal my event id and it returns that to me again or do some thing to detect the event
and pass it to getCheckoutData and verify the payment . thanks in advance
Related
In my Laravel project, I've got a job set up which runs and attempts to notify a user based on their threshold and chosen alert metrics. I'm using the php end() method to get the last item in an array and then attempting to get whatever metric the user has chosen.
However, upon dumping the data, this isn't returning the last array item, it's returning every item and I'm not sure why?
When I dump my data, I'm getting this format instead of the last item in the array:
[2021-04-13 13:30:45] production.DEBUG: array (
0 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '2190',
'period_from' => '2021-04-13 00:00:00',
'period_to' => '2021-04-13 13:30:02',
'created_at' => '2021-04-13 13:30:06',
),
1 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '5184',
'period_from' => '2021-04-12 00:00:00',
'period_to' => '2021-04-12 23:57:02',
'created_at' => '2021-04-12 23:57:07',
),
2 =>
(object) array(
'event_category' => 'My Category',
'event_action' => 'My Event',
'event_count' => '3820',
'period_from' => '2021-04-11 00:00:00',
'period_to' => '2021-04-11 23:57:02',
'created_at' => '2021-04-11 23:57:07',
),
)
I should just be seeing the last item, amongst all of my code, the following is of significant value here:
/**
* Notify if data meets threshold & alert rules
*
* #return void
*/
public function notifyAlertThreshold($alerts, $data)
{
$newestDataPart = end($data) ?? null;
// alerts for data source
foreach ($alerts as $key => $alert) {
Log::debug($newestDataPart);
$metric = !isset($newestDataPart->{$alert->metric}) ? $newestDataPart : $newestDataPart->{$alert->metric};
}
}
In context, here's some mode of the code, but the primary question here, is why is my end() method not returning the last item?
/**
* Execute the job.
*
* #return void
*/
public function handle()
{
$filters = json_decode($this->report->discovery_filters, true);
$this->reportStatus = 'complete';
$data = [];
foreach ($filters as $findableKey => $findable) {
/*
** If there are datasets on the findable objec, then we assume
** that we can build up a chart or some data structure.
*/
if (isset($findable['datasets'])) {
$pushableDatasets = [];
foreach ($findable['datasets'] as $datasetKey => $dataset) {
// query data
if (isset($dataset['query'])) {
$chartLabel = $findable['name'] ?? 'Untitled Chart';
$this->setDynamicChartOptions($chartLabel);
$additionFromField = $dataset['query']['additionFromField'] ?? '';
$resultData = [];
if ($dataset['query']['prefersConversionCalculation'] == 'yes') {
$totals = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['calculateConversionFromTotals'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$goal = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['calculateConversionByGoal'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$totals = $totals->flatten();
$goal = $goal->flatten();
$totalsGrouped = $this->groupData(
$totals,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
$goalsGrouped = $this->groupData(
$goal,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
$totalsGroupedFlattened = $totalsGrouped->flatten();
$goalsGroupedFlattened = $goalsGrouped->flatten();
$resultData = $this->getStructure($findable, $datasetKey, $goalsGroupedFlattened, $totalsGroupedFlattened);
array_push($pushableDatasets, $resultData);
} else {
$res = DB::table($dataset['query']['table'])
->select($dataset['query']['columns'])
->where($dataset['query']['filterBy'])
->orderBy($dataset['query']['orderBy']['field'], $dataset['query']['orderBy']['direction'])
->get()
->chunk(100);
$res = $res->flatten();
if (isset($dataset['query']['useGrouping']) && $dataset['query']['useGrouping'] == 'yes') {
$results = $this->groupData(
$res,
$dataset['query']['groupBy'],
$dataset['query']['groupByFormat'],
$additionFromField
);
// if we're using an addition function our array is already flattened
if (!empty($additionFromField)) {
$resultData = $results;
} else {
$resultData = $results->flatten();
}
array_push($pushableDatasets, $this->getStructure($findable, $datasetKey, $resultData));
}
}
$dataForAlerts = $resultData;
if ($dataset['query']['prefersConversionCalculation'] == 'yes') {
$dataForAlerts = $dataForAlerts['data'];
}
// alerting
$alerts = $this->getAlertThresholds($dataset['query']['table']);
$this->notifyAlertThreshold($alerts, $dataForAlerts);
}
}
$findable['datasets'] = $pushableDatasets;
}
array_push($data, $findable);
}
// no data or it's empty
if (!isset($data) || empty($data)) {
$this->reportStatus = 'error';
}
// create our report data entry
$this->updateReportData(false, $data);
}
I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.
I added srmklive/paypal package, I want to make paypal subscription. but it gives me this error message:
ErrorException
Undefined index: paypal_link
I am using laravel 6, and srmklive/paypal
Anyone can help me please to solve this issue ?
.env file
PAYPAL_MODE=sandbox
PAYPAL_SANDBOX_API_USERNAME=sb-ig0ex880582_api1.business.example.com
PAYPAL_SANDBOX_API_PASSWORD=3PZ2E986EZWQN2PN
PAYPAL_SANDBOX_API_SECRET=AZ2CBQPbtotiGlFrm1tAtmH-bBO3AfpRNGWDT6e68-yh69V.BeCgl7W6
PAYPAL_CURRENCY=USD
PAYPAL_SANDBOX_API_CERTIFICATE=
PaypalController.php file
public function payment(Request $request)
{
$data = [];
$data['items'] = [['name' => "Monthly Subscription", 'price' => 10, 'qty' => 1,],];
$data['subscription_desc'] = "Monthly Subscription #1";
$data['invoice_id'] = 1;
$data['invoice_description'] = "Monthly Subscription #1";
$data['return_url'] = url('/paypal/ec-checkout-success?mode=recurring');
$data['cancel_url'] = url('/');
$total = 0;
foreach ($data['items'] as $item) {
$total += $item['price'] * $item['qty'];
}
$data['total'] = $total;
//give a discount of 10% of the order amount
$data['shipping_discount'] = round((10 / 100) * $total, 2);
$provider = new ExpressCheckout;
// Use the following line when creating recurring payment profiles (subscriptions)
$response = $provider->setExpressCheckout($data);
$response = $provider->setExpressCheckout($data, true);
// The $token is the value returned from SetExpressCheckout API call
$startdate = Carbon::now()->toAtomString();
$profile_desc = !empty($data['subscription_desc']) ? $data['subscription_desc'] :
$data['invoice_description'];
$data = [
'PROFILESTARTDATE' => $startdate,
'DESC' => $profile_desc,
'BILLINGPERIOD' => 'Month', // Can be 'Day', 'Week', 'SemiMonth', 'Month', 'Year'
'BILLINGFREQUENCY' => 1, //
'AMT' => 10, // Billing amount for each billing cycle
'CURRENCYCODE' => 'USD', // Currency code
'TRIALBILLINGPERIOD' => 'Day',
'TRIALBILLINGFREQUENCY' => 10, // (Optional) set 12 for monthly, 52 for yearly
'TRIALTOTALBILLINGCYCLES' => 1, // (Optional) Change it accordingly
'TRIALAMT' => 0, // (Optional) Change it accordingly
];
$response = $provider->createRecurringPaymentsProfile($data, $response['TOKEN']);
// This will redirect user to PayPal
return redirect($response['paypal_link']);
}
I have a function for Paypal redirection for that I pass some values in params..
It only pass the Description field doesn't shows the amount to be paid,and rest of my order summaries..
Here is my function
public function postPayment()
{
$hot_id = \Session::get('hot_id');
$user_id = \Session::get('uid');
$check_in = \Session::get('check_in');
$check_out = \Session::get('check_out');
$mem_count = \Session::get('mem_count');
$rm_no = \Session::get('rm_no');
$check_in = strtotime($check_in);
$check_in = date('Y-m-d',$check_in);
$check_out = strtotime($check_out);
$check_out = date('Y-m-d',$check_out);
$datediff = strtotime($check_out) - strtotime($check_in);
$diff = floor($datediff/(86400));
$room_prize = \DB::select("SELECT `room_prize` FROM `abserve_hotel_rooms` WHERE `room_id` = ".$_POST['room_id']);
$arr = array();
foreach ($room_prize as $key => $value) {
$arr[]= (get_object_vars($value));
}
$room_prize = array();
foreach ($arr as $key => $value) {
$room_prize[]=($value['room_prize']);
}
if($rm_no == 1)
{
$room_prize = (int) $room_prize[0] * (int) $diff;
}
else
{
$room_prize = (int) $room_prize[0] * (int) $diff * (int) $rm_no;
}
$room_prize = number_format((float)$room_prize, 2, '.', '');
$room_id = $_POST['room_id'];
$today = new DateTime();
$created_at = $today->format('Y-m-d');
$values = array('user_id' => $user_id,'hotel_id' => $hot_id,'room_id'=>$room_id,'room_prize'=>$room_prize,'check_in'=>$check_in,'check_out'=>$check_out,'created_at'=>$created_at);
\DB::table('abserve_orders')->insert($values);
$order_id = DB::select("SELECT `id` FROM `abserve_orders` WHERE `room_id` = ".$_POST['room_id']." AND `user_id` = ".$user_id);
$arr = array();
foreach ($order_id as $key => $value) {
$arr[]= (get_object_vars($value));
}
$order_id = array();
foreach ($arr as $key => $value) {
$order_id[]=($value['id']);
}
$order_id = $order_id[0];
$params = array(
'cancelUrl' => url().'/cancel_order',
'returnUrl' => url().'/payment_success',
'name' => 'new order',
'description' => 'description1',
'amount' => $room_prize,
'currency' => 'USD',
'hot_id' => $hot_id,
'room_id' => $room_id,
'user_id' => $user_id,
'check_in' => $check_in,
'check_out' => $check_out,
'order_id' => $order_id,
'nights' => $diff,
);
// print_r($params);exit;
\Session::put('params', $params);
\Session::save();
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('googley555_api1.yahoo.com');
$gateway->setPassword('3EQ6S6PB68A52JKZ');
$gateway->setSignature('AFcWxV21C7fd0v3bYYYRCpSSRl31AHaEiWOLAf5jQQ3-A9hLlhypSz9h');
$gateway->setTestMode(true);
$response = $gateway->purchase($params)->send();
if ($response->isSuccessful()) {
// payment was successful: update database
print_r($response);
} elseif ($response->isRedirect()) {
// redirect to offsite payment gateway
$response->redirect();
} else {
// payment failed: display message to customer
echo $response->getMessage();
}
}
I don't know what are missing in it..
Someone please help me..
You can't pass in arbitrary parameters such as hot_id, room_id, etc to PayPal (or omnipay) because it won't know what to do with them. PayPal is only intended to take certain parameters and the ones that PayPal does not take are ignored by Omnipay.
You may have to provide all of these extra parameters as part of the description parameter, which PayPal does understand.
Ideally these should be displayed by your application in some kind of useful format to the user before redirecting the user to the PayPal checkout page.
I'm trying to render my order in my page validation but when refresh my validation.html.twig i got this error:
Error: Cannot use object of type FLY\BookingsBundle\Entity\Address as
array
if (!isset($order['tva']['%'.$entity->getTva()->getValue()]))
but i don't see anything wrong in my controller:
bill
public function bill()
{
$em = $this->getDoctrine()->getManager();
$generator = $this->container->get('security.secure_random');
$session = $this->getRequest()->getSession();
$address = $session->get('address');
$cart = $session->get('cart');
$order = array();
$totalHT = 0;
$totalTTC = 0;
$order = $em->getRepository('FLYBookingsBundle:Address')->find($address['address']);
$entities = $em->getRepository('FLYBookingsBundle:Post')->findArray(array_keys($session->get('cart')));
foreach($entities as $entity)
{
$priceHT = ($entity->getPrice() * $cart[$entity->getId()]);
$priceTTC = ($entity->getPrice() * $cart[$entity->getId()] / $entity->getTva()->getMultiplicate());
$totalHT += $priceHT;
$totalTTC += $priceTTC;
if (!isset($order['tva']['%'.$entity->getTva()->getValue()]))
$order['tva']['%'.$entity->getTva()->getValue()] = round($priceTTC - $priceHT,2);
else
$order['tva']['%'.$entity->getTva()->getValue()] += round($priceTTC - $priceHT,2);
$order['entity'][$order->getId()] = array('reference' => $order->getName(),
'quantity' => $cart[$entity->getId()],
'priceHT' => round($entity->getPrice(),2),
'priceTTC' => round($entity->getPrice() / $entity->getTva()->getMultiplicate(),2));
}
$order['address'] = array('surname' => $address->getSurname(),
'name' => $address->getName(),
'phone' => $address->getPhone(),
'address' => $address->getAddress(),
'zipcode' => $address->getZipcode(),
'city' => $address->getCity(),
'country' => $address->getCountry(),
'complement' => $address->getComplement());
$order['priceHT'] = round($totalHT,2);
$order['priceTTC'] = round($totalTTC,2);
$order['token'] = bin2hex($generator->nextBytes(20));
return $order;
}
ValidationAction
public function validationAction()
{
if ($this->get('request')->getMethod() == 'POST')
$this->setAddressOnSession();
$em = $this->getDoctrine()->getManager();
$prepareOrder = $this->forward('FLYBookingsBundle:Post:prepareOrder');
$order = $em->getRepository('FLYBookingsBundle:Address')->find($prepareOrder->getContent() );
return $this->render('FLYBookingsBundle:Post:validation.html.twig', array('order' => $order));
}
You are assigning Address object to the $order variable by $order = $em->getRepository('FLYBookingsBundle:Address')->find($address['address']); and then you want to use it as an array here $order['tva']..... and further down in your code. You have to work with $order by its methods/properties like $order->getTVA().