Not able to receive value in response in flutter to cashfree API - flutter

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

How to use axios response error.config to retry the request?

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)

how to input text parameter to GET api with space

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
}
));

How to Pass Form Data in Post Request using ionic-native-http in capacitor?

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
}

Angular2 Stripe integration stripeResponseHandler cannot access this

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));

How to catch a 401 (or other status error) in an angular service call?

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.