In my website I’m using Stripe but for some reasons decided to change to Heartland Payment methods.
As I’m using laravel, so my knowledge is about controllers and models, I tried to understand how to do this with heartland but didn’t get it. For showing the input field it is working fine with me so now I want to make the payment by click submit button but I don’t know how to send these input information to controller to complete the payment.
Please I need good example showing process in the controller.
I tried to get the controller content from this link but didn't find clear one: https://developer.heartlandpaymentsystems.com/Ecommerce/Card
Thank you in advance
Here the code:
route:
Route::get('/Payment/Charge', 'PaymentController#heartlandPost')->name('heartlandpost');
Payment form and jquery code:
<form id="payment-form" action="/Payment/Charge" method="get">
<div id="credit-card"></div>
</form>
<script src="https://api2.heartlandportico.com/SecureSubmit.v1/token/gp-1.0.1/globalpayments.js"> </script>
<script type="text/javascript">
GlobalPayments.configure({
publicApiKey: "pkapi_cert_*****"
});
// Create Form
const cardForm = GlobalPayments.creditCard.form("#credit-card");
cardForm.on("token-success", (resp) => {
// add payment token to form as a hidden input
const token = document.createElement("input");
token.type = "hidden";
token.name = "payment_token";
token.value = resp.paymentReference;
// Submit data to the integration's backend for processing
const form = document.getElementById("payment-form");
form.appendChild(token);
form.submit();
});
cardForm.on("token-error", (resp) => {
// show error to the consumer
});
</script>
Controller:
public function heartlandPost()
{
}
So from reading the documentation, it looks like you need to do:
<?php
use GlobalPayments\Api\ServicesConfig;
use GlobalPayments\Api\ServicesContainer;
use GlobalPayments\Api\Entities\Address;
use GlobalPayments\Api\PaymentMethods\CreditCardData;
use GlobalPayments\Api\Entities\Exceptions\ApiException;
public function heartlandPost()
{
$config = new ServicesConfig();
$config->secretApiKey = "skapi_cert_***";
$config->developerId = "000000";
$config->versionNumber = "0000";
$config->serviceUrl = "https://cert.api2.heartlandportico.com";
ServicesContainer::configure($config);
$card = new CreditCardData();
$card->token = $request->input('payment_token');
$address = new Address();
$address->postalCode = $request->input('postal_code');
try {
$response = $card->charge(10)
->withCurrency("USD")
->withAddress($address)
->execute();
} catch (ApiException $e) {
// handle error
}
// return your response to the client
}
where you need to update the config to match your own keys and whatnot, and I''m not sure how you are passing the amount / postal code to your backend so make sure you do that as well.
Related
I am trying to redirect to a page on my external page, what I have tried till now is. Manually I added some files.
In /custom/modules/Users/logic_hooks.php
<?php
$hook_version = 1;
$hook_array = Array();
$hook_array['after_logout'] = Array();
$hook_array['after_logout'][] = Array(
//Processing index. For sorting the array.
1,
//Label. A string value to identify the hook.
'after_logout example',
//The PHP file where your class is located.
'custom/modules/Users/logic_hooks_class.php',
//The class the method is in.
'logic_hooks_class',
//The method to call.
'after_logout_method'
);
?>
And another file in In /custom/modules/Users/logic_hooks_class.php
<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class logic_hooks_class
{
function after_logout_method($bean, $event, $arguments)
{
header('Location: http://raviranjan.info/');
}
function AfterLogout(&$bean, $event, $arguments)
{
SugarApplication::redirect('http://raviranjan.info/');
}
}
?>
So is there any other way to redirecting or just show something on screen before or after logging out from SugarCRM application.
Advance Thanks for any help.
There are multiple ways of doing this. Read following details:
show alert of any other type of message by handling click event of logout link. e.g. when user click that link then show alert of any other type of message.
after logout redirect user to your custom page( you can build custom entry point which will be accessible with auth=>false).
you can add any button or java-script to show message then redirect it to your target page.
Simple jquery selector, see following:
$("a.utilsLink").click(function(){
var r = confirm("Are you sure to logout?");
if (r == true) {
console.log("yes is clicked");
} else {
console.log("cancel is clicked...");
return false;
}
});
I'm new in PHP MVC, I have a question about how javascript works with php mvc
If I have a page with a button, when user click the button
It will send to next page and update data in database
$(document).ready(function(){
$("#btn").click(function(){
$.load(){... }
or $.post(){.....}//post data to another page
});
});
//next page
if(isset($_POST[])){
//update data
}
My question is
Should I send this data to controller than pass to model and output in view(if we need respond something)
Button --javascript--> controller -> model(update data) --send data back--> view
or
I can just send data to page and update without mvc
Sorry, i can't just comment your question yet
Your first approach is correct. Is recommended that you update data in models. Meanwhile, all SQL statements or ORM handles should be on it.
In your case, you have two options to show the data in view: Return a JSON in your php handle it with javascript, and load your view directly after update data. It depends how all your project is builded.
I can write some exemples, but you will need to give some peace of code.
// In your controller
if(isset($_POST)){
$obj = new MyObject();
$obj->name = $_POST['name'];
$obj->date = date("Y-m-d");
$obj->validatePost();
$obj->update();
$result = $obj->getData();
return $result;
}
// Your model
class MyObject {
public $name;
public $date;
public function validatePost(){
if($this->name == null){
// print error
}
}
public function update(){
// database cheets
}
public function getData(){
return $json;
}
}
This has to do with routing. So for getting parameters via url, you basically pass the data to the url following the route format you set.
This is working with links. I created the route, passed the data into the url, and used the request method to get the parameter for use in the controller. like URL::site("site/$color/$size")
What if I am constructing the url by form submission? For example, if I want to create a basic search query.
How do I get my form submission to look like this search/orange/large and not like this search.php?color=orange&size=large when I submit a form via get method.
By definition, the GET method puts the submitted information as URL parameters. If you specifically want to end up with a URL like site/$color/$size, you can use the POST-REDIRECT-GET pattern.
A partial example, from a controller on one of my sites (there is a submit button on the page named clear_cache_button):
public function action_index()
{
$session = Session::instance();
$is_post = (Request::current()->post('submit_button') !== NULL);
$is_clear_cache = (Request::current()->post('clear_cache_button') !== NULL);
$p = Database::instance()->table_prefix();
$people = DB::query(Database::SELECT, "
SELECT *
FROM `".$p."Tabe`;
")->cached(600, $is_clear_cache)->execute()->as_array('RegID');
if ($is_clear_cache)
{
HTTP::redirect(Request::current()->uri());
}
...
...
...
}
You can use Route filters (v3.3) or callbacks (3.1, 3.2) and set route params manually.
You can do it this way...
public function action_index()
{
// this will only be executed if you submmitted a form in your page
if(Arr::get($_POST,'search')){
$errors = '';
$data = Arr::extract($_POST,array('color','size'));
// you can now access data through the $data array:
// $data['color'], $data['size']
// perform validations here
if($data['color']=='') $error = 'Color is required';
elseif($data['size']=='') $error = 'Size is required';
if($error==''){
$this->request->redirect('search/'.$data['color'].'/'.$data['size']);
}
}
// load your search page view here
echo 'this is the search page';
}
Hope this helps you out.
I'm using Cake 2.1, and with it comes the new JsonView. What I'd like to do is POST to a method in my controller and render an html fragment so that I can return it as a value in json.
Previously I'd do something like this:
public function ajaxSubmit() {
if (!$this->request->is('ajax')) {
$this->redirect('/');
} else {
$this->autoRender = $this->layout = false;
$message = 'Please enter a message';
$this->set('message');
$errorFragment = $this->render('/Elements/errors/flash_error');
$toReturn = array('errorFragment' => $errorFragment);
return json_encode($toReturn);
}
}
Which only sends back the html fragment of that particular flash_error element such that I can't have multiple key => values being sent back in a standard json object. I want to be able to send both html fragments and just plain text as json.
So my question really is, how can I render an HTML element and set it with a (key=>value pair) to be sent back as json from my controller using the JsonView that Cake 2.1 provides? I already have set in my routes file Router::parseExtensions('json'); and I'm including the RequestHandler component inside of my AppController.
You shouldn't need a separate action for AJAX when using data views. Use can use the same action as your non AJAX submit.
However assuming that you wish to use a different action for AJAX because I don't know what your other action looks like, you can write something like this in app/View/ControllerName/json/ajaxSubmit.ctp.
<?php
$errorFragment = $this->element('errors/flash_error');
$toReturn = array('errorFragment' => $errorFragment);
echo json_encode($toReturn);
Then change your action to this
public function ajaxSubmit() {
if (!$this->request->is('ajax')) {
$this->redirect('/');
} else {
$message = 'Please enter a message';
$this->set('message');
}
}
See "Using a data view with view files" in the documentation.
I've been having problems created modular reusable components in my Zend Framework app. In this case I'm not referring to Zend Framework modules but rather the ability to have a reusable MVC widgety thing if you like. The problems I'm having may be very particular to my implementation, but I'm completely happy to throw it out and start again if someone can point me in the right direction. Anyway, specifics and code will hopefully explain things better and even if what I'm doing is not the best way it should show what I'm trying to achieve:
A simple example is a Mailing List sign up form. I want to include this on several pages of the site which use different Controllers and this presents a few problems in how to process the data and return relevant messages. I don't want to do either of the following as they really smell:
Create a base controller with the form processing in and extend (Bad)
Duplicate form processing code in relevant controllers (Even worse!)
The clean way to go feels to me to create a new Controller to process the mailing list form data, use a View Helper to easily output the form and relevant markup into the desired pages and then redirect back to the page where signup occurred once the form has been processed. However, I'd like to use the form validation provided by Zend_Form, which means I'd need to pass the form object back to the view helper somehow if validation fails but in the same request. I'm currently doing this by setting it as a variable on the view and then forwarding back to the previous page rather than redirecting, which is ok(ish). If validation is ok then I'd prefer to use a redirect back to the original page. I'm having trouble doing this though as I'd like to pass messages back to the component about the state of signup. Normally I'd use the FlashMessenger Action Helper, I could namespace it in this case so messages didn't clash with other page data, but I can't access it from within a View Helper. So currently I'm forwarding in this case too. I'd much prefer a redirect to prevent form resubmissions if a user refreshes the page and to keep the URL clean. I realise I essentially want to have a mini MVC dispatch process within a page and I think that's what the action stack is for? I really don't know much about this though and any pointers would be greatly appreciated. Here's my current code:
Controller:
<?php
class MailingListController extends Zend_Controller_Action {
public function insertAction() {
$request = $this->getRequest();
$returnTo = $request->getParam('return_to');
if(!$request->isPost() || (!isset($returnTo) || empty($returnTo))) {
$this->_redirect('/');
}
$mailingList = new Model_MailingList();
$form = new Form_MailingList();
$returnTo = explode('/', $returnTo);
if($form->isValid($_POST)) {
$emailAddress = $form->getValue('email_address');
$mailingList->addEmailAddress($emailAddress);
$this->view->mailingListMessages = $mailingList->getMessages();
$this->view->mailingListForm = "";
}
else {
$this->view->mailingListForm = $form;
}
$this->_forward($returnTo[2], $returnTo[1], $returnTo[0]);
}
}
return_to is a string containing the current URI (module/controller/action), which is generated in the View Helper. I'd prefer to redirect inside the $form->isValid($_POST) block.
View Helper:
<?php
class Zend_View_Helper_MailingList extends Zend_View_Helper_Abstract {
public function mailingList($form, $messages = "") {
if(!isset($form)) {
$request = Zend_Controller_Front::getInstance()->getRequest();
$currentPage = $request->getModuleName() . '/' . $request->getControllerName() . '/' . $request->getActionName();
$form = new Form_MailingList();
$form->setAction('/mailing-list/insert');
$form->setCurrentPage($currentPage);
}
$html = '<div class="mailingList"><h2>Join Our Mailing List</h2>' . $form;
$html .= $messages;
$html .= '</div>';
return $html;
}
}
Getting an instance of the Front Controller in the View Helper isn't ideal but I'd prefer to encapsulate as much as possible.
If I have a form object where validation has failed I can pass it back into the helper to output with error messages. If I have some messages to render I can also pass them into the helper.
In my view scripts I'm using the helper like so:
<?=$this->mailingList($this->mailingListForm, $this->mailingListMessages);?>
If neither mailingListForm or mailingListMessages has been set on the view by MailingListController, it will output a new form with no messages.
Any help is greatly appreciated!
Using ajax seems to be an optimal way. View Action Helper is used only for the first load of the mailing form.
Controller
class MailingListController extends Zend_Controller_Action {
public function insertAction() {
$request = $this->getRequest();
$form = new Form_MailingList();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$mailingList = new Model_MailingList();
$emailAddress = $form->getValue('email_address');
$mailingList->addEmailAddress($emailAddress);
$form = $mailingList->getMessages();
}
}
$this->view->form = $form;
}
}
view script insert.phtml
<?php echo $this->form; ?>
Form class
class Form_MailingList extends Zend_Form {
public function init() {
//among other things
$this->setAttrib('id', 'mailing-list-form');
$this->setAction('/mailing-list/insert');
}
}
View Helper
class Zend_View_Helper_MailingList extends Zend_View_Helper_Abstract {
public function mailingList() {
$this->view->headScript()->appendFile('/js/mailing-list.js');
return '<div id="mailing-list-wrap">' . $this->view->action('insert', 'mailing-list') . '</div>';
}
}
JS file mailing-list.js
$(document).ready(function() {
$('#mailing-list-form').submit(function() {
var formAction = $(this).attr('action');
var formData = $(this).serialize();
$.post(formAction, formData, function(data) {
//response going in form's parent container
$(this).parent().html(data);
});
return false;
});
});
I think the way you've done it is pretty close to what I would do. If you set aside the requirement of wanting to display the Zend_Form error messages in the page, then what you do instead is:
The view helper just displays the form (it doesn't need to take the form object or messages as parameters)
The form submits to your other controller as it does now
The mailing list controller redirects (instead of forwarding) back to the return URL on success
The mailing list controller redisplays the form on its own, along with errors on failure
This makes everything much simpler, the only issue is that if there are any validation errors then the user loses their context and gets a plain old page with the form on instead of where they were. You can then address this (either now or at a later date) by changing the form to submit via. Ajax instead, and rendering the errors via. JS. But this would be a fair amount of work.
OK, I've come up with a solution that I feel happier about and solves some of the problems I was facing. Hopefully, this might help someone out who's facing similar issues. The only downside now is that I'm referencing the Model inside the View Helper. Not loose coupling I know but I've seen this done several times before and it's even recommended in the ZF docs as a way to avoid using the 'action' view helper (which will create a new MVC dispatch loop). On the whole, I think the DRYness and encapsulation is worth it, there's probably some other suitable lingo too.
In order to be able to use a redirect back from my MailingListController but maintain the messages from my model and any form validation errors I need to store them in the session. For messages I'd normally use the FlashMessenger action helper, but as getting hold of this in a View Helper is not best practice, it won't handle my form errors and all it's really doing is saving stuff to the session anyway it's unnecessary. I can implement my own session storage in the Model_MailingList, which I can also use for the form errors. I can then repopulate the form with the errors after the redirect and print out any relevant messages. Anyway, here's the code:
Controller:
<?php
class MailingListController extends Zend_Controller_Action {
public function insertAction() {
$request = $this->getRequest();
$returnTo = $request->getParam('return_to');
if(!$request->isPost() || (!isset($returnTo) || empty($returnTo))) {
$this->_redirect('/');
}
$mailingList = new Model_MailingList();
$form = new Form_MailingList();
if($form->isValid($_POST)) {
$emailAddress = $form->getValue('email_address');
$mailingList->addEmailAddress($emailAddress);
}
else {
$mailingList->setFormErrors($form->getMessages());
}
$redirect = rtrim($request->getBaseUrl(), '/') . $returnTo;
$this->_redirect($redirect);
}
}
I've added a method to my Model_MailingList class; setFormErrors($errors) that I pass the error messages from the form if it fails validation. This saves the error array to the session.
I normally use a base model class that has addMessage and getMessages methods. These just access a protected array of messages. In my Model_MailingList I override these methods to store the messages in the session instead. In the addEmailAddress($emailAddress) method I'm already calling addMessage to say whether inserting the email address to the db has been successful.
Model:
<?php
class Model_MailingList extends Thinkjam_Model_DbAbstract {
private $_session;
public function __construct() {
$this->_session = new Zend_Session_Namespace(__CLASS__);
}
public function setFormErrors($errors) {
$this->_session->formErrors = $errors;
}
public function getFormErrors() {
$errors = array();
if(isset($this->_session->formErrors)) {
$errors = $this->_session->formErrors;
unset($this->_session->formErrors);
}
return $errors;
}
// override addMessage and getMessages
protected function addMessage($message) {
if(!isset($this->_session->messages)) {
$this->_session->messages = array();
}
$this->_session->messages[] = $message;
}
public function getMessages() {
if(isset($this->_session->messages)) {
$this->_messages = $this->_session->messages;
unset($this->_session->messages);
}
return $this->_messages;
}
…
public function addEmailAddress($emailAddress) {
...
// I call this if db insert was successful:
$this->addMessage("Thank you. You have been successfully added to the mailing list.")
}
}
I now don't need to pass any params to the view helper as it can query it's state from the Model directly. $this->view->messenger is just another view helper that converts an array to an unordered list.
View Helper:
<?php
class Zend_View_Helper_MailingList extends Zend_View_Helper_Abstract {
private $_mailingList;
public function MailingList() {
$this->_mailingList = new Model_MailingList();
return $this;
}
public function getForm() {
$request = Zend_Controller_Front::getInstance()->getRequest();
$currentPage = '/' . $request->getModuleName() . '/' . $request->getControllerName() . '/' . $request->getActionName();
$form = new Form_MailingList();
$form->setAction('/mailing-list/insert');
$form->setCurrentPage($currentPage);
$form->setErrors($this->_mailingList->getFormErrors());
$html = '<div class="mailingList"><h2>Join Our Mailing List</h2>' . $form;
$html .= $this->view->messenger($this->_mailingList->getMessages());
$html .= '</div>';
return $html;
}
}
Then in the Form_MailingList class I just need to add an additional method to repopulate the error messages. Although getMessages() is a method of Zend_Form there doesn't appear to be any corresponding setMessages(). You can do this on a Zend_Form_Element however, so I've added the following function to the Form_MailingList class:
Form:
<?php
class Form_MailingList extends Thinkjam_Form_Abstract {
...
public function setErrors(array $errors) {
foreach($errors as $key => $value) {
$this->getElement($key)->setErrors($value);
}
}
}
I can now add a signup form on any page of my site using the MailingList view helper:
<?=$this->MailingList()->getForm();?>
I realise a lot of the problems I was facing was down to a very specific set of circumstances, but hopefully this can help some other people out in some way!
Cheers,
Alex