A Ruby 1.9+ client for Cubits Merchant API v1.
Add this line to your application's Gemfile:
gem 'cubits'
And then execute:
$ bundle
Or install it yourself as:
$ gem install cubits
First thing you have to do is to generate your API token (key+secret) from your Cubits Pay account in the API integration section.
Then, configure your Cubits client:
require 'cubits'
Cubits.configure(key: '***', secret: '***')
Now you can test your API connection:
require 'cubits'
Cubits.configure(key: '***', secret: '***')
Cubits.available? # => true
If you configured multiple connections the last one will be used by default. You can get the current active connection key with Cubits.active_connection_key
and switch between connections with Cubits.active_connection_key=
. There is also a possibility to temporary switch the connection for a block: Cubits.with_connection_key() { ... }
Using the cubits
Ruby client you can create and retrieve invoices.
Invoices are represented by the Cubits::Invoice
class, which is a descendant of Hashie::Mash, so it's a Hash with a method-like access to its elements:
invoice.id # => "686e4238970a92f04f1f5a30035bf024"
invoice.status # => "pending"
invoice.invoice_amount # => "0.00446216"
invoice.invoice_currency # => "BTC"
invoice.address # => "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
Creates a new invoice.
For a list of accepted and returned parameters, see the POST /api/v1/invoices
page in the Cubits Help Center Developer's section.
invoice = Cubits::Invoice.create(price: '1.00', currency: 'EUR')
Here a call to POST /api/v1/invoices
is executed and the response is wrapped in a Cubits::Invoice
object.
Retrieves an existing invoice.
invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
Returns Cubits::Invoice
object or nil
if the specified invoice was not found.
Reloads Cubits::Invoice
object.
invoice = Cubits::Invoice.find("686e4238970a92f04f1f5a30035bf024")
# do some stuff...
invoice.reload # gets the up-to-date invoice data from the Cubits API
Using the cubits
Ruby client you can create, update and retrieve channels.
Channels are represented by the Cubits::Channel
class, which is a descendant of Hashie::Mash, so it's a Hash with a method-like access to its elements:
channel.id # => "d17ad6c96f83162a2764ecd4739d7ab2"
channel.receiver_currency # => "EUR"
channel.address # => "3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC"
Creates a new channel.
For a list of accepted and returned parameters, see the POST /api/v1/channels
page in the Cubits Help Center Developer's section.
channel = Cubits::Channel.create(receiver_currency: 'EUR')
Here a call to POST /api/v1/channels
is executed and the response is wrapped in a Cubits::Channel
object.
Retrieves an existing channel.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
Returns Cubits::Channel
object or nil
if the specified channel was not found.
Reloads Cubits::Channel
object.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
# do some stuff...
channel.reload # gets the up-to-date channel data from the Cubits API
Updates attributes of the channel.
For a list of accepted parameters, see the POST /api/v1/channels/{id}
page in the Cubits Help Center Developer's section.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.reference # => nil
channel.update(reference: "CHAN_192357")
channel.reference # => "CHAN_192357"
Returns channel transactions as Cubits::ResourceCollection
of Cubits::Channel::Tx
objects.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.count # => 42
The Cubits::ResourceCollection
object represents a collection of resources of a particular type:
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs # => <Cubits::ResourceCollection of Cubits::Channel::Tx ...>
Cubits::ResourceCollection
implements Ruby Enumerable interface, and therefore exposes all the basic iterators (#each
, #select
, #map
) as well as many other methods.
In addition to that, some helper methods are implemented:
Returns number of elements in the collection:
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.count # => 42
Returns all the elements of the collection as an Array
:
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.all # => [{ "tx_ref_code"=>"YYWZN",
# "state"=>"pending",
# "channel_id"=>"d17ad6c96f83162a2764ecd4739d7ab2",
# ...
# },
# ...
# ]
Returns the first element of the collection:
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.first # => { "tx_ref_code"=>"YYWZN", "state" => "pending", ... }
Returns the last element of the collection:
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.last # => { "tx_ref_code"=>"WWZKX", "state" => "completed", ... }
Finds and returns an element in the collection with a given id (or tx_ref_code in case of Cubits::Channel::Tx), or nil
if the element cannot be found.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.find("PGDAV") # => { "tx_ref_code"=>"PGDAV", "state" => "completed", ... }
Reloads collection. Resets preloaded elements and element count.
channel = Cubits::Channel.find("d17ad6c96f83162a2764ecd4739d7ab2")
channel.txs.count # => 42
# ... new transaction is created
channel.txs.count # => 42
channel.txs.reload.count # => 43
This resource represents a merchant channel transaction. An instance of Cubits::Channel::Tx
should be obtained from a channel.txs
collection or instantiated
from a callback.
Returns the Cubits::Channel
object, owning this transaction:
tx = Cubits::Channel::Tx.from_callback(
cubits_callback_id: 'ABCDEFGH',
cubits_key: '7287ba0902...',
cubits_signature: '7d89c35c2...',
body: '{"tx_ref_code": "YYWZN", "state": "pending", ...}'
)
tx.channel # => {"receiver_currency"=>"EUR", "name"=>nil, ...}
tx.channel.class # => Cubits::Channel
Your Cubits accounts are represented by the Cubits::Account
class, which is a descendant of Hashie::Mash, so it's a Hash with a method-like access to its elements:
account = Cubits::Account.all.first
account.currency # => "EUR"
account.balance # => "125.00"
Retrieves a list of accounts.
Returns Array
of Cubits::Account
objects.
Cubits::Account.all # => [{ currency: 'EUR', balance: '125.00' }, ...]
Requests a quote for a "buy" or "sell" operation.
Quotes contain information about the current Cubits exchange rate for a certain operation type of a certain amount and can serve as an estimation for subsequent buy or sell requests.
Creates a new quote.
For a list of accepted and returned parameters, see the POST /api/v1/quotes
page in the Cubits Help Center Developer's section.
quote = Cubits::Quote.create(
operation: 'buy',
sender: {
currency: 'EUR'
},
receiver: {
currency: 'BTC',
amount: '1.0'
}
)
quote.sender # => {"currency"=>"EUR", "amount"=>"172.81"}
Here a call to POST /api/v1/quotes
is executed and the response is wrapped in a Cubits::Quote
object.
Cubits.buy
helper method creates a transaction to buy bitcoins using funds from your Cubits account. Bought bitcoins will be credited to your Cubits wallet.
The exact exchange rate will be calculated at the transaction execution time.
Attribute | Data type | Description |
---|---|---|
sender | Hash | Sender attributes define the spending part of the transaction |
sender[:currency] | String | ISO 4217 code of the currency that you want to spend (e.g. "EUR") |
sender[:amount] | String | Amount in specified currency to be spent, decimal number as a string (e.g. "12.50") |
Cubits.buy sender: { currency: 'EUR', amount: '150.00' }
# => {"tx_ref_code"=>"RNXH3"}
On success, .buy
creates a transaction and returns its reference code.
Cubits.sell
helper method creates a transaction to sell bitcoins from your Cubits wallet and receive the according amount in the specified fiat currency. Fiat funds will be credited to your Cubits cash account.
The exact exchange rate will be calculated at the transaction execution time.
Attribute | Data type | Description |
---|---|---|
sender | Hash | Sender attributes define the spending part of the transaction |
sender[:amount] | String | Amount in BTC to be spent, decimal number as a string (e.g. "0.01250000") |
receiver | Hash | Receiver attributes define the receiving part of the transaction |
receiver[:currency] | String | ISO 4217](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) code of the currency that you want to receive (e.g. "EUR") |
Cubits.sell sender: { amount: '0.45000000' }, receiver: { currency: 'EUR' }
# => {"tx_ref_code"=>"4XRX3"}
On success, .sell
creates a transaction and returns its reference code.
Cubits.send_money
helper method allows you to send Bitcoin from your Cubits Wallet to an external Bitcoin address.
name | type | description |
---|---|---|
amount | String | Amount in BTC to be sent, decimal as a String (e.g. "0.1234000") |
address | String | Bitcoin address to send the amount to |
Cubits.send_money amount: '1.5000000', address: '3BnYBqPnGtRz2cfcnhxFKy3JswU3biMk5q'
# => {"tx_ref_code"=>"64RHH"}
On success .send_money
creates a transaction and returns its reference code.
Cubits Merchant API provides an authentication mechanism for callback requests it posts to the merchant specified URL's. That way merchants can be sure, that the data posted within a callback comes from a trusted source.
The callback authentication is described in detail in the Cubits Help Center Developer's section.
The cubits
ruby gem provides a Cubits::Callback
class for easy and straightforward callback verification and parsing.
Provided all relevant headers and body are extracted from the callback request, from_params()
method validates the signature, parses request body and returns passed data wrapped in a given Cubits::Resource
-based class object.
Signature of the callback is verified using key+secret pair, passed to Cubits.configure(...)
beforehand.
name | type | description |
---|---|---|
cubits_callback_id | String | Value of the CUBITS_CALLBACK_ID header |
cubits_key | String | Value of the CUBITS_KEY header |
cubits_signature | String | Value of the CUBITS_SIGNATURE header |
body | String | Callback request body as a String |
resource_class | Resource, nil | (optional) subclass of Cubits::Resource (e.g. Cubits::Invoice ). If specified, an object of that class is instantiated and initialized with the parsed request body. (default: nil) |
allow_insecure | Boolean | (optional) Allow insecure, unsigned callbacks (default: false) |
An instance of a given resource_class
or a Hash
.
Cubits::InvalidSignature
is raised if either cubits_key
passed with the callback
does not match the preconfigured API key, or the cubits_signature
does not match
the signature calculated from a preconfigured API key+secret pair.
Cubits::InsecureCallback
is raised if the callback is unsigned, and allow_insecure
option is false.
Validate and parse callback into a plain Hash
:
data = Cubits::Callback.from_params(
cubits_callback_id: 'ABCDEFGH',
cubits_key: '7287ba0902...',
cubits_signature: '7d89c35c2...',
body: '{"attr1": 123, "attr2": "hello"}'
)
data # => { 'attr1' => 123, 'attr2' => 'hello' }
data.class # => Hash
Validate and parse callback into a Cubits::Invoice
object:
invoice = Cubits::Callback.from_params(
cubits_callback_id: 'ABCDEFGH',
cubits_key: '7287ba0902...',
cubits_signature: '7d89c35c2...',
body: '{"attr1": 123, "attr2": "hello"}',
resource_class: Cubits::Invoice
)
invoice # => { 'attr1' => 123, 'attr2' => 'hello' }
invoice.class # => Cubits::Invoice
Process an insecure, unsigned callback:
data = Cubits::Callback.from_params(
cubits_callback_id: 'ABCDEFGH',
body: '{"attr1": 123, "attr2": "hello"}',
allow_insecure: true
)
data # => { 'attr1' => 123, 'attr2' => 'hello' }
Cubits::Invoice
, Cubits::Channel
and Cubits::Channel::Tx
expose
a helper method: .from_callback()
which can be used to validate callback and instantiate a resource object in one go:
invoice = Cubits::Invoice.from_callback(
cubits_callback_id: 'ABCDEFGH',
cubits_key: '7287ba0902...',
cubits_signature: '7d89c35c2...',
body: '{"attr1": 123, "attr2": "hello"}'
)
invoice # => { 'attr1' => 123, 'attr2' => 'hello' }
invoice.class # => Cubits::Invoice