BitPay Ruby Library

Implement blockchain payments on your e-commerce website using BitPay's Ruby client library.

Using the BitPay Ruby Client Library

Prerequisites

You must have a BitPay merchant account to use this library. It's free to sign-up for a BitPay merchant account.

Once you have a BitPay merchant account, you will need a working BitPay Access Token – this can be done either via the library or manually in the BitPay Dashboard.

Quick Start

Installation

gem install bitpay-sdk


In your Gemfile:

gem 'bitpay-sdk', :require => 'bitpay_sdk'


Or directly:

require 'bitpay_sdk'


Configuration

The bitpay client creates a cryptographically secure connection to your server by pairing an API code with keys generated by the library. The client can be initialized with pre-existing keys passed in as a pem file, or paired if initialized with a pem file and a tokens hash. Examples can be found in the cucumber step helpers.

Pairing

Most calls to the BitPay REST API require that your client is paired with the bitpay.com server. To pair with bitpay.com you need to have an approved merchant account.

Your client can be paired via the pos (point-of-sale) or merchant facade (or both). The pos facade allows for invoices to be created. The merchant facade has broader privileges to view all invoices, bills, and ledger entries, as well as to issue refunds. Consider the level of access required when you pair your client.

A quick note on keys

The BitPay client gem includes the BitPay KeyUtilities gem, which can be used to generate new public private key pairs which it returns in PEM format. However, there are no methods which save the keys anywhere, so it is your responsibility to store the PEM file somewhere secure.

BitPay authentication

BitPay authentication depends on four parts:

  1. An account on our servers.
  2. A token shared between the client and the server.
  3. A public key, shared between the client and the server.
  4. A private key, held exclusively by the client.

In order to complete authentication, you have to associate your private key with a token, and associate that token with an account. Once this authentication is complete, as long as you have the private key, you never have to authenticate again. The token you created will always be associated with that private key, so any time you create a new bitpay client object with that key, it is authenticated with BitPay. This is true whether you use the ruby-client, python client, or no client at all, the key is the important thing.

There are two ways to authenticate, from the client side or the server side. The Ruby Client supports both.

To pair from the server side, you log in to the BitPay server, navigate to dashboard/merchant/api-tokens, and create a new token. This creates a new token, which is associated with your account. It is not associated with a key, so we provide a pairing code that you can use as a one time secret to associate the token with a key. From the client side, you can use the client.pair_pos_client(<pairing_code>) method to associate that method with a key held by the client.

To pair from the client side, you use the client to call the /tokens endpoint on the server with no parameters. This creates a token on the server and associates that token with a public key. What it doesn't do is associate that token to an account (because we don't know what account to associate with). This call returns a pairing code, which is a one time secret that allows you to find the token you just created. In order to associate the token with an account, you log in to the BitPay server, and use the dashboard/merchant/api-tokens interface to associate the token with a specific account. And example of client side pairing is shown below.

Pairing Programatically

If you are developing a client with built-in pairing capability, you can pair programattically using the pair_client method. This method can be called in two ways:

This is an example of creating a paired client with the BitPay toolset.

$ gem install bitpay-sdk
Successfully installed bitpay-sdk-2.2.0
1 gem installed
$ irb
2.1.1 :001 > require 'bitpay_sdk'
 => true 
2.1.2 :002 > pem = BitPay::KeyUtils.generate_pem
 => "-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIH8oSTRm8lVMTVOsDZleIB8AmkiuHnp+ctEknqeUmZahoAcGBSuBBAAK\noUQDQgAEbjhdKA+X8NEKgcbHhyJaBMvePV7Sj6AQuOMQzuZYdskdkPY1/jlfQwNG\n4GVd/zSw4uhfukw/SDBOEKlQGVAmxQ==\n-----END EC PRIVATE KEY-----\n" 
2.1.1 :002 > client = BitPay::SDK::Client.new(api_uri: 'https://test.bitpay.com', pem: pem)
 => #<BitPay::SDK::Client:0x000000019c6d40 @pem="---... @tokens={}> 
2.1.1 :003 > client.pair_client()
 => {"data"=>[{"policies"=>[{"policy"=>"id", "method"=>"inactive", "params"=>["Tf49SFeiUAtytFEW2EUqZgWj32nP51PK73M"]}], "token"=>"BKQyVdaGQZAArdkkSuvtZN5gcN2355c8vXLj5eFPkfuK", "dateCreated"=>1422474475162, "pairingExpiration"=>1422560875162, "pairingCode"=>"Vy76yTh"}]} 


As described above, using the value from the pairingCode element, visit https://test.bitpay.com/api-tokens and search to register for the appropriate facade. That client is now paired. As previously mentioned, you must save the pem string you generated in order to use the client again.

General Usage

Initialize the client

client = BitPay::SDK::Client.new(pem: File.read('bitpaykey.pem'))



Optional parameters:

  • api_uri - specify a different api endpoint (e.g. 'https://test.bitpay.com'). Ensure no trailing slash.
  • tokens - pass a stored hash of bitpay API tokens
  • user-agent - specify a custom user-agent value
  • debug: true - enable HTTP request logging to $stdout
  • insecure: true - disable HTTPs certificate validation (for local test environments)

Create a new bitcoin invoice

invoice = client.create_invoice(price: <price>, currency: <currency>)


With invoice creation, price and currency are the only required fields. If you are sending a customer from your website to make a purchase, setting redirectURL will redirect the customer to your website when the invoice is paid.

Response will be a hash with information on your newly created invoice. Send your customer to the url to complete payment:

{
  "url": "https://bitpay.com/invoice?id=NKaqMuZWy3BAcP77RdkEEv",
  "paymentUrls": {
    "BIP21": "bitcoin:mvYRECDxKPaPHnjNz9ZxiTpbx29xYNoRy4?amount=0.3745",
    "BIP72": "bitcoin:mvYRECDxKPaPHnjNz9ZxiTpbx29xYNoRy4?amount=0.3745&r=https://bitpay.com/i/NKaqMuZWy3BAcP77RdkEEv",
    "BIP72b": "bitcoin:?r=https://bitpay.com/i/NKaqMuZWy3BAcP77RdkEEv",
    "BIP73": "https://bitpay.com/i/NKaqMuZWy3BAcP77RdkEEv"
  },
  "status": "new",
  "btcPrice": "0.3745",
  "btcDue": "0.3745",
  "price": 148,
  "currency": "USD",
  "exRates": {
    "USD": 395.20000000000005
  },
  "invoiceTime": 1415987168612,
  "expirationTime": 1415988068612,
  "currentTime": 1415987168629,
  "guid": "438e8237-fff1-483c-81b4-dc7dba28922a",
  "id": "NKaqMuZWy3BAcP77RdkEEv",
  "transactions": [

  ],
  "btcPaid": "0.0000",
  "rate": 395.2,
  "exceptionStatus": false,
  "token": "9kZgUXFb5AC6qMuLaMpP9WopbM8X2UjMhkphKKdaprRbSKgUJNE6JNTX8bGsmgxKKv",
  "buyer": {
  }
}


There are many options available when creating invoices, which are listed in the BitPay API documentation.

Get invoice status

The ruby library provides two methods for fetching an existing invoice:

# For authorized clients with a 'merchant' token
client.get_invoice(id: 'PvVhgBfA7wKPWhuVC24rJo')

# For non-authenticated clients (public facade)
# Returns the public subset of invoice fields
client.get_public_invoice(id: 'PvVhgBfA7wKPWhuVC24rJo')


Create a refund request

Clients with a merchant token can initiate a refund request for a paid invoice:

client.refund_invoice(id: '6pbV13VBZfGFJ8BBmXmLZ8', params: {amount: 10, currency: 'USD'})



Refund rules:

  • Invoices cannot be refunded prior to 6 blockchain confirmations
  • Invoices without ["flags"]["refundable"] == true must specify a bitcoinAddress param (one was not provided as part of the transaction)
  • Invoices that are paid in full must specify an amount and currency param to indicate the amount to be refunded

View Refund Requests

The ruby library provides two methods for viewing refund requests. Both require a merchant token.

# To get an array of all refunds against a specific invoice
client.get_all_refunds_for_invoice(id: 'PvVhgBfA7wKPWhuVC24rJo')

# To get a specific refund for a specific invoice
client.get_refund(id: 'JB49z2MsDH7FunczeyDS8j', request_id: '4evCrXq4EDXk4oqDXdWQhX')


Cancel Refund Requests

Requires a merchant token.

client.cancel_refund(id: 'JB49z2MsDH7FunczeyDS8j', request_id: '4evCrXq4EDXk4oqDXdWQhX')


Make a HTTP request directly against the REST API

For API tasks which lack a dedicated library method, BitPay provides methods that will automatically apply the proper cryptographic parameters to a request.

client.send_request("GET", "invoices/JB49z2MsDH7FunczeyDS8j", facade: 'merchant')
## This request is identical to:
token = client.get_token("merchant")
client.get(path: "invoices/JB49z2MsDH7FunczeyDS8j", token: token)

## post requests are also possible
token = client.get_token("merchant")
client.post(path: "tokens", token: token, params: {facade: "pos"})  #returns a new token with pairing code
## equivalent to
client.send_request("POST", "tokens", facade: 'merchant', params: {facade: 'pos'})


Usage:

  • Specify HTTP verb and REST endpoint
  • Specifying a facade will fetch and apply the corresponding token
  • Alternatively provide a token explicitly
  • For POST requests, the params hash will be included as the message body

Testnet Usage

During development and testing, take advantage of the Bitcoin TestNet by passing a custom api_uri option on initialization:

BitPay::SDK::Client.new({api_uri: "https://test.bitpay.com/api"})


Note that in order to pair with testnet, you will need a pairing code from test.bitpay.com and will need to use the bitpay client with the --test option.

API Documentation

API Documentation is available on the BitPay site.

Running the Tests

In order to run the tests, you must have phantomjs installed and on your PATH.

The tests require that environment variables be set for the bitpay server, user name, password, an invoice id for refunds and a valid testnet bitcoin address for refunds. First run:

$ source ./spec/set_constants.sh https://test.bitpay.com <yourusername> <yourpassword> <a-confirmed-invoice-id> <a-valid-testnet-address>
$ bundle install
$ bundle exec rake


Tests are likely to run up against rate limiters on test.bitpay.com if used too frequently. Rake tasks which interact directly with BitPay will not run for the general public.

Integration Options
BitPay Ruby Library
Category

Libraries

View on GitHubview on rubygems

Get Started with the BitPay Ruby Library integration