Efectivo
Guía de Integración: Pago en Tienda de Conveniencia en Bidzi
Esta guía describe el flujo completo para integrar pagos en efectivo en tiendas de conveniencia usando la API de Bidzi.
Entorno de pruebas: Todos los ejemplos usan el endpoint de sandbox
https://api.sand.bidzi.mx. Para producción, reemplaza el dominio con el endpoint correspondiente.
Resumen del flujo
1. Autenticación → Obtener access_token
2. Crear método de pago → Obtener payment_method_id
3. Crear orden → Obtener order_id
4. Registrar pago → Obtener referencia + código de barras para el comprador
Recomendación: Guarda los IDs obtenidos en cada paso (
payment_method_id,order_id,payment_id) ya que los necesitarás en pasos posteriores y para el seguimiento de la transacción.
Paso 1 — Autenticación
Obtén un access_token llamando al servicio de autenticación de Bidzi con tus credenciales de API. Este token se usa como Bearer en todos los demás endpoints.
📘 Documentación: https://docs.bidzi.mx/docs/autenticación
El token tiene un tiempo de expiración. Implementa la lógica de refresco o re-autenticación según lo indique la documentación oficial.
Paso 2 — Crear método de pago en efectivo
Registra una intención de pago de tipo CASH. Esto genera un payment_method_id que usarás al momento de registrar el pago.
Request
curl --request POST \
--url https://api.sand.bidzi.mx/v1/payment-methods \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--data '{
"type": "CASH",
"alias": "Cash payment method"
}'| Campo | Tipo | Descripción |
|---|---|---|
type | string | Debe ser "CASH" para pago en tienda de conveniencia |
alias | string | Nombre descriptivo para identificar el método de pago |
Response
{
"payment_method_id": "pym_c79d63641e1243e9b64f5f6a7a8bae48",
"alias": "Cash payment method",
"type": "CASH",
"status": "ACTIVE",
"created_at": "1785172300000",
"updated_at": "1785172300000"
}Guarda el
payment_method_id— lo necesitarás en el Paso 4.
Nota sobre
created_at/updated_at: Los timestamps están en formato Unix Epoch en milisegundos (ms). Para convertirlos a fecha legible:new Date(1785172300000)en JavaScript odatetime.fromtimestamp(1785172300000 / 1000)en Python.
📘 Documentación: https://docs.bidzi.mx/reference/create-payment-method
Paso 3 — Crear orden
Registra el detalle de la compra: artículos, montos y datos del cliente. Esto representa el "checkout" de la transacción.
Request
curl --request POST \
--url https://api.sand.bidzi.mx/v1/orders \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--data '{
"country_code": "MX",
"merchant_order_id": "1366656595193",
"currency": "MXN",
"subtotal_amount": 1000,
"total_amount": 990,
"discounts": [
{
"amount": 10
}
],
"products": [
{
"product_id": "7197",
"name": "Pantalla TCL Smart TV Serie A3 A343 HD Android TV 40",
"quantity": 1,
"unit_price": 1000
}
],
"customer": {
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]"
}
}'Campos principales del body:
| Campo | Tipo | Descripción |
|---|---|---|
country_code | string | Código ISO del país. Para México: "MX" |
merchant_order_id | string | ID único de tu sistema para esta orden (evita duplicados) |
currency | string | Moneda ISO 4217. Para pesos mexicanos: "MXN" |
subtotal_amount | number | Suma de productos sin aplicar descuentos |
total_amount | number | Monto final a cobrar (subtotal_amount - sum(discounts)) |
discounts | array | Lista de descuentos aplicados. La suma debe corresponder a subtotal - total |
products | array | Detalle de artículos incluidos en la orden |
customer | object | Datos del comprador |
Importante: Verifica que
subtotal_amount - sum(discounts[].amount) == total_amount. Una inconsistencia puede provocar un error de validación en el API.
Response
{
"order_id": "ord_c9ab42cbc49e479e8972c6f0a14310de",
"status": "CREATED",
"expires_at": "1785258726000",
"merchant_order_id": "1366656595193",
"customer": {
"source": "ORDER",
"customer_id": "cus_21fa0cf02d1c4a73baf5b4f1c712c557",
"first_name": "John",
"last_name": "Doe",
"email": "[email protected]",
"created_at": "1785172300000",
"updated_at": "1785172300000"
},
"placed_at": "1785172326000",
"country": "México",
"country_code": "MX",
"currency": "MXN",
"subtotal_amount": 1000,
"discounts": [
{
"amount": 10.00
}
],
"total_amount": 990,
"products": [
{
"product_id": "7197",
"quantity": 1,
"unit_price": 1000.00,
"name": "Pantalla TCL Smart TV Serie A3 A343 HD Android TV 40"
}
],
"order_type": "STANDARD"
}Guarda el
order_id— lo necesitarás en el Paso 4.
Nota sobre
expires_at: La orden tiene una vigencia limitada. Si el comprador no realiza el pago en tienda antes de esta fecha, la orden expirará y deberás crear una nueva. Muestra este plazo al usuario en tu interfaz.
📘 Documentación: https://docs.bidzi.mx/reference/create-order
Paso 4 — Registrar pago
Con el payment_method_id y el order_id obtenidos en los pasos anteriores, registra el pago. La respuesta incluirá la referencia y el código de barras que el comprador necesita para pagar en la tienda de conveniencia.
Request
curl --request POST \
--url https://api.sand.bidzi.mx/v1/payments \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {ACCESS_TOKEN}' \
--header 'Idempotency-Key: {UUID_UNICO_POR_INTENTO}' \
--data '{
"payment_source": {
"type": "CASH",
"payment_method_id": "{PAYMENT_METHOD_ID}"
},
"order_id": "{ORDER_ID}"
}'| Header | Descripción |
|---|---|
Idempotency-Key | UUID único por cada nuevo intento de pago. Reutilizar el mismo valor en un reintento evita pagos duplicados. |
Importante sobre
Idempotency-Key: Genera un nuevo UUID para cada intento de pago distinto (e.g.,crypto.randomUUID()en Node.js ouuid.uuid4()en Python). Si haces un reintento exactamente del mismo pago ante un error de red, puedes reutilizar el mismo key para garantizar idempotencia.
Response
{
"payment_id": "pay_2a7f991dc7024fa3896f212bc0b3d6a2",
"order_id": "ord_c9ab42cbc49e479e8972c6f0a14310de",
"status": "PAYMENT_ACTION_REQUIRED",
"payment_source": {
"type": "CASH",
"payment_method_id": "pym_c79d63641e1243e9b64f5f6a7a8bae48"
},
"amount": {
"requested": 140.00,
"currency": "MXN"
},
"user_action_required": {
"type": "OFFLINE_PAYMENT",
"offline_payment_provider": {
"reference": "000000000000003235729294",
"barcode_url": "https://references-dev.s3.amazonaws.com/00000000000000000092929405",
"url_payment_receipt": "https://api-sand.tcpagos.mx/api/v2/transactions/public/xlfjjc5ptpqkocmp/transaction/voucher?application_id=32"
}
},
"transactions": [
{
"type": "REGISTER",
"transaction_id": "424801511369448d8398ce0b33ee6998",
"status": "SUCCESS",
"amount": 140.00,
"code": "APPROVED",
"provider": {
"merchant_provider_id": "mpv_2ac107f7f4ba4849a9d9ec814723e966",
"provider_id": "prc_4147ebfe2c264e1a8ddc6f80b83fb123",
"name": "tcpagos"
},
"created_at": "1785172326679"
}
],
"created_at": "1785172324833",
"updated_at": "1785172324833"
}Campos clave de la respuesta:
| Campo | Descripción |
|---|---|
status | Siempre será PAYMENT_ACTION_REQUIRED para CASH — el pago está pendiente de realizarse en tienda |
user_action_required.offline_payment_provider.reference | Referencia numérica que el comprador presenta en la caja de la tienda |
user_action_required.offline_payment_provider.barcode_url | URL de la imagen del código de barras escaneable en caja |
user_action_required.offline_payment_provider.url_payment_receipt | URL del recibo con las instrucciones completas para pagar en tienda |
⚠️ Muestra la referencia y el recibo al comprador. Una vez registrado el pago, debes presentarle al usuario la referencia (
reference) y/o el código de barras (barcode_url) para que pueda acudir a la tienda. Lo más recomendable es redirigirlo o mostrarle el recibo completo disponible enurl_payment_receipt, ya que incluye todas las instrucciones del proceso de pago en caja.
Flujo post-pago: El estado
PAYMENT_ACTION_REQUIREDindica que la orden está activa y esperando el pago en tienda. OrkestaPay notificará el cambio de estado (e.g.,COMPLETEDoFAILED) vía webhook cuando la tienda confirme la operación. Configura tu endpoint de webhook en el dashboard de OrkestaPay para recibir estas notificaciones.
📘 Documentación: https://docs.bidzi.mx/reference/create-payment
Resumen de IDs a persistir
| ID | Obtenido en | Para qué sirve |
|---|---|---|
access_token | Paso 1 | Autenticación en todos los endpoints |
payment_method_id | Paso 2 | Referenciar el método CASH al crear el pago |
order_id | Paso 3 | Asociar la orden al pago; consultas de estado de orden |
payment_id | Paso 4 | Seguimiento y conciliación del pago |
reference | Paso 4 | Código que el comprador presenta en caja para realizar el pago |
barcode_url | Paso 4 | Imagen del código de barras escaneable en la tienda |
url_payment_receipt | Paso 4 | Recibo con instrucciones completas para mostrar o enviar al comprador |
Errores comunes
| Escenario | Causa probable |
|---|---|
401 Unauthorized | access_token expirado o inválido — re-autentica |
| Orden rechazada por montos | subtotal_amount - discounts != total_amount |
| Pago duplicado | Se envió la misma Idempotency-Key para dos intentos distintos |
| Orden expirada al pagar | El comprador no pagó en tienda antes de expires_at — crea una nueva orden |
| Webhook no recibido | El endpoint de webhook no está configurado o no responde con 2xx |
| Comprador no puede pagar en tienda | No se mostraron la referencia o el recibo — asegúrate de exponer url_payment_receipt en tu UI |
Updated about 3 hours ago

