I began working on a Cash Bounty platform last year, but discontinued active development of this due to the difficulty involved in implementing some form of Payment Handling that could track transactions. One approach I was advised of was to use a different address per transaction - but, given that I wanted the funds to land directly at the recipients address (without me having to act as a mediator at all), I opted for attaching data to OP_RETURN's (via the `?op_return=xxxx` query parameter - which only has very limited support). This was not an elegant solution.
Ultimately, this has stoked me into working on a platform (Cash Pay Server) to ease this whole process via the BIP70 protocol. This has been a bit of a shitshow as wallet support is not great - and, if you implement BIP70, you should also implement the JSONPaymentProtocol (as both use the same URL scheme - and wallets can only really use one or the other). This is what I've attempted to do with Cash Pay Server.
What is Cash Pay Server?
Cash Pay Server is intended to be an open-source, self-hostable BIP70/JSONPaymentProtocol gateway for Bitcoin Cash.
At present, there are two components to this:
Cash Pay Server (The Node)
Cash Pay Server JS (Javascript Library)
The idea is to make Cash Payment Integration on sites as simple as possible.
Its usage, currently, is something like the following (feedback/suggestions welcome):
<!-- In future, will be a CDN. NPM package will also be available. -->
<script src="https://github.com/developers-cash/cash-pay-server-js/releases/download/v0.1.1/cashpay.min.js"></script>
<!-- Container QR Code will load into -->
<div id="invoice-container" style="width:256px;"></div>
<script>
// Actually create an invoice
var invoice = new CashPay.Invoice();
invoice.addAddress('bitcoincash:qz8dt7dlwkc5n4x9u6gclfwte8lr7n58gyavxt0vmp', 100000)
.setData('INVOICEID 12345')
.setWebhook('requested', 'https://webhook.site/5e22c4ae-95c6-4286-9af9-8dbb795e1539')
.setWebhook('broadcasted', 'https://webhook.site/5e22c4ae-95c6-4286-9af9-8dbb795e1539')
.create(document.getElementById('invoice-container')); // If argument given, will handle QR rendering, etc.
</script>
The above will:
Create an invoice and attach an InvoiceID (setData) to that invoice.
Render a QR code on page.
Change the QR code to a "green tick" once payment is broadcasted (via BIP70/JSONPaymentProto).
Trigger a webhook when the invoice is requested and payment is broadcasted.
This is important as most platforms would need to inform their backend systems once a payment has been made (i.e. to mark it as "paid" in their databases).
An example of this in action is available at the CodePen link here:
https://codepen.io/jimtendo/pen/LYpXKYe
Questions
Is this ready for Production usage?
No, not yet. I need to finalize the API's for this and implement some additional protections for the Webhooks (e.g. Signature Signing/Validation).
There's also additional features that are needed for this to be really useful (e.g. Confirmed Webhook Notifications, etc).
Will there be a free instance available for those who do not want to self-host?
Yes. The tentative address for this will be pay.infra.cash.
Can this send to multiple addresses at once?
Yes, this can be done by just calling the addAddress method.
invoice.addAddress('bitcoincash:qz8dt7dlwkc5n4x9u6gclfwte8lr7n58gyavxt0vmp', 100000)
.addAddress('bitcoincash:qreq5h8qj3cjtg3qvu82gla0kl80gu8amc859yhcdy', 100000)
Will this support SLP?
I'm not very well educated on SLP, but my understanding is that it relies upon OP_RETURN outputs, so theoretically this should be achievable. There is an addOutput(...)
function available that will accept a raw output script for cases like this. Eventually, depending on whether I can find a lightweight SLP library to compile these outputs, I may integrate this directly into the JS library.
I'm unsure which Wallets (due to poor implementation of BIP70) would support this. For example, I know older versions of the Bitcoin.com Wallet did not.
Will this support OP_RETURN?
Same answer as above currently.
How would I direct the JS Library to my own self-hosted instance?
The constructor accepts a configuration object:
var invoice = new CashPay.Invoice({ endpoint: 'https://your.instance.com' });
Is there an ETA on how long until this is usable?
I don't want to be over-optimistic, but am hoping I can have this ready within two months. This was a side-project done inbetween a full-time job so I didn't have a lot of time to invest in this. Now, I have a bit more time.
If someone wants to send me shekels, that'll incentivize me to get this done quicker.
Why BIP70?
BIP70 has a bad reputation. In my opinion, this is undeserved. It is not perfect, but most of the issues with it were to do with poor wallet implementation. Additionally, BitPay's JSONPaymentProtocol actually complicated things in that they both use the exact same URL schema. Therefore, anyone wishing to implement BIP70 also has to support JSONPaymentProtocol to ensure maximum support - as the wallets can only really support one or the other. Very disrespectful.
If anyone would like more details on how BIP70 vs JSONPaymentProto should be handled, happy to do a quick write-up on this. In general though, you want a "switchboard" type approach depending on the "accept" and "content-type" HTTP headers.
Can I render my own QR Code and not rely on the default container?
Yes, the container is more of a convenience, but the idea is to have event hooks in the JS library to allow this. In terms of the default container appearance, if any designers want to shoot something more attractive my way (or assist with that code itself, it'd be much welcomed). At the moment, that code is very messy and the default container isn't very attractive.
Other feedback or suggestions for features to accommodate other use-cases are also most welcome.
Great work!