I am using stripe to process my payments. I noticed that it keeps charging only $14.00 and I wanted to know how can I change that to something $1.00. I tried modifying the app.post("create-payment-intent") and still nothing is changing. Every time I check my stripe dashboard I still see $14.00 being charged. I have a copy of my code. Can someone please assist me with this. Thanks in advance
//Code
private void startCheckout() {
//amount will calculate from .00 make sure multiply by 100
//double amount=Double.parseDouble(mAmount.getText().toString())*1;
// Create a PaymentIntent by calling the sample server's /create-payment-intent endpoint.
MediaType mediaType = MediaType.get("application/json; charset=utf-8");
/*
String json = "{"
+ "\"currency\":\"usd\","
+ "\"items\":["
+ "{\"id\":\"photo_subscription\"}"
+ "]"
+ "}";
*/
double amount=123.0;
Map<String,Object> payMap=new HashMap<>();
Map<String,Object> itemMap=new HashMap<>();
List<Map<String,Object>> itemList =new ArrayList<>();
payMap.put("currency","usd");
payMap.put("amount","amount");
itemMap.put("id","photo_subscription");
itemMap.put("amount",amount);
itemList.add(itemMap);
payMap.put("items",itemList);
String json = new Gson().toJson(payMap);
//Log.i("TAG", "startCheckout: "+json);
RequestBody body = RequestBody.create(mediaType,json);
Request request = new Request.Builder()
.url(BACKEND_URL + "create-payment-intent")
.post(body)
.build();
httpClient.newCall(request)
.enqueue(new PayCallback(this));
// Hook up the pay button to the card widget and stripe instance
//Button payButton = findViewById(R.id.payButton);
payButton.setOnClickListener((View view) -> {
//String get_card=cardInputWidget.getCard().getAddressZip();
//Toast.makeText(PaymentPageActivity.this, get_card, Toast.LENGTH_SHORT).show();
PaymentMethodCreateParams params = cardInputWidget.getPaymentMethodCreateParams();
if (params != null) {
Map<String, String> extraParams = new HashMap<>();
extraParams.put("setup_future_usage", "off_session");
ConfirmPaymentIntentParams confirmParams = ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(params, paymentIntentClientSecret);
stripe.confirmPayment(this, confirmParams);
}
});
}
//server.js
const express = require("express");
const app = express();
const { resolve } = require("path");
// This is your real test secret API key.
const stripe = require("stripe")("sk_test_****************");
app.use(express.static("."));
app.use(express.json());
const calculateOrderAmount = items => {
// Replace this constant with a calculation of the order's amount
// Calculate the order total on the server to prevent
// people from directly manipulating the amount on the client
return 100;
};
app.post("/create-payment-intent", async (req, res) => {
const { items } = req.body;
// Create a PaymentIntent with the order amount and currency
const paymentIntent = await stripe.paymentIntents.create({
amount: calculateOrderAmount(items),
currency: "usd"
});
res.send({
clientSecret: paymentIntent.client_secret
});
});
app.get("/greet", async (req, res) => {
res.send('hello it is working');
});
const PORT= process.env.PORT || 5001;
app.listen(PORT, () => console.log('Node server listening on port $(PORT)'));
The issue here is that your client code is pointing to a server that does not have your local changes. You have two options:
Change your BACKEND_URL to point to your local server while your testing
Leave your BACKEND_URL as is, commit and push your changes to master, and run git push heroku master to push your changes to heroku.
Related
I am using the MultipartRequest for the image upload with the requested parameters, but getting the following exception from my below lines of code. The same API I have used the Android Native and its working very fine there, but getting exception in Flutter Android platform, please check the below error I am getting from the server
request entity too large413PayloadTooLargeError: request entity too large
at readStream (/data/consagous/loyaltie/node_modules/raw-body/index.js:155:17)
at getRawBody (/data/consagous/loyaltie/node_modules/raw-body/index.js:108:12)
at read (/data/consagous/loyaltie/node_modules/body-parser/lib/read.js:77:3)
at jsonParser (/data/consagous/loyaltie/node_modules/body-parser/lib/types/json.js:135:5)
at Layer.handle [as handle_request] (/data/consagous/loyaltie/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:317:13)
at /data/consagous/loyaltie/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:335:12)
at next (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:275:10)
at logger (/data/consagous/loyaltie/node_modules/morgan/index.js:144:5)
at Layer.handle [as handle_request] (/data/consagous/loyaltie/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:317:13)
at /data/consagous/loyaltie/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:335:12)
at next (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:275:10)
at expressInit (/data/consagous/loyaltie/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/data/consagous/loyaltie/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:317:13)
at /data/consagous/loyaltie/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:335:12)
at next (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:275:10)
at query (/data/consagous/loyaltie/node_modules/express/lib/middleware/query.js:45:5)
at Layer.handle [as handle_request] (/data/consagous/loyaltie/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:317:13)
at /data/consagous/loyaltie/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:335:12)
at next (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/data/consagous/loyaltie/node_modules/express/lib/router/index.js:174:3)
I have used the below lines of code for the uploading the image using the Multipart like below, please check it once.
Future<dynamic> apiUploadImage(
String url,
String eventType,
String name,
String email,
String password,
String mobile,
String _countryId,
String _stateId,
String _cityId,
String _zipCId,
String address,
var lati,
var longi,
String _categoryId,
File imageFile) async {
print("Current state = " + _stateId + " " + _cityId);
Uri uri = Uri.parse(url);
MultipartRequest request = new MultipartRequest('POST', uri);
request.headers[HEADER_CONTENT_TYPE_KEY] = HEADER_CONTENT_TYPE_VALUE;
request.headers[HEADER_VERSION_KEY] = HEADER_VERSION_VALUE;
request.headers[HEADER_DEVICE_TYPE_KEY] = HEADER_DEVICE_TYPE_VALUE;
request.headers[HEADER_DEVICE_ID_KEY] = HEADER_DEVICE_ID_VALUE;
request.headers[HEADER_AUTH_TOKEN_KEY] = HEADER_AUTH_TOKEN_VALUE;
request.headers[HEADER_TIME_KEY] = HEADER_TIME_VALUE;
request.fields['email'] = email;
request.fields['password'] = password;
request.fields['name'] = name;
request.fields['mobile'] = mobile;
request.fields['country'] = _countryId;
request.fields['state'] = _stateId;
request.fields['city'] = _cityId;
request.fields['zip_code'] = _zipCId;
request.fields['role_id'] = '3';
request.fields['device_type'] = HEADER_DEVICE_TYPE_VALUE;
request.fields['device_token'] = HEADER_AUTH_TOKEN_VALUE;
request.fields['category_id'] = _categoryId;
request.fields['address'] = address;
request.fields['lati'] = lati.toString();
request.fields['longi'] = longi.toString();
print("Current state = " + _stateId + " " + _cityId);
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var multipartFile = new MultipartFile("imagefile", stream, length,
filename: imageFile.path);
request.files.add(multipartFile);
var response = await request.send();
final respStr = await response.stream.bytesToString();
debugPrint(respStr);
}
Even though i even compressed the image file before sending but the problem is same, please check my compressor code for the image like below.
imageFile = await ImagePicker.pickImage(source: ImageSource.camera,imageQuality: 85);
I have searched the solutions , but it even not working please check it once.
1). First link
2). Second link
3). Third link
4). Forth link
From the server-side , we have also increased the payload limit in node server like below, but it is not working
bodyParser = { json: {limit: '50mb', extended: true}, urlencoded: {limit: '50mb', extended: true} };
I have tried all the ways on server-side and my side and i have referred this link but all are not working for me.Please check the my above code and let me know where am i wrong? Thanks
There's a named convenience constructor for files. Use it like this:
request.files.add(
await http.MultipartFile.fromPath(
'some_form_value_name',
File('somefile.zip').path,
contentType: MediaType('application', 'zip'),
),
);
To send test data, use the other named constructors (fromString and fromBytes) for example:
request.files.add(http.MultipartFile.fromBytes(
'another_form_name',
Uint8List(1000),
filename: 'somefile.zip',
contentType: MediaType('application', 'zip'),
));
I have used all the possible ways to come out from the problem but no one has worked for me, then after I have used the third part library dio 3.0.8 and working very well to upload the image on the server along with request parameters.
Inside the pubspec.yaml used this library,
dio: ^3.0.8
And on the code side, I have used the following code which works.Please check it once.
Dio dio = new Dio(); // with default Options
// Set default configs
dio.options.baseUrl = BASE_URL;
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout = 3000;
FormData formData = new FormData.fromMap({
"email": email,
"password": password,
"name": name,
"mobile": mobile,
"country":_countryId,
"state": _stateId,
"city": _cityId,
"zip_code": _zipCId,
"role_id": "3",
"category_id":_categoryId,
"address": address,
"lati": lati.toString(),
"longi": longi.toString(),
"device_type": HEADER_DEVICE_TYPE_VALUE,
"profile_image": await MultipartFile.fromFile(imageFile.path,filename: imageFile.path.split("/").last),
});
var response = await dio.post(REGISTRATION_URL, data: formData);
if (response.statusCode == 200) {
apiResponse.onSuccess(response.toString(), eventType);
print("Image Uploaded");
} else {
apiResponse.onError('Failed to load post');
print("Upload Failed");
}
}
Please check this library for more information Click here
I'm making a simple app for getting personal information from the user and number of images to send them through backend mail API with a one click of a button. So far, I can get and send the FormData through mail but I couldn't figure it out the how to send an array of images.
I have tried several API's but "Mailer" seems to best for SMTP. As for the code, I tried to convert the "File" class to String or List but none of those have worked for me. I'am not a intermediate coder so be kind with me :)
That's how I get the images using "image_picker"
File _image1;
Future getImage1Camera() async {
var image1 = await ImagePicker.pickImage(source: ImageSource.camera);
setState(() {
_image1 = image1;
});
}
And the "mailer" code
void _mailer() async{
if(!_formKey.currentState.validate()){
return;
}else{
_formKey.currentState.save();
}
String gmailUsername = '**';
String gmailPassword = '**';
final smtpServer = gmail(gmailUsername, gmailPassword);
final ceSendMail = Message()
..from = Address(gmailUsername, '')
..recipients.add('recipent')
..subject = 'Test'
..text = 'Plain Text'
..html = ''//Form Data
..attachments.add(_image1);//TODO: User input images
try {
final sendReport = await send(cekSendMail, smtpServer);
print('Message sent: ' + sendReport.toString());
} on MailerException catch (e) {
print('Message not sent.');
for (var p in e.problems) {
print('Problem: ${p.code}: ${p.msg}');
}
}
// Create a smtp client that will persist the connection
var connection = PersistentConnection(smtpServer);
// Send the message
await connection.send(cekSendMail);
// close the connection
await connection.close();
}
This is the error I get and whatever I try it's always the "type" error.
The argument type 'File' can't be assigned to the parameter type 'Attachment'.
So, how can I get multiple image files from user and send through mail API?
You need to wrap your file with FileAttachment
..attachments.add(FileAttachment(_image1))
I'm wiriting my application in Android, but i don't know how to send response only to device whos generated session with special ID in express-session. For example, i have 3 phones and click at the same time button login with difference data in pools, all 3 devices captured the same object instead of 3 different destined ( first response object from express was caught by 3 devices rest 2 object ignored, i want to sent object every one of them ).
....
var express = require('express');
var session = require('express-session');
var crypto = require('crypto');
var uuid = require('node-uuid');
var app = express();
app.use(session({
secret: 'DFGDFG',
resave: false,
saveUninitialized:false,
genid:function(req){
return crypto.createHash('sha256').update(uuid.v1()).update(crypto.randomBytes(256)).digest("hex");
},
}));
app.post('/login', (request,response)=> {
var post_data = request.body;
request.session.user = post_data.user;
request.session.password = post_data.password;
if(err){
console.log("error");
}
else{
var db= client.db('test');
db.collection('object').findOne({'user':request.session.user}, function(error,user){
if(user.password == request.session.password){
request.session.amount = user.amount; // if password was correct, sending amount account
console.log('Success');
res.send(request.session.amount);
}
else{
console.log('Password invalid');
}
}
});
I am very new to webrtc and coding, so apologies if this is not a clear question.
I have followed the Shane Tully example here and amended it to run on my AWS server. Its running find but it only allows me one connection at a time. I would like to have users enter my URL followed by a room name in order to connect to a room.
e.g. www.myurl.com/apple where apple is the room that will be created. Here is an example - if you add /apppl at the end of this URL it will create a room. (The code for this example is rather complex and uses socket.io. where I use ws for Node to create the websockets)
Does anyone have any advice on this? My overall aim is to create an Android App which incorporates video calling functionality, and uses WebView to display the calling feature, which is why I need different URLs for each pair of devices so they both access the same room.
Thank you in advance!
Claire
Server Code:
const HTTPS_PORT = 443;
const fs = require('fs');
const https = require('https');
const WebSocket = require('ws');
const WebSocketServer = WebSocket.Server;
const serverConfig = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem'),
};
// ----------------------------------------------------------------------------------------
// Create a server for the client html page
var handleRequest = function(request, response) {
// Render the single client html file for any request the HTTP server receives
console.log('request received: ' + request.url);
if(request.url === '/') {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(fs.readFileSync('client/index.html'));
} else if(request.url === '/webrtc.js') {
response.writeHead(200, {'Content-Type': 'application/javascript'});
response.end(fs.readFileSync('client/webrtc.js'));
}
};
var httpsServer = https.createServer(serverConfig, handleRequest);
httpsServer.listen(HTTPS_PORT, '0.0.0.0');
// ----------------------------------------------------------------------------------------
// Create a server for handling websocket calls
var wss = new WebSocketServer({server: httpsServer});
wss.on('connection', function(ws) {
ws.on('message', function(message) {
// Broadcast any received message to all clients
console.log('received: %s', message);
wss.broadcast(message);
});
});
wss.broadcast = function(data) {
this.clients.forEach(function(client) {
if(client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
};
console.log('Server running. Visit https://localhost:' + HTTPS_PORT + ' in Firefox/Chrome (note the HTTPS; there is no HTTP -> HTTPS redirect!)');
//console.log("TEST TEST TEST" + JSON.stringify(room));
Client Code:
var localVideo;
var remoteVideo;
var peerConnection;
var uuid;
var constraints = {
video: true,
audio: true,
};
var peerConnectionConfig = {
'iceServers': [
{'urls': 'stun:stun.services.mozilla.com'},
{'urls': 'stun:stun.l.google.com:19302'},
]
};
function pageReady() {
uuid = uuid();
localVideo = document.getElementById('localVideo');
remoteVideo = document.getElementById('remoteVideo');
serverConnection = new WebSocket('wss://' + window.location.hostname + ':443');
serverConnection.onmessage = gotMessageFromServer;
if(navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(constraints).then(getUserMediaSuccess).catch(errorHandler);
} else {
alert('Your browser does not support getUserMedia API');
}
}
//CB if it is possible to run gerUserMedia then gets the local video stream
function getUserMediaSuccess(stream) {
localStream = stream;
localVideo.src = window.URL.createObjectURL(stream); //Depreciated
//localVideo.srcObject = stream;
}
//CB this function starts the call
function start(isCaller) {
peerConnection = new RTCPeerConnection(peerConnectionConfig);
peerConnection.onicecandidate = gotIceCandidate;
peerConnection.onaddstream = gotRemoteStream;
//peerConnection.ontrack = gotRemoteStream;
peerConnection.addStream(localStream);
if(isCaller) {
peerConnection.createOffer().then(createdDescription).catch(errorHandler);
}
}
function gotMessageFromServer(message) {
if(!peerConnection) start(false);
var signal = JSON.parse(message.data);
// Ignore messages from ourself
if(signal.uuid == uuid) return;
if(signal.sdp) {
peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp)).then(function() {
// Only create answers in response to offers
if(signal.sdp.type == 'offer') {
peerConnection.createAnswer().then(createdDescription).catch(errorHandler);
}
}).catch(errorHandler);
} else if(signal.ice) {
peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
}
}
function gotIceCandidate(event) {
if(event.candidate != null) {
serverConnection.send(JSON.stringify({'ice': event.candidate, 'uuid': uuid}));
}
}
function createdDescription(description) {
console.log('got description');
peerConnection.setLocalDescription(description).then(function() {
serverConnection.send(JSON.stringify({'sdp': peerConnection.localDescription, 'uuid': uuid}));
}).catch(errorHandler);
}
function gotRemoteStream(event) {
console.log('got remote stream');
remoteVideo.src = window.URL.createObjectURL(event.stream);
//remoteVideo.src = event.stream;
}
function errorHandler(error) {
console.log(error);
}
// Taken from http://stackoverflow.com/a/105074/515584
// Strictly speaking, it's not a real UUID, but it gets the job done here
function uuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
You need to change the server's code in the example. Right now it is just broadcasting all the messages to all other clients. What you need to do is right a logic at server side to send messages to only those clients with same room id.
I have written a webRTC based p2p scalable broadcast following Shane Tully's example. Click here to see
You can follow from here and get an idea on what i mean by sending signalling messages to specific clients only. In your case message broadcasting should occur only for those clients having the same room id. I hope this helps !!
What would be best way to measure data usage in Android Xamarin app in Visual Studio?
I would like to know, how much data was transferred for each called request.
I was looking in Xamarin Profiler but there isn't any info about data usage.
Thanks.
One approach that you could use is via Android Device Monitor to watch network traffic
Alternatively you could wrap your request if you are using HttpClient in a custom handler and log the size of the request payload:
public class RequestLoggerHandler : HttpClientHandler
{
#if DEBUG
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var stopwatch = Stopwatch.StartNew();
HttpResponseMessage response = null;
var headers = request.Headers;
var responseString = string.Empty;
var requestString = string.Empty;
var outputStringBuilder = new StringBuilder();
const string LINE_ENDING = "===================================================================================================";
const string SECTION_ENDING = "---------------------------------------------------------------------------------------------------";
try
{
if (request.Content != null) requestString = await request.Content?.ReadAsStringAsync();
response = await base.SendAsync(request, cancellationToken);
responseString = await response.Content?.ReadAsStringAsync();
outputStringBuilder.AppendLine(LINE_ENDING);
// Headers
outputStringBuilder.AppendLine("REQUEST HEADERS:");
foreach (var header in headers)
outputStringBuilder.AppendLine($"HEADER: {header.Key}: {header.Value?.ToList()?.FirstOrDefault()}");
outputStringBuilder.AppendLine(SECTION_ENDING);
// Parameters
outputStringBuilder.AppendLine("REQUEST PARAMS:");
outputStringBuilder.AppendLine(requestString);
outputStringBuilder.AppendLine(SECTION_ENDING);
// Response
outputStringBuilder.AppendLine("RESPONSE:");
outputStringBuilder.AppendLine(responseString);
outputStringBuilder.AppendLine(SECTION_ENDING);
return response;
}
finally
{
stopwatch.Stop();
var totalSize = 0L;
if (response != null)
{
var bodylength = response.Content.Headers.ContentLength;
var headerlength = response.Headers.ToString().Length;
totalSize = bodylength.GetValueOrDefault() + headerlength;
}
outputStringBuilder.AppendLine(string.Format("REQUEST [{0}:{1}] Time:{2}| Size:{3}| HTTP-CODE:{4}",
request.Method.ToString(),
request.RequestUri,
stopwatch.Elapsed.ToString("ss\\.fff"),
totalSize.ToPrettyByteSize(),
response?.StatusCode.ToString() ?? "No Internet Connectivity"));
outputStringBuilder.AppendLine(LINE_ENDING);
Debug.WriteLine("\n" + outputStringBuilder);
}
}
#endif
}
Then in your output window using VSColorOutput extension it produces a nice readable report of your request/response, including time and size. You can of cause simplify this code if all you are after is just the request/response size.