La lógica de pago es fundamental para cualquier producto que se ocupe del dinero. Después de todo, una arquitectura de pago bien diseñada, si se prueba adecuadamente, ahorra toneladas de tiempo en el futuro.
Pero puede llevar demasiado tiempo dominar el nivel superior de trabajo con las pasarelas de pago populares.
Para ayudarte, escribí esta guía sobre el diseño de la lógica de pago en Stripe. Incluye casos de uso, ejemplos de proyectos y un poco de teoría con ejemplos de código.
Esta guía es principalmente para ingenieros de control de calidad, ya que ayuda a comprender cómo probar la lógica de pago basada en Stripe. Pero no salgan, PMs y desarrolladores. También tenemos muchos detalles interesantes para ti.

Cómo funciona Stripe

Comencemos con lo básico y revisemos el esquema de pago de Stripe.
Esquema de pago para Stripe
Este esquema funciona para usuarios que compran contenido en sitios web o mediante aplicaciones móviles. Los visitantes no necesitan registrarse y agregar tarjetas de crédito de enlace a sus perfiles: Stripe permite pagar el contenido sin problemas.
Todo lo que necesitan hacer es ingresar los datos de la tarjeta de crédito, y ocurre la magia:
  1. Las credenciales se envían a Stripe.
  2. Stripe tokeniza los datos y devuelve un token al back-end.
  3. El back-end crea una carga.
  4. Los datos se envían a Stripe nuevamente y comparte los detalles con los sistemas de pago.
  5. Los sistemas de pago responden a Stripe e indican si todo está bien. O informar sobre problemas.
  6. Stripe responde al servidor sobre el estado de la transacción.
Si todo va bien, el usuario obtiene contenido. Si no, un mensaje de error.
Además, hay dos condiciones necesarias para usar Stripe:
  • tienes una cuenta bancaria
  • usted es residente de uno de los 25 países admitidos

Conectar una tarjeta a Stripe

Vincular al usuario de su producto con el cliente de Stripe va del lado del servidor. Y se ve así:
  1. Las credenciales de la tarjeta de crédito van a Stripe (desde la aplicación o el sitio web);
  2. Stripe devuelve un token, luego va al back-end;
  3. El back-end lo devuelve a Stripe;
  4. Stripe comprueba si el cliente existe (en caso afirmativo, la tarjeta se agrega, no, crea un nuevo cliente y agrega la tarjeta).
La primera tarjeta agregada es el método de pago predeterminado. Stripe lo usará para realizar la transacción.

Conectando con una cuenta Stripe

Si está creando una aplicación a pedido como Uber y desea que se les pague a los usuarios (como los controladores de Uber), pídales que creen una cuenta primero.
Hay tres tipos de cuentas Stripe:
  • Estándar . Una cuenta ya existente con las credenciales requeridas. Registrado por el usuario, validado por Stripe y un banco.
  • Expresar . Permite una incorporación fácil: crea una cuenta por su cuenta y el usuario la llena con detalles. Trabaja dentro de los Estados Unidos.
  • Costumbre . Viene con el más alto nivel de flexibilidad y le permite modificar múltiples parámetros. A su vez, la plataforma es responsable de cada interacción con los usuarios.

Características principales de Stripe

Todavía sobre el tema de cómo funciona Stripe, sugiero echar un vistazo a sus características.

Cargos

Stripe realiza dos tipos de cargos: directo y de destino .
Carga directa
Volvamos al modelo de Uber. La plataforma cobra una cierta cantidad de los usuarios, y ese dinero va directamente a las cuentas vinculadas, a los conductores. El cargo directo implica que los conductores pagan todas las tarifas. Además, Uber también cobra un porcentaje fijo.

Cargo de destino
En este caso, la plataforma paga todas las tarifas y usted obtiene el patrimonio neto. Primero, la cantidad va a la cuenta de Stripe de su plataforma, y ​​luego hay una transferencia automática al socio (controladores).

Autorizar y capturar

Stripe admite pagos en dos pasos que permiten a los usuarios autorizar un cargo primero y capturarlo más tarde. Los emisores de tarjetas garantizan que los pagos de autenticación y la cantidad requerida se congelen en la tarjeta del cliente.
Si el cargo no se captura para este período, la autorización se cancela.
Así es como funciona en Uber: un conductor ve un costo aproximado del viaje al reservar el viaje. Si están de acuerdo, esta cantidad se congela en sus tarjetas hasta que terminen su viaje.
Cuando terminan el viaje, Uber calcula el precio final y lo carga de la tarjeta.
Esa es la razón por la cual los propietarios de productos eligen Stripe para el desarrollo de su aplicación de pago P2P . Como la confianza es lo más importante cuando se trata de transacciones entre pares.
Finalmente, aquí vienen otras tres características de Stripe que me gustaría mencionar.
Transferencias . Las transferencias van desde la cuenta de la plataforma a los proveedores. Por ejemplo, los controladores de Uber vinculan las cuentas de Stripe con sus perfiles para obtener el pago.
Suscripciones . Esta característica es bastante flexible y permite a los usuarios establecer intervalos, períodos de prueba y ajustar la suscripción a sus necesidades.
Los reembolsos . Si los compradores desean recuperar su dinero, los usuarios de Stripe pueden emitir fácilmente un reembolso a la tarjeta de los clientes.

Manejo de objetos de banda


A continuación, nos estamos moviendo a los objetos Stripe. Y aquí vienen los ejemplos de código que prometí.

Objeto fuente

Aquí hay una lista de verificación para el objeto fuente.
LLAVEVALOR
clienteID de la raya del cliente
carné de identidadstripe_id de la tarjeta agregada
last4últimos 4 números de tarjeta agregada
marcacompañía de tarjeta de crédito (Visa, AE)
exp_mes, exp_yearfecha de vencimiento de la tarjeta
El objeto mantiene un método de pago que ayuda a completar el cargo. También es posible vincular el objeto fuente con los usuarios. Esto les permite almacenar todos los métodos de pago allí.
Al realizar la prueba, es crucial asegurarse de que un método de pago se corresponde con el valor devuelto. Verifique last4 y exp_month / year para esto.
Si el objeto de origen está vinculado con un cliente y desea asegurarse de que pertenece a la persona correcta, verifique la identificación del cliente .
Aquí hay un JSON del objeto:
{
        "id": "card_1CboP4CLud4t5fBlZMiVrzBq",
        "object": "card",
        "address_city": null,
        "address_country": null,
        "address_line1": null,
        "address_line1_check": null,
        "address_line2": null,
        "address_state": null,
        "address_zip": null,
        "address_zip_check": null,
        "brand": "Visa",
        "country": "US",
        "customer": "cus_D1s9PQgvr6U46j",
        "cvc_check": "pass",
        "dynamic_last4": null,
        "exp_month": 4,
        "exp_year": 2024,
        "fingerprint": "soMjdt25OvcMcObY",
        "funding": "credit",
        "last4": "4242",
        "metadata": {},
        "name": null,
        "tokenization_method": null
      }

Objeto del cliente


Comenzando con la lista de verificación nuevamente.
LLAVEVALOR
suscripcionesla lista de suscripciones
carné de identidadcliente stripe_id
default_sourcestripe_id de la tarjeta predeterminada
fuenteslista de fuentes
El objeto de cliente almacena métodos de pago, incluido el predeterminado. Y contiene información sobre los usuarios y sus suscripciones.
También recuerda las tarjetas de crédito de los usuarios y el conjunto principal de métodos de pago. Puede cobrar a los usuarios manualmente en función de estos datos.
Lo mismo ocurre con las suscripciones: Stripe las administra y retira las tarifas automáticamente.
{
  "id": "cus_D1s9PQgvr6U46j",
  "object": "customer",
  "account_balance": 0,
  "created": 1528717303,
  "currency": null,
  "default_source": "card_1CboP4CLud4t5fBlZMiVrzBq",
  "delinquent": false,
  "description": null,
  "discount": null,
  "email": null,
  "invoice_prefix": "4A178DE",
  "livemode": false,
  "metadata": {},
  "shipping": null,
  "sources": {
    "object": "list",
    "data": [
      {
        "id": "card_1CboP4CLud4t5fBlZMiVrzBq",
        "object": "card",
        "address_city": null,
        "address_country": null,
        "address_line1": null,
        "address_line1_check": null,
        "address_line2": null,
        "address_state": null,
        "address_zip": null,
        "address_zip_check": null,
        "brand": "Visa",
        "country": "US",
        "customer": "cus_D1s9PQgvr6U46j",
        "cvc_check": "pass",
        "dynamic_last4": null,
        "exp_month": 4,
        "exp_year": 2024,
        "fingerprint": "soMjdt25OvcMcObY",
        "funding": "credit",
        "last4": "4242",
        "metadata": {},
        "name": null,
        "tokenization_method": null
      },
      {
        "id": "card_1CcC3uCLud4t5fBlW2UMknUW",
        "object": "card",
        "address_city": null,
        "address_country": null,
        "address_line1": null,
        "address_line1_check": null,
        "address_line2": null,
        "address_state": null,
        "address_zip": null,
        "address_zip_check": null,
        "brand": "Visa",
        "country": "US",
        "customer": "cus_D1s9PQgvr6U46j",
        "cvc_check": "pass",
        "dynamic_last4": null,
        "exp_month": 4,
        "exp_year": 2024,
        "fingerprint": "soMjdt25OvcMcObY",
        "funding": "credit",
        "last4": "4242",
        "metadata": {},
        "name": null,
        "tokenization_method": null
      }
    ],
    "has_more": false,
    "total_count": 2,
    "url": "/v1/customers/cus_D1s9PQgvr6U46j/sources"
  },
  "subscriptions": {
    "object": "list",
    "data": [],
    "has_more": false,
    "total_count": 0,
    "url": "/v1/customers/cus_D1s9PQgvr6U46j/subscriptions"
  }
}

Objeto de carga

Lista de verificación para el objeto de carga:
LLAVEVALOR
destinocuenta de rayas del beneficiario
carné de identidadcargar stripe_id
cantidadmonto de pago en centavos
Cantidad reembolsadacantidad reembolsada en centavos
clientecustomer_id de un pagador
capturadoverdadero - el pago se realiza, falso - autorizado
  • cantidad : siempre debe verificar qué cantidad se cobró durante el proceso de prueba. Puede ser en centavos, centavos de euro, etc.
  • cantidad_refinanciada : este campo tiene un valor diferente de cero si se reembolsó la cantidad total de la transacción (o su parte).
  • cliente - identificación de su cliente
  • capturado : indica el estado de la transacción. El dinero puede ser retenido en la tarjeta de crédito del usuario o puede ser cargado.
  • destino : la clave de destino almacenará la cuenta Stripe del usuario a la que ha transferido el dinero.
"fingerprint": "soMjdt25OvcMcObY",
    "funding": "credit",
    "last4": "4242",
    "metadata": {},
    "name": null,
    "tokenization_method": null
  },
  "source_transfer": null,
  "statement_descriptor": null,
  "status": "succeeded",
  "transfer_group": null
}
Objeto de reembolso
El objeto de reembolso está incrustado en el objeto de cargo en caso de que alguna parte del pago (o el pago completo) se reembolse al comprador.
LLAVEVALOR
estadoéxito / pendiente / fallido
carné de identidadreembolso stripe_id
cantidadmonto de pago en centavos
{
  "id": "re_1CcY10CLud4t5fBlN23KtYq7",
  "object": "refund",
  "amount": 999,
  "balance_transaction": "txn_1CcY10CLud4t5fBlhlmzzJuK",
  "charge": "ch_1CcD7dCLud4t5fBlC1srZNIB",
  "created": 1528892634,
  "currency": "usd",
  "metadata": {},
  "reason": null,
  "receipt_number": null,
  "status": "succeeded"
}
Objeto de transferencia
LLAVEVALOR
reversioneslista de objetos de transferencia inversa
carné de identidadIdentificación de Transferencia
cantidadmonto de pago en centavos
destinocuenta vinculada de un beneficiario
invertidofalso - transacción de dinero, verdadero - reverso
El objeto de transferencia mantiene información relacionada con la transferencia del saldo de la plataforma a otras cuentas. Al igual que los pagos a los socios de la plataforma: los conductores de Uber.
Tenga en cuenta que todas las transacciones deben iniciar sesión en la base de datos. De esta manera, durante la prueba, verá la identificación de la transferencia. Vaya a Stripe y verifique lo siguiente:
  • cantidad - la suma pagada a un beneficiario
  • destino : cuenta de Stripe del usuario que recibe el pago
  • invertido : si necesita cancelar una transacción, la tecla actúa como un indicador. Muestra un valor falso si la transacción tuvo éxito. Verdadero: si se invierte
  • reversiones : almacena una lista de objetos en caso de que se invierta alguna parte de la transferencia
{
  "id": "tr_1CcApyCLud4t5fBlZyx5mEPI",
  "object": "transfer",
  "amount": 250,
  "amount_reversed": 0,
  "balance_transaction": "txn_1CcApyCLud4t5fBlfA5cgXBz",
  "created": 1528803538,
  "currency": "usd",
  "description": null,
  "destination": "acct_18bAS3KcT341ksb9",
  "destination_payment": "py_1CcApyKcT341ksb9VawxIJdS",
  "livemode": false,
  "metadata": {},
  "reversals": {
    "object": "list",
    "data": [],
    "has_more": false,
    "total_count": 0,
    "url": "/v1/transfers/tr_1CcApyCLud4t5fBlZyx5mEPI/reversals"
  },
  "reversed": false,
  "source_transaction": null,
  "source_type": "card",
  "transfer_group": null
}
Objeto de transacción de saldo
LLAVEVALOR
tipotipo de transacción (cargo, reembolso, transferencia)
carné de identidadreembolso stripe_id
cantidadmonto del pago en centavos (preste atención a los signos +/-)
disponible enfecha en que el dinero estará disponible para un beneficiario
cuotacantidad de tarifa de Stripe
detalles de tarifalista de objetos de tarifa
redmonto de ingreso / gasto neto
estadoestado actual de la operación
El objeto almacena datos sobre cualquier cambio en el saldo de la aplicación. En realidad no necesitas probar este objeto. Es más bien para entender de dónde provienen las tarifas.
  • monto - monto del pago en centavos
  • available_on : el dinero enviado a los socios estará disponible para ellos a tiempo, y esta clave indica cuándo exactamente
  • tarifa - importe de la tarifa de Stripe
  • fee_details : lista de objetos de tarifa con una descripción de por qué se cobró la tarifa
  • neto - cantidad de ingreso neto
  • estado : el estado del éxito de la operación
  • tipo - tipo del objeto (cargo, reembolso, transferencia)
Ejemplo de código de transacción de saldo para transferencia:
{
  "id": "txn_1CcApyCLud4t5fBlfA5cgXBz",
  "object": "balance_transaction",
  "amount": -250,
  "available_on": 1528803538,
  "created": 1528803538,
  "currency": "usd",
  "description": null,
  "exchange_rate": null,
  "fee": 0,
  "fee_details": [],
  "net": -250,
  "source": "tr_1CcApyCLud4t5fBlZyx5mEPI",
  "status": "available",
  "type": "transfer"
}
Muestra de código de transacción de saldo por cargo:
{
  "id": "txn_1CbrRTCLud4t5fBlhRfMLdq1",
  "object": "balance_transaction",
  "amount": 10000,
  "available_on": 1529280000,
  "created": 1528728983,
  "currency": "usd",
  "description": "Charge user asdf11@example.com for instructor sodom@example.com lesson id: 77",
  "exchange_rate": null,
  "fee": 320,
  "fee_details": [
    {
      "amount": 320,
      "application": null,
      "currency": "usd",
      "description": "Stripe processing fees",
      "type": "stripe_fee"
    }
  ],
  "net": 9680,
  "source": "ch_1CbrP3CLud4t5fBlztHMxVzv",
  "status": "pending",
  "type": "charge"
}
Objeto de suscripción
LLAVEVALOR
planreglas para la suscripción: cantidad, intervalo, días de prueba
carné de identidadsuscripción stripe_id
application_fee_percent% cobrado por la suscripción
facturacióncarga automática o envío de factura
billing_cycle_anchorhora del siguiente ciclo de suscripción
current_period_start current_period_endplazos del período de suscripción actual
  • application_fee_percent : porcentaje del importe total que cobra la aplicación, el resto lo paga el propietario del contenido
  • facturación : responsable de cómo va el proceso de facturación, de forma automática o manual (a través de la factura)
  • billing_cycle_anchor : contiene la fecha de vencimiento del próximo pago para la renovación de la suscripción
  • current_period_start & current_period_end : período de validez de la suscripción del cliente
  • plan : almacena el objeto de un plan de suscripción, incluye un conjunto de reglas (cantidad a pagar, intervalo, número de días de prueba y más)
{
  "id": "sub_D2JskPBqcW24hu",
  "object": "subscription",
  "application_fee_percent": null,
  "billing": "charge_automatically",
  "billing_cycle_anchor": 1528820423,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "created": 1528820423,
  "current_period_end": 1531412423,
  "current_period_start": 1528820423,
  "customer": "cus_D2Jsi3JgT5zPh1",
  "days_until_due": null,
  "discount": null,
  "ended_at": null,
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_D2Js7N4mYxzAaY",
        "object": "subscription_item",
        "created": 1528820424,
        "metadata": {
        },
        "plan": {
          "id": "ivory-express-917",
          "object": "plan",
          "active": true,
          "aggregate_usage": null,
          "amount": 999,
          "billing_scheme": "per_unit",
          "created": 1528819224,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "name": "Ivory Express",
          "nickname": null,
          "product": "prod_D2JYysdjdQ2gwT",
          "statement_descriptor": null,
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "quantity": 1,
        "subscription": "sub_D2JskPBqcW24hu"
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_D2JskPBqcW24hu"
  },
  "livemode": false,
  "metadata": {
  },
  "plan": {
    "id": "ivory-express-917",
    "object": "plan",
    "active": true,
    "aggregate_usage": null,
    "amount": 999,
    "billing_scheme": "per_unit",
    "created": 1528819224,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "name": "Ivory Express",
    "nickname": null,
    "product": "prod_D2JYysdjdQ2gwT",
    "statement_descriptor": null,
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "start": 1528820423,
  "status": "active",
  "tax_percent": null,
  "trial_end": null,
  "trial_start": null
}

Casos de uso

Finalmente, pasamos a usar casos. Así que veamos cómo construimos la lógica de negocios usando Stripe.

Suscripciones

Caso : los usuarios pagan $ 5 / mes para obtener acceso al contenido. Su autor gana el 80% del costo total. Los clientes tienen cinco días de prueba.
Cómo hacer que funcione:
  1. Cree el plan de suscripción en Stripe, especifique el costo, el% de la tarifa de la aplicación y el intervalo.
  2. Integre webhooks para que el servidor comprenda cuándo alguien se suscribe y cuándo se le cobra.
  3. Integre los correos electrónicos para enviar a los usuarios facturas / recibos.
  4. Cuando un usuario compra la suscripción, Stripe cuenta cinco días a partir de ese momento y luego realiza el cargo.
  5. El autor obtiene dinero, la plataforma recibe su tarifa.
Tarifa : 2.9% + 30 centavos

Compra de contenido


Caso : Los usuarios compran contenido en un sitio web o aplicación móvil.
Cómo hacer que funcione:
  1. El cliente tokeniza una tarjeta.
  2. Backend hace la carga.
  3. Si el Cargo es exitoso, la lógica de negocios de la plataforma le permite al cliente obtener el contenido.
Tarifas : 2.9% del cargo + 30 centavos.

Plataforma bajo demanda (Uber)

Caso : el cliente paga el viaje, la plataforma cobra el 20%, el conductor obtiene el 80%.
Condiciones previas :
  • El conductor ha vinculado una cuenta
  • El usuario agregó una tarjeta
En este caso, debe crear transferencias por su cuenta después de que el usuario complete el pago.
Primero, autorice el pago cuando reserven el viaje y captúrelo cuando se complete el viaje.
Luego, cree una transferencia para el conductor: 80% de la suma total. Pague la tarifa de Stripe, y el resto será el ingreso neto.
Y la tarifa es : 2.9% + 30 centavos

Plataforma bajo demanda # 2

Las aplicaciones tipo Uber son perfectas para mostrar cómo funciona Stripe. Así que aquí va otro caso de uso.
Caso : el cliente paga por el servicio, la plataforma cobra el 20%, el conductor obtiene el 80%. Además, el conductor puede pagar $ 5 por el derecho de reserva prioritario.
Funciona si el conductor vinculó su cuenta y el usuario agregó una tarjeta de crédito.
  • Variante # 1. Usted cobra $ 5 del conductor (en el caso de la opción de prioridad), autoriza el pago para el cliente, realiza la captura cuando finaliza el viaje, realiza una transferencia para el conductor. Y quédate el resto. En este caso, paga una tarifa de 2.9% + 30 centavos por cada cargo.
  • Variante # 2. Puede saltarse las tarifas creando la monetización interna en su plataforma. Cuando recibe dinero del cliente, calcula la participación del conductor y transfiere esos fondos al saldo interno.
Flujo de fondos

En conclusión


Como puede ver, la implementación de la lógica de pago y sus pruebas no son tan difíciles como parecen. Todo lo que necesita hacer es manejar los objetos Stripe de la manera correcta. Y descubra cómo usar Stripe en su plataforma.

Espero que esta guía le sea útil cuando comience a diseñar la lógica de pago basada en Stripe y sus pruebas.