El Infierno de los Pub de PayPal en Flutter
Hablaré de los problemas que he tenido al intentar usar un plugin de PayPal para Flutter.
Hablaré de los problemas que he tenido al intentar usar un plugin de PayPal para Flutter.
Hace un tiempo había subido un video aquí en YouTube en la cual te hablaba sobre el infierno de los webview:
El Infierno de los WebView en Flutter
Pero te lo resumo rápidamente en caso que entres también aquí en contexto con lo que te voy a hablar la pesadilla era de que para cada sistema operativo para cada plataforma y también para cada operación es decir si quisieras ya sea ver contenido html mediante una URL es decir que le pruebes la URL y simplemente lo renderiza como si fuera un navegador o directamente tienes el código html y simplemente lo quieres representar era una pesadilla porque para Android iOS teníamos uno para Mac teníamos otros que no me funcionaba ninguno para Windows teníamos otro y así vamos por lo tanto a veces para renderizar simplemente unas como te digo ya sea una página html o directamente un contenido html era una pesadilla para todas las plataformas y tenía teniendo como cuatro y todavía tengo varios ahí por lo comentado pero parece que esas aguas nos traen otro problema
Es decir desde ahí venimos y es por eso que estoy haciendo la introducción a lo que era el webview tenemos la pesadilla o el infierno con los plugins o las extensiones para PayPal para Flutter en la cual tenemos una problemática similar y como te digo mencioné lo lo de los webview por el simplemente el hecho de que básicamente estos plugin funcionan de manera similar simplemente internamente instalan un bendito webview y a partir de ahí simplemente hacer el pago.
Este plugin al momento que digo estas palabras, hace que no levante la aplicación, debido a que su dependencia es muy antigua:
A problem occurred configuring project ':webview_flutter_x5'.
> Could not create an instance of type com.android.build.api.variant.impl.LibraryVariantBuilderImpl.
> Namespace not specified. Specify a namespace in the module's build file: /Users/andrescruz/.pub-cache/hosted/pub.dev/webview_flutter_x5-2.0.8+9/android/build.gradle. See https://d.android.com/r/tools/upgrade-assistant/set-namespace for information about setting the namespace.
Fíjate que si lo quito bueno primero voy a ver el error obviamente aquí puedes también ejecutar lo que es el Grande build de Android no lo va a hacer ahorita porque no quiero que tarde media hora el video pero ya ya yo se lo he hecho a lo que me refiero el error es por la dependencia del webview:
webview_flutter_x5
Por cierto ninguno de estos plugins son específicos de PayPal cosa que también a veces me da un poco de fastidio y también es los problemas que tenemos aquí en Flutter de que como es como quien dice tenemos desarrollo móvil y luego arriba tenemos Flutter en la pirámide entiéndase con desarrollo móvil como base de la pirámide sería scout o directamente Android Studio como que las empresas no se preocupan por colocar muchas de ellas me crear un plugin nativo para las plataformas que eso se agradecería muchísimo como hicieron en stripe aunque est TR es una pequeña pesadilla:
Para usar el plugin:
payPackWithPaypalPlugin(
String price, String tagPack, String userToken, BuildContext context,
[String coupon = '']) {
return UsePaypal(
sandboxMode: !appPayPalProduction,
clientId: paypalClientId,
secretKey: paypalSecret,
returnURL: "https://example.com/success",
cancelURL: "https://example.com/cancel",
transactions: [
{
"amount": {
"total": price,
"currency": "USD",
},
"description":
"${LocaleKeys.thankYouForPurchasingThisCourse.tr()}: $tagPack",
"item_list": {
"items": [
{
"name": tagPack,
"quantity": 1,
"price": price,
"currency": "USD"
}
],
}
}
],
note: "Contact us for any questions on your order.",
onSuccess: (Map params) {
print("onSuccess: $params");
},
onError: (error) {
print("onError: $error");
},
onCancel: (params) {
print('cancelled: $params');
});
}
Configurar el plugin porque tenemos que configurar al menos como cinco cosas pero esa es otra historia pero al menos lo hay aquí
Tenemos también este plugin que este me lo recomendó chtp que no lo encontraba por cierto y es un poco complicado aquí te lo voy a mostrar un poquito el código ya que bueno Provecho lo voy colocando por acá Este es el de flurer PayPal Fíjate que la integración es sencilla simplemente es una función aquí establecemos lo que es la cantidad y por lo demás aquí tenemos el de on success o on error o on cancel y ahí tú puedes hacer algo y es una pantalla como esta Fíjate que es una página web ahí tienes la URL aquí.
Este es el de PayPal sdk mientras tanto por cierto ya que quité este voy a ejecutarlo para ir ganando tiempo este es el otro PayPal sdk que también lo he estado utilizando pero es una pequeña pesadilla porque el chiste es que creas todo como si has tomado mi curso el Laravel básicamente aquí vas armando toda la orden de manera manual y a la final te da un bendito enlace para que tú lo lances otra vez venimos otra vez con la parte web no para que tú lo lances al navegador o hacia donde dios sabe tú quieras y por ahí procesa la orden:
// Crea la orden de PayPal y genera el enlace de pago
Future<Order?> createOrder(String amount) async {
// claves
var paypalEnvironment =
appPayPalProduction
? PayPalEnvironment.live(
clientId: paypalClientId,
clientSecret: paypalSecret,
)
: PayPalEnvironment.sandbox(
clientId: paypalClientId,
clientSecret: paypalSecret,
);
// client
var payPalHttpClient = PayPalHttpClient(
paypalEnvironment /*, accessToken: accessToken*/,
accessTokenUpdatedCallback: (accessToken) async {
// Persist token for re-use
},
);
// crea la ordenApi
final ordersApi = OrdersApi(payPalHttpClient);
try {
// orden
final orderRequest = OrderRequest(
intent: OrderRequestIntent.authorize,
purchaseUnits: [
PurchaseUnitRequest(
// amount: AmountWithBreakdown(currencyCode: "USD", value: "10.00"),
amount: AmountWithBreakdown(currencyCode: "USD", value: amount),
),
],
);
// creamos la orden
final order = await ordersApi.createOrder(orderRequest);
// link para procesar la orden
String? approveUrl =
order.links?.firstWhere((link) => link.rel == "approve").href;
// la orden fue creada exitosamente
if (approveUrl != null && approveUrl.isNotEmpty) {
await launchUrl(
Uri.parse(approveUrl),
mode: LaunchMode.externalApplication,
);
print("Respuesta de la orden: ${jsonEncode(order.toJson())}");
return order;
} else {
print("⚠ No se pudo obtener la URL de aprobación.");
}
} catch (e) {
print("Error al crear la orden: $e");
}
return null;
}
Entonces es una pesadilla porque obviamente ya cuando tú sales de la aplicación móvil y vas a una aplicación web es decir a otra aplicación ya directamente o mejor dicho cuando tú sales de aplicaciones en un en un teléfono Android o en cualquier dispositivo ya no tienes una forma directa de de saber cuándo va a terminar la operación entonces tú tienes que colocar aquí cuando regrese a la aplicación un botón o algo así eso fue lo que se me ocurrió para que sincronicen las operaciones por lo tanto no me gustó la implementación inclusive
Este otro plugin, tuve problemas antes en MacOS que al hacer el pago, me daba el error de:
Your PayPal credentials seems incorrect flutter_paypal_payment
Pero solamente en MacOS, al pasar el tiempo y al actualizar dependencias y Flutter, ya no aparece ese error, pero en el emulador la orden se queda procesando:
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => PaypalCheckoutView(
sandboxMode: true,
clientId: "",
secretKey: "",
transactions: const [
{
"amount": {
"total": '70',
"currency": "USD",
"details": {
"subtotal": '70',
"shipping": '0',
"shipping_discount": 0
}
},
"description": "The payment transaction description.",
// "payment_options": {
// "allowed_payment_method":
// "INSTANT_FUNDING_SOURCE"
// },
"item_list": {
"items": [
{
"name": "Apple",
"quantity": 4,
"price": '5',
"currency": "USD"
},
{
"name": "Pineapple",
"quantity": 5,
"price": '10',
"currency": "USD"
}
],
// shipping address is not required though
// "shipping_address": {
// "recipient_name": "tharwat",
// "line1": "Alexandria",
// "line2": "",
// "city": "Alexandria",
// "country_code": "EG",
// "postal_code": "21505",
// "phone": "+00000000",
// "state": "Alexandria"
// },
}
}
],
note: "Contact us for any questions on your order.",
onSuccess: (Map params) async {
print("onSuccess: $params");
},
onError: (error) {
print("onError: $error");
Navigator.pop(context);
},
onCancel: () {
print('cancelled:');
},
),
));
- Andrés Cruz
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter
Acepto recibir anuncios de interes sobre este Blog.
!Cursos desde!
4$
En Academia
Ver los cursos!Libros desde!
1$
Ver los libros