I'm trying to receive response order_token from test API https://sandbox.cashfree.com/pg/orders which is used to create session of a payment gateway. Here is the code.
CFEnvironment environment = CFEnvironment.SANDBOX;
Future<dynamic> createOrder() async {
var response = await http.post(
Uri.https('https://sandbox.cashfree.com/pg/orders'),
headers: {
'Content-Type': 'application/json',
'x-client-id': 'your x-client-id',
'x-client-secret': 'your x-client-secret',
'x-api-version': '2022-01-01',
'x-request-id': 'developer_name',
},
body: jsonEncode(
{
"order_id": widget.cartId,
"order_amount": widget.grandTotal,
"order_currency": "INR",
"order_note": "Additional order info",
"customer_details": {
"customer_id": widget.address.id,
"customer_name": "name",
"customer_email": widget.email,
"customer_phone": widget.address.phone,
}
},
),
);
if (response.statusCode == 200) {
if (jsonDecode(response.body)['status'] == 'OK') {
debugPrint(jsonDecode(response.body)['order_id']);
debugPrint('log');
Logger.i(response.body);
return jsonDecode(response.body)['order_id'];
}
}
return '';
}
createSession() {
createOrder().then((value) {
try {
var session = CFSessionBuilder()
.setEnvironment(environment)
.setOrderId(widget.cartId!)
.setOrderToken(value)
.build();
return session;
} on CFException catch (e) {
debugPrint(e.message);
}
});
return null;
}
But the response seems to null and payment gateway doesn't open. What might be going wrong with my code? I tried printing response but there in null value there,What might be going wrong? How do I get a response? I've done this in postman I get a response.
replace header placeholders with actual values like your x-client-secret and others
Try this
var decodedResponse = jsonDecode(utf8.decode(response.bodyBytes)) as Map;
orderId = decodedResponse["order_id"] as String;
orderToken = decodedResponse["order_token"] as String;
Once the order is created and session is created, there are further steps, then only the checkout page will open. Refer this example - https://pub.dev/packages/flutter_cashfree_pg_sdk/example
Note :- Ideally, you shouldn't be creating order from app level. It should be done from your backend (Move the order creation to your backend).
Related
I'm following a tutorial that uses an interceptor to retry a request with an authorization token, the code is like this:
import axios from "axios";
axios.defaults.baseURL = "http://localhost:8000/api/";
axios.interceptors.response.use(resp => resp, async error => {
console.log('error', error)
if (error.response?.status === 401) {
const {data, status} = await axios.post('refresh', {}, {withCredentials: true});
if (status === 200) {
axios.defaults.headers.common['Authorization'] = `Bearer ${data.accessToken}`
}
return axios(error.config) ;
}
return error;
});
In the tutorial this seems to work fine, but in my machine I'm getting this error :
error DOMException: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': 'function(header, parser) {
header = normalizeHeader(header);
if (!header)
return void 0;
const key = findKey(this, header);
if (key) {
const value = this[key];
if (!parser) {
return value;
}
if (parser === true) {
return parseTokens(value);
}
if (utils_default.isFunction(parser)) {
return parser.call(this, value, key);
}
if (utils_default.isRegExp(parser)) {
return parser.exec(value);
}
throw new TypeError("parser must be boolean|regexp|function");
}
}' is not a valid HTTP header field value.
at setRequestHeader (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:1208:17)
at Object.forEach (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:89:10)
at dispatchXhrRequest (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:1207:21)
at new Promise (<anonymous>)
at xhrAdapter (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:1111:10)
at Axios.dispatchRequest (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:1424:10)
at Axios.request (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:1666:33)
at wrap (http://localhost:5173/node_modules/.vite/deps/axios.js?v=1ea4ef45:16:15)
at http://localhost:5173/src/intereceptors/axios.ts?t=1665639283918:10:12
at async http://localhost:5173/src/pages/Home.svelte:74:20
if I replace return axios(error.config); with a regular request then everything works :
const userdata = await axios.get('http://localhost:8000/api/user')
return userdata;
I'm wondering if since I'm using a newer version of axios, things have changed and now this doesn't work anymore, or is there a way to make it work with axios(error.config)
I have an http service to GET movies api data it works fine but if i input 2 words for example
"The Batman" it's not working because it will return null but if i only input 1 word "Batman" it works fine, im still new with query query things
if you have the answer can you please answer with my full code ? because im quite slow to understand some logic
here is my code
Future searchMovie(movieName) async {
Uri url = Uri.parse('https://api.themoviedb.org/3/search/movie?api_key={key}&query=$movieName');
var response = await http.get(url);
if (response.statusCode == 200) {
List data = jsonDecode(response.body)['results'];
List<SearchMovieModel> searchedMovies = [];
for (var item in data) {
searchedMovies.add(SearchMovieModel.fromJson(item));
}
return searchedMovies;
} else {
throw Exception('Error get data');
}
}
you can try this way.
String query ='The Batman';
await get(Uri.parse('https://api.themoviedb.org/3/search/movie').replace(
queryParameters: {
'api_key' :'key',
'query' : query
}
));
I have used a Validation Form to take the input from users and I have a submit button on which submit() function is being called.
insertuserdata() is a function in service.ts file where api is being called. I am passing form data in the api. File(e.g pdf,doc,docx etc.) can also be passed to the api as multi part form data.
But I am using Ionic-Native-Http to pass multi part form data using capacitor.
I am getting the error as status 415.Please help with this.
submit()
{
this.isSubmitted = true;
if (!this.ionicForm.valid) {
console.log('Please provide all the required values!')
return false;
} else {
console.log(this.ionicForm.value)
}
console.log("this is deptid", this.deptid)
console.log("this is description", this.ionicForm.controls["description"].value)
console.log("this is cid", this.ionicForm.controls["subquery"].value)
console.log("this is location", this.ionicForm.controls["location"].value)
console.log("query",this.ionicForm.controls["query"].value)
console.log("Insert Form Data")
const formData = new FormData();
formData.append('postedby', this.employeeId);
formData.append('description', this.ionicForm.controls["description"].value);
formData.append('location', this.ionicForm.controls["location"].value);
formData.append('deptid', this.deptid);
formData.append('cid', this.ionicForm.controls["subquery"].value);
formData.append('file', this.ionicForm.get('profile').value);
console.log("Insert Api call")
this.c2s.insertuserdata(formData).then((insertdata: any) =>{
console.log("Insert Response",insertdata)
})
insertuserdata(formData) {
let httpOptions = {
headers: new HttpHeaders({
'enctype': 'multipart/form-data;',
'Content-Type': 'application/json'
})
};
this.insert = this.http1.post("https://webapplnapp.tatapower.com/tpc_restfull_service/api/connecttosolve/postQuery", formData, httpOptions);
return this.insert
}
I'm integrating Stripe payments with Angular2 (actually Ionic but the code is the same)
the call to Stripe.card.createToken is successful and returns a token
but in stripeResponseHandler which is an async callback, I cannot access any of the "this" variables. for example I cannot set this.amount = 10 and I cannot call this._http.post
how can I access the "this" variables ? I'm trying to http post the token and the amount to an API to make the payment
constructor(private _navController: NavController,
private _http: Http) { }
submitPayment() {
Stripe.setPublishableKey(this.key);
this.card = new Card();
this.card.number = this.cardNumber;
this.card.cvc = this.cardCVC;
this.card.exp_month = this.cardExpMonth;
this.card.exp_year = this.cardExpYear;
this.card.address_zip = this.cardAddressZip;
try {
Stripe.card.createToken(this.card, this.stripeResponseHandler);
}
catch (e) {
alert(e.message);
}
// Prevent the form from being submitted:
return false;
}
stripeResponseHandler(status, response) {
if (response.error) { // Problem!
alert(response.error);
} else { // Token was created!
// Get the token ID:
alert(response.id);
try {
this.amount = 10;
let payment = new Payment();
payment.token = response.id;
payment.amount = this.amount;
let body = JSON.stringify(payment);
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
this._http.post(this.url, body, options)
.map(res => res.json())
.catch(this.handleError);
}
catch (e) {
alert(e.message);
}
}
}
handleError(error: Response) {
// may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);
alert('error' + error.text + " " + error.statusText);
return Observable.throw(error.json().error || 'Server error');
}
If you just pass the function reference, then JavaScript doesn't keep the this reference. You have to take care of this explicitely:
Instead of
Stripe.card.createToken(this.card, this.stripeResponseHandler);
use
Stripe.card.createToken(this.card, (status, person) => this.stripeResponseHandler(status, person));
See also https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
or
Stripe.card.createToken(this.card, this.stripeResponseHandler.bind(this));
Using $http I can catch errors like 401 easily:
$http({method: 'GET', url: 'http://localhost/Blog/posts/index.json'}).
success(function(data, status, headers, config) {
$scope.posts = data;
}).
error(function(data, status, headers, config) {
if(status == 401)
{
alert('not auth.');
}
$scope.posts = {};
});
But how can I do something similar when using services instead. This is how my current service looks:
myModule.factory('Post', function($resource){
return $resource('http://localhost/Blog/posts/index.json', {}, {
index: {method:'GET', params:{}, isArray:true}
});
});
(Yes, I'm just learning angular).
SOLUTION (thanks to Nitish Kumar and all the contributors)
In the Post controller I was calling the service like this:
function PhoneListCtrl($scope, Post) {
$scope.posts = Post.query();
}
//PhoneListCtrl.$inject = ['$scope', 'Post'];
As suggested by the selected answer, now I'm calling it like this and it works:
function PhoneListCtrl($scope, Post) {
Post.query({},
//When it works
function(data){
$scope.posts = data;
},
//When it fails
function(error){
alert(error.status);
});
}
//PhoneListCtrl.$inject = ['$scope', 'Post'];
in controller call Post like .
Post.index({},
function success(data) {
$scope.posts = data;
},
function err(error) {
if(error.status == 401)
{
alert('not auth.');
}
$scope.posts = {};
}
);
Resources return promises just like http. Simply hook into the error resolution:
Post.get(...).then(function(){
//successful things happen here
}, function(){
//errorful things happen here
});
AngularJS Failed Resource GET
$http is a service just like $resource is a service.
myModule.factory('Post', function($resource){
return $http({method: 'GET', url: 'http://localhost/Blog/posts/index.json'});
});
This will return the promise. You can also use a promise inside your factory and chain that so your factory (service) does all of the error handling for you.