Mercado Pago vía Widget
En esta página
Requisitos previos#
Antes de implementar los pagos de Mercado Pago Wallet, asegúrate de tener:
- Mercado Pago habilitado en el Panel de Administración de DEUNA.
- Un token de pedido generado.
- Integrado DEUNA SDK en su proyecto.
- Revisé la documentación del Widget de Pago para su plataforma.
Configuración del método de pago#
Mostrar el Widget de Pago pasando la configuración de Mercado Pago en el paymentMethods parameter.
[
{
"paymentMethod": "wallet",
"processors": [ "mercadopago_wallet" ]
}
]Widget de Pago - Web#
DeunaSDK.initPaymentWidget({
orderToken: 'YOUR_ORDER_TOKEN',
paymentMethods: [
{
paymentMethod: 'wallet',
processors: ['mercadopago_wallet'],
},
],
callbacks: { ... },
});Widget de Pago - iOS#
deunaSDK.initPaymentWidget(
orderToken: "<DEUNA_ORDER_TOKEN>",
callbacks: PaymentWidgetCallbacks(
onSuccess: { order in
// Close the DEUNA widget
self.deunaSDK.close {
// Handle successful payment:
// - Navigate to confirmation screen
// - Show success message
// - Update order status
}
},
onError: { error in
if error.type == .paymentError {
// Handle payment errors:
// - Show error message
// - Allow retry
// - Log analytics
}
}
),
paymentMethods: [
[
"paymentMethod": "wallet",
"processors": ["mercadopago_wallet"]
]
]
)import DeunaSDK
import SwiftUI
struct PaymentView: View {
let deunaSDK: DeunaSDK
var body: some View {
VStack {
DeunaWidget(
deunaSDK: deunaSDK,
configuration: PaymentWidgetConfiguration(
orderToken: "YOUR_ORDER_TOKEN",
callbacks: PaymentWidgetCallbacks(
onSuccess: { order in
deunaSDK.dispose {
// Handle post-payment flow
}
},
onError: { error in
if error.type == .paymentError {
// Implement error handling
}
}
),
paymentMethods: [
[
"paymentMethod": "wallet",
"processors": ["mercadopago_wallet"]
]
]
)
)
}
}
}Widget de Pago - Android#
Por razones de seguridad, MercadoPago requiere que sus URL de pago se carguen en un Pestaña personalizada en lugar de un WebView.
Es crucial entender que si bien un Pestaña personalizada está abierto, deberías evitar actualizar tu UI o realizando acciones como navegación o mostrar cuadros de diálogo. Estas operaciones podrían causar comportamiento inesperado, incluyendo la aplicación falla.
Por lo tanto, sólo debe ejecutar dichas acciones después de que el usuario haya cerrado la pestaña Personalizada. Para detectar cuando la pestaña Personalizar se cierra, implemente el siguiente código en su Actividad principal:
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/**
* Register for activity result callbacks,
* needed to wait until the custom chrome tab is closed
*/
ExternalUrlHelper.registerForActivityResult(this)
}
}Ahora muestra el widget de pago.
deunaSDK.initPaymentWidget(
orderToken = "<DEUNA_ORDER_TOKEN>",
callbacks = PaymentWidgetCallbacks().apply {
onSuccess = { order ->
// Close the DEUNA widget
this.deunaSDK.close {
// Handle successful payment:
// - Navigate to confirmation screen
// - Show success message
// - Update order status
}
}
onError = { error ->
if (error.type == PaymentErrorType.PAYMENT_ERROR) {
// Handle payment errors:
// - Show error message
// - Allow retry
// - Log analytics
}
}
},
paymentMethods = listOf(
mapOf(
"paymentMethod" to "wallet",
"processors" to listOf("mercadopago_wallet")
)
)
)@Composable
fun YourScreen(
deunaSDK: DeunaSDK,
orderToken: String,
userToken: String,
) {
// Maintains the Deuna WebView instance across recompositions
val deunaWidget = remember { mutableStateOf<DeunaWidget?>(null) }
Column(modifier = Modifier.padding(16.dp)) {
// Container for the embedded payment widget
// MUST specify dimensions (e.g., .height(400.dp) or .weight(1f) in parent Column)
Box(
modifier = yourModifier
) {
AndroidView(
modifier = Modifier.fillMaxSize(),
factory = { context ->
DeunaWidget(context).apply {
this.widgetConfiguration = PaymentWidgetConfiguration(
sdkInstance = deunaSDK,
orderToken = orderToken,
userToken = userToken,
paymentMethods = listOf(
mapOf(
"paymentMethod" to "wallet",
"processors" to listOf("mercadopago_wallet")
)
),
callbacks = PaymentWidgetCallbacks().apply {
onSuccess = { data ->
deunaWidget.value?.waitUntilExternalUrlIsClosed {
// Handle post-payment flow
}
}
onError = { error ->
// Handle error
}
},
)
this.build() // Render the DEUNA widget
// Store reference for later submission
deunaWidget.value = this
}
}
)
}
Spacer(modifier = Modifier.height(16.dp))
}
// Critical: Clean up DeunaWidget resources when composable leaves composition
DisposableEffect(Unit) {
onDispose {
deunaWidget.value?.destroy()
Log.d("DeunaWidget", "WebView resources cleaned up")
}
}
}Widget de Pago - React Native#
import React from 'react';
import { View, Button } from 'react-native';
import { DeunaSDK, DeunaWidget } from '@deuna/react-native-sdk';
// Initialize SDK
const deunaSDK = DeunaSDK.initialize({
publicApiKey: 'YOUR_PUBLIC_API_KEY',
environment: 'sandbox', // or "production"
});
const PaymentScreen = () => {
const launchPayment = () => {
deunaSDK.initPaymentWidget({
orderToken: 'YOUR_ORDER_TOKEN',
paymentMethods: [
{
paymentMethod: 'wallet',
processors: ['mercadopago_wallet'],
},
],
callbacks: {
onSuccess: async (order) => {
await deunaSDK.close();
// Handle successful payment
console.log('Payment successful:', order);
},
onError: async (error) => {
// Handle payment errors
console.error('Payment error:', error);
if (...) {
// Always await the close operation
await deunaSDK.close();
// Handle UI updates
console.log('Payment widget closed due to error.');
}
},
},
});
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<DeunaWidget instance={deunaSDK} />
<Button title="Paga con Mercado Pago" onPress={launchPayment} />
</View>
);
};