En artículos anteriores, analizamos los principios generales de la organización de una pasarela de pago bitcoin, descubrimos las herramientas y el software necesarios e incluso montamos nuestra propia red bitcoin de bolsillo.
Para comprender los siguientes pasos, es recomendable tener al menos un conocimiento básico de qué es JSON y cómo funciona el protocolo http.
En resumen, JSON (Notación de objetos JavaScript) es un formato simple que permite transmitir datos heterogéneos en forma de texto sin formato. Es importante que JSON le permita no solo transferir datos, sino también restaurar su estructura. Inicialmente (como se puede adivinar fácilmente por el nombre) se propuso para el lenguaje JavaScript, pero debido a su simplicidad se generalizó bastante. Es interesante para nosotros principalmente porque esta es la forma de datos que se utiliza al intercambiar información entre nuestro código y bitcoind.
No daré ejemplos de código terminado. Ahora se utilizan diferentes lenguajes de programación para el desarrollo web, y describir ejemplos en cada uno de ellos está más allá del alcance y alcance de nuestra serie de artículos. En su lugar, mostraré el resultado de la ejecución usando curl, una utilidad de línea de comandos de Unix/Linux. En caso de que sea imposible prescindir de un ejemplo, utilizaré pseudocódigo.
Lo más importante que debemos entender ahora es cómo podemos interactuar con el servidor bitcoind y cómo podemos realizar las tareas más importantes y críticas para conseguir una pasarela de pago que funcione.
Primero, intentemos obtener información sobre el estado del nodo, pero no con el comando bitcoin-cli getwalletinfo, como hicimos antes, sino usando una solicitud RPC. Ejecutemos el siguiente comando:
curl --data-binary '{"jsonrpc":"1.0","method":"getwalletinfo","params":[]}' http://nombre de usuario:contraseña de usuario@localhost:18332
En este comando pasamos la solicitud JSON generada. En realidad, la llamada en sí: "method":"getwalletinfo". Esta solicitud se envía como una solicitud http normal a la dirección localhost:18332, es decir, nuestra máquina local y el puerto RPC que especificamos al configurar la red de prueba. Y username:userpassword - corresponde a los parámetros rpcuser y rpcpassword que especificamos en el mismo archivo de configuración. Como resultado, obtendremos algo como esto:
{
"resultado": {
"walletname": "wallet.dat",
"versión de billetera": 159900,
"saldo": 14717.18723440,
"saldo_no confirmado": 0.00000000,
"equilibrio_inmaduro": 78.12526560,
"cuentatx": 1002,
"keypoololdest": 1528970690,
"tamaño de grupo de claves": 999,
"keypoolsize_hd_internal": 1000,
"paytxfee": 0..00000000,
"hdmasterkeyid": "be875fb1dc27d408a5c032d8714cf21cbc3b9af0"
},
"error": nulo,
"identificación": nulo
}
El primer paso para recibir pagos utilizando bitcoin (como la mayoría de las criptomonedas) es obtener una nueva dirección única, que también servirá como identificador de pago. Esto es exactamente lo que hicimos cuando ejecutamos el comando bitcoin-cli getnewaddress. De hecho, este comando tiene parámetros adicionales, pero ahora no nos interesan. Intentemos hacer esto nuevamente (se supone que tiene bitcoind instalado y uno de prueba configurado, como se describe en artículos anteriores de la serie)
bitcoin-cli obtener nueva dirección 2N49FdQ7Ppb1W8BXfNYUPT4BcnWu5B4zFVt
Ahora necesitamos hacer lo mismo, pero usando JSON-RPC. La solicitud en sí tendrá el mismo formato que en el ejemplo anterior, solo que en lugar de "method":"getwalletinfo" especificaremos "method":"getnewaddress":
curl --datos-binario \
'{"jsonrpc":"1.0","method":"getnewaddress","params":[]}' \
http://nombre de usuario:contraseña de usuario@localhost:18332
Y el resultado será el siguiente:
{
"resultado": "2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF",
"error": nulo,
"identificación": nulo
}
Si nos fijamos bien en la estructura de la respuesta, veremos elementos comunes en ambos casos:
{
"resultado": ... ,
"error": nulo,
"identificación": nulo
}
El campo resultado contiene el resultado de la solicitud y error, en consecuencia, una descripción del error si la solicitud no se pudo completar. Como hemos hecho todo correctamente hasta ahora, nunca hemos observado que este campo no esté vacío (nulo). Pero la realidad no es tan despejada, por lo que al analizar la respuesta del servidor, siempre se debe verificar este campo en busca de errores, y solo entonces proceder a procesar el resultado.
Volvamos a nuestra nueva dirección.
Entonces, sabemos cómo obtener una nueva dirección, y esto se puede hacer en cantidades ilimitadas (bueno, dentro del marco de la vida humana, eso es seguro). ¿Qué debemos hacer exactamente con él a continuación? Al crear un formulario de pago para un cliente, le proporciona esta dirección, indicando el monto que se le debe transferir. Guarda la dirección en un lugar seguro, indicando a qué orden se aplica y a qué usuario se aplica. Ahora dejemos de lado los problemas de implementación de la interfaz, como el código QR, botones mágicos como "Pagar mediante billetera Bitcoin", ahora es importante que dominemos el principio en sí...
Después de recibir la dirección, debemos saber cuándo el cliente realizó el pago. Una de las formas más sencillas y obvias es comprobar periódicamente si se han recibido fondos o no. Por supuesto, podemos hacer esto a través de getwalletinfo, pero este comando nos mostrará el estado general de nuestra billetera y no indicará de ninguna manera quién realizó exactamente el pago. Si su tienda opera de forma semimanual, recibe pedidos varias veces al día y sus clientes lo necesitan más de lo que usted los necesita, puede solicitarle al cliente un número de transacción de bitcoin después del pago.
Pero esto, en primer lugar, es un inconveniente y, en segundo lugar, no resuelve el problema por completo. Pero supongamos que eligió esta opción. El usuario afirma haber pagado y te proporciona un número de transacción:
ce397d610c0066f1f4f38d532bc527daac3bd6aac25081618be63620d9078c7b
Puedes utilizar un explorador de bloques público como blockchain.info, pero claramente eso no es lo que estamos haciendo aquí. Sólo bitcoind, sólo hardcore. Intentemos verificar la transacción nosotros mismos usando la línea de comando:
bitcoin-cli gettransaction ce397d610c0066f1f4f38d532bc527daac3bd6aac25081618be63620d9078c7b
En respuesta, recibiremos algo como esto (si la transacción, por supuesto, realmente existe y se realizó a través de la red):
{
"cantidad": 0.00000000,
"tarifa": -0.00007880,
"confirmaciones": 0,
"confiable": verdadero,
"txid": "ce397d610c0066f1f4f38d532bc527daac3bd6aac25081618be63620d9078c7b",
"conflictos de billetera": [
],
"tiempo": 1529143485,
"tiemporecibido": 1529143485,
"bip125-reemplazable": "no",
"detalles": [
{
"cuenta": "",
"dirección": "2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF",
"categoría": "enviar",
"cantidad": -10.00000000,
"etiqueta": "",
"vout": 0,
"tarifa": -0.00007880,
"abandonado": falso
},
{
"cuenta": "",
"dirección": "2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF",
"categoría": "recibir",
"monto": 10.00000000,
"etiqueta": "",
"vout": 0
}
],
"hexadecimal": "02000000.....12bf2ed000e9030000"
}
He eliminado parte de la información para que sea más fácil de leer, pero en general esto es exactamente lo que obtendremos como respuesta. En primer lugar, siempre deberás prestar atención al parámetro confirmaciones; indica si la transacción está incluida en el bloque, es decir, si está confirmada. En Bitcoin, generalmente se acepta que una transacción se confirma después de 6 confirmaciones, pero últimamente a menudo se limitan a 3 o incluso a una confirmación. Lo segundo a lo que debemos prestar atención es a la lista details, que muestra todas las entradas y salidas de la transacción. Estamos interesados en bloques que contienen category": "receive . Esto es lógico, esperamos el pago... Y en estos bloques ya debemos buscar la dirección que le dimos al cliente y comparar la cantidad que envió. Tenemos mucha más información, pero esta es exactamente la información que nos interesa en primer lugar.
Hagamos lo mismo, pero usando una solicitud RPC:
curl --datos-binario \
'{"jsonrpc":"1.0","method":"gettransaction","params":["ce397d610c0066f1f4f38d532bc527daac3bd6aac25081618be63620d9078c7b"]}' \
http://nombre de usuario:contraseña de usuario@localhost:18332
No duplicaré la respuesta, es completamente idéntica a la recibida mediante la línea de comando. Pero en la propia solicitud tenemos algo nuevo. Preste atención al bloque "params". Dejó de estar vacío. En cambio, tenemos un número de transacción. Al realizar solicitudes RPC, recuerde que el orden de los parámetros es importante porque no tienen nombre. Lo necesitaremos en el siguiente ejemplo.
Por supuesto, pedirle al usuario un número de transacción no está de moda, es inconveniente y en general. Y tendremos que afrontar nosotros mismos el hecho del pago. No sabemos si hubo pago y en caso afirmativo, cuándo. Lo único que tenemos que hacer, como dije anteriormente, es verificar el estado de la dirección una vez por minuto.
bitcoin-cli getreceivedbyaddress 2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF
Nota para el propietario: al realizar la solicitud, por defecto en la respuesta solo veremos los fondos que ya han sido confirmados. Si queremos ver el hecho de un pago no confirmado, entonces debemos agregar 0 al final del comando.
Si queremos ver qué monto tiene, por ejemplo, al menos 6 confirmaciones, entonces debemos agregar 6 en consecuencia. Es decir, indicamos el número mínimo de confirmaciones que nos interesa. Intentemos ejecutar la misma solicitud, pero en forma de solicitud RPC.
curl --datos-binario \
'{"jsonrpc":"1.0","method":"getreceivedbyaddress","params":["2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF", 0]}' \
http://nombre de usuario:contraseña de usuario@localhost:18332
Y veremos un resultado similar al siguiente:
{
"resultado": 10.00000000,
"error": nulo,
"identificación": nulo
}
Vemos que una persona amable nos transfirió 10 bitcoins. Pero como especificamos el segundo parámetro 0 en la solicitud, no sabemos si tienen confirmaciones. Puede cambiar este parámetro, por ejemplo, a 1 y repetir la solicitud. Asumiremos que esto es tarea y que puedes manejarla por tu cuenta.
No hemos recibido demasiada información y puede generar preguntas. Por ejemplo, no sabemos el año en que se realizó el pago. El usuario podría, por ejemplo, pagar no con un solo pago, sino con varios.. En general me gustaría recibir más información. Bien, para esto, en lugar de getreceivedbyaddress podemos usar listreceivedbyaddress.
curl --data-binary '{"jsonrpc":"1.0","method":"listreceivedbyaddress","params":[]}' http://nombre de usuario:contraseña de usuario@localhost:18332
Este comando devolverá todos los pagos a todas nuestras direcciones emitidas con números de transacción.
{
"resultado": [
{
"dirección": "...",
"cuenta": "",
"cantidad": ...,
"confirmaciones": 7,
"etiqueta": "",
"txids": [
"..."
]
},
{
"dirección": "2NBqem3SZijakVD4Cy6ZQTMTZzCPRjNMeKF",
"cuenta": "",
"monto": 10.00000000,
"confirmaciones": 6,
"etiqueta": "",
"txids": [
"ce397d610c0066f1f4f38d532bc527daac3bd6aac25081618be63620d9078c7b"
]
}
],
"error": nulo,
"identificación": nulo
}
Y ya entre estos datos necesitaremos encontrar todas nuestras direcciones y saber quién nos transfirió y cuánto. Es importante recordar que, de forma predeterminada, listreceivedbyaddress solo le devolverá transacciones confirmadas. Si desea obtener la lista completa, debe pasar 0 como parámetro, como en el caso de getreceivedbyaddress.
Utilizar este método se vuelve cada vez más difícil y costoso con el tiempo, porque ves todas las transacciones con todas las direcciones que tienes.
En general, tenemos todo lo que necesitamos para aceptar pagos utilizando bitcoin. Por supuesto, el método descrito no es el más conveniente, pero aún así le permite organizar una pasarela de pago sencilla.
Lea también: ACEPTAMOS PAGOS EN BITCOIN: PRIMERA PARTE, TEÓRICO
ACEPTAMOS PAGOS EN BITCOIN: SEGUNDA PARTE. HERRAMIENTAS Y PREPARACIÓN
ACEPTA EL PAGO EN BITCOIN: TERCERA PARTE, TU TESTNET. CON BLACKJACK
Leer también
Aceptamos pagos en bitcoin: Tercera parte, nuestra testnet. con veintiuna
En el último artículo te dije cómo instalar bitcoind (al menos en Ubuntu Linux) y cómo conectarte a testnet. Pero testnet es una buena solución cuando se realizan pruebas en un sitio web ya preparado que ya se ha implementado en un servidor de Internet. Pero para el desarrollo local esta está lejos de ser la solución más conveniente.
Aceptamos pago en bitcoin: Segunda parte. Herramientas y preparación
Quizás no logré asustarte lo suficiente como para hacerte renunciar a esta loca idea de aceptar pagos en bitcoins. Bueno, entonces tengo otra porción de dolor de cabeza para ti.
