How to use Razorpay Orders API in Flutter? - flutter

I'm implementing a payment gateway in my flutter application. So Razorpay recommends me to use Orders API. But I don't get any ways to implement Orders API.
I had referred the below documentation. It contains examples for java, PHP, etc. But nothing found for Flutter / Dart.
https://razorpay.com/docs/payment-gateway/orders/integration/#example
Thanks in advance.

Future<void> generate_ODID() async {
var orderOptions = {
'amount': 50000, // amount in the smallest currency unit
'currency': "INR",
'receipt': "order_rcptid_11"
};
final client = HttpClient();
final request =
await client.postUrl(Uri.parse('https://api.razorpay.com/v1/orders'));
request.headers.set(
HttpHeaders.contentTypeHeader, "application/json; charset=UTF-8");
String basicAuth = 'Basic ' +
base64Encode(utf8.encode(
'${'YourKEY'}:${'YourSECRET'}'));
request.headers.set(HttpHeaders.authorizationHeader, basicAuth);
request.add(utf8.encode(json.encode(orderOptions)));
final response = await request.close();
response.transform(utf8.decoder).listen((contents) {
print('ORDERID'+contents);
String orderId = contents.split(',')[0].split(":")[1];
orderId = orderId.substring(1, orderId.length - 1);
Fluttertoast.showToast(
msg: "ORDERID: " +orderId,
toastLength: Toast.LENGTH_SHORT);
Map<String, dynamic> checkoutOptions = {
'key': 'YourKEY',
'amount': 11100,
'name': 'Demo',
'description': 'Fssai Registrtion Charge',
'prefill': {'contact': '8910407549', 'email': 'xx.xx#gmail.com'},
'external': {
'wallets': ['paytm']
}
};
try {
_razorpay.open(checkoutOptions);
} catch (e) {
print(e.toString());
}
});
}
I am using this same code snippet but when I am trying to do payments with google pay then it will fail with "Your money is not debited, Your server is busy" Error, but when I try to do with providing UPI Id manually then the transaction goes smoothly, otherwise transactions not done using UPI. Is there any way to solve this?

final client = HttpClient();
final request =
await client.postUrl(Uri.parse('https://api.razorpay.com/v1/orders'));
request.headers.set(
HttpHeaders.contentTypeHeader, "application/json; charset=UTF-8");
String basicAuth = 'Basic ' +
base64Encode(utf8.encode(
'${dotenv.env['RAZORPAY_KEY']!}:${dotenv.env['RAZORPAY_SECRET']!}'));
request.headers.set(HttpHeaders.authorizationHeader, basicAuth);
request.add(utf8.encode(json.encode(orderOptions)));
final response = await request.close();
response.transform(utf8.decoder).listen((contents) {
String orderId = contents.split(',')[0].split(":")[1];
orderId = orderId.substring(1, orderId.length - 1);
Map<String, dynamic> checkoutOptions = {
'key': dotenv.env['RAZORPAY_KEY']!,
'amount': total * 100,
"currency": "INR",
'name': 'E Drives',
'description': 'E Bike',
'order_id': orderId, // Generate order_id using Orders API
'timeout': 300,
};
try {
_razorpay.open(checkoutOptions);
} catch (e) {
log.e(e.toString());
}
You can use HttpClient and send a request to the Razorpay Orders API.
Hope this answers your question.

Thankfully, Razorpay has Flutter package which you can use. The following code snippet might help :
import 'package:razorpay_flutter/razorpay_flutter.dart';
_razorpay = Razorpay();
var options = {
'key': '<YOUR_KEY_ID>',
'amount': 100, //in the smallest currency sub-unit.
'name': 'Acme Corp.',
'order_id': 'order_EMBFqjDHEEn80l', // Generate order_id using Orders API
'description': 'Fine T-Shirt',
'prefill': {
'contact': '9123456789',
'email': 'gaurav.kumar#example.com'
}
};
_razorpay.open(options);
Please go through this page for further details. And this YouTube video will help as well.

You can use the Below code. it's working as expected.
createOrderId(amount, description, id, userId) async {
final int Amount = int.parse(amount) * 100;
http.Response response = await http.post(
Uri.parse(
"https://api.razorpay.com/v1/orders",
),
headers: {
"Content-Type": "application/json",
"Authorization":
"Basic ${base64Encode(utf8.encode('testKey:secreateKey'))} "
},
body: json.encode({
"amount": Amount,
"currency": "INR",
"receipt": "OrderId_$id",
"notes": {"userId": "$userId", "packageId": "$id"},
}));
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
openCheckout(amount, description, id, userId, data["id"]);
}
print(response.body);
}
void openCheckout(amount, description, id, userId, String orderId) async {
final int Amount = int.parse(amount) * 100;
var options = {
'key': 'testkey',
'amount': Amount,
'name': 'Name',
'description': description,
'order_id': orderId,
// "prefill": {
// "name": name,
// "email": emails,
// },
"notes": {"userId": "$userId", "packageId": "$id"},
'external': {
'wallets': ['paytm']
}
};
try {
_razorpay.open(options);
} catch (e) {
debugPrint('Error: e');
}
}

Might be helpful for someone.
Hope you set up all the necessary things.
Step 1: creating Order using Razorpay official Order Api:
//* create order##############################################################
void createOrder() async {
String username = 'xxxxxxxxxx';// razorpay pay key
String password = "xxxxxxxxxxxxxxxx";// razoepay secret key
String basicAuth =
'Basic ${base64Encode(utf8.encode('$username:$password'))}';
Map<String, dynamic> body = {
"amount": 1 * 100,
"currency": "INR",
"receipt": "rcptid_11"
};
var res = await http.post(
Uri.https(
"api.razorpay.com", "v1/orders"), //https://api.razorpay.com/v1/orders // Api provided by Razorpay Official 💙
headers: <String, String>{
"Content-Type": "application/json",
'authorization': basicAuth,
},
body: jsonEncode(body),
);
if (res.statusCode == 200) {
openCheckout(jsonDecode(res.body)['id']); // 😎🔥
}
print(res.body);
}
//*#################################################################
Step 2: Open Razorpay checkout interface.
After getting orderId from Razorpay official Api, pass the id when calling openCheckout(jsonDecode(res.body)['id']); function
void openCheckout(String orderId) async {
var options = {
'key': 'xxxxxxxxxxxxxxxx',
"amount": 1 * 100,
'order_id': orderId,
'name': 'main.co.in',
// 'prefill': {'contact': '', 'email': 'test#razorpay.com'},
'external': {
'wallets': ['paytm']
}
};
try {
razorpay.open(options);
} catch (e) {
debugPrint('Error: e');
}
}
3rd Step: Signature verification.
This is important if you automatically wanna transfer your amount to your bank account.
for Hmac SHA key , install this package: crypto:
handlerPaymentSuccess(PaymentSuccessResponse response) {
final key = utf8.encode('NgDLPyiDRPuQpcXy1E3GKTDv');
final bytes = utf8.encode('${response.orderId}|${response.paymentId}');
final hmacSha256 = Hmac(sha256, key);
final generatedSignature = hmacSha256.convert(bytes);
if (generatedSignature.toString() == response.signature) {
log("Payment was successful!");
//Handle what to do after a successful payment.
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("Success : payment successful"),
// content: const Text("Are you sure you wish to delete this item?"),
actions: <Widget>[
ElevatedButton(
onPressed: () {
Navigator.of(context).pop(true);
// PlaceOrderPrepaid();
},
child: Text("OK"))
// ),
],
);
},
);
} else {
log("The payment was unauthentic!");
}
}
Thats it!

Related

non-local notification using workManager flutter

i tried to send notification to another device when the app is terminated using workManager
it does not work, however the same function works if i use it without workManager
here is the code
in the main
await Workmanager().initialize(callBAckDispatcher, isInDebugMode: true);
callBackDispathcer
callBAckDispatcher() {
WidgetsFlutterBinding.ensureInitialized();
Firebase.initializeApp();
Workmanager().executeTask((taskName, inputData) async {
if (taskName == "t") {
int id = 7
await sFunction(id, await returnUserName());
}
return Future.value(true);
});
}
sFunction
sFunction(int id, String sender) async {
List<Map> response =
await SQLdb().readData('''SELECT * FROM `timer_chat` WHERE id = $id
''');
String reciever = response[0]['reciever'];
String message = response[0]['message'];
try {
String currentToken = await auth.getusertoken(reciever);
auth.sendnotify("my app",
"your message has been sent: " + message, "1", currentToken);
} catch (e) {
print("notification did not send: " + e.toString());
}
}
finally sendnotify
sendnotify(String title, String body, String id, String token) async {
try {
await http.post(
Uri.parse("https://fcm.googleapis.com/fcm/send"),
headers: <String, String>{
'content-type': 'application/json',
'Authorization': 'key=$serverToken',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{
'body': body.toString(),
'title': title.toString()
},
'priority': 'high',
'data': <String, dynamic>{
'click_action': "FLUTTER_NOTIFICATION_CLICK",
'id': id.toString(),
"name": "me",
"lastname": "wolf"
},
"to": token
},
),
);
} catch (e) {
print("something went wrong in notiiiii" + e.toString());
}
}
i'm sending notifications using firebase cloud messaging API. it worked fine inside the app but in workManager it does not. any idea why?
thank you

how can get paylod data when I using FCM in flutter?

how can get paylod data when I using FCM in flutter?
I tried used this methods, but I still could not got the data...
where has issues?
void getInitialMessage() async {
RemoteMessage? message =
await FirebaseMessaging.instance.getInitialMessage();
print(message?.data["type"]);
if (message != null) {
if (message.data["type"] == "noti") {
print("AAAAA");
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
PostDetailScreen(postid: message.data["postid"]),
),
);
} else if (message.data["type"] == "active") {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PostDetailScreen(postid: '456'),
),
);
}
}
}
When I go to postman to test, I will send this format
Future<void> sendPushMessage(String token, String body, String title,
String postid, String images) async {
try {
await http.post(
Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{
'Content-Type': 'application/json',
'Authorization':
'key=AAAAm2nkpqg:APA91bH9l8kYkJqGyGnVJhUe4dmG5KeYVrErEB_vl7vhZDGBAgFGOYsyHguDna-SBeP8juVoTtLQ61aI61QZ-46JFwaR-8KPai7CT6n4-jRZFBIMOHEl1Ph',
},
body: jsonEncode(
<String, dynamic>{
'notification': <String, dynamic>{'body': body, 'title': title},
'priority': 'high',
'timeToLive': 24 * 60 * 60,
'data': <String, dynamic>{
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
'id': '1',
'status': 'done',
'type': 'noti',
'postid': 'Mi6Y3sE9E0uz4uAvQjwC'
},
"to": token,
},
),
);
} catch (e) {
print("error push notification");
}
}
I can receive the Notification, but I have setting "type": "noti". So when I click the notification message, it shoule be print AAAAA and Navigator to PostDetailScreen. But It's always open app then go to homepage....
Send out FCM message with this structure, here I use NodeJS Firebase Cloud Function, but the important thing is to add the second, options part:
await admin.messaging().sendToDevice(tokens, {
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
type: 'noti',
postid: 'ulEdnFiEZxyyc33UNvJs'
},
notification: {
title: 'title',
body: 'body'
},
}, {
contentAvailable: true,
priority: 'high',
timeToLive: 24 * 60 * 60, // in seconds
});
After this, in getInitialMessage you should have:
message.data['type'] // 'noti'
message.data['postid'] // 'ulEdnFiEZxyyc33UNvJs'

The client_secret Provided does not match any associated PaymentIntent on this account

I'm trying to use flutter_stripe for a stripe connect account, But I always get the
same error: The client_secret provided doesn't match the client_secret associated with the PaymentIntend.
I've completed all steps according to flutter_stripe but I still face this error.
Below is my code Please check this and help me.
inde.js
const functions = require("firebase-functions");
const stripe = require("stripe")("secret_key");
exports.stripePaymentIntentRequest = functions.https.onRequest(async (req, res) => {
try {
let customerId;
//Gets the customer who's email id matches the one sent by the client
const customerList = await stripe.customers.list({
email: req.body.email,
limit: 1
});
//Checks the if the customer exists, if not creates a new customer
if (customerList.data.length !== 0) {
customerId = customerList.data[0].id;
}
else {
const customer = await stripe.customers.create({
email: req.body.email
});
customerId = customer.data.id;
}
//Creates a temporary secret key linked with the customer
const ephemeralKey = await stripe.ephemeralKeys.create(
{ customer: customerId },
{ apiVersion: '2020-08-27' }
);
//Creates a new payment intent with amount passed in from the client
const paymentIntent = await stripe.paymentIntents.create({
amount: parseInt(req.body.amount),
currency: 'usd',
customer: customerId,
})
res.status(200).send({
clientSecret: paymentIntent.client_secret,
paymentIntent: paymentIntent,
ephemeralKey: ephemeralKey.secret,
customer: customerId,
success: true,
})
} catch (error) {
res.status(404).send({ success: false, error: error.message })
}
});
PaymentService.dart
Future<void> initPaymentSheet(
{required BuildContext context, required String email, required int amount}) async {
try {
// 1. create payment intent on the server
final response = await http.post(
Uri.parse(
'Firebase api link of Functions'),
body: {
'email': email,
'amount': amount.toString(),
});
Map<String, dynamic> paymentIntentBody = jsonDecode(response.body);
log(paymentIntentBody.toString());
//2. initialize the payment sheet
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: paymentIntentBody["clientSecret"],
merchantDisplayName: 'Flutter Stripe Store Demo',
customerId: paymentIntentBody['customer'],
customerEphemeralKeySecret: paymentIntentBody['ephemeralKey'],
style: ThemeMode.light,
testEnv: true,
merchantCountryCode: 'US',
),
);
await Stripe.instance.presentPaymentSheet();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Payment completed!')),
);
} catch (e) {
if (e is StripeException) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Error from Stripe: ${e.error.localizedMessage}'),
),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error the Stripe of : $e')),
);
}
}
}
The log error print on my console is :
> [log] {paymentIntent:
> pi_3LI2acCTAUDjRNFV1Ra3dahz_secret_Fcqw73pWrE4avKRyuDVzRBitG,
> ephemeralKey:
> ek_test_YWNjdF8xSlQ3amtDVEFVRGpSTkZWLDl1OE5Vdm1jTGY4T1RpaVhHOTB3NTRVSkQ5UGl4azA_00j32OYG9n,
> customer: cus_LHG2YpQP9Cgwuy, success: true}
The following code is from a previous Stripe evaluation stage. But it worked. Slim it down to your needs.
Remember to publish your secret key to the server, so the server can talk to Stripe.
code.dart
Future<bool> payWithPaymentSheet(
ProductModel productModel, PriceModel priceModel,
{String merchantCountryCode = 'DE'}) async {
if (kIsWeb) {
throw 'Implementation not availabe on Flutter-WEB!';
}
String uid = AuthService.instance.currentUser().uid;
String email = AuthService.instance.currentUser().email ?? '';
HttpsCallableResult response;
try {
response = await FirebaseFunctions
.httpsCallable('createPaymentIntent')
.call(<String, dynamic>{
'amount': priceModel.unitAmount,
'currency': priceModel.currency,
'receipt_email': email,
'metadata': {
'product_id': productModel.id,
'user_id': uid,
"valid_until": productModel.getUntilDateTime().toIso8601String(),
'product_name': productModel.name.tr,
},
'testEnv': kDebugMode,
});
} on FirebaseFunctionsException catch (error) {
log(error.code);
log(error.details);
log(error.message ?? '(no message)');
Get.snackbar(
error.code,
error.message ?? '(no message)',
icon: const Icon(Icons.error_outline),
);
return false;
}
Map<String, dynamic> paymentIntentBody = response.data;
await Stripe.instance.initPaymentSheet(
paymentSheetParameters: SetupPaymentSheetParameters(
paymentIntentClientSecret: paymentIntentBody["clientSecret"],
currencyCode: priceModel.currency,
applePay: false,
googlePay: false,
merchantCountryCode: merchantCountryCode,
merchantDisplayName: Strings.appName,
testEnv: kDebugMode,
customerId: paymentIntentBody['customer'],
customerEphemeralKeySecret: paymentIntentBody['ephemeralKey'],
));
try {
await Stripe.instance.presentPaymentSheet();
return true;
} on StripeException catch (e) {
log(e.error.code.name);
log(e.error.message ?? '(no message)');
log(e.error.localizedMessage ?? '(no message)');
Get.snackbar(e.error.code.name, e.error.message ?? '',
icon: const Icon(Icons.error_outline));
} catch (e) {
Get.snackbar('An unforseen error occured', e.toString(),
icon: const Icon(Icons.error_outline));
}
return false;
}
index.ts
// SETTING SECRET KEY ON SERVER:
// cd functions
// firebase functions:config:set stripe.secret_key="sk_live_51L...Noe"
// firebase deploy --only functions
let stripe = require("stripe")(functions.config().stripe.secret_key);
exports.createPaymentIntent = functions
.https.onCall((data, context) => {
// if (!context.auth) {
// return { "access": false };
// }
return new Promise(function (resolve, reject) {
stripe.paymentIntents.create({
amount: data.amount,
currency: data.currency,
receipt_email: decodeURIComponent(data.receipt_email),
metadata: data.metadata,
}, function (err, paymentIntent) {
if (err != null) {
functions.logger.error("Error paymentIntent: ", err);
reject(err);
}
else {
resolve({
clientSecret: paymentIntent.client_secret,
paymentIntentData: paymentIntent,
});
}
});
});
});

Digest Authentication not working with HttpClient

I have used all approaches to Post data using digest authentication but it is not working?
HttpClient authenticatingClient = HttpClient(); authenticatingClient.addCredentials( Uri.parse( 'http://202.142.0000', ), 'aa',=>realm HttpClientDigestCredentials('admin', 'admin'), ); clients = https.IOClient(authenticatingClient); clients .post( Uri.parse( 'http://202.142.0000', ), headers: {'Content-Type': 'application/json'}, body: json.encode({ "Protocol": "a[enter image description here][1]", "Packets": [ { "Id": 1, "Type": "PumpGetStatus", "Data": {"Pump": 1} } ] }), ) .then((value) { print(value.headers); });
Try this code and report the results.
You'll be aiming for the code shown in main (which uses pre-authentication, as long as you know the realm in advance). Somehow, I'm guessing that aa isn't the valid realm.
The code in main2 can be substituted temporarily. Even though it will definitely fail, it will print out the realm, etc. to confirm the true values.
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as ioc;
void main() async {
final postMap = {
'Protocol': 'o',
'Packets': [
{
'Id': 1,
'Type': 'PumpGetStatus',
'Data': {'Pump': 1}
}
]
};
final uri = Uri.parse('http://202.142.x.x');
final authenticatingClient = HttpClient();
authenticatingClient.addCredentials(
uri,
'aa', // is this actually the realm, or is it a guess?
HttpClientDigestCredentials('admin', 'admin'),
);
http.Client client = ioc.IOClient(authenticatingClient);
final response = await client.post(
uri,
headers: {'Content-Type': 'application/json'},
body: json.encode(postMap),
);
print(response.statusCode);
print(response.body);
client.close();
}
void main2() async {
final postMap = {
'Protocol': 'o',
'Packets': [
{
'Id': 1,
'Type': 'PumpGetStatus',
'Data': {'Pump': 1}
}
]
};
final uri = Uri.parse('http://202.142.x.x');
final authenticatingClient = HttpClient();
authenticatingClient.authenticate = ((u, s, r) async {
print('uri=$u scheme=$s realm=$r');
return false;
});
http.Client client = ioc.IOClient(authenticatingClient);
final response = await client.post(
uri,
headers: {'Content-Type': 'application/json'},
body: json.encode(postMap),
);
print(response.statusCode);
print(response.body);
client.close();
}

How to create customer in stripe payment gateway flutter?

I am using stripe sdk for payment and trying to create customer in that ,
static Future<Map<String, dynamic>> createcustomer() async {
try {
var body = {
'name': 'Jenny Rosen',
'address': {
'line1': '510 Townsend St',
'postal_code': '98140',
'city': 'San Francisco',
'state': 'CA',
'country': 'US',
}
};
var response = await http.post(
'https://api.stripe.com/v1/customers',
body: json.encode(body),
headers: StripeService.headers
);
print('resvfdg: ${jsonDecode(response.body)}');
return jsonDecode(response.body);
} catch (err) {
print('err charging user: ${err.toString()}');
}
return null;
}
i am getting the error code: parameter_unknown,message: Received unknown parameter ,
how to create customer in stripe ?? or what i am missing in this ?
i don't know how to apply this and i need to create customer for doing international payment outside india , if i done payment in "INR" it will working properly , but for any other currency they asked for name and address.
I'm using Dio, this code is working for me:
static Future<Map<String, dynamic>> createcustomer() async {
try {
var data = {
'name': 'Jenny Rosen',
'address': {
'line1': '510 Townsend St',
'postal_code': '98140',
'city': 'San Francisco',
'state': 'CA',
'country': 'US',
}
};
Response response = await Dio().post('https://api.stripe.com/v1/customers',
data: data,
options: Options(contentType:Headers.formUrlEncodedContentType,
headers: {
'Authorization': 'Bearer ${secret}', // your secret key
}
),
);
print('response: ${jsonDecode(response.data)}');
return jsonDecode(response.data);
} catch (err) {
print('err charging user: ${err.toString()}');
}
return null;
}
I have used this api is working fine but response is paramter unknown
{error: {code: parameter_unknown, doc_url: https://stripe.com/docs/error-codes/parameter-unknown, message: Received unknown parameter: {"address":"sss","email":"aryan#gmail.com","name":"aryan","phone":"953667"}, param: {"address":"sss","email":"aryan#gmail.com","name":"aryan","phone":"953667"}, type: invalid_request_error}}
Flutter Code
Future createcustomer() async {
try {
var body = {
"address": "sss",
"email": "aryan#gmail.com",
"name": "aryan",
"phone": "95366710",
};
//final response = await http.post(Uri.parse("https://api.stripe.com/v1/customers"),
final response = await http.post(Uri.parse("https://api.stripe.com/v1/customers"),
headers: {
"Content-Type": "application/x-www-form-urlencoded","Authorization": "Bearer ${sKey}",
},
body: json.encode(body),
);
print('resvfdg: ${jsonDecode(response.body)}');
return jsonDecode(response.body);
} catch (err) {
print('err charging user: ${err.toString()}');
}
}