How to solve Laravel sslcommerze integration error? - laravel

I've done all the settings for demo payment gateway with sslcommerze, as per the below link.
https://www.youtube.com/watch?v=cdGZLO0-76E
https://github.com/sslcommerz/SSLCommerz-Laravel
But I've an error after pressing Pay Now Button. "Error in Communication"
https://prnt.sc/tx321e
The Pop up appears but does not show select bank option. Hpw can I fix this?

Create a sandbox account from:
[[https://developer.sslcommerz.com/registration/]]
You can put any dummy data for registration, except your email address.
[Note: Email address should be valid. You will receive a email verification code through your email. Put the information that you will remember].
Click here to login to the merchant panel:
[[https://sandbox.sslcommerz.com/manage/]]
Login ID: "That you have given during the registration"
Password: "That you have given during the registration"
[Note: Now you will get an email containing with STORE_ID and STORE_PASSWORD, it might take a couple of seconds]
Go to .env file from your laravel project:
Add those following lines at the end of the file:
STORE_ID = That you received from the mail
STORE_PASSWORD = That you received from the mail
Set your database name, username, and password at the same time.
Download the SslCommerz zip file or clone in any folder:
[[https://github.com/sslcommerz/SSLCommerz-Laravel]]
The file folder structure look like this,
|-- config/
|-- sslcommerz.php
|-- app/Library/SslCommerz
|-- AbstractSslCommerz.php (core file)
|-- SslCommerzInterface.php (core file)
|-- SslCommerzNotification.php (core file)
|-- README.md
|-- orders.sql (sample)
Now follow the steps to integrate payment gateway to integrate to your paypal project:
Step 1: Extract the file
Step 2: Copy the Library folder and put it in the laravel project's app/ directory. If needed, then run composer dump - o.
Step 3: Copy the config/sslcommerz.php file into your laravel project's config/ folder.
Step 4: Copy the SslCommerzPaymentController into your laravel project's Controllers folder
Step 5: Copy the defined routes from routes/web.php into your laravel project's route file.
Step 6: Add the below routes into the $excepts array of VerifyCsrfToken middleware.
protected $except = [
'/pay-via-ajax', '/success','/cancel','/fail','/ipn'
];
Step 7: Copy all the view files under the resource folder and paste into your laravel project's resources/views/ folder.
Step 8: To integrate popup checkout, use the below script before the end of body tag. Add it in any blade template that you want add your button.
For Example: welcome.blade.php-> paste the code below, before ending of the body tag.
For Sandbox:
<script>
(function (window, document) {
var loader = function () {
var script = document.createElement("script"), tag = document.getElementsByTagName("script")[0];
script.src = "https://sandbox.sslcommerz.com/embed.min.js?" + Math.random().toString(36).substring(7);
tag.parentNode.insertBefore(script, tag);
};
window.addEventListener ? window.addEventListener("load", loader, false) : window.attachEvent("onload", loader);
})(window, document);
</script>
For Live:
<script>
(function (window, document) {
var loader = function () {
var script = document.createElement("script"), tag = document.getElementsByTagName("script")[0];
script.src = "https://seamless-epay.sslcommerz.com/embed.min.js?" + Math.random().toString(36).substring(7);
tag.parentNode.insertBefore(script, tag);
};
window.addEventListener ? window.addEventListener("load", loader, false) : window.attachEvent("onload", loader);
})(window, document);
</script>
Step 9: Use the below button where you want to show the "Pay Now" button:
Should be in the same place where step 8 was implemented.
Pay Now
There is a orders.sql file in the SslCommerz folder. You can import it directrly from the phpmyadmin. Or you make a migration and model manually. And create new table according to the oraders.sql file columns.
You're done!
Some problem you might face.
Possible solution:-
-> Check DB class in the SslCommerzPaymentController and change, use DB into Illuminate\Support\Facades\DB;
-> Import SslCommerzPaymentController from the web.php.
-> Migrate the table.
-> Add this line of code to the payViaAjax method in the SslCommerzPaymentController, if you want to retrieve data dynamically from the form
public function payViaAjax(Request $request, $id)
{
<<$requestData = (array)json_decode($request->cart_json);>>

Copy and put 4 key-value pairs to your .env file from below.
SSLCZ_STORE_ID=<your store id>
SSLCZ_STORE_PASSWORD=<your store password>
SSLCZ_TESTMODE=true
IS_LOCALHOST=true

Related

How to display PDF Documents on the browser using a View in Laravel 5.8

I'm working on a web application using Laravel 5.8, I'm new to Laravel framework. I would like to display PDF documents on the browser when users click on some buttons. I will allow authenticated users to "View" and "Download" the PDF documents.
I have created a Controller and a Route to allow displaying of the documents. I'm however stuck because I have a lot of documents and I don't know how to use a Laravel VIEW to display and download each document individually.
/* PDFController*/
public function view($id)
{
$file = storage_path('app/pdfs/') . $id . '.pdf';
if (file_exists($file)) {
$headers = [
'Content-Type' => 'application/pdf'
];
return response()->download($file, 'Test File', $headers, 'inline');
} else {
abort(404, 'File not found!');
}
}
}
/The Route/
Route::get('/preview-pdf/{id}', 'PDFController#view');
Mateus' answer does a good job describing how to setup your controller function to return the PDF file. I would do something like this in your /routes/web.php file:
Route::get('/show-pdf/{id}', function($id) {
$file = YourFileModel::find($id);
return response()->file(storage_path($file->path));
})->name('show-pdf');
The other part of your question is how to embed the PDF in your *.blade.php view template. For this, I recommend using PDFObject. This is a dead simple PDF viewer JavaScript package that makes embedding PDFs easy.
If you are using npm, you can run npm install pdfobject -S to install this package. Otherwise, you can serve it from a CDN, or host the script yourself. After including the script, you set it up like this:
HTML:
<div id="pdf-viewer"></div>
JS:
<script>
PDFObject.embed("{{ route('show-pdf', ['id' => 1]) }}", "#pdf-viewer");
</script>
And that's it — super simple! And, in my opinion, it provides a nicer UX for your users than navigating to a page that shows the PDF all by itself. I hope you find this helpful!
UPDATE:
After reading your comments on the other answer, I thought you might find this example particularly useful for what you are trying to do.
According to laravel docs:
The file method may be used to display a file, such as an image or PDF, directly in the user's browser instead of initiating a download.
All you need to do is pass the file path to the method:
return response()->file($pathToFile);
If you need custom headers:
return response()->file($pathToFile, $headers);
Route::get('/show-pdf/{id}', function($id) {
$file = YourFileModel::find($id);
return response()->file(storage_path($file->path));
})->name('show-pdf');
Or if file is in public folder
Route::get('/show-pdf', function($id='') {
return response()->file(public_path().'pathtofile.pdf');
})->name('show-pdf');
then show in page using
<embed src="{{ route('show-pdf') }}" type="text/pdf" >

Download database file attachments by their real names

I can't figure out how to get a database file attachment, to be downloaded with is real file name.
My model have many file attachements (many attachOne) and there is no problem to get link to them with
{{ model.myfile.filename }}
What I want to do is to get those files downloaded with their real file name.
I try to define an ajax event handler in my layout like so :
function onDonwload()
{
$path = post('path');
$name = post('name');
// Storage::exists('uploads/public/5ce/28c/3aa/5ce27c3aae590316657518.pdf'); => OK
// Storage::exists($path); =>OK
$path = storage_path().'/app/'. $path;
return Response::download( $path, $name);
}
and
<button data-request="onDonwload"
data-request-data="path: 'uploads/public/5ce/28c/3aa/5ce27c3aae590316657518.pdf', name: 'my real name">
Download
</button>
No missing file error, but get the browser to freeze with an alert that say "A webpage slow down your browser, what do you want to do?".
Did I miss an important point?
You should add separate page for downloading files, Ajax can not help you to download file ( may be it can but process is little complex and long)
create page with /file-download/:id here you can specify any url wit param :id and give it name file-download you can give any name you like for demo i used this name.
In that Page Html section will be Blank and in Page's code section add this code. here you can also check additional security check like user is logged in or not file is of related user or not. for now i am just checking file is related to particular Modal or not.
function onStart() {
$fileId = $this->param('id');
$file = \System\Models\File::find($fileId);
// for security please check attachment_type == your model with namespace
// only then lat use download file other wise user can download all the files by just passing id
if($file && $file->attachment_type == 'Backend\Models\User') { // here add your relation model name space for comparison
$file->output('attachment');
}
else {
echo "Unauthorised.";
}
exit();
}
Generating links, please replace page name with page you created.
<a href="{{ 'file-download'|page({'id': model.myfile.id}) }}" >{{ model.myfile.filename }}</a>
Now, when you click on link file should be downloaded with its original name, and for invalid file id it should show message Unauthorised..
if any doubts please comment.

Redirect from method in Vue.js with Vue-router older than version 1.x.x

I'm not much of a frontend developer but I know enough javascript to do the minimum.
I'm trying to plug into a last piece of login however my vue components are:
"vue-resource": "^0.9.3",
"vue-router": "^0.7.13"
I'm not experienced enough to move up to v1 or v2 respectively.
I would like to achieve something similar to this.
However I'm not getting a successful redirect.
my app.js file:
var router = new VueRouter();
...
import Auth from './services/auth.js';
router.beforeEach(transition => {
if(transition.to.auth &&!Auth.authenticated)
{
transition.redirect('/login');
}
else
{
transition.next();
}
});
```
In my login.js file
```
methods: {
/**
* Login the user
*/
login(e) {
e.preventDefault();
this.form.startProcessing();
var vm = this;
this.$http.post('/api/authenticate',
{ email : this.form.email,
password : this.form.password
})
.then(function(response){
vm.form.finishProcessing();
localStorage.setItem('token', response.data.token);
vm.$dispatch('authenticateUser');
},
function(response) {
if(response.status == 401)
{
let error = {'password': ['Email/Password do not match']};
vm.form.setErrors(error);
}else{
vm.form.setErrors(response.data);
}
});
}
}
I tried to do as suggested:
vm.form.finishProcessing();
localStorage.setItem('token', response.data.token);
vm.$dispatch('authenticateUser');
vm.$route.router.go('/dashboard');
However all it did was append the url on top.
I see that the 3 previous events were successfully done but not the redirect.
it went from:
http://dev.homestead.app:8000/login#!/
to
http://dev.homestead.app:8000/login#!/dashboard
when I need the entire page to go to:
http://dev.homestead.app:8000/login/dashboard#1/
I think i have a missing concept in order to do the redirect correctly.
UPDATE
As per suggested i have added param: append => false but nothing happens.
what i did afterward was within app.js create a method called redirectLogin() with console.log() outputs - that worked. what i did further is i put vm.$route.router.go inside there and called the method via vm.$dispatch('redirectLogin'); and that also didn't work.
NOTE:
The HTML is being rendered in Laravel first. the route I originally had (and working) as login/dashboard and that route is available via normal Laravel route. the blade is being rendered via view template.
So far I've been trying to vue redirect over to login/dashboard (not working) perhaps I should somehow remove login/dashboard and use the route.map and assign login/dashboard?
I would rather keep the login/dashboard as a laravel route due to authentication and other manipulation.
For Vue 2
this.$router.push('/path')
As par the documentation, router.go appends the path in the current route, however in your case it is appending along with # in the router as well.
You can use param: append, to directly arrive at your desired destination, like following:
vm.$route.router.go({name: '/login/dashboard#1/', params: {append: false}})
Edited
If it is not happening, you can try $window.location method like following:
var url = "http://" + $window.location.host + "login/dashboard";
console..log(url);
$window.location.href = url;
I think their is a misunderstanding here of how vue-router works. It seems you are not wanting to load a new route with a corresponding component, rather you simply want to redirect to a new page then let that page load and in turn fire up a fresh instance of vue.
If the above is correct you don't need vue-router at all. Simply add the below when you need to load the page:
window.location.href = '/login/dashboard'
If you'd rather simulate a redirect to that page (no back button history) then:
window.location.replace('/login/dashboard')
EDIT
The above would be fired when you have finished all processing that the page must run to set the users state which the next page requires. This way the next page can grab it and should be able to tell the correct state of the user (logged in).
Therefore you'll want to fire the redirect when the Promise has resolved:
.then(function(response){
vm.form.finishProcessing()
// store the Auth token
localStorage.setItem('token', response.data.token)
// not sure whether this is required as this page, and in turn this instance of vue, is about to be redirected
vm.$dispatch('authenticateUser')
// redirect the user to their dashboard where I assume you'd run this.$dispatch('authenticateUser') again to get their state
window.location.replace('/login/dashboard')

Why creating a route with angular-fullstack creates a component?

Im using angular-fullstack newest version I think "generatorVersion": "3.7.5", and right now I created a route
yo angular-fullstack:controller products and it created the files:
products.controller.js
products.controller.spec.js
products.js
products.scss
and when I tried
yo angular-fullstack:controller product_new_view
inside the folder /client/app/products it created a new folder
/client/app/products/product_new_view
which I think is ok but the question is why the controller definition is not inside a component as in /client/app/products/products.controller.js
angular.module('meanshopApp')
.component('products', {
templateUrl: 'app/products/templates/products.html',
controller: ProductsComponent
})
})();
instead is just
angular.module('meanshopApp')
.controller('ProductNewViewCtrl', function ($scope) {
$scope.message = 'Hello';
});
does that mean that for every new view I need to create a route? cause I read https://docs.angularjs.org/guide/component and there it says
Components as route templates
Components are also useful as route templates (e.g. when using ngRoute). In a component-based application, every view is a component:
Im new to angular by the way

How to create download link in Laravel

I am having problem creating a download link to download files via a Mobile App from Laravel Storage folder.
I did something like $link = Response::Download(storage_path()./file/example.png) but to no avail.
I moved the file to the public folder and used http://domain.com/file/example.png and asset('file/example.png') but to no avail.
I am getting 404 NOT FOUND ERROR
How do I solve this?
Take a look at the Laravel Helpers documentation: http://laravel.com/docs/4.2/helpers
If you want a link to your asset, you can do it like this:
$download_link = link_to_asset('file/example.png');
Edit
If the above method does not work for you, then you can implement a fairly simple Download route in app/routes.php which looks like this:
Note this example assumes your files are located in app/storage/file/ location
// Download Route
Route::get('download/{filename}', function($filename)
{
// Check if file exists in app/storage/file folder
$file_path = storage_path() .'/file/'. $filename;
if (file_exists($file_path))
{
// Send Download
return Response::download($file_path, $filename, [
'Content-Length: '. filesize($file_path)
]);
}
else
{
// Error
exit('Requested file does not exist on our server!');
}
})
->where('filename', '[A-Za-z0-9\-\_\.]+');
Usage: http://your-domain.com/download/example.png
This will look for a file in: app/storage/file/example.png (if it exists, send the file to browser/client, else it will show error message).
P.S. '[A-Za-z0-9\-\_\.]+ this regular expression ensures user can only request files with name containing A-Z or a-z (letters), 0-9 (numbers), - or _ or . (symbols). Everything else is discarded/ignored. This is a safety / security measure....
Updating answer for Laravel 5.0 and above:
<a href={{ asset('file/thing.png') }}>Thing</a>
You do not need any route or controller.Just give it to anchor tag.
<a href="{{URL::to('/')}}/file/example.png" target="_blank">
<button class="btn"><i class="fa fa-download"></i> Download File</button>
</a>

Resources