Paypal Express Checkout window keeps loading - javascript

I'm trying to integrate the PayPal button to execute a simple payment to a new Paypal account I just created.
Following the guide I rendered the button, but when I click on it and the new window shows up, nothing happens. The "loading lock" keeps spinning, but no errors are shown in the new window, nor in my page. No calls to "onError()" function are executed. I don't know what's wrong! I followed the instruction of the guide!
Navigating other websites I saw that in the new window, while loading (and the "loading lock" spins) some get/post are executed, nothing is executed in my case.
This is my HTML and related .js file (well, part of them)
//THIS FUNCTION IS CALLED TO DISPLAY A NEW ELEMENT CONTAINING THE BUTTON
function payment(todelete) {
destroy(todelete);
$("#pay").delay(timeFade).fadeIn(timeFade);
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'MYKEY',
production: 'MYKEY'
},
commit: true,
payment: function(data, actions) {
fetch("/getOldAmount").then(function(res){
return (res.json());
}).then(function(data){
var old_amount = data[0].Donation;
var amount_tot = $("#amount").val();
//BUILDING A RANDOM TEST JSON, NOT RELATED TO MY CODE
var payment_json = {
transactions: [
{
amount: {
total: '1.00',
currency: 'USD'
}
}
]
};
if(amount_tot > old_amount){
//WHEN CLICKING PAYPAL BUTTON I CAN SEE THIS LOG, SO EVERYTHING IS FINE HERE
console.log("EXECUTING PAYPAL POST");
return actions.payment.create(payment_json);
} else {
console.log("Amount too low to execute transaction");
}
});
},
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function(payment) {
console.log("AUTHORIZED");
});
},
onError: function(data, actions){
console.log("ERRORRRRRR");
console.log(data);
}
}, '#paypal-button');
}
<div class="container pagination-centered" style="display: block">
<div class="form-group">
<label class="richest_header" for="amount">ENTER AMOUNT</label>
<input type="text" class="form-control amount-field" id="amount" placeholder="Amount..." name="amountField">
</div>
<div id="paypal-button"></div>
</div>
<!-- HEADER -->
[...]
<script src="https://www.paypalobjects.com/api/checkout.js">
<script type="text/javascript" src="assets/script/myscript.js"></script>
[...]
Do I need to do something more?
Do I need to add code?
Am I doing something wrong?
Why is paypal documentation so poor?

You need to return the promise to payment() -- return fetch("/getOldAmount").then(...

Related

Errors: Use intent=capture to use client-side capture [Paypal Javascript SDK]

I am using the PayPal javascript SDK to create a Paypal subscription button for my web page, the problem resides when testing the button using a sandbox account in which after performing all the payment for the subscription the following error appears:
Error: Use intent=capture to use client-side capture ...
Here's my HTML script used to show my pay PayPal button
<script src="https://www.paypal.com/sdk/js?client-id=MY_CLIENT_ID&vault=true&intent=subscription&components=buttons"></script>
<div id="paypal-button-container"></div>
Heres my js file which performs the respective handlers depending on the actions and status of the payment:
paypal.Buttons({
style: {
shape: 'rect',
color: 'black',
layout: 'vertical',
label: 'subscribe'
},
createSubscription: function(data, actions) {
if (discordUser.value === "") {
alert("Introduce tu usuario de discord");
return;
}
slotDecremented = true;
alterSlots();
return actions.subscription.create({
'plan_id': 'P-ID' // here is my plan id
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
sendEmailToken(details.payer.email_address, discordUser.value, data.subscriptionID);
});
},
onCancel: function(data) {
alterSlots(true);
slotDecremented = false;
},
onError: function(data) {
if (!slotDecremented) {
return;
}
alterSlots(true);
slotDecremented = false;
}
}).render('#paypal-button-container');
the alterSlot() function makes an API call with AJAX to my specific endpoint, just extra information if neccesary
EDIT:
The sendEmailToken() function makes an AJAX request to an API hosted on my server, such that the server performs the correct action and being secure (just metadata for knowing what's going on in that part)
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
sendEmailToken(details.payer.email_address, discordUser.value, data.subscriptionID);
});
},
actions.order.capture() is for a client-side one-time payment button. It does not belong in a Subscribe button, as there is no order to capture.
See e.g. the PayPal Subscriptions documentation, which only has a basic success alert in its onApprove example: https://developer.paypal.com/docs/subscriptions/integrate/#create-the-subscription
Since it appears your intent is to perform a server-side operation such as sending an email after subscription approval, you should be activating said subscription from your server to ensure subscriptions don't become active without your server being correctly being notified of this fact. Here is some information: https://stackoverflow.com/a/65139331/2069605

Laravel Ajax 419 Error on Production but not Local Development and Nothing In /storage/logs/laravel.log

So I've run into this issue where I'm having a 419 Error code when submitting my AJAX request through my project. I know that this error is due to the CSRF Token not being passed, or not valid.
Story behind this: I've created a "maintenance mode" on my project. This maintenance mode restricts access to the front end by displaying the 503 error page, but still allows my administrators access to the backend to update the site, etc. This is done using some middleware. See the code here on my github page for more information on how I accomplish this functionality.
https://github.com/JDsWebService/ModelAWiki/commit/263a59ebba42688d4a232a5838334b9ee419504c
So maybe this is an issue with the 503 error page on my production environment? I'm not too sure.
I've taken a look at this Question and Answer on SOF, but it doesnt seem to be helping me any.
Laravel 5.5 ajax call 419 (unknown status)
Here is the production site, take a look at the console for more information: http://modelawiki.com/
Here is my code pertaining to the 419 error:
Javascript
$(document).ready(function() {
// CSRF Ajax Token
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
// Add Section Post Button
$('#subscribeButton').click(function(event) {
/* Act on the event */
// Clear Feedback Boxes
$('#valid-feedback').css("display", "none");
$('#invalid-feedback').css("display", "none");
// Input Field
var email = $('#email').val();
var token = $('meta[name="csrf-token"]').attr('content');
console.log(email);
console.log(token);
// Post
$.ajax({
type: 'POST',
url: '/email/subscribe/',
dataType: 'json',
data: {
email: email,
"_token": token,
},
success: function (data) {
// Check Server Side validation
if($.isEmptyObject(data.errors)){
// Show the Feedback Div
$('#valid-feedback').css("display", "block");
// Add the Bootsrapt Is Invalid Class
$('#email').addClass('is-valid');
// Validation Failed Display Error Message
$('#valid-feedback').text(data['success']);
// Animate the Object
$('#email').animateCss('tada', function() {});
console.log(data['success']);
}else{
// Show the Feedback Div
$('#invalid-feedback').css("display", "block");
// Add the Bootsrapt Is Invalid Class
$('#email').addClass('is-invalid');
// Validation Failed Display Error Message
$('#invalid-feedback').text(data.errors[0]);
// Animate the Object
$('#email').animateCss('shake', function() {});
console.log(data.errors);
}
},
error: function (data) {
console.log(data);
}
}); // End Ajax POST function
}); // End Click Event
// On Focus of the Email Box
$('#email').focus(function(event) {
/* Act on the event */
$('#valid-feedback').css("display", "none");
$('#invalid-feedback').css("display", "none");
});
}); // End Document Ready
HTML Form
<div class="input-group input-group-newsletter">
<input type="email" class="form-control" placeholder="Enter email..." aria-label="Enter email..." aria-describedby="basic-addon" id="email">
<div class="input-group-append">
<button class="btn btn-secondary" type="button" id="subscribeButton">Notify Me!</button>
</div>
<div id="invalid-feedback" class="invalid-feedback"></div>
<div id="valid-feedback" class="valid-feedback"></div>
</div>
Header (This shows that the CSRF token is actually on the 503 error page)
<meta name="csrf-token" content="{{ csrf_token() }}">
Again, this code works on my local environment, but not on my production environment. (I also know that AJAX requests can and are being handled in other parts of my site just fine on the production environment, so I know it's not a server issue and has to do with code)
Just in case here is my controller code as well.
// Store the Email into the database
public function subscribe(Request $request) {
// Validate the request
$validator = Validator::make($request->all(), [
'email' => 'required|email|max:255|unique:email_subscribers,email',
]);
// If the validation fails
if($validator->fails()) {
return response()->json([
'errors' => $validator->errors()->all(),
]);
}
// New Section Object
$subscription = new EmailSubscription;
// Add Name into Section Object
$subscription->email = $request->email;
// Save the Section
$subscription->save();
// Return The Request
return response()->json([
'success' => 'You have successfully subscribed! Check your email!'
]);
}
And my route
// Email Routes
Route::prefix('email')->group(function() {
// Create Post Route for subscribing
Route::post('/subscribe', 'EmailSubscriptionsController#subscribe')->name('email.subscribe');
});
Just in case it can help someone, we experienced the same issue and it was due to a server space disk issue. Therefore, Laravel was unable to write files (sessions.php notably).

Paypal Sandbox App login error

I've a problem with my sandbox app. I integrated the script given for the paypal checkout express payment in my web app. This the script :
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div id="paypal-button-container"></div>
<script>
var total = 0;
$.getJSON("/Home/getTotal", function (result) {
total = result;
});
// Render the PayPal
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
label: 'buynow',
fundingicons: true, // optional
branding: true // optional
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AT9iydEDhcqfM_dhU8MR0lvkFgZBjD1oXQVrG-CR9CyK_vd-aXpNzEnyVV7um_hAPrkqQX8JhtjGCbBt'
},
// Wait for the PayPal button to be clicked
payment: function (data, actions) {
return actions.payment.create({
transactions: [
{
amount: { total: total, currency: 'USD' }
}
]
});
},
// Wait for the payment to be authorized by the customer
onAuthorize: function (data, actions) {
return actions.payment.execute().then(function () {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
This code displays a paypal button. When I click on the button, it shows me a login page to proceed to the payement. The problem is : I can't login on this page with a paypal account that I have. I read somewhere that only the sandbox's test accounts can be used to login on this page, but I want to let everyone who has a paypal account login in this page. What should I do ? Thank you for your answers!
I've found the solution : if you want to let everybody login into your payment's page, you've to pass to production mode.

Integrate Paypal and Paypal Express with PayPal REST API

I try to integrate Paypal as a payment method.
When the User clicks on "checkout", it should be able that the user click's on 'direct to paypal' to do the express checkout. Or going the "normal" way, entering his shipping data and clicks on the last page "pay with paypal"
I follow the Paypal REST API documentation and the express checkout works fine. But I didn't get the "normal" checkout to run.
The problem isn't in the backend. So all backend operations (create payment, accept payment, etc.) running well.
But in the frontend I'm getting errors.
My Code for the Express checkout is:
<script type="text/javascript" src="https://www.paypalobjects.com/api/checkout.js?ver=4.6.1">
//....
if (jQuery('#paypal_express_btn_div').length > 0) {
paypal.Button.render({
env: 'sandbox'
payment: function(resolve, reject) {
var orderId = jQuery("#orderPostId").val();
// Set up the payment here, when the buyer clicks on the button
var CREATE_PAYMENT_URL = ajaxObject.ajaxURL;
paypal.request.post(
CREATE_PAYMENT_URL,
{
action: 'create_paypal_payment',
orderId: orderId,
}
)
.then(function(data) {
resolve(data.paymentID);
})
.catch(function(err) {
reject(err);
});
},
onAuthorize: function(data, actions) {
//After the reload, a confirm page will be shown
window.location = data.returnUrl;
},
onCancel: function(data, actions) {
return actions.redirect();
},
}, '#paypal_express_btn_div');
}
As I said, this works well.
When the user clicks the button, the method "create_paypal_payment" runs on the backend. The payment get's created and when the payment is created, the paypal window get's shown to the user.
Now he can confirm the payment by clicking "next". Then (after the page reload) a confim page is shown to the user (with all payment and shipping data) and when he clicks "confirm payment" everything is fine.
But now I try to do the payment at the end of the order. (So the user has entered his shipping data etc.)
The first steps running well. So I can create the payment in the backend.
But now I'm getting an error when I try to run the payment execute method in the "onAuthorize" Action. My method "executePayPerPayPalBasic" will not be executed. I'm getting directly an error.
My Code:
if (jQuery("#paypal_btn_div").length > 0) {
var RS_IB_PAYMENT_URL = ajaxObject.ajaxURL;
paypal.Button.render({
env: 'sandbox'
commit: true, //button "pay now" in the paypal window
payment: function(resolve, reject) {
var orderId = jQuery("orderPostId").val();
// Set up the payment here, when the buyer clicks on the button
paypal.request.post(
RS_IB_PAYMENT_URL,
{
action: 'create_paypal_payment',
orderId: orderId,
}
)
.then(function(data) {
resolve(data.paymentID);
})
.catch(function(err) {
reject(err);
});
},
onAuthorize: function(data, actions) {
// Execute the payment here, when the buyer approves the transaction
var payerID = data.payerID;
var paymentID = data.paymentID;
var paymentToken = data.paymentToken;
var returnUrl = data.returnUrl;
paypal.request.post(
RS_IB_PAYMENT_URL,
{
action: 'executePayPerPayPalBasic',
orderId: orderId,
payerID: payerID,
paymentID: paymentID,
paymentToken: paymentToken,
returnUrl: returnUrl
}
)
.then(function(data) {
var paypallink = data.data["PERMALINK"];
window.location = paypallink;
})
.catch(function(err) {
reject(err);
});
}
}, '#paypal_btn_div');
}
The error:
"Error: window.paypal<["./node_modules/post-robot/src/drivers/receive/types.js"]/exports.RECEIVE_MESSAGE_TYPES<#https://www.paypalobjects.com/api/checkout.js:3319:40
receiveMessage#https://www.paypalobjects.com/api/checkout.js:1444:13
messageListener#https://www.paypalobjects.com/api/checkout.js:1462:13
"
Another strange thing is, as I understand, normaly the "commit" parameter should handle if the paypal button is "pay now" or "next".
Because of this, I'm not set the parameter in my express checkout (because I want the "next" button) and setting the parameter to true in my normal checkout.
But since I used the commit Parameter 1 time. I always getting the "pay now" button. Even in my Express Checkout Button.
I have tried to set the parameter to false manually. But it doensn't work.
I tried this with Firefox, Google Chrome and Microsoft Edge.
The error only occurs on Firefox.
In Google Chrome and Microsoft Edge it works like a charm.
But on each of these three Browsers the Button Text has the Text "pay now" and never shows "next".
Also, all payments are marked as Paypal Express Payments. Is there any Parameter to check my second code als 'normal' payment. Or is it normal, that when I do the payment with the checkout.js all payments are marked as Express Payment?
Where is my failure? Can anybody help me?

How do I call inputs and buttons in my EmberJS acceptance tests?

This is maddening, as there is little to no help on google/the internet for this. https://guides.emberjs.com/v2.4.0/testing/acceptance/ is also not very helpful, even though it tries. I am basically learning this from scratch. I know a modest amount of HTML, handlebars, and javascript, but emphasis on the modest.
Here is my template, much of it is copied code from my architect's design who doesn't have time to help me :
<form {{action "login" on="submit"}} class="col-md-4 col-md-offset-4">
{{#if loginFailed}}
<div class="alert">Invalid username or password.</div>
{{/if}}
<div class="form-group">
<label for="inputEmail">Email address</label>
{{input value=username type="email" class="form-control" id="inputEmail1" placeholder="Email"}}
</div>
<div class="form-group">
<label for="inputPassword">Password</label>
{{input value=password type="password" class="form-control" id="inputPassword" placeholder="Password"}}
</div>
<button type="submit" class="btn btn-default" disabled={{isProcessing}}>Log in!</button>
</form>
Note the application runs correctly (I'm able to generate a login screen which connects to my local database, and I am able to log in correctly when the credentials are correct and not login when they aren't).
There is also a large .js file for the route which has an ajax call and corresponding promise from it, which I can sort of understand, but bottom line, it works :
import Ember from 'ember';
import ajax from 'ic-ajax';
export default Ember.Route.extend({
loginFailed: false,
isProcessing: false,
beforeModel: function(){
this.store.unloadAll('security-setting');
this.store.unloadAll('org');
var user = this.modelFor('application').user;
user.setProperties({email: '', auth: ''});
},
actions: {
login: function() {
this.setProperties({
loginFailed: false,
isProcessing: true
});
var _this = this;
ajax({
url: _this.modelFor('application').url + '/signin.json/',
type: 'post',
data: {session: {email: this.controller.get("username"), password: this.controller.get("password")}},
}).then(
function(result) {
// proprietary stuff, it all works
},
function(error){
alert(error.jqXHR.responseText);
this.set('isProcessing', false);
_this.set("loginFailed", true);
}
);
},
},
reset: function() {
this.set('isProcessing', false);
this.controller.set('password', '');
this.controller.set('username', '');
}
});
Here is the acceptance test I am trying to write :
import Ember from 'ember';
import { module, test } from 'qunit';
import startApp from 'ember-super-user/tests/helpers/start-app';
module('Acceptance | login', {
beforeEach: function() {
this.application = startApp();
},
afterEach: function() {
Ember.run(this.application, 'destroy');
}
});
test('visiting /login and fail a login attempt', function(assert) {
visit('/login');
fillIn('input.username', 'insert-username-here');
fillIn('input.password', 'insert-password-here');
click('button.submit');
// I know this assert is wrong but I haven't even gotten this far yet so I'm // not thinking about it; basically what happens is a popup appears and says // wrong-username-or-password-etc
andThen(function() {
assert.equal(currentURL(), '/login');
});
});
Execution dies on the fillIn lines of code. I really don't know what to do here, I've tried all combinations of 'input.username', 'input.inputEmail1', 'input.inputEmail'... I'm just not sure what I'm supposed to do, at all. I'm also pretty sure that 'button.submit' will not just magically work either. Then, I know I'll be even more lost when I try to fill in the andThen promise to acknowledge the fact that a popup appeared saying wrong-password-etc.
Please help; thanks very much for your time.
EDIT: I have been able to fix the fillIn parts of the test, but the click (probably the click, anyway, as the error messages are unclear as to which line is the problem) is producing some errors that I am unable to diagnose. Error messages appear in the output of the QUnit test suites that don't make sense to me --
TypeError: Cannot read property 'set' of undefined# 4286 ms
Expected:
true
Result:
false
Diff:
trufalse
at http://localhost:7357/assets/test-support.js:3592:13
at exports.default._emberTestingAdaptersAdapter.default.extend.exception (http://localhost:7357/assets/vendor.js:52460:7)
at onerrorDefault (http://localhost:7357/assets/vendor.js:43162:24)
at Object.exports.default.trigger (http://localhost:7357/assets/vendor.js:67346:11)
at Promise._onerror (http://localhost:7357/assets/vendor.js:68312:22)
at publishRejection (http://localhost:7357/assets/vendor.js:66619:15)
EDIT 2: The latest change for changing 'button' to 'submit' still doesn't work. Current error message :
Error: Element input[type='submit'] not found.# 166 ms
Expected:
true
Result:
false
Diff:
trufalse
Source:
at http://localhost:7357/assets/test-support.js:3592:13
at exports.default._emberTestingAdaptersAdapter.default.extend.exception (http://localhost:7357/assets/vendor.js:52460:7)
at onerrorDefault (http://localhost:7357/assets/vendor.js:43162:24)
at Object.exports.default.trigger (http://localhost:7357/assets/vendor.js:67346:11)
at Promise._onerror (http://localhost:7357/assets/vendor.js:68312:22)
at publishRejection (http://localhost:7357/assets/vendor.js:66619:15)
Your selector for each input is wrong. Since you gave each one an id, you can do this:
fillIn('#inputEmail1', 'insert-username-here');
fillIn('#inputPassword', 'insert-password-here');
Remember that you are using CSS selectors for the first argument of fillIn, IDs use # prefix and classes use ..
For the submit button, you did not add a class or ID, but if it is the only submit button on the page you can target it like this:
click('button[type="submit"]');
The fillIn and click functions takes in css selectors. so for example, clicking on the submit would look like,
click("input[type='submit']");

Categories

Resources