flutter - Connect user to stripe connect to allow him receiving money - Stack Overflow
I have a flutter app and I try to connect user to stripe connect so he is able to receive money and me to get 10 % of his sells but when I try to initiate the functionality I receive this error
`0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:646:7)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18)
<asynchronous suspension>
#2 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:22:24)
<asynchronous suspension>
#3 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)
<asynchronous suspension>
#4 _PaymentMethodState._testFunction (package:influfit/PaymentMethod.dart:122:22)
<asynchronous suspension>
flutter: Stack trace: #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:646:7)
#1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18)
<asynchronous suspension>
#2 MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:22:24)
<asynchronous suspension>
#3 HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)
<asynchronous suspension>
#4 _PaymentMethodState._testFunction (package:influfit/PaymentMethod.dart:122:22)
<asynchronous suspension>
flutter: Starting Stripe account creation for user: 8k4b52239lRqFlunTHQuWkO9ZfS2
flutter: User email: [email protected]
flutter: Firebase Functions Error - Code: -1004, Message: Could not connect to the server., Details: null
`
This is the code that I am using to do this and this is the index.js with cloud functionalities I use ... can someone recommend what to do or another option?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_functions/cloud_functions.dart';
class PaymentMethod extends StatefulWidget {
@override
_PaymentMethodState createState() => _PaymentMethodState();
}
class _PaymentMethodState extends State<PaymentMethod> {
bool _isLoading = false;
String? _error;
String? _stripeStatus;
User? _currentUser;
late FirebaseFunctions functions;
@override
void initState() {
super.initState();
// Initialize Firebase Functions with region
functions = FirebaseFunctions.instanceFor(region: 'us-central1');
_initializeAuth();
}
Future<void> _initializeAuth() async {
// Listen to auth state changes
FirebaseAuth.instance.authStateChanges().listen((User? user) {
setState(() {
_currentUser = user;
});
if (user != null) {
_checkStripeStatus();
}
});
}
Future<void> _checkStripeStatus() async {
try {
final result = await functions.httpsCallable('checkStripeAccount').call();
if (result.data['accountId'] != null) {
setState(() {
_stripeStatus = 'Connected to Stripe';
});
}
} catch (e) {
print('Error checking Stripe status: $e');
}
}
Future<void> _createStripeAccount() async {
if (!mounted) return;
setState(() {
_isLoading = true;
_error = null;
});
try {
final user = FirebaseAuth.instance.currentUser;
if (user == null) {
throw Exception('User not logged in');
}
// Get fresh ID token
await user.getIdToken(true);
print('Starting Stripe account creation for user: ${user.uid}');
print('User email: ${user.email}');
final result = await functions.httpsCallable(
'createStripeAccount',
options: HttpsCallableOptions(
timeout: const Duration(seconds: 60),
),
).call({
'email': user.email,
'userId': user.uid,
});
print('Raw response: ${result.data}');
if (result.data['success'] == true && result.data['accountLink'] != null) {
final accountLink = result.data['accountLink'];
print('Account link received: $accountLink');
setState(() {
_stripeStatus = 'Stripe account created successfully';
});
}
} on FirebaseFunctionsException catch (e) {
print('Firebase Functions Error - Code: ${e.code}, Message: ${e.message}, Details: ${e.details}');
setState(() {
_error = 'Error: ${e.message}';
});
} catch (e, stackTrace) {
print('Error creating Stripe account: $e');
print('Stack trace: $stackTrace');
setState(() {
_error = 'Error: ${e.toString()}';
});
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
}
Future<void> _testFunction() async {
try {
final user = FirebaseAuth.instance.currentUser;
if (user == null) {
print('No user logged in');
return;
}
// Get fresh ID token
final idToken = await user.getIdToken(true);
print('Got fresh ID token');
final result = await functions.httpsCallable('testFunction').call({
'test': 'data',
'userId': user.uid,
});
print('Test function response: ${result.data}');
} catch (e, stack) {
print('Test function error: $e');
print('Stack trace: $stack');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Colors.black),
title: Text(
'Payment Method',
style: TextStyle(
color: Colors.black,
fontFamily: 'Montserrat',
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
elevation: 0,
),
body: _currentUser == null
? Center(
child: Text('Please log in to continue'),
)
: Container(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: _testFunction,
child: Text('Test Firebase Function'),
),
SizedBox(height: 16),
Text(
'Stripe Connect Account',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'Montserrat',
),
),
SizedBox(height: 16),
if (_stripeStatus != null)
Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.green.shade50,
borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Icon(Icons.check_circle, color: Colors.green),
SizedBox(width: 8),
Text(
_stripeStatus!,
style: TextStyle(
color: Colors.green,
fontFamily: 'Montserrat',
),
),
],
),
)
else
Text(
'Connect your bank account to receive payments',
style: TextStyle(fontFamily: 'Montserrat'),
),
SizedBox(height: 16),
if (_error != null)
Container(
padding: EdgeInsets.all(8),
margin: EdgeInsets.only(bottom: 16),
color: Colors.red.shade100,
child: Text(
_error!,
style: TextStyle(
color: Colors.red,
fontFamily: 'Montserrat',
),
),
),
if (_isLoading)
Center(child: CircularProgressIndicator())
else if (_stripeStatus == null)
ElevatedButton(
onPressed: _createStripeAccount,
child: Text('Connect with Stripe'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
padding: EdgeInsets.symmetric(
horizontal: 32,
vertical: 12,
),
),
),
],
),
),
);
}
}
and my index.js file :
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const stripe = require('stripe')(functions.config().stripe.secret);
admin.initializeApp();
// Check if user has a Stripe account
exports.checkStripeAccount = functions.https.onCall(async (data, context) => {
if (!context.auth) {
throw new functions.https.HttpsError('unauthenticated', 'User must be logged in');
}
try {
const userId = context.auth.uid;
const userDoc = await admin.firestore()
.collection('users')
.doc(userId)
.get();
const stripeAccountId = userDoc.data()?.stripeAccountId;
if (stripeAccountId) {
const account = await stripe.accounts.retrieve(stripeAccountId);
return { accountId: account.id };
}
return { accountId: null };
} catch (error) {
console.error("Error checking Stripe account:", error);
throw new functions.https.HttpsError('internal', error.message);
}
});
// Create Stripe Connect account
exports.createStripeAccount = functions.https.onCall(async (data, context) => {
try {
if (!context.auth) {
throw new functions.https.HttpsError('unauthenticated', 'Must be logged in');
}
const userId = context.auth.uid;
const userEmail = data.email;
if (!userEmail) {
throw new functions.https.HttpsError('invalid-argument', 'Email is required');
}
// Create Stripe account
const account = await stripe.accounts.create({
type: 'express',
email: userEmail,
capabilities: {
card_payments: {requested: true},
transfers: {requested: true},
},
});
// Save to Firestore
await admin.firestore()
.collection('users')
.doc(userId)
.set({
stripeAccountId: account.id,
stripeAccountCreatedAt: admin.firestore.FieldValue.serverTimestamp(),
}, { merge: true });
// Create account link
const accountLink = await stripe.accountLinks.create({
account: account.id,
refresh_url: `/stripe/refresh`,
return_url: `/stripe/success`,
type: 'account_onboarding',
});
return {
success: true,
accountId: account.id,
accountLink: accountLink.url
};
} catch (error) {
console.error("Error creating Stripe account:", error);
throw new functions.https.HttpsError('internal', error.message);
}
});
最新文章
- 一晃三十年 回顾改变世界的那些Windows
- Google的AR眼镜
- 微软反攻打响跨界战争:Win8移动领域伸橄榄枝
- powershell - Windows AutoPilot - Set Auto Login - Stack Overflow
- schema - TALLY XML API ISSUE - Stack Overflow
- python - Deploy Flask, Pyspark code in azure app service - Stack Overflow
- spi - Interrupt safety of `HAL_SPI_TransmitReceive` - Stack Overflow
- anova - Conducting a repeated-measures ANCOVA in R -- utterly lost - Stack Overflow
- powerbi - I have two table Fact table and Dimention table and I am trying to calculate Past year sales .Value its not working -
- ios - AccessorySetupKit picker doesn't show accessory unless previously paired in Setting app first - Stack Overflow
- Error installing pip packages due to error in launcher and wrong python version - Stack Overflow
- reactjs - how to fetch headers in middleware in Next js - Stack Overflow
- javascript - MineFlayer bot Error: read ECONNRESET as I was trying to log it in to my server - Stack Overflow
- reactjs - why react dev tools paint highlights to components in this example - Stack Overflow
- c - What happens if you call free() on non allocated memory returned by a function - Stack Overflow
- javascript - Firebase Auth link - Problem with the Google login, no possibility to change to own project name - Stack Overflow
- tsx - Does Inversify actually require emitDecoratorMetadata for Typescript? - Stack Overflow