Después de estudiar el Checkout podemos entrar en una de las partes más importantes de cualquier plataforma de comercio electrónico: los pagos.
Cuando un cliente pulsa Place order, podemos tener la impresión de que ocurre una única acción:
Cliente
↓
Paga
↓
Pedido completadoEn realidad pueden intervenir varios conceptos y procesos diferentes.
Drupal Commerce distingue claramente entre:
- Payment Provider
- Payment Gateway
- Payment Method
- Payment
- Payment Workflow
Además, una transacción puede pasar por operaciones como:
Authorization
Capture
Void
RefundComprender estas diferencias es fundamental para configurar correctamente Stripe, PayPal, Authorize.Net u otro proveedor, y también para diseñar procesos B2B, pagos manuales o integraciones personalizadas.
1. Empezar separando los conceptos
Podemos comenzar con una visión general:
Customer
↓
Payment Method
↓
Payment Gateway
↓
Payment Provider
↓
Financial transactionMientras Drupal Commerce mantiene localmente:
Order
↓
Payment
↓
Gateway
↓
Remote transactionNo debemos confundir estas piezas.
2. Payment Provider
El Payment Provider es el servicio externo que procesa realmente una transacción.
Algunos ejemplos habituales son:
Stripe
PayPal
Authorize.Net
Adyen
BraintreePodemos pensar:
Drupal Commerce
↓
Payment Provider
↓
Bank / Card Network
↓
Customer accountDrupal Commerce no sustituye al proveedor de pagos.
Commerce necesita una integración que permita comunicarse con él.
Esa integración aparece mediante un Payment Gateway.
3. Payment Gateway
Un Payment Gateway representa dentro de Commerce una configuración utilizada para comunicarse con un sistema de pagos.
Por ejemplo:
Payment Gateway
Stripe Production
Provider:
Stripe
Mode:
Live
Currency:
EUREl Gateway contiene o utiliza la configuración necesaria para conectar Commerce con el proveedor.
Conceptualmente:
Drupal Commerce
↓
Payment Gateway
↓
Stripe API
↓
StripeEl Gateway actúa como puente entre ambos sistemas.
4. Payment Gateway no es Payment Method
Esta distinción es fundamental.
Supongamos que configuramos:
Gateway:
StripeEl cliente puede pagar mediante:
Visa **** 4242Stripe es el Gateway o proveedor de la integración.
La tarjeta es el Payment Method.
PAYMENT GATEWAY
Stripe
PAYMENT METHOD
Visa
**** 4242
Expires 08/29Por tanto:
Payment Gateway
= cómo Commerce procesa el pago
Payment Method
= con qué paga el cliente5. Payment Method
Un Payment Method representa información local sobre un método de pago del cliente gestionado por un proveedor.
Por ejemplo:
Customer
Daniel Example
Payment Methods
├── Visa **** 4242
└── Mastercard **** 1234El Payment Method puede contener información segura para identificar el método sin almacenar directamente datos sensibles como el número completo de una tarjeta.
Conceptualmente:
Drupal Commerce
Payment Method
Visa **** 4242
Remote reference
pm_xxxxxxxxx
↓
Payment Provider
Actual payment instrumentLa información sensible puede permanecer gestionada por el proveedor.
6. Payment Methods reutilizables
En determinados gateways on-site el cliente puede guardar un Payment Method.
Por ejemplo:
Customer account
Saved payment methods
├── Visa **** 4242
└── Mastercard **** 1234Durante una nueva compra:
Choose payment method
● Visa **** 4242
○ Mastercard **** 1234
○ Add new payment methodEsto permite reutilizar el método en pedidos posteriores.
7. Payment Method no significa necesariamente tarjeta
Una tarjeta de crédito es solamente un ejemplo.
Dependiendo del proveedor podemos tener métodos como:
Credit Card
PayPal
Bank Account
Wallet
Provider-specific payment methodEl Gateway determina qué tipos de Payment Methods soporta.
8. Payment
Un Payment representa una transacción de pago asociada a un Order.
Por ejemplo:
Order #1001
Total:
120 EUR
Payment
Amount:
120 EUR
Gateway:
Stripe
State:
CompletedPodemos resumir:
Payment Gateway
= mecanismo para procesar
Payment Method
= instrumento del cliente
Payment
= transacción monetariaEsta es probablemente la distinción más importante del artículo.
9. La relación completa
Podemos visualizarla así:
CUSTOMER
│
▼
PAYMENT METHOD
Visa **** 4242
│
▼
PAYMENT GATEWAY
Stripe
│
▼
PAYMENT PROVIDER
Stripe
│
▼
REMOTE TRANSACTION
Mientras en Commerce:
ORDER
│
▼
PAYMENT
│
├── Amount
├── State
├── Gateway
└── Remote ID10. Un Order puede tener varios Payments
No debemos asumir que:
1 Order = 1 PaymentPuede ocurrir:
Order Total
1000 EUR
Payment #1
Credit Card
600 EUR
Payment #2
Bank Transfer
400 EURO:
Order
100 EUR
Initial Payment
100 EUR
Refund
-20 EURPor eso Commerce mantiene Payments como entidades independientes relacionadas con el Order.
11. Total del Order frente a Amount Paid
El Order puede tener:
Order Total
100 EURmientras solamente hemos recibido:
Payments
50 EUREntonces conceptualmente:
Order Total
100 EUR
Total Paid
50 EUR
Balance
50 EURCommerce puede calcular cuánto se ha pagado a partir de los Payments relacionados con el Order.
Esto resulta especialmente importante para:
- Pagos parciales
- Pagos manuales
- B2B
- Capturas parciales
- Reembolsos
12. Payment State
Al igual que los Orders, los Payments tienen su propio estado.
Podemos encontrar conceptualmente estados como:
New
Authorization
Completed
Partially Refunded
RefundedEl estado describe la situación financiera de esa transacción.
Esto confirma una idea que ya vimos anteriormente:
Order State
≠
Payment State13. Order Workflow frente a Payment Workflow
Supongamos:
Order
State:
FulfillmentMientras:
Payment
State:
CompletedEsto significa:
El dinero fue recibido
pero
el producto todavía debe entregarse.Otro escenario:
Order
State:
Validation
Payment
State:
AuthorizationEsto puede significar:
El dinero está autorizado
pero
todavía no ha sido capturado.Ambos procesos deben mantenerse separados.
14. On-site Payment Gateway
En un Gateway on-site, el proceso de pago se integra directamente con el checkout del sitio.
Conceptualmente:
Drupal Checkout
Credit Card
[____________]
Expiry
[____]
CVV
[___]
↓
Payment Provider APISin embargo, esto no significa necesariamente que Drupal almacene los datos sensibles de la tarjeta.
Los proveedores modernos suelen utilizar técnicas como:
- Tokenization
- Hosted fields
- JavaScript SDKs
- Payment tokens
Drupal puede recibir solamente una referencia segura al Payment Method.
15. Off-site Payment Gateway
En un Gateway off-site, el usuario abandona temporalmente el checkout para completar el pago en otro sistema.
Por ejemplo:
Drupal Commerce
↓
Checkout
↓
Redirect
↓
Payment Provider
↓
Customer pays
↓
Redirect back
↓
Drupal CommerceUn ejemplo conceptual típico es:
Pay with PayPal
↓
paypal.com
↓
Approve payment
↓
Return to store16. On-site frente a Off-site
Podemos resumir:
ON-SITE
Customer
↓
Drupal Checkout
↓
Provider API
OFF-SITE
Customer
↓
Drupal Checkout
↓
Provider Website
↓
Drupal CommerceLa experiencia y los requisitos técnicos son diferentes.
17. Manual Payment Gateway
No todos los pagos necesitan una API externa.
Podemos tener métodos manuales como:
Bank Transfer
Cash
Check
Invoice
Cash on DeliveryPor ejemplo:
Order placed
↓
Customer receives bank details
↓
Customer transfers money
↓
Administrator confirms payment
↓
Payment completedEsto es especialmente útil en ciertos proyectos B2B.
18. Autorizar frente a cobrar
Cuando trabajamos con tarjetas aparece una diferencia muy importante:
Authorization
≠
CapturePodemos pensar en una autorización como:
Confirmar que el importe puede cobrarse y reservar esa capacidad de pago.
Mientras la captura representa:
Solicitar realmente el cobro del importe previamente autorizado.
19. Authorize and Capture
El flujo más sencillo es realizar ambas operaciones inmediatamente.
Customer pays
↓
Authorize
↓
Capture
↓
Payment completedDesde el punto de vista del usuario parece una única operación.
Por ejemplo:
Order
100 EUR
Customer clicks Pay
↓
Authorization
100 EUR
↓
Capture
100 EUR
↓
Payment
CompletedEste modelo es habitual cuando queremos cobrar inmediatamente.
20. Authorize Only
También podemos autorizar primero y capturar posteriormente.
Checkout
Order:
100 EUR
↓
Authorization:
100 EUR
↓
Order processing
↓
Capture:
100 EUR
↓
Completed PaymentEsto puede ser útil cuando existe un intervalo entre realizar el pedido y confirmar que realmente podremos cumplirlo.
21. Ejemplo de autorización y captura
Supongamos que vendemos un producto físico.
Customer places order
↓
Authorize 500 EUR
↓
Check inventory
↓
Prepare shipment
↓
Capture 500 EUR
↓
ShipAsí podemos evitar cobrar definitivamente antes de saber que podremos entregar el producto.
22. Payment Authorization State
Después de autorizar:
Payment
Amount:
500 EUR
State:
AuthorizationPosteriormente:
Capture
↓
Payment
State:
CompletedEl Payment cambia de estado conforme evoluciona la transacción financiera.
23. Capture
La operación Capture solicita al proveedor completar el cobro de un Payment previamente autorizado.
Conceptualmente:
Payment
State:
Authorization
Amount:
500 EUR
↓
Capture
↓
State:
CompletedDependiendo del proveedor puede existir también captura parcial.
24. Partial Capture
Supongamos:
Authorization
500 EURpero solamente podemos enviar parte del pedido.
El Gateway podría permitir:
Capture
300 EUREste tipo de proceso depende de las capacidades del proveedor y de la integración Commerce utilizada.
No debemos asumir que todos los Gateways soportan las mismas operaciones.
25. Void
Una autorización que todavía no ha sido capturada puede, cuando el proveedor lo permite, ser anulada mediante Void.
Authorization
500 EUR
↓
Order canceled
↓
Void authorizationConceptualmente estamos diciendo:
No vamos a utilizar esta autorización para realizar el cobro.
26. Void frente a Refund
Esta diferencia es muy importante.
VOID
Authorization exists
↓
Money not captured
↓
Cancel authorizationMientras:
REFUND
Money already captured
↓
Return moneyPor tanto:
Before capture
↓
Void
After capture
↓
RefundLa operación exacta dependerá siempre de las capacidades del proveedor.
27. Refund
Cuando un Payment ya fue completado podemos necesitar devolver dinero.
Por ejemplo:
Payment
100 EUR
Completed
↓
Refund
100 EUR
↓
Payment
RefundedEl Refund representa una operación financiera sobre un Payment existente.
28. Partial Refund
No todos los reembolsos necesitan devolver el importe completo.
Por ejemplo:
Payment
100 EUR
Completed
↓
Refund
25 EUR
↓
Payment
Partially RefundedPosteriormente podríamos devolver el resto.
Additional Refund
75 EUR
↓
Payment
Refunded29. Cancelar un Order no devuelve automáticamente el dinero conceptualmente
Esta separación merece especial atención.
Podemos hacer:
Order
↓
Cancel
↓
CanceledPero si el cliente ya pagó:
Payment
↓
Still CompletedNecesitamos definir qué debe ocurrir financieramente.
Por ejemplo:
Cancel Order
↓
Refund Payment
↓
Release Stock
↓
Notify ERPEstas son operaciones relacionadas, pero conceptualmente independientes.
30. Refund no significa necesariamente Return
Otro concepto diferente es la devolución física del producto.
Podemos tener:
Customer returns product
↓
Warehouse receives item
↓
Return approved
↓
Refund paymentPero:
Return
≠
RefundReturn pertenece al proceso logístico/comercial.
Refund pertenece al proceso financiero.
Un sistema avanzado puede necesitar modelar ambos explícitamente.
31. El Payment Gateway define sus capacidades
No todos los Gateways soportan:
Authorization
Capture
Partial Capture
Void
Refund
Partial Refund
Stored Payment MethodsPor ejemplo, un Gateway puede soportar:
Authorize
Capture
Refundmientras otro solamente:
Immediate paymentPor eso seleccionar un proveedor de pagos requiere analizar primero los procesos del negocio.
32. Antes de elegir Stripe, PayPal u otro proveedor
No deberíamos comenzar preguntando:
¿Qué módulo de Stripe instalamos?
Primero deberíamos responder:
- ¿Queremos cobrar inmediatamente?
- ¿Necesitamos autorización y captura posterior?
- ¿Necesitamos pagos recurrentes?
- ¿Necesitamos guardar Payment Methods?
- ¿Necesitamos partial refunds?
- ¿Qué monedas utilizamos?
- ¿En qué países operamos?
- ¿Qué métodos esperan nuestros clientes?
Después podemos evaluar qué proveedor y módulo satisface esos requisitos.
33. Test Mode y Live Mode
Los Gateways suelen tener un entorno de prueba y otro de producción.
Conceptualmente:
TEST
Drupal
↓
Payment Gateway
↓
Provider Sandboxy:
LIVE
Drupal
↓
Payment Gateway
↓
Provider ProductionDurante desarrollo debemos utilizar credenciales de prueba.
Los pagos no deberían convertirse accidentalmente en transacciones reales.
34. Configuración y secretos
Los Payment Gateways suelen requerir datos como:
Public Key
Secret Key
Merchant ID
Client ID
Client Secret
Webhook SecretNo todos estos valores deberían tratarse como configuración pública exportable.
Debemos distinguir entre:
Commerce configuration
↓
Config
Credentials / secrets
↓
Environment-specific secret managementEsto es especialmente importante cuando trabajamos con repositorios Git y varios entornos.
35. Development, Staging y Production
Podemos tener:
Development
Stripe Test
Test credentials
Staging
Stripe Test
Different test credentials
Production
Stripe Live
Production credentialsEl modelo de despliegue debe permitir compartir la configuración funcional sin exponer credenciales sensibles.
36. Webhooks y notificaciones asíncronas
No siempre conocemos el resultado definitivo de un pago inmediatamente.
Por ejemplo:
Customer
↓
Drupal
↓
Provider
↓
Processing
↓
Drupal continuesPosteriormente:
Payment Provider
↓
Webhook
↓
Drupal Commerce
↓
Update PaymentLos proveedores pueden enviar notificaciones asíncronas cuando cambia una transacción.
37. Por qué los Webhooks son importantes
Supongamos un pago off-site.
Drupal
↓
PayPal
↓
Customer paysEl cliente podría cerrar el navegador antes de regresar al sitio.
No podemos depender exclusivamente de:
Customer returns to Drupalpara saber que el pago ocurrió.
El proveedor puede informar directamente:
PayPal
↓
Webhook
↓
Drupal
↓
Payment completedEsto hace el sistema más robusto.
38. Remote ID
Un Payment suele necesitar relacionarse con la transacción existente en el proveedor externo.
Conceptualmente:
Drupal Payment
ID:
481
Remote ID:
pi_3ABC123XYZMientras en el proveedor:
Payment Provider
Transaction:
pi_3ABC123XYZEsta relación permite posteriormente realizar operaciones como:
Capture
Void
Refundsobre la transacción correcta.
39. No guardar datos sensibles innecesariamente
Un principio fundamental en pagos es minimizar los datos financieros sensibles gestionados directamente por nuestra aplicación.
Por ejemplo, no deberíamos diseñar campos Drupal como:
field_credit_card_number
field_cvvpara almacenar tarjetas.
Debemos utilizar las soluciones seguras proporcionadas por el Payment Provider y el módulo de integración.
Conceptualmente:
Sensitive Payment Data
↓
Payment Provider
Drupal
↓
Token / Reference
↓
Safe metadata40. PCI DSS
Cuando manejamos pagos con tarjeta también debemos considerar los requisitos de seguridad de la industria de pagos.
La arquitectura seleccionada puede modificar significativamente las responsabilidades de cumplimiento.
Una integración moderna intenta normalmente reducir la cantidad de información sensible que atraviesa directamente nuestro servidor.
Este aspecto debe evaluarse junto con el Payment Provider y la implementación concreta utilizada.
41. Ejemplo B2C: pago inmediato
Supongamos una tienda de ropa.
Order Total
100 EUR
↓
Checkout
↓
Payment Method
Visa **** 4242
↓
Gateway
Stripe
↓
Authorize + Capture
↓
Payment
100 EUR
Completed
↓
Order
FulfillmentDespués:
Warehouse
↓
Shipping
↓
Order CompletedPayment y Order evolucionan independientemente.
42. Ejemplo B2C: autorización primero
Supongamos ahora que queremos verificar stock antes de cobrar definitivamente.
Checkout
↓
Authorize 500 EUR
↓
Payment
Authorization
↓
Warehouse confirms availability
↓
Capture 500 EUR
↓
Payment
Completed
↓
ShipSi no podemos entregar:
Authorization
↓
Void
↓
Cancel Order43. Ejemplo B2B: pago mediante factura
Un proyecto B2B puede funcionar de manera completamente diferente.
Distributor
↓
Checkout
↓
Purchase Order Number
↓
Order placed
↓
ERP
↓
Invoice
↓
Payment after 30 daysNo necesitamos obligatoriamente un pago online durante checkout.
Posteriormente un administrador o integración podría registrar:
Manual Payment
Bank Transfer
5000 EUR
CompletedEsto demuestra que Commerce Payment no está limitado a tarjetas de crédito.
44. Ejemplo Off-site
Supongamos:
Customer
↓
Checkout
↓
PayPal selected
↓
Redirect to PayPal
↓
Customer approves
↓
PayPal processes
↓
Return to Drupal
↓
Order completedEn paralelo:
PayPal
↓
Webhook
↓
Drupal
↓
Payment state synchronizedEl flujo de navegador y el flujo de comunicación servidor-servidor pueden coexistir.
45. Ejemplo de reembolso
Supongamos:
Order #1001
Total:
200 EUR
Payment:
200 EUR
CompletedEl cliente devuelve uno de los productos.
Returned Product:
50 EURPodemos realizar:
Refund
50 EUREntonces:
Payment
Original:
200 EUR
Refunded:
50 EUR
Net:
150 EUR
State:
Partially RefundedEl Order Workflow y el proceso de Return pueden necesitar lógica adicional, pero el Refund pertenece al Payment.
46. Payment no debería determinar por sí solo el Order Workflow
Puede ser tentador implementar:
Payment Completed
↓
Order CompletedPero normalmente esto sería incorrecto para productos físicos.
Un pago completado solamente significa:
Financial obligation
↓
satisfiedEl Order todavía puede necesitar:
Picking
Packing
Shipping
DeliveryPor tanto podríamos tener:
Payment
Completed
Order
Fulfillmenty solamente más tarde:
Order
Completed47. Tampoco debemos confundir Payment Failed con Order Canceled
Supongamos que una tarjeta es rechazada.
Payment attempt
↓
FailedEso no significa necesariamente:
Order
CanceledPodemos permitir:
Payment failed
↓
Choose another Payment Method
↓
Try again
↓
Payment completedEl Order puede continuar existiendo como Draft durante este proceso.
48. Idempotencia y pagos
Las integraciones de pago deben diseñarse con especial cuidado para evitar ejecutar dos veces la misma operación.
Por ejemplo:
User clicks Pay
↓
Request sent
↓
Slow response
↓
User clicks Pay againNo queremos terminar con:
Payment #1
100 EUR
Payment #2
100 EURLos proveedores y módulos de pago modernos ofrecen mecanismos para reducir este riesgo, pero debemos considerarlo especialmente cuando desarrollamos integraciones personalizadas.
49. No implementar nosotros mismos lo que ya hace el Gateway
Cuando utilizamos un módulo de integración consolidado deberíamos aprovechar su arquitectura.
No deberíamos crear soluciones paralelas como:
Custom Stripe API calls
inside checkout formsi el Gateway ya proporciona:
Payment Method creation
Payment creation
Authorization
Capture
Refund
Webhook handlingUtilizar las APIs de Commerce permite que nuestro sistema continúe siendo extensible y mantenible.
50. Cómo seleccionar un Payment Gateway
Antes de seleccionar un proveedor o módulo deberíamos construir una pequeña matriz de requisitos.
Requirement Required?
Credit cards Yes
PayPal Yes
Stored methods Yes
Authorize / Capture Yes
Partial refund Yes
EUR Yes
CHF Yes
Recurring payments Future
Off-site payments OptionalDespués podemos comparar los proveedores disponibles.
Esto es mucho mejor que seleccionar primero un proveedor y adaptar después el negocio a sus limitaciones.
51. Preguntas para Payment Discovery
Proveedores
- ¿Qué Payment Providers utiliza actualmente el cliente?
- ¿Existen contratos existentes?
- ¿Qué países soportan?
- ¿Qué monedas soportan?
Payment Methods
- ¿Tarjetas?
- ¿PayPal?
- ¿Transferencia bancaria?
- ¿Wallets?
- ¿Invoice?
Checkout
- ¿Pago on-site u off-site?
- ¿Pago obligatorio durante checkout?
- ¿Se pueden guardar métodos?
Transaction
- ¿Authorize + Capture inmediato?
- ¿Authorize Only?
- ¿Cuándo se realiza Capture?
Refunds
- ¿Necesitamos refunds?
- ¿Partial refunds?
- ¿Quién puede ejecutarlos?
Orders
- ¿Qué debe ocurrir cuando el Payment se completa?
- ¿Qué debe ocurrir cuando falla?
- ¿Qué ocurre al cancelar el Order?
Integraciones
- ¿ERP?
- ¿Accounting?
- ¿Invoice system?
- ¿Fraud service?
Operaciones
- ¿Quién gestiona refunds?
- ¿Quién revisa pagos fallidos?
- ¿Quién realiza captures manuales?
52. Una matriz para separar conceptos
Podemos utilizar esta guía:
¿Quién procesa realmente el dinero?
↓
Payment Provider
¿Cómo se conecta Commerce?
↓
Payment Gateway
¿Con qué paga el cliente?
↓
Payment Method
¿Qué transacción monetaria ocurrió?
↓
Payment
¿Solo reservamos capacidad de cobro?
↓
Authorization
¿Realizamos el cobro?
↓
Capture
¿Cancelamos una autorización?
↓
Void
¿Devolvemos dinero ya cobrado?
↓
Refund53. Modelo mental completo
Podemos integrar todo lo estudiado:
CUSTOMER
│
▼
CART / ORDER
│
▼
CHECKOUT
│
▼
PAYMENT METHOD
│
▼
PAYMENT GATEWAY
│
▼
PAYMENT PROVIDER
│
├── Authorize
│
├── Capture
│
├── Void
│
└── Refund
│
▼
PAYMENT
│
├── Amount
├── State
├── Gateway
└── Remote transaction
│
▼
ORDER PAID STATUSMientras el Order continúa su propio proceso:
ORDER
Draft
↓
Placed
↓
Fulfillment
↓
CompletedY el Payment puede seguir:
PAYMENT
New
↓
Authorization
↓
Completed
↓
Partially Refunded
↓
RefundedAmbos workflows se relacionan, pero no representan lo mismo.
54. La regla de las cinco preguntas
Podemos resumir el diseño de Payments mediante cinco preguntas:
1. ¿Quién procesa el dinero?
↓
Payment Provider
2. ¿Cómo se integra Commerce?
↓
Payment Gateway
3. ¿Con qué paga el cliente?
↓
Payment Method
4. ¿Qué operación financiera ocurrió?
↓
Payment
5. ¿Qué debemos hacer después?
↓
Order / Fulfillment / Integration logicConclusión
El sistema de Payments de Drupal Commerce separa cuidadosamente las diferentes responsabilidades que intervienen en una transacción financiera.
Podemos resumirlas así:
Payment Provider
= servicio que procesa
realmente la transacción
Payment Gateway
= integración entre Commerce
y el proveedor
Payment Method
= instrumento utilizado
por el cliente
Payment
= registro de una
transacción financiera
Authorization
= reserva la posibilidad
de cobrar
Capture
= ejecuta el cobro
Void
= cancela una autorización
Refund
= devuelve dinero
previamente cobradoLa separación más importante continúa siendo:
Checkout
= experiencia de compra
Order
= transacción comercial
Payment
= transacción financiera
Shipping / Fulfillment
= cumplimiento de la compraCuando entendemos estas diferencias podemos diseñar correctamente tanto una tienda B2C con Stripe como un sistema B2B con transferencias, pagos diferidos o facturación.
También podemos evaluar proveedores de pago basándonos en necesidades reales en lugar de simplemente instalar el primer módulo disponible.
En el siguiente artículo estudiaremos la otra gran pieza de una tienda de productos físicos: Shipping y Fulfillment en Drupal Commerce.
Veremos Shipments, Shipping Methods, Shipping Services, Packages, perfiles de envío, tarifas, peso, zonas, promociones de envío y cómo separar correctamente el cálculo del transporte del proceso real de fulfillment.