比特币交易中的Webhooks-如何应用业务逻辑?

时间:2018-10-04 23:07:29

标签: blockchain webhooks bitcoin payment-integration

我想开始在我的网站上接受比特币。

为了做到这一点,我编写了以下代码,但是我真的很难理解在交易完成后如何实现适当的业务逻辑。

代码如下:

<html>

<head>

    <title>Pay with Bitcoin</title>

    <script>

            //Gets the URL of the Webpage and gets the price value of this transaction in USD.
            //For simplicity Here the Value is passed in the URL.
            //However in production you wanna use POST instead of GET.

            const myUrl = window.location.href;
            const url = new URL(myUrl);
            const usdPrice = url.searchParams.get("price");

            //This is the function where all the magin happens

            const showQR = () => {

                    //URL of the api which will provide us with current BTC exchange rate

                    const apiUrl = "https://blockchain.info/ticker";

                    const hr = new XMLHttpRequest();

                    hr.open('GET', apiUrl, true);

                    hr.onreadystatechange = function(){

                    //Make sure the API sent a valid response

                        if(hr.readyState == 4){

                            let ticker = JSON.parse(hr.responseText);

                            //Get last BTC/USD exchange value from the API , then convert Price from USD to BTC 

                            let BTCprice = ticker.USD.last;

                            let btcToPay = usdPrice / BTCprice;

                            //Make sure you have just 8 decimal points in your BTC price!!

                            btcToPay = btcToPay.toFixed(8);

                            //Use google API (or other...) to create the QR code. Pass on your btc public address and 
                            //the amount (btc price) dynamically created. Message and label parameters can be dynamic too.

                            let qrurl = "https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl=bitcoin:1BAnkZn1qW42uRTyG2sCRN9F5kgtfb5Bci?amount="+btcToPay+"%26label=CarRental%26message=BookingID123456";

                            //Populate the 'btc' DIV with QR code and other info...
                            document.getElementById('btc').innerHTML = "<img src=" +qrurl+"><br> <span class = 'greenMoney'>" + usdPrice + " usd / " + btcToPay + " BTC </span>";

                            }

                    }

                hr.send();

            };

    </script>

</head>

<body onload = "showQR()">

    <h1>Pay with BitCoin</h1>

    <div id = "btc">

    </div>

</body>

</html>

此代码执行以下操作:

  1. 使用区块链API获取当前USD / BTC汇率。

  2. 以美元的价格获取URL的价格并将其转换为BTC

  3. 使用Google API生成QR码。

  4. 将价格,标签和消息嵌入QR码

  5. 在DIV中呈现QR码

我还设置了一个Web挂钩服务,它将监听指定钱包地址中发生的新交易。然后通过POST请求对我的服务器进行回调。

问题是:传递给QR码的标签和消息参数不会写在区块链中。

它们只是方便客户参考的内容,以提醒他该笔特定交易的价格。

结果,回调到我的服务器几乎没有用。

实际上,该回调不会返回任何预订ID或任何其他信息,这些信息可以帮助我了解谁为之付款。不用说,在这种情况下,不可能有任何业务逻辑:我无法更新数据库上的订单状态,也无法向正确的客户发送确认电子邮件。

如何最好通过QR码将相关信息(例如,预订ID)嵌入BTC付款中?

如果这是可能的,我以后如何在服务器收到回叫通知我对BTC钱包进行了新付款的回调时检索此信息?

2 个答案:

答案 0 :(得分:0)

简而言之,你不能。

在接受付款时,您应该给每张发票一个新的BTC地址。这样,当您收到传入交易的通知时,您可以检查接收地址以查看正在支付的发票,并将接收到的金额与预期金额进行比较。

注意

从技术上讲,您可以将订单ID之类的东西嵌入OP_RETURN中。但是,大多数钱包都不支持这样的交易,并且任何想要通过交换帐户向您付款的用户都无法遵守。

答案 1 :(得分:0)

@Raghav Sood感谢您为我提供了正确的指导。

在后端使用NodeJS / Express / MongoDB,我设法实现了一个我想在这里分享的解决方案。

在开始之前,我要大声否认:此解决方案不是唯一的解决方案,不是最好的解决方案,不是最快的解决方案,而且可能不是最优雅的解决方案。

无论如何,此解决方案的优点是不依赖于打包的第三方解决方案。这符合比特币社区的整个“无中介”哲学的精神。最令人不解的是,您的XPub始终保留在服务器中,并且不与任何外部服务共享,这可能是最明智的方法。

话虽如此,这是向人展示动态唯一BTC地址的方法:

  1. 首先,我放置了一个计数器,该计数器跟踪从我的高清钱包中为客户创建了多少个btc地址。

确保与您绝不两次向客户展示相同的地址非常重要,这有利于各方的隐私,也有利于在应用中实现业务逻辑。

为此,我将“计数器值”存储到数据库中。每次有人访问BTC付款页面时,都会使用“ dealCount”函数从mongo中检索此值,并将其分配给“ serialPay”变量,该变量等于从Mongo + 1获得的值。在后端,代码为像这样的东西:

`function dealCount(){`

        return new Promise(function(resolve, reject){

            Deal.find({_id: "ID_OF_OBJ_WHERE_YOU_STORE_COUNTER"}, function(err, data){

              if(err){

                console.log(err);

              }

                resolve(data[0].serialDeal + 1);

            })

        })

      };

获得的新值(以后将再次保存到Mongo中,以便跟踪创建的地址)用于为手头的客户生成新的BTC公共地址。如果您继续阅读,将会看到方法。

要动态创建新的公共地址,需要其高清电子钱包的xPub密钥。如果使用NodeJS进行编码,则有几个库(可以导入到服务器中)可以很容易地实现此操作:bitcoinjs-lib和/或bitcore-lib。我个人选择了Bitcore-lib,因为要处理的依赖项较少,而且我发现支持材料更容易消化。

按代码排列,地址生成如下:

        const bitcore = require('bitcore-lib');

        app.post("/pay.html", urlencodedParser, function(req, res){

        let serialPay = dealCount();

        serialPay.then(function(serialPay){

          const pub = new bitcore.HDPublicKey('INSERT_HERE_YOUR_XPUB_KEY');

          let derivedHdPk = pub.derive('m/0/'+serialPay);

          let derivedPk = derivedHdPk.publicKey;

          let myDynAddress = new bitcore.Address(derivedPk);

          res.render('pay', {myDynAddress: myDynAddress});

        });

      });
  1. 然后,使用EJS作为模板引擎,我可以轻松地在前端(/pay.ejs)中使接收比特币地址动态化:

    let myDynAddress = "<%=myDynAddress%>";
    let qrurl = "https://chart.googleapis.com/chart?chs=250x250&cht=qr&chl=bitcoin:"+myDynAddress+"?amount="+btcToPay+"%26label=CarRental";
    

    这将动态生成QR码。在最初的问题中,可以看到如何将其呈现到网页中。同时,还应该放置一个函数,将更新的“ serialPay”计数器存储回数据库。

  2. 在这一点上,应该只开始监视对生成的动态BTC地址的传入(未确认)付款。一种简单的方法是使用blockchain.info websocket API。付款到帐后,按照@Raghav Sood的建议进行处理:请检查传入的交易,以确保客户向正确的地址支付了正确的金额。

现在,您知道谁支付了什么费用,并且可以触发各种业务逻辑。