Saltar al contenido principal
Tutoriales

Pagos de Stripe en Capacitor: Nuevas directrices de Apple

Aprende a implementar enlaces de pago de Stripe en tu aplicación Capacitor para procesar pagos de bienes digitales de acuerdo con las nuevas directrices de Apple vigentes a partir del 1 de mayo de 2025.

Martin Donadieu

Martin Donadieu

Gerente de Contenido

Pagos de Stripe en Capacitor: Nuevas directrices de Apple

Implementar enlaces de pago de Stripe en aplicaciones Capacitor según nuevas directrices de Apple

A partir del 1 de mayo de 2025, Apple ha implementado cambios significativos en sus Directrices de revisión de la Tienda de aplicaciones siguiendo la sentencia del caso Epic v. AppleEstos cambios permiten específicamente a los desarrolladores de aplicaciones en los Estados Unidos enlazar con métodos de pago externos para bienes y servicios digitales, abriendo alternativas al sistema de compras en la aplicación de Apple.

La batalla épica que cambió los pagos móviles para siempre

El camino hacia este momento ha sido largo y controvertido. Todo comenzó en agosto de 2020 cuando Epic Games, el creador del juego popular Fortnite, violó deliberadamente las directrices de la Tienda de aplicaciones de Apple implementando una opción de pago directa que evitaba la comisión del 30% de Apple. Apple eliminó inmediatamente Fortnite de la Tienda de aplicaciones y Epic respondió presentando una demanda que cuestionaba el control de Apple sobre la distribución de aplicaciones iOS y los pagos en la aplicación.

Después de años de batallas legales, recursos y recursos contrarios, los tribunales finalmente dictaminaron que Apple debe permitir a los desarrolladores dirigir a los usuarios a métodos de pago alternativos fuera de sus aplicaciones. Esta decisión cambia fundamentalmente la economía del ecosistema de la Tienda de aplicaciones, que ha operado bajo el mismo modelo financiero básico desde su lanzamiento en 2008.

La sentencia final - Sin más recursos

What hace particularmente significativo en esta decisión es que es final y no puede ser apelada más. La Corte Suprema rechazó escuchar el recurso de Apple en 2025 temprano, sellando la decisión de la corte inferior como la ley de la tierra. Esto significa que los desarrolladores pueden implementar métodos de pago externos con confianza de que Apple no puede revertir esta decisión a través de desafíos legales adicionales.

Trato Igual Garantizado por la Ley

Lo más importante, la decisión establece explícitamente que Apple no puede discriminar contra aplicaciones que utilizan métodos de pago externos. La corte prohibió específicamente a Apple de:

  1. No cobrar tarifas adicionales ni imponer requisitos adicionales a aplicaciones que utilizan métodos de pago externos
  2. No dar tratamiento preferencial en los resultados de búsqueda o destacar aplicaciones que únicamente utilizan el sistema de IAP de Apple
  3. Usar medidas técnicas para hacer que las experiencias de pago externas sean inferiores al propio sistema de Apple
  4. Imponer requisitos de divulgación onerosos más allá de la información básica del consumidor

Estas protecciones explícitas significan que los desarrolladores pueden implementar Stripe o otros proveedores de pago externos sin temor a represalias sutiles o discriminación de Apple. El campo de juego se ha nivelado legalmente, y Apple debe tratar a todas las aplicaciones de manera igualitaria independientemente de sus opciones de método de pago.

The decisión representa uno de los desafíos más significativos a la aproximación de jardín cerrado de Apple y marca un cambio crucial en cómo la monetización de aplicaciones móviles puede funcionar. Para los desarrolladores que han denunciado durante mucho tiempo el 30% de comisión de Apple (reducido a 15% para pequeñas empresas), esta decisión ofrece un camino hacia márgenes de beneficio más altos y más control sobre la experiencia del cliente.

Beneficios financieros de utilizar Stripe en lugar de las compras en la aplicación de Apple

Las implicaciones financieras de este cambio son sustanciales para los desarrolladores:

  • Tarifas de procesamiento de pagos reducidas: Apple suele cobrar una comisión del 30% en las compras en la aplicación (15% para pequeñas empresas), mientras que la tarifa de Stripe es solo alrededor de 2,9% + $0,30 por transacción. Esta diferencia puede aumentar significativamente tus márgenes de beneficio.

  • Pagos más rápidos: Con Apple, suelen esperar 45-90 días para recibir sus fondos. Stripe, por otro lado, deposita los pagos en su cuenta bancaria dentro de 2-3 días hábiles.

  • Proceso de devolución simplificado: Gestiona las devoluciones directamente a través de la consola de Stripe en lugar de pasar por el sistema de devolución más complejo de Apple.

Estos ahorros de costos y mejor flujo de efectivo pueden ser cambiantes, especialmente para los desarrolladores y empresas más pequeños.

En este artículo, exploraremos cómo implementar enlaces de pago de Stripe en tu Capacitor para aprovechar estas nuevas reglas, mientras se asegura la conformidad con las directrices actualizadas de Apple __CAPGO_KEEP_0__.

This implementation is based on La documentación oficial de Stripe para Enlaces de pagoadaptada específicamente para aplicaciones Capacitor.

Entendiendo las nuevas directrices

Las directrices de revisión de aplicaciones de la Tienda de Mac App Store se han actualizado y ahora permiten a los desarrolladores dirigir a los usuarios a sitios web externos para el procesamiento de pagos, específicamente para bienes digitales y suscripciones. Este cambio solo es aplicable actualmente a las aplicaciones distribuidas en la Tienda de Mac App Store de los Estados Unidos.

Puntos clave a entender:

  1. Puedes enlazar opciones de pago externas para bienes digitales dentro de tu aplicación
  2. Esto solo aplica a aplicaciones en la Tienda de Mac App Store de EE. UU.
  3. Debes cumplir con los requisitos de divulgación de Apple
  4. Te responsabilizas por todo el soporte al cliente y el manejo de devoluciones

Vamos a sumergirnos en la implementación técnica:

Primero, crea un enlace de pago en tu Consola de Stripe:

  1. Navega a la sección de Enlaces de Pago en tu Consola de Stripe
  2. Haz clic en ”+ Nuevo” para crear un nuevo enlace de pago
  3. Define los detalles de tu producto o suscripción
  4. Bajo las configuraciones de ”Después del pago” selecciona ”No mostrar página de confirmación”
  5. Establece un enlace universal como tu URL de éxito (lo configuraremos más tarde)
  6. Haz clic en ”Crear Enlace” para generar tu enlace de pago

Para redirigir a los usuarios a tu aplicación después de la finalización del pago, configura los enlaces universales:

  1. Crear un apple-app-site-association archivo en tu dominio:
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appIDs": ["YOURTEAMID.com.yourdomain.yourapp"],
        "components": [
          {
            "/": "/checkout_redirect*",
            "comment": "Matches any URL whose path starts with /checkout_redirect"
          }
        ]
      }
    ]
  }
}
  1. Almacene este archivo en https://yourdomain.com/.well-known/apple-app-site-association

  2. Asegúrese de que se sirva con el tipo MIME correcto application/json

  3. Configure su aplicación Capacitor para manejar enlaces universales agregando la correspondiente autorización. Primero, en su capacitor.config.ts:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. Agregue la autorización de Dominios Asociados a su proyecto de Xcode:
    • Abra su proyecto de Xcode
    • Seleccione la meta de su aplicación
    • Vaya a ‘Firma y capacidades’
    • Haga clic en ‘+ Capacidad’ y seleccione ‘Dominios Asociados’
    • Agregar applinks:yourdomain.com

Paso 3: Crear una página de reemplazo

Crear una página de reemplazo en la URL de redirección para manejar casos en los que la aplicación no esté instalada:

<!DOCTYPE html>
<html>
<head>
  <title>Redirecting...</title>
  <meta http-equiv="refresh" content="0;url=https://yourdomain.com/app-download">
</head>
<body>
  <p>Redirecting to download page...</p>
</body>
</html>

Paso 4: Implementar el botón de pago en su aplicación Capacitor

Now, add the payment button to your app:

import { Capacitor } from '@capacitor/core';

export async function openPaymentLink(userEmail, userId) {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(userEmail),
    client_reference_id: userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

Por qué Safari importa: Al abrir el enlace de pago en Safari (a través de window.open) en lugar de un navegador en la aplicación, es beneficioso porque los usuarios que han guardado previamente su información de pago con Stripe Link tendrán sus credenciales disponibles automáticamente. Esto crea una experiencia de pago más suave donde los usuarios no necesitarán reingresar su información de tarjeta de crédito, lo que reduce significativamente la fricción y las tasas de abandono.

Configure su aplicación para manejar los enlaces universales cuando los usuarios sean redirigidos de regreso:

  1. Primero, instale el plugin de Aplicación:
npm install @capacitor/app
  1. Registre el plugin de Aplicación en su aplicación:
import { App } from '@capacitor/app';

// In your initialization code
App.addListener('appUrlOpen', (event) => {
  // Example URL: https://yourdomain.com/checkout_redirect?session_id=cs_test_...
  const url = new URL(event.url);
  
  if (url.pathname.startsWith('/checkout_redirect')) {
    // Extract any parameters you need
    const params = new URLSearchParams(url.search);
    const sessionId = params.get('session_id');
    
    // Handle successful payment
    if (sessionId) {
      // Verify the payment on your server if needed
      verifyPayment(sessionId);
      
      // Update UI to reflect successful purchase
      updatePurchaseStatus(true);
    }
  }
});

async function verifyPayment(sessionId) {
  // Call your backend to verify the payment
  // This is optional if you're relying on webhooks
}

function updatePurchaseStatus(success) {
  // Update your app UI to reflect purchase status
}

Step 6: Configurar Webhook para la cumplimiento de pedidos

Finalmente, configure un webhook en su servidor para manejar los pagos exitosos:

// Using Express.js as an example
const express = require('express');
const stripe = require('stripe')('sk_test_your_stripe_secret_key');
const app = express();

// Use raw body parser for webhook signature verification
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = 'whsec_your_webhook_secret';
  
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
  } catch (err) {
    console.log(`Webhook Error: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  // Handle the checkout.session.completed event
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    
    // Retrieve client_reference_id (your user ID)
    const userId = session.client_reference_id;
    
    // Grant access to the purchased content
    await grantAccess(userId, session.id);
  }
  
  res.status(200).send();
});

async function grantAccess(userId, sessionId) {
  // Your logic to grant access to the purchased content
  // This could be updating a database, sending a notification, etc.
}

app.listen(3000, () => console.log('Webhook server running on port 3000'));

Compatibilidad con Android

Queremos ser claros: la sentencia de Epic v. Apple ha cambiado fundamentalmente el panorama de los pagos móviles. No solo impacta directamente a las aplicaciones de iOS, sino que también fortalece la posición de los desarrolladores de Android que han estado utilizando métodos de pago externos.

Los desarrolladores de Android pueden implementar soluciones de pago externas con total confianza. La sentencia del caso de Apple ha establecido un precedente que protege a los desarrolladores de todas las plataformas de posibles restricciones futuras. Esta decisión judicial ha validado lo que muchos desarrolladores de Android han estado haciendo durante años - ofrecer opciones de pago alternativas con tarifas más bajas.

La tienda de aplicaciones de Google siempre ha sido menos restrictiva sobre los métodos de pago externos que Apple, y ahora que se ha establecido el precedente legal, no hay prácticamente riesgo en implementar Stripe u otros proveedores de pago externos en sus aplicaciones de Android. Puede seguir adelante con estas implementaciones sabiendo que está en terreno firme legal.

La implementación que hemos cubierto para iOS funciona casi de manera idéntica para dispositivos Android. Dado que la tienda de aplicaciones de Google no tiene las mismas restricciones sobre los métodos de pago externos, puede utilizar la misma aproximación de enlaces de pago de Stripe sin necesidad de diálogos de discusión especial.

Para manejar el enrutamiento profundo (equivalente a enlaces universales en iOS), necesitará:

  1. Configurar los enlaces de la aplicación en su AndroidManifest.xml para manejar la URL de redirección
  2. Crear un .well-known/assetlinks.json archivo en su dominio con los detalles de su aplicación
  3. Usar la misma appUrlOpen lógica de escucha para procesar pagos exitosos

La belleza de Capacitor es que una vez que se han implementado las configuraciones específicas de la plataforma, el flujo de pago real code sigue siendo el mismo en ambas plataformas.

Creando una interfaz de pago

Aquí hay un ejemplo de un componente de botón de pago en Vue que puedes agregar a tu aplicación Capacitor:

<template>
  <div class="payment-container">
    <div class="pricing-card">
      <h2 class="mb-4 text-xl font-bold">{{ product.name }}</h2>
      <p class="mb-6 text-gray-600">{{ product.description }}</p>
      <div class="mb-6 price-tag">
        <span class="text-2xl font-bold">${{ product.price }}</span>
        <span v-if="product.isSubscription" class="text-sm text-gray-500">/month</span>
      </div>
      <button 
        @click="handlePayment" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Purchase Now
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { Dialog } from '@capacitor/dialog';

const props = defineProps({
  product: {
    type: Object,
    required: true
  },
  userEmail: {
    type: String,
    default: ''
  },
  userId: {
    type: String,
    required: true
  }
});

const isLoading = ref(false);

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

async function openPaymentLink() {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(props.userEmail),
    client_reference_id: props.userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

async function handlePayment() {
  isLoading.value = true;
  try {
    // Only show the disclosure on iOS
    if (window.Capacitor?.getPlatform() === 'ios') {
      const userConfirmed = await showExternalPaymentDisclosure();
      if (!userConfirmed) return;
    }
    
    await openPaymentLink();
  } catch (error) {
    console.error('Payment error:', error);
    await Dialog.alert({
      title: 'Payment Error',
      message: 'There was an error initiating the payment. Please try again.'
    });
  } finally {
    isLoading.value = false;
  }
}
</script>

Manejo de diferentes regiones

Dado que las nuevas directrices de Apple solo se aplican a las aplicaciones en la Tienda de Aplicaciones de Apple de EE. UU., necesitarás una estrategia para detectar las regiones de los usuarios y aplicar el método de pago apropiado. Aquí hay un enfoque más confiable utilizando la geolocalización de IP:

import { Capacitor } from '@capacitor/core';

async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  try {
    // Use a geolocation service to determine user's country
    const response = await fetch('https://ipapi.co/json/');
    const locationData = await response.json();
    
    // Check if the user is in the United States
    if (locationData.country_code === 'US') {
      return 'external'; // Can use Stripe Payment Links
    } else {
      return 'iap'; // Must use In-App Purchases
    }
  } catch (error) {
    console.error('Error detecting region:', error);
    return 'iap'; // Default to IAP to be safe
  }
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

Esta aproximación utiliza el servicio gratuito ipapi.co para determinar el país del usuario en función de su dirección IP. También podrías utilizar otros servicios de geolocalización como MaxMind, o implementar esta comprobación en el lado del servidor para una mayor seguridad.

Nota: Si bien esta aproximación funciona, es importante recordar que la geolocalización de IP no siempre es 100% precisa. Para aplicaciones críticas, considera utilizar múltiples métodos de detección o permitir que los usuarios seleccionen manualmente su región.

Deteción de ubicación más precisa con plugins de Capacitor

Para una detección de ubicación más precisa, puedes utilizar el plugin de geolocalización de Capacitor junto con @capgo/capacitor-nativegeocoder para determinar el país del usuario con mayor precisión:

  1. Primero, instala los plugins requeridos:
npm install @capacitor/geolocation @capgo/capacitor-nativegeocoder
  1. Configura los plugins en tu proyecto Capacitor. Agrega lo siguiente a tu capacitor.config.ts:
import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. Implementar la detección de región basada en ubicación:
import { Capacitor } from '@capacitor/core';
import { Geolocation } from '@capacitor/geolocation';
import { NativeGeocoder } from '@capgo/capacitor-nativegeocoder';

async function isUserInUSA() {
  try {
    // Request permission first
    const permissionStatus = await Geolocation.requestPermissions();
    
    if (permissionStatus.location === 'granted') {
      // Get current position
      const position = await Geolocation.getCurrentPosition({
        timeout: 10000,
        enableHighAccuracy: false
      });
      
      // Use NativeGeocoder to reverse geocode the coordinates
      const results = await NativeGeocoder.reverseGeocode({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        useLocale: true,
        maxResults: 1
      });
      
      if (results.addresses.length > 0) {
        // Check if the user is in the USA
        return results.addresses[0].countryCode === 'US';
      }
    }
    
    // If we couldn't determine location or permission denied, fall back to IP detection
    return await isUserInUSAByIP();
  } catch (error) {
    console.error('Error detecting location:', error);
    // Fall back to IP detection on error
    return await isUserInUSAByIP();
  }
}

async function isUserInUSAByIP() {
  try {
    const response = await fetch('https://ipapi.co/json/');
    const data = await response.json();
    return data.country_code === 'US';
  } catch (error) {
    console.error('Error detecting IP location:', error);
    return false; // Default to false to be safe
  }
}

export async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  // Check if user is in the USA
  const isUSA = await isUserInUSA();
  return isUSA ? 'external' : 'iap';
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

Esta implementación proporciona una forma más precisa de determinar si un usuario se encuentra físicamente ubicado en los Estados Unidos. Primero intenta utilizar el GPS del dispositivo y el geocodificador nativo para determinar el país. Si eso falla (debido a problemas de permisos o otros errores), se recurre a la detección basada en IP.

Recuerde agregar los permisos necesarios a sus info.plist (iOS) y AndroidManifest.xml (Android) archivos:

Para iOS (ios/App/App/Info.plist):

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to determine which payment method to use based on regional availability.</string>

Para Android (android/app/src/main/AndroidManifest.xml):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Usar este enfoque le da la forma más precisa de determinar si un usuario es elegible para opciones de pago externas de acuerdo con las nuevas directrices de Apple.

Gestión de Suscripciones

Una de las ventajas clave de utilizar Stripe para los pagos es la capacidad de ofrecer y gestionar suscripciones. Aquí está cómo manejar la gestión de suscripciones en su aplicación Capacitor:

1. Crear una página de gestión de suscripciones

Agregar una página de gestión de suscripciones en su aplicación para mostrar las suscripciones activas del usuario:

<template>
  <div class="subscription-manager">
    <div v-if="isLoading" class="loading-indicator">
      Loading subscription data...
    </div>
    
    <div v-else-if="subscription" class="subscription-info">
      <h2 class="mb-4 text-xl font-bold">Your Subscription</h2>
      
      <div class="mb-6 plan-details">
        <p><span class="font-medium">Plan:</span> {{ subscription.planName }}</p>
        <p><span class="font-medium">Status:</span> {{ subscription.status }}</p>
        <p><span class="font-medium">Renews:</span> {{ formatDate(subscription.currentPeriodEnd) }}</p>
      </div>
      
      <button 
        @click="manageSubscription" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Manage Subscription
      </button>
    </div>
    
    <div v-else class="no-subscription">
      <p class="mb-4">You don't have an active subscription.</p>
      <button 
        @click="goToPricingPage" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        View Plans
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { getUserSubscription } from '../services/subscription';

const subscription = ref(null);
const isLoading = ref(true);

onMounted(async () => {
  try {
    const userData = await getUserSubscription();
    subscription.value = userData.subscription;
  } catch (error) {
    console.error('Failed to load subscription:', error);
  } finally {
    isLoading.value = false;
  }
});

function formatDate(timestamp) {
  return new Date(timestamp * 1000).toLocaleDateString();
}

function manageSubscription() {
  // Open Stripe Customer Portal
  window.open(subscription.value.portalUrl, '_blank');
}

function goToPricingPage() {
  // Navigate to pricing page
  // router.push('/pricing');
}
</script>

2. Portal del cliente para la gestión de suscripciones

Stripe ofrece un Portal del cliente que permite a los usuarios gestionar sus suscripciones. Puede crear un enlace a este portal desde su servidor:

// Server-side code (Node.js)
const stripe = require('stripe')('sk_your_stripe_secret_key');

async function createPortalSession(customerId) {
  const session = await stripe.billingPortal.sessions.create({
    customer: customerId,
    return_url: 'https://yourdomain.com/account',
  });
  
  return session.url;
}

Cumpliendo con las normas de la Tienda de Aplicaciones

Para asegurarse de que su implementación cumpla con las directrices de Apple:

  1. Incluir las declaraciones adecuadas sobre compras externas
  2. Implementar una hoja de diálogo informando a los usuarios que están saliendo de la aplicación (como lo requiere Apple)
  3. No intenten eludir la comisión de Apple en las compras realizadas dentro de la aplicación
  4. Comunicar claramente a los usuarios que Apple no es responsable de la transacción

Aquí hay un ejemplo de implementar la modal de declaración requerida:

import { Dialog } from '@capacitor/dialog';

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

export async function initiateExternalPayment(userEmail, userId) {
  const userConfirmed = await showExternalPaymentDisclosure();
  
  if (userConfirmed) {
    await openPaymentLink(userEmail, userId);
  }
}

Probando su implementación

Para probar su implementación:

  1. Haga clic en su botón de pago en su aplicación, que debería mostrar la declaración y luego abrir la página de pago de Stripe
  2. Complete un pago de prueba utilizando la tarjeta de prueba de Stripe 4242 4242 4242 4242
  3. Después del pago, deberías ser redirigido de regreso a tu aplicación a través del enlace universal
  4. Verifica que tu webhook recibió el checkout.session.completed evento

Conclusión

La capacidad de utilizar opciones de pago externas para bienes digitales en aplicaciones de iOS es un cambio significativo que da a los desarrolladores más flexibilidad. Si bien este cambio solo se aplica actualmente a las aplicaciones en la Tienda de Aplicaciones de Apple de EE. UU., proporciona una importante alternativa al sistema de compras en la aplicación de Apple.

Al utilizar los enlaces de pago de Stripe con Capacitor, puedes implementar rápidamente una experiencia de pago fluida mientras mantienes la conformidad con las directrices de Apple. Este enfoque también te da la ventaja de la infraestructura de pago robusta de Stripe, tarifas de procesamiento más bajas (3% vs 30%) y pagos más rápidos (días en lugar de meses) en comparación con el sistema de compras en la aplicación de Apple.

Recuerda que deberás manejar todos los problemas de soporte al cliente y las devoluciones directamente, ya que estos trámites ocurren fuera del ecosistema de Apple.

¿Has implementado los enlaces de pago de Stripe en tu aplicación Capacitor? Comparte tu experiencia en los comentarios debajo!

Preguntas frecuentes

Q: ¿Este enfoque es conforme con las directrices de Apple?
A: Sí, a partir del 1 de mayo de 2025, Apple permite enlazar a métodos de pago externos para bienes y servicios digitales en aplicaciones distribuidas en la Tienda de Aplicaciones de Apple de EE. UU., siempre y cuando incluyas las declaraciones requeridas.

Q: ¿Necesito pagar la comisión de Apple cuando se utilizan métodos de pago externos?
A: No, uno de los principales beneficios de las nuevas reglas es que los pagos procesados fuera del sistema de Apple no están sujetos a su comisión.

Q: ¿Mi empresa necesita estar basada en los Estados Unidos para aprovechar estas nuevas reglas?
A: No, cualquier empresa del mundo puede implementar métodos de pago externos siempre y cuando su aplicación esté disponible en la Tienda de Aplicaciones de Apple de los Estados Unidos y los usuarios que realicen las compras estén ubicados en los Estados Unidos. La norma se aplica al mercado (Tienda de Aplicaciones de Apple de los Estados Unidos) y la ubicación de los usuarios, no la ubicación de su empresa. Esto significa que los desarrolladores de Europa, Asia, América del Sur o cualquier otro lugar pueden implementar Enlaces de Pago de Stripe para sus clientes de los Estados Unidos.

Q: ¿Qué sucede si un usuario fuera de los EE. UU. intenta utilizar la opción de pago externa?
A: Debería implementar la detección de región (como se muestra en el artículo) para ofrecer solo opciones de pago externas a los usuarios de los EE. UU. Para otras regiones, debería continuar utilizando el sistema de compras en la aplicación de Apple.

Q: ¿Puedo utilizar esto para bienes o servicios físicos consumidos fuera de la aplicación?
A: Sí, Apple siempre ha permitido métodos de pago externos para bienes y servicios físicos consumidos fuera de la aplicación (como compartir un taxi o pedir comida).

Continúa desde Enlaces de Pago de Stripe en Capacitor: Nuevas Directrices de Apple

Si está utilizando Enlaces de Pago de Stripe en Capacitor: Nuevas Directrices de Apple para planificar la seguridad y la conformidad, conectéalo con Cifrado para el detalle de implementación en Cifrado, Cumplimiento para el detalle de implementación en Cumplimiento, Capgo Escáner de Seguridad para el flujo de trabajo del producto en Capgo Escáner de Seguridad, Capgo Seguridad para el flujo de trabajo del producto en Capgo Seguridad, y Capgo Centro de Confianza para el flujo de trabajo del producto en Capgo Centro de Confianza.

Actualizaciones en vivo para aplicaciones Capacitor

Cuando haya un error en la capa web, envía la corrección a través de Capgo en lugar de esperar días para la aprobación de la tienda. Los usuarios reciben la actualización en segundo plano mientras los cambios nativos siguen en el camino de revisión normal.

Comienza ahora

Últimas noticias de nuestro Blog

Capgo te da las mejores herramientas que necesitas para crear una aplicación móvil verdaderamente profesional.