Baron is a bitcoin payment processor that makes it easy to manage bitcoin transactions.
- Allows for invoice creation in USD or BTC
- Invoice balances created in USD are converted to BTC at time of payment
- Records BTC exchange rates when payments are made
- Keeps a history of all invoices and payments
Clone the repository:
$ git clone https://github.com/slickage/baron.git
Change directories to Baron and install dependencies:
$ npm install
Configurations can be changed in the config.js file in the root of Baron.
var config = {
couchdb: {
url: process.env.DB_URL || 'http://localhost:5984',
name: process.env.DB_NAME || 'baron'
},
bitcoind: {
host: process.env.BITCOIND_HOST || 'localhost',
port: process.env.BITCOIND_PORT || 18332,
user: process.env.BITCOIND_USER || 'username',
pass: process.env.BITCOIND_PASS || 'password'
},
insight: {
host: process.env.INSIGHT_HOST || 'localhost',
port: process.env.INSIGHT_PORT || '3001',
protocol: process.env.INSIGHT_PROTOCOL || 'http'
},
port: process.env.PORT || 8080,
baronAPIKey: process.env.BARON_API_KEY || 'youshouldreallychangethis',
chainExplorerUrl: process.env.CHAIN_EXPLORER_URL || 'http://tbtc.blockr.io/tx/info',
updateWatchListInterval: process.env.UPDATE_WATCH_LIST_INTERVAL || 15000,
lastBlockJobInterval: process.env.LAST_BLOCK_JOB_INTERVAL || 15000,
webhooksJobInterval: process.env.WEBHOOKS_JOB_INTERVAL || 15000,
paymentValidForMinutes: process.env.PAYMENT_VALID_FOR_MINUTES || 5,
trackPaymentUntilConf: process.env.TRACK_PAYMENT_UNTIL_CONF || 100
};
couchdb
- Database connection configsbitcoind
- Bitcoin client connetion configsinsight
- Insight connection configsport
- The port that Baron should run onbaronAPIKey
- A secret key that is used to validate invoice creation [1]chainExplorerUrl
- A link to the tx route of a chain explorerupdateWatchListInterval
- How often the watched payments job should run in mslastBlockJobInterval
- How often the last block job should run in mswebhooksJobInterval
- How often the webhooks job should run in mspaymentValidForMinutes
- How long before exchange rate refreshes for paymenttrackPaymentUntilConf
- How long to watch payments for before no longer updating
NOTES:
- [1] The
baronAPIKey
can be generated usingnode generatetoken.js stringToHash
. - Properties in config.js can be overriden using a .env file and foreman.
Modify bitcoin's bitcoin.conf:
# (optional) connects bitcoin client to testnet
testnet=1
# allows json-rpc api calls from Baron
server=1
# these should match your config or .env bitcoind username and password
rpcuser=username
rpcpassword=password
First ensure that both insight-api and bitcoin are running and that their connection properties are correctly set in Baron's config.
Running Baron with node
$ node server.js
Running Baron with foreman and nodemon
$ foreman start -f Procfile-dev
Invoices allow a person to receive payment for goods or services in BTC. The invoice can be created in USD for a fixed price invoice or in BTC. USD invoices are converted to BTC at time of payment using the current exchange rate for BTC.
After an invoice is created, it can be viewed by going to the /invoices/:invoiceId route. For example:
http://localhost:8080/invoices/8c945af08f257c1417f4c21992586d33
Invoices have the following properties:
access_token
- The API key for Baron to verify that invoice creator is trusted [1]currency
- Currency of the invoice, can be either USD or BTCmin_confirmations
- Minimum confirmations before a payment is considered paidexpiration
(optional) - Expiration time for invoice (unix timestamp)terms
- (optional) A URL to a specific terms and conditions page for this invoicewebhooks
- (optional) An object containing event webhooks [2]line_items
- Array storing line itemsdescription
- Line item description textquantity
- Quantity of the item purchasedamount
- The unit cost of the line item [3]
NOTES:
- [1] The access token is not stored with the invoice, it is just used for Baron to verify that the invoice creator is trusted. This access token must match the
baronAPIKey
property in config.js. - [2] See the Webhooks section below for a more detailed description
- [3] Line item amounts are stored in whatever currency the invoice is set to.
An example of a new Invoice object:
var newInvoice = {
"access_token" : "268f84b93a69bbdf4c5f37dd67196eac75fdcda86dad301cc3fb4aed0670c2cb",
"currency" : "BTC",
"min_confirmations" : 3,
"expiration" : 1399997753000, // Optional
"terms" : "http://somesite.com/terms", // Optional
"webhooks" : { // Optional
"paid": { "url": "http://somesite.com/notifypaid", "token": "268f84b93a69bbd" }
},
"line_items" : [
{
"description" : "Foo",
"quantity" : 2,
"amount" : 0.125
},
{
"description" : "Bar",
"quantity" : 1,
"amount" : 2.5
}
]
};
Invoices can be created by doing a POST of the newInvoice object to /invoices route. For example:
http://localhost:8080/invoices
Payments are created when the 'Pay Now' button on an invoice is clicked. User's are redirected to a view that displays the payment information such as amount due, address and QR Code for fulfillment of the invoice.
When a user's payment reaches the invoice's minimum confirmations, the payment is considered to be in the 'paid' status. Baron also handles other payment statuses:
Status | Description |
---|---|
Paid |
When the received payment fully pays off an invoice |
Overpaid |
When the received payment pays more than the invoice required |
Parital |
When the received payment pays less than the invoice required |
Unpaid |
Payments are unpaid when initially created |
Pending |
Payments are pending until they reach the invoices min confirmations |
Invalid |
Payments that have been reorged or double spent |
Payments can be viewed by going to the /pay/:invoiceId route. For example:
http://localhost:8080/pay/8c945af08f257c1417f4c21992586d33
Payments have the following properties:
invoice_id
- Invoice that this payment is associated withaddress
- Address to send BTC toamount_paid
- Stores the amount that was paid (Always stored in BTC)expected_amount
- Stores the amount that the payment expects to receiveblock_hash
- Stores the blockhash that the transaction was confirmed intospot_rate
- Stores the exchange rate at the time of paymentstatus
- The status of this payment (paid, unpaid, partial, overpaid, pending, invalid)tx_id
- Stores the transaction ID from bitcoindwatched
- Indicates if the payment is actively being watched by Baroncreated
- Time the payment was createdpaid_timestamp
- Time that payment became 'paid' statusreorg_history
- When applicable, contains the history of block hashes that the transaction was reorged out ofdouble_spent_history
- When applicable, contains the history of transaction ID's that double spent this payment
NOTE: This is just for reference, all payments are created and handled internally by Baron.
Baron is able to handle when a bitcoin transaction is reorged, double spent, or mutated. For example:
Baron is also able to handle partial payments. When a payment only partially fulfills an invoice the user can click the 'Pay Now' button again, this will create a new payment with the remaining balance. If the user has script enabled the payment page will automatically refresh with an updated remaining balance and payment address. Alternatively user's can also send multiple payments to the same address.
This is an example of an invoice that was paid in full by two separate payments:
Baron is capable of doing a POST to a url when a payment event occurs. A payment event is when a payment goes from one status to anther. If a payment was to go from unpaid
to paid
status this would trigger the webhook stored in newInvoice.webhooks.paid
. Here is a full list of supported webhooks:
var newInvoice = {
//...
"webhooks": {
"paid": { "url": "http://somesite.com/notifypaid", "token": "93a69bbdf4c5f37dd6" }
"partial": { "url": "http://somesite.com/notifypartial", "token": "93a69bbdf4c5f37dd6" }
"invalid": { "url": "http://somesite.com/notifyinvalid", "token": "93a69bbdf4c5f37dd6" }
"pending": { "url": "http://somesite.com/notifypending", "token": "93a69bbdf4c5f37dd6" }
}
//...
};
url
- The url Baron should POST to when the payment event occurstoken
- A sha256 of a token that the invoice creating app is aware of
If webhooks are needed, the application creating the webhooks should create a secret that will be used for the token. The secret should be some message wrapped in a sha256 hash. It should then hash that token and pass it as as webhook's token properties.
MIT