How to generate PayPal order pay link to email - laravel

I'm trying to generate PayPal link to email, where user can pay for their order later. I'am using paypal/rest-api-sdk-php. For example using this route:
Route::get('/order/pay/{hash}', 'Frontend\PaymentController#orderPay')->name('order.pay');
My code for payment creation works (see code). When user cancel the payment or payment is unsuccessful, how can I return to the incomplete transaction and try to pay for it again? Should I create new payment everytime user goes to order pay route? Or can I simply identify the incomplete transaction in PayPal and redirect to some(?) PayPal link then?
use PayPal\Api\Payer;
use PayPal\Api\Item;
use PayPal\Api\ItemList;
use PayPal\Api\Details;
use PayPal\Api\Amount;
use PayPal\Api\Transaction;
use PayPal\Api\RedirectURLs;
use PayPal\Api\Payment;
/*
* #param \App\Order $order
* #return string
*/
public function createPayment($order)
{
$transaction = $this->getTransactionByOrderHash($order->hash);
if ($transaction) {
if ($transaction->is_refunded) {
return 'Paymant has already been refunded';
}
if ($transaction->is_payed) {
return 'Paymant has already been payed';
}
}
$price = $order->to_pay;
$currencyCode = $order->currency->iso_code;
try {
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$item = new Item();
$item
->setName(__('invoice.pfa_title'))
->setCurrency($currencyCode)
->setQuantity(1)
->setSku($order->vs)
->setPrice($price);
$itemList = new ItemList();
$itemList->setItems([$item]);
$details = new Details();
$details
->setShipping(0)
->setTax(0)
->setSubtotal($price);
$amount = new Amount();
$amount
->setCurrency($currencyCode)
->setTotal($price)
->setDetails($details);
$transaction = new Transaction();
$transaction
->setAmount($amount)
->setItemList($itemList)
->setInvoiceNumber(uniqid());
$redirectUrls = new RedirectUrls();
$redirectUrls
->setReturnUrl(route('paypal.success', $order->hash))
->setCancelUrl(route('paypal.cancel'));
$payment = new Payment();
$payment
->setIntent('sale')
->setPayer($payer)
->setRedirectUrls($redirectUrls)
->setTransactions([$transaction]);
$payment->create($this->apiContext);
$approvalUrl = $this->getApprovalUrl($payment);
if ($approvalUrl) {
session([
'approval_url' => $approvalUrl,
'transaction_id' => $payment->getId(),
]);
return 'payment was successful';
}
} catch (PayPalConnectionException $ex) {
return json_decode($ex->getData());
} catch (Throwable $e) {
return $e->getMessage();
}
return 'payment was unsuccessful';
}

Why use the deprecated v1/payments PayPal-PHP-SDK, instead of the current v2/checkout/orders Checkout-PHP-SDK ?
In any case, yes you can create a new Payment/Order object everytime the customer attempts a checkout. Just set the invoice_id field to your own same but unique invoice/order number for the thing that customer is paying for, so that if the customer does happen to be trying to make a duplicate payment attempt for such a # that has already resulted in a successful transaction on your PayPal account before, it will be blocked by default (according to your PayPal account settings)

Related

Laravel Controller Request Verify

Can someone help me verify a request via controller? I don't know how to do this.
public function verify(Request $request){
$key = clean($request->purchasecode);
$response = \Core\Http::url("https://cdn.gempixel.com/validator/";)
->with('X-Authorization', 'TOKEN '.md5(url()))
->body(['url' => url(), 'key' => $key])
->post()
->getBody();
if(!$response || empty($response) || $response == "Failed"){
return back()->with("danger", "This purchase code is not valid. It is either for another item or has been disabled.");
}elseif($response == "TooMany"){
return back()->with("danger", "This purchase code is already used on another domain. If you need to reset it, please us your purchase code and domain to reset it.");
}elseif($response == "Wrong.Item"){
return back()->with("danger", "This purchase code is for another item. Please use a Premium URL Shortener extended license purchase code.");
}elseif($response == "Wrong.License"){
return back()->with("danger", "This purchase code is for a standard license. Please use a Premium URL Shortener extended license purchase code.");
} else {
$setting = DB::settings()->where('config', 'purchasecode')->first();
$setting->var = $key;
$setting->save();
$this->seelfdb($response);
}
}
/**
* Seelfdb:code
*
* #author GemPixel <https://gempixel.com>
* #version 6.0
* #return void
*/
private function seelfdb($r){
$q = str_replace("_PRE_", DBprefix, $r);
$qs = explode("|", $q);
foreach ($qs as $query) {
if(!DB::raw_execute($query)){
return Gem::trigger(500, 'Task failed.');
}
}
return back()->with('success', base64_decode('RXh0ZW5kZWQgdmVyc2lvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgdW5sb2NrZWQuIFlvdSBtYXkgbm93IHVzZSBwYXltZW50IG1vZHVsZXMgYW5kIHN1YnNjcmlwdGlvbnMu'));
}
}
It's a laravel based website. I need to enable payment methods, the only method to do this is by verifying the purchase code. You can see the validator URL in the code. But I want to Bypass or something like this to verify any purchase code to trigger
$setting = DB::settings()->where('config', 'purchasecode')->first();
$setting->var = $key;
$setting->save();
$this->seelfdb($response);
And then I couldn't understand what is this code
private function seelfdb($r){
$q = str_replace("_PRE_", DBprefix, $r);
$qs = explode("|", $q);
foreach ($qs as $query) {
if(!DB::raw_execute($query)){
return Gem::trigger(500, 'Task failed.');
}
}
return back()->with('success', base64_decode('RXh0ZW5kZWQgdmVyc2lvbiBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgdW5sb2NrZWQuIFlvdSBtYXkgbm93IHVzZSBwYXltZW50IG1vZHVsZXMgYW5kIHN1YnNjcmlwdGlvbnMu'));
}

Order split with online transaction on checkout in magento 2.4 enterprise

I'm facing one issue while splitting the order on checkout. I followed these code mentioned in the link:-
https://magento.stackexchange.com/questions/196669/magento-2-split-order-for-every-item
and
https://github.com/magestat/magento2-split-order
Both solution is working with offline payment like check/mo, Cash on delivery, po number etc. But its not working with credit card details. Always getting error regarding credit card details.
I'm putting some more information through code:-
I am stuck at a point to distribute order and assign payment method into it.
there are two scenario i'm getting:
if i assign payment method checkmo,Cash on delivery then order is splitted and everything is working fine with this.
But i need to order products using credit card and when i assign payment method code(credit card payment method is 'nmi_directpost') and also assign card details into quote and placed and order then its showing me error differently, Some time its shows credit card details is not valid, sometime page is redirected to cart page without any log/exception. Here is bunch of code i'm trying to do:-
public function aroundPlaceOrder(QuoteManagement $subject, callable $proceed, $cartId, $payment = null)
{
$currentQuote = $this->quoteRepository->getActive($cartId);
// Separate all items in quote into new quotes.
$quotes = $this->quoteHandler->normalizeQuotes($currentQuote);
if (empty($quotes)) {
return $result = array_values([($proceed($cartId, $payment))]);
}
// Collect list of data addresses.
$addresses = $this->quoteHandler->collectAddressesData($currentQuote);
/** #var \Magento\Sales\Api\Data\OrderInterface[] $orders */
$orders = [];
$orderIds = [];
foreach ($quotes as $items) {
/** #var \Magento\Quote\Model\Quote $split */
$split = $this->quoteFactory->create();
// Set all customer definition data.
$this->quoteHandler->setCustomerData($currentQuote, $split);
$this->toSaveQuote($split);
// Map quote items.
foreach ($items as $item) {
// Add item by item.
$item->setId(null);
$split->addItem($item);
}
\Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('new quote 1st :-'. print_r($split->getData(),true));
$this->quoteHandler->populateQuote($quotes, $split, $items, $addresses, $payment);
// $split->getPayment()->setMethod('nmi_directpost');
// if ($payment) {
// $split->getPayment()->setQuote($split);
// $data = $payment->getData();
// $paymentDetails = $paymentCardDetails = '';
// $postData = file_get_contents("php://input");//Get all param
// $postData = (array)json_decode($postData);//Decode all json param
// foreach ($postData as $key => $value) {
// if ($key == 'paymentMethod') { //Get paymentMethod details
// $paymentDetails = (array)$value;
// foreach ($paymentDetails as $key1 => $paymentValue) {
// if ($key1 == 'additional_data') { //get paymentMethod Details like card details
// $paymentCardDetails = (array)$paymentValue;
// }
// }
// }
// }
// $split->setMethod('checkmo');
\Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('Paynet :-');
// $payment = $quotes->getPayment();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
$quote = $cart->getQuote();
$paymentMethod = $quote->getPayment()->getMethod();
$payment = $this->checkoutSession->getQuote()->getData();
\Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('second Paynet :-');
\Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('new quote :-'. print_r($paymentMethod,true));
// $split->setPayment($payment);
// $split->getPayment()->importData(array(
// 'method' =>'nmi_directpost',
// 'cc_type' =>'VI',
// 'cc_number' =>'4111111111111111',
// 'cc_exp_year' =>'2025',
// 'cc_exp_month'=>'10',
// ));
// }
// \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('original quote :-'. print_r($quotes->getData(),true));
\Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('new quote :-'. print_r($split->getData(),true));
// \Magento\Framework\App\ObjectManager::getInstance()->get('Psr\Log\LoggerInterface')->info('new quote :-'. print_r($payment->getData(),true));
// Dispatch event as Magento standard once per each quote split.
$this->eventManager->dispatch(
'checkout_submit_before',
['quote' => $split]
);
$this->toSaveQuote($split);
$order = $subject->submit($split);
$orders[] = $order;
$orderIds[$order->getId()] = $order->getIncrementId();
if (null == $order) {
throw new LocalizedException(__('Please try to place the order again.'));
}
}
$currentQuote->setIsActive(false);
$this->toSaveQuote($currentQuote);
$this->quoteHandler->defineSessions($split, $order, $orderIds);
$this->eventManager->dispatch(
'checkout_submit_all_after',
['orders' => $orders, 'quote' => $currentQuote]
);
return $this->getOrderKeys($orderIds);
}
Please suggest how can we achieve order splitting with credit card payment.
Splitting payment across multiple credit cards like this is referred to as 'partial authorization'. (Note: This is a very different thing from 'partial invoicing' or 'partial capturing', terms you'll also see thrown around.)
Magento's default Authorize.Net gateway includes partial authorization functionality, you just have to enable it in the gateway settings. This works with both Community and Enterprise Edition. See official documentation on the setup and workflow here.
To my knowledge, this is the only payment method that supports it.
Note that the customer does not get to choose how much to charge to each card. Rather, if the card they enter does not have sufficient funds, they will be prompted to enter another one.

Class not found in Laravel 7

I have installed a package for Laravel 7, the package in question is this http://paypal.github.io/PayPal-PHP-SDK/ to manage payments with Paypal.
I created everything, controller, web route, everything.
But the moment I go to the page to test I can't find the class.
Target class [App\Http\Controllers\PaypalController] does not exist.
PaypalController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
// use to process billing agreements
use PayPal\Api\Agreement;
use PayPal\Api\Payer;
use PayPal\Api\Plan;
use PayPal\Api\ShippingAddress;
class PaypalController extends Controller
{
private $apiContext;
private $mode;
private $client_id;
private $secret;
private $plan_id;
// Create a new instance with our paypal credentials
public function __construct()
{
// Detect if we are running in live mode or sandbox
if(config('paypal.settings.mode') == 'live'){
$this->client_id = config('paypal.live_client_id');
$this->secret = config('paypal.live_secret');
$this->plan_id = env('PAYPAL_LIVE_PLAN_ID', '');
} else {
$this->client_id = config('paypal.sandbox_client_id');
$this->secret = config('paypal.sandbox_secret');
$this->plan_id = env('PAYPAL_SANDBOX_PLAN_ID', '');
}
// Set the Paypal API Context/Credentials
$this->apiContext = new ApiContext(new OAuthTokenCredential($this->client_id, $this->secret));
$this->apiContext->setConfig(config('paypal.settings'));
}
public function paypalRedirect(){
// Create new agreement
$agreement = new Agreement();
$agreement->setName('App Name Monthly Subscription Agreement')
->setDescription('Basic Subscription')
->setStartDate(\Carbon\Carbon::now()->addMinutes(5)->toIso8601String());
// Set plan id
$plan = new Plan();
$plan->setId($this->plan_id);
$agreement->setPlan($plan);
// Add payer type
$payer = new Payer();
$payer->setPaymentMethod('paypal');
$agreement->setPayer($payer);
try {
// Create agreement
$agreement = $agreement->create($this->apiContext);
// Extract approval URL to redirect user
$approvalUrl = $agreement->getApprovalLink();
return redirect($approvalUrl);
} catch (PayPal\Exception\PayPalConnectionException $ex) {
echo $ex->getCode();
echo $ex->getData();
die($ex);
} catch (Exception $ex) {
die($ex);
}
}
public function paypalReturn(Request $request){
$token = $request->token;
$agreement = new \PayPal\Api\Agreement();
try {
// Execute agreement
$result = $agreement->execute($token, $this->apiContext);
$user = Auth::user();
$user->role = 'subscriber';
$user->paypal = 1;
if(isset($result->id)){
$user->paypal_agreement_id = $result->id;
}
$user->save();
echo 'New Subscriber Created and Billed';
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
echo 'You have either cancelled the request or your session has expired';
}
}
}
Routes
Route::get('/subscribe/paypal', 'PaypalController#paypalRedirect');
Route::get('/subscribe/paypal/return', 'PaypalController#paypalReturn');
I can't understand what the problem is! Thank you all
Just run:
composer dump-autoload
to regenerate all classes, see: https://getcomposer.org/doc/03-cli.md
Mention the Laravel 7 route:
Route::post('create_paypal_plan','App\Http\Controllers\PaypallController#create_plan');
just like this.

Magento SOAP login error

I have configured Magento SOAP api to connect it with my android app, customers can login from android app into magento. The problem I am facing is when I send the request it shows the error - "Session expired".
this is my API.php file
<?php
// app/code/local/Anaqa/Customapimodule/Model/Login/Api.php
class Anaqa_Customapimodule_Model_Customerlogin_Api extends Mage_Api_Model_Resource_Abstract {
public function customerEntry($email) {
#Mage::app()->setCurrentStore($website);
# // Init a Magento session. This is super ultra important
#Mage::getSingleton('core/session');
// $customer Mage_Customer_Model_Customer
// We get an instance of the customer model for the actual website
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
// Load the client with the appropriate email
$customer->loadByEmail($email);
return $customer;
}
/*
ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient('http://magentohost/api/soap/?wsdl', array('cache_wsdl' => WSDL_CACHE_NONE));
$session = $client->login('apiUser', 'apiKey');
$result = $client->call($session, 'product.list');
$client->endSession($session);
Mage::app()->setCurrentStore($website);
// Init a Magento session. This is super ultra important
Mage::getSingleton('core/session');
// $customer Mage_Customer_Model_Customer
// We get an instance of the customer model for the actual website
$customer = Mage::getModel('customer/customer')
->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
// Load the client with the appropriate email
$customer->loadByEmail($email);
// Get a customer session
$session = Mage::getSingleton('customer/session');
$session->loginById($customer->getId());
if ($session->isLoggedIn()) {
return $session->getSessionId();
} else {
return null;
}
} */
}
I would use the customer/session model to access the customer.
$sessionCustomer = Mage::getSingleton('customer/session');
if($sessionCustomer->isLoggedIn()) {
$customer = Mage::getSingleton('customer/session')->getCustomer();
The wrinkle here is in order for magento to access the session data it needs to know the customer is logged in, otherwise you won't be able to return the customer data with the session data.

send transactional email magento

I'm trying to send a confirmation email when a subscription order is created in magento but is not sending anything.
i know email configuration its fine because when i buy a regular product i do receive the email.
i created a template on System -> Transactional Emails , template with id=12, then on code on class AW_Sarp2_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage i call to send subs email method but it never sends any email
class AW_Sarp2_Model_Checkout_Type_Onepage extends Mage_Checkout_Model_Type_Onepage
{
public function saveOrder()
{ Mage::log("checkout/onepage",null,"onepageemail.log");
$isQuoteHasSubscriptionProduct = Mage::helper('aw_sarp2/quote')->isQuoteHasSubscriptionProduct(
$this->getQuote()
);
if (!$isQuoteHasSubscriptionProduct) //HERE I ASK IF IS A SUBSCRIBE PRODUCT {Mage::log("checkout/onepage34",null,"onepageemail.log");
return parent::saveOrder();
}
$this->validate();
$isNewCustomer = false;
switch ($this->getCheckoutMethod()) {
case self::METHOD_GUEST:Mage::log("checkout/onepage40",null,"onepageemail.log");
$this->_prepareGuestQuote();
break;
case self::METHOD_REGISTER:Mage::log("checkout/onepage43",null,"onepageemail.log");
$this->_prepareNewCustomerQuote();
$isNewCustomer = true;
break;
default:Mage::log("checkout/onepage47",null,"onepageemail.log");
$this->_prepareCustomerQuote();
break;
}
if ($this->getQuote()->getCustomerId()) {Mage::log("checkout/onepage52",null,"onepageemail.log");
$this->getQuote()->getCustomer()->save();
}
#AW_SARP2 override start
$service = Mage::getModel('aw_sarp2/sales_service_profile', $this->getQuote());Mage::log("checkout/onepage56",null,"onepageemail.log");
$service->submitProfile();Mage::log("checkout/onepage57",null,"onepageemail.log");
#AW_SARP2 override end
$this->getQuote()->save();Mage::log("checkout/onepage60",null,"onepageemail.log");
if ($isNewCustomer) {Mage::log("checkout/onepage61",null,"onepageemail.log");
try {
$this->_involveNewCustomer();Mage::log("checkout/onepage63",null,"onepageemail.log");
} catch (Exception $e) {
Mage::logException($e);
}
}
$this->_checkoutSession->setLastQuoteId($this->getQuote()->getId())
->setLastSuccessQuoteId($this->getQuote()->getId())
->clearHelperData();Mage::log("checkout/onepage71",null,"onepageemail.log");
// add recurring profiles information to the session
$profiles = $service->getRecurringPaymentProfiles();Mage::log("checkout/onepage73",null,"onepageemail.log");
if ($profiles) {Mage::log("checkout/onepage74",null,"onepageemail.log");
$ids = array();
foreach ($profiles as $profile) {
$ids[] = $profile->getId();
}Mage::log("checkout/onepage78",null,"onepageemail.log");
$this->sendSubscribeEmail2();Mage::log("checkout/onepage79",null,"onepageemail.log");
$this->_checkoutSession->setLastRecurringProfileIds($ids);
Mage::log("checkout/onepage82",null,"onepageemail.log");
}
return $this;
}
public function sendSubscribeEmail2(){ //HERE I TRY TO SEND THE EMAIL
$templateId = 12;
// Set sender information
$senderName = Mage::getStoreConfig('trans_email/ident_support/name');
$senderEmail = Mage::getStoreConfig('trans_email/ident_support/email');
$sender = array('name' => $senderName,
'email' => $senderEmail);
// Set recepient information
$recepientEmail = 'minorandres#gmail.com';
$recepientName = 'Test Test';
// Get Store ID
$storeId = Mage::app()->getStore()->getId();
// Set variables that can be used in email template
$vars = array('customerName' => 'test',
'customerEmail' => 'minorandres#gmail.com');
$translate = Mage::getSingleton('core/translate');Mage::log("checkout/onepage103",null,"onepageemail.log");
// Send Transactional Email
Mage::getModel('core/email_template')
->sendTransactional($templateId, $sender, $recepientEmail, $recepientName, $vars, $storeId);Mage::log("checkout/onepage106",null,"onepageemail.log");
if (!Mage::getModel('core/email_template')->getSentSuccess()) {
Mage::log("EXCEPTION!!!! =( checkout/onepage107",null,"onepageemail.log");
}
is there something in xml files that i have to do or other place?, please help me
Since i am dealing with subscription products they are handle by a different SMTP provider, on the exception.log i got and error "Mandril cant send email" something like that then i went to Admin Panel and under system>transactional emails has a subtab called mandril i configured that tool and create an account on mandril, then i put the API key indicaded by mandril into system>configuration>mandril(on left side).

Resources