I am working with Stripe (developing a payment system) on React.js and I am trying to translate the code below into React.js and use axios to create the endpoint that receives the POST request from the backend (Django):
var handler = StripeCheckout.configure({
key: 'pk_test_zNq2YI8Spsyi81TknNujN36T',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
$.ajax({
type: "POST",
url: 'http://localhost:8000/subscriptions/codes/pay/',
data: {amount: amount, token: token},
});
}
});
I am stuck on Step 4 from this link : Stripe for React, which explains the POST request but they are using Express, and I am using Django.
The server side code can be written in any language/frameworks as long as it provides an endpoint subscriptions/codes/pay/ for your front-end post.
In Django, you can refer to the document at [0] on how to get started on creating a REST API
A very simple code
define your route
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('subscriptions/checkout', views.ElementView.as_view(), name="Stripe Checkout"),
path('subscriptions/codes/pay', views.charge, name='charge'),
]
And in your view definitions
from django.http import HttpResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
#require_http_methods(["POST"])
#csrf_exempt
def charge(request):
# request.body will contain your data {amount: amount, token: token}
return HttpResponse(request.body)
Again, the backend implementation should be language/framework agnostic; it will work as long as your backend provide a valid POST API allowing you to send your StripeToken back
[0] https://docs.djangoproject.com/en/2.1/intro/tutorial01/
Related
I'm getting a 400 error and isAxiosError: true. I think the problem is the auth line is not formatted correctly, or I'm not quite understanding how params work in axios and what's needed by the api? What am I doing wrong in my translating of python to Axios/JS?
Here's the Voila Norbert API documentation.
Here's my Axios api call.
axios.post('https://api.voilanorbert.com/2018-01-08/search/name', {
params: {
auth: {any_string: API_KEY},
data: {
domain: 'amazon.com',
name: 'Jeff Bezos'
}
}
})
Here's the python version:
API_TOKEN = 'abcde'
req = requests.post(
'https://api.voilanorbert.com/2018-01-08/search/name',
auth=('any_string', API_TOKEN),
data = {
'name': 'Cyril Nicodeme',
'domain': 'reflectiv.net'
}
)
I am a year late with this answer but I found your question while dealing with this same error with the same API. The API documentation's suggested Python code works for me with a successful response, but I want to do it in Node and the JS code returns a 400 error. I'm sharing my solution in case it helps others in the future.
I believe the core issue is that the API expects the data to be posted as form data, not as JSON. I followed an example in another post to post form data with Axios but still was receiving a 400 error.
Then I tried posting it using the request package instead of Axios, and that results in a successful response (no error):
const request = require('request');
var data = {'name': 'Jeff Bezos', 'domain': 'amazon.com'};
request.post({
url: 'https://any_string:API_KEY#api.voilanorbert.com/2018-01-08/search/name',
form: data,
}, function(error, response, body){
console.log(body);
});
This example works when the data is included in the form: field but does not work when it is in body:
Please note the request package is deprecated and in maintenance mode.
According to their documentation, https://github.com/axios/axios, you need to give auth as a separate field, not inside params:
axios.post('https://api.voilanorbert.com/2018-01-08/search/name', {
auth: {
username: 'any_string',
password: API_KEY
},
data: {
domain: 'amazon.com',
name: 'Jeff Bezos'
}
})
Updated: removed the nesting of data in params. They should be sent as POST body, not URL params.
I have a small problem with my Http Service in my Angular CLI app.
I have a form I need to submit. Data from this form are sent to API and stored into database.
This is the service
import {Injectable} from "#angular/core";
import {Http, Headers} from "#angular/http";
#Injectable()
export class HttpService {
private api: string = "http://localhost/api/www/";
constructor(private http: Http) {
}
insertRouteReview(data: {}) {
const headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
});
this.http.post(this.api+"route/addreview", data, {headers: headers});
}
}
Data sample:
{
"reviewId": 1,
"userId": 1,
"routeId": 1,
"ratio": 3,
"description": "lorem ipsumaaa"
}
Note: urlencoded is there before PHP cannot handle the application/json format.
When I send the data via some tool (For example Restlet Client) like this
The data are stored into DB successfully. So API should be fine.
What Am I doing wrong in my angular app? I get no error when I click the button which gets the data and pass them into http service.
E:
Code which is triggered after submit button is clicked
onSubmit() {
let review: {} = {
reviewId: +this.reviewForm.value.reviewId,
userId: +this.userService.userId,
routeId: +this.routeId,
ratio: +this.reviewForm.value.ratio,
description: this.reviewForm.value.description
};
this.httpService.insertRouteReview(review);
}
The review form is just form created in typescript and its working fine. If I dump values (or review object) I can see the proper values.
E: I subscribed to the post and now Its working fine. Thank you
The problem was I didn't subscribed to that post() method. When I did it, I reached the API.
I am using GAE for web development, on jinja2 and python2.7
I can get data from Python. But I failed to send data from JavaScript to Python. Here is the JavaScript code:
function toSave() {
var val_no = $('#field-no').val();
var val_name = $('#field-name').val();
var val_address = $('#field-address').val();
var val_phone = $('#field-phone').val();
var val_car = $('#field-car').val();
var val_penalty = $('#field-penalty').val();
$.ajax({
type: 'GET',
url: "https:/test/User_update",
data: {
"no": val_no,
"name": val_name,
"address": val_address,
"phone": val_phone,
"car": val_car,
"penalty": val_penalty
},
dataType: "json"
}).done(function () {
$('#modal-1').modal('hide');
table.row.data([val_no, val_name, val_address, val_phone, val_car, val_penalty, UserIndex_CreateEditButton(val_no, val_name, val_address, val_phone, val_car, val_penalty), UserIndex_CreateDeleteButton(val_no)], $('#' + tempUpdate));
});
}
And the Python code (class User_update in main.py):
import os
import webapp2
import MySQLdb
import json
import logging
import googlemaps
import jinja2
import sys
import urllib
import urllib2
import json as simplejson
import codecs
reload(sys)
sys.setdefaultencoding('utf-8')
from operator import eq
from datetime import datetime
from collections import OrderedDict
class User_update(webapp2.RequestHandler):
def get(self):
jsonData = json.loads(self.get('data'))
# penalty = self.request.get('data')
# phone = urllib.request.urlopen(req).read()
# data = urllib.requset.urlopen("http://www.daum.net").read()
# phone=urllib2.urlopen("https://firststep-2016.appspot.com/Log").read()
self.response.headers['Content-Type']='text/plain'
db = connect_to_cloudsql()
cursor = db.cursor()
cursor.execute("SET names utf8")
cursor.execute('SET SQL_SAFE_UPDATES=0;')
cursor.execute("""update User set name='%s',address='%s',phone='%s',car_num='%s',penalty='%s' where no='%s' """%(jsonData.name,jsonData.address,jsonData.phone,jsonData.car,jsonData.penalty,jsonData.no))
db.commit()
db.close()
How can I get the JavaScript data from Python?
HTTP Methods
First it is good to understand how the communication works in general.
HTTP has various methods, such as GET and POST (see https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol).
Relevant methods for you in this case:
GET is meant for read-only requests. Unlike other HTTP methods, GET requests do not carry body with data that is sent to the server. All of the data would get sent via URL parameters. In some case also as part of the header. GET requests may be repeated or cached as they are read-only. Which is why they shouldn't be used for updates.
POST and PUT can update data, generally POST is used to create objects whereas PUT is used to update an existing object. Both HTTP methods do accept a body with the data.
Since you are updating a user, PUT seems to be appropriate.
Sending data to the server, via jQuery's ajax
Most developers might assume it but it is worth listing out all of the direct dependencies, in this case you seem to be using jQuery to get the value and send the request to the server. In particular $.ajax: http://api.jquery.com/jQuery.ajax/
As the documentation for the data attribute:
Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests.
So even though GET doesn't accept a body, jQuery adds it to the URL for you. As mentioned before I would advice against using GET for updates.
At this point you could make use of the browser's developer tools to inspect the network requests. That way you will see what exactly is sent to the server.
Receiving data in the server
I believe the API you are using is: http://webapp2.readthedocs.io/en/latest/guide/handlers.html
You should be able to get the individual values like so (there won't be a 'data' parameter):
val_no = self.request.get("no")
val_name = self.request.get("name")
# ...
For PUT or POST it should work like this (http://webapp2.readthedocs.io/en/latest/guide/request.html#post-data):
val_no = self.request.POST['no']
val_name = self.request.POST['name']
# ...
Security
Your server code is vulnerable to https://en.wikipedia.org/wiki/SQL_injection
It is not part of your question but quite serious. I wouldn't make that code available on a public server and if it is now I would remove it until fixed.
Looks like you are trying to post data using the wrong method. You should use POST instead of GET to send data to the server
$.ajax({
type: 'POST',
url: "https://firststep-2016.appspot.com/User_update",
data: {
"no": val_no,
"name": val_name,
"address": val_address,
"phone": val_phone,
"car": val_car,
"penalty": val_penalty
},
dataType: "json"
}).done(function () {
$('#modal-1').modal('hide');
table.row.data([val_no, val_name, val_address, val_phone, val_car, val_penalty, UserIndex_CreateEditButton(val_no, val_name, val_address, val_phone, val_car, val_penalty), UserIndex_CreateDeleteButton(val_no)], $('#' + tempUpdate));
});
Then handle the incoming data in the Python server
def post(self):
....
I'm a bit new to Django and trying to understand it. Currently, I'm creating a network topology visualiser (think routers and switches connected together). It works fine and all of the data is saved in a javascript object.
I want to have the ability to, when a user clicks a button, send this javascript object to django so that it can be parsed and handled appropriately. I did a lot of research and found a bunch of similar implementation which use a combination of JQuery and ajax to POST a JSON string. This is some of my code currently:
mainapp/urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^NetworkTopology/', include('OpenAutomation.NetworkTopology.urls')),
url(r'^NetworkTopology/json/', include('OpenAutomation.NetworkTopology.urls')),
url(r'^admin/', admin.site.urls),
]
NetworkTopology/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^json/$', views.returnjson, name='returnjson'),
]
NetworkTopology/views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
def index(request):
return render_to_response('index.html')
def returnjson(request):
if request.is_ajax():
request_data = request.POST
print("Raw Data: " + request_data.body)
return HttpResponse("OK")
JavaScript function (return JSON button is pressed):
function returnJsonTop(){
$(document).ready(function() {
$.ajax({
method: 'POST',
url: '/NetworkTopology/json',
dataType: 'json',
data: JSON.stringify(nodes.get(),null,4),
success: function (data) {
//this gets called when server returns an OK response
alert("it worked!");
},
error: function (data) {
alert("it didnt work");
}
});
});
}
In my index template, I have created a button which calls the returnJsonTop() function when it is pressed:
<button id="submitJson" onclick="returnJsonTop();">Deploy</button>
Currently, when I press the Deploy button, I just get the 'it didn't work' alert that has been setup to handle an errors. I'd really appreciate someone pointing me in the right direction here. I suspect the issue is in my urls.py files but I've tried various combinations of urls without any luck.
You're trying to access body on request.POST. But body is an attribute directly of the request. Your code should be:
request_data = request.body
print("Raw Data: " + request_data)
Also note, in your Javascript that $(document).ready line makes no sense there; you should remove it.
For those reading this later, this is what I did:
mainapp/urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^NetworkTopology/', include('OpenAutomation.NetworkTopology.urls')),
url(r'^admin/', admin.site.urls),
]
NetworkTopology/urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^json/$', views.returnjson, name='returnjson'),
]
NetworkTopology/views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.views.decorators.csrf import csrf_exempt
def index(request):
return render_to_response('index.html')
#csrf_exempt
def returnjson(request):
if request.is_ajax():
request_data = request.POST
print("Raw Data: " + str(request_data))
return HttpResponse("OK")
I was getting a 403 error so I added '#csrf_exempt'. I'll probably change this to handle it properly afterwards.
Return JSON function:
function returnJsonTop(){
$.ajax({
method: 'POST',
url: '/NetworkTopology/json/',
dataType: 'json',
data: JSON.stringify(nodes.get(),null,4)
});
}
First of all you dont even need to use all this in your ajax call
data: JSON.stringify(nodes.get(),null,4),
replace by
data: nodes.get(),
should be enough as long as this method returns a valid json object
Second one, I ´d strongly recommend you to use a framework to help you to parse JSON
Python have may, but to illustrate this example, I've used django rest framework, which is a very good one.
from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from rest_framework.renderers import JSONRenderer
import json
import controllers#this class belongs to my business logic layer, you can encapsulate yours and use instead of it
#in this solution you must create a pre-parser to handle responses
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
#csrf_exempt # this is for prevent invasions
def login(request):
#this one here handle your jquery post data into a valid json object in python represented by a Dict
envelopin = json.loads(request.body)
# here we pass the dict inside my business controll logic routine which also responds with a valid Python Dict
envelopout = controllers.login(envelopin)
# and for last, we use our pre-parser Class to make your response be handled by jquery as valid json
return JSONResponse(envelopout)
and that is it, you success jQuery data variable, will hold the envelopout json object, in the same shape as it has inside yor django-python code.
hope this help
I have an account at Vimeo.com and am trying to figure out how to log in using the Python Requests package. Here are my initial observations:
Logging in is done via a post request to https://vimeo.com/log_in?ssl=0&iframe=0&popup=0&player=0&product_id=0 and requires an email, password, action, service, and token to be passed as body data
The token for the post request appears to be different from the xsrft token but I'm not able to get either as the token appears to be generated via javascript and only valid for each session (though it isn't clear)
Cookies are necessary
Here is some initial code:
import requests
from bs4 import BeautifulSoup
url = 'http://vimeo.com/log_in?ssl=0&iframe=0&popup=0&player=0&product_id=0'
payload = {'email': 'some#email.com',
'password': 'privatepassword',
'action': 'login',
'service': 'vimeo',
'token': '?????'
}
response = requests.post(url, data=payload, allow_redirects=True)
soup = BeautifulSoup(response.text)
I can't figure out how to get the correct token for the post request and whether the token is associated with the vuid or xsrft token.