I'm new to Payum. A lot thing quite confuse to me. I'm try to build up a simple paypal express checkout like the example show on the Payum document.However, when I tried to process the payment, it shows up an exception:
"Payum payment named my_paypal_express_checkout does not exist.
500 Internal Server Error - InvalidArgumentException"
Here is the config:
payum:
security:
token_storage:
Acme\PaymentBundle\Entity\PayumSecurityToken:
doctrine:
driver: orm
storages:
Acme\PaymentBundle\Entity\PaymentDetails:
doctrine:
driver: orm
contexts:
Ibase_paypal_express:
paypal_express_checkout_nvp:
...codes...
Here are the code of prepare and done action in controller:
public function preparePaypalAction(Request $request)
{
$paymentName = 'ibase_paypal_express_checkout';
$form = $this->createPurchaseForm();
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
$storage = $this->get('payum')->getStorage('Ibase\PaymentBundle\Entity\PaymentDetails');
/** #var \Ibase\CartBundle\Entity\PaymentDetails $paymentDetails */
$paymentDetails = $storage->createModel();
$paymentDetails['PAYMENTREQUEST_0_CURRENCYCODE'] = $data['currency'];
$paymentDetails['PAYMENTREQUEST_0_AMT'] = $data['amount'];//total amount ??
$storage->updateModel($paymentDetails);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$paymentName,
$paymentDetails,
'payment_done' // the route to redirect after capture;
);
$paymentDetails['INVNUM'] = $paymentDetails->getId();
$paymentDetails['RETURNURL'] = $captureToken->getTargetUrl();
$paymentDetails['CANCELURL'] = $captureToken->getTargetUrl();
$storage->updateModel($paymentDetails);
return $this->redirect($captureToken->getTargetUrl());
}
return $this->render('PaymentBundle:PaypalExpress:paypalPrepare.html.twig', array(
'form' => $form->createView(),
'paymentName' => $paymentName
));
}
public function doneAction(Request $request)
{
$token = $this->get('payum.security.http_request_verifier')->verify($request);
$payment = $this->get('payum')->getPayment($token->getPaymentName());
$status = new BinaryMaskStatusRequest($token);
$payment->execute($status);
if ($status->isSuccess()) {
$this->getUser()->addCredits(100);
$this->get('session')->getFlashBag()->set(
'notice',
'Payment success. Credits were added'
);
} else if ($status->isPending()) {
$this->get('session')->getFlashBag()->set(
'notice',
'Payment is still pending. Credits were not added'
);
} else {
$this->get('session')->getFlashBag()->set('error', 'Payment failed');
}
return $this->redirect('home');
}
/**
* #return \Symfony\Component\Form\Form
*/
protected function createPurchaseForm()
{
return $this->createFormBuilder()
->add('amount', null, array(
'data' => 1,
'constraints' => array(new Range(array('max' => 2)))
))
->add('currency', null, array('data' => 'AUD'))
->getForm()
;
}
Anyone can help will be appreciate!
Look at your YML file
contexts:
Ibase_paypal_express:
and your code :
$paymentName = 'ibase_paypal_express_checkout';
Notice the capital 'I' and string name? Those two names/values should be the same.
So either
$paymentName = 'Ibase_paypal_express';
or
contexts:
ibase_paypal_express_checkout:
Related
hey there I'm trying to do crud operation using Symfony and elastic search, crud is working fine but when I insert or delete data then elastic search data is not updating by self I need to run populate command every time. can you help with this?
here is my fos_elastica.yml file.
fos_elastica:
clients:
default: { url: '%env(ELASTICSEARCH_URL)%' }
indexes:
reply:
properties:
category:
type: object
properties:
title: ~
persistence:
driver: orm
model: App\Entity\Reply
and here is my controller.
<?php
namespace App\Controller\CP\Support\Replies;
use App\Controller\CP\AbstractCPController;
use App\Entity\Reply;
use App\Form\Filter\ReplyFilterType;
use App\Form\ReplyType;
use App\Repository\ReplyRepository;
use App\Security\Enum\AdminPermission;
use App\Security\Routing\DenyAccessUnlessGranted;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use FOS\ElasticaBundle\Finder\TransformedFinder;
use Elastica\Util;
use Throwable;
#[Route('/support/pre-defined-replies/reply')]
#[DenyAccessUnlessGranted(permission: AdminPermission::MANAGE_PRE_DEFINED_REPLIES_REPLY)]
class ReplyController extends AbstractCPController
{
private ReplyRepository $replyRepository;
public function __construct(ReplyRepository $replyRepository)
{
$this->replyRepository = $replyRepository;
}
#[Route('/', name: 'cp_support_pre_defined_replies_reply_index', methods: ['GET'])]
public function index(TransformedFinder $replyFinder, Request $request): Response
{
$searchTerm = '';
$filterForm = $this->createForm(ReplyFilterType::class);
$filterForm->handleRequest($request);
if ($filterForm->isSubmitted()) {
$category = $filterForm->get('category')->getData();
$searchTerm = $category->getName();
}
$search = Util::escapeTerm($searchTerm);
$results = $replyFinder->find($search);
return $this->render('support/pre_defined_replies/reply/index.html.twig', [
'replies' => $results,
'form' => $filterForm->createView(),
]);
}
#[Route('/new', name: 'cp_support_pre_defined_replies_reply_new', methods: ['GET', 'POST'])]
public function new(Request $request): Response
{
$reply = new Reply();
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully created new reply.');
} catch (Throwable $throwable) {
$this->addFlash('danger', 'fail create new reply.');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/new.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
#[Route('/{id}/edit', name: 'cp_support_pre_defined_replies_reply_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, Reply $reply): Response
{
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully updated reply');
} catch (Throwable $throwable) {
$this->addFlash('danger', 'failed to update reply');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/edit.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
#[Route('/{id}/delete', name: 'cp_support_pre_defined_replies_reply_delete', methods: ['POST'])]
public function delete(Request $request, Reply $reply): Response
{
$csrfTokenReply = (string) $request->request->get('csrf');
$status = false;
$errorMessage = null;
if ($this->isCsrfTokenValid('reply', $csrfTokenReply)) {
try {
$this->replyRepository->remove($reply);
$status = true;
$this->addFlash('danger', 'category successfully deleted');
} catch (\Throwable $e) {
$errorMessage = 'An error occurred when deleting category from DB.';
}
} else {
$errorMessage = 'Invalid CSRF token';
}
return new JsonResponse(['status' => $status, 'errorMessage' => $errorMessage]);
}
}
we can use refresh indexes in elastic search for update data
first we need to bind new parameter in service.yaml file
App\Controller\CP\Support\Replies\ReplyController:
tags: [ controller.service_arguments ]
bind:
FOS\ElasticaBundle\Finder\TransformedFinder $replyFinder: '#fos_elastica.finder.reply'
FOS\ElasticaBundle\Elastica\Index: '#fos_elastica.index.reply'
then we can use simply like this in controller to refresh indexes
#[Route('/new', name: 'cp_support_pre_defined_replies_reply_new', methods: ['GET', 'POST'])]
public function new(Request $request, Index $replyIndex): Response
{
$reply = new Reply();
$form = $this->createForm(ReplyType::class, $reply);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
try {
$this->replyRepository->add($reply, true);
$this->addFlash('success', 'successfully created new reply.');
$replyIndex->refresh();
} catch (Throwable $throwable) {
$this->addFlash('danger', 'fail create new reply.');
}
return $this->redirectToRoute('cp_support_pre_defined_replies_reply_index', [], Response::HTTP_SEE_OTHER);
}
return $this->renderForm('support/pre_defined_replies/reply/new.html.twig', [
'reply' => $reply,
'form' => $form,
]);
}
I have a search form that works with the method POST, but the method POST doesn't display the requested data in the url.
With method POST the url look like this:
/search_flight
with the method GET no results found, the url look like this:
/search_flight?from=Cape+Town%2C+International+CPT&to=Johannesburg%2C+O.R.+Tambo+International+JNB&departuredate=2016%2F01%2F08&arrivaldate=2016%2F10%2F04&price=57.5%2C1000
I also noticed that with the method GET the data is reset in each input of the form.
routing.yml
searchFlight:
path: /search_flight
defaults: { _controller: FLYBookingsBundle:Post:searchtabflightResult }
requirements:
_method: GET|POST
controller
This method send the requested data to the method searchtabflightResultAction that will handle the query.
public function searchtabflightAction()
{
//$form = $this->createForm(new SearchflightType(),null, array('action' => $this->generateUrl('searchFlight'),'method' => 'GET',));
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
return $this->render('FLYBookingsBundle:Post:searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
.
<form action="{{ path ('searchFlight') }}" method="GET">
{# here I have my forms #}
</form>
.
public function searchtabflightResultAction(Request $request)
{
//$form = $this->createForm(new SearchflightType());
$form = $this->get('form.factory')->createNamed(null, new SearchflightType());
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
$airport1 = $form["to"]->getData();
$airport = $form["from"]->getData();
$departureDateObj = $form["departuredate"]->getData();
$arrivalDateObj = $form["arrivaldate"]->getData();
$price = $form["price"]->getData();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($airport1,$airport,$departureDateObj,$arrivalDateObj,$price);
return $this->render('FLYBookingsBundle:Post:searchtabflightResult.html.twig', array(
'entities' => $entities,
'form' => $form->createView(),
));
}
How can I make my search filter works with method get ?
Everything should be done within two actions, the basic concept is:
SearchFlightType has with/wo price option:
class SearchFlightType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('from', FormType\TextType::class)
->add('to', FormType\TextType::class)
->add('departuredate', FormType\TextType::class)
->add('arrivaldate', FormType\TextType::class);
if ($options['price']) {
$builder->add( 'price', FormType\TextType::class );
}
$builder
->add('submit', FormType\SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'price' => false,
));
}
}
Controller.php
class PostController extends Controller
{
/**
* #Route("/index", name="index")
*/
public function indexAction(Request $request)
{
$defaultData = array();
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// action is set to the specific route, so the form will
// redirect it's submission there
'action' => $this->generateUrl('search_flight_result'),
// method is set to desired GET, so the data will be send
//via URL params
'method' => 'GET',
));
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
));
}
/**
* #Route("/search_flight_result", name="search_flight_result")
*/
public function searchTabFlightResultAction(Request $request)
{
$defaultData = array();
$entities = null;
$form = $this->createForm(SearchFlightType::class, $defaultData, array(
// again GET method for data via URL params
'method' => 'GET',
// option for price form field present
'price' => true,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// get data from form
$data = $form->getData();
// process the data and get result
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('FLYBookingsBundle:Post')->searchflight($data['from'], $data['to'], ...);
}
return $this->render('Post/searchtabflight.html.twig', array(
'form' => $form->createView(),
// present the result
'entities' => $entites,
));
}
}
I have 2 Entities: Company and User that have a link company_user ManyToMany
I would like to be able to display the list of companies linked to the connected user.
So I followed this: http://symfony.com/doc/current/form/dynamic_form_modification.html#form-events-user-data
However, in my request, I can not display the company related to the user.
Here is my CompanyRepo
<?php
namespace BudgetBundle\Repository;
use Doctrine\ORM\EntityRepository;
/**
* CompanyRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class CompanyRepository extends EntityRepository
{
public function companyByUser($user){
return $qb = $this->createQueryBuilder('cr')
->where('cr.id = :user')
->setParameter('user', $user);
}
}
My FOrmType
public function buildForm(FormBuilderInterface $builder, array $options)
{
// grab the user, do a quick sanity check that one exists
$user = $this->tokenStorage->getToken()->getUser();
if (!$user) {
throw new \LogicException(
'The FriendMessageFormType cannot be used without an authenticated user!'
);
}
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($user) {
$form = $event->getForm();
$formOptions = array(
'class' => Company::class,
'property' => 'name',
'query_builder' => function (CompanyRepository $er) use ($user) {
// build a custom query
// return $er->createQueryBuilder('u')->addOrderBy('fullName', 'DESC');
return $er->companyByUser($user);
// or call a method on your repository that returns the query builder
// the $er is an instance of your UserRepository
// return $er->createOrderByFullNameQueryBuilder();
},
);
// create the field, this is similar the $builder->add()
// field name, field type, data, options
$form->add('company', EntityType::class, $formOptions);
}
);
}
And my controller
public function addDebitAction( Request $request ) {
$em = $this->getDoctrine()->getManager();
$debit = new Debit();
$form = $this->createForm( DebitType::class, $debit );
$amountCapital = $em->getRepository('BudgetBundle:Capital')->find($this->getUser());
if ( $request->isMethod( 'POST' ) && $form->handleRequest( $request )->isValid() ) {
$em = $this->getDoctrine()->getManager();
$capital = $em->getRepository( 'BudgetBundle:Capital' )->findOneBy( [ 'user' => $this->getUser()->getId() ] );
if ($capital == false){
$this->get('session')->getFlashBag()->set('error', 'Vous devez avoir un capital de départ, merci d\'en ajouter un !');
return $this->redirectToRoute('budget_add_gain');
}
else{
$capital->setTotalDebits($capital->getTotalDebits() + $debit->getAmount());
$amountCapital->setAmount($amountCapital->getAmount() - $debit->getAmount()); // MEt a jout le capital
}
$em = $this->getDoctrine()->getManager();
$debit->setUser( $this->getUser() );
$em->persist( $debit );
$em->flush();
$request->getSession()->getFlashBag()->add( 'success', 'Debit Added !' );
return $this->redirectToRoute( 'budget_homepage' );
}
return $this->render( '#Budget/Views/company/debit.html.twig', [ 'form' => $form->createView() ] );
}
Try this:
public function companyByUser($user){
return $this->createQueryBuilder('cr')
->innerJoin('cr.users', 'u', 'WITH', 'u = :user')
->setParameter('user', $user);
}
You also need to set a choice_label on your query builder in the form type. Something like :
choice_label => 'company_name'
I don't know what your company and user entities fields are, so make sure you replace users and company_name with the correct fields names.
I currently have PayPal working fine via Payum in Symfony2 and am now trying to configure SecurePay (via Omnipay), however it does not even seem to be connecting to SecurePay and there is no documentation to support it, so I am very stuck.
In the logs there does not seem to be any external communication. In SecurePay there is no record of my payment.
Thank you very much in advance for any help,
Dan
Here's an example of the payment_order database record:
{"amount":45,"currency":"AUD","description":"Payment for #96","clientIp":"127.0.0.1","card":{},"_reference":null,"_status":"failed","_status_code":null,"_status_message":null}
Here is my configuration:
payum:
security:
token_storage:
XX\PaymentBundle\Entity\PaymentToken: { doctrine: orm }
storages:
XX\PaymentBundle\Entity\Order: { doctrine: orm }
contexts:
SecurePay_DirectPost:
omnipay:
type: 'SecurePay_DirectPost'
options:
merchantId: ABC0001
transactionPassword: abc123
testMode: true
And my capture Method:
/**
* #Route("/{id}/cardcapture", name = "card_payment_capture")
* #Template()
*/
public function captureSecurePayAction(Collection $collection) {
$paymentName = 'SecurePay_DirectPost';
$storage = $this->get('payum')->getStorage('XX\PaymentBundle\Entity\Order');
$order = $storage->createModel();
$paymentDetails['amount'] = 10;
$paymentDetails['card'] = new SensitiveValue(array(
'number' => $_POST['card-number'],
'cvv' => $_POST['cvv'],
'expiryMonth' => $_POST['exp-month'],
'expiryYear' => $_POST['exp-year'],
'firstName' => $_POST['card-name'],
'lastName' => '',
));
$order->setNumber($collection->getId());
$order->setCurrencyCode('AUD');
$order->setTotalAmount($collection->getAmount()."00");
$order->setDescription('Payment for #' . $collection->getId());
$order->setClientId($collection->getId());
$order->setClientEmail($collection->getEmail());
$storage->updateModel($order);
$captureToken = $this->get('payum.security.token_factory')->createCaptureToken(
$paymentName,
$order,
'payment_complete'
);
return $this->redirect($captureToken->getTargetUrl());
}
And finally my complete action:
/**
* #Route("/complete", name = "payment_complete")
* #Template()
*/
public function completeAction()
{
$token = $this->get('payum.security.http_request_verifier')->verify($this->request);
$payment = $this->get('payum')->getPayment($token->getPaymentName());
$payment->execute($status = new GetHumanStatus($token));
$model = $status->getModel();
$id = explode("#", $model['description']);
$collection = $this->em->getRepository('XXCollectionBundle:Collection')->find($id[1]);
if ($status->isCaptured()) {
$collection->setStatus("PAID");
$collection->setAmountPaid($model['PAYMENTREQUEST_0_AMT']);
$collection->setIsActive(true);
} else if ($status->isPending()) {
$collection->setStatus("PAYMENT PENDING");
} else {
$collection->setStatus("PAYMENT FAILED");
}
$this->em->persist($collection);
$this->em->flush();
$this->sendReceiptEmail($collection, $status);
return array(
'status' => $status,
'collection' => $collection
);
}
I have a form that will perform a search action with a drop down list of choices of category to search. The drop down list are subjects to search by. So:
Search by:
1) Invoice #
2) Tracking #
3) BL #
Then enter in the value and submit to search.
I have my form:
// src Bundle\Form\Type\SearchType.php
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('kind', 'choice', array(
'choices' => array(
'invoice' => 'Invoice #',
'trackingno' => 'Tracking Number'
'blno' => 'BL #',
),
'label' => 'Search by: '
))
->add('value', 'text', array(
'label' => false
))
->add('Submit','submit');
}
With this function in the controller:
public function getForm() {
$form = $this->createForm(new SearchType(), array(
'action' => $this->generateUrl('search_view'),
'method' => 'POST'
) );
return $form;
}
With the action going to 'search_view' function:
/**
* #param Request $request
* #Route("/results/", name="search_view")
*/
public function searchAction(Request $request) {
$kind = $request->get('kind');
$value = $request->get('value');
$em = $this->getDoctrine()->getManager();
$findCfs = $em->getRepository("CFSBundle:Cfs")
->searchCfs($kind, $value);
return $this->render("CFSBundle:Search:index.html.twig", array(
'results' => $findCfs
));
}
My problem is I do not where to go to perform the database retrieval base on the category. This is what I have in the repository:
public function searchCfs($kind, $value) {
$query = $this->getEntityManager()
->createQuery('
SELECT
c.blno, m.ctrno, c.carrier, m.refno
FROM
CFSBundle:Cfs c
LEFT JOIN
cfs.refno m
WHERE
:kind LIKE :value
')->setParameter("kind", $kind)
->setParameter("value", $value);
try {
return $query->getResult();
} catch(\Doctrine\ORM\NoResultException $e) {
return null;
}
}
Of course this isn't working. I thought about creating different queries for each category and have the conditions submit according to its category, but I was wondering if there was one simple solution to this?
I'd advise using the QueryBuilder class when writing a query such as this, rather than writing DQL directly.
You could then do something like the following in your repository:
const KIND_INVOICE_NO = 'invoice';
const KIND_TRACKING_NO = 'tracking';
const KIND_BL_NO = 'blno';
public function searchCfs($kind, $value) {
$queryBuilder = $this->createQueryBuilder('c')
->select('c.blno, m.ctrno, c.carrier, m.refno')
->leftJoin('cfs.refno', 'm');
if ($kind === self::KIND_INVOICE_NO) {
$queryBuilder->where('c.invoiceno = :queryValue');
} elseif ($kind === self::KIND_TRACKING_NO) {
$queryBuilder->where('m.ctrno = :queryValue')
} elseif ($kind === self::KIND_BL_NO) {
$queryBuilder->where('c.blno = :queryValue')
}
$queryBuilder->setParameter('queryValue', $value);
$query = $queryBuilder->getQuery();
try {
return $query->getResult();
} catch(\Doctrine\ORM\NoResultException $e) {
return null;
}
}