我想开始在我的网站上接受比特币。
为了做到这一点,我编写了以下代码,但是我真的很难理解在交易完成后如何实现适当的业务逻辑。
代码如下:
<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>
此代码执行以下操作:
使用区块链API获取当前USD / BTC汇率。
以美元的价格获取URL的价格并将其转换为BTC
使用Google API生成QR码。
将价格,标签和消息嵌入QR码
在DIV中呈现QR码
我还设置了一个Web挂钩服务,它将监听指定钱包地址中发生的新交易。然后通过POST请求对我的服务器进行回调。
问题是:传递给QR码的标签和消息参数不会写在区块链中。
它们只是方便客户参考的内容,以提醒他该笔特定交易的价格。
结果,回调到我的服务器几乎没有用。
实际上,该回调不会返回任何预订ID或任何其他信息,这些信息可以帮助我了解谁为之付款。不用说,在这种情况下,不可能有任何业务逻辑:我无法更新数据库上的订单状态,也无法向正确的客户发送确认电子邮件。
如何最好通过QR码将相关信息(例如,预订ID)嵌入BTC付款中?
如果这是可能的,我以后如何在服务器收到回叫通知我对BTC钱包进行了新付款的回调时检索此信息?
答案 0 :(得分:0)
简而言之,你不能。
在接受付款时,您应该给每张发票一个新的BTC地址。这样,当您收到传入交易的通知时,您可以检查接收地址以查看正在支付的发票,并将接收到的金额与预期金额进行比较。
注意
从技术上讲,您可以将订单ID之类的东西嵌入OP_RETURN中。但是,大多数钱包都不支持这样的交易,并且任何想要通过交换帐户向您付款的用户都无法遵守。
答案 1 :(得分:0)
@Raghav Sood感谢您为我提供了正确的指导。
在后端使用NodeJS / Express / MongoDB,我设法实现了一个我想在这里分享的解决方案。
在开始之前,我要大声否认:此解决方案不是唯一的解决方案,不是最好的解决方案,不是最快的解决方案,而且可能不是最优雅的解决方案。
无论如何,此解决方案的优点是不依赖于打包的第三方解决方案。这符合比特币社区的整个“无中介”哲学的精神。最令人不解的是,您的XPub始终保留在服务器中,并且不与任何外部服务共享,这可能是最明智的方法。
话虽如此,这是向人展示动态唯一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});
});
});
然后,使用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”计数器存储回数据库。
在这一点上,应该只开始监视对生成的动态BTC地址的传入(未确认)付款。一种简单的方法是使用blockchain.info websocket API。付款到帐后,按照@Raghav Sood的建议进行处理:请检查传入的交易,以确保客户向正确的地址支付了正确的金额。
现在,您知道谁支付了什么费用,并且可以触发各种业务逻辑。