I have tried different ways to handle payment via no webhook flow, but the only solution is to call stripe API directly from my dart code as follows:
var response = await http.post(
Uri.parse('https://api.stripe.com/v1/payment_intents'),
body: {
'amount': _calculateAmount(amount),
'currency': currency,
'payment_method_types[]': 'card',
'description': description,
'receipt_email': email,
},
headers: {
'Authorization': 'Bearer ${AppConfig.instance.stripeSecretKey}',
'Content-Type': 'application/x-www-form-urlencoded'
},
);
is my code still PCI compliant and properly secured to use in production?
Your code is still PCI compliant, but not secure. Secret key must be stored securely in your web or mobile app’s server-side code (such as in an environment variable or credential management system). Calling from Dart means you are exposing your credential to the whole world. It's explained in Stripe Doc
Related
What is the best practice to post data to a server, currently my database is a PostgreSql.
I would be posting to a REST Api and I want to be safe, to post I was going to use a token to verify that they are from the app but then if someone decompiles the app they will see the verification token and could then post to the API
String token = esR3bJM9bPLJoLgTesR3bJM9bPLJoLgT;
String apiUserLikes = current_server_address + "/api/user-likes/?token=$token";
final response = await http.post(
Uri.parse(apiUserLikes?token=$token),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'userID': '1234567969855478',
'UserDisplayName': 'John Jones',
'liked': 'true',
'dateLiked': '2022/12/05 00:00:00',
'eventLiked': 'Music concert at The stadium',
}),
);
What is the best way to protect users details and still post to the server
Thanks
You could never verify that the user is from the app because he can send the same request with just the command line. Even with authentication, it is still impossible to confirm. The only way to make it safe is to validate the data sent and add restriction against abuse like how many times per minute an IP/user could send data or how much could it send/download.
Instead of using static token you can use OAuth2 compliant security mechanism where token expires and new refresh token is generated/issued,
You can use firebase Auth or something like to make your App Compliant with OAuth.
For firebase Auth you can check the following link:
https://firebase.google.com/docs/auth/
i wanna work with this api in my flutter app
https://dev.chargily.com/docs/epay-api/
i have done the first part 1.Make Payment
but the second part 2. Payment confirmation i don't know how to do it because it contain webhook
(i wanna get the response sent via webhook_url)
this is the first part 1. Make Payment
final response = await dio
.post(
'http://epay.chargily.com.dz/api/invoice',
options: Options(headers: {
'X-Authorization':
'["API-KEY"]',
'Accept': 'application/json',
}),
data: jsonEncode(params),
)
.then((value) async {
log(value.data['checkout_url']);
var url = await value.data['checkout_url'];
work perfectly
i need the second part 2. Payment confirmation
Webhooks are a fancy word to describe a server calling another server's Web Api Endpoint. so, it's not meant to be used in the frontend.
you can't verify / get payment confirmation directly from a flutter app, you have to host your own backend / serverless function to act as a webhook and report back to the frontend environment.
I doing a Flutter app and I using dio to connect app with my web service.
When I want to access to custom headers in response, on mobile I don't have any problem, but this headers on web not be available and get different.
My code:
final dio = Dio();
final response = await dio.getUri(requestUri,
options: Options(headers: {
'authorization': 'Bearer ${credentials!.accessToken}',
}));
How I do to on web and mobile get a same custom headers?
This is due to CORS, part of the browser built-in cross-site security restrictions. Your server need to include your custom headers into the "preflight" OPTIONS response header Access-Control-Expose-Headers to allow your browser to see those headers.
For example, https://discuss.istio.io/t/configuring-cors/7458/5
Noobish Dev here. I'm developing an app that involves processing payments between customers and a particular service, the app would take a fee and pay the service provider directly to their bank accounts. Looking for advice really or perhaps a better implementation.
Anyway, after watching some tutorials online I developed the app to use my own form to handle a customers card data and send directly to Stripes API with curl request. In this instance to attach the card to a customer account. I find that stripe requires the apps/websites be PCI compliant when handling data and to not use custom form handling for fear of retaining card data, that leaves me stuck as this particular method we use by directly interacting with the API (I'm using Dio) is not recommended by Stripe as advised below.
App screenshot :
The snippet of code (works fine by the way):
Future<void> addCard(
{int cardNumber,
int month,
int year,
int cvc,
String stripeId,
String userId,
String cardHolderName,
String email}) async {
Map body = {
"type": "card",
"card[number]": cardNumber,
"card[exp_month]": month,
"card[exp_year]": year,
"card[cvc]": cvc,
"billing_details[name]": cardHolderName,
"billing_details[email]": email
};
dynamic stripeResponse;
try {
print('Successfully added payment method id $paymentMethodUrl');
Dio dio = Dio();
await dio
.post(paymentMethodUrl,
data: body,
options: Options(
contentType: Headers.formUrlEncodedContentType,
headers: headers))
.then((response) {
print(response.data);
stripeResponse = response;
String paymentId = response.data['id'];
Map stripeCustomer = {"customer": UserData.stripeID};
try {
dio
.post('$paymentMethodUrl/$paymentId/attach',
data: stripeCustomer,
options: Options(
contentType: Headers.formUrlEncodedContentType,
headers: headers))
.then((response) {
print(response.data);
print('Attached successfully');
});
} on DioError catch (e) {
print('Error attaching card to customer: ${e.response.data['error']['message']}');
}
});
} on DioError catch (e) {
print(stripeResponse);
print('Error adding card: ${e.response.data['error']['message']}');
}
}
https://stripe.com/docs/security#pci-dss-guidelines
The easiest way to be PCI compliant is as advised by Stripe:
Use one of our recommended payments integrations to collect payment information, which is securely transmitted directly to Stripe without it passing through your servers
Serve your payment pages securely using Transport Layer Security (TLS) so that they make use of HTTPS
Anyway I would appreciate it if anyone could give me some advice on this or maybe I'm misunderstanding something when it comes to compliance. I might just instead use Apple pay and Google pay if this option is not viable as I don't want to get into trouble if I'm not PCI compliant due to handing card data.
Thanks in advance.
As stated in thisSO post:
The sensitive information governed by PCI (i.e. raw card data) is sent
directly from the client to Stripe. Stripe creates a Payment Method to
represent that data (pm_) and returns that to the client so it can be
referenced from there.
However, Payment Intents must be created server-side in a secure
context with a secret or restricted API key, then the Payment Intent's
client secret should be sent to the client to allow for client-side
confirmation.
The section about validating your PCI compliance in Stripe's integration security guide has more information.
And as mentioned in the comment, you can explore using the plugins to provide all the functions you need for your app. I suggest to look into this flutter_stripe which was published by flutterstripe.io. You can also check out this blog(https://flutterstripe.medium.com/announcing-the-flutter-sdk-for-stripe-1ba2b3ee667c) where it was mentioned about the security feature that the package could offer:
Secure by default
SCA-Ready: The SDK automatically performs native 3D Secure authentication if needed
to comply with Strong Customer
Authentication
regulation in Europe.
PCI compliant: as the plugin does not handle sensitive information (such as credit card credentials) the plugin is PCI
compliant by default. You can find out more about PCI compliance and
why it’s important here.
I am new in mobile development world and right now trying to understand few basic things.
I did a simple login nativescript app and from backend side did a login logic with mongoose (MongoDb) and express. But now I don't know how to proceed... How do I connect between backend and app?
Thank you in advance,
Emil
You need to expose an API from your backend, I'll assume you have done this (or can find this out - it's very well documented).
So from the client {N} you will need to access the API, calling whichever end-points you need. If you were using a JWT type approach, you should use the http module in nativescript, which might look something like this:
var http = require("http");
var result;
http.request({
url: "https://myBackend.org/api/post",
method: "POST",
headers: { "Content-Type": "application/json" },
content: JSON.stringify({ username: "ValueOne", password: "ValueTwo" })
}).then(function (response) {
result = response.content.toJSON();
console.log(result); //result.message would have the clients auth token
}, function (e) {
// console.log("Error occurred " + e);
});
You could then store the token (in persistent storage with the application-settings module) and add it to the header of any request to a different API endpoint to interact with your backend as an authenticated user.
Alternatively, you can use one of the cloud backend SDKs, e.g. Azure Mobile Services or Firebase which make your life much easier.