Reputation: 1484
So basically what i am trying to do is to let customers add credit cards for later use, what i did on flutter is:
StripePayment.setOptions(StripeOptions(
publishableKey: "MY_KEY_HERE"));
and added a button:
onPressed: () async {
dynamic value =
await StripePayment.paymentRequestWithCardForm(
CardFormPaymentRequest(),
).catchError(setError).then(
(PaymentMethod paymentMethod) async {
try {
addCreditCard(paymentMethod); // post request to laravel cashier api with the payment method
print("Payment Method ID: ${paymentMethod.id}");
} catch (e) {
print(e);
}
},
);
},
So what i did here is, the user is able to press a button, an input form pops up that includes all required card details with the stripe verification algorithm, and once everything is entered i will get a PaymentMethod object returned(which contains a token and last 4digits etc..) after that i sent this PaymentMethod object to laravel cashier api which contains this function:
public function create_card(Request $request)
{
$user = $request->user();
$user->addPaymentMethod($request->method); //Laravel billable cashier function
return response()->json([
'message' => 'Successfully updated credit card'
], 201);
}
I get a response of No such payment method, i am not sure how to continue from here since i can't find any documentation for this.. Any help would be great.
Laravel's cashier billable addPaymentMethod function:
public function addPaymentMethod($paymentMethod)
{
$this->assertCustomerExists();
$stripePaymentMethod = $this->resolveStripePaymentMethod($paymentMethod);
if ($stripePaymentMethod->customer !== $this->stripe_id) {
$stripePaymentMethod = $stripePaymentMethod->attach(
['customer' => $this->stripe_id], $this->stripeOptions()
);
}
return new PaymentMethod($this, $stripePaymentMethod);
}
Upvotes: 0
Views: 2162
Reputation: 336
For anyone still struggling with this issue, I finally found a working solution for adding a payment method.
My setup is this:
Laravel Framework 8.37.0
"laravel/cashier": "^12.12",
"laravel/sanctum": "^2.9",
Flutter (Channel stable, 2.0.5)
Dart 2.12.3
stripe_payment: ^1.0.11
Flutter side:
sample_view.dart
is the screen that holds a button that calls the Stripe method:
import 'package:my_sample_package/services/payment_services.dart';
import 'package:flutter/material.dart';
import 'package:stripe_payment/stripe_payment.dart';
class Subscribe extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: ElevatedButton(
child: Text("Add new Payment Method"),
onPressed: () {
StripeService.addNewPayment();
},
)
)
),
);
}
}
payment_services.dart
is the file that handles the Stripe and Api calls:
import 'dart:convert';
import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'package:stripe_payment/stripe_payment.dart';
class StripeService {
Dio dio = new Dio();
static Future<dynamic> addNewPayment() async {
StripePayment.setOptions(
StripeOptions(
publishableKey: "your_stripe_publishable_key",
merchantId: "Test",
androidPayMode: 'test'
)
);
Dio dio = new Dio(); // I'm using Dio instead of the http package
String baseUrl = 'http://192.168.1.122:8000/api/'; // Your host, I started mine using ## php artisan serve --host 192.168.1.122 --port 8000 ##
String token = 'my_laravel_access_token'; // This is the token I get from Laravel Sanctum
await StripePayment.paymentRequestWithCardForm(
CardFormPaymentRequest(), // This will show the Native Payment Card form
)
.then(
(PaymentMethod paymentMethod) async {
try {
inspect(paymentMethod);
final response = await dio.post(
baseUrl + "user/subscription/payment-method/update", // My Laravel endpoint for updating the payment method
options: Options(
headers: { 'Authorization': 'Bearer $token' },
),
data: {
"payment_method": paymentMethod
}
);
inspect(response);
} catch (e) {
inspect(e);
}
},
).onError((error, stackTrace) {
inspect(error);
});
}
}
Laravel Side:
routes/api.php
file to register the route we need:
...
Route::group(['prefix' => 'user', 'middleware' => ['auth:sanctum']], function () {
Route::post('subscription/payment-method/update', [UserController::class, 'updatePaymentMethod']);
});
...
Controllers/UserController.php
file to register our method:
public function updatePaymentMethod(Request $request): \Illuminate\Http\JsonResponse
{
$user = auth()->user();
$user->updateDefaultPaymentMethod($request->payment_method['id']); // You need to pass just the payment method ID, not the whole object
return response()->json([
'message' => 'Payment method saved'
], 200);
}
Upvotes: 0
Reputation: 85
Try removing "async" and print the paymentMethod to check if you're getting a payment method id or not:
StripePayment
.paymentRequestWithCardForm(CardFormPaymentRequest())
.then((paymentMethod) {
print(paymentMethod);
}).catchError((error)=>{print(error)});
Upvotes: 0