PayPal Smart Buttons Server Side Integration is failing on live mode - javascript

I am working on an application in php where I have to integrate PayPal Smart Buttons to my application. Everything is working fine in sandbox mode. But when I turn it to Live or Production Environment. It gives JSON error.
PayPal Smart Buttons returns me JSON error
This answer helped me alot while setting up my environment for sandbox and everything else, this is working really fine. but only for sandbox mode!
I checked with account on paypal, the transactions are created there, but no response is being sent to server for further processing. It indicates the API is setup successfully and keys are good. But only issue is I m unable to capture response and send it back to server here is my code
create-paypal-transaction.php
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = self::buildRequestBody();
// 3. Call PayPal to set up a transaction
$client = PayPalClient::client();
$response = $client->execute($request);
// 4. Return a successful response to the client.
$json_obj= array('id'=>$response->result->id);
$jsonstring = json_encode($json_obj);
echo $jsonstring;
}
on client side
createOrder: function() {
return fetch('payments/create-paypal-transaction.php', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify($('#form_add').serializeObject())
}).then(function(res) {
console.log(res);
return res.json();
}).then(function(data) {
console.log(data);
return data.id;
});
I used console.log() for debugging server response but it is always
{
...
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
...
}
also the console shows below errors
create_order_error
click_initiate_payment_reject
Uncaught SyntaxError: Unexpected token < in JSON at position 0
ANY HELP WOULD BE APPRECIATED :)

Im getting the same issue, i've read that you need to redirect them to the approval url like such
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = self::buildRequestBody();
// 3. Call PayPal to set up a transaction
$client = PayPalClient::client();
$response = $client->execute($request);
$res_links = $response->result->links;
$approve_index = array_search('approve',array_column($res_links,'rel'));
redirect($res_links[$approve_index]->href);
// 4. Return a successful response to the client.
$json_obj= array('id'=>$response->result->id);
$jsonstring = json_encode($json_obj);
echo $jsonstring;
}
This ends up giving a cors error and when bypassing the cors checking in chrome(which is terrible) it simply closes the checkout popup and the response for the approval url is the html for the page.
In the network tab in your dev console, check the response for the create-paypal-transaction.php file. It'l give you the actual error the json > error is unrelated. You can also visit the file directly from your browser and see what errors you get there.
You can message me on discord if youd like im also working on getting this working. REDRUM#9269

Related

Axios POST request sends data to Express server but Error 404

Axios POST request sends data to Express sever but Error 404
Hello, world, I am trying to build a user authentication server for a project I am working on, but I am running into a problem trying to send a POST request to my Node.js Express server.
I want to send a POST request using Axios containing a username and password from the browser. But once sending the request it gives me a 404 Not Found error. The request has to go to http://website/api/login and my Node.js code should return either "authed" or "invalid". I tested the API inside Postman and that seems to be working. I also exported the request code from Postman and tested it with fetch API, xhr, and Axios, all returning the same result.
The server receives the data and handles it properly, but when I look in the Chromium debugger it appears that the request URL is just http://website/ and not http://website/api/login. I am honestly lost and I have tried what feels like everything, but I can't seem to make it work. Any help in pointing me in the right direction would be amazing! Thank you!
The code I use for the POST request is:
const username = document.getElementById("username").value;
const password = document.getElementById("password").value;
const data = JSON.stringify({"username": username, "password":password});
const config = {
method: 'post',
url: 'http://website/api/login',
headers: {
'Content-Type': 'application/json'
},
data : data
};
axios(config).then(function (response) {
console.log(JSON.stringify(response.data));
}).catch(function (err) {
console.log(err);
})
}
This is what I see in the Chromium debugger:
Headers
This is my Node.js / Express code:
app.post('/api/login', function (req, res, next) {
scriptFile.authUser(req.body, function (err, state) {
if (err) console.log(err);
else {
if (state) {
res.send("authed");
} else {
res.send("invalid");
}
}
});
})
Thank you for any help I can get.
I am stupid,
Breakdown of what happened:
Everything was working fine except that I put the input data and submit button inside a form, which will refresh the page...
I fixed it by changing the form to a div.
Hey checking your chrome console pic looks like your post request is hitting the root api address 'http://website/' and not the full path 'http://website/api/login

Custom error message in Google Apps Script Error object [duplicate]

This is a doPost function inside a Google App that returns a Hello World message.
function doPost(e){
return ContentService.createTextOutput('Hello World');
}
Now suppose I want to only accept valid JSON to be posted to this Google App endpoint and I want to send a respones with Bad Request status. How can I do that. Here's the pseudo code:
function doPost(e){
try{
const data = JSON.parse(e.postData.contents);
return ContentService.createTextOutput('Hello World');
}catch(err){
// Send Bad Request
}
}
Issue and workaround:
Unfortunately, in the current stage, ContentService cannot modify the status code. When I saw the official document of Class ContentService, such method cannot be found. Ref It seems that this is the current specification.
So in your situation, as the current workaround, how about returning the value as JSON data? By this, you can check the value using the key of JSON data. For example, how about the following sample script?
When the correct value without the error is returned,
return ContentService.createTextOutput(JSON.stringify({value: 'value'}));
When the value with the error is returned,
return ContentService.createTextOutput(JSON.stringify({error: 'Error message'}));
When you need .setMimeType(ContentService.MimeType.JSON), please add this.
Note:
When I searched about this at the Google issue tracker, I couldn't find it. So how about reporting this as the future request? Ref
Reference:
Class ContentService
Here's another workaround that allows raising errors on the client side for errors on the web app side. For example, a client might need to catch errors such as bad url args sent to the web app (i.e. the OP's question), or catch errors thrown by a method that is called from doGet() or doPost().
As far as I know, when an error is thrown downstream of doGet() or doPost(), a text error message is returned in the response, but the web app request itself succeeds, so there is no error thrown on the client side. As #Tanaike said, there still seems no way for a Google web app dev to throw an HTTP error from the app (like 400 Bad Request or 500 Internal Server Error).
The idea involves returning a function body from the web app, which the client can use to create and run a dynamic function via the Function() constructor (this assumes Javascript is available on the client).
So the web app can be written to:
return a function body that will throw an error for bad args, server method errors, etc.
return a function body that will return intended JSON when there is no error
This is a bit of a hack, but it unifies error handling on the client side. The client makes the http request, constructs a function using the function body returned in the response, and then runs this function, all in one try{} block. Then both Google-raised http errors and web app downstream errors can be caught in the catch{} block.
Example setup for a Google Apps Script client making a request to a Google web app:
(1) In the web app doGet() or doPost() function:
// this string will be returned by the webapp
var fnBody;
// for bad url args, return a fnBody that will throw an error with an indicative message
if(!urlArgsOk()) {
fnBody = "'use strict'; throw new Error('POST args error');";
}
// if url args are ok, call server method
else {
try {
// if the method call succeeds, return a fnBody that will return the intended JSON
var returnObj = myServerMethod(methodArgs);
fnBody = "'use strict'; return JSON.stringify(" + JSON.stringify(returnObj) + ");";
}
catch(serverErr) {
// if the method call fails, return a fnBody that will throw an error ...
// ... simple example shown here, but info from serverErr can be included in fnBody
fnBody = "'use strict'; throw new Error('server error');";
}
}
// return fnBody, which can be run via Function() on the client
return ContentService.createTextOutput(fnBody).setMimeType(ContentService.MimeType.TEXT);
(2) On the client side (Google apps script client making a POST request)
// Set the url, payload, and fetch options
var url = "https://script.google.com/_______/exec?arg1=val1&arg2=val2";
var payload = getPayloadString(); // whatever POST payload needs to be sent
var options = {
'method' : 'POST',
'contentType': 'application/json',
'muteHttpExceptions': false, // let Google http exceptions come through
'payload' : payload,
'headers': {authorization: "Bearer " + ScriptApp.getOAuthToken()}
};
// Send a request to the web app
try {
// make the POST request - this throws Google-generated HTTP errors if any
var response = UrlFetchApp.fetch(url, options);
// create the dynamic function from the fnBody returned
var responseFn = new Function(response.getContentText());
// run the function - this returns intended JSON content
// or throws web app downstream errors if any
var responseJson = responseFn();
}
catch(err) {
// handle either source of error
console.log(err.message);
}
There are potential security risks associated with dynamic code, so I'm not sure how widely applicable this might be. I might use this in an aplication that lives entirely in a private GCP domain, i.e. with the web app restricted to same-domain users and the client app also in the same domain. Some security is also added by the 'use strict' directive, which boxes the dynamic function in by setting its this to undefined (ref). But it's still a good idea to think through the dynamic code implications (ref1, ref2).

There was an error in evaluating the Pre-request Script

I'm trying to access the response of my POST request in Postman via Post Request Script.
I added this 2 lines, under Pre-request Script
let response = pm.response.json();
console.log('JSON Response: ',response );
Then, I opened up my Postman console, before hit Send to make my POST request
I kept getting
There was an error in evaluating the Pre-request Script: TypeError: Cannot read property 'json' of undefined
Do I need to enable anything on Postman?
Pre-request scripts are ran before the request is sent. You do not have a response yet.
Try putting your script under the Tests tab, which is ran after a response is received.
In my case, there was a script that was screwing up my request. If you get the postman collection from someone else, check this and try to fix it. (in my case I don't need it so I deleted it)
You can try setting an environment variable, get it and parse it, I was created a POST requests to make a login and get a token to each request.
const echoPostRequest = {
url: pm.environment.get("url_login"),
method: 'POST',
header: 'Content-Type: application/json',
body: {
mode: 'raw',
raw: JSON.stringify({ email: pm.environment.get("user"),password: pm.environment.get("password") })
}
};
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err ? err : res.json());
pm.environment.set("login_response", res.json());
pm.environment.set("bearer_token", pm.environment.get("login_response").bearer_token);
});
was helping a friend and he had tried to make an adjustment to all requests in the collection.
I found in the documentation, how to remove
https://learning.postman.com/docs/writing-scripts/pre-request-scripts/
Please Make Sure That You Cleared Text Area Of PRE-REQUEST & TESTS TAB
By Clearing Text I Solved This Issue
Check if you SSL was turn off. If isn't, turn off.
Settings >> General >> SSL Certificate Verification

Posting time records to Active Collab

Currently I am working on an app for Active Collab with ionic (AngularJS). When I tracked some time I want to post this time, so that I'll have this time in Active Collab. But when I tried to do that, I got an 500 Internal Server Error. This is my Code (I used the data from the Active Collab API Documentation, to test):
var postData = {
"value": 1.5,
"user_id": 1,
"job_type_id": 1,
"record_date": "2014-05-14",
"billable_status": 0
};
$http.post(baseUrl+'/projects/' + projectId +'/time-records/', postData, { headers: { 'Content-Type': 'application/json' }}).then(function(res){ ... }
The post request work for getting the token (issue-token). So I have no idea what the problem is. I hope anyone can help me?
To make the token-post working I had to add some lines to api.php. Wouldn't this be good to be there per default?
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
// return only the headers and not the content
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
header('Access-Control-Allow-Headers: X-Requested-With');
}
exit;
}
Thanks in advance!
I am currently running Active Collab locally. So baseUrl is: http://my-ip-address/mypath-to-ac/api/v5/projects/56/time-records/ . I do have an authInterceptor, so token should be appended. I also tried to send it within the post-request, but got same error.
Now I debugged it a little more and it says that some fields are null. But I definitely filled those fields and sent them.
This is the logged Data, that I'll send with the request:
{"value":"1.5","user_id":10,"job_type_id":"0","record_date":1467965415.184,"billable_status":0}
And this is the error, I'll get:
debugged error as screenshot

Google reCAPTCHA, 405 error and CORS issue

I am using AngularJS and trying to work with Google's reCAPTCHA,
I am using the "Explicitly render the reCAPTCHA widget" method for displaying the reCAPTCHA on my web page,
HTML code -
<script type="text/javascript">
var onloadCallback = function()
{
grecaptcha.render('loginCapcha', {
'sitekey' : 'someSiteKey',
'callback' : verifyCallback,
'theme':'dark'
});
};
var auth='';
var verifyCallback = function(response)
{
//storing the Google response in a Global js variable auth, to be used in the controller
auth = response;
var scope = angular.element(document.getElementById('loginCapcha')).scope();
scope.auth();
};
</script>
<div id="loginCapcha"></div>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
So far, I am able to achieve the needed functionality of whether the user is a Human or a Bot,
As per my code above, I have a Callback function called 'verifyCallback' in my code,
which is storing the response created by Google, in a global variable called 'auth'.
Now, the final part of reCAPCHA is calling the Google API, with "https://www.google.com/recaptcha/api/siteverify" as the URL and using a POST method,And passing it the Secret Key and the Response created by Google, which I've done in the code below.
My Controller -
_myApp.controller('loginController',['$rootScope','$scope','$http',
function($rootScope,$scope,$http){
var verified = '';
$scope.auth = function()
{
//Secret key provided by Google
secret = "someSecretKey";
/*calling the Google API, passing it the Secretkey and Response,
to the specified URL, using POST method*/
var verificationReq = {
method: 'POST',
url: 'https://www.google.com/recaptcha/api/siteverify',
headers: {
'Access-Control-Allow-Origin':'*'
},
params:{
secret: secret,
response: auth
}
}
$http(verificationReq).then(function(response)
{
if(response.data.success==true)
{
console.log("Not a Bot");
verified = true;
}
else
{
console.log("Bot or some problem");
}
}, function() {
// do on response failure
});
}
So, the Problem I am actually facing is that I am unable to hit the Google's URL, Following is the screenshot of the request I am sending and the error.
Request made -
Error Response -
As far as I understand it is related to CORS and Preflight request.So what am I doing wrong? How do I fix this problem?
As stated in google's docs https://developers.google.com/recaptcha/docs/verify
This page explains how to verify a user's response to a reCAPTCHA challenge from your application's backend.
Verification is initiated from the server, not the client.
This is an extra security step for the server to ensure requests coming from clients are legitimate. Otherwise a client could fake a response and the server would be blindly trusting that the client is a verified human.
If you get a cors error when trying to sign in with recaptcha, it could be that your backend server deployment is down.

Categories